Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e21ec3d
First version
jumpyvi Apr 20, 2026
0df05a1
Fix sysusers script
jumpyvi Apr 20, 2026
61fe3e1
Add links
jumpyvi Apr 20, 2026
d45c7f3
Add auto-updates to libvirt quadlet
jumpyvi Apr 20, 2026
bb35bbd
Fix bundle
jumpyvi Apr 20, 2026
1663c49
Reload daemon before enabling
jumpyvi Apr 20, 2026
3d9346e
Remove /etc bind mount
jumpyvi Apr 20, 2026
29c9bc9
Fix formating
jumpyvi Apr 21, 2026
3ba5141
Add missing path
jumpyvi Apr 21, 2026
01c1836
Add missing libvirt steps
jumpyvi Apr 21, 2026
c75c849
Fix flatpak package name
jumpyvi Apr 21, 2026
1bb7864
Add virtgl support
jumpyvi Apr 22, 2026
c1b1a98
make /etc/libvirt persistant on restart
jumpyvi Apr 22, 2026
cf455ea
Fix cask not support by linux
jumpyvi Apr 22, 2026
51746d8
Remove sysprof for now
jumpyvi Apr 22, 2026
b083d22
Fork virt-man
jumpyvi Apr 22, 2026
38161a9
Remove ydotool
jumpyvi Apr 22, 2026
cb0ce97
Firewall fixes
jumpyvi Apr 22, 2026
c7e419b
add iptables
jumpyvi Apr 22, 2026
cb51b10
re-add ydotool
jumpyvi Apr 22, 2026
024e916
ootb incus setup
jumpyvi Apr 22, 2026
8f017e7
Add acceleration support
jumpyvi Apr 22, 2026
da51a97
Rename everything for consistency
jumpyvi Apr 22, 2026
54aca3b
Fix path typo
jumpyvi Apr 22, 2026
9a82744
Rename missing quadlet
jumpyvi Apr 22, 2026
1e71bfa
Use moby from upstream brew
jumpyvi Apr 23, 2026
b8b7db7
Modularize the whole thing
jumpyvi Apr 23, 2026
1da1391
Fix flatpaks
jumpyvi Apr 23, 2026
15739c2
Fix docker paths
jumpyvi Apr 23, 2026
f05e42e
Add incus-cli
jumpyvi Apr 23, 2026
4ff964e
Swap enable for start
jumpyvi Apr 23, 2026
502cdcd
Typo
jumpyvi Apr 23, 2026
424de15
Switch back to custom docker cask
jumpyvi Apr 23, 2026
46b4722
Fix edge case where kvm isnt owned by kvm
jumpyvi Apr 24, 2026
8d0d3fb
Merge branch 'main' into dxnext
inffy Apr 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Unit]
Description=Cockpit Web Service
After=network-online.target
Wants=network-online.target sshd.service

[Container]
Image=quay.io/cockpit/ws:latest
ContainerName=cockpit-ws
Volume=/:/host:rslave
PodmanArgs=--privileged --pid=host

Network=host

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[Unit]
Description=Incus Container Service
After=network-online.target

[Container]
Image=ghcr.io/cmspam/incus-docker:nightly
AutoUpdate=registry
ContainerName=incus
PodmanArgs=--privileged --cgroupns=host --security-opt unmask=/sys/fs/cgroup --pid=host
Network=host

# Volume mappings
Volume=/dev:/dev
Volume=/var/lib/incus:/var/lib/incus
Volume=/lib/modules:/lib/modules:ro

AddDevice=/dev/kvm
AddDevice=/dev/bus/usb
Mount=type=bind,source=/dev/dri,destination=/dev/dri

[Install]
WantedBy=multi-user.target

[Service]
StateDirectory=incus
ExecStartPost=bash -c 'until [ -S /var/lib/incus/unix.socket ]; do sleep 0.2; done; chgrp incus-admin /var/lib/incus/unix.socket'
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[Unit]
Description=Libvirt Service in Podman
After=network-online.target

[Container]
Image=ghcr.io/jumpyvi/qemu-box:latest
AutoUpdate=registry
Network=host

PodmanArgs=--privileged --cgroupns=host --security-opt label=disable --pid=host

# Dbus
Mount=type=bind,source=/var/run/dbus/system_bus_socket,destination=/run/dbus/system_bus_socket

# UDev
Mount=type=bind,source=/var/run/udev,destination=/run/udev,ro

# KVV, USB Devices and OpenGL
AddDevice=/dev/kvm
AddDevice=/dev/bus/usb
Mount=type=bind,source=/dev/dri,destination=/dev/dri
Mount=type=bind,source=/var/run/libvirt-dx,destination=/run/libvirt

# Storage
Mount=type=bind,source=/var/lib/libvirt-dx,destination=/var/lib/libvirt
Volume=libvirt-conf:/etc/libvirt:Z

Exec=sh -c "chgrp kvm /dev/kvm && virtlogd -d && libvirtd"

