summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorStig Thormodsrud <stig@vyatta.com>2010-11-09 17:05:19 -0800
committerStig Thormodsrud <stig@vyatta.com>2010-11-09 17:05:19 -0800
commitae39faa486737dd4459eb8d66ff5fa1dc1be5166 (patch)
tree97cca32f378b591d080cf331fdf203232bdb3647 /scripts
parent02791991cab3889b6a002907fa4f113a470b7838 (diff)
downloadvyatta-config-mgmt-ae39faa486737dd4459eb8d66ff5fa1dc1be5166.tar.gz
vyatta-config-mgmt-ae39faa486737dd4459eb8d66ff5fa1dc1be5166.zip
Add first pass commit-confirm and rollback (requires reboot for now).
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/vyatta-commit-revs.pl4
-rwxr-xr-xscripts/vyatta-config-mgmt.pl121
2 files changed, 121 insertions, 4 deletions
diff --git a/scripts/vyatta-commit-revs.pl b/scripts/vyatta-commit-revs.pl
index 76937d1..9630f5a 100755
--- a/scripts/vyatta-commit-revs.pl
+++ b/scripts/vyatta-commit-revs.pl
@@ -50,8 +50,8 @@ if (! -d $archive_dir) {
system("sudo mkdir $archive_dir");
system("sudo chown vyatta:vyattacfg $archive_dir");
}
-my $cmd = 'cli-shell-api showCfg --show-active-only';
-system("$cmd > $tmp_config_file");
+my $cmd = '/opt/vyatta/sbin/vyatta-save-config.pl';
+system("$cmd $tmp_config_file > /dev/null");
if (compare($tmp_config_file, $last_commit_file) == 0) {
exit 0;
}
diff --git a/scripts/vyatta-config-mgmt.pl b/scripts/vyatta-config-mgmt.pl
index a6bac48..43e89f4 100755
--- a/scripts/vyatta-config-mgmt.pl
+++ b/scripts/vyatta-config-mgmt.pl
@@ -36,7 +36,10 @@ use Vyatta::Config;
use Vyatta::ConfigMgmt;
use Getopt::Long;
use File::Basename;
+use File::Copy;
use URI;
+use IO::Prompt;
+use Sys::Syslog qw(:standard :macros);
my $commit_uri_script = '/opt/vyatta/sbin/vyatta-commit-push.pl';
my $commit_revs_script = '/opt/vyatta/sbin/vyatta-commit-revs.pl';
@@ -45,6 +48,7 @@ my $commit_hook_dir = cm_get_commit_hook_dir();
my $archive_dir = cm_get_archive_dir();
my $config_file = "$archive_dir/config.boot";
my $lr_conf_file = cm_get_lr_conf_file();
+my $confirm_job_file = '/var/run/confirm.job';
my $debug = 0;
@@ -75,16 +79,31 @@ sub check_valid_rev {
exit 1;
}
+sub parse_at_output {
+ my @lines = @_;
+ foreach my $line (@lines) {
+ if ($line =~ /error/) {
+ return (1, '', '');
+ } elsif ($line =~ /job (\d+) (.*)$/) {
+ return (0, $1, $2);
+ }
+ }
+ return (1, '', '');
+}
+
+
#
# main
#
-my ($action, $uri, $revs, $revnum);
+my ($action, $uri, $revs, $revnum, $minutes, $filename);
Getopt::Long::Configure('pass_through');
GetOptions("action=s" => \$action,
"uri=s" => \$uri,
"revs=s" => \$revs,
"revnum=s" => \$revnum,
+ "minutes=s" => \$minutes,
+ "file=s" => \$filename,
);
die "Error: no action" if ! defined $action;
@@ -170,7 +189,8 @@ if ($action eq 'update-revs') {
system("sudo touch $archive_dir/commits");
system("sudo chgrp vyattacfg $archive_dir/commits");
system("sudo chmod 664 $archive_dir/commits");
- system("$commit_revs_script baseline config.boot");
+ my $cmd = "$commit_revs_script baseline config.boot";
+ system("sudo sg vyattacfg \"$cmd\"");
}
print "done\n";
exit 0;
@@ -231,6 +251,103 @@ if ($action eq 'diff') {
exit 0;
}
+if ($action eq 'commit-confirm') {
+ die "Error: no minutes" if ! defined $minutes;
+ print "commit-confirm [$minutes]\n" if $debug;
+ my $max_revs = cm_get_max_revs();
+ if (!defined $max_revs or $max_revs <= 0) {
+ print "commit-revisions is not configured.\n\n";
+ exit 1;
+ }
+ check_integer($minutes);
+ my $rollback_config = cm_commit_get_file(0);
+
+ # check if another commit-confirm pending
+
+ print "commit confirm will be automatically rebooted in $minutes minutes unless confirmed\n";
+ if (prompt("Proceed? [confirm]", -y1d=>"y")) {
+ } else {
+ print "commit confirm canceled\n";
+ exit 1;
+ }
+
+ my $config_rb = cm_get_config_rb();
+ cm_write_file($config_rb, $rollback_config);
+
+ $cmd = "/opt/vyatta/sbin/vyatta-config-mgmt.pl --action rollback"
+ . " --file $config_rb";
+ my @lines = `echo sudo sg vyattacfg \\"$cmd\\" | at now + $minutes minutes 2>&1`;
+ my ($err, $job, $time) = parse_at_output(@lines);
+ if ($err) {
+ print "Error: unable to schedule reboot\n";
+ exit 1;
+ }
+ system("echo $job > $confirm_job_file");
+
+ exit 0;
+}
+
+if ($action eq 'confirm') {
+ if (! -e $confirm_job_file) {
+ print "No confirm pending\n";
+ exit 0;
+ }
+ my $job = `cat $confirm_job_file`;
+ chomp $job;
+ system("sudo atrm $job");
+ system("sudo rm -f $confirm_job_file");
+ # log confirm
+ exit 0;
+}
+
+if ($action eq 'rollback') {
+ my ($method, $rollback_config) = (undef, undef);
+
+ if (defined $revnum) {
+ print "rollback [$revnum]\n" if $debug;
+ check_valid_rev($revnum);
+ $method = 'revnum';
+ if (prompt("Proceed with reboot? [confirm]", -y1d=>"y")) {
+ } else {
+ print "Cancelling rollback\n";
+ exit 0;
+ }
+ $rollback_config = cm_commit_get_file($revnum);
+ }
+
+ if (defined $filename) {
+ print "rollback [$filename]\n" if $debug;
+ if (! -e $filename) {
+ die "Error: file [$filename] doesn't exist";
+ }
+ if (defined $method) {
+ die "Error: can only define revnum or file";
+ }
+ $method = 'file';
+ # Should have code to validate config, but for now only
+ # called internally. If we later expose this to cli
+ # we'll need to prompt for confirmation.
+ $rollback_config = cm_read_file($filename);
+ }
+ if (!defined $method) {
+ die "Error: must define either revnum or file";
+ }
+
+ my ($user) = getpwuid($<);
+ cm_commit_add_log($user, 'rollback', '');
+ my $boot_config_file = cm_get_boot_config_file();
+ my $archive_dir = cm_get_archive_dir();
+ my $last_commit_file = cm_get_last_commit_file();
+ system("sudo mv $boot_config_file $archive_dir/config.boot-prerollback");
+ cm_write_file($boot_config_file, $rollback_config);
+ cm_write_file($last_commit_file, $rollback_config); # white lie
+ openlog($0, "", LOG_USER);
+ my $login = getpwuid($<) || "unknown";
+ syslog("warning", "Rollback reboot requested by $login");
+ closelog();
+ exec("sudo /sbin/reboot");
+}
+
exit $rc;
# end of file