diff --git a/modules/desktop/graphics/labwc.config.nix b/modules/desktop/graphics/labwc.config.nix
index 160f420ca..148c9445d 100644
--- a/modules/desktop/graphics/labwc.config.nix
+++ b/modules/desktop/graphics/labwc.config.nix
@@ -7,6 +7,8 @@
...
}: let
cfg = config.ghaf.graphics.labwc;
+
+ audio-ctrl = pkgs.callPackage ../../../packages/audio-ctrl {};
gtklockStyle = pkgs.writeText "gtklock.css" ''
window {
background: rgba(29, 29, 29, 1);
@@ -101,10 +103,19 @@
''}
-
+
-
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/microvm/virtualization/microvm/audiovm.nix b/modules/microvm/virtualization/microvm/audiovm.nix
index 25960b67b..6813393bb 100644
--- a/modules/microvm/virtualization/microvm/audiovm.nix
+++ b/modules/microvm/virtualization/microvm/audiovm.nix
@@ -3,11 +3,19 @@
{
config,
lib,
+ pkgs,
...
}: let
configHost = config;
vmName = "audio-vm";
macAddress = "02:00:00:03:03:03";
+ isGuiVmEnabled = config.ghaf.virtualization.microvm.guivm.enable;
+
+ sshKeysHelper = pkgs.callPackage ../../../../packages/ssh-keys-helper {
+ inherit pkgs;
+ inherit config;
+ };
+
audiovmBaseConfiguration = {
imports = [
(import ./common/vm-networking.nix {
@@ -59,18 +67,29 @@
hostPlatform.system = configHost.nixpkgs.hostPlatform.system;
};
+ services.openssh = config.ghaf.security.sshKeys.sshAuthorizedKeysCommand;
+
microvm = {
optimize.enable = true;
vcpu = 1;
mem = 256;
hypervisor = "qemu";
- shares = [
- {
- tag = "ro-store";
- source = "/nix/store";
- mountPoint = "/nix/.ro-store";
- }
- ];
+ shares =
+ [
+ {
+ tag = "ro-store";
+ source = "/nix/store";
+ mountPoint = "/nix/.ro-store";
+ }
+ ]
+ ++ lib.optionals isGuiVmEnabled [
+ {
+ # Add the waypipe-ssh public key to the microvm
+ tag = config.ghaf.security.sshKeys.waypipeSshPublicKeyName;
+ source = config.ghaf.security.sshKeys.waypipeSshPublicKeyDir;
+ mountPoint = config.ghaf.security.sshKeys.waypipeSshPublicKeyDir;
+ }
+ ];
writableStoreOverlay = lib.mkIf config.ghaf.development.debug.tools.enable "/nix/.rw-store";
qemu = {
machine =
@@ -83,7 +102,15 @@
};
};
+ fileSystems = lib.mkIf isGuiVmEnabled {${config.ghaf.security.sshKeys.waypipeSshPublicKeyDir}.options = ["ro"];};
+
# Fixed IP-address for debugging subnet
+ # SSH is very picky about to file permissions and ownership and will
+ # accept neither direct path inside /nix/store or symlink that points
+ # there. Therefore we copy the file to /etc/ssh/get-auth-keys (by
+ # setting mode), instead of symlinking it.
+ environment.etc = lib.mkIf isGuiVmEnabled {${config.ghaf.security.sshKeys.getAuthKeysFilePathInEtc} = sshKeysHelper.getAuthKeysSource;};
+
systemd.network.networks."10-ethint0".addresses = let
getAudioVmEntry = builtins.filter (x: x.name == "audio-vm-debug") config.ghaf.networking.hosts.entries;
ip = lib.head (builtins.map (x: x.ip) getAudioVmEntry);
diff --git a/packages/audio-ctrl/default.nix b/packages/audio-ctrl/default.nix
new file mode 100644
index 000000000..7380fbacd
--- /dev/null
+++ b/packages/audio-ctrl/default.nix
@@ -0,0 +1,43 @@
+# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# This is a temporary solution for volume control.
+#
+{
+ openssh,
+ writeShellApplication,
+ ...
+}:
+writeShellApplication {
+ name = "audio-ctrl";
+ runtimeInputs = [
+ openssh
+ ];
+ text = ''
+ function pamixer {
+ # Connect to audio-vm
+ output=$(ssh -q ghaf@audio-vm \
+ -i /run/waypipe-ssh/id_ed25519 \
+ -o StrictHostKeyChecking=no \
+ -o UserKnownHostsFile=/dev/null \
+ "pamixer $1")
+ }
+
+ case "$1" in
+ inc)
+ pamixer "-i 5"
+ ;;
+ dec)
+ pamixer "-d 5"
+ ;;
+ mut)
+ pamixer "--get-mute"
+ if [ "$output" = "false" ]; then
+ pamixer "-m"
+ else
+ pamixer "-u"
+ fi
+ ;;
+ esac
+ '';
+}
diff --git a/packages/nm-launcher/default.nix b/packages/nm-launcher/default.nix
index a8a43fe2d..f41f570f4 100644
--- a/packages/nm-launcher/default.nix
+++ b/packages/nm-launcher/default.nix
@@ -21,6 +21,7 @@ writeShellApplication {
-f -N -q ghaf@net-vm \
-i /run/waypipe-ssh/id_ed25519 \
-o StrictHostKeyChecking=no \
+ -o UserKnownHostsFile=/dev/null \
-o StreamLocalBindUnlink=yes \
-o ExitOnForwardFailure=yes \
-L /tmp/ssh_session_dbus.sock:/run/user/1000/bus \
diff --git a/packages/wifi-signal-strength/default.nix b/packages/wifi-signal-strength/default.nix
index 2442843a5..6f3420808 100644
--- a/packages/wifi-signal-strength/default.nix
+++ b/packages/wifi-signal-strength/default.nix
@@ -1,71 +1,65 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{
- stdenvNoCC,
- pkgs,
+ networkmanager,
+ openssh,
+ util-linux,
+ gawk,
+ coreutils-full,
+ writeShellApplication,
wifiDevice,
...
-}: let
- wifiSignalStrength =
- pkgs.writeShellScript
- "wifi-signal-strength"
- ''
- NETWORK_STATUS_FILE=/tmp/network-status
+}:
+writeShellApplication {
+ name = "wifi-signal-strength";
+ runtimeInputs = [
+ networkmanager
+ openssh
+ gawk
+ util-linux
+ coreutils-full
+ ];
+ text = ''
+ NETWORK_STATUS_FILE=/tmp/network-status
- export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/ssh_session_dbus.sock
- export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/tmp/ssh_system_dbus.sock
+ export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/ssh_session_dbus.sock
+ export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/tmp/ssh_system_dbus.sock
- # Lock the script to reuse
- LOCK_FILE=/tmp/wifi-signal.lock
- exec 99>"$LOCK_FILE"
- ${pkgs.util-linux}/bin/flock -w 60 -x 99 || exit 1
+ # Lock the script to reuse
+ LOCK_FILE=/tmp/wifi-signal.lock
+ exec 99>"$LOCK_FILE"
+ flock -w 60 -x 99 || exit 1
- # Return the result as json format for waybar and use the control socket to close the ssh tunnel.
- trap "${pkgs.openssh}/bin/ssh -q -S /tmp/nmcli_socket -O exit ghaf@net-vm && ${pkgs.coreutils-full}/bin/cat $NETWORK_STATUS_FILE" EXIT
+ # Return the result as json format for waybar and use the control socket to close the ssh tunnel.
+ trap 'ssh -q -S /tmp/nmcli_socket -O exit ghaf@net-vm && cat "$NETWORK_STATUS_FILE"' EXIT
- # Connect to netvm
- ${pkgs.openssh}/bin/ssh -M -S /tmp/nmcli_socket \
- -f -N -q ghaf@net-vm \
- -i /run/waypipe-ssh/id_ed25519 \
- -o StrictHostKeyChecking=no \
- -o StreamLocalBindUnlink=yes \
- -o ExitOnForwardFailure=yes \
- -L /tmp/ssh_session_dbus.sock:/run/user/1000/bus \
- -L /tmp/ssh_system_dbus.sock:/run/dbus/system_bus_socket
- signal0=
- signal1=
- signal2=
- signal3=
- no_signal=
- # Get IP address of netvm
- address=$(${pkgs.networkmanager}/bin/nmcli device show ${wifiDevice} | ${pkgs.gawk}/bin/awk '{ if ($1=="IP4.ADDRESS[1]:") {print $2}}')
- # Get signal strength and ssid
- connection=($(${pkgs.networkmanager}/bin/nmcli -f IN-USE,SIGNAL,SSID dev wifi | ${pkgs.gawk}/bin/awk '/^\*/{if (NR!=1) {print $2; print $3}}'))
- connection[0]=$(if [ -z ''${connection[0]} ]; then echo "-1"; else echo ''${connection[0]}; fi)
- # Set the icon of signal level
- signal_level=$(if [ ''${connection[0]} -gt 80 ]; then echo $signal3; elif [ ''${connection[0]} -gt 60 ]; then echo $signal2; elif [ ''${connection[0]} -gt 30 ]; then echo $signal1; elif [ ''${connection[0]} -gt 0 ]; then echo signal0; else echo $no_signal; fi)
- tooltip=$(if [ -z $address ]; then echo ''${connection[0]}%; else echo $address ''${connection[0]}%; fi)
- text=$(if [ -z ''${connection[1]} ]; then echo "No connection"; else echo ''${connection[1]} $signal_level; fi)
- # Save the result in json format
- RESULT="{\"percentage\":\""''${connection[0]}"\", \"text\":\""$text"\", \"tooltip\":\""$tooltip"\", \"class\":\"1\"}"
- echo $RESULT>/tmp/network-status
- ${pkgs.util-linux}/bin/flock -u 99
- '';
-in
- stdenvNoCC.mkDerivation {
- name = "wifi-signal-strength";
-
- phases = ["installPhase"];
-
- installPhase = ''
- mkdir -p $out/bin
- cp ${wifiSignalStrength} $out/bin/wifi-signal-strength
- '';
-
- meta = {
- description = "Script to get wifi data from nmcli to show network of netvm using D-Bus over SSH on Waybar.";
- platforms = [
- "x86_64-linux"
- ];
- };
- }
+ # Connect to netvm
+ ssh -M -S /tmp/nmcli_socket \
+ -f -N -q ghaf@net-vm \
+ -i /run/waypipe-ssh/id_ed25519 \
+ -o StrictHostKeyChecking=no \
+ -o UserKnownHostsFile=/dev/null \
+ -o StreamLocalBindUnlink=yes \
+ -o ExitOnForwardFailure=yes \
+ -L /tmp/ssh_session_dbus.sock:/run/user/1000/bus \
+ -L /tmp/ssh_system_dbus.sock:/run/dbus/system_bus_socket
+ signal0="\UF091F"
+ signal1="\UF0922"
+ signal2="\UF0925"
+ signal3="\UF0928"
+ no_signal="\UF092D"
+ # Get IP address of netvm
+ address=$(nmcli device show ${wifiDevice} | awk '{ if ($1=="IP4.ADDRESS[1]:") {print $2}}')
+ # Get signal strength and ssi
+ mapfile -t connection < <(nmcli -f IN-USE,SIGNAL,SSID dev wifi | awk '/^\*/{if (NR!=1) {print $2; print $3}}')
+ connection[0]=$(if [ -z "''${connection[0]}" ]; then echo "-1"; else echo "''${connection[0]}"; fi)
+ # Set the icon of signal level
+ signal_level=$(if [ "''${connection[0]}" -gt 80 ]; then echo "''${signal3}"; elif [ "''${connection[0]}" -gt 60 ]; then echo "''${signal2}"; elif [ "''${connection[0]}" -gt 30 ]; then echo "''${signal1}"; elif [ "''${connection[0]}" -gt 0 ]; then echo "''${signal0};" else echo "''${no_signal}"; fi)
+ tooltip=$(if [ -z "''${address}" ]; then echo "''${connection[0]}%"; else echo "''${address} ''${connection[0]}%"; fi)
+ text=$(if [ -z "''${connection[1]}" ]; then echo "No connection"; else echo "''${connection[1]} $signal_level"; fi)
+ # Save the result in json format
+ RESULT="{\"percentage\":\"''${connection[0]}\", \"text\":\"''${text}\", \"tooltip\":\"''${tooltip}\", \"class\":\"1\"}"
+ echo -e "$RESULT">/tmp/network-status
+ flock -u 99
+ '';
+}