New switch remote command for setting configuration parameters.
authorBen Pfaff <blp@nicira.com>
Wed, 5 Nov 2008 18:03:49 +0000 (10:03 -0800)
committerBen Pfaff <blp@nicira.com>
Wed, 5 Nov 2008 18:03:49 +0000 (10:03 -0800)
debian/commands/reconfigure [new file with mode: 0755]
debian/openflow-switch.install

diff --git a/debian/commands/reconfigure b/debian/commands/reconfigure
new file mode 100755 (executable)
index 0000000..a961052
--- /dev/null
@@ -0,0 +1,128 @@
+#! /usr/bin/perl
+
+use POSIX;
+use strict;
+use warnings;
+
+my $default = '/etc/default/openflow-switch';
+
+my (%config) = load_config($default);
+if (@ARGV) {
+    foreach my $arg (@ARGV) {
+        my ($key, $value) = $arg =~ /^([^=]+)=(.*)/
+          or die "bad argument '$arg'\n";
+        if ($value ne '') {
+            $config{$key} = $value;
+        } else {
+            delete $config{$key};
+        }
+    }
+    save_config($default, %config);
+}
+print "$_=$config{$_}\n" foreach sort(keys(%config));
+
+sub load_config {
+    my ($file) = @_;
+
+    # Get the list of the variables that the shell sets automatically.
+    my (%auto_vars) = read_vars("set -a && env");
+
+    # Get the variables from $default.
+    my (%config) = read_vars("set -a && . '$default' && env");
+
+    # Subtract.
+    delete @config{keys %auto_vars};
+
+    return %config;
+}
+
+sub read_vars {
+    my ($cmd) = @_;
+    local @ENV;
+    if (!open(VARS, '-|', $cmd)) {
+        print STDERR "$cmd: failed to execute: $!\n";
+        return ();
+    }
+    my (%config);
+    while (<VARS>) {
+        my ($var, $value) = /^([^=]+)=(.*)$/ or next;
+        $config{$var} = $value;
+    }
+    close(VARS);
+    return %config;
+}
+
+sub shell_escape {
+    local $_ = $_[0];
+    if ($_ eq '') {
+        return '""';
+    } elsif (m&^[-a-zA-Z0-9:./%^_+,]*$&) {
+        return $_;
+    } else {
+        s/'/'\\''/;
+        return "'$_'";
+    }
+}
+
+sub shell_assign {
+    my ($var, $value) = @_;
+    return $var . '=' . shell_escape($value);
+}
+
+sub save_config {
+    my ($file, %config) = @_;
+    my (@lines);
+    if (open(FILE, '<', $file)) {
+        @lines = <FILE>;
+        chomp @lines;
+        close(FILE);
+    }
+
+    # Replace all existing variable assignments.
+    for (my ($i) = 0; $i <= $#lines; $i++) {
+        local $_ = $lines[$i];
+        my ($var, $value) = /^\s*([^=#]+)=(.*)$/ or next;
+        if (exists($config{$var})) {
+            $lines[$i] = shell_assign($var, $config{$var});
+            delete $config{$var};
+        } else {
+            $lines[$i] = "#$lines[$i]";
+        }
+    }
+
+    # Find a place to put any remaining variable assignments.
+  VAR:
+    for my $var (keys(%config)) {
+        my $assign = shell_assign($var, $config{$var});
+
+        # Replace the last commented-out variable assignment to $var, if any.
+        for (my ($i) = $#lines; $i >= 0; $i--) {
+            local $_ = $lines[$i];
+            if (/^\s*#\s*$var=/) {
+                $lines[$i] = $assign;
+                next VAR;
+            }
+        }
+
+        # Find a place to add the var: after the final commented line
+        # just after a line that contains "$var:".
+        for (my ($i) = 0; $i <= $#lines; $i++) {
+            if ($lines[$i] =~ /^\s*#\s*$var:/) {
+                for (my ($j) = $i + 1; $j <= $#lines; $j++) {
+                    if ($lines[$j] !~ /^\s*#/) {
+                        splice(@lines, $j, 0, $assign);
+                        next VAR;
+                    }
+                }
+            }
+        }
+
+        # Just append it.
+        push(@lines, $assign);
+    }
+
+    open(NEWFILE, '>', "$file.tmp") or die "$file.tmp: create: $!\n";
+    print NEWFILE join('', map("$_\n", @lines));
+    close(NEWFILE);
+    rename("$file.tmp", $file) or die "$file.tmp: rename to $file: $!\n";
+}
index c074d35..53dc04d 100644 (file)
@@ -4,4 +4,5 @@ _debian/utilities/dpctl usr/sbin
 _debian/utilities/ofp-discover usr/sbin
 _debian/utilities/ofp-kill usr/sbin
 debian/ofp-switch-setup usr/sbin
-debian/openflow/usr/share/openflow/commands usr/share/openflow
+debian/openflow/usr/share/openflow/commands/* usr/share/openflow/commands
+debian/commands/* usr/share/openflow/commands