diff --git a/packages/ghaf-powercontrol/default.nix b/packages/ghaf-powercontrol/default.nix new file mode 100644 index 000000000..bd008830a --- /dev/null +++ b/packages/ghaf-powercontrol/default.nix @@ -0,0 +1,67 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + writeShellApplication, + lib, + ghafConfig, + systemd, + wlopm, + givc-cli, + ... +}: +let + inherit (builtins) replaceStrings; + inherit (lib) optionalString; + cliArgs = replaceStrings [ "\n" ] [ " " ] '' + --name ${ghafConfig.givc.adminConfig.name} + --addr ${ghafConfig.givc.adminConfig.addr} + --port ${ghafConfig.givc.adminConfig.port} + ${optionalString ghafConfig.givc.enableTls "--cacert /run/givc/ca-cert.pem"} + ${optionalString ghafConfig.givc.enableTls "--cert /run/givc/gui-vm-cert.pem"} + ${optionalString ghafConfig.givc.enableTls "--key /run/givc/gui-vm-key.pem"} + ${optionalString (!ghafConfig.givc.enableTls) "--notls"} + ''; + useGivc = ghafConfig.givc.enable; + # Handle Wayland display power state + waylandDisplayCmd = command: '' + WAYLAND_DISPLAY=/run/user/${builtins.toString ghafConfig.users.accounts.uid}/wayland-0 \ + wlopm --${command} '*' + ''; +in +writeShellApplication { + name = "ghaf-powercontrol"; + runtimeInputs = [ + systemd + wlopm + ] ++ (lib.optional useGivc givc-cli); + text = '' + case "$1" in + reboot|poweroff) + ${if useGivc then "givc-cli ${cliArgs}" else "systemctl"} "$1" + ;; + suspend) + # Lock sessions + loginctl lock-session + + # Switch off display before suspension + ${waylandDisplayCmd "off"} + + # Send suspend command to host, ensure screen is on in case of failure + ${if useGivc then "givc-cli ${cliArgs}" else "systemctl"} suspend \ + || ${waylandDisplayCmd "on"} + + # Switch on display on wakeup + ${waylandDisplayCmd "on"} + ;; + *) + echo "Unknown option. Supported: reboot, poweroff, suspend." + exit 1 + ;; + esac + ''; + + meta = { + description = "Wrapper script to control Ghaf power states using systemctl or GIVC."; + platforms = lib.platforms.linux; + }; +} diff --git a/packages/powercontrol/default.nix b/packages/powercontrol/default.nix deleted file mode 100644 index 664867dde..000000000 --- a/packages/powercontrol/default.nix +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2023 TII (SSRC) and the Ghaf contributors -# SPDX-License-Identifier: Apache-2.0 -{ - lib, - openssh, - stdenv, - writeShellScript, -}: -let - systemctl = "/run/current-system/systemd/bin/systemctl"; - busName = "org.freedesktop.login1"; - - makeSystemCtlPowerActionViaSsh = - { - hostAddress, - privateSshKeyPath, - method, - }: - writeShellScript "${method}-host" '' - ${openssh}/bin/ssh \ - -i ${privateSshKeyPath} \ - -o StrictHostKeyChecking=no \ - ghaf@${hostAddress} \ - ${systemctl} ${method}''; -in -stdenv.mkDerivation { - name = "powercontrol"; - - makePowerOffCommand = - { hostAddress, privateSshKeyPath }: - makeSystemCtlPowerActionViaSsh { - inherit hostAddress privateSshKeyPath; - method = "poweroff"; - }; - - makeRebootCommand = - { hostAddress, privateSshKeyPath }: - makeSystemCtlPowerActionViaSsh { - inherit hostAddress privateSshKeyPath; - method = "reboot"; - }; - - makeSuspendCommand = - { hostAddress, privateSshKeyPath }: - makeSystemCtlPowerActionViaSsh { - inherit hostAddress privateSshKeyPath; - method = "suspend"; - }; - - makeHibernateCommand = - { hostAddress, privateSshKeyPath }: - makeSystemCtlPowerActionViaSsh { - inherit hostAddress privateSshKeyPath; - method = "hibernate"; - }; - - polkitExtraConfig = '' - polkit.addRule(function(action, subject) { - if ((subject.user == "ghaf") && - (action.id == "${busName}.power-off" || - action.id == "${busName}.power-off-multiple-sessions" || - action.id == "${busName}.reboot" || - action.id == "${busName}.reboot-multiple-sessions" || - action.id == "${busName}.suspend" || - action.id == "${busName}.suspend-multiple-sessions" || - action.id == "${busName}.hibernate" || - action.id == "${busName}.hibernate-multiple-sessions") - ) { - return polkit.Result.YES; - } - }); - ''; - - meta = { - description = "Scripts for host power control"; - platforms = lib.platforms.linux; - }; -}