[Install]
WantedBy=multi-user.target

[Service]
RuntimeDirectory=libvirt-dx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[Unit]
Description=Docker Application Container Engine (brew)
Documentation=https://docs.docker.com/

[Service]
ExecStart=/bin/bash -c "env PATH='$PATH:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin' /home/linuxbrew/.linuxbrew/bin/dockerd"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The use of single quotes around $PATH prevents the shell from expanding the variable, and since env does not perform shell expansion, the literal string $PATH will be prepended to the environment variable. This will likely cause dockerd to fail when looking for system binaries. Using exec is also recommended for proper process management.

ExecStart=/bin/bash -c 'PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH" exec /home/linuxbrew/.linuxbrew/bin/dockerd'

ExecReload=/bin/kill -s HUP $MAINPID

Type=notify
NotifyAccess=all
KillMode=mixed
Delegate=yes

Restart=always
RestartSec=2
StartLimitBurst=3
StartLimitInterval=60s

TimeoutSec=0
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity

[Install]
WantedBy=default.target
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

System services should generally use multi-user.target for the WantedBy directive. default.target is typically used for user-level services or as a boot alias, and using it here is inconsistent with the brew-containerd.service which correctly uses multi-user.target.

WantedBy=multi-user.target

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[Unit]
Description=Docker Application Container Engine (Brew Rootless)
Documentation=https://docs.docker.com/go/rootless/

[Service]
Environment=PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/usr/bin:/usr/sbin:/bin
Environment=XDG_RUNTIME_DIR=/run/user/%U
ExecStart=/home/linuxbrew/.linuxbrew/bin/dockerd-rootless.sh --iptables=false
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
Type=notify
NotifyAccess=all
KillMode=mixed

[Install]
WantedBy=default.target

[Install]
WantedBy=default.target
36 changes: 36 additions & 0 deletions system_files/shared/usr/share/ublue-os/homebrew/dx-next.Brewfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
tap "ublue-os/experimental-tap"
tap "ublue-os/tap"


cask "android-platform-tools"
flatpak "org.flatpak.Builder"
brew "git-svn"
brew "git-subrepo"
brew "bpftop"
brew "numactl"
brew "p7zip"
brew "podman-compose"
brew "podman-tui"
#brew "sysprof"
brew "ublue-os/experimental-tap/ydotool"

# New
brew "lima"
brew "kind"
brew "incus"
brew "squashfs"
brew "devcontainer"
vscode "ms-vscode-remote.remote-containers"
flatpak "io.podman_desktop.PodmanDesktop"

# Wall of shame
#iotop
#bcc
#bpftrace
#fonts todo
#nicstat
#osbuild-selinux
#podman-machine
#tiptop
#udica
#util-linux-script
76 changes: 76 additions & 0 deletions system_files/shared/usr/share/ublue-os/just/apps.just
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,79 @@ cncf:
fi
fi
bbrew -f "/usr/share/ublue-os/homebrew/cncf.Brewfile"

dx_justfile := "/usr/share/ublue-os/just/dx.just"
# Experimental DX mode
dx-next:
#!/usr/bin/env bash
if ! gum confirm "Enter experimental DX mode?"; then
exit 0
fi

gum style \
--border rounded \
--border-foreground 212 \
--padding "0 2" \
--margin "1 0" \
"DX-Next Environment Setup" "Please select your installation path."

MODE=$(gum choose "Default" "Customize" --header "Installation Mode")

if [ -z "$MODE" ]; then
gum style --foreground 196 "Setup cancelled."
exit 0
fi

if [ "$MODE" = "Default" ]; then
CHOICES="Virt Docker DX-Tools"
gum style --foreground 242 "Proceeding with Default options: $CHOICES"
else
echo ""
gum style --foreground 242 " Use <space> to select/deselect, <enter> to confirm"
CHOICES=$(gum choose --no-limit \
--selected="Virt,Docker,DX-Tools" \
--header="--- Select Components ---" \
--cursor.foreground 212 --selected.foreground 212 \
"Virt" "Docker" "DX-Tools" "Incus" "Cockpit")
fi

if [ -z "$CHOICES" ]; then
gum style --foreground 196 "No options selected. Exiting."
exit 0
fi

gum style --foreground 212 "󱗼 Initializing DX-Next environment..."

# Always run group setup
just -f {{dx_justfile}} dx-groups

# All subchoices
if echo "$CHOICES" | grep -q "DX-Tools"; then
just -f {{dx_justfile}} dx-tools
fi

if echo "$CHOICES" | grep -q "Docker"; then
just -f {{dx_justfile}} dx-docker
fi

if echo "$CHOICES" | grep -q "Virt"; then
just -f {{dx_justfile}} dx-virt
fi

if echo "$CHOICES" | grep -q "Incus"; then
just -f {{dx_justfile}} dx-incus
fi

if echo "$CHOICES" | grep -q "Cockpit"; then
just -f {{dx_justfile}} dx-cockpit
fi

