ACC SHELL

Path : /proc/self/root/usr/share/YaST2/clients/
File Upload :
Current File : //proc/self/root/usr/share/YaST2/clients/inst_you.ycp

/**
 * 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