home *** CD-ROM | disk | FTP | other *** search
- /**
- * Module: sw_single.ycp
- *
- * Authors: Gabriele Strattner (gs@suse.de)
- * Klaus Kaempf <kkaempf@suse.de>
- *
- * Purpose: contains dialog loop for workflows:
- * "Install/Remove software"
- *
- * $Id: sw_single.ycp 34559 2006-11-22 12:38:46Z lslezak $
- */
-
- {
- textdomain "packager";
-
- import "Arch";
- import "Confirm";
- import "Installation";
- import "Directory";
- import "Mode";
- import "PackageCallbacks";
- import "PackageLock";
- import "SlideShow";
- import "SlideShowCallbacks";
- import "Kernel";
- import "Wizard";
- import "Popup";
- import "GetInstArgs";
- import "Label";
- import "PackageSystem";
- import "Report";
- import "FileUtils";
-
- Wizard::CreateDialog();
- Wizard::SetDesktopIcon("sw_single");
- Wizard::SetContents(_("Initializing..."), `Empty (), "", false, true);
-
- import "Packages";
-
- list<string> packagelist = []; // list of packages to act on
-
- // `install
- // `remove, `update: used from gnome-main-menu (#222757)
- symbol action = `install;
-
- boolean test_popup = false;
- boolean skip_source = false;
-
- // =============================================================
-
- // check test_popup
- // test_mode is checked for in Installation constructor
-
- define list<string> CheckArguments ()
- {
- integer arg_n = size (WFM::Args()) - 1;
-
- list<string> arg_list = [];
-
- while (arg_n >= 0)
- {
- if (WFM::Args(arg_n) == .test)
- {
- Mode::SetTest ("test");
- }
- else if (WFM::Args(arg_n) == .testp)
- {
- Mode::SetTest ("test"); // .testp implies .test
- test_popup = true;
- }
- else if (is (WFM::Args(arg_n), string))
- {
- string s = tostring (WFM::Args(arg_n));
- if (s == "--install")
- action = `install;
- else if (s == "--remove")
- action = `remove;
- else if (s == "--update")
- action = `update;
- else
- arg_list = add (arg_list, s);
- }
- else if (is (WFM::Args(arg_n), list))
- {
- foreach (any arg, (list)WFM::Args(arg_n), ``{ arg_list = add (arg_list, tostring (arg));});
- }
- arg_n = arg_n - 1;
- }
-
- y2milestone ("action: %1", action);
- return arg_list;
-
- }; // CheckArguments
-
- //
- // CheckWhichPackages
- //
- // Check arg_list:
- // If we're called with an absolute package path just install
- // this package without paying attention to dependencies.
- //
- // returns `done all done
- // `failed package not found
- // `next workflow "Change source of installation"
- // `found_descr started package manager
- // `unknown_descr found nothing
- //
-
- define symbol CheckWhichPackages (list<string> arg_list)
- {
- PackageSystem::EnsureTargetInit();
-
- y2milestone ("CheckWhichPackages (%1)", arg_list);
- // if sw_single is called with a list of packages or a package name
-
- string first_arg = "";
-
- if (size (arg_list) > 0)
- {
- first_arg = arg_list[0]:"";
- }
-
- /*
- * If the first argument is a package ending with .rpm call Pkg::TargetInstall for
- * each arg.
- */
- if (regexpmatch (first_arg, "\\.rpm$")) // package name given
- {
- // if sw_single is called with an absolute package-pathname, there is no need to
- // mount the source medium or check SuSE version or dependencies
-
- Pkg::TargetLogfile (Installation::destdir + Directory::logdir + "/y2logRPM");
-
- SlideShow::InitPkgData(true); // force reinitialization
-
- foreach (string package, arg_list, {
- if (SCR::Read (.target.size, package) > 0)
- {
- y2milestone ("SW_SINGLE: installing %1", package);
- Pkg::TargetInstall (package);
- }
- else
- {
- // error popup, %1 is the name of the .rpm package
- string message = sformat (_("Package %1 was not found on the medium."), package);
- y2error ("SW_SINGLE: Package %1 was not found on the medium", package);
- Popup::Message (message);
- return `failed;
- }
- });
-
- // package is installed without paying attention to SuSE dependencies
- // don't call SuSEConfig -> dialog loop ends
- return `done;
- }
- else if (first_arg != "") // firstarg given, but not *.rpm
- {
- string arg_name = arg_list[0]:"";
-
- if ( ! FileUtils::IsFile(arg_name) || FileUtils::GetSize(arg_name) <= 0 ) // Check: a local file ? bigger than 0?
- {
- packagelist = arg_list; // No: expect package names
- }
- else // Yes: try to read the file
- {
- y2milestone("Reading file %1", arg_name );
- packagelist = (list<string>) SCR::Read( .target.ycp, arg_name); // try .ycp list first
- if ((packagelist == nil)
- || (packagelist == []))
- {
- string packagestr = (string) SCR::Read( .target.string, arg_name); // string ascii file next
- packagelist = splitstring (packagestr, "\n");
- // filter empty lines out, bug #158226
- packagelist = filter (string package, packagelist, { return !regexpmatch(package, "^ *$"); });
- }
- }
- y2milestone("packagelist: %1", packagelist );
- }
-
- // start package manager
- const boolean enabled_only = true;
- boolean mgr_ok = Pkg::SourceStartManager(enabled_only);
- if (!mgr_ok)
- {
- Report::LongWarning(_("There was an error in installation source initialization.") + "\n" + Pkg::LastError ());
- }
- if (size(Pkg::SourceGetCurrent(enabled_only)) == 0)
- {
-
- Report::Warning(_("No installation source is defined.
- Only installed packages are displayed."));
- }
-
- Pkg::TargetInit (Installation::destdir, false);
-
- return `found_descr;
-
- }; // CheckWhichPackages
-
- // originally stolen from inst_do_net_test.ycp:IsDownloadedVersionNewer
- /**
- * Function checks two versions of installed rpm and decides
- * whether the second one is newer than the first one. This
- * function ignores non-numerical values in versions.
- * Version and Release parts are merged!
- * FIXME make a binding to librpm.
- * @param string first version
- * @param string second version
- * @return boolean true if the second one is newer than the first one
- */
- boolean VersionALtB (string a_version, string b_version) {
- list <string> a_version_l = filter(string s, splitstring(a_version, "-\."), {
- return regexpmatch(s, "^[0123456789]+$");
- });
- list <string> b_version_l = filter(string s, splitstring(b_version, "-\."), {
- return regexpmatch(s, "^[0123456789]+$");
- });
-
- y2milestone("Comparing versions %1 and %2", a_version_l, b_version_l);
- integer a_size = size (a_version_l);
- integer b_size = size (b_version_l);
- integer longer_size = a_size > b_size? a_size: b_size;
-
- boolean b_version_is_newer = false;
- integer compare = 0; // <0 if a<b, =0 if a==b, >0 if a>b
- integer i = 0;
- while (i < longer_size) {
- // -1 will make the desirable outcome of "2" < "2.0"
- integer a_item = tointeger(a_version_l[i]:"-1");
- integer b_item = tointeger(b_version_l[i]:"-1");
- if (a_item < b_item) {
- compare = -1;
- break;
- }
- if (a_item > b_item) {
- compare = 1;
- break;
- }
- i = i + 1;
- };
-
- y2milestone("%1 <=> %2 -> %3", a_version, b_version, compare);
- return compare < 0;
- }
-
- /**
- * Check if there is an uninstalled package of the same name with a
- * higher version. Otherwise we would forcefully reinstall it. #222757#c9
- */
- boolean CanBeUpdated (string package) {
- list< map<string,any> > props = Pkg::ResolvableProperties (package, `package, "" /*any version*/);
- // find maximum version and remember
- // if it is installed
- string max_ver = "0";
- boolean max_is_installed = false;
- foreach (map<string,any> prop, props, {
- string cur_ver = prop["version"]:"0";
- if (VersionALtB (max_ver, cur_ver)) {
- max_ver = cur_ver;
- // `installed or `selected is ok
- max_is_installed = prop["status"]:`available != `available;
- y2milestone ("new max: installed: %1", max_is_installed);
- }
- });
- return !max_is_installed;
- }
-
- // =============================================================
-
-
- // check whether running as root
- // and having the packager for ourselves
- if (! Confirm::MustBeRoot () || ! PackageLock::Check ())
- {
- UI::CloseDialog ();
- return `abort;
- }
-
- // check Args
- // set test_mode, test_popup
- list<string> arg_list = CheckArguments();
-
- // check the arguments and try the mount/search for local description
- symbol result = CheckWhichPackages (arg_list);
-
- Pkg::SetLocale (UI::GetLanguage (true));
-
- y2milestone ("SW_SINGLE: result CheckWhichPackages %1", result);
-
- if ((result == `done)
- || (result == `failed))
- {
- UI::CloseDialog();
- UI::CloseDialog();
- return `next;
- }
-
-
- boolean ask = false;
- boolean found_descr = result == `found_descr;
-
- do
- {
- list<string> old_failed_packs = [];
- if ((integer)SCR::Read (.target.size,
- "/var/lib/YaST2/failed_packages") > 0)
- {
- old_failed_packs = (list<string>)
- SCR::Read (.target.ycp, "/var/lib/YaST2/failed_packages");
- }
- if (size (old_failed_packs) > 0 && Popup::YesNo (
- _("During the last package installation,
- several package failed to install.
- Install them now?
- ")))
- {
- foreach (string p, old_failed_packs, {
- Pkg::PkgInstall (p);
- });
- }
-
- if ( found_descr )
- {
- if (size (packagelist) == 0) // packages given ?
- {
- result = (symbol)WFM::CallFunction( "inst_packages", []); // No: ask user via package selection widget
- y2milestone ("inst_packages returns %1", result);
- if (result == `accept)
- {
- result = `next;
- ask = true;
- }
- }
- else
- {
- list<string>nonexisting = filter (string p, packagelist, {
- return ! Pkg::IsAvailable (p);
- });
- if (action != `remove && size (nonexisting) > 0)
- {
- string missing = mergestring (nonexisting, ", ");
- y2error ("Tags %1 aren't available",
- mergestring (nonexisting, ", "));
- Report::Error (sformat (
- // error report, %1 is a list of packages
- _("Following packages haven't been found on the medium:\n%1"),
- mergestring (nonexisting, "\n")));
- return `cancel;
- }
- foreach (string package, packagelist, // Yes: install them
- {
- if (action == `install
- // TODO `update: tell the user if already up to date
- || (action == `update && CanBeUpdated (package))) {
- // select package for installation
- if (!Pkg::PkgInstall (package)) {
- // oops, package not found ? try capability
- Pkg::DoProvide ([package]);
- }
- }
- else if (action == `remove) {
- if (!Pkg::PkgDelete (package)) {
- // package failed, try capability
- Pkg::DoRemove ([package]);
- }
- }
- });
-
- if (Pkg::PkgSolve (false)) // Solve dependencies
- {
- result = `next; // go-on if no conflicts
- }
- else
- {
- result = (symbol)WFM::CallFunction( "inst_packages", []); // Ask user if conflicts
- y2milestone ("inst_packages returns %1", result);
- if (result == `accept)
- result = `next;
- }
- }
- }
-
- if (result == `next) // packages selected ?
- {
- SCR::Write (.target.ycp, "/var/lib/YaST2/failed_packages", []);
- boolean anyToDelete = Pkg::PkgAnyToDelete();
- SlideShow::SetLanguage (UI::GetLanguage(true));
- SlideShow::InitPkgData(true); // force reinitialization
- SlideShow::OpenSlideShowDialog();
-
- import "PackageInstallation";
- Pkg::TargetLogfile (Installation::destdir + Directory::logdir + "/y2logRPM");
- integer oldvmlinuzsize = (integer) SCR::Read(.target.size, "/boot/vmlinuz");
- list commit_result = PackageInstallation::CommitPackages (0, 0); // Y: commit them !
- integer newvmlinuzsize = (integer) SCR::Read(.target.size, "/boot/vmlinuz");
-
- SlideShow::CloseSlideShowDialog();
-
- if (Mode::normal () // run SuSEconfig only in normal system, not during installation
- && Installation::destdir == "/"
- && ((commit_result[0]:0 > 0)
- || anyToDelete))
- {
- // prepare "you must boot" popup in inst_suseconfig
- Kernel::SetInformAboutKernelChange (oldvmlinuzsize != newvmlinuzsize);
-
- result = (symbol) WFM::CallFunction ("inst_suseconfig", [GetInstArgs::Buttons(false, false)]);
- }
- }
- } while ( ask && Popup::YesNo (
- // Popup dialog contents
- _("Install or remove more packages?")));
-
- UI::CloseDialog();
-
- return (symbol) result;
- }
-