For guests registered with Red Hat Network, this patch allows for the conversion process to use RHN to download appropriate kernel package and its dependencies. We use yum on RHEL-5, up2date libraries on RHEL-4. We install matching kernel version whenever possible, latest available kernel version otherwise. _discover_kernel routine has been extended to return version-release of the default kernel found. --- lib/Sys/VirtV2V/GuestOS/RedHat.pm | 166 ++++++++++++++++++++++++++++-------- 1 files changed, 129 insertions(+), 37 deletions(-) diff --git a/lib/Sys/VirtV2V/GuestOS/RedHat.pm b/lib/Sys/VirtV2V/GuestOS/RedHat.pm index 77f0f3a..38a485c 100644 --- a/lib/Sys/VirtV2V/GuestOS/RedHat.pm +++ b/lib/Sys/VirtV2V/GuestOS/RedHat.pm @@ -475,7 +475,7 @@ sub add_kernel { my $self = shift; - my ($kernel_pkg, $kernel_arch) = $self->_discover_kernel(); + my ($kernel_pkg, $kernel_ver, $kernel_arch) = $self->_discover_kernel(); # If the guest is using a Xen PV kernel, choose an appropriate normal kernel # replacement @@ -547,56 +547,142 @@ sub add_kernel } } - my ($app, $depnames); - eval { + my $version; + + # systemid exists, assume the system is registered w/ RHN + if ($self->{g}->exists('/etc/sysconfig/rhn/systemid')) { my $desc = $self->{desc}; - ($app, $depnames) = - $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); - }; - # Return undef if we didn't find a kernel - if ($@) { - print STDERR $@; - return undef; - } + my ($min_virtio_ver, @kern_vr, @preinst_cmd, @inst_cmd, $inst_fmt); - my @missing; - if (!$self->{g}->exists($self->_transfer_path($app))) { - push(@missing, $app); + # filter out xen/xenU from release field + if ($kernel_ver =~ /^(\S+)-(\S+?)(xen)?(U)?$/) { + @kern_vr = ($1, $2); + $kernel_ver = join('-', @kern_vr); + } + + # RHEL-5 + if ($desc->{distro} eq 'rhel' && $desc->{major_version} eq '5') { + if (_rpmvercmp($kernel_ver, '2.6.18-128.el5') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', + "$kernel_pkg-$kernel_ver"); + } else { + # Install latest available kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', $kernel_pkg); + + # We need to upgrade kernel deps. first to avoid possible conflicts + my @deps; + my $deps = ($self->{config}->match_app($desc, $kernel_pkg, $kernel_arch))[1]; + + if ($deps) { + @preinst_cmd = (('/usr/bin/yum', '-y', 'upgrade'), @$deps); + } + } + } + # RHEL-4 + elsif ($desc->{distro} eq 'rhel' && $desc->{major_version} eq '4') { + if (_rpmvercmp($kernel_ver, '2.6.9-89.EL') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/python', '-c', + "import sys; sys.path.append('/usr/share/rhn');" . + "import actions.packages;" . + "actions.packages.cfg['forceInstall'] = 1;" . + "actions.packages.update([['$kernel_pkg', " . + "'$kern_vr[0]', '$kern_vr[1]', '']])"); + } else { + # Install latest available kernel version + @inst_cmd = ('/usr/sbin/up2date', '-fi', $kernel_pkg); + + # We need to upgrade kernel deps. first to avoid possible conflicts + my $deps = ($self->{config}->match_app($desc, $kernel_pkg, $kernel_arch))[1]; + + if ($deps) { + @preinst_cmd = (('/usr/sbin/up2date', '-fu'), @$deps); + } + } + } + else { + @inst_cmd = ('/usr/sbin/up2date', '-fi', $kernel_pkg); + } + + my (@k_before, @k_new); + + # List of kernels before the new kernel installation + @k_before = $self->{g}->glob_expand('/boot/vmlinuz-*'); + + eval { + # Upgrade dependencies if needed + if (@preinst_cmd) { + $self->{g}->command(\@preinst_cmd); + } + # Install new kernel + $self->{g}->command(\@inst_cmd); + }; + + $self->_augeas_error($@) if ($@); + + # Figure out which kernel has just been installed + foreach my $k ($self->{g}->glob_expand('/boot/vmlinuz-*')) { + grep(/^$k$/, @k_before) or push(@k_new, $k); + } + + # version-release of the new kernel package + $version = ($self->{g}->command_lines( + ['rpm', '-qf', '--qf=%{VERSION}-%{RELEASE}', $k_new[0]]))[0]; } else { - return undef if ($self->_newer_installed($app)); - } - my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch; + my ($app, $depnames); + eval { + my $desc = $self->{desc}; - my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + ($app, $depnames) = + $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); + }; + # Return undef if we didn't find a kernel + if ($@) { + print STDERR $@; + return undef; + } - # We can't proceed if there are any files missing - _die_missing(@missing) if (@missing > 0); + my @missing; + if (!$self->{g}->exists($self->_transfer_path($app))) { + push(@missing, $app); + } else { + return undef if ($self->_newer_installed($app)); + } - # Install any required kernel dependencies - $self->_install_rpms(1, @deps); + my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch; - # Inspect the rpm to work out what kernel version it contains - my $version; - my $g = $self->{g}; - foreach my $file ($g->command_lines - (["rpm", "-qlp", $self->_transfer_path($app)])) - { - if($file =~ m{^/boot/vmlinuz-(.*)$}) { - $version = $1; - last; + my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + + # We can't proceed if there are any files missing + _die_missing(@missing) if (@missing > 0); + + # Install any required kernel dependencies + $self->_install_rpms(1, @deps); + + # Inspect the rpm to work out what kernel version it contains + my $g = $self->{g}; + foreach my $file ($g->command_lines + (["rpm", "-qlp", $self->_transfer_path($app)])) + { + if($file =~ m{^/boot/vmlinuz-(.*)$}) { + $version = $1; + last; + } } - } - die(user_message(__x("{path} doesn't contain a valid kernel", - path => $app))) if(!defined($version)); + die(user_message(__x("{path} doesn't contain a valid kernel", + path => $app))) if(!defined($version)); - $self->_install_rpms(0, ($app)); + $self->_install_rpms(0, ($app)); + + } # Make augeas reload so it'll find the new kernel eval { - $g->aug_load(); + $self->{g}->aug_load(); }; $self->_augeas_error($@) if ($@); @@ -632,6 +718,7 @@ sub _discover_kernel # Get a current bootable kernel, preferrably the default my $kernel_pkg; + my $kernel_ver; my $kernel_arch; foreach my $i (@configs) { @@ -647,6 +734,11 @@ sub _discover_kernel # Get the kernel package name $kernel_pkg = $kernel->{package}; + + # Get the kernel package version + $kernel_ver = $kernel->{version}; + + last; } # Default to 'kernel' if package name wasn't discovered @@ -664,7 +756,7 @@ sub _discover_kernel # a very long time. $kernel_arch = 'i686' if('i386' eq $kernel_arch); - return ($kernel_pkg, $kernel_arch); + return ($kernel_pkg, $kernel_ver, $kernel_arch); } =item remove_kernel(version) -- 1.7.1
Milan, Some comments inline. On 14/05/10 15:06, Milan Zazrivec wrote:
For guests registered with Red Hat Network, this patch allows for the conversion process to use RHN to download appropriate kernel package and its dependencies.
We use yum on RHEL-5, up2date libraries on RHEL-4.
We install matching kernel version whenever possible, latest available kernel version otherwise.
_discover_kernel routine has been extended to return version-release of the default kernel found. --- lib/Sys/VirtV2V/GuestOS/RedHat.pm | 166 ++++++++++++++++++++++++++++-------- 1 files changed, 129 insertions(+), 37 deletions(-)
diff --git a/lib/Sys/VirtV2V/GuestOS/RedHat.pm b/lib/Sys/VirtV2V/GuestOS/RedHat.pm index 77f0f3a..38a485c 100644 --- a/lib/Sys/VirtV2V/GuestOS/RedHat.pm +++ b/lib/Sys/VirtV2V/GuestOS/RedHat.pm @@ -475,7 +475,7 @@ sub add_kernel { my $self = shift;
- my ($kernel_pkg, $kernel_arch) = $self->_discover_kernel(); + my ($kernel_pkg, $kernel_ver, $kernel_arch) = $self->_discover_kernel();
# If the guest is using a Xen PV kernel, choose an appropriate normal kernel # replacement @@ -547,56 +547,142 @@ sub add_kernel } }
- my ($app, $depnames); - eval { + my $version; + + # systemid exists, assume the system is registered w/ RHN + if ($self->{g}->exists('/etc/sysconfig/rhn/systemid')) {
Can we make this less of an explicit check for RHN registration that a check for the availability of an update mechanism? I was thinking you'd check to see if up2date/yum was installed, and if it was, try to run it. If running it failed, fall back to the config.
my $desc = $self->{desc};
- ($app, $depnames) = - $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); - }; - # Return undef if we didn't find a kernel - if ($@) { - print STDERR $@; - return undef; - } + my ($min_virtio_ver, @kern_vr, @preinst_cmd, @inst_cmd, $inst_fmt);
- my @missing; - if (!$self->{g}->exists($self->_transfer_path($app))) { - push(@missing, $app); + # filter out xen/xenU from release field + if ($kernel_ver =~ /^(\S+)-(\S+?)(xen)?(U)?$/) { + @kern_vr = ($1, $2); + $kernel_ver = join('-', @kern_vr); + } + + # RHEL-5 + if ($desc->{distro} eq 'rhel' && $desc->{major_version} eq '5') {
Again, with these tests, could we just check for the existence of /usr/bin/yum? I guess we'd need to use up2date in preference to yum if it was installed, as the most likely scenario here is RHEL 3/4 using yum for non-core repos.
+ if (_rpmvercmp($kernel_ver, '2.6.18-128.el5') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', + "$kernel_pkg-$kernel_ver"); + } else { + # Install latest available kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', $kernel_pkg); + + # We need to upgrade kernel deps. first to avoid possible conflicts
Why can't yum do it all in one go?
+ my @deps; + my $deps = ($self->{config}->match_app($desc, $kernel_pkg, $kernel_arch))[1]; + + if ($deps) { + @preinst_cmd = (('/usr/bin/yum', '-y', 'upgrade'), @$deps); + } + } + } + # RHEL-4 + elsif ($desc->{distro} eq 'rhel' && $desc->{major_version} eq '4') {
Using RHEL version to distinguish between the methods below is ok, I guess, as nothing except RHEL used up2date (as far as I'm aware).
+ if (_rpmvercmp($kernel_ver, '2.6.9-89.EL') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/python', '-c', + "import sys; sys.path.append('/usr/share/rhn');" . + "import actions.packages;" . + "actions.packages.cfg['forceInstall'] = 1;" . + "actions.packages.update([['$kernel_pkg', " . + "'$kern_vr[0]', '$kern_vr[1]', '']])");
Yuk, but ok ;)
+ } else { + # Install latest available kernel version + @inst_cmd = ('/usr/sbin/up2date', '-fi', $kernel_pkg); + + # We need to upgrade kernel deps. first to avoid possible conflicts + my $deps = ($self->{config}->match_app($desc, $kernel_pkg, $kernel_arch))[1]; + + if ($deps) { + @preinst_cmd = (('/usr/sbin/up2date', '-fu'), @$deps); + } + } + } + else { + @inst_cmd = ('/usr/sbin/up2date', '-fi', $kernel_pkg); + } + + my (@k_before, @k_new); + + # List of kernels before the new kernel installation + @k_before = $self->{g}->glob_expand('/boot/vmlinuz-*'); + + eval { + # Upgrade dependencies if needed + if (@preinst_cmd) { + $self->{g}->command(\@preinst_cmd); + } + # Install new kernel + $self->{g}->command(\@inst_cmd);
Again, why can't we do these in a single transaction?
+ }; + + $self->_augeas_error($@) if ($@);
Just ditch the eval {} block here. I recently ditched these elsewhere in the code.
+ + # Figure out which kernel has just been installed + foreach my $k ($self->{g}->glob_expand('/boot/vmlinuz-*')) { + grep(/^$k$/, @k_before) or push(@k_new, $k); + } + + # version-release of the new kernel package + $version = ($self->{g}->command_lines( + ['rpm', '-qf', '--qf=%{VERSION}-%{RELEASE}', $k_new[0]]))[0];
As above, can we arrange this block to fall-through if the execution of up2date/yum failed for some reason?
} else { - return undef if ($self->_newer_installed($app)); - }
- my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch; + my ($app, $depnames); + eval { + my $desc = $self->{desc};
- my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + ($app, $depnames) = + $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); + }; + # Return undef if we didn't find a kernel + if ($@) { + print STDERR $@; + return undef; + }
- # We can't proceed if there are any files missing - _die_missing(@missing) if (@missing > 0); + my @missing; + if (!$self->{g}->exists($self->_transfer_path($app))) { + push(@missing, $app); + } else { + return undef if ($self->_newer_installed($app)); + }
- # Install any required kernel dependencies - $self->_install_rpms(1, @deps); + my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch;
- # Inspect the rpm to work out what kernel version it contains - my $version; - my $g = $self->{g}; - foreach my $file ($g->command_lines - (["rpm", "-qlp", $self->_transfer_path($app)])) - { - if($file =~ m{^/boot/vmlinuz-(.*)$}) { - $version = $1; - last; + my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + + # We can't proceed if there are any files missing + _die_missing(@missing) if (@missing > 0); + + # Install any required kernel dependencies + $self->_install_rpms(1, @deps); + + # Inspect the rpm to work out what kernel version it contains + my $g = $self->{g}; + foreach my $file ($g->command_lines + (["rpm", "-qlp", $self->_transfer_path($app)])) + { + if($file =~ m{^/boot/vmlinuz-(.*)$}) { + $version = $1; + last; + } } - }
- die(user_message(__x("{path} doesn't contain a valid kernel", - path => $app))) if(!defined($version)); + die(user_message(__x("{path} doesn't contain a valid kernel", + path => $app))) if(!defined($version));
- $self->_install_rpms(0, ($app)); + $self->_install_rpms(0, ($app)); + + }
# Make augeas reload so it'll find the new kernel eval { - $g->aug_load(); + $self->{g}->aug_load();
Why?
};
$self->_augeas_error($@) if ($@); @@ -632,6 +718,7 @@ sub _discover_kernel
# Get a current bootable kernel, preferrably the default my $kernel_pkg; + my $kernel_ver; my $kernel_arch;
foreach my $i (@configs) { @@ -647,6 +734,11 @@ sub _discover_kernel
# Get the kernel package name $kernel_pkg = $kernel->{package}; + + # Get the kernel package version + $kernel_ver = $kernel->{version}; + + last; }
# Default to 'kernel' if package name wasn't discovered @@ -664,7 +756,7 @@ sub _discover_kernel # a very long time. $kernel_arch = 'i686' if('i386' eq $kernel_arch);
- return ($kernel_pkg, $kernel_arch); + return ($kernel_pkg, $kernel_ver, $kernel_arch); }
=item remove_kernel(version) -- 1.7.1
Thanks, Matt -- Matthew Booth, RHCA, RHCSS Red Hat Engineering, Virtualisation Team M: +44 (0)7977 267231 GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
On Friday 14 May 2010 17:43:34 Matthew Booth wrote:
Milan,
Some comments inline.
On 14/05/10 15:06, Milan Zazrivec wrote:
For guests registered with Red Hat Network, this patch allows for the conversion process to use RHN to download appropriate kernel package and its dependencies.
We use yum on RHEL-5, up2date libraries on RHEL-4.
We install matching kernel version whenever possible, latest available kernel version otherwise.
_discover_kernel routine has been extended to return version-release of the default kernel found. --- lib/Sys/VirtV2V/GuestOS/RedHat.pm | 166 ++++++++++++++++++++++++++++-------- 1 files changed, 129 insertions(+), 37 deletions(-)
diff --git a/lib/Sys/VirtV2V/GuestOS/RedHat.pm b/lib/Sys/VirtV2V/GuestOS/RedHat.pm index 77f0f3a..38a485c 100644 --- a/lib/Sys/VirtV2V/GuestOS/RedHat.pm +++ b/lib/Sys/VirtV2V/GuestOS/RedHat.pm @@ -475,7 +475,7 @@ sub add_kernel { my $self = shift;
- my ($kernel_pkg, $kernel_arch) = $self->_discover_kernel(); + my ($kernel_pkg, $kernel_ver, $kernel_arch) = $self->_discover_kernel();
# If the guest is using a Xen PV kernel, choose an appropriate normal kernel # replacement @@ -547,56 +547,142 @@ sub add_kernel } }
- my ($app, $depnames); - eval { + my $version; + + # systemid exists, assume the system is registered w/ RHN + if ($self->{g}->exists('/etc/sysconfig/rhn/systemid')) {
Can we make this less of an explicit check for RHN registration that a check for the availability of an update mechanism? I was thinking you'd check to see if up2date/yum was installed, and if it was, try to run it. If running it failed, fall back to the config.
This could be done I think.
my $desc = $self->{desc};
- ($app, $depnames) = - $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); - }; - # Return undef if we didn't find a kernel - if ($@) { - print STDERR $@; - return undef; - } + my ($min_virtio_ver, @kern_vr, @preinst_cmd, @inst_cmd, $inst_fmt);
- my @missing; - if (!$self->{g}->exists($self->_transfer_path($app))) { - push(@missing, $app); + # filter out xen/xenU from release field + if ($kernel_ver =~ /^(\S+)-(\S+?)(xen)?(U)?$/) { + @kern_vr = ($1, $2); + $kernel_ver = join('-', @kern_vr); + } + + # RHEL-5 + if ($desc->{distro} eq 'rhel' && $desc->{major_version} eq '5') {
Again, with these tests, could we just check for the existence of /usr/bin/yum? I guess we'd need to use up2date in preference to yum if it was installed, as the most likely scenario here is RHEL 3/4 using yum for non-core repos.
Yes, sounds reasonable.
+ if (_rpmvercmp($kernel_ver, '2.6.18-128.el5') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', + "$kernel_pkg-$kernel_ver"); + } else { + # Install latest available kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', $kernel_pkg); + + # We need to upgrade kernel deps. first to avoid possible conflicts
Why can't yum do it all in one go?
yum can do it all in one go as long as you don't have both i386 & x86_64 ecryptfs-utils installed (standard rhel-5 installation on x86_64 for example). You run 'yum install kernel' and it will correctly try to upgrade ecryptfs-utils.x86_64, but the new kernel will still conflict with ecryptfs-utils.i386 and the command fails.
+ my @deps; + my $deps = ($self->{config}->match_app($desc, $kernel_pkg, $kernel_arch))[1]; + + if ($deps) { + @preinst_cmd = (('/usr/bin/yum', '-y', 'upgrade'), @$deps); + } + } + } + # RHEL-4 + elsif ($desc->{distro} eq 'rhel' && $desc->{major_version} eq '4') {
Using RHEL version to distinguish between the methods below is ok, I guess, as nothing except RHEL used up2date (as far as I'm aware).
+ if (_rpmvercmp($kernel_ver, '2.6.9-89.EL') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/python', '-c', + "import sys; sys.path.append('/usr/share/rhn');" . + "import actions.packages;" . + "actions.packages.cfg['forceInstall'] = 1;" . + "actions.packages.update([['$kernel_pkg', " . + "'$kern_vr[0]', '$kern_vr[1]', '']])");
Yuk, but ok ;)
+ } else { + # Install latest available kernel version + @inst_cmd = ('/usr/sbin/up2date', '-fi', $kernel_pkg); + + # We need to upgrade kernel deps. first to avoid possible conflicts + my $deps = ($self->{config}->match_app($desc, $kernel_pkg, $kernel_arch))[1]; + + if ($deps) { + @preinst_cmd = (('/usr/sbin/up2date', '-fu'), @$deps); + } + } + } + else { + @inst_cmd = ('/usr/sbin/up2date', '-fi', $kernel_pkg); + } + + my (@k_before, @k_new); + + # List of kernels before the new kernel installation + @k_before = $self->{g}->glob_expand('/boot/vmlinuz-*'); + + eval { + # Upgrade dependencies if needed + if (@preinst_cmd) { + $self->{g}->command(\@preinst_cmd); + } + # Install new kernel + $self->{g}->command(\@inst_cmd);
Again, why can't we do these in a single transaction?
up2date is not that flexible (as far as I know). Anyway, we're looking at rhel-4 world, where we don't have to worry about the problems with new kernel dependencies. I'd vote for removing the up2date -fu part completely.
+ }; + + $self->_augeas_error($@) if ($@);
Just ditch the eval {} block here. I recently ditched these elsewhere in the code.
Okay.
+ + # Figure out which kernel has just been installed + foreach my $k ($self->{g}->glob_expand('/boot/vmlinuz-*')) { + grep(/^$k$/, @k_before) or push(@k_new, $k); + } + + # version-release of the new kernel package + $version = ($self->{g}->command_lines( + ['rpm', '-qf', '--qf=%{VERSION}-%{RELEASE}', $k_new[0]]))[0];
As above, can we arrange this block to fall-through if the execution of up2date/yum failed for some reason?
Okay.
} else { - return undef if ($self->_newer_installed($app)); - }
- my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch; + my ($app, $depnames); + eval { + my $desc = $self->{desc};
- my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + ($app, $depnames) = + $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); + }; + # Return undef if we didn't find a kernel + if ($@) { + print STDERR $@; + return undef; + }
- # We can't proceed if there are any files missing - _die_missing(@missing) if (@missing > 0); + my @missing; + if (!$self->{g}->exists($self->_transfer_path($app))) { + push(@missing, $app); + } else { + return undef if ($self->_newer_installed($app)); + }
- # Install any required kernel dependencies - $self->_install_rpms(1, @deps); + my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch;
- # Inspect the rpm to work out what kernel version it contains - my $version; - my $g = $self->{g}; - foreach my $file ($g->command_lines - (["rpm", "-qlp", $self->_transfer_path($app)])) - { - if($file =~ m{^/boot/vmlinuz-(.*)$}) { - $version = $1; - last; + my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + + # We can't proceed if there are any files missing + _die_missing(@missing) if (@missing > 0); + + # Install any required kernel dependencies + $self->_install_rpms(1, @deps); + + # Inspect the rpm to work out what kernel version it contains + my $g = $self->{g}; + foreach my $file ($g->command_lines + (["rpm", "-qlp", $self->_transfer_path($app)])) + { + if($file =~ m{^/boot/vmlinuz-(.*)$}) { + $version = $1; + last; + } } - }
- die(user_message(__x("{path} doesn't contain a valid kernel", - path => $app))) if(!defined($version)); + die(user_message(__x("{path} doesn't contain a valid kernel", + path => $app))) if(!defined($version));
- $self->_install_rpms(0, ($app)); + $self->_install_rpms(0, ($app)); + + }
# Make augeas reload so it'll find the new kernel eval { - $g->aug_load(); + $self->{g}->aug_load();
Why?
Because my $g = $self->{g}; is no longer valid here, but this could be handled more nicely, I agree. -Milan Zázrivec
};
$self->_augeas_error($@) if ($@); @@ -632,6 +718,7 @@ sub _discover_kernel
# Get a current bootable kernel, preferrably the default my $kernel_pkg; + my $kernel_ver; my $kernel_arch;
foreach my $i (@configs) { @@ -647,6 +734,11 @@ sub _discover_kernel
# Get the kernel package name $kernel_pkg = $kernel->{package}; + + # Get the kernel package version + $kernel_ver = $kernel->{version}; + + last; }
# Default to 'kernel' if package name wasn't discovered @@ -664,7 +756,7 @@ sub _discover_kernel # a very long time. $kernel_arch = 'i686' if('i386' eq $kernel_arch);
- return ($kernel_pkg, $kernel_arch); + return ($kernel_pkg, $kernel_ver, $kernel_arch); }
=item remove_kernel(version) -- 1.7.1
Thanks,
Matt
During the conversion process, use up2date or yum to download appropriate kernel package and its dependencies from Red Hat Network or previously setup repositories. Install matching kernel version whenever possible, latest kernel version otherwise. _discover_kernel routine has been extended to return version-release of the default kernel found. --- lib/Sys/VirtV2V/GuestOS/RedHat.pm | 166 +++++++++++++++++++++++++++++-------- 1 files changed, 130 insertions(+), 36 deletions(-) diff --git a/lib/Sys/VirtV2V/GuestOS/RedHat.pm b/lib/Sys/VirtV2V/GuestOS/RedHat.pm index 1a7afbd..ffa85be 100644 --- a/lib/Sys/VirtV2V/GuestOS/RedHat.pm +++ b/lib/Sys/VirtV2V/GuestOS/RedHat.pm @@ -471,7 +471,7 @@ sub add_kernel { my $self = shift; - my ($kernel_pkg, $kernel_arch) = $self->_discover_kernel(); + my ($kernel_pkg, $kernel_ver, $kernel_arch) = $self->_discover_kernel(); # If the guest is using a Xen PV kernel, choose an appropriate normal kernel # replacement @@ -543,52 +543,140 @@ sub add_kernel } } - my ($app, $depnames); - eval { + my $version; + my $g = $self->{g}; + my $update_fail = 0; + + # try using up2date / yum if available + if ($g->exists('/usr/sbin/up2date') or $g->exists('/usr/bin/yum')) { + my $desc = $self->{desc}; - ($app, $depnames) = - $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); - }; - # Return undef if we didn't find a kernel - if ($@) { - print STDERR $@; - return undef; - } + my ($min_virtio_ver, @kern_vr, @preinst_cmd, @inst_cmd, $inst_fmt); - my @missing; - if (!$self->{g}->exists($self->_transfer_path($app))) { - push(@missing, $app); - } else { - return undef if ($self->_newer_installed($app)); - } + # filter out xen/xenU from release field + if ($kernel_ver =~ /^(\S+)-(\S+?)(xen)?(U)?$/) { + @kern_vr = ($1, $2); + $kernel_ver = join('-', @kern_vr); + } - my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch; + # We need to upgrade kernel deps. first to avoid possible conflicts + my $deps = ($self->{config}->match_app($desc, $kernel_pkg, $kernel_arch))[1]; + + # use up2date when available (RHEL-4 and earlier) + if ($g->exists('/usr/sbin/up2date')) { + if (_rpmvercmp($kernel_ver, '2.6.9-89.EL') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/python', '-c', + "import sys; sys.path.append('/usr/share/rhn');" . + "import actions.packages;" . + "actions.packages.cfg['forceInstall'] = 1;" . + "actions.packages.update([['$kernel_pkg', " . + "'$kern_vr[0]', '$kern_vr[1]', '']])"); + } else { + # Install latest available kernel version + @inst_cmd = ('/usr/sbin/up2date', '-fi', $kernel_pkg); + } - my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + if (@$deps) { + use Data::Dumper; print Dumper($deps); + @preinst_cmd = ('/usr/sbin/up2date', '-fu', @$deps); + } + } + # use yum when available (RHEL-5 and beyond) + elsif ($g->exists('/usr/bin/yum')) { + if (_rpmvercmp($kernel_ver, '2.6.18-128.el5') >= 0) { + # Install matching kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', + "$kernel_pkg-$kernel_ver"); + } else { + # Install latest available kernel version + @inst_cmd = ('/usr/bin/yum', '-y', 'install', $kernel_pkg); + } - # We can't proceed if there are any files missing - _die_missing(@missing) if (@missing > 0); + if ($deps) { + @preinst_cmd = ('/usr/bin/yum', '-y', 'upgrade', @$deps); + } + } - # Install any required kernel dependencies - $self->_install_rpms(1, @deps); + my (@k_before, @k_new); - # Inspect the rpm to work out what kernel version it contains - my $version; - my $g = $self->{g}; - foreach my $file ($g->command_lines - (["rpm", "-qlp", $self->_transfer_path($app)])) - { - if($file =~ m{^/boot/vmlinuz-(.*)$}) { - $version = $1; - last; + # List of kernels before the new kernel installation + @k_before = $self->{g}->glob_expand('/boot/vmlinuz-*'); + + eval { + # Upgrade dependencies if needed + if (@preinst_cmd) { + $g->command(\@preinst_cmd); + } + # Install new kernel + $g->command(\@inst_cmd); + }; + + if ($@) { + $update_fail = 1; + } + else { + + # Figure out which kernel has just been installed + foreach my $k ($g->glob_expand('/boot/vmlinuz-*')) { + grep(/^$k$/, @k_before) or push(@k_new, $k); + } + + # version-release of the new kernel package + $version = ($g->command_lines( + ['rpm', '-qf', '--qf=%{VERSION}-%{RELEASE}', $k_new[0]]))[0]; } } - die(user_message(__x("{path} doesn't contain a valid kernel", - path => $app))) if(!defined($version)); + if ($update_fail) { + + my ($app, $depnames); + eval { + my $desc = $self->{desc}; + + ($app, $depnames) = + $self->{config}->match_app($desc, $kernel_pkg, $kernel_arch); + }; + # Return undef if we didn't find a kernel + if ($@) { + print STDERR $@; + return undef; + } + + my @missing; + if (!$g->exists($self->_transfer_path($app))) { + push(@missing, $app); + } else { + return undef if ($self->_newer_installed($app)); + } - $self->_install_rpms(0, ($app)); + my $user_arch = $kernel_arch eq 'i686' ? 'i386' : $kernel_arch; + + my @deps = $self->_get_deppaths(\@missing, $user_arch, @$depnames); + + # We can't proceed if there are any files missing + _die_missing(@missing) if (@missing > 0); + + # Install any required kernel dependencies + $self->_install_rpms(1, @deps); + + # Inspect the rpm to work out what kernel version it contains + foreach my $file ($g->command_lines + (["rpm", "-qlp", $self->_transfer_path($app)])) + { + if($file =~ m{^/boot/vmlinuz-(.*)$}) { + $version = $1; + last; + } + } + + die(user_message(__x("{path} doesn't contain a valid kernel", + path => $app))) if(!defined($version)); + + $self->_install_rpms(0, ($app)); + + } # Make augeas reload so it'll find the new kernel eval { @@ -628,6 +716,7 @@ sub _discover_kernel # Get a current bootable kernel, preferrably the default my $kernel_pkg; + my $kernel_ver; my $kernel_arch; foreach my $i (@configs) { @@ -643,6 +732,11 @@ sub _discover_kernel # Get the kernel package name $kernel_pkg = $kernel->{package}; + + # Get the kernel package version + $kernel_ver = $kernel->{version}; + + last; } # Default to 'kernel' if package name wasn't discovered @@ -660,7 +754,7 @@ sub _discover_kernel # a very long time. $kernel_arch = 'i686' if('i386' eq $kernel_arch); - return ($kernel_pkg, $kernel_arch); + return ($kernel_pkg, $kernel_ver, $kernel_arch); } =item remove_kernel(version) -- 1.7.1
participants (2)
-
Matthew Booth -
Milan Zazrivec