Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:lafenghu
perl-Bootloader
update-bootloader
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File update-bootloader of Package perl-Bootloader
#! /usr/bin/perl use POSIX; use Getopt::Long; use Bootloader::Tools; use Bootloader::Path; use Bootloader::MBRTools; use strict; # keep Pod::Usage optional (bnc #760464) eval "use Pod::Usage"; if(!exists $::{pod2usage}) { sub pod2usage { die "usage: update-bootloader [operation] [options]\n"; } } my %oper; my ($opt_default, $opt_force, $opt_force_default, $opt_help, $opt_man, $opt_previous, $opt_xen) = (0,0,0,0,0,0,0); my ($opt_image, $opt_initrd, $opt_name, $opt_xen_name, $opt_failsafe, $opt_xen_kernel) = ('','','','','',undef); my $add_product = 0; =head1 NAME update-bootloader - update/change bootloader configuration using Bootloader::Tools perl module =head1 SYNOPSIS update-bootloader [operation] [options] operation is one of --add, --remove or --refresh. valid options are --help, --man, --image <file>, --initrd <file>, --xen-kernel <file>, --xen, --default, --previous, --name <string>, --force, --force-default. =head1 DESCRIPTION B<update-bootloader> will let you modify your bootloader configuration using Bootloader::Tools perl module. =head1 OPERATIONS =over 8 =item B<--add> add an new image section. Needs a call to --refresh to take effect. =item B<--remove> remove the specified image section. Needs a call to --refresh to take effect. =item B<--refresh> activate the new config e.g. write boot loader to disk =back =head1 PARAMETER =over 8 =item B<--help> Print a brief help message and exits. =item B<--man> Prints the manual page and exits. =item B<--image> F<file> specify path to kernel image =item B<--initrd> F<file> specify path to initrd file =item B<--xen> specify that you what to add a xen and not a regular image section =item B<--xen-kernel> F<file> specify that you what to add a xen section with a specific image. Implies --xen option. =item B<--default> let the new section to be added be the default section if appropriate. Only allowed together with --add operation =item B<--previous> set some usuable defaults for image, initrd and name when =item B<--name> F<string> specify the name of the section to be added/removed =item B<--force> dont complain, just do the right thing =item B<--force-default> force the new section to be added to be the default section. Only allowed together with --add operation =back =cut # Get product name and version # If zypper is not available or versions is empty, use /etc/SuSE-release instead # linux is last possible fallback sub GetProduct { my $namever; my $loader = Bootloader::Tools::GetBootloader(); # first try: use zypper if ( -f '/usr/bin/zypper' ){ my $zypper_out = qx{zypper --terse tos -l}; if ($zypper_out =~ m/^labelLong\s*(\S.*\S)\s*\nlabelShort\s*(\S.*\S)[\s\n]*$/){ return $1 if ($1 ne "" && ($loader eq "grub" || $loader eq "grub2" || $loader eq "grub2-efi")); return $2 if ($2 ne ""); } } # Second try: Is there a usable /etc/SuSE-release? # This should really not be used anymore, as the syntax changed # no 'SP1' in the output. if (open(RELEASE, "</etc/SuSE-release") && ($loader eq "grub" || $loader eq "grub2" || $loader eq "grub2-efi")) { # first line is sufficient $namever = <RELEASE>; # delete everything starting with the first parenthesis $namever =~ s/\s*\(.*//; close(RELEASE); chomp $namever; return "$namever"; } # the last line of defense ... return "Linux"; } sub test_gettext { my $filename = "Locale/gettext.pm"; my $realfilename; foreach my $prefix (@INC) { $realfilename = "$prefix/$filename"; if (-f $realfilename) { return 1; } } return undef } my $logname = Bootloader::Path::Logname(); open (LOG, ">>$logname"); print LOG ("update-bootloader called:\n" . $0 . " " . join (" ", @ARGV) . "\n"); close LOG; GetOptions (\%oper, 'add|a' , 'refresh' , 'remove|r' , 'examinembr|e=s', 'default|d' => \$opt_default, 'force-default' => \$opt_force_default, 'help|h' => \$opt_help, 'force' => \$opt_force, 'image=s' => \$opt_image, 'initrd=s' => \$opt_initrd, 'man|m' => \$opt_man, 'xen' => \$opt_xen, 'xen-kernel=s' => \$opt_xen_kernel, 'name=s' => \$opt_name, 'previous|p' => \$opt_previous) or pod2usage(2); pod2usage(1) if $opt_help; pod2usage(-exitstatus => 0, -verbose => 2) if $opt_man; die("Specify exactly one operation, either 'add', 'remove' or 'refresh'\n") unless scalar keys(%oper) == 1; die("Option 'default' is only allowed for operation 'add'\n") if ($opt_default and not defined $oper{add}); die("Option 'force-default' is only allowed for operation 'add'\n") if ($opt_force_default and not defined $oper{add}); if (defined $oper{"examinembr"}) { my $ret = Bootloader::MBRTools::examineMBR($oper{"examinembr"}); if (defined $ret){ print "$ret\n"; exit 0; } else { exit 1; } } if (Bootloader::Tools::GetBootloader() eq "none") { open (LOG, ">>$logname"); print LOG ("none bootloader, skipped updating \n"); close LOG; exit 0; } if (Bootloader::Tools::GetBootloader() =~ /^(grub2|grub2-efi)$/) { open (LOG, ">>$logname"); print LOG ("grub2 bootloader, no add/remove section support\n"); close LOG; delete $oper{add}; delete $oper{remove}; } if ($opt_image and $opt_image !~ m;^/;) { $opt_image = getcwd . '/' . $opt_image } if ($opt_initrd and $opt_initrd !~ m;^/;) { $opt_initrd = getcwd . '/' . $opt_initrd; } if (defined $opt_xen_kernel) { $opt_xen = 1; } elsif ($opt_xen) { my $xen_flavor = $opt_image; $xen_flavor =~ s/.*-(\w+)/$1/; if ($xen_flavor eq "xenpae") { $opt_xen_kernel = "/boot/xen-pae.gz"; } else { $opt_xen_kernel = "/boot/xen.gz"; } } my $type = $opt_xen ? "xen" : "image"; InitLibrary(); if ($opt_previous) { unless ($opt_image) { $opt_image = GetDefaultImage() . ".previous"; } unless($opt_initrd) { $opt_initrd = GetDefaultInitrd() . ".previous"; } } # FIXME: these section names should be unified somehow together with multi # language and grafical menu handling if (defined $oper{add}) { my $loader = Bootloader::Tools::GetBootloader(); unless ($opt_name) { if ($opt_xen and $opt_previous) { if ($loader eq "grub" || $loader eq "lilo" || $loader eq "grub2") { $opt_name = "Previous Xen"; $add_product = 1; } else { $opt_name = "previous xen"; } } elsif ($opt_xen) { if ($loader eq "grub" || $loader eq "lilo" || $loader eq "grub2") { $opt_name = "Xen"; $add_product = 1; } else { $opt_name = "xen"; } } elsif ($opt_previous) { if ($loader eq "grub" || $loader eq "lilo" || $loader eq "grub2") { $opt_name = "Previous Kernel"; $add_product = 1; } else { $opt_name = "previous"; } } else { $opt_name = $opt_image; $opt_name =~ s/.*\///; } } # only localize on grub and lilo #FIXME jreidinger: I think this now doesn't work. because pbl get only version + type of kernel....maybe help translate strings like failsafe etc if (($loader eq "grub" || $loader eq "lilo") && defined(test_gettext())) { require Locale::gettext; setlocale(LC_MESSAGES, Bootloader::Tools::GetSystemLanguage()); my $d = Locale::gettext->domain("bootloader"); $d->dir("/usr/share/YaST2/locale"); my $opt_trans = $d->get($opt_name); chomp ($opt_trans); #log what is translated my $logname = Bootloader::Path::Logname(); open (LOG, ">>$logname"); print LOG ("translate :\n" . $0 . " " . join (" ", @ARGV) . "\n"); close LOG; # check whether translation only contains [a-zA-Z0-9 _] # otherwise fall back to untranslated string if ($opt_trans =~ /^[a-zA-Z\d _]+$/g ) { $opt_name = $opt_trans; } } # Naming scheme for default, smp, bigsmp and pae kernels if (($opt_name =~ /-default/) || ($opt_name =~ /-smp/) || ($opt_name =~ /-bigsmp/) || ($opt_name =~ /-pae/)) { if ($loader eq "grub" || $loader eq "grub2") { $opt_name =~ s/-[^-]*$//; $opt_failsafe = "Failsafe -- " . GetProduct() . " - " . $opt_name; $opt_name = GetProduct() . " - " . $opt_name; } else { $opt_failsafe = "Failsafe"; $opt_name = GetProduct(); } } # Naming scheme for all xen kernels, thus xen and xenpae elsif ($opt_xen) { if ($loader eq "grub" || $loader eq "grub2") { my $version = $opt_name; $version =~ s/-xen.*$//; $opt_name =~ s/^.*(xen.*)$/$1/; $opt_name = ucfirst ($opt_name); $opt_xen_name = "$opt_name -- " . GetProduct() . " - " . $version; } else { $opt_xen_name =~ s/^.*(xen.*)$/$1/; $opt_xen_name = ucfirst ($opt_xen_name); } } # Naming scheme for all other kernels else { my $flavor = $opt_name; $flavor =~ s/.*-(\w+)/$1/; $flavor = ucfirst ($flavor); # Create long labels for grub if ($loader eq "grub" || $loader eq "grub2") { my $version = $opt_name; $version =~ s/-[^-]*$//; $opt_name = $flavor . " -- " . GetProduct() . " - " . $version; $opt_failsafe = "Failsafe -- " . GetProduct() . " - " . $version; } # Create short labels for all other loaders else { $opt_name = GetProduct(); $opt_failsafe = "Failsafe"; } } } # # execute selected operation # if (defined $oper{add}) { open (LOG, ">>$logname"); print LOG ("update-bootloader: now executing operation add\n"); print LOG ("update-bootloader: changed opt name is $opt_name\n"); close LOG; die("Please specify name and kernel image for new section\n") unless $opt_name and $opt_image; my @params = ( type => $type, image => $opt_image, ); if (CountSections(@params) != 0) { if (not $opt_force) { die("There are already sections with image '$opt_image'\n"); } open (LOG, ">>$logname"); print LOG ("update-bootloader: section already exist. Skip add.\n"); close LOG; } else { # If, if option $opt_force_default is set, let this new kernel be # the default one. if ($opt_force_default) { push @params, default => $opt_default; } # Else, find out the flavor of the default kernel. If it is the same # flavor as the one of the new kernel, let the new kernel be the # default one. else { my $default_image = GetDefaultImage(); if (-l $default_image) { $default_image = readlink ($default_image); } $default_image =~ s/^.*-//; if ($opt_image =~ m/.*-${default_image}$/) { push @params, default => $opt_default; } } push @params, xen => $opt_xen_kernel if $type eq "xen"; push @params, initrd => $opt_initrd if $opt_initrd; # Add "xen" section if ($opt_xen) { # Add original_name to params to be able to create comment line push @params, original_name => "xen"; open (LOG, ">>$logname"); print LOG ("update-bootloader: calling Tools::AddSection (XEN)\n"); close LOG; AddSection($opt_xen_name, @params); } # Add "normal" section else { # Add original_name to params to be able to create comment line push @params, original_name => "linux"; open (LOG, ">>$logname"); print LOG ("update-bootloader: calling Tools::AddSection (normal)\n"); close LOG; AddSection($opt_name, @params); } my $arch = `uname --hardware-platform`; chomp ($arch); # Add a "Failsafe" section, but only if the underlying architecture is # one of i386, x86_84 or ia64 and the kernel flavor is either default, # smp, bigsmp or pae and not a xen kernel. if ((($arch eq "i386") || ($arch eq "x86_64") || ($arch eq "s390x") || ($arch eq "ia64")) && (($opt_image =~ /-default/) || ($opt_image =~ /-smp/) || ($opt_image =~ /-desktop/) || ($opt_image =~ /-bigsmp/) || ($opt_image =~ /-pae/)) && ($opt_xen != 1)) { # Add original_name to params to be able to create comment line push @params, original_name => "failsafe"; open (LOG, ">>$logname"); print LOG ("update-bootloader: calling Tools::AddSection (failsafe)\n"); close LOG; AddSection($opt_failsafe, @params); } } } if (defined $oper{remove}) { my @params = ( type => $type, image => $opt_image, ); push @params, xen => $opt_xen_kernel if $type eq "xen"; push @params, initrd => $opt_initrd if $opt_initrd; push @params, name => $opt_name if $opt_name; open (LOG, ">>$logname"); print LOG ("update-bootloader: now executing operation remove\n"); close LOG; my $num = CountSections(@params); if ($num > 0) { if ($num > 1 and not $opt_force) { open (LOG, ">>$logname"); print LOG ("update-bootloader: found $num sections, no opt_force: not removing\n"); close LOG; die("There is more than one section with image '$opt_image'\n"); } else { open (LOG, ">>$logname"); print LOG ("update-bootloader: calling Tools::RemoveSections\n"); close LOG; RemoveSections(@params); } } else { open (LOG, ">>$logname"); print LOG ("update-bootloader: no $opt_image found\n"); close LOG; } open (LOG, ">>$logname"); print LOG ("update-bootloader: finished operation remove\n"); close LOG; } if (defined $oper{refresh}) { # Always set $avoid_init=0 to guarentee bootloader installed (bnc#759224) my $ret = UpdateBootloader(0); exit 1 if ( !$ret ); } # # Local variables: # mode: perl # mode: font-lock # mode: auto-fill # fill-column: 78 # End: #
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor