Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ indentless
ine
Infof
Infoln
inotifywait
installable
INSTALLMESSAGE
INSTALLPROPERTY
Expand Down
25 changes: 25 additions & 0 deletions bats/tests/containers/volumes.bats
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,28 @@ known_failure_on_mount_type() {
assert_success
"${assert}_output" -rwxr-xr-x # spellcheck-ignore-line
}

@test 'filesystem monitoring' {
skip_on_windows
# wait for API
RD_TIMEOUT=10s try --max 30 --delay 5 rdctl api /settings
rdctl set --experimental.virtual-machine.mount.inotify
wait_for_container_engine
# Build an image that will monitor for changes.
ctrctl build --file - --tag rd_bats_volume_inotify "$HOST_WORK_PATH" <<<"
FROM $IMAGE_REGISTRY_2_8_1
RUN apk add --update-cache --no-interactive inotify-tools
ENTRYPOINT /usr/bin/inotifywait --recursive --quiet --timeout 30 /mount
"
# Schedule a change to be triggered.
{
sleep 10
date >"$HOST_WORK_PATH/foo"
} &
# Run the container, which should pick up the change and report it.
run ctrctl run \
--volume "$HOST_WORK_PATH:/mount:rw" --pull never \
rd_bats_volume_inotify
assert_output --regexp "/mount.*foo"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is probably good enough as-is, but I think it becomes clearer when you specify the full line:

Suggested change
assert_output --regexp "/mount.*foo"
assert_line "/mount/ ATTRIB foo"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is too rigid; if we later get proper MODIFY instead of ATTRIB, that should still pass.

assert_success
}
4 changes: 4 additions & 0 deletions pkg/rancher-desktop/assets/specs/command-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,10 @@ components:
cacheMode:
type: string
enum: [none, loose, fscache, mmap]
inotify:
type: boolean
x-rd-platforms: [darwin, linux]
x-rd-usage: file modification notification support, only for writable mounts
proxy:
type: object
x-rd-platforms: [win32]
Expand Down
5 changes: 5 additions & 0 deletions pkg/rancher-desktop/assets/translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,11 @@ virtualMachine:
virtiofs:
label: virtiofs
description: Exposes the filesystem by using an Apple Virtualization framework shared directory device.
inotify:
label: Filesystem event monitoring
enabled: Enabled
description: >-
Only a limited set of events are triggered; file deletions are ignored.
proxy:
legend: WSL Proxy
label: Enable the proxy used by rancher-desktop
Expand Down
5 changes: 4 additions & 1 deletion pkg/rancher-desktop/backend/lima.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export type LimaConfiguration = {
disk?: number;
mounts?: LimaMount[];
mountType: 'reverse-sshfs' | '9p' | 'virtiofs';
mountInotify?: boolean;
ssh: {
localPort: number;
loadDotSSHPubKeys?: boolean;
Expand Down Expand Up @@ -635,6 +636,7 @@ export default class LimaBackend extends events.EventEmitter implements VMBacken
memory: (this.cfg?.virtualMachine.memoryInGB || 4) * 1024 * 1024 * 1024,
mounts: this.getMounts(),
mountType: this.cfg?.virtualMachine.mount.type,
mountInotify: this.cfg?.experimental.virtualMachine.mount.inotify,
ssh: { localPort: await this.sshPort },
hostResolver: {
hosts: {
Expand Down Expand Up @@ -2154,8 +2156,9 @@ CREDFWD_URL='http://${ SLIRP.HOST_GATEWAY }:${ stateInfo.port }'
'experimental.virtualMachine.mount.9p.msizeInKib': undefined,
'experimental.virtualMachine.mount.9p.protocolVersion': undefined,
'experimental.virtualMachine.mount.9p.securityModel': undefined,
'virtualMachine.mount.type': undefined,
'experimental.virtualMachine.mount.inotify': undefined,
'experimental.virtualMachine.sshPortForwarder': undefined,
'virtualMachine.mount.type': undefined,
'virtualMachine.type': undefined,
'virtualMachine.useRosetta': undefined,
}));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
<script lang="ts">

import Vue from 'vue';
import { mapGetters } from 'vuex';

import MountTypeSelector from '@pkg/components/MountTypeSelector.vue';
import RdCheckbox from '@pkg/components/form/RdCheckbox.vue';
import RdFieldset from '@pkg/components/form/RdFieldset.vue';
import { Settings } from '@pkg/config/settings';
import { RecursiveTypes } from '@pkg/utils/typeUtils';

import type { PropType } from 'vue';

export default Vue.extend({
name: 'preferences-virtual-machine-volumes',
components: { MountTypeSelector },
props: {
components: {
MountTypeSelector, RdCheckbox, RdFieldset,
},
props: {
preferences: {
type: Object as PropType<Settings>,
required: true,
},
},
methods: {
computed: { ...mapGetters('preferences', ['isPreferenceLocked']) },
methods: {
onChange<P extends keyof RecursiveTypes<Settings>>(property: P, value: RecursiveTypes<Settings>[P]) {
this.$store.dispatch('preferences/updatePreferencesData', { property, value });
},
Expand All @@ -31,5 +37,26 @@ export default Vue.extend({
:preferences="preferences"
@update="onChange"
/>
<rd-fieldset
is-experimental
:legend-text="t('virtualMachine.mount.inotify.label')"
>
<rd-checkbox
class="inotify-options"
label-key="virtualMachine.mount.inotify.enabled"
description-key="virtualMachine.mount.inotify.description"
:value="preferences.experimental.virtualMachine.mount.inotify"
:is-locked="isPreferenceLocked('experimental.virtualMachine.mount.inotify')"
@input="onChange('experimental.virtualMachine.mount.inotify', $event)"
/>
</rd-fieldset>
</div>
</template>

<style lang="scss" scoped>
.virtual-machine-volumes {
display: flex;
flex-direction: column;
gap: 1rem;
}
</style>
1 change: 1 addition & 0 deletions pkg/rancher-desktop/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export const defaultSettings = {
msizeInKib: 128,
cacheMode: CacheMode.MMAP,
},
inotify: false,
},
proxy: {
enabled: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export default class SettingsValidator {
msizeInKib: this.checkLima(this.check9P(this.checkNumber(4, Number.POSITIVE_INFINITY))),
cacheMode: this.checkLima(this.check9P(this.checkEnum(...Object.values(CacheMode)))),
},
inotify: this.checkLima(this.checkBoolean),
},
proxy: {
enabled: this.checkPlatform('win32', this.checkBoolean),
Expand Down
Loading