Author: eelco
Date: Mon May 9 12:38:36 2011
New Revision: 27195
URL: https://svn.nixos.org/websvn/nix/?rev=27195&sc=1
Log:
* Refactoring.
Modified:
cloud/trunk/default.nix
cloud/trunk/src/nixos-deploy-network.pl
Modified: cloud/trunk/default.nix
==============================================================================
--- cloud/trunk/default.nix Mon May 9 09:36:53 2011 (r27194)
+++ cloud/trunk/default.nix Mon May 9 12:38:36 2011 (r27195)
@@ -3,7 +3,7 @@
stdenv.mkDerivation {
name = "nixos-deploy-network";
- src = ./src;
+ src = lib.cleanSource ./src;
buildInputs = [ perl makeWrapper perlPackages.XMLLibXML perlPackages.JSON ];
Modified: cloud/trunk/src/nixos-deploy-network.pl
==============================================================================
--- cloud/trunk/src/nixos-deploy-network.pl Mon May 9 09:36:53 2011
(r27194)
+++ cloud/trunk/src/nixos-deploy-network.pl Mon May 9 12:38:36 2011
(r27195)
@@ -1,5 +1,6 @@
#! /var/run/current-system/sw/bin/perl -w
+use strict;
use utf8;
use XML::LibXML;
use Cwd;
@@ -8,13 +9,24 @@
binmode(STDERR, ":utf8");
-# !!! Cleanly separate $state->{machines} (the deployment state) and
-# @machines (the deployment specification).
-
my @networkExprs;
-my @machines = ();
-my $outPath;
+
+# The deployment specification, obtained by evaluating the Nix
+# expressions specified by the user. $spec->{machines} is a mapping
+# from machine names (i.e. attribute names in the input) to a hash
+# containing the desired deployment characteristics of the
+# corresponding machine. E.g., $spec->{machines}->{foo}->{targetEnv}
+# contains the target environment type of machine ‘foo’ (e.g., ‘ec2’).
+my $spec;
+
+# The current deployment state, containing information about
+# previously created or initialised (virtual) machines. In
+# particular, $state->{machines} is a mapping from machine names to a
+# hash containing info about the corresponding machine, such as its IP
+# address. E.g., $state->{machines}->{foo}->{ipv6} contains the IPv6
+# address of machine ‘foo’.
my $state;
+
my $stateFile = "./state.json";
my $myDir = dirname(Cwd::abs_path($0));
@@ -35,11 +47,11 @@
startMachines();
# Evaluate and build each machine configuration locally.
- buildConfigs();
+ my $outPath = buildConfigs();
# Copy the closures of each machine configuration to the
# corresponding target machine.
- copyClosures();
+ copyClosures($outPath);
# Activate the new configuration on each machine, and do a
# rollback if any fails.
@@ -81,7 +93,7 @@
} else {
die "machine ‘$name’ has an unknown target environment type
‘$targetEnv’";
}
- push @machines, $info;
+ $spec->{machines}->{$name} = $info;
}
}
@@ -106,9 +118,9 @@
sub startMachines {
- foreach my $machine (@machines) {
-
- my $prevMachine = $state->{machines}->{$machine->{name}};
+ foreach my $name (keys %{$spec->{machines}}) {
+ my $machine = $spec->{machines}->{$name};
+ my $prevMachine = $state->{machines}->{$name};
if (defined $prevMachine) {
# So we already created/used a machine in a previous
@@ -118,13 +130,12 @@
if ($machine->{targetEnv} eq $prevMachine->{targetEnv}) {
# !!! Also check that parameters like the EC2 are the
# same.
- $machine->{ipv6} = $prevMachine->{ipv6}; # !!! hack
- print STDERR "machine ‘$machine->{name}’ already exists\n";
+ print STDERR "machine ‘$name’ already exists\n";
next;
}
# !!! Handle killing cloud VMs, etc. When killing a VM,
# make sure it's not marked as precious.
- die "machine ‘$machine->{name}’ was previously created with
incompatible deployment parameters\n";
+ die "machine ‘$name’ was previously created with incompatible
deployment parameters\n";
}
if ($machine->{targetEnv} eq "none") {
@@ -133,29 +144,28 @@
elsif ($machine->{targetEnv} eq "adhoc") {
- print STDERR "starting missing VM ‘$machine->{name}’...\n";
+ print STDERR "starting missing VM ‘$name’...\n";
my $vmId = `ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{createVMCommand}`;
die "unable to start VM: $?" unless $? == 0;
chomp $vmId;
- $machine->{vmId} = $vmId;
-
- $ipv6 = `ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{queryVMCommand} $machine->{vmId} 2> /dev/null`;
+ my $ipv6 = `ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{queryVMCommand} $vmId 2> /dev/null`;
die "unable to query VM state: $?" unless $? == 0;
-
chomp $ipv6;
- $machine->{ipv6} = $ipv6;
print STDERR "IPv6 address is $ipv6\n";
- $state->{machines}->{$machine->{name}} =
+ $state->{machines}->{$name} =
{ targetEnv => $machine->{targetEnv}
- , vmId => $machine->{vmId}
- , ipv6 => $machine->{ipv6}
+ , vmId => $vmId
+ , ipv6 => $ipv6
+ , # Need to remember these so that we know how to kill
+ # the VM later, among other things.
+ adhoc => $machine->{adhoc}
};
writeState;
- print STDERR "checking whether VM ‘$machine->{name}’ is reachable
via SSH...\n";
+ print STDERR "checking whether VM ‘$name’ is reachable via
SSH...\n";
system "ssh -o StrictHostKeyChecking=no root\@$ipv6 true <
/dev/null 2> /dev/null";
die "cannot SSH to VM: $?" unless $? == 0;
@@ -168,9 +178,9 @@
writeState;
# Figure out how we're gonna SSH to each machine. Prefer IPv6
- # addresses over hostnames.
- foreach my $machine (@machines) {
- $machine->{sshName} = $machine->{ipv6} || $machine->{targetHost} ||
die "don't know how to reach ‘$machine->{name}’";
+ # addresses over hostnames.while
+ while (my ($name, $machine) = each %{$state->{machines}}) {
+ $machine->{sshName} = $machine->{ipv6} || $machine->{targetHost} ||
die "don't know how to reach ‘$name’";
}
# So now that we know the hostnames / IP addresses of all
@@ -178,14 +188,14 @@
# network configuration that can be stacked on top of the
# user-supplied network configuration.
my $hosts = "";
- foreach my $machine (@machines) {
- $hosts .= "$machine->{ipv6} $machine->{name}\\n" if defined
$machine->{ipv6};
+ while (my ($name, $machine) = each %{$state->{machines}}) {
+ $hosts .= "$machine->{ipv6} $name\\n" if defined $machine->{ipv6};
}
open STATE, ">physical.nix" or die;
print STATE "{\n";
- foreach my $machine (@machines) {
- print STATE " $machine->{name} = { config, pkgs, ... }:\n";
+ while (my ($name, $machine) = each %{$state->{machines}}) {
+ print STATE " $name = { config, pkgs, ... }:\n";
print STATE " {\n";
if ($machine->{targetEnv} eq "adhoc") {
print STATE " require = [ $myDir/adhoc-cloud-vm.nix ];\n";
@@ -200,31 +210,33 @@
sub buildConfigs {
print STDERR "building all machine configurations...\n";
- $outPath = `nix-build $myDir/eval-machine-info.nix --arg networkExprs '[
@networkExprs ./physical.nix ]' -A machines`;
+ my $outPath = `nix-build $myDir/eval-machine-info.nix --arg networkExprs
'[ @networkExprs ./physical.nix ]' -A machines`;
die "unable to build all machine configurations" unless $? == 0;
chomp $outPath;
+ return $outPath;
}
sub copyClosures {
+ my ($outPath) = @_;
# !!! Should copy closures in parallel.
- foreach my $machine (@machines) {
- print STDERR "copying closure to machine ‘$machine->{name}’...\n";
- my $toplevel = readlink "$outPath/$machine->{name}" or die;
+ while (my ($name, $machine) = each %{$state->{machines}}) {
+ print STDERR "copying closure to machine ‘$name’...\n";
+ my $toplevel = readlink "$outPath/$name" or die;
$machine->{toplevel} = $toplevel;
system "nix-copy-closure --gzip --to root\@$machine->{sshName}
$toplevel";
- die "unable to copy closure to machine ‘$machine->{name}’" unless $?
== 0;
+ die "unable to copy closure to machine ‘$name’" unless $? == 0;
}
}
sub activateConfigs {
- foreach my $machine (@machines) {
- print STDERR "activating new configuration on machine
‘$machine->{name}’...\n";
+ while (my ($name, $machine) = each %{$state->{machines}}) {
+ print STDERR "activating new configuration on machine ‘$name’...\n";
system "ssh -o StrictHostKeyChecking=no root\@$machine->{sshName}
nix-env -p /nix/var/nix/profiles/system --set $machine->{toplevel} \\;
/nix/var/nix/profiles/system/bin/switch-to-configuration switch";
if ($? != 0) {
# !!! do a rollback
- die "unable to activate new configuration on machine
‘$machine->{name}’";
+ die "unable to activate new configuration on machine ‘$name’";
}
}
}
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits