feat: add GUI domain formula

For: https://github.com/ben-grande/qusal/issues/89
This commit is contained in:
Ben Grande 2024-07-18 15:09:02 +02:00
parent fa11a1da7f
commit 735b324821
No known key found for this signature in database
GPG Key ID: 00C64E14F51F9E56
50 changed files with 1334 additions and 0 deletions

View File

@ -39,6 +39,9 @@ host:
- rpm_spec/qusal-sys-electrumx.spec
- rpm_spec/qusal-sys-firewall.spec
- rpm_spec/qusal-sys-git.spec
- rpm_spec/qusal-sys-gui.spec
- rpm_spec/qusal-sys-gui-gpu.spec
- rpm_spec/qusal-sys-gui-vnc.spec
- rpm_spec/qusal-sys-mirage-firewall.spec
- rpm_spec/qusal-sys-net.spec
- rpm_spec/qusal-sys-pgp.spec

View File

@ -8,6 +8,7 @@ Qusal troubleshooting guidelines.
* [Qrexec client shows Request refused](#qrexec-client-shows-request-refused)
* [Salt wrapper qubesctl command fails](#salt-wrapper-qubesctl-command-fails)
* [Get Salt management information](#get-salt-management-information)
* [No support for unfinished formulas](#no-support-for-unfinished-formulas)
## Detect if your issue was already opened
@ -91,3 +92,13 @@ the qube being managed:
sudo qubesctl state.apply dom0.helpers
qvm-mgmt tpl-qubes-builder
```
## No support for unfinished formulas
If you have been redirect to this section, be aware that the formula you are
using is unfinished and no support will be provided. It is development only
and if you are not a developer, there is a chance you will find yourself lost
on how to debug and revert back to a known good state.
Again, don't try the formula if you don't know how to fix problems that may
arise.

View File

@ -0,0 +1,112 @@
# SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
%define project sys-gui-gpu
%define license_csv AGPL-3.0-or-later,GPL-2.0-only
## Reproducibility.
%define source_date_epoch_from_changelog 1
%define use_source_date_epoch_as_buildtime 1
%define clamp_mtime_to_source_date_epoch 1
## Changelog is trimmed according to current date, not last date from changelog.
%define _changelog_trimtime 0
%define _changelog_trimage 0
%global _buildhost %{name}
## Python bytecode interferes when updates occur and restart is not done.
%undefine __brp_python_bytecompile
Name: qusal-sys-gui-gpu
Version: 0.0.1
Release: 1%{?dist}
Summary:
Group: qusal
Packager: %{?_packager}%{!?_packager:Ben Grande <ben.grande.b@gmail.com>}
Vendor: Ben Grande
License: AGPL-3.0-or-later AND GPL-2.0-only
URL: https://github.com/ben-grande/qusal
BugURL: https://github.com/ben-grande/qusal/issues
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
Requires: qubes-mgmt-salt
Requires: qubes-mgmt-salt-dom0
Requires: qusal-sys-gui
%description
Setup a GPU GUI domain named "sys-gui-gpu". The GPU is attached to the qube
and all graphics computation are handled by this qube. Requires a dedicated
graphics card (external GPU) and PCI passthrough support.
%prep
%setup -q
%build
%check
%pre
%install
rm -rf %{buildroot}
install -m 755 -d \
%{buildroot}/srv/salt/qusal \
%{buildroot}%{_docdir}/%{name} \
%{buildroot}%{_defaultlicensedir}/%{name}
for license in $(echo "%{license_csv}" | tr "," " "); do
license_dir="LICENSES"
if test -d "salt/%{project}/LICENSES"; then
license_dir="salt/%{project}/LICENSES"
fi
install -m 644 "${license_dir}/${license}.txt" %{buildroot}%{_defaultlicensedir}/%{name}/
done
install -m 644 salt/%{project}/README.md %{buildroot}%{_docdir}/%{name}/
rm -rf \
salt/%{project}/LICENSES \
salt/%{project}/README.md \
salt/%{project}/.*
cp -rv salt/%{project} %{buildroot}/srv/salt/qusal/%{name}
%post
if test "$1" = "1"; then
## Install
qubesctl top.enable qvm.sys-gui pillar=True
qubesctl state.apply sys-gui-gpu.create
qubesctl --skip-dom0 --targets=tpl-sys-gui state.apply sys-gui-gpu.install
qubesctl --skip-dom0 --targets=sys-gui-gpu state.apply sys-gui-gpu.configure
qubesctl state.apply sys-gui-gpu.prefs
elif test "$1" = "2"; then
## Upgrade
true
fi
%preun
if test "$1" = "0"; then
## Uninstall
true
elif test "$1" = "1"; then
## Upgrade
true
fi
%postun
if test "$1" = "0"; then
## Uninstall
true
elif test "$1" = "1"; then
## Upgrade
true
fi
%files
%defattr(-,root,root,-)
%license %{_defaultlicensedir}/%{name}/*
%doc %{_docdir}/%{name}/README.md
%dir /srv/salt/qusal/%{name}
/srv/salt/qusal/%{name}/*
%dnl TODO: missing '%ghost', files generated during %post, such as Qrexec policies.
%changelog

View File

@ -0,0 +1,112 @@
# SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
%define project sys-gui-vnc
%define license_csv AGPL-3.0-or-later,GPL-2.0-only
## Reproducibility.
%define source_date_epoch_from_changelog 1
%define use_source_date_epoch_as_buildtime 1
%define clamp_mtime_to_source_date_epoch 1
## Changelog is trimmed according to current date, not last date from changelog.
%define _changelog_trimtime 0
%define _changelog_trimage 0
%global _buildhost %{name}
## Python bytecode interferes when updates occur and restart is not done.
%undefine __brp_python_bytecompile
Name: qusal-sys-gui-vnc
Version: 0.0.1
Release: 1%{?dist}
Summary:
Group: qusal
Packager: %{?_packager}%{!?_packager:Ben Grande <ben.grande.b@gmail.com>}
Vendor: Ben Grande
License: AGPL-3.0-or-later AND GPL-2.0-only
URL: https://github.com/ben-grande/qusal
BugURL: https://github.com/ben-grande/qusal/issues
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
Requires: qubes-mgmt-salt
Requires: qubes-mgmt-salt-dom0
Requires: qusal-sys-gui
%description
Setup a VNC GUI domain named "sys-gui-vnc". The qube spawns a VNC server and
you can connect from other qubes to it. It is primarily intended for remote
administration.
%prep
%setup -q
%build
%check
%pre
%install
rm -rf %{buildroot}
install -m 755 -d \
%{buildroot}/srv/salt/qusal \
%{buildroot}%{_docdir}/%{name} \
%{buildroot}%{_defaultlicensedir}/%{name}
for license in $(echo "%{license_csv}" | tr "," " "); do
license_dir="LICENSES"
if test -d "salt/%{project}/LICENSES"; then
license_dir="salt/%{project}/LICENSES"
fi
install -m 644 "${license_dir}/${license}.txt" %{buildroot}%{_defaultlicensedir}/%{name}/
done
install -m 644 salt/%{project}/README.md %{buildroot}%{_docdir}/%{name}/
rm -rf \
salt/%{project}/LICENSES \
salt/%{project}/README.md \
salt/%{project}/.*
cp -rv salt/%{project} %{buildroot}/srv/salt/qusal/%{name}
%post
if test "$1" = "1"; then
## Install
qubesctl top.enable qvm.sys-gui pillar=True
qubesctl state.apply sys-gui-vnc.create
qubesctl --skip-dom0 --targets=tpl-sys-gui state.apply sys-gui-vnc.install
qubesctl --skip-dom0 --targets=sys-gui-vnc state.apply sys-gui-vnc.configure
qubesctl state.apply sys-gui-vnc.prefs
elif test "$1" = "2"; then
## Upgrade
true
fi
%preun
if test "$1" = "0"; then
## Uninstall
true
elif test "$1" = "1"; then
## Upgrade
true
fi
%postun
if test "$1" = "0"; then
## Uninstall
true
elif test "$1" = "1"; then
## Upgrade
true
fi
%files
%defattr(-,root,root,-)
%license %{_defaultlicensedir}/%{name}/*
%doc %{_docdir}/%{name}/README.md
%dir /srv/salt/qusal/%{name}
/srv/salt/qusal/%{name}/*
%dnl TODO: missing '%ghost', files generated during %post, such as Qrexec policies.
%changelog

113
rpm_spec/qusal-sys-gui.spec Normal file
View File

@ -0,0 +1,113 @@
# SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
%define project sys-gui
%define license_csv AGPL-3.0-or-later,GPL-2.0-only
## Reproducibility.
%define source_date_epoch_from_changelog 1
%define use_source_date_epoch_as_buildtime 1
%define clamp_mtime_to_source_date_epoch 1
## Changelog is trimmed according to current date, not last date from changelog.
%define _changelog_trimtime 0
%define _changelog_trimage 0
%global _buildhost %{name}
## Python bytecode interferes when updates occur and restart is not done.
%undefine __brp_python_bytecompile
Name: qusal-sys-gui
Version: 0.0.1
Release: 1%{?dist}
Summary: Hybrid GUI domain in Qubes OS
Group: qusal
Packager: %{?_packager}%{!?_packager:Ben Grande <ben.grande.b@gmail.com>}
Vendor: Ben Grande
License: AGPL-3.0-or-later AND GPL-2.0-only
URL: https://github.com/ben-grande/qusal
BugURL: https://github.com/ben-grande/qusal/issues
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
Requires: qubes-mgmt-salt
Requires: qubes-mgmt-salt-dom0
Requires: qusal-dotfiles
Requires: qusal-utils
%description
Setup a Hybrid GUI domain named "sys-gui". Dom0 remains with the X Server and
graphics drivers but runs only a single GUI application, a full-screen proxy
for the GUI domain's graphical server.
%prep
%setup -q
%build
%check
%pre
%install
rm -rf %{buildroot}
install -m 755 -d \
%{buildroot}/srv/salt/qusal \
%{buildroot}%{_docdir}/%{name} \
%{buildroot}%{_defaultlicensedir}/%{name}
for license in $(echo "%{license_csv}" | tr "," " "); do
license_dir="LICENSES"
if test -d "salt/%{project}/LICENSES"; then
license_dir="salt/%{project}/LICENSES"
fi
install -m 644 "${license_dir}/${license}.txt" %{buildroot}%{_defaultlicensedir}/%{name}/
done
install -m 644 salt/%{project}/README.md %{buildroot}%{_docdir}/%{name}/
rm -rf \
salt/%{project}/LICENSES \
salt/%{project}/README.md \
salt/%{project}/.*
cp -rv salt/%{project} %{buildroot}/srv/salt/qusal/%{name}
%post
if test "$1" = "1"; then
## Install
qubesctl top.enable qvm.sys-gui pillar=True
qubesctl state.apply sys-gui.create
qubesctl --skip-dom0 --targets=tpl-sys-gui state.apply sys-gui.install
qubesctl --skip-dom0 --targets=sys-gui state.apply sys-gui.configure
qubesctl state.apply sys-gui.prefs
elif test "$1" = "2"; then
## Upgrade
true
fi
%preun
if test "$1" = "0"; then
## Uninstall
true
elif test "$1" = "1"; then
## Upgrade
true
fi
%postun
if test "$1" = "0"; then
## Uninstall
true
elif test "$1" = "1"; then
## Upgrade
true
fi
%files
%defattr(-,root,root,-)
%license %{_defaultlicensedir}/%{name}/*
%doc %{_docdir}/%{name}/README.md
%dir /srv/salt/qusal/%{name}
/srv/salt/qusal/%{name}/*
%dnl TODO: missing '%ghost', files generated during %post, such as Qrexec policies.
%changelog

View File

@ -0,0 +1,79 @@
# sys-gui
GPU GUI domain in Qubes OS.
## Table of Contents
* [Description](#description)
* [Installation](#installation)
* [Uninstallation](#uninstallation)
* [Usage](#usage)
## Description
Setup a GPU GUI domain named "sys-gui-gpu". The GPU is attached to the qube
and all graphics computation are handled by this qube. Requires a dedicated
graphics card (external GPU) and PCI passthrough support.
## Installation
WARNING: [unfinished formula](../../docs/TROUBLESHOOT.md#no-support-for-unfinished-formulas).
* Top:
```sh
sudo qubesctl top.enable qvm.sys-gui pillar=True
sudo qubesctl top.enable sys-gui-gpu
sudo qubesctl --targets=tpl-sys-gui,sys-gui-gpu state.apply
sudo qubesctl top.disable sys-gui-gpu
sudo qubesctl state.apply sys-gui-gpu.prefs
```
* State:
<!-- pkg:begin:post-install -->
```sh
sudo qubesctl top.enable qvm.sys-gui pillar=True
sudo qubesctl state.apply sys-gui-gpu.create
sudo qubesctl --skip-dom0 --targets=tpl-sys-gui state.apply sys-gui-gpu.install
sudo qubesctl --skip-dom0 --targets=sys-gui-gpu state.apply sys-gui-gpu.configure
sudo qubesctl state.apply sys-gui-gpu.prefs
```
<!-- pkg:end:post-install -->
The formula assumes Intel graphics card, if you have a card from another
vendor, please use
[qvm-pci](https://www.qubes-os.org/doc/how-to-use-pci-devices/#qvm-pci-usage)
to persistently attach the GPU with the permissive option to `sys-gui-gpu`.
Shutdown all your running qubes as the global property `default_guivm` has
changed to `sys-gui-gpu`.
## Uninstallation
Reboot you computer and prevent Qubes OS autostart of any qube, be it
`sys-gui-gpu` or the qubes connected to it to reach dom0. For that, you need to
boot Qubes OS with
[qubes.skip_autostart GRUB parameter](https://www.qubes-os.org/doc/autostart-troubleshooting/).
Only after you have done these steps manually, you can continue the
uninstallation procedure.
Set Global preference `default_guivm` to `dom0` and disable `autostart` of
`sys-gui-gpu`:
```sh
sudo qubesctl state.apply sys-gui-gpu.cancel
```
## Usage
Qubes that have their `guivm` preference set to `sys-gui-gpu`, will use it as
the GUI domain.
The process to enter `sys-gui-gpu` can be a simple logout, but on most
platforms, a reboot is required and recommended to prevent data loss.
The login credentials are the same used in `dom0`, the first user in the
`qubes` group and the corresponding password.

View File

@ -0,0 +1,14 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
include:
- sys-gui.cancel-common
- qvm.sys-gui-gpu-detach-gpu
"{{ slsdotpath }}-gpu-disable-autostart":
qvm.prefs:
- name: {{ slsdotpath }}-gpu
- autostart: False

View File

@ -0,0 +1,8 @@
{#
SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
include:
- sys-gui.clone

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-gpu.clone

View File

@ -0,0 +1,13 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- sys-gui.configure
- qvm.sys-gui-gpu-vm
{% endif -%}

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'sys-gui-gpu':
- match: nodegroup
- sys-gui-gpu.configure

View File

@ -0,0 +1,86 @@
{#
SPDX-FileCopyrightText: 2020 Artur Puzio <contact@puzio.waw.pl>
SPDX-FileCopyrightText: 2020 Frederic Pierret <frederic.pierret@qubes-os.org>
SPDX-FileCopyrightText: 2020 - 2024 Marmarek Marczykowski-Gorecki <marmarek@invisiblethingslab.com>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-2.0-only
#}
{%- from "qvm/template.jinja" import load -%}
{%- from "qvm/template-gui.jinja" import gui_common -%}
include:
- .clone
"{{ slsdotpath }}-gpu-installed":
pkg.installed:
- install_recommends: False
- skip_suggestions: True
- pkgs:
- qubes-input-proxy-sender
{% if 'psu' in salt['pillar.get']('qvm:sys-gui-gpu:dummy-modules', []) %}
- dummy-psu-sender
{% endif %}
{% load_yaml as defaults -%}
name: tpl-{{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
prefs:
- audiovm: ""
{%- endload %}
{{ load(defaults) }}
{% load_yaml as defaults -%}
name: {{ slsdotpath }}-gpu
force: True
require:
- sls: {{ slsdotpath }}.clone
present:
- template: tpl-{{ slsdotpath }}
- label: black
prefs:
- template: tpl-{{ slsdotpath }}
- label: black
- memory: 600
- maxmem: 4000
- virt_mode: hvm
- netvm: ""
- guivm: ""
- audiovm: ""
- kernelopts: "nopat iommu=soft swiotlb=8192 root=/dev/mapper/dmroot ro console=hvc0 xen_scrub_pages=0"
- autostart: False # TODO: set to True
- include_in_backups: True
features:
- enable:
- no-default-kernelopts
- service.lightdm
- service.guivm
{% if 'psu' in salt['pillar.get']('qvm:sys-gui-gpu:dummy-modules', []) %}
- service.dummy-psu
{% endif %}
- set:
- video-model: none
- input-dom0-proxy: true
{%- endload %}
{{ load(defaults) }}
{{ gui_common(defaults.name) }}
# Set GuiVM target for input-proxy-sender of dom0 attached input devices (not USB)
"{{ slsdotpath }}-gpu-input-proxy-target":
file.managed:
- name: /etc/qubes/input-proxy-target
- contents: "TARGET_DOMAIN=sys-gui-gpu"
# Set Qubes RPC policy for sys-usb to sys-gui-gpu
"{{ slsdotpath }}-gpu-usb-input-proxy-target":
file.managed:
- name: /etc/qubes/policy.d/45-sys-gui-gpu.policy
{% if salt['pillar.get']('qvm:sys-usb:mouse-action', 'ask') == 'ask' %}
- text: qubes.InputMouse * {{ salt['pillar.get']('qvm:sys-usb:name', 'sys-usb') }} dom0 ask user=root default_target=sys-gui-gpu
{% elif salt['pillar.get']('qvm:sys-usb:mouse-action', 'ask') == 'allow' %}
- text: qubes.InputMouse * {{ salt['pillar.get']('qvm:sys-usb:name', 'sys-usb') }} dom0 allow user=root target=sys-gui-gpu
{% endif %}

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-gpu.create

14
salt/sys-gui-gpu/init.top Normal file
View File

@ -0,0 +1,14 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-gpu.create
'tpl-sys-gui':
- sys-gui-gpu.install
'sys-gui-gpu':
- sys-gui-gpu.configure

View File

@ -0,0 +1,16 @@
{#
SPDX-FileCopyrightText: 2019 Frederic Pierret <frederic.pierret@qubes-os.org>
SPDX-FileCopyrightText: 2020 - 2024 Marmarek Marczykowski-Gorecki <marmarek@invisiblethingslab.com>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-2.0-only
Upstream pkg.installed install weak_deps/recommends.
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- sys-gui.install
{% endif -%}

View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'tpl-sys-gui':
- sys-gui-gpu.install

View File

@ -0,0 +1,19 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
include:
- qvm.sys-gui-gpu-attach-gpu
"{{ slsdotpath }}-gpu-autostart":
qvm.prefs:
- name: {{ slsdotpath }}-gpu
- autostart: True
"{{ slsdotpath }}-gpu-activate":
cmd.run:
- require:
- qvm: "{{ slsdotpath }}-gpu-autostart"
- name: qubes-prefs default_guivm {{ slsdotpath }}-gpu

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-gpu.prefs

1
salt/sys-gui-gpu/version Normal file
View File

@ -0,0 +1 @@
0.0.1

View File

@ -0,0 +1,98 @@
# sys-gui
VNC GUI domain in Qubes OS.
## Table of Contents
* [Description](#description)
* [Installation](#installation)
* [Uninstallation](#uninstallation)
* [Usage](#usage)
## Description
Setup a VNC GUI domain named "sys-gui-vnc". The qube spawns a VNC server and
you can connect from other qubes to it. It is primarily intended for remote
administration.
## Installation
WARNING: [unfinished formula](../../docs/TROUBLESHOOT.md#no-support-for-unfinished-formulas).
* Top:
```sh
sudo qubesctl top.enable qvm.sys-gui pillar=True
sudo qubesctl top.enable sys-gui-vnc
sudo qubesctl --targets=tpl-sys-gui,sys-gui-vnc state.apply
sudo qubesctl top.disable sys-gui-vnc
sudo qubesctl state.apply sys-gui-vnc.prefs
```
* State:
<!-- pkg:begin:post-install -->
```sh
sudo qubesctl top.enable qvm.sys-gui pillar=True
sudo qubesctl state.apply sys-gui-vnc.create
sudo qubesctl --skip-dom0 --targets=tpl-sys-gui state.apply sys-gui-vnc.install
sudo qubesctl --skip-dom0 --targets=sys-gui-vnc state.apply sys-gui-vnc.configure
sudo qubesctl state.apply sys-gui-vnc.prefs
```
<!-- pkg:end:post-install -->
Shutdown all your running qubes as the global property `default_guivm` has
changed to `sys-gui-vnc`.
## Access control
_Default policy_: `any qube` is `denied` to connected to any other qube.
Allow qube `sys-remote` to connect `sys-gui-vnc` on port `5900`:
```qrexecpolicy
qubes.ConnectTCP +5900 sys-remote @default allow target=sys-gui-vnc
qubes.ConnectTCP * sys-remote @anyvm deny
```
## Usage
Qubes that have their `guivm` preference set to `sys-gui-vnc`, will use it as
the GUI domain.
It unnecessary to have a `netvm` set for the VNC client qube for testing, but
it is necessary to make the VNC server accessible from remote computers. If
you plan to expose `sys-gui-vnc` to the network, it must have another
authenticated transport such as a `VPN` or `VNC over SSH`.
From a trusted qube that has a VNC client installed, such as
[remmina](../remmina/README.md), bind the port `6000` to the port `5900`
listening on `sys-gui-vnc`:
```sh
qvm-connnect-tcp 6000::5900
```
On the VNC client application, set connection protocol to `VNC` and host to
`127.0.0.1:6000`.
The login credentials are the same used in `dom0`, the first user in the
`qubes` group and the corresponding password.
## Uninstallation
Set Global preference `default_guivm` to `dom0` and disable `autostart` of
`sys-gui-vnc`:
```sh
sudo qubesctl state.apply sys-gui-vnc.cancel
```
You must also revert exposing the VNC server to other qubes and remote hosts:
* Delete or deny calls to Qrexec policy rules allowing qubes to connect with
`qubes.ConnectTCP` to `sys-gui-vnc`; and
* Close firewall ports and disable services that expose the VNC client qube
to external hosts.

View File

@ -0,0 +1,13 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
include:
- sys-gui.cancel-common
"{{ slsdotpath }}-vnc-disable-autostart":
qvm.prefs:
- name: {{ slsdotpath }}-vnc
- autostart: False

View File

@ -0,0 +1,8 @@
{#
SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
include:
- sys-gui.clone

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-vnc.clone

View File

@ -0,0 +1,13 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- sys-gui.configure
- qvm.sys-gui-vnc-vm
{% endif -%}

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'sys-gui-vnc':
- match: nodegroup
- sys-gui-vnc.configure

View File

@ -0,0 +1,71 @@
{#
SPDX-FileCopyrightText: 2021 Frederic Pierret <frederic.pierret@qubes-os.org>
SPDX-FileCopyrightText: 2021 - 2024 Marmarek Marczykowski-Gorecki <marmarek@invisiblethingslab.com>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-2.0-only
#}
{%- from "qvm/template.jinja" import load -%}
{%- from "qvm/template-gui.jinja" import gui_common -%}
include:
- .clone
{% if 'psu' in salt['pillar.get']('qvm:sys-gui-vnc:dummy-modules', []) or 'backlight' in salt['pillar.get']('qvm:sys-gui-vnc:dummy-modules', []) %}
"{{ slsdotpath }}-vnc-installed":
pkg.installed:
- install_recommends: False
- skip_suggestions: True
- pkgs:
{% if 'psu' in salt['pillar.get']('qvm:sys-gui-vnc:dummy-modules', []) %}
- dummy-psu-sender
{% endif %}
{% if 'backlight' in salt['pillar.get']('qvm:sys-gui-vnc:dummy-modules', []) %}
- dummy-backlight-dom0
{% endif %}
{% endif %}
{% load_yaml as defaults -%}
name: tpl-{{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
prefs:
- audiovm: ""
{%- endload %}
{{ load(defaults) }}
{% load_yaml as defaults -%}
name: {{ slsdotpath }}-vnc
force: True
require:
- sls: {{ slsdotpath }}.clone
present:
- template: tpl-{{ slsdotpath }}
- label: black
prefs:
- template: tpl-{{ slsdotpath }}
- label: black
- memory: 400
- maxmem: 4000
- netvm: ""
- guivm: dom0
- audiovm: ""
- autostart: False # TODO: set to True
- include_in_backups: True
features:
- enable:
- service.lightdm
- service.guivm
- service.guivm-vnc
{% if 'psu' in salt['pillar.get']('qvm:sys-gui-vnc:dummy-modules', []) %}
- service.dummy-psu
{% endif %}
{% if 'backlight' in salt['pillar.get']('qvm:sys-gui-vnc:dummy-modules', []) %}
- service.dummy-backlight
{% endif %}
{%- endload %}
{{ load(defaults) }}
{{ gui_common(defaults.name) }}

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-vnc.create

14
salt/sys-gui-vnc/init.top Normal file
View File

@ -0,0 +1,14 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-vnc.create
'tpl-sys-gui':
- sys-gui-vnc.install
'sys-gui-vnc':
- sys-gui-vnc.configure

View File

@ -0,0 +1,16 @@
{#
SPDX-FileCopyrightText: 2019 Frederic Pierret <frederic.pierret@qubes-os.org>
SPDX-FileCopyrightText: 2020 - 2024 Marmarek Marczykowski-Gorecki <marmarek@invisiblethingslab.com>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-2.0-only
Upstream pkg.installed install weak_deps/recommends.
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- sys-gui.install
{% endif -%}

View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'tpl-sys-gui':
- sys-gui-vnc.install

View File

@ -0,0 +1,16 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
"{{ slsdotpath }}-vnc-autostart":
qvm.prefs:
- name: {{ slsdotpath }}-vnc
- autostart: True
"{{ slsdotpath }}-vnc-activate":
cmd.run:
- require:
- qvm: "{{ slsdotpath }}-vnc-autostart"
- name: qubes-prefs default_guivm {{ slsdotpath }}-vnc

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui-vnc.prefs

1
salt/sys-gui-vnc/version Normal file
View File

@ -0,0 +1 @@
0.0.1

70
salt/sys-gui/README.md Normal file
View File

@ -0,0 +1,70 @@
# sys-gui
Hybrid GUI domain in Qubes OS.
## Table of Contents
* [Description](#description)
* [Installation](#installation)
* [Uninstallation](#uninstallation)
* [Usage](#usage)
## Description
Setup a Hybrid GUI domain named "sys-gui". Dom0 remains with the X Server and
graphics drivers but runs only a single GUI application, a full-screen proxy
for the GUI domain's graphical server.
## Installation
WARNING: [unfinished formula](../../docs/TROUBLESHOOT.md#no-support-for-unfinished-formulas).
* Top:
```sh
sudo qubesctl top.enable qvm.sys-gui pillar=True
sudo qubesctl top.enable sys-gui
sudo qubesctl --targets=tpl-sys-gui,sys-gui state.apply
sudo qubesctl top.disable sys-gui
sudo qubesctl state.apply sys-gui.prefs
```
* State:
<!-- pkg:begin:post-install -->
```sh
sudo qubesctl top.enable qvm.sys-gui pillar=True
sudo qubesctl state.apply sys-gui.create
sudo qubesctl --skip-dom0 --targets=tpl-sys-gui state.apply sys-gui.install
sudo qubesctl --skip-dom0 --targets=sys-gui state.apply sys-gui.configure
sudo qubesctl state.apply sys-gui.prefs
```
<!-- pkg:end:post-install -->
Shutdown all your running qubes as the global property `default_guivm` has
changed to `sys-gui`.
## Usage
Qubes that have their `guivm` preference set to `sys-gui`, will use it as the
GUI domain.
Logout and in the login manager (lightdm, sddm), select session type
`GUI domain (sys-gui)`.
The login credentials are the same used in `dom0`, the first user in the
`qubes` group and the corresponding password.
## Uninstallation
Set Global preference `default_guivm` to `dom0` and disable `autostart` of
`sys-gui`:
```sh
sudo qubesctl state.apply sys-gui.cancel
```
Logout and in the login manager (lightdm, sddm), select session type
`Plasma (X11)` or `Xfce`.

View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
"{{ slsdotpath }}-revert-default_guivm-to-dom0":
cmd.run:
- name: qubes-prefs default_guivm dom0

13
salt/sys-gui/cancel.sls Normal file
View File

@ -0,0 +1,13 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
include:
- .cancel-common
"{{ slsdotpath }}-disable-autostart":
qvm.prefs:
- name: {{ slsdotpath }}
- autostart: False

8
salt/sys-gui/clone.sls Normal file
View File

@ -0,0 +1,8 @@
{#
SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% from 'utils/macros/clone-template.sls' import clone_template -%}
{{ clone_template('fedora-minimal', sls_path) }}

10
salt/sys-gui/clone.top Normal file
View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui.clone

View File

@ -0,0 +1,13 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- dotfiles.copy-all
- qvm.sys-gui-vm
{% endif -%}

View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'sys-gui':
- match: nodegroup
- sys-gui.configure

83
salt/sys-gui/create.sls Normal file
View File

@ -0,0 +1,83 @@
{#
SPDX-FileCopyrightText: 2019 - 2020 Frederic Pierret <frederic.pierret@qubes-os.org>
SPDX-FileCopyrightText: 2020 - 2024 Marmarek Marczykowski-Gorecki <marmarek@invisiblethingslab.com>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-2.0-only
#}
{%- from "qvm/template.jinja" import load -%}
{%- from "qvm/template-gui.jinja" import gui_common -%}
include:
- .clone
{% if 'psu' in salt['pillar.get']('qvm:sys-gui:dummy-modules', []) or 'backlight' in salt['pillar.get']('qvm:sys-gui:dummy-modules', []) %}
"{{ slsdotpath }}-installed":
pkg.installed:
- install_recommends: False
- skip_suggestions: True
- pkgs:
{% if 'psu' in salt['pillar.get']('qvm:sys-gui:dummy-modules', []) %}
- dummy-psu-sender
{% endif %}
{% if 'backlight' in salt['pillar.get']('qvm:sys-gui:dummy-modules', []) %}
- dummy-backlight-dom0
{% endif %}
{% endif %}
{% load_yaml as defaults -%}
name: tpl-{{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
prefs:
- audiovm: ""
{%- endload %}
{{ load(defaults) }}
{% load_yaml as defaults -%}
name: {{ slsdotpath }}
force: True
require:
- sls: {{ slsdotpath }}.clone
present:
- template: tpl-{{ slsdotpath }}
- label: black
prefs:
- template: tpl-{{ slsdotpath }}
- label: black
- netvm: ""
- memory: 400
- maxmem: 4000
- guivm: dom0
- audiovm: dom0
- autostart: False # TODO: set to True
- include_in_backups: True
features:
- enable:
- gui-allow-fullscreen
- service.guivm
- service.guivm-gui-agent
{% if 'psu' in salt['pillar.get']('qvm:sys-gui:dummy-modules', []) %}
- service.dummy-psu
{% endif %}
{% if 'backlight' in salt['pillar.get']('qvm:sys-gui:dummy-modules', []) %}
- service.dummy-backlight
{% endif %}
- set:
- gui-secure-copy-sequence: none
- gui-secure-paste-sequence: none
{%- endload %}
{{ load(defaults) }}
{{ gui_common(defaults.name) }}
"{{ slsdotpath }}-xsessions":
file.managed:
- name: /usr/share/xsessions/sys-gui.desktop
- source: salt://{{ slsdotpath }}/files/server/xsessions/sys-gui.desktop
- mode: '0644'
- user: root
- group: root
- makedirs: True

10
salt/sys-gui/create.top Normal file
View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui.create

View File

@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2020 Artur Puzio <contact@puzio.waw.pl>
#
# SPDX-License-Identifier: GPL-2.0-only
# vim: ft=systemd
[Unit]
ConditionPathExists=/var/run/qubes-service/lightdm
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,8 @@
# SPDX-FileCopyrightText: 2020 Marmarek Marczykowski-Gorecki <marmarek@invisiblethingslab.com>
#
# SPDX-License-Identifier: GPL-2.0-only
[Desktop Entry]
Name=GUI Domain (sys-gui)
Exec=qubes-guivm-session sys-gui
Type=Application

14
salt/sys-gui/init.top Normal file
View File

@ -0,0 +1,14 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui.create
'tpl-sys-gui':
- sys-gui.install
'sys-gui':
- sys-gui.configure

91
salt/sys-gui/install.sls Normal file
View File

@ -0,0 +1,91 @@
{#
SPDX-FileCopyrightText: 2019 Frederic Pierret <frederic.pierret@qubes-os.org>
SPDX-FileCopyrightText: 2020 - 2024 Marmarek Marczykowski-Gorecki <marmarek@invisiblethingslab.com>
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: GPL-2.0-only
Upstream pkg.installed installs weak_deps/recommends.
#}
{% if grains['nodename'] != 'dom0' -%}
include:
- utils.tools.common.update
- dotfiles.copy-all
"{{ slsdotpath }}-installed":
pkg.installed:
- require:
- sls: utils.tools.common.update
- install_recommends: False
- skip_suggestions: True
- pkgs:
# Qubes related packages
- qubes-core-agent-passwordless-root
- qubes-manager
- qubes-desktop-linux-manager
- qubes-vm-guivm
# Xfce related packages
- arc-theme
- gvfs
- xdg-user-dirs-gtk
- xfce4-appfinder
- xfce4-datetime-plugin
- xfce4-panel
- xfce4-places-plugin
- xfce4-power-manager
- xfce4-pulseaudio-plugin
- xfce4-session
- xfce4-settings
- xfce4-settings-qubes
- xfce4-taskmanager
- xfce4-terminal
- xfconf
- xfwm4
{% set pkg = {
'Debian': {
'pkg': ['blackbird-gtk-theme', 'gnome-themes-standard',
'greybird-gtk-theme', 'gtk3-engines-xfce', 'libxfce4ui-utils',
'lightdm', 'xfce4-screenshooter', 'xfdesktop4', 'xscreensaver']
},
'RedHat': {
'pkg': ['dummy-psu-receiver', 'dummy-psu-module', 'dummy-backlight-vm',
'adwaita-gtk2-theme', 'adwaita-icon-theme', 'greybird-dark-theme',
'greybird-light-theme', 'greybird-xfce4-notifyd-theme',
'greybird-xfwm4-theme', 'gtk-xfce-engine', 'lightdm-gtk',
'xfce4-about', 'xfce4-screenshooter-plugin', 'xfdesktop',
'xfwm4-themes', 'xscreensaver-base']
},
}.get(grains.os_family) -%}
"{{ slsdotpath }}-installed-os-specific":
pkg.installed:
- require:
- sls: utils.tools.common.update
- install_recommends: False
- skip_suggestions: True
- pkgs: {{ pkg.pkg|sequence|yaml }}
"{{ slsdotpath }}-lightdm-service-unit":
file.managed:
- name: /usr/lib/systemd/system/lightdm.service.d/qubes.conf
- source: salt://{{ slsdotpath }}/files/server/systemd/lightdm.service.d/qubes.conf
- mode: '0644'
- user: root
- group: root
- makedirs: True
"{{ slsdotpath }}-lightdm-service-enabled":
service.enabled:
- require:
- pkg: "{{ slsdotpath }}-installed"
- name: lightdm
"{{ slsdotpath }}-lock-root":
user.present:
- name: root
- password: '!!'
{% endif -%}

9
salt/sys-gui/install.top Normal file
View File

@ -0,0 +1,9 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'tpl-sys-gui':
- sys-gui.install

16
salt/sys-gui/prefs.sls Normal file
View File

@ -0,0 +1,16 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
"{{ slsdotpath }}-autostart":
qvm.prefs:
- name: {{ slsdotpath }}
- autostart: True
"{{ slsdotpath }}-activate":
cmd.run:
- require:
- qvm: "{{ slsdotpath }}-autostart"
- name: qubes-prefs default_guivm {{ slsdotpath }}

10
salt/sys-gui/prefs.top Normal file
View File

@ -0,0 +1,10 @@
{#
SPDX-FileCopyrightText: 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: AGPL-3.0-or-later
#}
base:
'dom0':
- match: nodegroup
- sys-gui.prefs

1
salt/sys-gui/version Normal file
View File

@ -0,0 +1 @@
0.0.1