nixos: add Cua sandbox module
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
./cache-server.nix
|
||||
./cache.nix
|
||||
./code.nix
|
||||
./cua.nix
|
||||
./desktop.nix
|
||||
./electron.nix
|
||||
./environment.nix
|
||||
|
||||
246
nixos/cua.nix
Normal file
246
nixos/cua.nix
Normal file
@@ -0,0 +1,246 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.myModules.cua;
|
||||
flavorDefaults = {
|
||||
xfce = {
|
||||
image = "trycua/cua-xfce:latest";
|
||||
storageMountPath = "/home/cua/storage";
|
||||
apiContainerPort = 8000;
|
||||
noVncContainerPort = 6901;
|
||||
};
|
||||
kasm = {
|
||||
image = "trycua/cua-ubuntu:latest";
|
||||
storageMountPath = "/home/kasm-user/storage";
|
||||
apiContainerPort = 8000;
|
||||
noVncContainerPort = 6901;
|
||||
};
|
||||
qemu-linux = {
|
||||
image = "trycua/cua-qemu-linux:latest";
|
||||
storageMountPath = "/storage";
|
||||
apiContainerPort = 5000;
|
||||
noVncContainerPort = 8006;
|
||||
};
|
||||
};
|
||||
selectedFlavor = flavorDefaults.${cfg.flavor};
|
||||
usingQemu = cfg.flavor == "qemu-linux";
|
||||
in
|
||||
{
|
||||
options.myModules.cua = {
|
||||
enable = lib.mkEnableOption "Cua Linux computer-use sandbox";
|
||||
|
||||
android = {
|
||||
enable = lib.mkEnableOption "Cua Android QEMU computer-use sandbox";
|
||||
|
||||
image = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "trycua/cua-qemu-android:latest";
|
||||
description = "OCI image to run for the Cua Android QEMU sandbox.";
|
||||
};
|
||||
|
||||
bindAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Address on which to expose the Cua Android API and VNC web ports.";
|
||||
};
|
||||
|
||||
apiPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8001;
|
||||
description = "Host port for the Cua Android computer-server API.";
|
||||
};
|
||||
|
||||
webVncPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 6080;
|
||||
description = "Host port for the Cua Android VNC web UI.";
|
||||
};
|
||||
|
||||
emulatorDevice = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "Samsung Galaxy S10";
|
||||
description = "Android emulator device profile.";
|
||||
};
|
||||
|
||||
autoStart = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to start the Cua Android sandbox automatically.";
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to open the Cua Android API and VNC web ports in the firewall.";
|
||||
};
|
||||
|
||||
extraOptions = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra options passed to the Cua Android container runtime.";
|
||||
};
|
||||
};
|
||||
|
||||
flavor = lib.mkOption {
|
||||
type = lib.types.enum [ "xfce" "kasm" "qemu-linux" ];
|
||||
default = "xfce";
|
||||
description = "Cua Linux sandbox flavor to run.";
|
||||
};
|
||||
|
||||
image = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = selectedFlavor.image;
|
||||
defaultText = "upstream default image for the selected Cua flavor";
|
||||
description = "OCI image to run for the Cua Linux sandbox.";
|
||||
};
|
||||
|
||||
storageDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/cua/linux";
|
||||
description = "Host directory used for persistent Cua VM storage.";
|
||||
};
|
||||
|
||||
bindAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Address on which to expose the Cua API and noVNC ports.";
|
||||
};
|
||||
|
||||
apiPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = selectedFlavor.apiContainerPort;
|
||||
defaultText = "upstream API port for the selected Cua flavor";
|
||||
description = "Host port for the Cua computer-server API.";
|
||||
};
|
||||
|
||||
noVncPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = selectedFlavor.noVncContainerPort;
|
||||
defaultText = "upstream noVNC port for the selected Cua flavor";
|
||||
description = "Host port for the Cua noVNC web UI.";
|
||||
};
|
||||
|
||||
vncPort = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.port;
|
||||
default = 5901;
|
||||
description = "Optional host port for direct VNC access. Only used by the XFCE flavor.";
|
||||
};
|
||||
|
||||
vncResolution = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "1024x768";
|
||||
description = "VNC desktop resolution for the Cua XFCE container.";
|
||||
};
|
||||
|
||||
ramSize = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "8G";
|
||||
description = "RAM allocated to the Cua QEMU VM.";
|
||||
};
|
||||
|
||||
cpuCores = lib.mkOption {
|
||||
type = lib.types.ints.positive;
|
||||
default = 4;
|
||||
description = "CPU cores allocated to the Cua QEMU VM.";
|
||||
};
|
||||
|
||||
diskSize = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "64G";
|
||||
description = "Disk size allocated to the Cua QEMU VM. Only used by the QEMU Linux flavor.";
|
||||
};
|
||||
|
||||
shmSize = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "512m";
|
||||
description = "Shared-memory size for non-QEMU Cua desktop containers.";
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to open the Cua API and noVNC ports in the firewall.";
|
||||
};
|
||||
|
||||
autoStart = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to start the Cua sandbox container automatically.";
|
||||
};
|
||||
|
||||
extraOptions = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Extra options passed to the container runtime.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
virtualisation.docker.enable = true;
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${toString cfg.storageDir} 0750 root root -"
|
||||
];
|
||||
|
||||
virtualisation.oci-containers.containers = {
|
||||
cua-sandbox = {
|
||||
image = cfg.image;
|
||||
autoStart = cfg.autoStart;
|
||||
ports = [
|
||||
"${cfg.bindAddress}:${toString cfg.noVncPort}:${toString selectedFlavor.noVncContainerPort}"
|
||||
"${cfg.bindAddress}:${toString cfg.apiPort}:${toString selectedFlavor.apiContainerPort}"
|
||||
]
|
||||
++ lib.optionals (cfg.flavor == "xfce" && cfg.vncPort != null) [
|
||||
"${cfg.bindAddress}:${toString cfg.vncPort}:5901"
|
||||
];
|
||||
volumes = [
|
||||
"${toString cfg.storageDir}:${selectedFlavor.storageMountPath}"
|
||||
];
|
||||
devices = lib.optionals usingQemu [
|
||||
"/dev/kvm:/dev/kvm"
|
||||
];
|
||||
capabilities = lib.optionalAttrs usingQemu {
|
||||
NET_ADMIN = true;
|
||||
};
|
||||
environment =
|
||||
lib.optionalAttrs usingQemu {
|
||||
RAM_SIZE = cfg.ramSize;
|
||||
CPU_CORES = toString cfg.cpuCores;
|
||||
DISK_SIZE = cfg.diskSize;
|
||||
}
|
||||
// lib.optionalAttrs (cfg.flavor == "xfce") {
|
||||
VNC_RESOLUTION = cfg.vncResolution;
|
||||
}
|
||||
// lib.optionalAttrs (cfg.flavor == "kasm") {
|
||||
VNCOPTIONS = "-disableBasicAuth";
|
||||
};
|
||||
extraOptions =
|
||||
lib.optionals (!usingQemu) [ "--shm-size=${cfg.shmSize}" ]
|
||||
++ cfg.extraOptions;
|
||||
};
|
||||
cua-android = lib.mkIf cfg.android.enable {
|
||||
image = cfg.android.image;
|
||||
autoStart = cfg.android.autoStart;
|
||||
ports = [
|
||||
"${cfg.android.bindAddress}:${toString cfg.android.webVncPort}:6080"
|
||||
"${cfg.android.bindAddress}:${toString cfg.android.apiPort}:8000"
|
||||
];
|
||||
devices = [
|
||||
"/dev/kvm:/dev/kvm"
|
||||
];
|
||||
environment = {
|
||||
EMULATOR_DEVICE = cfg.android.emulatorDevice;
|
||||
WEB_VNC = "true";
|
||||
};
|
||||
extraOptions = cfg.android.extraOptions;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts =
|
||||
lib.optionals cfg.openFirewall (
|
||||
[ cfg.apiPort cfg.noVncPort ]
|
||||
++ lib.optional (cfg.flavor == "xfce" && cfg.vncPort != null) cfg.vncPort
|
||||
)
|
||||
++ lib.optionals cfg.android.openFirewall [ cfg.android.apiPort cfg.android.webVncPort ];
|
||||
};
|
||||
}
|
||||
@@ -19,6 +19,15 @@
|
||||
myModules.gitea-runner.enable = true;
|
||||
myModules.postgres.enable = true;
|
||||
myModules.tts.enable = true;
|
||||
myModules.cua = {
|
||||
enable = true;
|
||||
android = {
|
||||
enable = true;
|
||||
# Android is QEMU/KVM-only. Keep this manually startable until SVM/AMD-V
|
||||
# is exposed to Linux and /dev/kvm exists on this host.
|
||||
autoStart = false;
|
||||
};
|
||||
};
|
||||
myModules.railbird-k3s = {
|
||||
enable = false;
|
||||
serverAddr = "https://jimi-hendnix.local:6443";
|
||||
|
||||
Reference in New Issue
Block a user