{"id":18320330,"url":"https://github.com/rufiorogue/vmvm","last_synced_at":"2026-03-01T23:32:44.455Z","repository":{"id":72668176,"uuid":"565575710","full_name":"rufiorogue/vmvm","owner":"rufiorogue","description":"Bootstrap and run QEMU VM from YAML specification","archived":false,"fork":false,"pushed_at":"2025-05-11T04:05:36.000Z","size":148,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-23T21:19:02.153Z","etag":null,"topics":["qemu","yaml","yaml-configuration"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rufiorogue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-11-13T20:41:16.000Z","updated_at":"2025-05-11T04:05:39.000Z","dependencies_parsed_at":"2024-12-23T08:42:04.923Z","dependency_job_id":"390e23dd-0303-4ae9-a161-ad9e9903675b","html_url":"https://github.com/rufiorogue/vmvm","commit_stats":null,"previous_names":["rufiorogue/vmvm","roovio/vmvm"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/rufiorogue/vmvm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufiorogue%2Fvmvm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufiorogue%2Fvmvm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufiorogue%2Fvmvm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufiorogue%2Fvmvm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rufiorogue","download_url":"https://codeload.github.com/rufiorogue/vmvm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rufiorogue%2Fvmvm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29987698,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T22:42:38.399Z","status":"ssl_error","status_checked_at":"2026-03-01T22:41:51.863Z","response_time":124,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["qemu","yaml","yaml-configuration"],"created_at":"2024-11-05T18:15:55.933Z","updated_at":"2026-03-01T23:32:44.449Z","avatar_url":"https://github.com/rufiorogue.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# VMVM - a user friendly QEMU frontend\n\nRunning QEMU is hard for mere mortals. It has a lot of options and even simplest tasks require passing\na lot of them to fully define the virtual environment. With this app a lot of complexity can be hidden\naway under a simple facade of a small config file.\n\n## Features\n\n- Command-line interface to run QEMU and dependent processes from shell\n- YAML file to configure the virtual machine\n- Options for CPU, RAM, network, disk, EFI, SecureBoot, TPM for Windows 11, and more\n- Auto-selection of machine type and default features based on architecture\n- Support x86_64, i386 and aarch64 architectures\n\n## Dependencies\n\n- QEMU\n- Python 3.10+\n- pyyaml\n\n## Installation\n\n### For Python Package\nRun `poetry build -v -n` to build the Python package.\n\n### For Arch Linux Package\nRun `makepkg -sri` to build and install the Arch Linux package.\n\n## Usage\n\nFirst you need to create a YAML configuration file named `vmconfig.yml`,\npresumably in a dedicated directory for the VM but this is not required.\n\nHere is an example of a configuration file:\n\n```yaml\nprototype: w10\nname: windows10\ncpus: 4\nram: 8G\ndisk: system.qcow2\nos_install:\n    - Win10_21H2_English_x64.iso\n    - virtio-win-0.1.240.iso\n```\n\nThen invoke `vmvm` as follows:\n\n```\nvmvm ACTION [CURRENT_DIR]\n```\n\nCURRENT_DIR is path to `vmconfig.yml` location. If not specified, current working directory is used.\nNote that all non-absolute paths in the config are relative to `vmconfig.yml` location.\n\n| Action    | Description |\n| --------- | ----------- |\n| `init`    | Create an image file for the first HDD in the config (if does not exist). In the example above `system.qcow2` will be created |\n| `install` | Run VM, boot from CD |\n| `run`     | Run VM, boot from first HDD |\n| `console` | open an interactive QMP shell |\n\n`install` and `run` both run the VM however the difference is how the boot device is selected.\n\n`install`:\n- first boot from CD, after reboot - from first HDD\n- exists merely for convenience. Typically you use it only once, to install the OS\n\n`run`:\n- always boot from first HDD\n- if `need_cd` = `false` (default) then `os_install` is ignored and thus no CD images are mounted\n- if `need_cd` = `true` then `os_install` images are mounted\n\n## Configuration Options\n\n### `name`\n(Required) Name of your virtual machine\n\n### `prototype`\n(Optional) Select a virtual hardware set tuned for particular guest OS.\n\nValues: `default` (x86_64/aarch64), `linux` (x86_64/aarch64), `linux-x86_64-3daccel` (Virgl support),`w10`, `w11`, `wxp`, `w2k`, `w98`.\n\nIf not specified, `default` for current arch is used.\n\n### `cpus`\n(Optional) Number of CPUs for your virtual machine\n\n### `ram`\n(Optional) Amount of RAM for your virtual machine. You can specify this in gigabytes (G) or megabytes (M).\n\n### `arch`\n(Optional) architecture: same as suffix part of `qemu-system-...`.\n\nValues: `i386`, `x86_64`, `aarch64`\n\n### `efi`\n(Optional) enable EFI.  `true`=EFI, `false`=BIOS\n\n### `secureboot`\n(Optional) enable EFI SecureBoot (`OVMF_CODE.secboot.fd`). Has no effect unless `efi` is set to `true`\n\n### `tpm`\n(Optional) software emulation of Trusted Platform Module 2.0.\nRequires [swtpm](https://www.qemu.org/docs/master/specs/tpm.html#the-qemu-tpm-emulator-device) to be installed\n\n### `bootmenu`\n(Optional) enable boot menu\n\n### `floppy`\n(Optional) floppy image file\n\n### `disk` (alias `disks`)\n(Required) Disk image file. Can also be /dev/... file to pass through a host block device.\n(Optional) `disks` is an alias for `disk`. Both can be a single path spec or list of path specs.\n\nSupports discard (trim) requests on the blockdev, Execute `fstrim -av` on the guest to relinquish the free space.\n\n### `disk_virtio`\n(Optional) for disk emulation, specify `blk` to use `virtio-blk`, `scsi` to use `virtio-scsi`\nor `none` to disable virtio and emulate IDE controller instead. Applicable only to image file based disks.\n`blk` theoretically yields best performance. `scsi` is best for large disk arrays. `none` for legacy OSes.\n\n**Performance tip:** `disk_virtio` = `blk` will create one controller for each disk on PCIe bus,\nso do not use `blk` if more than a few disks. Use `scsi` in such case.\n\n### `os_install`\n(Optional) mount these images if action is `install`. Can be a single path spec or list of path specs\n\n### `need_cd`\n(Optional) always have ISO images mounted, even if action is not `install`.\n\n### `usb`\n(Optional) USB Passthrough. Can be a single device spec or list of specs. Device spec is `vendor:product`.\n\nExample: `usb: 1234:5678`\n\nQEMU user must be able to rw the device. One way to achieve this is to create a file `/etc/udev/rules.d/50-usbpassthrough.rules`\n\n```udev\nSUBSYSTEM==\"usb\", ATTR{idVendor}==\"xxxx\", ATTR{idProduct}==\"xxxx\", MODE=\"0666\"\n```\nand then run\n```\nsudo udev trigger\n```\n\n### `pci`\n(Optional) PCIe Passthrough. Can be a single device spec or list of specs. Device spec is `\u003cbus number\u003e:\u003cdevice number\u003e` notation such as `09:00`.\nAt the moment only GPU devices are supported. Multiple devices with same combination of vendor/product are unsupported.\n\nSome preparations must be in place before attempting PCIe passthrough:\n\n1. Ensure the PCIe device is exclusively controlled by vfio-pci module\n\n1.1. Find iommu group, bus/device address and vendor/product of the PCIe device:\n```\n#!/bin/bash\nshopt -s nullglob\nfor g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do\n    echo \"IOMMU Group ${g##*/}:\"\n    for d in $g/devices/*; do\n        echo -e \"\\t$(lspci -nns ${d##*/})\"\n    done;\ndone;\n```\n\nThe output will be something like:\n```\nIOMMU Group 2:\n\t00:03.0 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-1fh) PCIe Dummy Host Bridge [1022:1452]\n\t00:03.1 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) PCIe GPP Bridge [1022:1453]\n\t09:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK106GL [Quadro K4000] [10de:11fa] (rev a1)\n\t09:00.1 Audio device [0403]: NVIDIA Corporation GK106 HDMI Audio Controller [10de:0e0b] (rev a1)\n```\nIn this case we want to passthrough `09:00.0` and `09:00.1` devices with vendor/product `10de:11fa` and `10de:0e0b` respectively.\n\n1.2. Add to kernel parameters\n1.2.1. For AMD processors:\n```\namd_iommu=pt\n```\n1.2.2. For Intel processors:\n```\nintel_iommu=pt\n```\n\n1.3. Edit `/etc/modprobe.d/vfio.conf`\n```\noptions vfio-pci ids=10de:11fa,10de:0e0b\nsoftdep snd_hda_intel pre: vfio-pci\nsoftdep drm pre: vfio-pci\nsoftdep nvidia pre: vfio-pci\nsoftdep nouveau pre: vfio-pci\n```\n\n1.4. vfio dev file permissions are too strict by default. To fix this, first add the running user to `kvm` group, then create file `/etc/udev/rules.d/50-vfio.rules`\n```\nSUBSYSTEM==\"vfio\", OWNER=\"root\", GROUP=\"kvm\"\n```\nand then run\n```\nsudo udev trigger\n```\n\n1.5. Extract GPU VBIOS. From the current directory of the vm (where `vmconfig.yml` is located):\n```\n# echo 1 \u003e /sys/bus/pci/devices/0000\\:09:00.0/rom\n# cat /sys/bus/pci/devices/0000\\:09:00.0/rom \u003e vbios.rom\n# echo 0 \u003e /sys/bus/pci/devices/0000\\:09:00.0/rom\n```\n\nFor more detail refer to the [venerable article](https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF) in ArchWiki.\n\n\n### `share_dir_as_fsd`\n(Optional) Share a host directory with [virtiofsd](https://virtio-fs.gitlab.io/index.html).\nUse with Linux guests. This method provides best performance as well as other useful virtualisation features.\n\nYou can mount the directory on the guest as follows:\n```\nmount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt/share\n```\n\nExample: `share_dir_as_fsd: /home/user/shared`.  Path can be relative to current directory.\n\n### `share_dir_as_fat`\n(Optional) Emulate a FAT disk with contents from a directory tree.\nSee [documentation](https://www.qemu.org/docs/master/system/images.html#virtual-fat-disk-images).\nDo not use non-ASCII filenames or attempt to write to the FAT directory on the host systemwhile accessing it with the guest system.\n\n### `share_dir_as_floppy`\n(Optional) Emulate a floppy with contents from a directory tree.\nSee [documentation](https://www.qemu.org/docs/master/system/images.html#virtual-fat-disk-images).\nDo not use non-ASCII filenames or attempt to write to the FAT directory on the host system while accessing it with the guest system.\n\n### `nic`\n(Optional) allows to override or disable default network interface card selected by machine type.\n`none` disables network card. `virtio` selects `virtio-net-pci` card.\nYou can also specify exact model name (see `qemu-system-\u003cARCH\u003e -device help` for list of network devices)\n\n### `nic_forward_ports`\n(Optional) Forward local port X to guest port Y.\n\nExample:\n```yaml\nnic_forward_ports:\n    - host: 2222\n    guest: 22\n```\nthen on the host you can do:\n```\nssh localhost -p 2222\n```\n\n### `gpu`\n(Optional) GPU model (see `qemu-system-\u003cARCH\u003e -device help` and \"Display devices\" section).\n\n### `display`\n(Optional) QEMU UI to use (see `qemu-system-\u003cARCH\u003e -display help`).\n\nTypical values: `gtk`, `sdl`, `none`.\n\n`none` disables UI entirely so you have to rely on other methods to obtain graphical output of the VM.\nsuch as SPICE (TODO: or external monitor, if PCI passthrough is configured).\nNote that GPU hardware in the VM is not affected by this setting, i.e. if `display` is set to `none`\nthe GPU is operating, but you cannot easily see the graphics because there is no window.\n\n\n### `sound`\n(Optional) Soundcard type.\n\nTypical values: `hda`, `ac97`, `sb16`, `none`.\n\n### `spice`\n(Optional) SPICE server config.\n- `unix`: use Unix socket. The path to the socket then will be `/run/user/\u003cUID\u003e/qemu/\u003cmachine name\u003e/spice.sock`.\n- `auto`: use TCP connection, find the next available port number starting from 5900.\n- `(port)`: use TCP connection, specify the port number explicitly.\n- `none`: disables SPICE entirely. Required if using a 3D-accelerated GPU such as `virtio-vga-gl`.\n\n### `control_socket`\n(Optional) enable QMP control socket `/run/user/\u003cUID\u003e/qemu/\u003cmachine name\u003e/qmp.sock`. Allows to control the VM with either\nin-built QMP console mode or dedicated clients like\n[`qmp-shell`](https://qemu.readthedocs.io/projects/python-qemu-qmp/en/latest/man/qmp_shell.html) or `qmp-tui`\nfrom [`qemu.qmp`](https://pypi.org/project/qemu.qmp/) package.\n\n## Ejecting / changing CD images\n\nYou can eject or change image for by using QEMU monitor:\n\n```\n(qemu) change \u003cdevice\u003e \u003cpath to image\u003e\n```\n\nIf you run as `install` action and have `os_install` option set then you can use QEMU monitor command above to change the ISO image.\nThe CD-ROM devices have names like `cddev0`, `cddev1`, etc. Sometimes QEMU monitor does not see these `cddevX` devices due to the bug,\nif so happens use `qmp-shell`.\n\nIf you don't run as `install` then (since `os_install` is ignored) you are left with any default CD-ROM device present in the machine.\nMachine `PC` doesn't allow (or so it seems) to add a ide-cd device without the respective img file node backend, so you are out of luck.\nMachine `Q35` has a default device `ide2-cd0` that is always present even if no image specified on the command line.\nTo view available block devices type in QEMU monitor:\n\n```\n(qemu) info block\n```\n\n## Interactive QMP console\n\nAn interactive QMP shell is opened by specifying action `console`. For it to work `control_socket` option must also be set to `true` in the config.\n\nUnder the hood it is implemented as an integrated `qmp-shell` from `qemu.qmp` project.\nFor console command syntax reference check [qmp-shell](https://qemu.readthedocs.io/projects/python-qemu-qmp/en/latest/man/qmp_shell.html) man page.\n\nFor detailed QMP commands reference check the [official QEMU documentation](https://www.qemu.org/docs/master/interop/qemu-qmp-ref.html).\n\n\n## Handy SMB server\n\nAs an alternative to `share_...` config options,  a docker compose is provided in subdirectory `smb` to spin up a SMB server,\nto be accessed from guest. Refer to the respective [README](smb/README.md).\n\n## Development\n\n### Setting up the environment\n\n1. Install the project dependencies using Poetry: `poetry install --no-root`.\n2. If some changes are done in `pyproject.toml`, then `poetry lock` should be used to generate an updated `poetry.lock` file.\n3. After making changes in the code, execute `poetry install` to install the package in a virtual environment.\n4. Perform tests to validate implemented features.\n\n### Testing\n\nWithin the root directory:\n\n1. Run the main program: `poetry run vmvm ...`.\n2. Run tests: `pytest`","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frufiorogue%2Fvmvm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frufiorogue%2Fvmvm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frufiorogue%2Fvmvm/lists"}