ACC SHELL
/**
* Module: Update.ycp
*
* Authors: Anas Nashif <nashif@suse.de>
* Arvin Schnell <arvin@suse.de>
* Lukas Ocilka <locilka@suse.cz>
*
* Purpose: Update module
*
* $Id: Update.ycp 51421 2008-09-23 15:24:33Z locilka $
*/
{
module "Update";
textdomain "update";
import "Installation";
import "Packages";
import "ProductFeatures";
import "ProductControl";
import "Stage";
import "SuSERelease";
import "Mode";
// number of packages to install
global integer packages_to_install = 0;
// number of packages to update
global integer packages_to_update = 0;
// number of packages to remove
global integer packages_to_remove = 0;
// number of packages unknown (problematic) by update
global integer unknown_packages = 0;
// number of errors (packages?) returned by solver
global integer solve_errors = 0;
// // Flag is set true if the user decides to delete unmaintained packages
// global boolean deleteOldPackages = nil;
// Flag is set to true when package downgrade is allowed
global boolean silentlyDowngradePackages = nil;
// Flag is set to true if installed packages should be kept
global boolean keepInstalledPatches = nil;
// don't allow upgrade only update
global boolean disallow_upgrade = false;
global boolean did_init1 = false;
global boolean did_init2 = false;
global integer last_runlevel = -1;
// Only an update, NOT an upgrade
global boolean onlyUpdateInstalled = nil;
global string selected_selection = "";
global boolean products_incompatible = false;
// Version of the targetsystem
//
// !!! moved to Installation::installedVersion !!!
//
// global map <string, any> installedVersion = $[];
// Version of the source medium
//
// !!! moved to Installation::updateVersion !!!
//
// global map <string, any> updateVersion = $[];
// Flag, if the basesystem have to be installed
global boolean updateBasePackages = false;
// counter for installed packages
global integer packagesInstalled = 0;
// see bug #40358
global boolean manual_interaction = false;
// are the products (installed and to update) compatible?
boolean _products_compatible = nil;
/*-----------------------------------------------------------------------
* FATE #301844 - Tuning Update Features
*-----------------------------------------------------------------------*/
boolean ListOfRegexpsMatchesProduct (list <string> regexp_items, string product) {
if (regexp_items == nil || regexp_items == []) return false;
if (product == nil) {
y2error ("Product is nil");
return false;
}
boolean ret = false;
foreach (string one_regexp, regexp_items, {
if (regexpmatch (product, one_regexp)) {
y2milestone (">%1< is matching >%2<", product, one_regexp);
ret = true;
break;
}
});
y2milestone ("Returning %1", ret);
return ret;
}
/**
* Returns whether old packages should be removed (defined in control file).
* True means - delete old RPMs when updating. (Functionality for FATE #301844).
*/
/*
// not supported by libzypp anymore
global boolean DeleteOldPackages () {
// changes deleteOldPackages variable
any default_dop_a = ProductFeatures::GetFeature ("software", "delete_old_packages");
boolean default_dop = nil;
if (default_dop_a == nil || default_dop_a == "") {
y2error ("software/delete_old_packages not defined");
return false;
}
if (is (default_dop_a, boolean)) default_dop = (boolean) default_dop_a;
string installed_system = SuSERelease::ReleaseInformation (Installation::destdir);
y2milestone ("Processing '%1' from '%2'", installed_system, Installation::destdir);
if (installed_system == nil || installed_system == "") {
y2error ("Cannot find out installed system name");
return default_dop;
}
any reverse_dop_a = ProductFeatures::GetFeature ("software", "delete_old_packages_reverse_list");
// No reverse rules defined
if (reverse_dop_a == "") {
return default_dop;
}
// not a list or empty list
list <string> reverse_dop = (list <string>) reverse_dop_a;
if (reverse_dop == nil || reverse_dop == []) return default_dop;
if (ListOfRegexpsMatchesProduct (reverse_dop, installed_system)) {
return (! default_dop);
}
return default_dop;
}
*/
/**
* Returns whether upgrade process should only update installed packages or
* also install new packages. True means - do not upgrade, only update packages.
* (Functionality for FATE #301844).
*/
global boolean OnlyUpdateInstalled () {
// changes onlyUpdateInstalled variable
any default_ous_a = ProductFeatures::GetFeature ("software", "only_update_selected");
boolean default_ous = nil;
if (default_ous_a == nil || default_ous_a == "") {
y2error ("software/only_update_selected not defined");
return false;
}
if (is (default_ous_a, boolean)) default_ous = (boolean) default_ous_a;
string installed_system = SuSERelease::ReleaseInformation (Installation::destdir);
y2milestone ("Processing '%1' from '%2'", installed_system, Installation::destdir);
if (installed_system == nil || installed_system == "") {
y2error ("Cannot find out installed system name");
return default_ous;
}
any reverse_ous_a = ProductFeatures::GetFeature ("software", "only_update_selected_reverse_list");
// No reverse rules defined
if (reverse_ous_a == "") {
return default_ous;
}
// not a list or empty list
list <string> reverse_ous = (list <string>) reverse_ous_a;
if (reverse_ous == nil || reverse_ous == []) return default_ous;
if (ListOfRegexpsMatchesProduct (reverse_ous, installed_system)) {
return (! default_ous);
}
return default_ous;
}
/**
* Returns whether upgrade process should silently downgrade packages if needed.
* 'true' means that packages might be downgraded, 'nil' is returned when
* the feature is not supported in the control file.
*/
global boolean SilentlyDowngradePackages () {
// returns empty string if not defined, buggy GetBooleanFeature
any default_sdp_a = ProductFeatures::GetFeature ("software", "silently_downgrade_packages");
boolean default_sdp = nil;
if (default_sdp_a == nil || default_sdp_a == "") {
y2milestone ("software/silently_downgrade_packages not defined");
return nil;
}
if (is (default_sdp_a, boolean)) default_sdp = (boolean) default_sdp_a;
string installed_system = SuSERelease::ReleaseInformation (Installation::destdir);
y2milestone ("Processing '%1' from '%2'", installed_system, Installation::destdir);
if (installed_system == nil || installed_system == "") {
y2error ("Cannot find out installed system name");
return default_sdp;
}
any reverse_sdp_a = ProductFeatures::GetFeature ("software", "silently_downgrade_packages_reverse_list");
// No reverse rules defined
if (reverse_sdp_a == "") {
return default_sdp;
}
// not a list or empty list
list <string> reverse_sdp = (list <string>) reverse_sdp_a;
if (reverse_sdp == nil || reverse_sdp == []) return default_sdp;
if (ListOfRegexpsMatchesProduct (reverse_sdp, installed_system)) {
return (! default_sdp);
}
return default_sdp;
}
/**
* Returns whether the installed product is supported for upgrade.
* (Functionality for FATE #301844).
*/
global boolean IsProductSupportedForUpgrade () {
string installed_system = SuSERelease::ReleaseInformation (Installation::destdir);
y2milestone ("Processing '%1' from '%2'", installed_system, Installation::destdir);
if (installed_system == nil || installed_system == "") {
y2error ("Cannot find out installed system name");
return false;
}
any supported_products_a = ProductFeatures::GetFeature ("software", "products_supported_for_upgrade");
// No products defined
if (supported_products_a == "") {
y2warning ("No products_supported_for_upgrade defined");
return true;
}
// not a list or empty list
list <string> supported_products = (list <string>) supported_products_a;
if (supported_products == nil || supported_products == []) return true;
if (ListOfRegexpsMatchesProduct (supported_products, installed_system)) {
return true;
}
return false;
}
/*-----------------------------------------------------------------------
* GLOBAL FUNCTIONS
*-----------------------------------------------------------------------*/
global list<string> SelectedProducts () {
list<map<string,any> > selected
= Pkg::ResolvableProperties ("", `product, "");
selected = filter (map<string,any> p, selected, {
return p["status"]:nil == `selected;
});
return maplist (map<string,any> p, selected, {
// TRANSLATORS: "Update to: $product_name"
return p["display_name"]:p["summary"]:p["name"]:p["version"]:_("Unknown Product");
});
}
/**
* Check if installed product and product to upgrade to are compatible
* @return boolean true if update is possible
*/
global boolean ProductsCompatible () {
if (_products_compatible == nil)
{
if (Stage::normal ())
{
// check if name of one of the products on the installation
// media is same as one of the installed products
// assuming that multiple products on installation media
// are compatible and compatibility is transitive
list<map<string,any> > inst =
Pkg::ResolvableProperties ("", `product, "");
inst = filter (map<string,any> p, inst, {
return p["status"]:nil == `installed;
});
list<string> inst_names = maplist (map<string,any> p, inst, {
return p["name"]:"";
});
list<string> to_install = maplist (integer src,
Pkg::SourceGetCurrent (true),
{
map<string,string> prod_info = Pkg::SourceProduct (src);
return prod_info["name"]:"";
});
// filter out empty products
to_install = filter (string o_p, to_install, { return o_p != ""; });
y2milestone ("Installed products: %1", inst_names);
y2milestone ("Products on installation media: %1", to_install);
// at least one product name found
if (size (to_install) > 0) {
string equal_product = find (string i, inst_names, {
string found = find (string u, to_install, {
return u == i;
});
return found != nil;
});
_products_compatible = equal_product != nil;
// no product name found
// bugzilla #218720, valid without testing according to comment #10
} else {
y2warning ("No products found, setting product-compatible to 'true'");
_products_compatible = true;
}
}
else
{
_products_compatible = true; // FIXME this is temporary
}
y2milestone ("Products found compatible: %1", _products_compatible);
}
return _products_compatible;
}
global void IgnoreProductCompatibility () {
_products_compatible = true;
}
/**
* Set initial values for variables that user can't change.
* They are defined in the control file.
*/
global define void InitUpdate () {
y2milestone ("Calling: InitUpdate()");
silentlyDowngradePackages = SilentlyDowngradePackages();
y2milestone ("silentlyDowngradePackages: %1", silentlyDowngradePackages);
}
/**
* Drops packages defined in control file (string) software->dropped_packages
*
* @see bnc #300540
*/
global void DropObsoletePackages () {
string packages_to_drop = ProductFeatures::GetStringFeature ("software", "dropped_packages");
if (packages_to_drop == nil || packages_to_drop == "") {
y2milestone ("No obsolete packages to drop");
return;
}
list <string> l_packages_to_drop = splitstring (packages_to_drop, ", \n");
y2milestone ("Packages to drop: %1", l_packages_to_drop);
foreach (string one_package, l_packages_to_drop, {
if (Pkg::PkgInstalled (one_package) || Pkg::IsSelected (one_package)) {
y2milestone ("Package to delete: %1", one_package);
Pkg::PkgDelete (one_package);
}
});
}
/**
*
*/
global define void Reset ()
{
y2milestone ("Calling: UpdateReset()");
Update::InitUpdate();
// deleteOldPackages = DeleteOldPackages();
// y2milestone ("deleteOldPackages %1", deleteOldPackages);
onlyUpdateInstalled = OnlyUpdateInstalled();
y2milestone ("onlyUpdateInstalled %1", onlyUpdateInstalled);
disallow_upgrade = false;
manual_interaction = false;
products_incompatible = false;
_products_compatible = nil;
Installation::update_backup_modified = true;
Installation::update_backup_sysconfig = true;
Installation::update_remove_old_backups = false;
Installation::update_backup_path = "/var/adm/backup";
}
/**
*
*/
global define void fill_version_map (map <string, any>& data)
{
if (data["name"]:"?" == "?" && data["version"]:"?" == "?") {
data["nameandversion"] = "?";
} else {
data["nameandversion"] = data["name"]:"?" + " " + data["version"]:"?";
}
list <string> tmp0 = [];
if (regexpmatch (data["version"]:"", " -")) {
splitstring (data["version"]:"", " -");
}
list <string> tmp1 = [];
if (regexpmatch (tmp0[0]:"", "\.")) {
splitstring (tmp0[0]:"", ".");
}
integer tmp2 = tointeger (tmp1[0]:"-1");
if (tmp2 >= 0)
data["major"] = tmp2;
integer tmp3 = tointeger (tmp1[1]:"-1");
if (tmp3 >= 0)
data["minor"] = tmp3;
}
/**
* Read product name and version for the old and new release.
* Fill Installation::installedVersion and Installation::updateVersion.
* @return success
*/
global define boolean GetProductName ()
{
Installation::installedVersion = $[];
Installation::updateVersion = $[];
// get old product name
// cannot use product information from package manager
// for pre-zypp products
// #153576
string old_name = SuSERelease::ReleaseInformation
(Installation::destdir);
y2milestone("SuSERelease::ReleaseInformation: %1", old_name);
// Remove 'Beta...' from product release
if (regexpmatch (old_name, "Beta")) {
old_name = regexpsub (old_name, "^(.*)[ \t]+Beta.*$", "\\1");
// Remove 'Alpha...' from product release
} else if (regexpmatch (old_name, "Alpha")) {
old_name = regexpsub (old_name, "^(.*)[ \t]+Alpha.*$", "\\1");
}
integer p = findlastof (old_name, " ");
if (p == nil)
{
y2error ("release info <%1> is screwed", old_name);
Installation::installedVersion = $[];
}
else
{
Installation::installedVersion["show"] = old_name;
Installation::installedVersion["name"] = substring (old_name, 0, p);
Installation::installedVersion["version"] = substring (old_name, p + 1);
fill_version_map (Installation::installedVersion);
}
// "minor" and "major" version keys
// bug #153576, "version" == "9" or "10.1" or ...
string inst_ver = Installation::installedVersion["version"]:"";
if (inst_ver != "" && inst_ver != nil) {
// SLE, SLD, OES...
if (regexpmatch (inst_ver, "^[0123456789]+$")) {
Installation::installedVersion["major"] = tointeger (inst_ver);
// openSUSE
} else if (regexpmatch (inst_ver, "^[0123456789]+\.[0123456789]+$")) {
Installation::installedVersion["major"] = tointeger (regexpsub (inst_ver, "^([0123456789]+)\.[0123456789]+$", "\\1"));
Installation::installedVersion["minor"] = tointeger (regexpsub (inst_ver, "^[0123456789]+\.([0123456789]+)$", "\\1"));
} else {
y2error("Cannot find out major/minor from >%1<", inst_ver);
}
} else {
y2error("Cannot find out version: %1", Installation::installedVersion);
}
if (Mode::test()) {
y2error ("Skipping detection of new system");
return true;
}
// get new product name
integer num = size (Packages::theSources);
if (num <= 0)
{
y2error ("No source");
Installation::updateVersion["name"] = "?";
Installation::updateVersion["version"] = "?";
fill_version_map (Installation::updateVersion);
return false;
}
integer update_to_source = nil;
y2milestone ("Known sources: %1", Packages::theSources);
// So-called System Update
if (Stage::normal()) {
foreach (integer source_id, Packages::theSources, {
map source_map = Pkg::SourceProductData (source_id);
// source need to be described
if (source_map != $[]) {
if (source_map["productversion"]:"A" == Installation::installedVersion["version"]:"B") {
y2milestone ("Found matching product: %1", source_map);
update_to_source = source_id;
} else {
y2error ("Found non-matching product: %1", source_map);
// every invalid product is selected
if (update_to_source == nil)
update_to_source = source_id;
}
}
});
}
// fallback for Stage::normal()
if (Stage::normal()) {
if (update_to_source == nil) update_to_source = Packages::theSources[num-1]:0;
// default for !Stage::normal
} else {
update_to_source = Packages::GetBaseSourceID();
}
map new_product = Pkg::SourceProductData (update_to_source);
map new_source = Pkg::SourceGeneralData (update_to_source);
y2milestone ("Product to update to: %1 %2 %3", update_to_source, new_product, new_source);
if (new_product == nil)
{
Installation::updateVersion["name"] = "?";
Installation::updateVersion["version"] = "?";
y2error("Cannot find out source details: %1", Installation::updateVersion);
fill_version_map (Installation::updateVersion);
return false;
}
// bugzilla #225256, use "label" first, then a "productname"
Installation::updateVersion["show"] = new_product["label"]:nil;
if (Installation::updateVersion["show"]:nil == nil) {
y2warning ("No 'label' defined in product");
if (new_product["productname"]:"?" == "?" && new_product["productversion"]:"?" == "?") {
Installation::updateVersion["show"] = "?";
} else {
Installation::updateVersion["show"] = new_product["productname"]:"?" + " " + new_product["productversion"]:"?";
}
}
Installation::updateVersion["name"] = new_product["label"]:new_product["productname"]:"?";
Installation::updateVersion["version"] = new_product["productversion"]:"?";
fill_version_map (Installation::updateVersion);
string new_ver = Installation::updateVersion["version"]:"";
if (new_ver != "" && new_ver != nil) {
// SLE, SLD, OES...
if (regexpmatch (new_ver, "^[0123456789]+$")) {
Installation::updateVersion["major"] = tointeger (new_ver);
// openSUSE
} else if (regexpmatch (new_ver, "^[0123456789]+\.[0123456789]$")) {
Installation::updateVersion["major"] = tointeger (regexpsub (new_ver, "^([0123456789]+)\.[0123456789]$", "\\1"));
Installation::updateVersion["minor"] = tointeger (regexpsub (new_ver, "^[0123456789]+\.([0123456789])$", "\\1"));
} else {
y2error("Cannot find out major/minor from %1", new_ver);
}
} else {
y2error("Cannot find out version: %1", Installation::updateVersion);
}
y2milestone ("update from %1 to %2", Installation::installedVersion, Installation::updateVersion);
return true;
}
global list<string> GetBasePatterns ()
{
// get available base patterns
list<map<string,any> > patterns = Pkg::ResolvableProperties ("", `pattern, "");
patterns = filter (map<string,any> p, patterns, {
if (p["status"]:nil != `selected && p["status"]:nil != `available)
return false;
// if type != base
return true;
});
return maplist (map<string,any> p, patterns, {
return p["name"]:"";
});
}
/**
* Get all available base selections sorted in reverse order
* (highest ordered bases selection comes first).
*/
global define list<string> GetBaseSelections ()
{
list<string> available_base_selections = sort (string x, string y, Pkg::GetSelections (`available, "base"), {
map xmap = Pkg::SelectionData(x);
map ymap = Pkg::SelectionData(y);
return (xmap["order"]:"" > ymap["order"]:"");
});
y2milestone ("available_base_selections %1", available_base_selections);
return available_base_selections;
}
string ReadInstalledDesktop() {
SCR::Execute (.target.bash, "/bin/mv -f /etc/sysconfig/windowmanager /etc/sysconfig/windowmanager.old");
SCR::Execute (.target.bash, "/bin/ln -s /mnt/etc/sysconfig/windowmanager /etc/sysconfig/windowmanager");
string ret = (string)SCR::Read (.sysconfig.windowmanager.DEFAULT_WM);
SCR::Execute (.target.bash, "/bin/rm -f /etc/sysconfig/windowmanager");
SCR::Execute (.target.bash, "/bin/mv -f /etc/sysconfig/windowmanager.old /etc/sysconfig/windowmanager");
return ret;
}
global void SetDesktopPattern() {
string desktop = ReadInstalledDesktop();
if (desktop == "kde" || desktop == "gnome")
{
y2milestone ("Selecting pattern to install: %1", desktop);
Pkg::ResolvableInstall (desktop, `pattern);
}
}
/**
* Propose a selection for the update and save it's name in
* Update::selected_selection.
*/
global define void ProposeSelection ()
{
selected_selection = "";
list available_selections = GetBaseSelections ();
// nulth try: teh default desktop
string desktop = ReadInstalledDesktop();
map wm2sel = $[
"kde" : "default",
"gnome" : "default-Gnome",
];
selected_selection = wm2sel[desktop]:"";
if (!contains (available_selections, selected_selection))
selected_selection = "";
if (selected_selection != "")
{
y2milestone ("using default desktop %1 to define selection: %2",
desktop, selected_selection);
return;
}
// first try: installed one
list tmp1 = Pkg::GetSelections (`installed, "base");
if (tmp1 != nil && tmp1 != [])
selected_selection = tmp1[0]:"";
if (!contains (available_selections, selected_selection))
selected_selection = "";
if (selected_selection != "") {
y2milestone ("using installed selection: %1", selected_selection);
return;
}
// second try: available selection with highest order
if (size (available_selections) > 0)
selected_selection = available_selections[0]:"";
if (selected_selection != "") {
y2milestone ("using highest order selection: %1", selected_selection);
return;
}
// error: no selection available
y2error ("no selection available");
}
/**
*
*/
global define void Detach ()
{
Pkg::TargetFinish ();
did_init1 = false;
did_init2 = false;
}
void TextsUsedInFuture () {
// TRANSLATORS: check-box, it might happen that we need to downgrade some packages during update
string aaa = _("Allow Package Downgrade");
}
}
ACC SHELL 2018