working on the stateless kiosk, dynamic hostnames not yet working
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
result/
|
result/
|
||||||
result
|
result
|
||||||
|
deploy
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# This module defines the software stack for a stateless kiosk.
|
## This module defines the software stack for a stateless kiosk.
|
||||||
# It includes a custom Firefox wrapper, Cage (Wayland kiosk compositor), and specific networking configuration.
|
# It now uses Sway (Wayland compositor) and Chromium in kiosk mode.
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
@@ -9,22 +9,15 @@
|
|||||||
}:
|
}:
|
||||||
lib.mkMerge [
|
lib.mkMerge [
|
||||||
(import ./kiosk-browser.nix {
|
(import ./kiosk-browser.nix {
|
||||||
inherit
|
inherit config lib pkgs inputs;
|
||||||
config
|
})
|
||||||
lib
|
(import ./services.nix {
|
||||||
pkgs
|
inherit config lib pkgs inputs;
|
||||||
inputs
|
|
||||||
;
|
|
||||||
})
|
})
|
||||||
(import ./net.nix {
|
(import ./net.nix {
|
||||||
inherit
|
inherit config lib pkgs inputs;
|
||||||
config
|
})
|
||||||
lib
|
(import ./programs.nix {
|
||||||
pkgs
|
inherit config lib pkgs inputs;
|
||||||
inputs
|
|
||||||
;
|
|
||||||
})
|
})
|
||||||
{
|
|
||||||
services.openssh.enable = false;
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,52 +1,14 @@
|
|||||||
# This module configures Firefox for kiosk mode.
|
|
||||||
# It wraps Firefox with specific policies to disable UI elements and lock down the browser.
|
# This module configures Chromium for kiosk mode under Sway.
|
||||||
# It also includes a startup script that determines the kiosk URL based on the machine's MAC address.
|
# It includes a startup script that determines the kiosk URL based on the machine's MAC address.
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
kioskPolicies = {
|
macCaseBuilder = (import ./mac-hostmap.nix { inherit lib; }).macCaseBuilder;
|
||||||
DisableAppUpdate = true;
|
macCases = macCaseBuilder {
|
||||||
DisableFirefoxStudies = true;
|
varName = "STATION";
|
||||||
DisableTelemetry = true;
|
|
||||||
DisablePocket = true;
|
|
||||||
DisableSetDesktopBackground = true;
|
|
||||||
DisableFeedbackCommands = true;
|
|
||||||
DontCheckDefaultBrowser = true;
|
|
||||||
OverrideFirstRunPage = "";
|
|
||||||
OverridePostUpdatePage = "";
|
|
||||||
NoDefaultBookmarks = true;
|
|
||||||
DisableProfileImport = true;
|
|
||||||
|
|
||||||
Permissions = {
|
|
||||||
Camera = { Allow = ["homeassistant.lan"]; };
|
|
||||||
Microphone = { Allow = ["homeassistant.lan"]; };
|
|
||||||
Location = { Allow = ["homeassistant.lan"]; };
|
|
||||||
Notifications = { Allow = ["homeassistant.lan"]; };
|
|
||||||
Clipboard = { Allow = ["homeassistant.lan"]; };
|
|
||||||
Fullscreen = { Allow = ["homeassistant.lan"]; };
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
chromiumKiosk = pkgs.writeShellScriptBin "chromiumkiosk" ''
|
||||||
extraPrefs = pkgs.writeText "kiosk-prefs.js" ''
|
|
||||||
pref("browser.shell.checkDefaultBrowser", false);
|
|
||||||
pref("browser.startup.homepage_override.mstone", "ignore");
|
|
||||||
pref("startup.homepage_welcome_url", "");
|
|
||||||
pref("startup.homepage_welcome_url.additional", "");
|
|
||||||
pref("browser.sessionstore.resume_from_crash", false);
|
|
||||||
pref("browser.sessionstore.max_resumed_crashes", 0);
|
|
||||||
pref("network.captive-portal-service.enabled", false);
|
|
||||||
pref("network.connectivity-service.enabled", false);
|
|
||||||
pref("browser.messaging-system.whatsNewPanel.enabled", false);
|
|
||||||
pref("browser.aboutwelcome.enabled", false);
|
|
||||||
pref("privacy.popups.showBrowserMessage", false);
|
|
||||||
'';
|
|
||||||
|
|
||||||
firefoxWrapped = pkgs.wrapFirefox pkgs.firefox-unwrapped {
|
|
||||||
extraPolicies = kioskPolicies;
|
|
||||||
extraPrefsFiles = [ extraPrefs ];
|
|
||||||
};
|
|
||||||
|
|
||||||
firefoxKiosk = pkgs.writeShellScriptBin "firefoxkiosk" ''
|
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
@@ -70,12 +32,7 @@ let
|
|||||||
|
|
||||||
# Map MAC addresses to specific station IDs
|
# Map MAC addresses to specific station IDs
|
||||||
case "$MAC" in
|
case "$MAC" in
|
||||||
"00:e0:4c:46:0b:32") STATION="1" ;;
|
${macCases}
|
||||||
"00:e0:4c:46:07:26") STATION="2" ;;
|
|
||||||
"00:e0:4c:46:05:94") STATION="3" ;;
|
|
||||||
"00:e0:4c:46:07:11") STATION="4" ;;
|
|
||||||
"00:e0:4c:46:08:02") STATION="5" ;;
|
|
||||||
"00:e0:4c:46:08:5c") STATION="6" ;;
|
|
||||||
*) ;;
|
*) ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -93,31 +50,31 @@ let
|
|||||||
# Add BrowserID query param if we have one
|
# Add BrowserID query param if we have one
|
||||||
if [ -n "$BROWSER_ID" ]; then
|
if [ -n "$BROWSER_ID" ]; then
|
||||||
if [[ "$URL" == *"?"* ]]; then
|
if [[ "$URL" == *"?"* ]]; then
|
||||||
URL="$URL&BrowserID=$BROWSER_ID"
|
URL="$URL&BrowserID=$BROWSER_ID"
|
||||||
else
|
else
|
||||||
URL="$URL?BrowserID=$BROWSER_ID"
|
URL="$URL?BrowserID=$BROWSER_ID"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
exec ${firefoxWrapped}/bin/firefox --kiosk "$URL"
|
exec ${pkgs.chromium}/bin/chromium --kiosk --noerrdialogs --disable-infobars --disable-session-crashed-bubble "$URL"
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
environment.systemPackages = [ firefoxKiosk ];
|
environment.systemPackages = [
|
||||||
|
pkgs.chromium
|
||||||
|
chromiumKiosk
|
||||||
|
];
|
||||||
|
|
||||||
services.xserver.enable = false;
|
systemd.user.services.chromium-kiosk = {
|
||||||
services.seatd.enable = true;
|
description = "Chromium Kiosk";
|
||||||
|
wantedBy = [ "graphical-session.target" ];
|
||||||
services.cage = {
|
partOf = [ "graphical-session.target" ];
|
||||||
enable = true;
|
serviceConfig = {
|
||||||
user = "engr-ugaif";
|
ExecStart = "${chromiumKiosk}/bin/chromiumkiosk";
|
||||||
program = "${firefoxKiosk}/bin/firefoxkiosk";
|
Restart = "on-failure";
|
||||||
};
|
Type = "simple";
|
||||||
|
};
|
||||||
systemd.services.cage = {
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
wants = [ "network-online.target" ];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
27
sw/stateless-kiosk/mac-hostmap.nix
Normal file
27
sw/stateless-kiosk/mac-hostmap.nix
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Shared MAC address to station mapping and case builder for stateless-kiosk modules
|
||||||
|
{ lib }:
|
||||||
|
let
|
||||||
|
hostmap = {
|
||||||
|
"00:e0:4c:46:0b:32" = "1";
|
||||||
|
"00:e0:4c:46:07:26" = "2";
|
||||||
|
"00:e0:4c:46:05:94" = "3";
|
||||||
|
"00:e0:4c:46:07:11" = "4";
|
||||||
|
"00:e0:4c:46:08:02" = "5";
|
||||||
|
"00:e0:4c:46:08:5c" = "6";
|
||||||
|
};
|
||||||
|
# macCaseBuilder: builds a shell case statement from a hostmap
|
||||||
|
# varName: the shell variable to assign
|
||||||
|
# prefix: optional string to prepend to the value (default: "")
|
||||||
|
# attrset: attribute set to use (default: hostmap)
|
||||||
|
macCaseBuilder = {
|
||||||
|
varName,
|
||||||
|
prefix ? "",
|
||||||
|
attrset ? hostmap
|
||||||
|
}:
|
||||||
|
lib.concatStringsSep "\n" (
|
||||||
|
lib.mapAttrsToList (mac: val: " ${mac}) ${varName}=${prefix}${val} ;;") attrset
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit hostmap macCaseBuilder;
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
netdevs."20-vlan5" = {
|
netdevs."20-vlan5" = {
|
||||||
netdevConfig = {
|
netdevConfig = {
|
||||||
Kind = "vlan";
|
Kind = "vlan";
|
||||||
Name = "vlan5";
|
Name = "vlan5";
|
||||||
};
|
};
|
||||||
vlanConfig.Id = 5;
|
vlanConfig.Id = 5;
|
||||||
};
|
};
|
||||||
|
|||||||
7
sw/stateless-kiosk/programs.nix
Normal file
7
sw/stateless-kiosk/programs.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.sway = {
|
||||||
|
enable = true;
|
||||||
|
wrapperFeatures.gtk = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
54
sw/stateless-kiosk/services.nix
Normal file
54
sw/stateless-kiosk/services.nix
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
macCaseBuilder = (import ./mac-hostmap.nix { inherit lib; }).macCaseBuilder;
|
||||||
|
shellCases = macCaseBuilder {
|
||||||
|
varName = "NEW_HOST";
|
||||||
|
prefix = "nix-station";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.xserver.enable = false;
|
||||||
|
services.seatd.enable = true;
|
||||||
|
services.openssh.enable = true;
|
||||||
|
services.dbus.enable = true;
|
||||||
|
security.polkit.enable = true;
|
||||||
|
|
||||||
|
services.displayManager = {
|
||||||
|
autoLogin = {
|
||||||
|
enable = true;
|
||||||
|
user = "engr-ugaif";
|
||||||
|
};
|
||||||
|
|
||||||
|
sddm = {
|
||||||
|
enable = true;
|
||||||
|
wayland.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultSession = "sway";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.dynamic-hostname = {
|
||||||
|
description = "Set hostname based on MAC address";
|
||||||
|
wantedBy = [ "sysinit.target" ];
|
||||||
|
wants = [ "default.target" ];
|
||||||
|
after = [ "default.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = pkgs.writeShellScript "dynamic-hostname" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Pick first non-loopback interface with a MAC
|
||||||
|
IFACE="$(ls /sys/class/net | grep -v '^lo$' | head -n1)"
|
||||||
|
MAC="$(cat /sys/class/net/$IFACE/address | tr '[:upper:]' '[:lower:]')"
|
||||||
|
|
||||||
|
case "$MAC" in
|
||||||
|
${shellCases}
|
||||||
|
*) NEW_HOST="nix-station-unregistered" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
${pkgs.nettools}/bin/hostname "$NEW_HOST"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user