summaryrefslogtreecommitdiffstats
path: root/mgaapplet-upgrade-helper
diff options
context:
space:
mode:
Diffstat (limited to 'mgaapplet-upgrade-helper')
-rwxr-xr-xmgaapplet-upgrade-helper364
1 files changed, 364 insertions, 0 deletions
diff --git a/mgaapplet-upgrade-helper b/mgaapplet-upgrade-helper
new file mode 100755
index 00000000..a045aa09
--- /dev/null
+++ b/mgaapplet-upgrade-helper
@@ -0,0 +1,364 @@
+#!/usr/bin/perl
+################################################################################
+# Mandriva Online Distribution Upgrade Helper #
+# #
+# Copyright (C) 2008-2010 Mandriva #
+# #
+# Thierry Vignaud <tvignaud at mandriva dot com> #
+# #
+# This program is free software; you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License Version 2 as #
+# published by the Free Software Foundation. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the Free Software #
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+################################################################################
+
+use strict;
+use POSIX ":sys_wait_h";
+use lib qw(/usr/lib/libDrakX);
+use standalone; # for explanations
+use common;
+BEGIN { require_root_capability() }
+use run_program;
+use feature 'state';
+
+BEGIN { unshift @::textdomains, 'mgaonline' }
+
+use mygtk2 qw(gtknew); #- do not import gtkadd which conflicts with ugtk2 version
+use ugtk2 qw(:all);
+use lib qw(/usr/lib/libDrakX/drakfirsttime);
+use mgaonline;
+use Rpmdrake::open_db;
+use lang;
+use mgaapplet_gui qw(run_ask_credentials_dialog);
+
+ugtk2::add_icon_path("/usr/share/mgaonline/pixmaps/");
+my ($log_file);
+
+my ($new_distro_version, $download_dir);
+foreach my $opt (@ARGV) {
+ if ($opt =~ /--(rpm-root|urpmi-root)=(.*)/) {
+ $::rpmdrake_options{$1}[0] = $2;
+ } elsif ($opt =~ /--new_distro_version=(.*)/) {
+ $new_distro_version = $1;
+ } elsif ($opt =~ /--download-all=(.*)/) {
+ $download_dir = $1;
+ }
+}
+
+my $root = Rpmdrake::open_db::fast_open_urpmi_db()->{root};
+
+my $product_id = common::parse_LDAP_namespace_structure(cat_("$root/etc/product.id"));
+
+if (!$ENV{URPMI_IGNORESIZE}) {
+ check_available_free_space('/usr', 800) &&
+ check_available_free_space('/var', 800)
+ or exit(1);
+}
+
+run_program::raw({ detach => 1 }, 'ionice', '-p', $$, '-n7');
+
+upgrade();
+
+my ($refork_gurpmi);
+
+sub check_available_free_space {
+ my ($dir, $wanted_MB) = @_;
+
+ my (undef, $free_KB) = MDK::Common::System::df($dir);
+
+ if ($free_KB / 1024 < $wanted_MB) {
+ my $msg = ugtk2::escape_text_for_TextView_markup_format(
+ N("Your system does not have enough space left in %s for upgrade (%dMB < %dMB)",
+ $dir,
+ $free_KB / 1024, $wanted_MB));
+ ugtk2::ask_warn(N("Error"), $msg);
+ 0;
+ } else {
+ 1;
+ }
+}
+
+sub run_gurpmi() {
+ my @initial_args = ('--replacefiles', '--clean');
+ push @initial_args, "--download-all=$download_dir" if $download_dir;
+
+ # Windows are created before upgrading packages, to guarantee that
+ # any possible related GTK upgrade won't affect us...
+ my $succeeded_win = create_upgrade_succeeded_window();
+ my $failed_win = create_upgrade_failed_window();
+
+ while ($refork_gurpmi) {
+
+ my $ok = fork_gurpmi(@initial_args);
+ if ($refork_gurpmi && !$ok) {
+ $refork_gurpmi--;
+ } else {
+ undef $refork_gurpmi;
+ }
+
+ # update media in case mirrors got updated if needed:
+ update_media() if $refork_gurpmi;
+
+ if (!$refork_gurpmi) {
+ if (!$ok) {
+ $failed_win->main && upgrade();
+ } else {
+ rm_rf(get_stale_upgrade_filename());
+ $succeeded_win->main and !$::testing and any::reboot();
+ my $mgaapp_pid = common::is_running('mgaapplet');
+ defined($mgaapp_pid) && kill('HUP', $mgaapp_pid);
+ }
+ }
+ }
+}
+
+my $width = 500;
+my @common = (
+ # explicitely wrap (for 2008.1):
+ line_wrap => 1,
+ # workaround infamous 6 years old gnome bug #101968:
+ width => $width - 50,
+);
+
+sub create_upgrade_failed_window() {
+ local $mygtk2::left_padding = 0;
+ my $w = ugtk2->new(N("Error"));
+ gtkadd($w->{window},
+ gtknew('VBox', children_tight => [
+ get_banner(),
+ gtknew('Label_Left', text => N("Installation failed"), @common),
+ gtknew('Label_Left', text => N("Installation logs can be found in '%s'", $log_file), @common),
+ create_okcancel($w, N("Retry"), N("Cancel")),
+ ]),
+ );
+ $w->{ok}->grab_focus;
+ return $w;
+}
+
+sub create_upgrade_succeeded_window() {
+ local $mygtk2::left_padding = 0;
+ my $w = ugtk2->new(N("Congratulations"));
+ gtkadd($w->{window},
+ gtknew('VBox', children_tight => [
+ get_banner(),
+ gtknew('Label_Left', text => N("Upgrade to Mageia %s release was successfull.", $new_distro_version),
+ @common),
+ gtknew('Label_Left', text => N("You must restart your system."), @common),
+ create_okcancel($w, N("Reboot"), N("Cancel")),
+ ]),
+ );
+ $w->{ok}->grab_focus;
+ return $w;
+}
+
+# Returns: undef if failed to authenticate, [$email, $passwd] otherwise
+sub powerpack_auth_callback {
+ my ($email, $passwd) = @_;
+ my $profile = mgaonline::get_my_mdv_profile($email, $passwd);
+
+ # Checking for profile retrieving errors...
+ if ($profile->{code} != 0) {
+ my $in = interactive->vnew;
+ $in->ask_warn(N("Error"),
+ N("An error occurred") . "\n" . $profile->{message});
+ return;
+ }
+
+ # Checking rights to powerpack media...
+ #
+ # level 2 => mandriva group
+ # level 6 => powerpack subscriber group
+ # data.families => acces to especific version if matches
+ # powerpack-VERSION
+ #
+ my $level = $profile->{data}{club}{level};
+ if ($level == 2 || $level == 6) {
+ return [$email, $passwd];
+ }
+ elsif ($profile->{data}{families} =~ /powerpack-$new_distro_version/i) {
+ return [$email, $passwd];
+ }
+ else {
+ mgaapplet_gui::run_no_rights_dialog(
+ N("Powerpack Media Configuration"),
+ N("You current Mageia account does not have Powerpack subscription enabled."),
+ 'https://my.mandriva.com/powerpack/',
+ );
+ return;
+ }
+}
+
+sub try_to_add_powerpack_media() {
+ my $is_powerpack = mgaonline::is_restricted_media_supported();
+ my $auth_info;
+
+ # Validating current product for offering powerpack medias...
+
+ if ($is_powerpack) {
+ # Verifying rights of current powerpack users...
+ my $title = N("Powerpack Media Configuration");
+ my $description = N("Please fill your My.Mageia login and password to add additional package media for Powerpack.");
+
+ # If no rights @auth_info == ()...
+ $auth_info = run_ask_credentials_dialog(
+ $title,
+ $description,
+ \&powerpack_auth_callback,
+ );
+ }
+ elsif ($product_id->{product} !~ /flash|free|one/i) {
+ return; # don't offer pwp for any other product
+ }
+
+ my $choice; # will be 'powerpack', 'free' or undef
+ while ($auth_info
+ || ($choice = mgaapplet_gui::open_ask_powerpack_dialog(
+ $product_id->{product},
+ $new_distro_version))) {
+ $auth_info and return $auth_info;
+
+ # Get the new authentication info from user...
+ my $title = N("Powerpack Media Configuration");
+ my $description = N("Please fill your account ID to add Powerpack %s version packages media once you have subscribed online",
+ $new_distro_version);
+ $auth_info = run_ask_credentials_dialog(
+ $title,
+ $description,
+ \&powerpack_auth_callback,
+ top_extra => $mgaapplet_gui::powerpack_ad,
+ );
+ }
+ defined $choice or exit 0; # means user has canceled upgrade
+ return;
+}
+
+sub upgrade() {
+ my $xid = gtkroot()->XWINDOW;
+
+ run_program::raw({ detach => 1 }, 'xdg-screensaver', 'suspend', $xid);
+ my $_w = before_leaving { run_program::raw({ detach => 1 }, 'xdg-screensaver', 'resume', $xid) };
+
+ my $file = "$ENV{HOME}/urpmi.cfg.backup." . int(rand 100000);
+ log::explanations("backuping urpmi configuration in $file");
+ cp_af("$root/etc/urpmi/urpmi.cfg", $file);
+
+ my $urpm = Rpmdrake::open_db::fast_open_urpmi_db();
+
+ my $urpmi_lock = eval {
+ local $urpm->{fatal} = sub { die @_ };
+ urpm::lock::urpmi_db($urpm, 'exclusive');
+ };
+
+ if (my $err = $@) {
+ log::explanations(sprintf("locking urpmi database failed: %s"), $err);
+ ugtk2::ask_warn(N("Error"),
+ N("Installation failed"),
+ '',
+ formatAlaTeX(N("Packages database is locked. Please close other applications
+working with packages database (do you have another media
+manager on another desktop, or are you currently installing
+packages as well?)."))
+ );
+ exit(1);
+ }
+ undef $urpmi_lock;
+
+ touch(get_stale_upgrade_filename());
+
+ log::explanations(
+ "checking if restricted (powerpack) media is to be addded");
+ # add_pwp_auth != undef, means user asked for pwp with good credentials
+ my $add_pwp_auth = try_to_add_powerpack_media();
+
+ log::explanations("removing all existing urpmi media for upgrade");
+ run_program::run('urpmi.removemedia', if_($root, '--urpmi-root', $root), '-a');
+
+ $urpm = Rpmdrake::open_db::fast_open_urpmi_db();
+ if ($urpm->{global_config}{downloader}) {
+ log::explanations("disabling custom downloader in order to use aria2");
+ delete $urpm->{global_config}{downloader};
+ urpm::media::write_config($urpm);
+ }
+
+ log::explanations("adding urpmi media for new distribution");
+
+ $ENV{URPMI_ADDMEDIA_REASON} = join(',', 'reason=upgrade', 'upgrade_by=mgaapplet', "upgrade_from=$product_id->{version}");
+ # the following modifies $MIRRORLIST expansion in urpm/mirrors.pm,
+ # it must be set for gurpmi.addmedia, but also for gurpmi
+ $ENV{URPMI_ADDMEDIA_PRODUCT_VERSION} = $new_distro_version;
+
+ system('gurpmi.addmedia', '--silent-success', if_($root, "--urpmi-root=$root"), '--distrib', '--mirrorlist', '$MIRRORLIST') and do {
+ log::explanations("adding media for new distribution failed");
+ rm_rf(get_stale_upgrade_filename());
+ log::explanations("restoringing urpmi configuration from $file");
+ cp_af($file, "$root/etc/urpmi/urpmi.cfg");
+ update_media();
+ ugtk2::ask_warn(N("Error"),
+ N("Installation failed"),
+ N("Failure when adding medium"),
+ );
+ exit(2);
+ };
+
+ if ($add_pwp_auth) {
+ log::explanations("adding restricted (powerpack) media");
+
+ my ($email, $passwd) = @$add_pwp_auth;
+ unless (mgaonline::add_medium_powerpack(
+ $email,
+ $passwd,
+ $new_distro_version,
+ urpm::cfg::get_arch()
+ )) {
+ # FIXME Don't replicate code like this!
+ log::explanations("adding media for new distribution failed");
+ rm_rf(get_stale_upgrade_filename());
+ log::explanations("restoringing urpmi configuration from $file");
+ cp_af($file, "$root/etc/urpmi/urpmi.cfg");
+ update_media();
+ ugtk2::ask_warn(N("Error"),
+ N("Installation failed"),
+ N("Failed to add powerpack restricted medium"),
+ );
+ exit(2);
+ }
+ # Media was added, update it and move along...
+ update_media();
+ }
+
+ log::explanations("upgrading urpmi and rpmdrake");
+ log::explanations("upgrading the whole system");
+
+ # rerun gurpmi in case there was an issue (with eg: big transactions:
+ $refork_gurpmi = 4;
+ {
+ # force PATH:
+ local $ENV{TMPDIR} = undef;
+ my $log_template =
+ "gurpmi_upgrade_to_${new_distro_version}_XXXXXXXX";
+ $log_file = chomp_(`mktemp -u --tmpdir=$ENV{HOME}/ --suffix=.log $log_template`);
+ log::explanations("logging gurpmi message in '$log_file'");
+ }
+
+ # we cannot use installUpdates() as MandrivaUpdate needs the media
+ # flaged as update (or else, we need to add a new option to MandrivaUpdate):
+ run_gurpmi();
+}
+
+sub fork_gurpmi {
+ run_program::raw({ timeout => 'never' },
+ 'gurpmi', '>>', $log_file, '2>>', $log_file, '--auto', '--auto-select',
+ if_($root, "--urpmi-root=$root"), @_);
+}
+
+sub update_media() {
+ run_program::run('urpmi.update', if_($root, '--urpmi-root', $root), '-a', '--nocheck');
+}