diff options
Diffstat (limited to 'nixos/modules/virtualisation/nixos-container.sh')
-rw-r--r-- | nixos/modules/virtualisation/nixos-container.sh | 106 |
1 files changed, 95 insertions, 11 deletions
diff --git a/nixos/modules/virtualisation/nixos-container.sh b/nixos/modules/virtualisation/nixos-container.sh index f4e34588d6eb..c72b6fb92814 100644 --- a/nixos/modules/virtualisation/nixos-container.sh +++ b/nixos/modules/virtualisation/nixos-container.sh @@ -1,15 +1,21 @@ #! @bash@/bin/sh -e usage() { - echo "Usage: $0 login <container-name>" >&2 + echo "Usage: $0 create <container-name> [--config <filename>]" >&2 + echo " $0 update <container-name>" >&2 + echo " $0 destroy <container-name>" >&2 + echo " $0 login <container-name>" >&2 echo " $0 root-shell <container-name>" >&2 + echo " $0 set-root-password <container-name> <password>" >&2 } -args="`getopt --options '' -l help -- "$@"`" +args="`getopt --options '' -l help -l config: -- "$@"`" eval "set -- $args" +extraConfigFile= while [ $# -gt 0 ]; do case "$1" in (--help) usage; exit 0;; + (--config) shift; extraConfigFile=$1;; (--) shift; break;; (*) break;; esac @@ -28,26 +34,104 @@ getContainerRoot() { fi } -if [ $action = login ]; then +container="$1" +if [ -z "$container" ]; then usage; exit 1; fi +shift - container="$1" - if [ -z "$container" ]; then usage; exit 1; fi - shift +if [ $action = create ]; then + + confFile="/etc/containers/$container.conf" + root="/var/lib/containers/$container" + + if [ -e "$confFile" -o -e "$root/nix" ]; then + echo "$0: container ‘$container’ already exists" >&2 + exit 1 + fi + + profileDir="/nix/var/nix/profiles/per-container/$container" + mkdir -m 0755 -p "$root/etc/nixos" "$profileDir" + + config=" +{ config, pkgs, ... }: + +with pkgs.lib; + +{ boot.isContainer = true; + security.initialRootPassword = mkDefault \"!\"; + networking.hostName = mkDefault \"$container\"; + networking.useDHCP = false; + imports = [ <nixpkgs/nixos/modules/virtualisation/container-login.nix> $extraConfigFile ]; +}" + configFile="$root/etc/nixos/configuration.nix" + echo "$config" > "$configFile" + + nix-env -p "$profileDir/system" -I "nixos-config=$configFile" -f '<nixpkgs/nixos>' --set -A system + + # Allocate a new /8 network in the 10.233.* range. + network="$(sed -e 's/.*_ADDRESS=10\.233\.\(.*\)\..*/\1/; t; d' /etc/containers/*.conf | sort -n | tail -n1)" + if [ -z "$network" ]; then network=0; else : $((network++)); fi + + hostAddress="10.233.$network.1" + localAddress="10.233.$network.2" + echo "host IP is $hostAddress, container IP is $localAddress" >&2 + + cat > "$confFile" <<EOF +PRIVATE_NETWORK=1 +HOST_ADDRESS=$hostAddress +LOCAL_ADDRESS=$localAddress +EOF + + echo "starting container@$container.service..." >&2 + systemctl start "container@$container.service" + +elif [ $action = update ]; then getContainerRoot - exec @socat@/bin/socat "unix:$root/var/lib/login.socket" -,echo=0,raw + configFile="$root/etc/nixos/configuration.nix" + profileDir="/nix/var/nix/profiles/per-container/$container" -elif [ $action = root-shell ]; then + nix-env -p "$profileDir/system" -I "nixos-config=$configFile" -f '<nixpkgs/nixos>' --set -A system - container="$1" - if [ -z "$container" ]; then usage; exit 1; fi - shift + echo "reloading container@$container.service..." >&2 + systemctl reload "container@$container.service" + +elif [ $action = destroy ]; then getContainerRoot + confFile="/etc/containers/$container.conf" + if [ ! -w "$confFile" ]; then + echo "$0: cannot destroy declarative container (remove it from your configuration.nix instead)" + exit 1 + fi + + if systemctl show "container@$container.service" | grep -q ActiveState=active; then + echo "stopping container@$container.service..." >&2 + systemctl stop "container@$container.service" + fi + + rm -f "$confFile" + +elif [ $action = login ]; then + + getContainerRoot + exec @socat@/bin/socat "unix:$root/var/lib/login.socket" -,echo=0,raw + +elif [ $action = root-shell ]; then + + getContainerRoot exec @socat@/bin/socat "unix:$root/var/lib/root-shell.socket" - +elif [ $action = set-root-password ]; then + + password="$1" + if [ -z "$password" ]; then usage; exit 1; fi + + # FIXME: not very secure. + getContainerRoot + (echo "passwd"; echo "$password"; echo "$password") | @socat@/bin/socat "unix:$root/var/lib/root-shell.socket" - + else echo "$0: unknown action ‘$action’" >&2 exit 1 |