diff options
-rw-r--r-- | ChangeLog.md | 33 | ||||
-rw-r--r-- | DOCS.md | 91 | ||||
-rw-r--r-- | IDEAS.md | 105 | ||||
-rw-r--r-- | TODO.md | 97 | ||||
-rwxr-xr-x | kvmx | 252 | ||||
-rw-r--r-- | kvmxfile | 53 | ||||
-rwxr-xr-x | share/provision/debian/desktop-basic | 20 | ||||
-rwxr-xr-x | share/provision/debian/messenger | 6 | ||||
-rwxr-xr-x | share/provision/debian/tor-browser | 2 | ||||
-rwxr-xr-x | share/provision/debian/web-basic | 4 | ||||
-rwxr-xr-x | share/provision/debian/webserver | 8 |
11 files changed, 494 insertions, 177 deletions
diff --git a/ChangeLog.md b/ChangeLog.md index d2062bd..14e33d4 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,37 @@ # ChangeLog -## 0.1.1 - unreleased +## 0.3.0 - 2024-09-19 + +* Increase the maximum number of shared folders to avoid error in when KVMX + attempts to setup too many 9p folder shares: + + kvm: -drive file=/var/cache/qemu/$guest/box.img,if=virtio,discard=unmap: + PCI: no slot/function available for virtio-blk-pci, all in use or reserved` + +* Per-mountpoint mode option (ro, rw). + +* Spice: + * Improved spice window handling. + + * Inotify action for watching a folder in the host and issuing commands in the + guest upon change. + + * Notification on Awesome VM when a Spice session taking too long to open. + +## 0.2.0 - 2024-07-02 + +* Increase default `msize` for 9p mounts to 32MiB depending on kernel support, + which may only be effective depending on `trans_virtio` driver support for + sizes larger than 500kB. + +* QEMU parameter updates: + * Update `nowait` to `wait=off`. + + * Update `server` to `server=on`. + + * Update `unix` to `unix=on`. + + * Update `disable-ticketing` to `disable-ticketing=on`. * Provide default parameters by loading the sample config. This allows a `kvmxfile` to be small and have only the overrides. @@ -1,6 +1,6 @@ # KVMX Documentation -Misc documentation on kvmx and qemu. +Misc documentation on kvmx and QEMU. ## USB hotplug support @@ -46,8 +46,7 @@ Misc documentation on kvmx and qemu. Nowadays this can be done with `kvmx growpart <device> <partition> <additional_size>`, but here goes some manual procedures if needed. -* Image resize action, doing something like this, thanks to - https://ahelpme.com/linux/online-resize-of-a-root-ext4-file-system-increase-the-space/ +Image resize can be manually done with a procedure like this thanks to [these docs][]: # poweroff kvmx poweroff $guest @@ -77,3 +76,89 @@ here goes some manual procedures if needed. kvmx ssh $guest sudo resize2fs /dev/vda2 kvmx ssh $guest sudo touch /forcefsck kvmx restart $guest + +[these docs]: https://ahelpme.com/linux/online-resize-of-a-root-ext4-file-system-increase-the-space/ + +## Folder sharing + +### Virtio + +References on virtio: + +* [Virtio on Linux — The Linux Kernel documentation](https://www.kernel.org/doc/html/v6.8/driver-api/virtio/virtio.html) + * [linux kernel - VIRTIO: How it increase performance - Stack Overflow](https://stackoverflow.com/questions/24737882/virtio-how-it-increase-performance) + * [Virtual I/O Device (VIRTIO) Version 1.1](https://docs.oasis-open.org/virtio/virtio/v1.1/cs01/virtio-v1.1-cs01.html#x1-240006) + +### With virtio and 9p + +* Status: works on kvmx. +* Limitations: performance is low on Linux (as of 2024-08-01), due to a + limitation in the kernel. +* Since fixes for CVE-2023-2861 were released, it's not possible anymore to set + UNIX sockets in shared folders. + +#### Details + +Some references on 9p folder sharing: + +* [v9fs: Plan 9 Resource Sharing for Linux — The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/filesystems/9p.html) + * [Documentation/9p - QEMU](https://wiki.qemu.org/Documentation/9p) + * [Documentation/9psetup - QEMU](https://wiki.qemu.org/Documentation/9psetup) + * [v9fs · GitHub](https://github.com/v9fs) + +Support for opening sockets was removed with fixes for CVE-2023-2861: + +* [Os boot issues on 9p filesystem due to unix domain sockets open failure (#2337) · Issues · QEMU / QEMU · GitLab](https://gitlab.com/qemu-project/qemu/-/issues/2337) +* [9pfs: prevent opening special files (CVE-2023-2861) (f6b0de53) · Commits · QEMU / QEMU · GitLab](https://gitlab.com/qemu-project/qemu/-/commit/f6b0de53fb87ddefed348a39284c8e2f28dc4eda) +* [CVE - CVE-2023-2861](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-2861) +* [SECURITY DLA 3759-1 qemu security update](https://lists.debian.org/debian-lts-announce/2024/03/msg00012.html) + +#### Performance + +Performance limitations: + +* There's a limit in the Linux kernel, which is explained in [this + message](https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg06850.html) + as being `.maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3)`. +* The limit is present at `trans_virtio.c` (as of 2024-08-01): + [linux/net/9p/trans_virtio.c at master - L803 · torvalds/linux · + GitHub](https://github.com/torvalds/linux/blob/master/net/9p/trans_virtio.c#L803) +* [History for net/9p/trans_virtio.c - torvalds/linux · GitHub](https://github.com/torvalds/linux/commits/master/net/9p/trans_virtio.c) + +Discussion an proposals to overcome this limit: + +* [Can not set high msize with virtio-9p (Was: Re: virtiofs vs 9p performan](https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg06343.html) + * [Re: Can not set high msize with virtio-9p (Was: Re: virtiofs vs 9p perfo](https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg06850.html) +* [remove msize limit in virtio transport - LWN.net](https://lwn.net/Articles/901523/) + * [New Patches Aim To Boost Linux 9p Performance By ~10x - Phoronix](https://www.phoronix.com/news/Linux-9p-10x-Performance) + * [9p performance increase by ~10x reflected in WSL? · microsoft/WSL · Discussion #9412 · GitHub](https://github.com/microsoft/WSL/discussions/9412) + * [VM: 9p: degraded performance: a reasonable high msize should be chosen on client/guest side · Issue #10219 · canonical/lxd · GitHub](https://github.com/canonical/lxd/issues/10219) + * [Add msize configuration for windows-side 9P client (=higher WSL2 disk speed) · Issue #9125 · microsoft/WSL · GitHub](https://github.com/microsoft/WSL/issues/9125) + * [[Virtio-fs] Can not set high msize with virtio-9p (Was: Re: virtiofs vs 9p performance)](https://listman.redhat.com/archives/virtio-fs/2021-March/002811.html) + +Patches: + +* [[PATCH v6 00/11] remove msize limit in virtio transport [LWN.net]](https://lwn.net/ml/linux-kernel/cover.1657920926.git.linux_oss@crudebyte.com/) +* [[PATCH v5 00/11] remove msize limit in virtio transport - Christian Schoenebeck](https://lore.kernel.org/all/cover.1657636554.git.linux_oss@crudebyte.com/) +* [Performance fixes for 9p filesystem - LWN.net](https://lwn.net/Articles/918213/) +* Other (untriaged list): + * [Re: [PATCH v5 00/11] remove msize limit in virtio transport - Christian Schoenebeck](https://lore.kernel.org/all/7468612.NupLhYsxyy@silver/) + * [[PATCH v3 0/7] net/9p: remove msize limit in virtio transport - Christian Schoenebeck](https://lore.kernel.org/netdev/cover.1632327421.git.linux_oss@crudebyte.com/) + * [[PATCH v2 1/7] net/9p: show error message if user 'msize' cannot be satisfied — Netdev](https://www.spinics.net/lists/netdev/msg768036.html) + * [[PATCH v2 00/10] Performance fixes for 9p filesystem - Eric Van Hensbergen](https://lore.kernel.org/lkml/20221218232217.1713283-1-evanhensbergen@icloud.com/) + * [[Virtio-fs] [PATCH v2 0/3] virtio: increase VIRTQUEUE_MAX_SIZE to 32k](https://listman.redhat.com/archives/virtio-fs/2021-October/004135.html) + * [[v4,08/12] net/9p: limit 'msize' to KMALLOC_MAX_SIZE for all transports - Patchwork](https://patchwork.kernel.org/project/netdevbpf/patch/39f81db5e5b25a1e4f94ad3b05552044209aff21.1640870037.git.linux_oss@crudebyte.com/) + * [Thread: [V9fs-developer] [PATCH] Improve 9p performance for read operations | Plan 9 Resource Sharing for Linux](https://sourceforge.net/p/v9fs/mailman/v9fs-developer/thread/B272E6A0-C349-4B23-BE6F-7CBA8D6C4B6B%40icloud.com/) + +### With virtiofs + +* The `virtiofsd` implementation from upstream QUEMY was removed on [version + 8.0](https://wiki.qemu.org/ChangeLog/8.0), in favor of the [virtio-fs / + virtiofsd](https://gitlab.com/virtio-fs/virtiofsd) implementation. +* [virtiofs - shared file system for virtual machines](https://virtio-fs.gitlab.io/) + * [virtiofs - shared file system for virtual machines / Standalone usage](https://virtio-fs.gitlab.io/howto-qemu.html) + * [Debian -- Details of package virtiofsd in trixie](https://packages.debian.org/trixie/virtiofsd) + * [rust-virtiofsd - Debian Package Tracker](https://tracker.debian.org/pkg/rust-virtiofsd) + * [libvirt: Sharing files with Virtiofs](https://libvirt.org/kbase/virtiofs.html) + * [virtio-fs / virtiofsd · GitLab](https://gitlab.com/virtio-fs/virtiofsd) + * [VirtIO-FS Is Looking Quite Good For Shared File-System With VMs - Phoronix](https://www.phoronix.com/news/VirtIO-FS-Looking-Good-2020) @@ -1,68 +1,28 @@ # Ideas -## Options - -* Short-form deprectations that may need to be upgraded soon: - * Update `nowait` to `wait=off`. - - * Update `server` to `server=on`. - - * Update `unix` to `unix=on`. - - * Update `disable-ticketing` to `disable-ticketing=on`. - -## Usability - -* Docs (tutorial and manpage). - -* Makefile and debian package. - -* Patch for spice-client-gtk for menuless windows (spicec usecase). - -* Systemd service for a single VM. - -* Shell completions. - -* Support for other Spice clients such as [Remmina](https://remmina.org). - -* Support for user-wide configurations that override both the sample and the - guest `kvmxfile`. - -* Support for multiple source/targets pairs (analogous to `shared_folders`) at: - * `provision_rsync` - -* Be more distro-agnostic, making any debian-specific routine as a separate function. - -* Be more agnostic on some personal choices (locales, softwares etc). - -* Support for per-guest `known_hosts` for SSH logins. - -## Virtualization +## Workflow -* Config option to [disable - networking](https://wiki.qemu.org/Documentation/Networking#How_to_disable_network_completely), - passing `-net none`. +### Continuous Integration script (kvmx-ci) -* [Nested virtualization](http://www.rdoxenham.com/?p=275) - ([1](https://wiki.archlinux.org/index.php/KVM#Nested_virtualization), - [2](https://ladipro.wordpress.com/2017/02/24/running-hyperv-in-kvm-guest/)). +* For schedule jobs (like cron). +* Pull from remote repository and check source integrity. +* Automatic VM (re-)creation and/or provisioning. +* Logging. +* Status report. -## Workflow - -* Continuous Integration script (kvmx-ci): - * For schedule jobs (like cron). - * Pull from remote repository and check source integrity. - * Automatic VM (re-)creation and/or provisioning. - * Logging. - * Status report. +### Test suite * Test suite for kvmx itself. +### Provisioning improvements + * Option `provision_always` to provision whenever a guest is started. * Option to re-create the backing file whenever a guest is started (if backing file is enabled). +### Qubes-like behavior + * A qubes-like behavior: guest configured: * Option 1: * With backing file and a basebox as a TemplateVM, using a `template_vm` @@ -75,7 +35,8 @@ * Use `$shared_folders` to mount custom data into the guest, allowing for specific /home/user contents. -* KVMX lifecycle enhancements: +### Lifecycle enhancements + * kvmx recycle <vm-name> # kvmx stop/destroy/up/provision * kvmx mount <vm-name> <host-folder> <guest-mountpoint> # live 9p mounting * kvmx run <vm-name> <command-file> # uploads a script as a temp file in the guest and runs it @@ -83,6 +44,8 @@ # start the VM if needed, skip if no command is set (skip when backing_file=1?); # that could allow for mass upgrades using `kvmx-supervise foreach upgrade` +### Disposability enhancements + * KVMX disposable enhancements: * kvmx disposable <vm-name> [command] * kvmx disposable-run <vm-name> <command-file> @@ -93,11 +56,6 @@ ## Folder sharing -* Try to umount all sshfs volumes in the host. - -* Remount 9p shared folders and reinitialize spice-vdagent upon resume from - disk [see possible bug](https://bugzilla.redhat.com/show_bug.cgi?id=1333072). - * Alternative folder sharing support: * NFS, SMB. * Or even [SSH to a server](https://superuser.com/questions/831659/mount-a-local-directory-to-a-remote-ssh-server)). @@ -117,34 +75,3 @@ * https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=all&keywords=fuse * Additional way to handle missing image on `kvmx up` by spawning `kvmx_install` instead of `kvmx-create`. - -* Fix isolinux support: - * http://www.syslinux.org/wiki/index.php?title=Development/Testing - * http://linux-kernel-driver.blogspot.com.br/2009/06/linux-kernel-development-using.html - * https://bbs.archlinux.org/viewtopic.php?id=177299 - -## Audio fixes to avoid crackling on input - -Implement an option to reduce crackling on sound input. - -See: - -* https://stackoverflow.com/questions/32193050/qemu-pulseaudio-and-bad-quality-of-sound#35998501 -* https://www.reddit.com/r/VFIO/comments/542bw1/ha_got_rid_of_the_pulse_audio_crackling/ -* https://www.reddit.com/r/VFIO/comments/ibmjs3/finally_fixed_crackling_audio_when_passing/ -* https://www.reddit.com/r/VFIO/comments/746t4h/getting_rid_of_audio_crackling_once_and_for_all/ -* https://www.reddit.com/r/VFIO/comments/8aqju8/audio_crackling_when_routing_output_to_pulseaudio/ - -Fix: - - export QEMU_AUDIO_DRV="pa" - export QEMU_PA_SAMPLES="8192" - export QEMU_AUDIO_TIMER_PERIOD="99" - -## Simultaneous clients connections - -Implement the following: - - export SPICE_DEBUG_ALLOW_MC=1 - -For explanation, check https://www.spice-space.org/multiple-clients.html @@ -0,0 +1,97 @@ +# TODO + +## Fixes + +* [ ] Issue with SSH access on `trixie` VMs: maybe the default ciphers have changed? + +* [ ] Support for `virt-viewer` is currently broken (as of 2024-08-04). + +* [ ] Improve `xrandr` handling (not working on big monitors with very high + resolutions). + +## Usability + +* [ ] Hard pause VM (--hard): besides pausing the process, also try to pause it + in the QEMU monitor. + +* [ ] Submit patch for spice-client-gtk for menuless windows (spice usecase) to + Debian. + +* [ ] Docs (tutorial and manpage). + +* [ ] Makefile and debian package. + +* [ ] Systemd service for a single VM. + +* [ ] Shell completions. + +* [ ] Support for other Spice clients such as [Remmina](https://remmina.org). + +* [ ] Support for user-wide configurations that override both the sample and the + guest `kvmxfile`. + +* [ ] Support for multiple source/targets pairs (analogous to `shared_folders`) at: + * [ ] `provision_rsync`. + +* [ ] Be more distro-agnostic, making any debian-specific routine as a separate function. + +* [ ] Be more agnostic on some personal choices (locales, softwares etc). + +* [ ] Support for per-guest `known_hosts` for SSH logins. + +## Virtualization + +* [ ] Config option to [disable + networking](https://wiki.qemu.org/Documentation/Networking#How_to_disable_network_completely), + passing `-net none`. + +* [ ] [Nested virtualization](http://www.rdoxenham.com/?p=275) + ([1](https://wiki.archlinux.org/index.php/KVM#Nested_virtualization), + [2](https://ladipro.wordpress.com/2017/02/24/running-hyperv-in-kvm-guest/)). + +## Folder sharing + +* [ ] Dynamically add PCI bridges depending on the number of shared folders, + avoiding PCI slot exhaustion. + +* [ ] Mount/umount/remount commands to manage shared folders. + +* [ ] Try to umount all sshfs volumes in the host when powering off. + +* [ ] Remount 9p shared folders and reinitialize spice-vdagent upon resume from + disk [see possible bug](https://bugzilla.redhat.com/show_bug.cgi?id=1333072). + +* [ ] Support for [virtiofs](https://virtio-fs.gitlab.io/howto-qemu.html). + +## Audio fixes to avoid crackling on input + +* [ ] Implement an option to reduce crackling on sound input. + +The fix involves setting the following variables: + + export QEMU_AUDIO_DRV="pa" + export QEMU_PA_SAMPLES="8192" + export QEMU_AUDIO_TIMER_PERIOD="99" + +References: + +* https://stackoverflow.com/questions/32193050/qemu-pulseaudio-and-bad-quality-of-sound#35998501 +* https://www.reddit.com/r/VFIO/comments/542bw1/ha_got_rid_of_the_pulse_audio_crackling/ +* https://www.reddit.com/r/VFIO/comments/ibmjs3/finally_fixed_crackling_audio_when_passing/ +* https://www.reddit.com/r/VFIO/comments/746t4h/getting_rid_of_audio_crackling_once_and_for_all/ +* https://www.reddit.com/r/VFIO/comments/8aqju8/audio_crackling_when_routing_output_to_pulseaudio/ + +## Simultaneous clients connections + +* [ ] Implement the following: + + export SPICE_DEBUG_ALLOW_MC=1 + +For explanation, check https://www.spice-space.org/multiple-clients.html + +## Image handling + +* [ ] Fix isolinux support: + * http://www.syslinux.org/wiki/index.php?title=Development/Testing + * http://linux-kernel-driver.blogspot.com.br/2009/06/linux-kernel-development-using.html + * https://bbs.archlinux.org/viewtopic.php?id=177299 @@ -19,7 +19,7 @@ # # Basic parameters -VERSION="0.1.1" +VERSION="0.3.0" BASENAME="`basename $0`" DIRNAME="`dirname $0`" ACTION="$1" @@ -125,8 +125,10 @@ function __kvmx_initialize { # Load the default config, providing defaults source $APP_BASE/kvmxfile || exit 1 - # Set hostname (this is already done with the default config) - #hostname="${hostname:-$VM}" + # Set hostname + if [ "$hostname" == "kvmx" ] && [ "$VM" != "kvmx" ]; then + hostname="$VM" + fi # Set domain (this is already done with the default config) #domain="${domain:-example.org}" @@ -263,16 +265,20 @@ function kvmx_spice { exit 1 fi + local spicestring + if [ "$spice_client" == "spicy" ] && which spicy &> /dev/null; then + spicestring="spice display 0:0" #spicy -h localhost -p $PORT & spicy --uri=spice+unix://$SPICESOCKET & elif [ "$spice_client" == "remote-viewer" ] && which remote-viewer &> /dev/null; then + spicestring="$VM \(1\)" #remote-viewer spice://localhost:$PORT & remote-viewer spice+unix://$SPICESOCKET & # This is untested due to libvirt requirements elif [ "$spice_client" == "virt-viewer" ] && which virt-viewer &> /dev/null; then #virt-viewer spice://localhost:$PORT & - virt-viewer spice+unix://$SPICESOCKET & + virt-viewer -c spice+unix://$SPICESOCKET & # Unsupported as spicec was deprecated #elif [ "$spice_client" != "spicec" ] && which spicec &> /dev/null; then # # https://lists.freedesktop.org/archives/spice-devel/2013-September/014643.html @@ -282,6 +288,7 @@ function kvmx_spice { exit 1 else if which spicy &> /dev/null; then + spicestring="spice display 0:0" #spicy -h localhost -p $PORT & spicy --uri=spice+unix://$SPICESOCKET & fi @@ -290,18 +297,65 @@ function kvmx_spice { SPICEPID="$!" echo "$SPICEPID" > $SPICEFILE - # Give time to connect - sleep 2 + # Fix window title and position + if which /usr/bin/xdotool &> /dev/null && [ ! -z "$spicestring" ]; then + local spicewait="0" + local windowid + local windowpid + local notify="0" - # Fix window title an position - if which /usr/bin/xdotool &> /dev/null; then + # Wait for the spice window to show up. This might take a while and we'll + # wait only a few times + while (( $spicewait <= 10 )); do + windowid="`xdotool search --name "$spicestring" 2> /dev/null`" + + if [ ! -z "$windowid" ]; then + # Get the SPICE PID + windowpid="`xprop -id $windowid | grep '_NET_WM_PID(CARDINAL)' | cut -d = -f 2 | sed -e 's/ //g'`" + + if [ ! -z "$windowpid" ] && [ "$windowpid" == "$SPICEPID" ]; then + break + else + windowid="" + windowpid="" + fi + fi + + # It's waiting too long, notify the user + if which awesome-client &> /dev/null && [ "$notify" == "0" ]; then + notify="1" + + echo "naughty.notify({title = \"KVMX:\", text =\"Starting GUI session for $VM\", timeout = 2})" | awesome-client + fi + + # Wait a bit and try again + sleep 1 + let spicewait++ + done + + # Set window position + # + # Configuration xclient_windowmove can be set either at kvmxconfig + # or as a user setting at ~/.config/kvmxconfig (which will affect all guests). if [ ! -z "$xclient_windowmove" ]; then #xdotool search --name "SPICEc:0" windowmove $xclient_windowmove - xdotool search --name "spice display 0:0" windowmove $xclient_windowmove + #xdotool search --name "spice display 0:0" windowmove $xclient_windowmove + #xdotool search --name "$spicestring" windowmove $xclient_windowmove + + if [ ! -z "$windowid" ]; then + xdotool windowmove $windowid $xclient_windowmove + fi fi + # Rename window, search by title version #xdotool search --name "SPICEc:0" set_window --name $VM - xdotool search --name "spice display 0:0" set_window --name $VM + #xdotool search --name "spice display 0:0" set_window --name $VM + #xdotool search --name "$spicestring" set_window --name $VM + + # Rename window, window ID version + if [ ! -z "$windowid" ]; then + xdotool set_window --name $VM $windowid + fi fi if [ "$ACTION" == "spice" ]; then @@ -357,20 +411,36 @@ function kvmx_up { # See http://wiki.qemu-project.org/Documentation/9psetup local shared="-fsdev local,id=shared,path=$shared_folder,security_model=none -device virtio-9p-pci,fsdev=shared,mount_tag=shared" elif [ ! -z "$shared_folders" ]; then + # Add a PCI bus for shared filesystems + # See https://www.qemu.org/docs/master/system/device-emulation.html + # https://www.suse.com/support/kb/doc/?id=000019383 + # https://unix.stackexchange.com/questions/588912/add-more-pci-slots-to-virtual-machine + # + # Perhaps could also be implemented with the PXB (PCI Expander Bridge): + # https://github.com/qemu/qemu/blob/master/docs/pci_expander_bridge.txt + local shared_bus="-device pci-bridge,bus=pci.0,addr=5,chassis_nr=1,id=shared.0" + local old_ifs="$IFS" local shared_item - local shared + local shared="$shared_bus" IFS="," for shared_item in $shared_folders; do local id="`echo $shared_item | cut -d ':' -f 1`" local shared_folder="`echo $shared_item | cut -d ':' -f 2`" local shared_folder_mountpoint="`echo $shared_item | cut -d ':' -f 3`" + local shared_folder_mode="`echo $shared_item | cut -d ':' -f 4`" + + if [ "$shared_folder_mode" == "ro" ]; then + shared_folder_mode=",readonly=on" + else + shared_folder_mode="" + fi # Get absolute path of shared folder relative to project path mkdir -p $shared_folder shared_folder="`cd $KVMX_PROJECT_FOLDER && cd $shared_folder &> /dev/null && pwd`" - shared="$shared -fsdev local,id=$id,path=$shared_folder,security_model=none -device virtio-9p-pci,fsdev=$id,mount_tag=$id" + shared="$shared -fsdev local,id=$id,path=$shared_folder,security_model=none${shared_folder_mode} -device virtio-9p-pci,fsdev=$id,mount_tag=$id,bus=shared.0" unset shared_folder unset shared_folder_mountpoint @@ -459,7 +529,7 @@ function kvmx_up { fi if [ -z "$shared_folder_msize" ]; then - shared_folders_msize="524288" + shared_folders_msize="33554432" fi if [ -z "$shared_folders_cache" ]; then @@ -545,7 +615,7 @@ function kvmx_up { # Otherwise any guest could open a spice connection to another guest using the host local IP (10.0.2.2) and the other guest spice port if [ -z "$spice" ] || [ "$spice" == "1" ]; then #spice_opts="-spice port=$PORT,addr=127.0.0.1,disable-ticketing,streaming-video=off,jpeg-wan-compression=never,playback-compression=off,zlib-glz-wan-compression=never,image-compression=off" - spice_opts="-spice unix,addr=$SPICESOCKET,disable-ticketing,streaming-video=off,jpeg-wan-compression=never,playback-compression=off,zlib-glz-wan-compression=never,image-compression=off" + spice_opts="-spice unix=on,addr=$SPICESOCKET,disable-ticketing=on,streaming-video=off,jpeg-wan-compression=never,playback-compression=off,zlib-glz-wan-compression=never,image-compression=off" spice_opts="$spice_opts -device virtio-serial-pci" spice_opts="$spice_opts -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0" spice_opts="$spice_opts -chardev spicevmc,id=spicechannel0,name=vdagent" @@ -591,39 +661,39 @@ function kvmx_up { # Run virtual machine, nohup approach # See https://en.wikipedia.org/wiki/Nohup#Overcoming_hanging - #nohup setsid kvm -m $memory -name $VM \ - # -chardev "socket,id=monitor,path=$MONITORFILE,server,nowait" -mon chardev=monitor,mode=readline \ - # -chardev "socket,id=serial0,path=$CONSOLEFILE,server,nowait" -device isa-serial,chardev=serial0 \ - # -smp $smp -cpu host \ - # $balloon \ - # $graphics $shared \ - # $image_opts \ - # $spice_opts \ - # $sound_opts \ - # $cdrom_opts \ - # $boot_opts \ - # $net_opts \ - # $rng_opts \ + #nohup setsid kvm -m $memory -name $VM \ + # -chardev "socket,id=monitor,path=$MONITORFILE,server=on,wait=off" -mon chardev=monitor,mode=readline \ + # -chardev "socket,id=serial0,path=$CONSOLEFILE,server=on,wait=off" -device isa-serial,chardev=serial0 \ + # -smp $smp -cpu host \ + # $balloon \ + # $graphics $shared \ + # $image_opts \ + # $spice_opts \ + # $sound_opts \ + # $cdrom_opts \ + # $boot_opts \ + # $net_opts \ + # $rng_opts \ # $qemu_opts &> $LOGFILE < /dev/null & # Run virtual machine, screen approach # This is more immune to hangups - screen $screen_log $LOGFILE -S kvmx-qemu-$VM -d -m kvm -m $memory -name $VM \ - -chardev "socket,id=monitor,path=$MONITORFILE,server,nowait" -mon chardev=monitor,mode=readline \ - -chardev "socket,id=serial0,path=$CONSOLEFILE,server,nowait" -device isa-serial,chardev=serial0 \ - -smp $smp -cpu host \ - $balloon \ - $graphics $shared \ - $image_opts \ - $spice_opts \ - $sound_opts \ - $cdrom_opts \ - $boot_opts \ - $net_opts \ - $rng_opts \ - $usb_opts \ - -pidfile $PIDFILE \ - -D $LOGFILE \ + screen $screen_log $LOGFILE -S kvmx-qemu-$VM -d -m kvm -m $memory -name $VM \ + -chardev "socket,id=monitor,path=$MONITORFILE,server=on,wait=off" -mon chardev=monitor,mode=readline \ + -chardev "socket,id=serial0,path=$CONSOLEFILE,server=on,wait=off" -device isa-serial,chardev=serial0 \ + -smp $smp -cpu host \ + $balloon \ + $graphics $shared \ + $image_opts \ + $spice_opts \ + $sound_opts \ + $cdrom_opts \ + $boot_opts \ + $net_opts \ + $rng_opts \ + $usb_opts \ + -pidfile $PIDFILE \ + -D $LOGFILE \ $qemu_opts # Only if nohup approach is being used @@ -701,15 +771,20 @@ function kvmx_up { local id="`echo $shared_item | cut -d ':' -f 1`" local shared_folder="`echo $shared_item | cut -d ':' -f 2`" local shared_folder_mountpoint="`echo $shared_item | cut -d ':' -f 3`" + local shared_folder_mode="`echo $shared_item | cut -d ':' -f 4`" # Get absolute path of shared folder relative to project path shared_folder="`cd $KVMX_PROJECT_FOLDER && cd $shared_folder &> /dev/null && pwd`" + if [ "$shared_folder_mode" == "ro" ]; then + shared_folder_mode=",ro" + fi + # Restore IFS for a while or kvmx_ssh won't work IFS="$old_ifs" echo "Mounting $shared_folder on $shared_folder_mountpoint ($id) on guest using 9p..." echo "sudo mkdir -p $shared_folder_mountpoint" | kvmx_ssh - echo "sudo mount -t 9p -o trans=virtio,msize=$shared_folders_msize $id $shared_folder_mountpoint -oversion=9p2000.L,posixacl,cache=$shared_folders_cache -o sync -o dirsync" | kvmx_ssh + echo "sudo mount -t 9p -o trans=virtio,msize=${shared_folders_msize}${shared_folder_mode} $id $shared_folder_mountpoint -oversion=9p2000.L,posixacl,cache=$shared_folders_cache -o sync -o dirsync" | kvmx_ssh IFS="," unset shared_folder @@ -1245,7 +1320,7 @@ function kvmx_rsync_to { DEST="$2" if [ -z "$ORIG" ]; then - echo "usage $BASENAME rsync_to $GUEST <orig> [dest]" + echo "usage $BASENAME rsync_to $VM <orig> [dest]" exit 1 fi @@ -1282,7 +1357,7 @@ function kvmx_rsync_from { DEST="$2" if [ -z "$ORIG" ]; then - echo "usage $BASENAME rsync_from $GUEST <orig> [dest]" + echo "usage $BASENAME rsync_from $VM <orig> [dest]" exit 1 fi @@ -2283,36 +2358,40 @@ function kvmx_xrandr { # Set screen resolution depending on which screen the spice session is currently located local id="`xdotool search --name $VM`" - # XrandR approach, matches the full screen size, not ideal when using - # multiple monitors/outputs or if the window size is smaller than the - # current screen size - #local screen="`xdotool getwindowgeometry $id | grep screen: | cut -d '(' -f 2 | cut -d : -f 2 | cut -d ')' -f 1 | sed -e 's/ //'`" - #local mode="`xrandr | grep "Screen ${screen}:" | cut -d , -f 2 | sed -e 's/ current //' -e 's/ //g' | tr 'x' ' '`" + if [ ! -z "$id" ]; then + # XrandR approach, matches the full screen size, not ideal when using + # multiple monitors/outputs or if the window size is smaller than the + # current screen size + #local screen="`xdotool getwindowgeometry $id | grep screen: | cut -d '(' -f 2 | cut -d : -f 2 | cut -d ')' -f 1 | sed -e 's/ //'`" + #local mode="`xrandr | grep "Screen ${screen}:" | cut -d , -f 2 | sed -e 's/ current //' -e 's/ //g' | tr 'x' ' '`" - # Pure xdotool approach, matches the current window size - # Better support for multiple monitors/outputs and for windows of arbitrary sizes - local mode="`xdotool getwindowgeometry $id | grep -i geometry: | cut -d : -f 2 | tr 'x' ' '`" + # Pure xdotool approach, matches the current window size + # Better support for multiple monitors/outputs and for windows of arbitrary sizes + local mode="`xdotool getwindowgeometry $id | grep -i geometry: | cut -d : -f 2 | tr 'x' ' '`" - if [ ! -z "$resolution_y_offset" ]; then - local x="`echo $mode | awk '{ print $1 }'`" - local y="`echo $mode | awk '{ print $2 }'`" + if [ ! -z "$resolution_y_offset" ]; then + local x="`echo $mode | awk '{ print $1 }'`" + local y="`echo $mode | awk '{ print $2 }'`" - mode="$x $(($y $resolution_y_offset))" + mode="$x $(($y $resolution_y_offset))" + fi fi fi - if [ -z "$xrandr_device" ]; then - xrandr_device="Virtual-0" - fi + if [ ! -z "$id" ]; then + if [ -z "$xrandr_device" ]; then + xrandr_device="Virtual-0" + fi - local line="`cvt $mode | tail -1 | sed -e 's/^Modeline//'`" - local name="`echo $line | awk '{ print $1 }'`" + local line="`cvt $mode | tail -1 | sed -e 's/^Modeline//'`" + local name="`echo $line | awk '{ print $1 }'`" - echo "Setting Modeline $line..." + echo "Setting Modeline $line..." - echo DISPLAY=:0 xrandr --newmode $line | kvmx_ssh - echo DISPLAY=:0 xrandr --addmode $xrandr_device $name | kvmx_ssh - echo DISPLAY=:0 xrandr --output $xrandr_device --mode $name | kvmx_ssh + echo DISPLAY=:0 xrandr --newmode $line | kvmx_ssh + echo DISPLAY=:0 xrandr --addmode $xrandr_device $name | kvmx_ssh + echo DISPLAY=:0 xrandr --output $xrandr_device --mode $name | kvmx_ssh + fi fi } @@ -2560,6 +2639,45 @@ function kvmx_growpart { kvmx_restart } +# Inotify dispatcher +function kvmx_inotify { + local watched="$1" + + shift + local command="$*" + + # Syntax check + if [ -z "$command" ]; then + echo "usage $BASENAME inotify $VM <watched> <command>" + echo "example: kvmx inotify $guest hostfolder make -C guestfolder compile" + exit 1 + fi + + # Check if watched exists + if [ ! -e "$watched" ]; then + echo "Not found: $watched" + exit 1 + fi + + local args + local event + + # Build arg list of events + if [ ! -z "$inotify_events" ]; then + for event in $inotify_events; do + args="$args -e $event" + done + fi + + # Inform user what's about to happen + echo "Watching $watched on guest \"$VM\" to exec \"$command\" upon changes..." + + # Dispatch + while inotifywait $args -r $watched; do + echo "$command" | kvmx_ssh + done +} + # Dispatch if type kvmx_$ACTION 2> /dev/null | grep -q "kvmx_$ACTION ()"; then __kvmx_initialize $* @@ -40,13 +40,30 @@ net="user" # Set this is you want to be able to share multiple folders between host and guest using 9p. # Needs ssh_support set to "y" and a workable SSH connection to the guest. -# Format: <id1>:<host-folder1>:<guest-mountpoint1>,<id2>:<host-folder2>:<guest-mountpoint2>[,...] +# Mode defaults to "rw"; set to "ro" to ensure volume is shared and mounted read-only. +# Format: <id1>:<host-folder1>:<guest-mountpoint1>[:mode1],<id2>:<host-folder2>:<guest-mountpoint2>[:mode2][,...] #shared_folders="shared1:.:/home/$user/code/$VM,shared2:$HOME/.local/share/app:/home/$user/.local/share/app" +#shared_folders="shared1:.:/home/$user/code/$VM,shared2:ro:$HOME/.local/share/app:/home/$user/.local/share/app:rw" -# Maximum packet size including any headers for shared folders using 9p -# See https://forums.lime-technology.com/topic/34691-9p-sharing-speed-not-what-i-expected/ +# Maximum packet size in bytex including any headers for shared folders using 9p +# In the past this was limited to 500kB: https://lwn.net/Articles/901523/ +# +# See https://wiki.qemu.org/Documentation/9psetup +# https://wiki.qemu.org/Documentation/9p +# https://www.kernel.org/doc/html/latest/filesystems/9p.html # https://github.com/clearcontainers/hyperstart/pull/25 -#shared_folders_msize="524288" +# https://issues.guix.gnu.org/47225 +# +# Examples: 4194304 bytes = 4MiB +# 16777216 bytes = 16MiB +# 33554432 bytes = 32MiB +# +# Depending on upstream support (kernel and virtio), the underlying drivers may +# cap this to a max, and give you the following message: +# +# 9pnet: Limiting 'msize' to 512000 as this is the maximum supported by transport virtio +# +#shared_folders_msize="33554432" # Shared folders caching # See https://www.kernel.org/doc/Documentation/filesystems/9p.txt @@ -59,18 +76,18 @@ net="user" # Folder to sync during provisioning in the format "/host/folder1 /guest/folder1,/host/folder2 /guest/folder2[,...]". # Needs ssh_support set to "y" and a workable SSH connection to the guest. -#provision_rsync="$KVMX_BASE/share/provision/ /usr/local/share/kvmx/provision/" #provision_rsync="puppet/ /etc/puppet/" +provision_rsync="$KVMX_BASE/share/provision/ /usr/local/share/kvmx/provision/" # Options for provision_rsync #provision_rsync_opts="--exclude=somefolder" # Absolute path for a provision script located inside the guest. # Needs ssh_support set to "y" and a workable SSH connection to the guest. -#provision_command="sudo apt-get update && sudo apt-get dist-upgrade -y && sudo apt-get autoremove -y && sudo apt-get clean" -#provision_command="/usr/local/share/kvmx/provision/debian/development && /etc/puppet/bin/provision && /etc/puppet/bin/deploy" -#provision_command="/usr/local/share/kvmx/provision/debian/development && /etc/puppet/bin/deploy" -#provision_command="/usr/local/share/kvmx/provision/debian/development && /home/$user/code/$VM/bin/custom-provisioner" +#provision_command="sudo apt-get update && sudo apt-get dist-upgrade -y && sudo apt-get autoremove -y && sudo apt-get clean && true" +#provision_command="/usr/local/share/kvmx/provision/debian/development $hostname $domain $mirror && /etc/puppet/bin/provision && /etc/puppet/bin/deploy" +#provision_command="/usr/local/share/kvmx/provision/debian/development $hostname $domain $mirror && /etc/puppet/bin/deploy" +#provision_command="/usr/local/share/kvmx/provision/debian/development $hostname $domain $mirror && /home/$user/code/$VM/bin/custom-provisioner" #provision_command="/usr/local/share/kvmx/provision/debian/development" #provision_command="/usr/local/share/kvmx/provision/debian/trashman" #provision_command="/usr/local/share/kvmx/provision/debian/desktop-basic" @@ -105,7 +122,7 @@ graphics="-vga qxl" vnc_client="virt-viewer" # SPICE support -spice="0" +spice="1" # Set this if you want to attach an spice client when the machine boots. run_spice_client="0" @@ -115,6 +132,14 @@ run_spice_client="0" #spice_client="virt-viewer" spice_client="spicy" +# Move the SPICE window client to a specific position in the desktop. +# +# Configuration xclient_windowmove can be set either at kvmxconfig +# or as a user setting at ~/.config/kvmxconfig (which will affect all guests). +# +# Example: move X11 client window below the WM bar +#xclient_windowmove="0 21" + # Set this if you want that kvmx-vdagent is triggered after the machine boots. kvmx_vdagent="0" @@ -264,3 +289,11 @@ bootloader="grub" #export QEMU_AUDIO_DRV="pa" #export QEMU_PA_SAMPLES="8192" #export QEMU_AUDIO_TIMER_PERIOD="99" + +# Inotify events listened by the "inotify" action +# +# See inotifywait(0) for the full list and description of all supported events. +# +# By default, exclude "access", "close", "close_write", "close_nowrite", "open" +# from the list of events +inotify_events="modify attrib moved_to moved_from move move_self create delete delete_self unmount" diff --git a/share/provision/debian/desktop-basic b/share/provision/debian/desktop-basic index 30c9ea3..2eeaf5d 100755 --- a/share/provision/debian/desktop-basic +++ b/share/provision/debian/desktop-basic @@ -46,10 +46,11 @@ apps/metadot/metadot deps-bundle desktop-basic # Additional packages echo "Installing additional desktop-basic packages..." -$APT_INSTALL xpra lightdm firejail xsel tigervnc-viewer +$APT_INSTALL xpra lightdm firejail xsel tigervnc-viewer alsa-utils pulseaudio -# See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=861744 -$APT_INSTALL torbrowser-launcher alsa-utils pulseaudio +# Tor Browser launcher +# Deprecated in favor of https://git.fluxo.info/utils-tor +#$APT_INSTALL torbrowser-launcher # System-wide configuration sudo cp $DIRNAME/files/desktop-basic/etc/lightdm/lightdm.conf /etc/lightdm/lightdm.conf @@ -76,6 +77,13 @@ fi # User configuration mkdir -p $HOME/.custom -if [ ! -e "$HOME/.custom/xsession" ]; then - cp $DIRNAME/files/desktop-basic/home/user/.custom/xsession $HOME/.custom/xsession -fi +# Only install the custom xsession config if it does not exist +#if [ ! -e "$HOME/.custom/xsession" ]; then +# cp $DIRNAME/files/desktop-basic/home/user/.custom/xsession $HOME/.custom/xsession +#fi + +# Always install the custom xsession config if it does not exist +# +# VMs with custom xsession procedures should use an additional +# $HOME/.custom/xsession-$HOSTNAME +cp $DIRNAME/files/desktop-basic/home/user/.custom/xsession $HOME/.custom/xsession diff --git a/share/provision/debian/messenger b/share/provision/debian/messenger index bdd8f7e..9b63a21 100755 --- a/share/provision/debian/messenger +++ b/share/provision/debian/messenger @@ -25,6 +25,7 @@ HOSTNAME="$1" DOMAIN="$2" MIRROR="$3" APT_INSTALL="sudo LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y" +CONFIG='PROGRAMS="signal-desktop"' # Provision the basic stuff $DIRNAME/desktop-basic $HOSTNAME $DOMAIN $MIRROR @@ -37,3 +38,8 @@ sudo trashman install signal-desktop # Install Gajim $APT_INSTALL gajim gajim-omemo + +# Startup +if ! grep -q "^$CONFIG$" $HOME/.custom/xsession-${HOSTNAME} 2> /dev/null; then + echo "$CONFIG" >> $HOME/.custom/xsession-${HOSTNAME} +fi diff --git a/share/provision/debian/tor-browser b/share/provision/debian/tor-browser index 05218cd..baf231d 100755 --- a/share/provision/debian/tor-browser +++ b/share/provision/debian/tor-browser @@ -30,7 +30,7 @@ APT_INSTALL="sudo LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y" $DIRNAME/web-basic $HOSTNAME $DOMAIN $MIRROR # Use a stacked window manager to reduce browser fingerprinting -$DIRNAME/openbox +$DIRNAME/openbox $HOSTNAME $DOMAIN $MIRROR # Install Tor Browser # No need to install tor-browser during provision, as the tor-browser script diff --git a/share/provision/debian/web-basic b/share/provision/debian/web-basic index 2d3c06d..8956a80 100755 --- a/share/provision/debian/web-basic +++ b/share/provision/debian/web-basic @@ -29,6 +29,10 @@ APT_INSTALL="sudo LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y" # Provision the basic stuff $DIRNAME/desktop-basic $HOSTNAME $DOMAIN $MIRROR +# Aditional metadot modules +apps/metadot/metadot load-bundle web-basic +apps/metadot/metadot deps-bundle web-basic + # Additional packages echo "Installing additional web packages..." $APT_INSTALL firefox-esr chromium wget diff --git a/share/provision/debian/webserver b/share/provision/debian/webserver index 650452f..9098007 100755 --- a/share/provision/debian/webserver +++ b/share/provision/debian/webserver @@ -18,5 +18,13 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +# Parameters +DIRNAME="`dirname $0`" +BASENAME="`basename $0`" +HOSTNAME="$1" +DOMAIN="$2" +MIRROR="$3" + +# Run sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get autoremove -y && sudo apt-get clean sudo apt-get install -y apache2 |