summary refs log tree commit diff
path: root/pkgs/tools/virtualization/nixos-container/nixos-container.pl
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/tools/virtualization/nixos-container/nixos-container.pl')
-rwxr-xr-xpkgs/tools/virtualization/nixos-container/nixos-container.pl79
1 files changed, 64 insertions, 15 deletions
diff --git a/pkgs/tools/virtualization/nixos-container/nixos-container.pl b/pkgs/tools/virtualization/nixos-container/nixos-container.pl
index 2a9625501b6..0ba0d5546a0 100755
--- a/pkgs/tools/virtualization/nixos-container/nixos-container.pl
+++ b/pkgs/tools/virtualization/nixos-container/nixos-container.pl
@@ -22,13 +22,27 @@ $ENV{"NIXOS_CONFIG"} = "";
 sub showHelp {
     print <<EOF;
 Usage: nixos-container list
-       nixos-container create <container-name> [--nixos-path <path>] [--system-path <path>] [--config-file <path>] [--config <string>] [--ensure-unique-name] [--auto-start] [--bridge <iface>] [--port <port>] [--host-address <string>] [--local-address <string>]
+       nixos-container create <container-name>
+         [--nixos-path <path>]
+         [--system-path <path>]
+         [--config <string>]
+         [--config-file <path>]
+         [--flake <flakeref>]
+         [--ensure-unique-name]
+         [--auto-start]
+         [--bridge <iface>]
+         [--port <port>]
+         [--host-address <string>]
+         [--local-address <string>]
        nixos-container destroy <container-name>
        nixos-container start <container-name>
        nixos-container stop <container-name>
        nixos-container terminate <container-name>
        nixos-container status <container-name>
-       nixos-container update <container-name> [--config <string>] [--config-file <path>]
+       nixos-container update <container-name>
+         [--config <string>]
+         [--config-file <path>]
+         [--flake <flakeref>]
        nixos-container login <container-name>
        nixos-container root-login <container-name>
        nixos-container run <container-name> -- args...
@@ -49,6 +63,8 @@ my $signal;
 my $configFile;
 my $hostAddress;
 my $localAddress;
+my $flake;
+my $flakeAttr = "container";
 
 GetOptions(
     "help" => sub { showHelp() },
@@ -63,6 +79,7 @@ GetOptions(
     "config-file=s" => \$configFile,
     "host-address=s" => \$hostAddress,
     "local-address=s" => \$localAddress,
+    "flake=s" => \$flake,
     ) or exit 1;
 
 if (defined $hostAddress and !defined $localAddress or defined $localAddress and !defined $hostAddress) {
@@ -73,7 +90,12 @@ my $action = $ARGV[0] or die "$0: no action specified\n";
 
 if (defined $configFile and defined $extraConfig) {
     die "--config and --config-file are mutually incompatible. " .
-        "Please define on or the other, but not both";
+        "Please define one or the other, but not both";
+}
+
+if (defined $flake && $flake =~ /^(.*)#([^#"]+)$/) {
+    $flake = $1;
+    $flakeAttr = $2;
 }
 
 # Execute the selected action.
@@ -97,8 +119,6 @@ sub writeNixOSConfig {
 
     my $localExtraConfig = "";
 
-
-
     if ($extraConfig) {
         $localExtraConfig = $extraConfig
     } elsif ($configFile) {
@@ -121,6 +141,14 @@ EOF
     write_file($nixosConfigFile, $nixosConfig);
 }
 
+sub buildFlake {
+    system("nix", "build", "-o", "$systemPath.tmp", "--",
+           "$flake#nixosConfigurations.\"$flakeAttr\".config.system.build.toplevel") == 0
+        or die "$0: failed to build container from flake '$flake'\n";
+    $systemPath = readlink("$systemPath.tmp") or die;
+    unlink("$systemPath.tmp");
+}
+
 if ($action eq "create") {
     # Acquire an exclusive lock to prevent races with other
     # invocations of ‘nixos-container create’.
@@ -176,6 +204,7 @@ if ($action eq "create") {
     push @conf, "HOST_BRIDGE=$bridge\n";
     push @conf, "HOST_PORT=$port\n";
     push @conf, "AUTO_START=$autoStart\n";
+    push @conf, "FLAKE=$flake\n" if defined $flake;
     write_file($confFile, \@conf);
 
     close($lock);
@@ -191,6 +220,10 @@ if ($action eq "create") {
     mkpath($profileDir, 0, 0755);
 
     # Build/set the initial configuration.
+    if (defined $flake) {
+        buildFlake();
+    }
+
     if (defined $systemPath) {
         system("nix-env", "-p", "$profileDir/system", "--set", $systemPath) == 0
             or die "$0: failed to set initial container configuration\n";
@@ -326,19 +359,35 @@ elsif ($action eq "status") {
 }
 
 elsif ($action eq "update") {
-    my $nixosConfigFile = "$root/etc/nixos/configuration.nix";
 
-    # FIXME: may want to be more careful about clobbering the existing
-    # configuration.nix.
-    if ((defined $extraConfig && $extraConfig ne "") ||
-         (defined $configFile && $configFile ne "")) {
-        writeNixOSConfig $nixosConfigFile;
+    # Unless overriden on the command line, rebuild the flake recorded
+    # in the container config file. FIXME: read the container config
+    # in a more sensible way.
+    if (!defined $flake && !defined $configFile && !defined $extraConfig) {
+        my $s = read_file($confFile);
+        $s =~ /^FLAKE=(.*)$/m;
+        $flake = $1;
     }
 
-    system("nix-env", "-p", "$profileDir/system",
-           "-I", "nixos-config=$nixosConfigFile", "-f", "<nixpkgs/nixos>",
-           "--set", "-A", "system") == 0
-        or die "$0: failed to build container configuration\n";
+    if (defined $flake) {
+        buildFlake();
+        system("nix-env", "-p", "$profileDir/system", "--set", $systemPath) == 0
+            or die "$0: failed to set container configuration\n";
+    } else {
+        my $nixosConfigFile = "$root/etc/nixos/configuration.nix";
+
+        # FIXME: may want to be more careful about clobbering the existing
+        # configuration.nix.
+        if ((defined $extraConfig && $extraConfig ne "") ||
+            (defined $configFile && $configFile ne "")) {
+            writeNixOSConfig $nixosConfigFile;
+        }
+
+        system("nix-env", "-p", "$profileDir/system",
+               "-I", "nixos-config=$nixosConfigFile", "-f", "<nixpkgs/nixos>",
+               "--set", "-A", "system") == 0
+            or die "$0: failed to build container configuration\n";
+    }
 
     if (isContainerRunning) {
         print STDERR "reloading container...\n";