diff --git a/_dev/conf.py b/_dev/conf.py index 9f311f45..c643b145 100644 --- a/_dev/conf.py +++ b/_dev/conf.py @@ -186,7 +186,7 @@ htmlhelp_basename = 'QubesOSdev' # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - 'python': ('http://docs.python.org/', None), + 'python': ('https://docs.python.org/', None), # 'core-admin': ('https://dev.qubes-os.org/projects/core-admin/en/latest/', None), } diff --git a/developer/building/development-workflow.md b/developer/building/development-workflow.md index dd72699a..5f1581bd 100644 --- a/developer/building/development-workflow.md +++ b/developer/building/development-workflow.md @@ -12,42 +12,41 @@ title: Development workflow A workflow for developing Qubes OS+ -First things first, setup [QubesBuilder](/doc/qubes-builder/). This guide -assumes you're using qubes-builder to build Qubes. +To begin, setup [QubesBuilder](/doc/qubes-builder-v2/). This guide +assumes you're using qubes-builder v2 to build Qubes. ## Repositories and committing Code -Qubes is split into a bunch of git repos. These are all contained in the -`qubes-src` directory under qubes-builder. Subdirectories there are separate -components, stored in separate git repositories. +Qubes source code is split into many git repos. These are all contained in the +`artifacts/sources` directory under qubes-builder. Subdirectories there are +separate components, stored in separate git repositories. The best way to write and contribute code is to create a git repo somewhere -(e.g., github) for the repo you are interested in editing (e.g., +(e.g., GitHub) for the repo you are interested in editing (e.g., `qubes-manager`, `core-agent-linux`, etc). To integrate your repo with the rest of Qubes, cd to the repo directory and add your repository as a remote in git **Example:** ~~~ -$ cd qubes-builder/qubes-src/qubes-manager -$ git remote add abel git@github.com:abeluck/qubes-manager.git +$ cd qubes-builder/artifacts/sources/qubes-manager +$ git remote add abel git@GitHub.com:abeluck/qubes-manager.git ~~~ You can then proceed to easily develop in your own branches, pull in new -commits from the dev branches, merge them, and eventually push to your own repo -on github. +commits from the dev branches, merge them, and eventually push to your own repo. When you are ready to submit your changes to Qubes to be merged, push your changes, then create a signed git tag (using `git tag -s`). Finally, send a -letter to the Qubes listserv describing the changes and including the link to -your repository. You can also create pull request on github. Don't forget to -include your public PGP key you use to sign your tags. +letter to the Qubes listserv describing the changes, and including a link to +your repository. If you are using GitHub you can instead create a pull request. +Don't forget to include the public PGP key you use to sign your tags. ### Kernel-specific notes #### Prepare fresh version of kernel sources, with Qubes-specific patches applied -In qubes-builder/qubes-src/linux-kernel: +In `qubes-builder/artifacts/sources/linux-kernel`: ~~~ make prep @@ -66,7 +65,7 @@ drwxr-xr-x 6 user user 4096 Nov 21 20:48 kernel-3.4.18/linux-obj #### Go to the kernel tree and update the version -In qubes-builder/qubes-src/linux-kernel: +In `qubes-builder/artifacts/sources/linux-kernel`: ~~~ cd kernel-3.4.18/linux-3.4.18 @@ -74,14 +73,14 @@ cd kernel-3.4.18/linux-3.4.18 #### Changing the config -In kernel-3.4.18/linux-3.4.18: +In `kernel-3.4.18/linux-3.4.18`: ~~~ cp ../../config .config make oldconfig ~~~ -Now change the configuration. For example, in kernel-3.4.18/linux-3.4.18: +Now change the configuration. For example, in `kernel-3.4.18/linux-3.4.18`: ~~~ make menuconfig @@ -117,9 +116,7 @@ vi series.conf #### Building RPMs -TODO: Is this step generic for all subsystems? - -Now it is a good moment to make sure you have changed kernel release name in +Now is a good moment to make sure you have changed the kernel release name in rel file. For example, if you change it to '1debug201211116c' the resulting RPMs will be named 'kernel-3.4.18-1debug20121116c.pvops.qubes.x86\_64.rpm'. This will help @@ -131,34 +128,23 @@ your changes locally. To actually build RPMs, in qubes-builder: ~~~ -make linux-kernel +./qb -c linux-kernel package fetch prep build ~~~ -RPMs will appear in qubes-src/linux-kernel/pkgs/fc20/x86\_64: +RPMs will appear in +`artifacts/repository/destination_name/package_name` +(for example `artifacts/repository/host-fc37/linux-kernel-6.6.31-1.1/` -~~~ --rw-rw-r-- 1 user user 42996126 Nov 17 04:08 kernel-3.4.18-1debug20121116c.pvops.qubes.x86_64.rpm --rw-rw-r-- 1 user user 43001450 Nov 17 05:36 kernel-3.4.18-1debug20121117a.pvops.qubes.x86_64.rpm --rw-rw-r-- 1 user user 8940138 Nov 17 04:08 kernel-devel-3.4.18-1debug20121116c.pvops.qubes.x86_64.rpm --rw-rw-r-- 1 user user 8937818 Nov 17 05:36 kernel-devel-3.4.18-1debug20121117a.pvops.qubes.x86_64.rpm --rw-rw-r-- 1 user user 54490741 Nov 17 04:08 kernel-qubes-vm-3.4.18-1debug20121116c.pvops.qubes.x86_64.rpm --rw-rw-r-- 1 user user 54502117 Nov 17 05:37 kernel-qubes-vm-3.4.18-1debug20121117a.pvops.qubes.x86_64.rpm -~~~ +### Useful [QubesBuilder](/doc/qubes-builder-v2/) commands -### Useful [QubesBuilder](/doc/qubes-builder/) commands - -1. `make check` - will check if all the code was committed into repository and -if all repository are tagged with signed tag. -2. `make show-vtags` - show version of each component (based on git tags) - -mostly useful just before building ISO. **Note:** this will not show version -for components containing changes since last version tag. -3. `make push` - push change from **all** repositories to git server. You must -set proper remotes (see above) for all repositories first. -4. `make prepare-merge` - fetch changes from remote repositories (can be -specified on commandline via GIT\_SUBDIR or GIT\_REMOTE vars), (optionally) -verify tags and show the changes. This do not merge the changes - there are -left for review as FETCH\_HEAD ref. You can merge them using `git merge -FETCH_HEAD` (in each repo directory). Or `make do-merge` to merge all of them. +1. `./qb package diff` - show uncommitted changes +2. ` ./qb repository check-release-status-for-component` and +`./qb repository check-release-status-for-template` - show version of each + component/template (based on git tags) +3. `./qb package sign` - sign built packages +4. `./qb package publish` and `./qb package upload` - publish signed packages + and upload published + repository ## Copying Code to dom0 @@ -297,12 +283,12 @@ if [ "$1" = "tb" ]; then exit $? fi -git remote add $1 git@github.com:$1/qubes-`basename $PWD` +git remote add $1 git@GitHub.com:$1/qubes-`basename $PWD` ~~~ It should be executed from component top level directory. This script takes one argument - remote name. If it is `tb`, then it creates qrexec-based git remote -to `testbuilder` VM. Otherwise it creates remote pointing at github account of +to `testbuilder` VM. Otherwise it creates remote pointing at GitHub account of the same name. In any case it points at repository matching current directory name. @@ -321,7 +307,7 @@ current and current-testing). ### RPM packages - yum repo -In source VM, grab [linux-yum](https://github.com/QubesOS/qubes-linux-yum) repository (below is assumed you've made it in +In source VM, grab [linux-yum](https://GitHub.com/QubesOS/qubes-linux-yum) repository (below is assumed you've made it in `~/repo-yum-upload` directory) and replace `update_repo.sh` script with: ~~~ @@ -337,7 +323,7 @@ find -type f -name '*.rpm' -delete qrexec-client-vm $VMNAME local.UpdateYum ~~~ -In target VM, setup actual yum repository (also based on [linux-yum](https://github.com/QubesOS/qubes-linux-yum), this time +In target VM, setup actual yum repository (also based on [linux-yum](https://GitHub.com/QubesOS/qubes-linux-yum), this time without modifications). You will also need to setup some gpg key for signing packages (it is possible to force yum to install unsigned packages, but it isn't possible for `qubes-dom0-update` tool). Fill `~/.rpmmacros` with @@ -417,7 +403,7 @@ Remember to also import gpg public key using `rpm --import`. Steps are mostly the same as in the case of yum repo. The only details that differ: -- use [linux-deb](https://github.com/QubesOS/qubes-linux-deb) instead of [linux-yum](https://github.com/QubesOS/qubes-linux-yum) as a base - both in source and target VM +- use [linux-deb](https://GitHub.com/QubesOS/qubes-linux-deb) instead of [linux-yum](https://GitHub.com/QubesOS/qubes-linux-yum) as a base - both in source and target VM - use different `update_repo.sh` script in source VM (below) - use `local.UpdateApt` qrexec service in target VM (code below) - in target VM additionally place `update-local-repo.sh` script in repository dir (code below) diff --git a/developer/building/qubes-builder-details.md b/developer/building/qubes-builder-details.md index f3582284..1f5e9f3f 100644 --- a/developer/building/qubes-builder-details.md +++ b/developer/building/qubes-builder-details.md @@ -10,6 +10,12 @@ ref: 65 title: Qubes builder details --- + + + Components Makefile.builder file -------------------------------- diff --git a/developer/building/qubes-builder-v2.md b/developer/building/qubes-builder-v2.md new file mode 100644 index 00000000..2ad60e9f --- /dev/null +++ b/developer/building/qubes-builder-v2.md @@ -0,0 +1,166 @@ +--- +lang: en +layout: doc +permalink: /doc/qubes-builder-v2/ +redirect_from: +- /en/doc/qubes-builder-v2/ +- /doc/QubesBuilder2/ +- /wiki/QubesBuilder2/ +ref: 311 +title: Qubes builder v2 +--- + +This is a brief introduction to using Qubes Builder v2 to work with Qubes OS +sources. It will walk you through installing and configuring Builder v2, and +using it to fetch and build Qubes OS packages. + +For details and customization, use [Qubes OS v2 builder documentation](https://github.com/QubesOS/qubes-builderv2/). + +# Overview + +In the second generation of Qubes OS builder, container or disposable qube +isolation is used to perform every stage of the build and release process. +From fetching sources to building, everything is executed inside an isolated +*cage* (either a disposable or a container) using an *executor*. For every +command that needs to perform an action on sources, like cloning and +verifying Git repos, rendering a SPEC file, generating SRPM or Debian +source packages, a new cage is used. Only the signing, publishing, and +uploading stages are executed locally outside a cage. + + +# Setup + +This is a simple setup using a docker executor. This is a good default choice; +if you don't know which executor to use, use docker. + +1. First, decide what qube you are going to use when working with Qubes + Builder v2. It can be an AppVM or a Standalone qube, with some steps + different between the two. + +2. Installing dependencies + + - If you want to use an app qube for developing, install dependencies in the template. + If you are using a standalone, install them in the qube itself. + Dependencies are specified in `dependencies-*. + txt` files in the main builder directory, and you can install them easily + in the following ways: + 1. for Fedora, use: + + ```shell + $ sudo dnf install $(cat dependencies-fedora.txt) + $ test -f /usr/share/qubes/marker-vm && sudo dnf install qubes-gpg-split + ``` + 2. for Debian (note: some Debian packages require Debian version 13 or + later), use: + + ```shell + $ sudo apt install $(cat dependencies-debian.txt) + $ test -f /usr/share/qubes/marker-vm && sudo apt install qubes-gpg-split + ``` + + If you have installed dependencies in the template, close it, and + (re)start the development qube. + +3. Clone the qubes-builder v2 repository into a location of your choice: + + ```shell + git clone https://github.com/QubesOS/qubes-builderv2 + cd qubes-builderv2/ + ``` + +4. If you haven't previously used docker in the current qube, you need to set up + some permissions. In particular, the user has to be added to the `docker` + group: + + ```shell + $ sudo usermod -aG docker user + ``` + Next, **restart the qube**. + +5. Finally, you need to generate a docker image: + + ```shell + $ tools/generate-container-image.sh docker + ``` + + In an app qube, as `/var/lib/docker` is not persistent by default, you also + need to use [bind-dirs](/doc/bind-dirs/) to avoid repeating this step after reboot, adding + the following to the `/rw/config/qubes-bind-dirs.d/docker.conf` file in + this qube: + + ``` + binds+=( '/var/lib/docker' ) + ``` + +# Configuration + +To use Qubes OS Builder v2, you need to have a `builder.yml` configuration file. +You can use one of the sample files from the `example-configs/` directory; for a +more readable `builder.yml`, you can also include one of the files from that +directory in your `builder.yml`. An example `builder.yml` is: + +``` +# include configuration relevant for the current release +include: +- example-configs/qubes-os-r4.2.yml + +# which repository to use to fetch sources +use-qubes-repo: + version: 4.2 + testing: true + +# each package built will have local build number appended to package release +# number. It makes it easier to update in testing environment +increment-devel-versions: true + +# reduce output +debug: false + +# this can be set to true if you do not want sources to be automatically +# fetched from git +skip-git-fetch: false + +# executor configuration +executor: + type: docker + options: + image: "qubes-builder-fedora:latest" +``` + + +# Using Builder v2 + +To fetch sources - in this example, for the `core-admin-client` package, you +can use the following command: + +```shell +$ ./qb -c core-admin-client package fetch +``` + +This will fetch the sources for the listed package and place them in +`artifacts/sources` directory. + +To build a package (from sources in the `artifacts/sources` directory), use: + +```shell +$ ./qb -c core-admin-client package fetch prep build +``` + +or, if you want to build for a specific target (`host-fc37` is a `dom0` +using Fedora 37, `vm-fc40` would be a qube using Fedora 40 etc.), use: + +```shell +$ ./qb -c core-admin-client -d host-fc37 package fetch prep build +``` + +If you want to fetch the entire Qubes OS source use the following: + +```shell +$ ./qb package fetch +``` + +**caution**: some repositories might have additional requirements. You can +disable repositories that are not needed in the `example-configs/*.yml` +file you are using by commenting them out. In particular, `python-fido2`, +`lvm` and `windows`-related repositories have special requirements. + diff --git a/developer/building/qubes-builder.md b/developer/building/qubes-builder.md index 035a36d3..58573dea 100644 --- a/developer/building/qubes-builder.md +++ b/developer/building/qubes-builder.md @@ -10,6 +10,12 @@ ref: 64 title: Qubes builder --- + + **Note: See [ISO building instructions](/doc/qubes-iso-building/) for a streamlined overview on how to use the build system.** diff --git a/developer/building/qubes-iso-building.md b/developer/building/qubes-iso-building.md index fe9fb452..7b131bed 100644 --- a/developer/building/qubes-iso-building.md +++ b/developer/building/qubes-iso-building.md @@ -12,6 +12,12 @@ ref: 63 title: Qubes ISO building --- + + Build Environment ----------------- diff --git a/developer/code/code-signing.md b/developer/code/code-signing.md index d22c3cf8..8074840d 100644 --- a/developer/code/code-signing.md +++ b/developer/code/code-signing.md @@ -65,7 +65,9 @@ Currently, [these](https://github.com/marmarek/signature-checker/blob/master/che In the example below, we will use `keyserver.ubuntu.com`. -Replace 6E2F4E7AF50A5827 with your key ID, which is the last 8 hex digits of the long number in the second line of the output above: +Replace 6E2F4E7AF50A5827 with your key ID, preferably the **long keyID** +which is the last 16 hex digits of the long number in the second line +of the output above: ``` pub rsa3072 2021-12-30 [SC] [expires: 2023-12-30] 87975838063F97A968D503266E2F4E7AF50A5827 @@ -76,11 +78,6 @@ $ gpg --send-keys --keyserver hkps://keyserver.ubuntu.com 6E2F4E7AF50A5827 gpg: sending key 6E2F4E7AF50A5827 to hkps://keyserver.ubuntu.com ``` -``` -$ gpg --send-keys --keyserver hkps://keyserver.ubuntu.com 6E2F4E7AF50A5827 -gpg: sending key 6E2F4E7AF50A5827 to hkps://keyserver.ubuntu.com -``` - ## Using PGP with Git If you're submitting a patch via GitHub (or a similar Git server), please sign @@ -147,9 +144,11 @@ Although GitHub adds a little green `Verified` button next to the commit, the [s 1. Is the commit signed? If the commit is not signed, you can see the message + > policy/qubesos/code-signing — No signature found 2. If the commit is signed, the key is downloaded from a GPG key server. If you can see the following error message, please check if you have uploaded the key to a key server. + > policy/qubesos/code-signing — Unable to verify (no valid key found) ### No Signature Found diff --git a/developer/code/source-code.md b/developer/code/source-code.md index 85e5cf13..83173e6c 100644 --- a/developer/code/source-code.md +++ b/developer/code/source-code.md @@ -60,6 +60,7 @@ method you choose, you must [sign your code](/doc/code-signing/) before it can b * **Preferred**: Use GitHub's [fork & pull requests](https://guides.github.com/activities/forking/). + Opening a pull request on GitHub greatly eases the code review and tracking process. In addition, especially for bigger changes, it's a good idea to send a message to the [qubes-devel mailing list](/support/#qubes-devel) in order to notify people who diff --git a/developer/debugging/automated-tests.md b/developer/debugging/automated-tests.md index 38e4aca2..51870d97 100644 --- a/developer/debugging/automated-tests.md +++ b/developer/debugging/automated-tests.md @@ -132,7 +132,7 @@ Whereas integration tests are mostly stored in the [qubes-core-admin](https://gi To for example run the `qubes-core-admin` unit tests, you currently have to clone at least [qubes-core-admin](https://github.com/QubesOS/qubes-core-admin) and its dependency [qubes-core-qrexec](https://github.com/QubesOS/qubes-core-qrexec) repository in the branches that you want to test. -The below example however will assume that you set up a build environment as described in the [Qubes Builder documentation](/doc/qubes-builder/). +The below example however will assume that you set up a build environment as described in the [Qubes Builder documentation](/doc/qubes-builder-v2/). Assuming you cloned the `qubes-builder` repository to your home directory inside a fedora VM, you can use the following commands to run the unit tests: @@ -267,11 +267,13 @@ It feeds off of the openQA test data to make graph plots. Here is an example: ![openqa-investigator-splitgpg-example.png](/attachment/doc/openqa-investigator-splitgpg-example.png) Some outputs: + - plot by tests - plot by errors - markdown Some filters: + - filter by error - filter by test name diff --git a/developer/debugging/test-bench.md b/developer/debugging/test-bench.md index ca48a5ea..66a072c5 100644 --- a/developer/debugging/test-bench.md +++ b/developer/debugging/test-bench.md @@ -205,9 +205,10 @@ pushd ${HOME}/builder >/dev/null # the following are needed only if you have sources outside builder #rm -rf qubes-src/core-admin -#make COMPONENTS=core-admin get-sources +#qb -c core-admin package fetch -make core-admin +qb -c core-admin -d host-fc41 prep build +# update your dom0 fedora distribution as appropriate qtb-install qubes-src/core-admin/rpm/x86_64/qubes-core-dom0-*.rpm qtb-runtests ``` diff --git a/developer/debugging/vm-interface.md b/developer/debugging/vm-interface.md index 9c54619d..dc33827c 100644 --- a/developer/debugging/vm-interface.md +++ b/developer/debugging/vm-interface.md @@ -22,18 +22,19 @@ Qubes VM have some settings set by dom0 based on VM settings. There are multiple ### Keys exposed by dom0 to VM +- `/qubes-base-template` - base template - `/qubes-vm-type` - VM type, the same as `type` field in `qvm-prefs`. One of `AppVM`, `ProxyVM`, `NetVM`, `TemplateVM`, `HVM`, `TemplateHVM` - `/qubes-vm-updatable` - flag whether VM is updatable (whether changes in root.img will survive VM restart). One of `True`, `False` - `/qubes-vm-persistence` - what data do persist between VM restarts: - `full` - all disks - `rw-only` - only `/rw` disk - `none` - none -- `/qubes-timezone - name of timezone based on dom0 timezone. For example `Europe/Warsaw` +- `/qubes-timezone` - name of timezone based on dom0 timezone. For example `Europe/Warsaw` - `/qubes-keyboard` (deprecated in R4.1) - keyboard layout based on dom0 layout. Its syntax is suitable for `xkbcomp` command (after expanding escape sequences like `\n` or `\t`). This is meant only as some default value, VM can ignore this option and choose its own keyboard layout (this is what keyboard setting from Qubes Manager does). This entry is created as part of gui-daemon initialization (so not available when gui-daemon disabled, or not started yet). - `/keyboard-layout` - keyboard layout based on GuiVM layout. Its syntax can be `layout+variant+options`, `layout+variant`, `layout++options` or simply `layout`. For example, `fr+oss`, `pl++compose:caps` or `fr`. This is meant only as some default value, VM can ignore this option and choose its own keyboard layout (this is what keyboard setting from Qubes Manager does). - `/qubes-debug-mode` - flag whether VM has debug mode enabled (qvm-prefs setting). One of `1`, `0` - `/qubes-service/SERVICE_NAME` - subtree for VM services controlled from dom0 (using the `qvm-service` command or Qubes Manager). One of `1`, `0`. Note that not every service will be listed here, if entry is missing, it means "use VM default". A list of currently supported services is in the `qvm-service` man page. -- `/qubes-netmask` - network mask (only when VM has netvm set); currently hardcoded "255.255.255.0" +- `/qubes-netm ask` - network mask (only when VM has netvm set); currently hardcoded "255.255.255.0" - `/qubes-ip` - IP address for this VM (only when VM has netvm set) - `/qubes-gateway` - default gateway IP (only when VM has netvm set); VM should add host route to this address directly via eth0 (or whatever default interface name is) - `/qubes-primary-dns` - primary DNS address (only when VM has netvm set) diff --git a/developer/debugging/windows-debugging.md b/developer/debugging/windows-debugging.md index 852d1c67..089dfecd 100644 --- a/developer/debugging/windows-debugging.md +++ b/developer/debugging/windows-debugging.md @@ -10,253 +10,80 @@ ref: 50 title: Windows debugging --- -Debugging Windows code can be tricky in a virtualized environment. The guide below assumes Xen hypervisor and Windows 7 VMs. +Debugging Windows code can be tricky in a virtualized environment. The guide below assumes Qubes 4.2 and Windows 7 or later VMs. User-mode debugging is usually straightforward if it can be done on one machine. Just duplicate your normal debugging environment in the VM. -Things get complicated if you need to perform kernel debugging or troubleshoot problems that only manifest on system boot, user logoff or similar. For that you need two Windows VMs: the *host* and the *target*. The *host* will contain [WinDbg](https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx) installation, your source code and private symbols. The *target* will run the code being debugged. Both will be linked by virtual serial ports. +Things get complicated if you need to perform kernel debugging or troubleshoot problems that only manifest on system boot, user logoff or similar. For that you need two Windows VMs: the *host* and the *target*. The *host* will contain the debugger, your source code and private symbols. The *target* will run the code being debugged. We will use kernel debugging over network which is supported from Windows 7 onwards. The main caveat is that Windows kernel supports only specific network adapters for this, and the default one in Qubes won't work. -- First, you need to prepare separate copies of both *target* and *host* VM configuration files with some changes. Copy the files from **/var/lib/qubes/appvms/vmname/vmname.conf** to some convenient location, let's call them **host.conf** and **target.conf**. -- In both copied files add the following line at the end: `serial = 'pty'`. This will make Xen connect VM's serial ports to dom0's ptys. -- From now on you need to start both VMs like this: `qvm-start --custom-config=/your/edited/host.conf host` -- To connect both VM serial ports together you will either need [socat](http://www.dest-unreach.org/socat/) or a custom utility described later. -- To determine which dom0 pty corresponds to VM's serial port you need to read xenstore, example script below: +## Important note -```bash -#!/bin/sh +- Do not install Xen network PV drivers in the target VM. Network kernel debugging needs a specific type of NIC or it won't work, the network PV drivers interfere with that. -id1=$(xl domid "$1-dm") -tty1=$(xenstore-read /local/domain/${id1}/device/console/3/tty) -echo $tty1 -``` +- If you have kernel debugging active when the Xen PV drivers are being installed, make sure to disable it before rebooting (`bcdedit /set debug off`). You can re-enable debugging after the reboot. The OS won't boot otherwise. I'm not sure what's the exact cause. I know that busparams for the debugging NIC change when PV drivers are installed (see later), but even changing that accordingly in the debug settings doesn't help -- so it's best to disable debug for this one reboot. -Pass it a running VM name and it will output the corresponding pty name. +## Modifying the NIC of the target VM -- To connect both ptys you can use [socat](http://www.dest-unreach.org/socat/) like that: +You will need to create a custom libvirt config for the target VM. See [the documentation](https://dev.qubes-os.org/projects/core-admin/en/latest/libvirt.html) for overview of how libvirt templates work in Qubes. The following assumes the target VM is named `target-vm`. -```bash -#!/bin/sh +- Edit `/usr/share/qubes/templates/libvirt/xen.xml` to prepare our custom config to override just the NIC part of the global template: + - add `{% raw %}{% block network %}{% endraw %}` before `{% raw %}{% if vm.netvm %}{% endraw %}` + - add `{% raw %}{% endblock %}{% endraw %}` after the matching `{% raw %}{% endif %}{% endraw %}` +- Copy `/usr/share/qubes/templates/libvirt/devices/net.xml` to `/etc/qubes/templates/libvirt/xen/by-name/target-vm.xml`. +- Add `` to the `` section. +- Enclose everything within `{% raw %}{% block network %}{% endraw %}` + `{% raw %}{% endblock %}{% endraw %}`. +- Add `{% raw %}{% extends 'libvirt/xen.xml' %}{% endraw %}` at the start. +- The final `target-vm.xml` should look something like this: -id1=$(xl domid "$1-dm") -id2=$(xl domid "$2-dm") -tty1=$(xenstore-read /local/domain/${id1}/device/console/3/tty) -tty2=$(xenstore-read /local/domain/${id2}/device/console/3/tty) -socat $tty1,raw $tty2,raw -``` +~~~ +{% raw %} +{% extends 'libvirt/xen.xml' %} +{% block network %} + + + + +