# Final Banner
echo ""
gum style --border normal --border-foreground 212 \
"You are now testing the experimental DX mode. Please report any issues to the GitHub, or come talk with us on Discord!

󰙯 https://discord.gg/8RZGC3uFzA
 https://github.com/projectbluefin/common"

gum style --foreground 220 "⏻ Please reboot to fully apply changes."
100 changes: 100 additions & 0 deletions system_files/shared/usr/share/ublue-os/just/dx.just
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
dx_justfile := "/usr/share/ublue-os/just/dx.just"

# Add user to all DX group with sysusers, this is always ran
dx-groups:
#!/usr/bin/env bash
current=$(groups "$USER")
missing=()
for group in libvirt docker incus-admin; do
echo "$current" | grep -qw "$group" || missing+=("$group")
done

if [ ${#missing[@]} -ne 0 ]; then
gum format -- "Adding $USER to: **${missing[*]}**"
sudo mkdir -p /etc/sysusers.d/
for group in "${missing[@]}"; do echo "m $USER $group"; done | sudo tee /etc/sysusers.d/dx-groups.conf > /dev/null
sudo systemd-sysusers /etc/sysusers.d/dx-groups.conf
fi

# A developper's essential toolkit such as VSCode, podman-tui, etc
dx-tools:
#!/usr/bin/env bash
gum style --foreground 212 "󱁯 Installing DX-Tools & Base Apps..."
brew bundle --file=/usr/share/ublue-os/homebrew/dx-next.Brewfile
brew install --cask ublue-os/tap/visual-studio-code-linux

# Setup rootless and rootfull docker with brew
dx-docker:
#!/usr/bin/env bash
just -f {{dx_justfile}} dx-docker-rootless
just -f {{dx_justfile}} dx-docker-root


dx-docker-rootless:
#!/usr/bin/env bash
gum style --foreground 212 "󰡨 Setting up Rootless Docker..."

brew install docker
brew install --cask ublue-os/experimental-tap/dockerd-linux
mkdir -p ~/.config/systemd/user/
cp /usr/share/ublue-os/dx/units/user/dockerd-rootless-dx.service ~/.config/systemd/user/

systemctl --user daemon-reload
systemctl --user enable --now dockerd-rootless-dx

dx-docker-root:
#!/usr/bin/env bash
gum style --foreground 212 "󰡨 Setting up Rootfull Docker..."
sudo cp /usr/share/ublue-os/dx/units/system/dockerd-dx.service /etc/systemd/system/
brew install --cask ublue-os/experimental-tap/dockerd-linux
brew install iptables docker
sudo systemctl daemon-reload
sudo systemctl enable --now dockerd-dx
/home/linuxbrew/.linuxbrew/bin/docker context switch default


# Setup qemu/libvirt using quadlets
dx-virt:
#!/usr/bin/env bash
gum style --foreground 212 " Setting up Libvirt/QEMU..."
flatpak install -y org.virt_manager.virt-manager
flatpak install -y org.virt_manager.virt_manager.Extension.Qemu


SOCKET_DIR="/run/libvirt-dx"
echo 'SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", GROUP="libvirt"' | sudo tee /etc/udev/rules.d/50-spice-usb.rules
sudo mkdir -p /var/lib/libvirt-dx "$SOCKET_DIR"
sudo chmod 775 "$SOCKET_DIR"

if ! sudo firewall-cmd --permanent --get-zones | grep -qw libvirt; then
sudo firewall-cmd --permanent --new-zone=libvirt
fi
sudo firewall-cmd --permanent --zone=libvirt --set-target=ACCEPT
sudo firewall-cmd --reload

sudo mkdir -p /etc/containers/systemd/
sudo mkdir -p /var/lib/libvirt-dx/images/
sudo cp /usr/share/ublue-os/dx/quadlets/libvirt-dx.container /etc/containers/systemd/
sudo systemctl daemon-reload
sudo systemctl start libvirt-dx

flatpak override --user --filesystem=/run/libvirt-dx org.virt_manager.virt-manager
flatpak run org.virt_manager.virt-manager -c "qemu:///system?socket=/run/libvirt-dx/libvirt-sock" &>/dev/null &
flatpak run org.virt_manager.virt-manager -c "qemu:///session" &>/dev/null &

# Setup incus and incus-webui with quadlet
dx-incus:
#!/usr/bin/env bash
gum style --foreground "#cc3d19" " Enabling and Starting Incus..."
brew install incus
sudo cp /usr/share/ublue-os/dx/quadlets/incus-dx.container /etc/containers/systemd/
sudo systemctl daemon-reload
sudo systemctl start incus-dx

# Setup cockpit with quadlet
dx-cockpit:
#!/usr/bin/env bash
gum style --foreground "#2c77df" " Enabling and Starting Cockpit..."
sudo cp /usr/share/ublue-os/dx/quadlets/cockpit-dx.container /etc/containers/systemd/
sudo systemctl daemon-reload
sudo systemctl start cockpit-dx