Author: eelco
Date: Wed May 4 16:34:16 2011
New Revision: 27149
URL: https://svn.nixos.org/websvn/nix/?rev=27149&sc=1
Log:
* Keep information about previously created VMs in ./state.json.
Modified:
cloud/trunk/src/nixos-deploy-network.pl
Modified: cloud/trunk/src/nixos-deploy-network.pl
==============================================================================
--- cloud/trunk/src/nixos-deploy-network.pl Wed May 4 14:59:17 2011
(r27148)
+++ cloud/trunk/src/nixos-deploy-network.pl Wed May 4 16:34:16 2011
(r27149)
@@ -4,12 +4,17 @@
use XML::LibXML;
use Cwd;
use File::Basename;
+use JSON;
binmode(STDERR, ":utf8");
+# !!! Cleanly separate $state->{machines} (the deployment state) and
+# @machines (the deployment specification).
+
my @networkExprs;
my @machines = ();
my $outPath;
+my $state;
my $myDir = dirname(Cwd::abs_path($0));
@@ -69,7 +74,7 @@
} elsif ($targetEnv eq "adhoc") {
$info->{adhoc} =
{ controller => $m->findvalue('./attrs/attr[@name =
"adhoc"]/attrs/attr[@name = "controller"]/string/@value') || die
- , startVMCommand => $m->findvalue('./attrs/attr[@name =
"adhoc"]/attrs/attr[@name = "startVMCommand"]/string/@value') || die
+ , createVMCommand => $m->findvalue('./attrs/attr[@name =
"adhoc"]/attrs/attr[@name = "createVMCommand"]/string/@value') || die
, queryVMCommand => $m->findvalue('./attrs/attr[@name =
"adhoc"]/attrs/attr[@name = "queryVMCommand"]/string/@value') || die
};
} else {
@@ -81,11 +86,39 @@
sub readState {
+ local $/;
+ open(my $fh, '<', './state.json') or die "$!";
+ $state = decode_json <$fh>;
+}
+
+
+sub writeState {
+ open(my $fh, '>', './state.json.new') or die "$!";
+ print $fh encode_json($state);
}
sub startMachines {
foreach my $machine (@machines) {
+
+ my $prevMachine = $state->{machines}->{$machine->{name}};
+
+ if (defined $prevMachine) {
+ # So we already created/used a machine in a previous
+ # execution. If it matches the current deployment
+ # parameters, we're done; otherwise, we have to kill the
+ # old machine (if permitted) and create a new one.
+ 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";
+ 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";
+ }
if ($machine->{targetEnv} eq "none") {
# Nothing to do here.
@@ -93,33 +126,40 @@
elsif ($machine->{targetEnv} eq "adhoc") {
- print STDERR "checking whether VM ‘$machine->{name}’ exists...\n";
+ print STDERR "starting missing VM ‘$machine->{name}’...\n";
+ my $vmId = `ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{createVMCommand}`;
+ die "unable to start VM: $?" unless $? == 0;
+ chomp $vmId;
- my $ipv6 = `ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{queryVMCommand} $machine->{name} 2> /dev/null`;
- die "unable to query VM state: $?" unless $? == 0 || $? == 256;
+ $machine->{vmId} = $vmId;
- if ($? == 256) {
- print STDERR "starting missing VM ‘$machine->{name}’...\n";
- system "ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{createVMCommand} $machine->{name}";
- die "unable to start VM: $?" unless $? == 0;
-
- $ipv6 = `ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{queryVMCommand} $machine->{name} 2> /dev/null`;
- die "unable to query VM state: $?" unless $? == 0;
- }
+ $ipv6 = `ssh $machine->{adhoc}->{controller}
$machine->{adhoc}->{queryVMCommand} $machine->{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}} =
+ { targetEnv => $machine->{targetEnv}
+ , vmId => $machine->{vmId}
+ , ipv6 => $machine->{ipv6}
+ };
+
+ writeState;
+
print STDERR "checking whether VM ‘$machine->{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;
- $machine->{ipv6} = $ipv6;
}
}
+ # !!! Kill all machines in $state that no longer exist in $machines.
+
+ writeState;
+
# Figure out how we're gonna SSH to each machine. Prefer IPv6
# addresses over hostnames.
foreach my $machine (@machines) {
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits