summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rwxr-xr-xscripts/vyatta-boot-image.pl144
-rw-r--r--templates/set/system/boot-image/node.def2
-rw-r--r--templates/set/system/node.def1
-rw-r--r--templates/show/system/installed-images/node.def2
5 files changed, 150 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 0660d3a..a9deebe 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,6 +22,7 @@ bin_SCRIPTS += scripts/vyatta-cpu-summary.pl
bin_SCRIPTS += scripts/yesno
bin_SCRIPTS += scripts/vyatta-gettime.pl
bin_SCRIPTS += scripts/show-users.pl
+bin_SCRIPTS += scripts/vyatta-boot-image.pl
bin_sudo_users_SCRIPTS = scripts/vyatta-identify-interface.pl
bin_sudo_users_SCRIPTS += scripts/vyatta-delete-log-file.sh
diff --git a/scripts/vyatta-boot-image.pl b/scripts/vyatta-boot-image.pl
new file mode 100755
index 0000000..23dd7a0
--- /dev/null
+++ b/scripts/vyatta-boot-image.pl
@@ -0,0 +1,144 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+my $UNION_GRUB_CFG = '/live/image/boot/grub/grub.cfg';
+
+# this function parses the grub config file and returns a hash reference
+# of the parsed data.
+sub parseGrubCfg {
+ my $fd = undef;
+ return undef if (!open($fd, '<', $UNION_GRUB_CFG));
+
+ my %ghash = ();
+ my @entries = ();
+ my $in_entry = 0;
+ my $idx = 0;
+ while (<$fd>) {
+ if ($in_entry) {
+ if (/^}/) {
+ $in_entry = 0;
+ ++$idx;
+ } elsif (/^\s+linux /) {
+ my %ehash = (
+ 'idx' => $idx,
+ 'ver' => undef,
+ 'term' => undef,
+ 'reset' => undef
+ );
+ # kernel line
+ if (/^\s+linux \/boot\/([^\/ ]+)\/.* boot=live /) {
+ # union install
+ $ehash{'ver'} = $1;
+ } else {
+ # old install
+ $ehash{'ver'} = 'Old non-image installation';
+ }
+ if (/console=tty0.*console=ttyS0/) {
+ $ehash{'term'} = 'serial';
+ } else {
+ $ehash{'term'} = 'kvm';
+ }
+ if (/standalone_root_pw_reset/) {
+ $ehash{'reset'} = 1;
+ } else {
+ $ehash{'reset'} = 0;
+ }
+ push @entries, \%ehash;
+ }
+ } elsif (/^set default=(\d+)$/) {
+ $ghash{'default'} = $1;
+ } elsif (/^menuentry /) {
+ $in_entry = 1;
+ }
+ }
+ close($fd);
+ $ghash{'entries'} = \@entries;
+ return \%ghash;
+}
+
+# this function takes the default terminal type and a list of all entries
+# and returns the "boot list", i.e., the list for user to select which one
+# to boot.
+sub getBootList {
+ my ($dterm, $entries) = @_;
+ my %vhash = ();
+ my @list = ();
+ foreach (@{$entries}) {
+ my ($ver, $term) = ($_->{'ver'}, $_->{'term'});
+ next if ($_->{'reset'}); # skip password reset entry
+ next if ($term ne $dterm); # not the default terminal
+ next if (defined($vhash{$ver})); # version already in list
+ $vhash{$ver} = 1;
+ push @list, $_;
+ }
+ return \@list;
+}
+
+sub displayBootList {
+ my ($didx, $entries) = @_;
+ for my $i (0 .. $#{$entries}) {
+ my $di = $i + 1;
+ my $ver = ${$entries}[$i]->{'ver'};
+ my $m = '';
+ if ($didx == ${$entries}[$i]->{'idx'}) {
+ $m = ' (default boot)';
+ }
+ printf " %2d: %s%s\n", $di, $ver, $m;
+ }
+}
+
+my ($show, $sel) = (undef, undef);
+GetOptions(
+ 'show' => \$show,
+ 'select' => \$sel
+);
+
+my $gref = parseGrubCfg();
+if (!defined($gref)) {
+ print "Cannot find GRUB configuration file. Exiting...\n";
+ exit 1;
+}
+my $def_idx = $gref->{'default'};
+my $entries = $gref->{'entries'};
+if (!defined($def_idx) || !defined($entries)
+ || !defined(${$entries}[$def_idx])) {
+ print "Error parsing GRUB configuration file. Exiting...\n";
+ exit 1;
+}
+my $def_term = ${$entries}[$def_idx]->{'term'};
+
+my $bentries = getBootList($def_term, $entries);
+
+print "The system currently has the following images installed:\n\n";
+displayBootList($def_idx, $bentries);
+print "\n";
+
+exit 0 if ($show); # show-only. done.
+
+print 'Select the default boot image: ';
+my $resp = <STDIN>;
+if (!defined($resp) || !($resp =~ /^\d+$/) || ($resp < 1)
+ || ($resp > ($#{$bentries} + 1))) {
+ print "Invalid selection. Default is not changed. Exiting...\n";
+ exit 1;
+}
+
+print "\n";
+$resp -= 1;
+my $new_idx = ${$bentries}[$resp]->{'idx'};
+my $new_ver = ${$bentries}[$resp]->{'ver'};
+system("sed -i 's/^set default=.*\$/set default=$new_idx/' $UNION_GRUB_CFG");
+if ($? >> 8) {
+ print "Failed to set the default boot image. Exiting...\n";
+ exit 1;
+}
+print <<EOF;
+Default boot image has been set to "$new_ver".
+You need to reboot the system to start the new default image.
+
+EOF
+exit 0;
+
diff --git a/templates/set/system/boot-image/node.def b/templates/set/system/boot-image/node.def
new file mode 100644
index 0000000..c5848a4
--- /dev/null
+++ b/templates/set/system/boot-image/node.def
@@ -0,0 +1,2 @@
+help: Set the system default boot image
+run: sudo /opt/vyatta/bin/vyatta-boot-image.pl --select
diff --git a/templates/set/system/node.def b/templates/set/system/node.def
new file mode 100644
index 0000000..eef577c
--- /dev/null
+++ b/templates/set/system/node.def
@@ -0,0 +1 @@
+help: Set system operational parameters
diff --git a/templates/show/system/installed-images/node.def b/templates/show/system/installed-images/node.def
new file mode 100644
index 0000000..08caab7
--- /dev/null
+++ b/templates/show/system/installed-images/node.def
@@ -0,0 +1,2 @@
+help: Show installed Vyatta images
+run: /opt/vyatta/bin/vyatta-boot-image.pl --show