ACC SHELL
/**
* Package: online-update
* Summary: Call YOU during installation
* Authors: Arvin Schnell <arvin@suse.de>
*/
{
textdomain "online-update";
import "Directory";
import "FileUtils";
import "GetInstArgs";
import "Internet";
import "Label";
import "Mode";
import "OnlineUpdate";
import "OnlineUpdateCallbacks";
import "PackageCallbacksInit";
import "PackagesUI";
import "Popup";
import "ProductControl";
import "ProductFeatures";
import "Stage";
import "Wizard";
string saved_path = Directory::vardir + "/selected_patches.ycp";
string restarted_path = Directory::vardir + "/continue_you";
/* Called backwards */
if(GetInstArgs::going_back())
{
y2milestone ("going_back -> returning `auto");
return `auto;
}
boolean after_restart = false;
if (FileUtils::Exists (restarted_path))
{
y2milestone ("installation restarted from YOU");
SCR::Execute (.target.remove, restarted_path);
after_restart = true;
}
if (!Internet::do_you && !after_restart) // nothing to do
{
y2milestone ("Internet::do_you is false -> `auto");
return `auto;
}
// I have a feeling that we may need a lot of hacks here
// to make things work
boolean Hack (string what) {
boolean hack = (SCR::Read (.target.size, "/tmp/hack-" + what) != -1);
if (hack)
y2milestone ("HACK: %1", what);
return hack;
}
boolean already_up = false;
if (!Mode::test())
already_up = Internet::Status ();
boolean i_set_demand = false;
if (!already_up)
{
Wizard::SetContents (_("Initializing ..."), `Empty (), "", true, true);
if (!Internet::demand)
{
Internet::SetDemand (true);
i_set_demand = true;
}
Internet::Start ("");
integer i = 150;
while (i > 0)
{
if (!Internet::Status ())
break;
if (Internet::Connected ())
break;
// ping anything (www.suse.com) to trigger dod connections
SCR::Execute (.target.bash_background,
"/bin/ping -c 1 -w 1 195.135.220.3");
sleep (1000);
i = i - 1;
}
if (i < 1)
{
y2warning ("Internet::Status timed out, no connection available?");
}
}
symbol ret = `auto;
// initalize package callbacks
PackageCallbacksInit::InitPackageCallbacks();
if (after_restart || Hack ("init-target-and-sources"))
{
Pkg::TargetInit ("/", false);
}
else // reinitialize target after release notes were read (#232247)
{
Pkg::TargetFinish ();
Pkg::TargetInitialize ("/");
Pkg::TargetLoad ();
}
// source data are cleared in registration client, and
// inst_ask_online_update.ycp may not be called
Pkg::SourceStartManager (true);
integer selected = 0;
boolean check_licenses = false;
boolean reboot_needed = false;
boolean normal_patches_selected = false;
// check if YaST was restarted
if (FileUtils::Exists (saved_path))
{
string saved = (string) SCR::Read (.target.ycp, saved_path);
// saved value actually is not needed during installation
y2milestone ("previous action of YOU: %1", saved);
SCR::Execute (.target.remove, saved_path);
}
// save solver flags
map<string,any> solver_flags_backup = Pkg::GetSolverFlags ();
// ignore reccomends when we weant only pkg management patches
Pkg::SetSolverFlags ($[
"ignoreAlreadyRecommended" : true,
"onlyRequires" : true
]);
// first solver run, so preselecting works well
Pkg::PkgSolve (true);
// select the patches affecting pkg management
selected = Pkg::ResolvablePreselectPatches (`affects_pkg_manager);
y2milestone ("Preselected patches for pkg management: %1", selected);
// if no patch is selected, pre-select all security and recommended
if (selected < 1)
{
// restore the original solver settings - enable recommends
Pkg::SetSolverFlags (solver_flags_backup);
// new solver run required to include recommends
Pkg::PkgSolve (true);
selected = Pkg::ResolvablePreselectPatches (`all);
y2milestone ("All preselected patches: %1", selected);
}
// solver must be run after preselction (bnc#474601)
boolean solved = Pkg::PkgSolve (true);
// run package selector to allow user interaction
if (!solved ||
ProductFeatures::GetBooleanFeature("globals", "manual_online_update") ||
Hack ("ui"))
{
Pkg::TargetInitDU([]); // init DiskUsage counter (#197497)
symbol ret_sel = nil;
repeat
{
ret_sel = PackagesUI::RunPackageSelector ($[ "mode" : `youMode ]);
if (ret_sel == `cancel)
{
y2milestone ("package selector canceled -> `next");
Pkg::SetSolverFlags (solver_flags_backup);
return `next;
}
if (ret_sel == `accept)
{
boolean restart_yast = false;
normal_patches_selected = false;
foreach (map patch, Pkg::ResolvableProperties ("", `patch, ""),
{
if (patch["status"]:`none == `selected)
{
if (patch["affects_pkg_manager"]:false)
restart_yast = true;
else
normal_patches_selected = true;
}
});
if (restart_yast && normal_patches_selected &&
!Popup::ContinueCancel(OnlineUpdate::more_selected_message))
{
// user wants to re-examine the selection
ret = nil;
}
}
} until (ret_sel == `cancel || ret_sel == `accept);
}
else if (selected > 0)
{
check_licenses = true;
}
boolean more_patches_needed = false;
foreach (map patch, Pkg::ResolvableProperties("", `patch, ""), {
if (patch["status"]:`none == `selected)
{
y2milestone ("selected patch: %1", patch);
if (patch["affects_pkg_manager"]:false)
{
if (patch["reboot_needed"]:false)
ret = `reboot;
else if (ret != `reboot)
ret = `restart_same_step;
}
else if (patch["reboot_needed"]:false)
{
// patch requiring reboot should be installed in this run
ret = `reboot;
}
else
{
normal_patches_selected = true;
}
}
// patch not selected: touch saved_path to force the restart
else if (patch["is_needed"]:false)
{
y2milestone ("patch needed but not selected: %1", patch);
more_patches_needed = true;
}
});
// tell the caller (/sbin/yast2) to call online update again
if (ret != `auto && more_patches_needed)
{
string save_message = (ret == `reboot) ? "reboot" : "restart";
SCR::Write (.target.ycp, saved_path, "inst_" + save_message);
}
// no packagemanager/reboot patch selected ...
if (ret == `auto)
{
// ... and nothing to install -> skip the installation at all
if (!normal_patches_selected && !Pkg::PkgAnyToInstall () &&
!Pkg::PkgAnyToDelete ())
{
y2milestone ("no patch selected after all -> `next");
Pkg::SetSolverFlags (solver_flags_backup);
return `next;
}
}
// if the package selector was not opened, ask to confirm licenses
if (check_licenses)
{
boolean rejected = false;
foreach (string p, Pkg::GetPackages (`selected, true), {
string license = Pkg::PkgGetLicenseToConfirm (p);
if (license != nil && license != "")
{
string rt_license = sformat ("<p><b>%1</b></p>\n%2", p, license);
if (! Popup::AnyQuestionRichText (
// popup heading, with rich text widget and Yes/No buttons
_("Do you accept this license agreement?"),
rt_license,
70, 20,
Label::YesButton (), Label::NoButton (),
`focus_none))
{
y2milestone("License not accepted: %1", p);
Pkg::PkgTaboo (p);
rejected = true;
}
else
{
Pkg::PkgMarkLicenseConfirmed (p);
}
}
});
// we must run solver again and offer manual intervention if it fails
if (rejected && !Pkg::PkgSolve (true))
{
symbol ret_sel = PackagesUI::RunPackageSelector($["mode":`youMode]);
if (ret_sel == `cancel)
{
y2milestone ("package selector canceled -> `next");
Pkg::SetSolverFlags (solver_flags_backup);
return `next;
}
}
}
// install the patches
OnlineUpdateCallbacks::RegisterOnlineUpdateCallbacks();
WFM::call( "online_update_install" );
if (ret == `reboot)
{
// message popup
Popup::Message (_("Some application requiring restart has been updated. The system will
reboot now then continue the installation.
"));
if (more_patches_needed)
{
y2milestone ("there are more patches to install after reboot...");
// after reboot, run the online update again
ret = `reboot_same_step;
SCR::Write (.target.ycp, restarted_path, 1);
}
}
else if (ret == `restart_same_step)
{
Popup::Message (OnlineUpdate::restart_message);
if (more_patches_needed)
{
y2milestone ("restarting YaST, expecting another patches in the next YOU run");
SCR::Write (.target.ycp, restarted_path, 1);
}
else
{
y2milestone ("restarting YaST, but there are no patches for the next YOU run");
ret = `restart_yast;
}
}
if (!already_up)
{
Internet::Stop ("");
if (i_set_demand)
{
Internet::SetDemand (false);
}
}
y2milestone ("result of inst_you: %1", ret);
Pkg::SetSolverFlags (solver_flags_backup);
return ret;
}
ACC SHELL 2018