home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
modules
/
Packages.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
39KB
|
1,350 lines
/**
* File: Packages.ycp
* Package: Package selections
* Authors: Anas Nashif <nashif@suse.de>
*
* $Id: Packages.ycp 34552 2006-11-22 08:26:03Z lslezak $
*/
{
module "Packages";
textdomain "packager";
import "AddOnProduct";
import "Arch";
import "Directory";
import "InstURL";
import "Kernel";
import "Mode";
import "Stage";
import "Linuxrc";
import "Language";
import "ProductFeatures";
import "ProductControl";
import "Report";
import "SlideShow";
import "SpaceCalculation";
import "String";
import "Popup";
import "Label";
import "Wizard";
import "DirInstall";
import "PackageCallbacksInit";
import "Product";
import "DefaultDesktop";
import "SourceDialogs";
/**
* Force full proposal routine next run
*/
boolean full_repropose = false;
/**
* Installation source has been initialized?
*/
boolean init_called = false;
/**
* Installation source initialization is WIP
*/
boolean init_in_progress = false;
/**
* Error which occurred during installation source initialization
*/
string init_error = nil;
// cache for the proposed summary
map cached_proposal = nil;
// the selection used for the cached proposal
list<string> cached_proposal_packages = [];
list<map> cached_proposal_patterns = [];
list<map> cached_proposal_products = [];
list<map> cached_proposal_patches = [];
list<map> cached_proposal_selections = [];
list<string> cached_proposal_languages = [];
global boolean install_sources = false; // Installing source packages ?
global integer timestamp = 0; // last time of getting the target map
global string metadir = "/yast-install";
global boolean metadir_used = false; // true if meta data and inst-sys is in ramdisk
global list<integer> theSources = []; // id codes of sources in priority order
global list<string> theSourceDirectories = []; // product directories on sources
global map<integer,integer> theSourceOrder = $[]; // installation order
string servicepack_metadata = "/servicepack.tar.gz";
// to remember if warning should occurre if switching base selection
global boolean base_selection_modified = false;
global boolean base_selection_changed = false;
// Local variables
string choosen_base_selection = "";
// count of errors during packages solver
global integer solve_errors = 0;
/**
* Packages to be selected when proposing the list
*/
list<string> additional_packages = [];
boolean system_packages_selected = false;
// DefaultDesktop::PrefferedWindowManager
// global string window_manager = nil;
global boolean using_patterns = false;
global string add_on_products_list = nil;
// summary functions
/**
* List selected resolvables of specified kind
* @param what symbol specifying the kind of resolvables to select
* @param format string format string to print summaries in
* @return a list of selected resolvables
*/
global list<string> ListSelected (symbol what, string format) {
if (format == "" || format == nil)
format = "%1";
list<map<string,any> > selected = Pkg::ResolvableProperties ("", what, "");
// ignore hidden patterns
if (what == `pattern)
{
selected = filter (map<string,any> r, selected, {
return r["user_visible"]:nil == true;
});
}
selected = filter (map<string,any> r, selected, {
return r["status"]:nil == `selected;
});
list<string> ret = maplist (map<string,any> r, selected, {
string disp = r["summary"]:r["name"]:"";
return sformat (format, disp);
});
return ret;
}
/**
* Count the total size of packages to be installed
* @return string formatted size of packages to be installed
*/
global string CountSizeToBeInstalled () {
integer sz = 0;
if (! Mode::installation () && !DirInstall::installing_into_dir )
{
list<string> packages = Pkg::GetPackages (`selected, true);
foreach (string p, packages, {
sz = sz + Pkg::PkgSize (p);
});
// convert into kB
sz = sz / 1024;
}
else // in case of fresh installation, disk is initially empty
{
map<string,list> du = Pkg::TargetGetDU ();
foreach (string mp, list usages, du, {
sz = sz + usages[2]:0 - usages[1]:0;
});
}
y2milestone ("Total size of packages to install (kB): %1", sz);
return String::FormatSizeWithPrecision (sz*1024, 1, true);
}
/**
* Return information about suboptimal distribution if relevant
* @return string the information string or empty string
*/
global string InfoAboutSubOptimalDistribution () {
// warn about suboptimal distribution
// this depends on the kernel
string dp = (string) SCR::Read(.content.DISTPRODUCT);
if (dp==nil)
dp = "";
if (ProductFeatures::GetBooleanFeature ("software",
"inform_about_suboptimal_distribution") &&
Arch::i386 () && issubstring(dp, "DVD"))
{
string tmp = (string) SCR::Read(.proc.cpuinfo.value."0"."flags");
list flags = (size (tmp) > 0) ? splitstring (tmp, " ") : [];
// this depends on the cpu (lm = long mode)
if (contains (flags, "lm"))
{
// warning text
return _("Your computer is a 64-bit x86-64 system. However, you are trying to install a 32-bit distribution.");
}
}
return "";
}
/**
* Return the summary output lines
* @param flags a list of flags, allowed are `product, `pattern, `selection,
* `size, `desktop
* @return a list of the output lines
*/
global list<string> SummaryOutput (list<symbol> flags) {
list<string> output = [ InfoAboutSubOptimalDistribution () ];
if (contains (flags, `product))
output = (list<string>)merge (output, ListSelected (`product, ""));
if (contains (flags, `desktop))
output = (list<string>)add (output, DefaultDesktop::Description ());
if (contains (flags, `pattern))
output = (list<string>)
merge (output, ListSelected (`pattern, "+ %1"));
if (contains (flags, `selection))
output = (list<string>)
merge (output, ListSelected (`selection, "+ %1"));
if (contains (flags, `size))
output = (list<string>)add (output,
// part of summary, %1 is size of packages (in MB or GB)
sformat (_("Size of Packages to Install: %1"),
CountSizeToBeInstalled ()));
output = filter (string o, output, {
return o != "" && o != nil;
});
return output;
}
/**
* Check if selected software fits on the partitions
* @param init boolean true if partition sizes have changed
* @return boolean true if selected software fits, false otherwise
*/
global boolean CheckDiskSize (boolean init) {
if (init)
{
y2milestone ("Resetting space calculation");
SpaceCalculation::GetPartitionInfo();
}
return SpaceCalculation::CheckDiskSize();
}
/**
* Print the installatino proposal summary
* @param flags a list of symbols, see above
* @param boolean use_cache if true, use previous proposal if possible
* @returnu a map proposal summary
*/
global map Summary (list<symbol> flags, boolean use_cache) {
if (init_error != nil)
{
return $[
"warning" : init_error,
"warning_level" : `blocker,
];
}
map ret = $[];
if (! CheckDiskSize (! use_cache))
{
ret = $[
"warning" : ProductFeatures::GetFeature ("software","selection_type") == `fixed
// summary warning
? _("Not enough disk space.")
// summary warning
: _("Not enough disk space. Remove some packages in the single selection."),
"warning_level" : Mode::update() ? `warning : `blocker,
];
}
else
{
// check available free space (less than 5% and less than 1GB)
list<map> free_space = SpaceCalculation::CheckDiskFreeSpace(5, 1024*1024);
if (size(free_space) > 0)
{
string warning = "";
foreach(map df, free_space,
{
string partition = df["dir"]:"";
integer free_pct = df["free_percent"]:0;
integer free_kB = df["free_size"]:0;
string w = sformat(_("Only %1 (%2%%) free space available on partition %3.<BR>"), String::FormatSize(free_kB*1024), free_pct, partition);
warning = warning + w;
}
);
if (warning != "")
{
ret["warning"] = warning;
ret["warning_level"] = `warning;
}
}
}
ret["raw_proposal"] = SummaryOutput (flags);
return ret;
}
// proposal control functions
global void ForceFullRepropose () {
full_repropose = true;
}
global boolean SelectProduct ();
/**
* Reset package selection, but keep objects of specified type
* @param keep a list of symbols specifying type of objects to be kept
*/
global void Reset (list<symbol> keep) {
list<map<string,any> > restore = [];
foreach (symbol type, keep, {
list<map<string,any> > selected = Pkg::ResolvableProperties ("", type, "");
foreach (map<string,any> s, selected, {
restore = add (restore, $[
"type" : type,
"name" : s["name"]:""
]);
});
});
Pkg::PkgReset();
foreach (map<string,any> res, restore, {
Pkg::ResolvableInstall (res["name"]:"", (symbol)(res["type"]:nil));
});
system_packages_selected = false;
}
/**
* Initialize add-on products provided by the installation source
*/
global void InitializeAddOnProducts() {
if (Packages::add_on_products_list != nil)
{
y2milestone ("Found list of add-on products to preselect: %1", Packages::add_on_products_list);
Packages::SelectProduct ();
PackageCallbacksInit::SetMediaCallbacks();
AddOnProduct::AddPreselectedAddOnProducts (Packages::add_on_products_list);
Packages::add_on_products_list = nil; // do not select them any more
}
}
/*-----------------------------------------------------------------------
* LOCALE FUNCTIONS
*-----------------------------------------------------------------------*/
/**
* Add a package to list to be selected before proposal
* Can be called only before the installation proposal, later doesn't
* have any effect
* @param package string package to be selected
*/
global void addAdditionalPackage(string package)
{
additional_packages = add (additional_packages, package);
}
/**
* Compute architecture packages
* @return list(string)
*/
define list<string> architecturePackages ()
{
list<string> packages = [];
// remove unneeded / add needed packages for ppc
if (Arch::ppc ())
{
if (Arch::board_mac ())
{
packages = add (packages, "mouseemu");
}
if (Arch::board_mac_new ()
|| Arch::board_mac_old ())
{
string pmac_board = "";
list<map> pmac_compatible = (list<map>) SCR::Read(.probe.cpu);
foreach (map pmac_compatible_tmp, pmac_compatible, {
pmac_board = pmac_compatible_tmp["system"]:"";
});
// install pbbuttonsd on PowerBooks and iMacs
if (issubstring (pmac_board, "PowerBook")
|| issubstring (pmac_board, "PowerMac2,1")
|| issubstring (pmac_board, "PowerMac2,2")
|| issubstring (pmac_board, "PowerMac4,1")
|| issubstring (pmac_board, "iMac,1"))
{
packages = add (packages, "pbbuttonsd");
packages = add (packages, "powerprefs");
}
// mol is fun, and needs root access to kmem
packages = add (packages, "mol");
packages = add (packages, "sudo");
}
if (Arch::ppc64 () && (Arch::board_chrp () || Arch::board_iseries ()))
{
packages = add (packages, "iprutils");
}
}
if (Arch::ia64 ())
{
// install fpswa if the firmware has an older version
if (SCR::Execute(.target.bash, "/sbin/fpswa_check_version") != 0)
{
packages = add (packages, "fpswa");
}
}
// add numactl on x86_64 with SMP
if (Arch::has_smp () && Arch::x86_64 ())
{
packages = add (packages, "numactl");
packages = add (packages, "irqbalance");
}
return packages;
}
/**
* graphicPackages ()
* Compute graphic (x11) packages
* @return list(string) list of rpm packages needed
*/
define list<string> graphicPackages ()
{
list<string> packages = [];
// don't setup graphics if running via serial console
if (!Linuxrc::serial_console ())
{
packages = [ "xorg-x11", "xorg-x11-server", "xorg-x11-server-glx",
"libusb", "sax2", "sax2-gui", "sax2-ident", "sax2-tools",
"sax2-libsax", "sax2-libsax-perl"];
}
y2milestone ("X11 Packages to install: %1", packages);
return packages;
}
/**
* Compute special packages
* @return list(string)
*/
define list<string> modePackages ()
{
list<string> packages = [];
if (Linuxrc::vnc ())
{
packages = add (packages, "tightvnc");
packages = add (packages, "yast2-qt");
packages = add (packages, "xorg-x11");
packages = add (packages, "fvwm2");
packages = add (packages, "sax2-tools");
}
if (Linuxrc::display_ip ())
{
packages = add (packages, "yast2-qt");
packages = add (packages, "xorg-x11");
packages = add (packages, "fvwm2");
packages = add (packages, "sax2-tools");
}
if (Linuxrc::braille ())
{
packages = add (packages, "sbl");
}
y2milestone ("Installation mode packages: %1", packages);
return packages;
}
/**
* Compute special java packages
* @return list(string)
*/
define list<string> javaPackages ()
{
if (!Arch::alpha ())
return [];
list<string> packages = [];
list cpus = (list) SCR::Read (.probe.cpu);
string model = cpus[0, "model"]:"EV4";
string cputype = substring (model, 2, 1);
if ((cputype == "6") || (cputype == "7") || (cputype == "8"))
{
packages = ["cpml_ev6"];
}
else
{
packages = ["cpml_ev5"];
}
return packages;
}
/**
* Compute language dependant packages
* @return list(string)
*/
define list<string> languagePackages ()
{
list<string> packages = [];
list<string> locales = Pkg::GetAdditionalLocales();
locales = prepend (locales, Pkg::GetLocale());
string transpac = "yast2-trans-";
foreach (string loc, locales, {
if (Pkg::IsAvailable (transpac + loc))
packages = add (packages, transpac + loc);
else if (Pkg::IsAvailable (transpac + substring (loc, 0, 2)))
packages = add (packages, transpac + substring (loc, 0, 2));
else
y2warning ("No locale package found for %1", loc);
});
y2milestone ("Language packages: %1", packages);
return packages;
}
/**
* Compute board (vendor) dependant packages
* @return list(string)
*/
define list<string> boardPackages ()
{
list<string> packages = [];
list <map <string, any> > probe = (list <map <string, any> >)SCR::Read (.probe.system);
packages = (list<string>)probe[0,"requires"]:[];
y2milestone ("Board/Vendor specific packages: %1", packages);
return packages;
}
/**
* Compute packages required to access the installation source
* @return list(string) list of the required packages
*/
list<string> sourceAccessPackages()
{
list<string> ret = [];
string instmode = Linuxrc::InstallInf("InstMode");
y2milestone("Installation mode: %1", instmode);
if (instmode == "smb" || instmode == "cifs")
{
// /sbin/mount.cifs is required to mount a SMB/CIFS share
ret = ["cifs-mount"];
}
y2milestone("Packages for access to the installation source: %1", ret);
return ret;
}
/*
* Additional kernel packages from control file
* @return list<string> Additional Kernel packages
*/
define list<string> ComputeAdditionalKernelPackages ()
{
string final_kernel = Kernel::GetFinalKernel ();
integer pos = findfirstof(final_kernel, "-");
string extension = substring(final_kernel, pos, size(final_kernel));
list<string> akp = [];
if (extension!="")
{
list<string> kernel_packages = (list<string>)
ProductFeatures::GetFeature ("software", "kernel_packages");
if (size(kernel_packages) > 0 && kernel_packages != nil)
{
akp = maplist(string p , kernel_packages, {
return (p + "-" + extension);
});
}
}
return akp;
}
/*-----------------------------------------------------------------------
* GLOBAL FUNCTIONS
*-----------------------------------------------------------------------*/
global list<string> ComputeSystemPatternList () {
list<string> pattern_list = [];
// also add the 'laptop' selection if PCMCIA detected
if (Arch::is_laptop () || Arch::has_pcmcia ())
{
foreach (string pat_name, ["laptop", "Laptop"], {
list<map<string, any> > pat_list = Pkg::ResolvableProperties (pat_name, `pattern, "");
if (size (pat_list) > 0)
pattern_list = add (pattern_list, pat_name);
});
}
y2milestone ("System patterns: %1", pattern_list);
return pattern_list;
}
/**
* Build and return list of packages which depends on the
* the current target system and the preselected packages
* (architecture, X11....)
* @return list<string> packages
*/
global define list<string> ComputeSystemPackageList ()
{
import "Storage";
list<string> install_list = architecturePackages ();
install_list = (list<string>) union (install_list, modePackages ());
install_list = (list<string>) union (install_list,
Storage::AddPackageList());
install_list = (list<string>) union (install_list,
additional_packages);
// Kernel is added in autoinstPackages () if autoinst is enabled
if (!Mode::update () || !Mode::autoinst ())
{
list <string> kernel_pkgs = Kernel::ComputePackages ();
list <string> kernel_pkgs_additional = ComputeAdditionalKernelPackages();
install_list = (list <string>) union (install_list, kernel_pkgs);
if (size(kernel_pkgs_additional) > 0 && kernel_pkgs_additional != nil)
{
install_list = (list <string>) union (install_list, kernel_pkgs_additional);
}
}
if (Pkg::IsSelected("xorg-x11") && Linuxrc::vnc ())
{
install_list = (list<string>) union (install_list, graphicPackages ());
}
else
{
y2milestone ("Not selecting graphic packages");
}
if (Pkg::IsSelected("java"))
{
install_list = (list<string>) union (install_list, javaPackages ());
}
else
{
y2milestone ("Not selecting java packages");
}
install_list = (list<string>) union (install_list, languagePackages ());
install_list = (list<string>) union (install_list, boardPackages ());
// add packages required to access the installation source in the 2nd stage and at run-time
install_list = (list<string>) union (install_list, sourceAccessPackages());
// and the most flexible enhancement for other products
// NOTE: not really flexible, because it requires the client
// in the instsys, instead use <kernel-packages> in the control file.
if (ProductFeatures::GetFeature ("software", "packages_transmogrify") != "")
{
list<string> tmp_list = (list<string>)
WFM::CallFunction (ProductFeatures::GetStringFeature ("software", "packages_transmogrify"),
[ install_list ]);
// Make sure we did not get a nil from calling the client, i.e.
// if the client does not exist at all..
if (tmp_list != nil)
{
install_list = tmp_list;
}
}
list<string> packages = (list<string>)
ProductFeatures::GetFeature ("software", "packages");
if (size(packages) > 0 && packages != nil )
{
y2milestone("Adding packages from control file: %1", packages);
install_list = (list<string>) union (install_list, packages);
}
install_list = toset (install_list);
y2milestone ("auto-adding packages: %1", install_list);
return install_list;
}
/**
* Check whether content file in the specified source is the same
* as the one in the ramdisk
* @param source integer the source ID to check
* @return boolean true if content files match
*/
global boolean CheckContentFile (integer source) {
y2milestone ("Checking content file");
string instmode = Linuxrc::InstallInf("InstMode");
if (! (instmode == nil || instmode == "cd" || instmode == "dvd"))
{
y2milestone ("Installing via network, not checking the content file");
return true;
}
string media_content = Pkg::SourceProvideFile (source, 1, "/content");
string media = (string)SCR::Read (.target.string, media_content);
string ramdisk = (string)SCR::Read (.target.string, "/content");
boolean ret = (media == ramdisk);
y2milestone ("Content files are the same: %1", ret);
return ret;
}
/**
* Import GPG keys found in the inst-sys
*/
void ImportGPGKeys () {
map out = (map) SCR::Execute (.target.bash_output, "/bin/ls -d /*.gpg");
foreach (string file, splitstring (out["stdout"]:"", "\n"), {
if (file != "")
Pkg::ImportGPGKey (file, true);
});
}
string UpdateSourceURL (string url) {
string ret = "";
while (ret == "")
{
if (Popup::YesNo (_("Failed to initialize the catalog. Try again?")))
{
ret = SourceDialogs::EditPopup (url);
}
else
{
// error in proposal, %1 is URL
init_error = sformat (_("No catalog found at '%1'."),
InstURL::HidePassword (url));
return "";
}
}
return ret;
}
list<string> LocaleVersions (string lang) {
list<string> ret = [ lang ];
list<string> components = splitstring (lang, ".");
if (components[0]:"" != lang && components[0]:"" != "")
{
lang = components[0]:"";
ret = add (ret, lang);
}
components = splitstring (lang, "_");
if (components[0]:"" != lang && components[0]:"" != "")
{
lang = components[0]:"";
ret = add (ret, lang);
}
return ret;
}
string ContentFileProductLabel () {
string language = Language::language;
list<string> locales = LocaleVersions (Language::language);
string ret = "";
foreach (string loc, locales, {
if (ret == "")
{
string val = (string)SCR::Read (add (.content, "LABEL." + loc));
if (val != "" && val != nil)
{
ret = val;
return ret;
}
}
});
return (string)SCR::Read (.content.LABEL);
}
void SlideShowSetUp (integer source) {
// setup slidedir
map productmap = Pkg::SourceProductData (source);
string datadir = productmap["datadir"]:"suse";
string slidedir_find = "/" + datadir + "/setup/slide";
string dir = Pkg::SourceProvideOptionalFile (source, 1,
slidedir_find + "/directory.yast");
string slidedir = nil;
if (dir != nil)
slidedir = Pkg::SourceProvideDir (source, 1, slidedir_find);
string our_slidedir = (string)WFM::Read (.local.tmpdir, "");
if (slidedir == nil)
{
y2milestone("No slide directory '%1' found on source '%2'.",
slidedir_find, source);
}
else
{
// copy all files to our own copy
WFM::Execute (.local.bash,
sformat ("cp -r %1/* %2/", slidedir, our_slidedir)) ;
}
y2milestone ("Setting up the slide directory local copy: %1",
our_slidedir);
SlideShow::SetSlideDir (our_slidedir);
}
integer IntegrateServicePack (boolean show_popup, string base_url) {
/* Check for Service Pack */
boolean servicepack_available = false;
if ((integer)WFM::Read(.local.size, servicepack_metadata) > 0)
{
y2milestone("Service Pack data available");
boolean popup_open = false;
if (show_popup)
{
UI::OpenDialog(`opt(`decorated ),
// popup - information label
`Label(_("Integrating booted media...")));
popup_open = true;
}
string spdir = metadir + "/Service-Pack/CD1";
WFM::Execute (.local.mkdir, spdir);
y2milestone ("Filling %1", spdir);
WFM::Execute(.local.bash, "tar -zxvf " +
servicepack_metadata + " -C " + spdir);
string sp_url = "dir:" + spdir;
integer sp_source = Pkg::SourceCreate (sp_url, "");
// close the popup in order to be able to ask about the license
if (popup_open)
{
popup_open = false;
UI::CloseDialog ();
}
if (sp_source == -1)
{
Report::Error (_("Failed to integrate service pack source."));
return nil;
}
if (! AddOnProduct::AcceptedLicenseAndInfoFile(sp_source))
{
y2milestone ("service pack license rejected");
Pkg::SourceDelete (sp_source);
return nil;
}
if ((integer)WFM::Read (.local.size, spdir + "/installation.xml") > 0)
{
AddOnProduct::WFIntegrate (spdir + "/installation.xml");
}
if ((integer)WFM::Read (.local.size, spdir + "/y2update.tgz") > 0)
{
AddOnProduct::UpdateInstSys (spdir + "/y2update.tgz");
}
theSources = add (theSources, sp_source);
y2internal ("Service pack source: %1, changing to URL: %2",
sp_source, base_url);
Pkg::SourceChangeUrl (sp_source, base_url);
}
}
/**
* Initialize the installation sources
* @param show_popup boolean true to display information about initialization
*/
global void Initialize(boolean show_popup) {
if (init_called || init_in_progress)
{
y2warning ("Packages::Initialize() already called");
return;
}
init_in_progress = true;
boolean popup_open = false;
if (show_popup)
{
UI::OpenDialog(`opt(`decorated ),
// popup - information label
`Label(_("Initializing catalogs...")));
popup_open = true;
}
PackageCallbacksInit::InitPackageCallbacks ();
// Initialize package manager
init_error = nil;
y2milestone ("Packages::Initialize()");
// usual mountpoint for the source medium
string base_url = "";
if (Mode::test ())
{
// Fake values for testing purposes
base_url = "dir:///dist/next-i386";
}
else
{
base_url = InstURL::installInf2Url ("");
}
// hide password from URL if present
string log_url = InstURL::HidePassword(base_url);
y2milestone ("Initialize Package Manager: %1", log_url);
// Set languages for packagemanager. Always set the UI language. Set
// language for additional packages only in Stage::initial ().
Pkg::SetLocale (Language::language);
boolean again = true;
theSources = Pkg::SourceStartCache (true); // dummy in 1st stage
while (again)
{
if (Stage::initial ())
{
integer initial_source = nil;
ImportGPGKeys ();
while (initial_source == nil)
{
initial_source = Pkg::SourceCreateBase (base_url, "");
if (initial_source == -1 || initial_source == nil)
{
y2error ("No source on '%1'", log_url);
base_url = UpdateSourceURL (base_url);
if (base_url != "")
{
initial_source = nil;
}
else
{
if (popup_open)
UI::CloseDialog ();
init_in_progress = false;
return;
}
}
if (! CheckContentFile (initial_source))
{
string label = ContentFileProductLabel ();
// bug #159754, release the mounted CD
Pkg::SourceReleaseAll();
Pkg::SourceDelete (initial_source);
initial_source = nil;
if (! Popup::ContinueCancel (
// message popup, %1 is product name
sformat (_("Insert %1 CD 1"), label)))
{
init_error = sformat (_("%1 CD 1 not found"), label);
if (popup_open)
UI::CloseDialog ();
init_in_progress = false;
return;
}
}
}
SlideShowSetUp (initial_source);
// Set the product before setting up add-on products
// In the autoyast mode it could be that the proposal
// screen will not be displayed. So the product will
// not be set. Bug 178831
SelectProduct ();
if (popup_open)
{
popup_open = false;
UI::CloseDialog ();
}
theSources = [ initial_source ];
integer sp_source = IntegrateServicePack (show_popup, base_url);
if (sp_source != nil)
theSources = add (theSources, sp_source);
if (ProductFeatures::GetFeature ("software", "selection_type") == `fixed)
{
Pkg::SetSelection (ProductFeatures::GetStringFeature ("software", "base_selection"));
}
string tmp_add_on_products = Pkg::SourceProvideOptionalFile (initial_source, 1, "/add_on_products");
if (tmp_add_on_products != nil)
{
add_on_products_list = ((string)SCR::Read (.target.tmpdir)) + "/add_on_products";
WFM::Execute (.local.bash, sformat ("cp %1 %2", tmp_add_on_products, add_on_products_list));
}
else
{
add_on_products_list = nil;
}
}
else // cont or normal mode
{
if (theSources == nil || size (theSources) <= 0)
{
y2error ("Pkg::SourceStartCache failed");
theSources = [];
}
else if ( Stage::cont () // rewrite URL if cd/dvd since ide-scsi might have changed it
&& ((substring (base_url, 0, 2) == "cd")
|| (substring (base_url, 0, 3) == "dvd")))
{
foreach (integer source, theSources, {
map data = Pkg::SourceGeneralData (source); // get source data
string url = data["url"]:"";
if ((substring (url, 0, 2) == "cd") // source comes from cd/dvd
|| (substring (url, 0, 3) == "dvd"))
{
string new_url = InstURL::RewriteCDUrl(url);
y2milestone ("rewrite url: '%1'->'%2'", url, InstURL::HidePassword(new_url));
Pkg::SourceChangeUrl (source, new_url);
}
});
}
}
y2milestone ("theSources %1", theSources);
y2milestone ("theSourceDirectories %1", theSourceDirectories);
if (size (theSources) >= 0)
{
init_called = true;
again = false;
}
else
{
import "PackageCallbacks";
// an error message
string errortext = sformat (_("Error while initializing package descriptions.
Check the log file %1 for more details."), Directory::logdir + "/y2log") +
"\n" + Pkg::LastError();
// FIXME somewhere get correct current_label and wanted_label
string result = PackageCallbacks::MediaChange (errortext, base_url, "",
0, "", 1, "", false);
}
}
if (popup_open)
UI::CloseDialog ();
init_in_progress = false;
}
global void Init(boolean unused) {
Initialize (true);
}
/**
* Select the base product on the media for installation
* @return boolean true on success
*/
global boolean SelectProduct () {
Packages::Initialize (true);
list<map<string,any> > products = Pkg::ResolvableProperties ("", `product, "");
products = filter (map<string,any> p, products, {
return p["category"]:"" == "base";
});
if (size (products) == 0)
{
y2milestone ("No base product found on media");
return true;
}
list<map<string,any> >selected_products = filter (map<string,any> p, products, {
return p["status"]:nil == `selected;
});
// no product selected -> select them all
boolean ret = true;
if (size (selected_products) == 0)
{
y2milestone ("No product selected so far...");
foreach (map<string,any> p, products, {
y2milestone ("Selecting product %1", p["name"]:"");
ret = Pkg::ResolvableInstall (p["name"]:"", `product) && ret;
});
}
return ret;
}
/**
* Select system patterns
* @param reselect boolean true to select only those which are alrady selected
*/
void SelectSystemPatterns (boolean reselect) {
list<string> system_patterns = ComputeSystemPatternList ();
// autoinstallation has patterns specified in the profile
if (! Mode::autoinst ())
{
system_patterns = (list<string>)
merge (system_patterns, DefaultDesktop::PatternsToSelect ());
system_patterns = (list<string>)
toset (merge (system_patterns, Product::patterns));
}
if (! reselect)
{
list<string> to_deselect = DefaultDesktop::PatternsToDeselect ();
y2milestone ("Deselecting system patterns %1", to_deselect);
foreach (string p, to_deselect, {
Pkg::ResolvableRemove (p, `pattern);
});
y2milestone ("Selecting system patterns %1", system_patterns);
foreach (string p, system_patterns, {
Pkg::ResolvableInstall (p, `pattern);
});
}
else
{
y2milestone ("Re-selecting system patterns %1", system_patterns);
list<string>pats = filter (string p, system_patterns, {
list<map<string,any> > descrs = Pkg::ResolvableProperties (p, `pattern, "");
descrs = filter (map<string,any> descr, descrs, {
return descr["status"]:nil == `selected;
});
return size (descrs) > 0;
});
y2milestone ("Selected patterns to be reselected: %1", pats);
foreach (string p, pats, {
Pkg::ResolvableRemove (p, `pattern);
Pkg::ResolvableInstall (p, `pattern);
});
}
}
/**
* Select system packages
* @param reselect boolean true to select only those which are alrady selected
*/
void SelectSystemPackages (boolean reselect) {
list<string> system_packages = ComputeSystemPackageList();
if (! reselect)
{
y2milestone ("Selecting system packages %1", system_packages);
}
else
{
y2milestone ("Re-selecting new versions of system packages %1", system_packages);
// first deselect the package (and filter selected ones)
system_packages = filter (string p, system_packages, {
if (Pkg::IsProvided (p) || Pkg::IsSelected (p))
{
Pkg::PkgDelete (p);
return true;
}
return false;
});
y2milestone ("System packages to be reselected: %1", system_packages);
}
map <string, any> res = Pkg::DoProvide (system_packages);
if (size (res) > 0)
{
foreach (string s, any a, res, {
y2warning ("Pkg::DoProvide failed for %1: %2", s, a);
});
}
}
/**
* Select appropriate XEN kernel if the XEN pattern is selected
*/
void SelectXenKernel () {
// check Xen pattern status
list<map> xen_patterns = Pkg::ResolvableProperties("xen_server", `pattern, "");
// is the Xen pattern selected?
boolean xen_selected = false;
foreach(map pattern, xen_patterns,
{
if (pattern["status"]:`unknown == `selected)
{
xen_selected = true;
}
});
if (xen_selected)
{
if (contains (Kernel::GetPackages (), "kernel-bigsmp"))
{
y2milestone("Selected Xen kernel: kernel-xenpae");
// install PAE Xen
Pkg::PkgNeutral("kernel-xen");
Pkg::PkgInstall("kernel-xenpae");
}
else
{
// install standard Xen
Pkg::PkgNeutral("kernel-xenpae");
Pkg::PkgInstall("kernel-xen");
}
}
}
/**
* Make a proposal for package selection
* @param force reset
* @param re-initialize
* @return map for the API proposal
*/
global map Proposal (boolean force_reset, boolean reinit, boolean simple) {
// if the cache is valid and reset or reinitialization is not required
// then the cached proposal can be used
if (cached_proposal != nil && force_reset == false && reinit == false)
{
// selected packages
list<string> selected_packages = Pkg::GetPackages(`selected, false);
// selected patterns
list<map> selected_patterns = filter(map p, Pkg::ResolvableProperties("", `pattern, ""), {return p["status"]:`unknown == `selected;});
// selected products
list<map> selected_products = filter(map p, Pkg::ResolvableProperties("", `product, ""), {return p["status"]:`unknown == `selected;});
// selected patches
list<map> selected_patches = filter(map p, Pkg::ResolvableProperties("", `patch, ""), {return p["status"]:`unknown == `selected;});
// selected selections
list<map> selected_selections = filter(map s, Pkg::ResolvableProperties("", `selection, ""), {return s["status"]:`unknown == `selected;});
// selected languages
list<string> selected_languages = (list<string>)union([Pkg::GetLocale()], Pkg::GetAdditionalLocales());
// if the package selection has not been changed the cache is up to date
if (selected_packages == cached_proposal_packages && selected_patterns == cached_proposal_patterns
&& selected_products == cached_proposal_products && selected_patches == cached_proposal_patches
&& selected_selections == cached_proposal_selections && selected_languages == cached_proposal_languages)
{
y2milestone("using cached software proposal");
return cached_proposal;
}
else
{
y2milestone("invalid cache: the software selection has been chaged");
}
}
else
{
y2milestone("the cached proposal is empty or reset is required");
}
UI::OpenDialog(`opt(`decorated ),
// popup label
`Label (_("Evaluating package selection...")));
y2milestone ("Packages::Proposal: force_reset %1, reinit %2, lang '%3'",
force_reset, reinit, Language::language);
if ( force_reset )
{
Kernel::ProbeKernel();
Packages::Reset ([`product]);
reinit = true;
}
boolean initial_run = reinit || ! init_called;
Initialize (true);
if (init_error != nil)
{
UI::CloseDialog();
return Summary ([], false);
}
if (initial_run)
{
// autoyast can configure AdditionalLocales
// we don't want to overwrite this
if( ! Mode::autoinst ())
{
Pkg::SetAdditionalLocales ([Language::language]);
}
}
SelectProduct ();
if (ProductFeatures::GetFeature ("software", "selection_type") == `auto)
{
y2milestone ("Doing pattern-based software selection");
SelectSystemPackages (system_packages_selected && ! initial_run);
SelectSystemPatterns (system_packages_selected && ! initial_run);
system_packages_selected = true;
Pkg::PkgFreshen();
}
else if (ProductFeatures::GetFeature ("software","selection_type") == `fixed)
{
y2milestone ("Selection type: fixed");
}
else
{
y2error ("unknown value %1 for ProductFeatures::GetFeature (software, selection_type)",
(symbol)ProductFeatures::GetFeature ("software", "selection_type"));
}
SelectXenKernel ();
if (! Pkg::PkgSolve (false))
{
solve_errors = Pkg::PkgSolveErrors ();
}
map ret = Summary (
[ `product, `pattern, `selection, `size, `desktop ],
false);
// TODO simple proposal
// cache the proposal
cached_proposal = ret;
// remember the status
cached_proposal_packages = Pkg::GetPackages(`selected, false);
cached_proposal_patterns = filter(map p, Pkg::ResolvableProperties("", `pattern, ""), {return p["status"]:`unknown == `selected;});
cached_proposal_products = filter(map p, Pkg::ResolvableProperties("", `product, ""), {return p["status"]:`unknown == `selected;});
cached_proposal_patches = filter(map p, Pkg::ResolvableProperties("", `patch, ""), {return p["status"]:`unknown == `selected;});
cached_proposal_selections = filter(map s, Pkg::ResolvableProperties("", `selection, ""), {return s["status"]:`unknown == `selected;});
cached_proposal_languages = (list<string>)union([Pkg::GetLocale()], Pkg::GetAdditionalLocales());
UI::CloseDialog();
y2milestone ("Software proposal: %1", ret);
return ret;
}
/**
* Initialize the catalogs with popup feedback
* Use Packages::Initialize (true) instead
*/
global void InitializeCatalogs() {
Packages::Initialize (true);
}
global boolean InitFailed () {
boolean ret = init_error != nil;
y2milestone ("Package manager initialization failed: %1", ret);
return ret;
}
/* EOF */
}