ACC SHELL
/**
* File: clients/inst_finish.ycp
* Package: installation
* Summary: Finish installation
* Authors: Klaus Kämpf <kkaempf@suse.de>
* Arvin Schnell <arvin@suse.de>
* Jiri Srain <jsrain@suse.de>
*
* $Id: inst_finish.ycp 58749 2009-09-24 13:49:49Z kmachalkova $
*/
{
textdomain "installation";
import "AddOnProduct";
import "WorkflowManager";
import "Installation";
import "Linuxrc";
import "Misc";
import "Mode";
import "Stage";
import "Popup";
import "ProductControl";
import "Progress";
import "Report";
import "Wizard";
import "String";
import "GetInstArgs";
import "ProductFeatures";
import "SlideShow";
import "InstError";
import "PackageCallbacks";
// added for fate# 303395
import "Directory";
if (GetInstArgs::going_back())
return `auto;
// --> Functions
void ReportClientError (string client_error_text) {
// get the latest errors
map cmd = (map) WFM::Execute (.local.bash_output, "tail -n 200 /var/log/YaST2/y2log | grep ' <\\(3\\|5\\)> '");
InstError::ShowErrorPopUp (
_("Installation Error"),
client_error_text,
(cmd["exit"]:-1 == 0 && cmd["stdout"]:"" != "" ? cmd["stdout"]:"" : nil)
);
}
// <-- Functions
boolean test_mode = false;
if (size (WFM::Args()) > 0 && is (WFM::Args(0), string)) {
y2milestone ("Args: %1", WFM::Args());
if (WFM::Args(0) == "test")
test_mode = true;
}
if (test_mode) Wizard::CreateDialog();
Wizard::DisableBackButton ();
Wizard::DisableNextButton ();
// Adjust a SlideShow dialog if not configured
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" : "finish",
"description" : _("Finishing Basic Installation"),
// fixed value
"value" : 100,
"units" : `sec,
]]);
}
get_setup = nil;
Wizard::SetTitleIcon ("yast-sysconfig");
// Do not open a new SlideShow widget, reuse the old one instead
// variable used later to close that dialog (if needed)
boolean required_to_open_sl_dialog = (! SlideShow::HaveSlideWidget());
if (required_to_open_sl_dialog) {
y2milestone ("SlideShow dialog not yet created");
SlideShow::OpenDialog();
}
// Might be left from the previous stage
SlideShow::HideTable();
SlideShow::MoveToStage("finish");
string log = _("Creating list of finish scripts to call...");
SlideShow::SubProgress (0, "");
SlideShow::StageProgress (0, log);
SlideShow::AppendMessageToInstLog (log);
// Used later in 'stages' definition
// Using empty callbacks that don't break the UI
PackageCallbacks::RegisterEmptyProgressCallbacks();
Pkg::TargetInitialize (Installation::destdir);
Pkg::TargetLoad();
PackageCallbacks::RestorePreviousProgressCallbacks();
list<map<string,any> > stages = [
$[
"id" : "copy_files",
// progress stage
"label" : _("Copy files to installed system"),
"steps" : [
"autoinst_scripts1",
"mouse",
"copy_files",
"copy_systemfiles",
// For live installer only
(Mode::live_installation() ? "live_copy_files":""),
"switch_scr",
],
"icon" : "pattern-basis",
],
$[
"id" : "save_config",
// progress stage
"label" : _("Save configuration"),
"steps" : [
"ldconfig",
"save_config",
// For live installer only
(Mode::live_installation() ? "live_save_config":""),
"runlevel",
"desktop",
"fonts",
"storage",
"iscsi-client",
"kernel",
"x11",
"proxy",
"pkg",
"driver_update1",
// bnc #340733
"system_settings",
],
"icon" : "yast-desktop-select",
],
$[
"id" : "install_bootloader",
// progress stage
"label" : _("Install boot manager"),
"steps" : [
"bootloader",
((ProductFeatures::GetBooleanFeature ("globals", "enable_kdump") == true) ? "kdump" : "")
],
"icon" : "yast-bootloader",
],
$[
"id" : "save_settings",
// progress stage
"label" : _("Save installation settings"),
"steps" : [
"yast_inf",
"network",
"firewall_stage1",
"ntp-client",
"ssh_settings",
"ssh_service",
"save_hw_status",
"users",
"autoinst_scripts2",
"installation_settings",
],
"icon" : "yast-network",
],
$[
"id" : "prepare_for_reboot",
// progress stage
"label" : _("Prepare system for initial boot"),
"steps" : [
// For live installer only
(Mode::live_installation() ? "live_runme_at_boot":""),
// vm_finish called only if yast2-vm is installed
// Can't use PackageSystem::Installed as the current SCR is attached to inst-sys
// instead of the installed system
(Pkg::PkgInstalled ("yast2-vm") ? "vm":""),
"driver_update2",
// no second stage if possible
"pre_umount",
// copy logs just before 'umount'
// keeps maximum logs available after reboot
"copy_logs",
"umount",
],
// bnc #438154
"icon" : (Mode::live_installation() ? "yast-live-install-finish":"yast-scripts"),
],
];
if (size (ProductControl::inst_finish) > 0)
{
y2milestone ("Using inst_finish steps definition from control file");
stages = ProductControl::inst_finish;
// Inst-finish need to be translated (#343783)
string textdom = ProductControl::productControl["textdomain"]:"control";
list <map<string,any> > stages_copy = stages;
y2milestone ("Inst finish stages before: %1", stages);
integer counter = -1;
// going through copy, the original is going to be changed in the loop
foreach (map<string,any> one_stage, stages_copy, {
counter = counter + 1;
string label = one_stage["label"]:"";
if (label == nil || label == "") return;
string loc_label = dgettext (textdom, label);
// if translated
if (loc_label != nil && loc_label != "" && loc_label != label) {
stages[counter, "label"] = loc_label;
}
});
y2milestone ("Inst finish stages after: %1", stages);
}
else
{
y2milestone ("inst_finish steps definition not found in control file");
}
// merge steps from add-on products
// bnc #438678
stages[0, "steps"] = merge (
WorkflowManager::GetAdditionalFinishSteps("before_chroot"),
stages[0, "steps"]:[]
);
stages[1, "steps"] = merge (
WorkflowManager::GetAdditionalFinishSteps("after_chroot"),
stages[1, "steps"]:[]
);
stages[3, "steps"] = merge (
stages[3, "steps"]:[],
WorkflowManager::GetAdditionalFinishSteps("before_umount")
);
symbol run_type = `installation;
if (Mode::update ())
run_type = `update;
else if (Mode::autoinst ())
run_type = `autoinst;
else if (Mode::live_installation ())
run_type = `live_installation;
integer steps_count = 0;
integer stages_to_check = size (stages);
integer currently_checking = 0;
stages = maplist (map<string,any> stage, stages, {
currently_checking = currently_checking + 1;
SlideShow::SubProgress (100 * currently_checking / stages_to_check,
sformat (_("Checking stage: %1..."), stage["label"]:stage["id"]:""));
list<map> steps = maplist (string s, stage["steps"]:[], {
// some steps are called in live installer only
if (s == "" || s == nil) {
return nil;
}
s = s + "_finish";
if (! WFM::ClientExists (s)) {
y2error ("Missing YCP client: %1", s);
return nil;
}
y2milestone ("Calling inst_finish script: %1 (Info)", s);
boolean orig = Progress::set (false);
map info = (map) WFM::CallFunction (s, ["Info"]);
if (test_mode == true) {
if (info == nil) info = $[];
y2milestone ("Test mode, forcing run");
info["when"] = [`installation, `update, `autoinst];
}
Progress::set (orig);
if (info == nil) {
y2error ("Client %1 returned invalid data", s);
ReportClientError (sformat ("Client %1 returned invalid data.", s));
return nil;
}
if (info["when"]:nil != nil && ! contains (info["when"]:[], run_type))
return nil;
y2milestone ("inst_finish client %1 will be called", s);
info["client"] = s;
steps_count = steps_count + info["steps"]:1;
return info;
});
stage["steps"] = filter (map s, steps, {
return s != nil;
});
return stage;
});
y2milestone ("These inst_finish stages will be called:");
foreach (map<string,any> stage, stages, {
y2milestone ("Stage: %1", stage);
});
stages = filter (map<string,any> s, stages, {
return size (s["steps"]:[]) > 0;
});
list<string> stage_names = maplist (map<string,any> s, stages, {
return s["label"]:"";
});
boolean aborted = false;
integer stages_nr = size (stages);
integer current_stage = -1;
integer current_stage_percent = 0;
string fallback_msg = nil;
foreach (map<string,any> stage, stages, {
if (stage["icon"]:"" != "")
Wizard::SetTitleIcon (stage["icon"]:"");
current_stage = current_stage + 1;
current_stage_percent = (100 * current_stage / stages_nr);
SlideShow::StageProgress (current_stage_percent, stage["label"]:"");
SlideShow::AppendMessageToInstLog (stage["label"]:"");
integer steps_nr = size (stage["steps"]:[]);
integer current_step = -1;
foreach (map step, stage["steps"]:[], {
current_step = current_step + 1;
// a fallback busy message
fallback_msg = sformat (_("Calling step %1..."), step["client"]:"");
SlideShow::SubProgress (100 * current_step / steps_nr, step["title"]:fallback_msg);
SlideShow::StageProgress (current_stage_percent + (100 / stages_nr * current_step / steps_nr), nil);
// use as ' * %1' -> ' * One of the finish steps...' in the SlideShow log
SlideShow::AppendMessageToInstLog (sformat (_(" * %1"), step["title"]:fallback_msg));
boolean orig = Progress::set (false);
if (test_mode == true) {
y2milestone ("Test-mode, skipping WFM::CallFunction (%1, ['Write'])", step["client"]:"");
sleep (500);
} else {
WFM::CallFunction (step["client"]:"", ["Write"]);
}
Progress::set (orig);
// Handle user input during client run
any user_ret = UI::PollInput ();
// Aborting...?
if (user_ret == `abort) {
if (Popup::ConfirmAbort (`incomplete)) {
aborted = true;
break;
}
// Anything else
} else {
SlideShow::HandleInput (user_ret);
}
});
if (aborted)
break;
SlideShow::SubProgress (100, nil);
});
SlideShow::StageProgress (100, nil);
SlideShow::AppendMessageToInstLog (_("Finished"));
if (aborted)
{
y2milestone ("inst_finish aborted");
return `abort;
}
if (required_to_open_sl_dialog) {
y2milestone ("Closing previously opened SlideShow dialog");
SlideShow::CloseDialog();
}
// --------------------------------------------------------------
// Check if there is a message left to display
// and display it, if necessary
// Do not call any SCR, it's already closed!
if (size (Misc::boot_msg) > 0 && !Mode::autoinst ())
{
// bugzilla #245742, #160301
if ((Linuxrc::usessh () && !Linuxrc::vnc())
// also live installation - bzilla #297691
|| Mode::live_installation ())
{
// Display the message and wait for user to accept it
Report::DisplayMessages (true, 0);
}
else
Report::DisplayMessages (true, 10);
Report::Message (Misc::boot_msg);
Misc::boot_msg = "";
}
if (test_mode) {
Wizard::CloseDialog();
return `auto;
}
// fate #303395: Use kexec to avoid booting between first and second stage
// run new kernel via kexec instead of reboot
// command for reading kernel_params
string cmd = sformat("ls '%1/kexec_done' |tr -d '\n'", String::Quote (Directory::vardir));
y2milestone("Checking flag of successful loading kernel via command %1", cmd);
map out = (map)WFM::Execute(.local.bash_output, cmd);
cmd = sformat("%1/kexec_done",Directory::vardir);
// check output
if (out["stdout"]:"" != cmd)
{
y2milestone ("File kexec_done was not found, output: %1", out);
return `next;
}
// hack for using kexec switch to console 1
cmd = sformat ("chvt 1");
y2milestone("Switch to console 1 via command: %1", cmd);
// switch to console 1
out = (map)WFM::Execute(.local.bash_output, cmd);
// check output
if (out["exit"]:nil != 0)
{
y2error ("Switching failed, output: %1", out);
return `next;
}
// waiting s for switching...
sleep(1000);
return `next;
} // EOF
ACC SHELL 2018