ACC SHELL
/**
* Module: inst_rpmcopy.ycp
*
* Authors: Klaus Kaempf <kkaempf@suse.de>
* Stefan Hundhammer <sh@suse.de> (slide show)
* Arvin Schnell <arvin@suse.de>
*
* Purpose:
* Install all the RPM packages the user has selected.
* Show installation dialogue. Show progress bars.
* Request medium change from user.
*
* Packages module :
* "installed"
*
* $Id: inst_rpmcopy.ycp 61082 2010-03-02 09:10:41Z ug $
*/
{
textdomain "packager";
import "Mode";
import "Stage";
import "Installation";
import "Language";
import "PackageInstallation";
import "Packages";
import "SlideShow";
import "PackageSlideShow";
import "SlideShowCallbacks";
import "Popup";
import "Report";
import "SourceManager";
import "Linuxrc";
import "FileUtils";
import "AutoinstData";
include "packager/storage_include.ycp";
/**
* Removes all already installed patches and selections.
* See bugzilla #210552 for more information.
*/
void RemoveObsoleteResolvables () {
y2milestone ("--------- removing obsolete selections ---------");
// this removes only information about selections and applied patches
// it doesn't remove any package
y2milestone ("Removing all information about selections and patches in %1", Installation::destdir);
Pkg::TargetStoreRemove (Installation::destdir, `selection);
// disabled by FATE #301990, bugzilla #238488
// Pkg::TargetStoreRemove (Installation::destdir, `patch);
y2milestone ("--------- removing obsolete selections ---------");
}
// ------------------------------------------------------------------------------------------------------
// begin of commit installation functions
// ------------------------------------------------------------------------------------------------------
list <map <string, any> > remaining = [];
list <string> srcremaining = [];
/**
* Fills-up 'remaining' and 'srcremaining' lists with information of
* objects that need to be installed.
*/
void InitRemainingPackages () {
y2milestone ("Looking for remaining packages");
string file_remaining_packages = Installation::destdir + "/var/lib/YaST2/remaining";
string file_remaining_srcs = Installation::destdir + "/var/lib/YaST2/srcremaining";
// Packages remaining for installation
if (FileUtils::Exists (file_remaining_packages)) {
remaining =
(list <map <string, any> >) SCR::Read (.target.ycp, [file_remaining_packages, []]);
if (remaining == nil)
remaining = [];
y2milestone ("File %1 contains %2 packages",
file_remaining_packages, size (remaining));
}
// repositories remaining for installation
if (FileUtils::Exists (file_remaining_srcs)) {
srcremaining =
(list<string>) SCR::Read (.target.ycp, [file_remaining_srcs, []]);
if (srcremaining == nil)
srcremaining = [];
y2milestone ("File %1 contains %2 packages",
file_remaining_srcs, size (srcremaining));
}
}
/**
* And returns whether some objects need to be installed as the result.
*
* @return boolean whether some packages need to be installed
*/
boolean SomePackagesAreRemainForInstallation () {
// Either 'remaining' or 'srcremaining' are not empty
integer size_remaining = (remaining == nil ? 0 : size (remaining));
integer size_srcremaining = (srcremaining == nil ? 0 : size (srcremaining));
y2milestone ("remaining: %1, srcremaining: %2", size_remaining, size_srcremaining);
return (size_remaining > 0 || size_srcremaining > 0);
}
/**
* Sets remaining packages to be installed
*/
void InstallRemainingAndBinarySource () {
// second stage of package installation, re-read list of remaining binary and source
// packages
string backupPath = (string) SCR::Read(.target.string, [Installation::destdir + "/var/lib/YaST2/backup_path", ""]);
if ( backupPath != nil && backupPath != "")
{
y2milestone("create package backups in %1",backupPath);
Pkg::CreateBackups (true);
Pkg::SetBackupPath (backupPath);
}
integer failed_packages = 0;
y2milestone ("%1 resolvables remaining", size (remaining));
foreach (map<string,any> res, remaining, ``{
string name = res["name"]:"";
symbol kind = res["kind"]:`package;
string arch = res["arch"]:"";
string vers = res["version"]:"";
if (! Pkg::ResolvableInstallArchVersion (name, kind, arch, vers))
failed_packages = failed_packages + 1;
});
y2milestone ("%1 source packages remaining", size (srcremaining));
foreach (string pkg, srcremaining, ``{
if (! Pkg::PkgSrcInstall (pkg))
failed_packages = failed_packages + 1;
});
if (failed_packages > 0)
{
// error report, %1 is number
Report::Error (sformat(_("Failed to select %1 packages for installation."), failed_packages));
}
}
void AutoinstPostPackages () {
// post packages from autoinstall
map <string, any> res = Pkg::DoProvide (AutoinstData::post_packages);
if (size (res) > 0)
{
foreach (string s, any a, res, ``{
y2warning ("Pkg::DoProvide failed for %1: %2", s, a);
});
}
list<string> failed = [];
list<string> patterns = AutoinstData::post_patterns;
/* set SoftLock to avoid the installation of recommended patterns (#159466) */
foreach( map<string,any> p, Pkg::ResolvableProperties ("", `pattern, ""), ``{
Pkg::ResolvableSetSoftLock( p["name"]:"", `pattern );
});
foreach(string p, toset(patterns),
``{
if (! Pkg::ResolvableInstall( p, `pattern ) )
{
failed = add(failed, p);
}
});
if (size(failed) > 0 )
{
y2error("Error while setting pattern: %1", mergestring(failed, ","));
Report::Warning(sformat(_("Could not set patterns: %1."), mergestring(failed, ",")));
}
//
// Solve dependencies
//
if( !Pkg::PkgSolve(false) ) {
Report::Error( _("The package resolver run failed. Please check your software section in the autoyast profile.") );
}
}
symbol InstallPackagesFromMedia (integer current_cd_no, integer maxnumbercds) {
symbol result = `next;
y2milestone("Installing packages from media %1 -> %2", current_cd_no, maxnumbercds);
// 1->1 for default fist stage installation
// 0->0 for default second stage (or other) installation
while (current_cd_no <= maxnumbercds) {
// nothing to install/delete
if (Pkg::IsAnyResolvable(`any, `to_remove) == false
&& Pkg::IsAnyResolvable(`any, `to_install) == false)
{
y2milestone ("No package left for installation");
break;
}
// returns [ int successful, list failed, list remaining ]
list commit_result = PackageInstallation::CommitPackages( current_cd_no, 0 );
if (commit_result == nil || size (commit_result) == 0)
{
y2error("Commit failed");
string failed = mergestring(commit_result[1]:[], "\n");
// error message - displayed in a scrollable text area
// %1 - an error message (details)
Report::LongError(sformat(_("Installation Failed
Details:
%1
Package installation will be aborted.
"),
Pkg::LastError())
);
return `abort;
}
integer count = commit_result[0]:0;
y2milestone ("%1 packages installed", count);
list failed = commit_result[1]:[];
if (size (failed) > 0)
{
y2milestone ("failed: %1", failed);
list previous_failed = (list) SCR::Read (.target.ycp, [Installation::destdir +
"/var/lib/YaST2/failed_packages", []]);
if (size (previous_failed) > 0)
failed = union (previous_failed, failed);
SCR::Write (.target.ycp, Installation::destdir + "/var/lib/YaST2/failed_packages", failed);
}
list remaining = commit_result[2]:[];
if (size (remaining) >= 0)
{
y2milestone ("remaining: %1", remaining);
SCR::Write (.target.ycp, Installation::destdir + "/var/lib/YaST2/remaining", remaining);
}
else
{
SCR::Execute (.target.remove, Installation::destdir + "/var/lib/YaST2/remaining");
}
list srcremaining = commit_result[3]:[];
if (size (srcremaining) >= 0)
{
y2milestone ("repository remaining: %1", srcremaining);
SCR::Write (.target.ycp, Installation::destdir + "/var/lib/YaST2/srcremaining", srcremaining);
}
else
{
SCR::Execute (.target.remove, Installation::destdir + "/var/lib/YaST2/srcremaining");
}
if (count < 0) // aborted by user
{
result = `abort;
break;
}
// break on first round with Mediums
if (Stage::initial () && !Mode::test ())
break;
current_cd_no = current_cd_no + 1;
}
return result;
}
map <string, integer> CountStartingAndMaxMediaNumber () {
// Bugzilla #170079
// Default - unrestricted
map <string, integer> ret = $["maxnumbercds" : 0, "current_cd_no" : 0];
// has the inst-sys been successfuly unmounted?
string umount_result = Linuxrc::InstallInf ("umount_result");
string media = Linuxrc::InstallInf ("InstMode");
y2milestone("umount result: %1, inst repository type: %2", umount_result, media);
if (Packages::metadir_used) {
// all is in ramdisk, we can install all repositories now, works in every stage
ret["current_cd_no"] = 0;
ret["maxnumbercds"] = 0;
y2milestone("StartingAndMaxMediaNumber: MetaDir used %1/%2", ret["current_cd_no"]:nil, ret["maxnumbercds"]:nil);
} else if (Stage::initial ()) {
// is CD or DVD medium mounted? (inst-sys)
if (umount_result != "0" && (media == "cd" || media == "dvd"))
{
y2milestone("The installation CD/DVD cannot be changed.");
// only the first CD will be installed
ret["current_cd_no"] = 1;
ret["maxnumbercds"] = 1;
}
// otherwise use the default setting - install all media
y2milestone("StartingAndMaxMediaNumber: Stage initial %1/%2", ret["current_cd_no"]:nil, ret["maxnumbercds"]:nil);
// Three following cases have the same solution, CDstart = 0, CDfinish = 0
// ZYPP should solve what it needs and when.
// Leaving it here as the backward compatibility if someone decides to change it back.
} else if (Mode::autoinst () && Stage::cont () && size( AutoinstData::post_packages ) > 0) {
// one more compatibility feature to old YaST, post-packages
// Simply install a list of package after initial installation (only
// makes sense with nfs installatons)
ret["current_cd_no"] = 0; // was 1
ret["maxnumbercds"] = 0; // was 10
y2milestone("StartingAndMaxMediaNumber: Autoinst in cont %1/%2", ret["current_cd_no"]:nil, ret["maxnumbercds"]:nil);
} else if (Stage::cont ()) {
// continue with second CD but only in continue mode
// bug #170079, let zypp solve needed CDs
ret["current_cd_no"] = 0;
ret["maxnumbercds"] = 0;
y2milestone("StartingAndMaxMediaNumber: Stage cont %1/%2", ret["current_cd_no"]:nil, ret["maxnumbercds"]:nil);
} else if (Installation::dirinstall_installing_into_dir) {
// All in one
ret["current_cd_no"] = 0; // was 1
ret["maxnumbercds"] = 0; // was 10
y2milestone("StartingAndMaxMediaNumber: Dir install %1/%2", ret["current_cd_no"]:nil, ret["maxnumbercds"]:nil);
}
return ret;
}
// ------------------------------------------------------------------------------------------------------
// end of commit installation functions
// ------------------------------------------------------------------------------------------------------
if (Installation::image_only)
return `auto;
// bugzilla #208222
ReleaseHDDUsedAsInstallationSource();
// bugzilla #326327
Packages::SlideShowSetUp (Language::language);
Pkg::SetTextLocale (Language::language);
SlideShow::SetLanguage (Language::language);
// Initialize and check whether some packages need to be installed
// stop proceeding the script if they don't (Second stage)
if (Stage::cont() && ! Mode::live_installation () && !Mode::autoinst() ) {
InitRemainingPackages();
if (SomePackagesAreRemainForInstallation() != true) {
y2milestone ("No packages need to be installed, skipping...");
return `auto;
} else {
y2milestone ("Some packages need to be installed...");
}
}
// start target, create new rpmdb if none is existing
// FIXME error checking is missing all around here, initialization could actually fail!
if (Pkg::TargetInitialize (Installation::destdir) != true) {
// continue-cancel popup
if(Popup::ContinueCancel(_("Initializing the target directory failed")) == false) {
return `abort;
}
}
if (Mode::update()) {
// Removes all already installed patches and selections.
// See bugzilla #210552 for more information.
RemoveObsoleteResolvables();
}
if (Stage::cont() && ! Mode::live_installation ()) {
// initialize the package agent in continue mode
Packages::Init( true );
// in 1st stage, this is opened already
SlideShow::OpenDialog ();
}
if (Mode::autoinst () && Stage::cont ()) {
AutoinstPostPackages();
}
// initial mode, move download area, check for repository caching
if (Stage::initial ()) {
SourceManager::InstInitSourceMoveDownloadArea();
// continue mode, set remaining packages to be installed
} else if (! Mode::live_installation ()){
InstallRemainingAndBinarySource();
}
// Install the software from Medium1 to Mediummax, but not the already
// installed base packages.
// This part is also used for installation in running system (Stage::cont ())
map <string, integer> cdnumbers = CountStartingAndMaxMediaNumber();
integer maxnumbercds = cdnumbers["maxnumbercds"]:10;
integer current_cd_no = cdnumbers["current_cd_no"]:1;
map <string, map <string,any> > get_setup = SlideShow::GetSetup();
if (get_setup == nil || get_setup == $[]) {
y2milestone ("No SlideShow setup has been set, adjusting");
SlideShow::Setup([$[
"name" : "packages",
"description" : _("Installing Packages..."),
"value" : PackageSlideShow::total_size_to_install / 1024 , // kilobytes
"units" : `kb,
]]);
}
get_setup = nil;
// re-initialize package information
PackageSlideShow::InitPkgData(true);
// we want the table
SlideShow::ShowTable();
// Do not open a new SlideShow widget, reuse the old one instead
boolean required_to_open_sl_dialog = (! SlideShow::HaveSlideWidget());
// BNC #443755
if (required_to_open_sl_dialog) {
y2milestone ("SlideShow dialog not yet created");
SlideShow::OpenDialog();
}
// move the progress to the packages stage
SlideShow::MoveToStage("packages");
// install packages from CD current_cd_no to CD maxnumbercds
symbol result = InstallPackagesFromMedia (current_cd_no, maxnumbercds);
// sync package manager FIXME
if (result != `abort && ! Stage::initial ())
{
y2milestone ("Calling PkgCommit (%1)", 9999);
Pkg::PkgCommit (9999);
}
// BNC #443755
if (required_to_open_sl_dialog) {
y2milestone ("Closing previously opened SlideShow dialog");
SlideShow::CloseDialog();
}
if (result != `abort)
{
if (Stage::cont ())
{
// some new SCR asgents might have been installed
SCR::RegisterNewAgents();
}
}
return result;
}
ACC SHELL 2018