ACC SHELL
Path : /usr/share/YaST2/clients/ |
|
Current File : //usr/share/YaST2/clients/inst_automatic_configuration.ycp |
/**
* File: clients/inst_automatic_configuration.ycp
* Package: installation
* Summary: Automatic configuration instead of the second stage
* Authors: Lukas Ocilka <locilka@suse.cz>
*
* $Id: inst_automatic_configuration.ycp 58525 2009-09-04 12:20:57Z kmachalkova $
*
* @see http://visnov.blogspot.com/2008/02/getting-rid-of-2nd-stage-of.html
*/
{
import "Mode";
import "Stage";
import "FileUtils";
import "Directory";
import "GetInstArgs";
import "Wizard";
import "Progress";
// reads the control file
// and sets sections of ProductFeatures
import "ProductControl";
import "ProductFeatures";
import "InstError";
textdomain "installation";
if (GetInstArgs::going_back()) {
// bnc #395098
// There is no reason to go back as AC is non-interactive
// and additionally there is nothing before AC to run
y2milestone ("Returning `next, no reason to go back");
return `next;
}
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();
y2milestone ("automatic_configuration started");
// list <map <string, any> > proposal_scripts_to_call = [
// $[
// "label":_("Finishing configuration..."),
// "type":"scripts",
// "items":["addon_update_sources", "inst_extrasources", "suseconfig", "save_hardware_status"]
// ],
// ];
list <map <string, any> > proposal_scripts_to_call = [];
map <string, any> globals_features = ProductFeatures::GetSection ("globals");
list <map> acc = (list <map>) globals_features["automatic_configuration"]:[];
list <string> acc_ignore = (list <string>) globals_features["ac_redraw_and_ignore"]:[];
if (acc == nil || acc == []) {
y2warning ("No AC defined (%1), skipping...", acc);
return `next;
}
map< string, list <string> > disabled_ac_items = ProductControl::GetDisabledACItems();
foreach (map one_step, acc, {
map new_step = $[
"unique" : one_step["unique_id"]:"",
"label" : one_step["text_id"]:"",
"icon" : one_step["icon"]:"yast",
"type" : one_step["type"]:"scripts",
"items" : maplist (string one_ic_item, (list <string>) one_step["ac_items"]:[], {
return one_ic_item;
}),
];
// filter out the wrong ones
new_step["items"] = filter (string one_item, new_step["items"]:[], {
if (one_item == nil || one_item == "") {
y2error ("Wrong item '%1' came from %2", one_item, one_step);
return false;
}
if ( haskey( disabled_ac_items, new_step["unique"]:"") &&
contains(disabled_ac_items[ new_step["unique"]:"" ]:[], one_item ) ) {
y2milestone("Item %1 found among disabled items", one_item);
return false;
}
return true;
});
new_step["label"] = ProductControl::GetTranslatedText (new_step["label"]:"");
if (new_step["label"]:"" == "" || new_step["label"]:nil == nil) {
y2error ("Unknown label text ID '%1', using fallback", new_step["label"]:"");
new_step["label"] = _("Creating automatic configuration...");
}
proposal_scripts_to_call = add (proposal_scripts_to_call, (map <string, any>) new_step);
});
/**
* Prepares the list of installation scripts to be executed.
* This comes from control file where scripts are mentioned without the leading
* "inst_" but they are actually named that way ("inst_something").
*
* @example ["aa", "inst_bb"] -> ["inst_aa", "inst_bb"]
*/
list <string> NormalizeScriptNames (list <string> names) {
list <string> ret_names = [];
foreach (string one_name, names, {
if (regexpmatch (one_name, "^inst_")) {
ret_names = add (ret_names, one_name);
} else {
ret_names = add (ret_names, "inst_" + one_name);
}
});
return ret_names;
}
/**
* Similar to NormalizeScriptNames but it add "_proposal" instead if "inst_".
*
* @example ["aa", "bb_proposal"] -> ["aa_proposal", "bb_proposal"]
*/
list <string> NormalizeProposalNames (list <string> names) {
list <string> ret_names = [];
foreach (string one_name, names, {
if (regexpmatch (one_name, "_proposal$")) {
ret_names = add (ret_names, one_name);
} else {
ret_names = add (ret_names, one_name + "_proposal");
}
});
return ret_names;
}
void HandleExceptions (string proposal_name) {
if (proposal_name == "x11_proposal" || proposal_name == "x11") {
if (! UI::TextMode()) {
y2milestone ("Printing >don't panic<!");
SCR::Write (.dev.tty.stderr,
// TRANSLATORS: this message is displayed on console when X11 configuration
// switches from running X to console. Sometimes it looks like
// the installation has failed.
_("
******************************************************
Do not panic!
X11 Configuration must switch to console for a while
to detect your videocard properly...
******************************************************
")
);
}
}
}
integer nr_of_steps = 0;
void SetWizardContents () {
Wizard::SetContents (
_("Automatic Configuration"),
`VBox (
// faster progress
`ReplacePoint(
`id ("rp_one_set_progress"),
`ProgressBar (
`id ("one_set_progress"),
_("Preparing configuration..."),
100,
0
)
),
// overall-autoconf progress
`ProgressBar (
`id ("autoconf_progress"),
_("Creating automatic configuration..."),
nr_of_steps,
0
)
),
_("<p>Installation is currently writing the automatic configuration. Please wait...</p>"),
false, false
);
}
integer current_sub_step = 0;
integer current_step = 0;
string current_client = "";
boolean ac_redraw_and_ignore = nil;
void DumpACUIError () {
y2error ("AC progress widgets missing");
y2warning ("---------------------- UI DUMP ----------------------");
UI::DumpWidgetTree();
y2warning ("---------------------- UI DUMP ----------------------");
}
string last_client = nil;
void NextStep () {
// If a Progress is missing, it's recreated and an error is reported
if (last_client == nil) last_client = current_client;
ac_redraw_and_ignore = (last_client == nil ? false : contains (acc_ignore, last_client));
current_sub_step = current_sub_step + 1;
current_step = current_step + 1;
// BNC #483211: It might happen that some client close the dialog
if (! UI::WidgetExists (`id (`next)) && ! UI::WidgetExists (`id (`back)) && ! UI::WidgetExists (`id (`abort))) {
y2error ("There is no Wizard dialog open! Creating one...");
Wizard::OpenNextBackStepsDialog();
DumpACUIError();
InstError::ShowErrorPopupWithLogs (
sformat (_("An error has occured while calling '%1' AC script."), last_client)
);
}
// BNC #483211: It might happen that some client changes the dialog
if (! UI::WidgetExists (`id ("one_set_progress")) || ! UI::WidgetExists (`id ("autoconf_progress"))) {
if (ac_redraw_and_ignore == true) {
y2warning ("There is no Automatic Configuration dialog, adjusting the current one... (ignored)");
} else {
DumpACUIError();
y2error ("There is no Automatic Configuration dialog, adjusting the current one...");
InstError::ShowErrorPopupWithLogs (
sformat (_("An error has occured while calling '%1' AC script."), last_client)
);
}
// Redraw after showing an error
SetWizardContents();
}
if (UI::WidgetExists (`id ("one_set_progress")))
UI::ChangeWidget (`id ("one_set_progress"), `Value, current_sub_step);
else
y2error ("Widget one_set_progress doesn't exist");
if (UI::WidgetExists (`id ("autoconf_progress")))
UI::ChangeWidget (`id ("autoconf_progress"), `Value, current_step);
else
y2error ("Widget autoconf_progress doesn't exist");
}
void DummyFunction () {
sleep (random (1600));
}
void CallScripts (list <string> scripts_to_call) {
y2milestone ("Scripts to call: %1", scripts_to_call);
scripts_to_call = NormalizeScriptNames (scripts_to_call);
foreach (string one_script, scripts_to_call, {
y2milestone ("Calling script %1", one_script);
current_client = one_script;
NextStep();
boolean progress_before = Progress::set (false);
any result = (
test_mode ?
DummyFunction()
:
WFM::CallFunction (one_script, [ $["AutomaticConfiguration":true] ])
);
Progress::set (progress_before);
y2milestone ("Script %1 returned %2", one_script, result);
last_client = one_script;
});
}
void CallProposals (list <string> proposals_to_call) {
y2milestone ("Scripts to call: %1", proposals_to_call);
proposals_to_call = NormalizeProposalNames (proposals_to_call);
foreach (string one_proposal, proposals_to_call, {
y2milestone ("Calling script %1 MakeProposal", one_proposal);
current_client = one_proposal;
NextStep();
boolean progress_before = Progress::set (false);
HandleExceptions (one_proposal);
any result = (
test_mode ?
DummyFunction()
:
WFM::CallFunction (one_proposal, ["MakeProposal", $[ "AutomaticConfiguration":true ]])
);
Progress::set (progress_before);
y2milestone ("Script %1 returned %2", one_proposal, result);
last_client = one_proposal;
});
foreach (string one_proposal, proposals_to_call, {
y2milestone ("Calling script %1 Write", one_proposal);
current_client = one_proposal;
NextStep();
boolean progress_before = Progress::set (false);
any result = (
test_mode ?
DummyFunction()
:
WFM::CallFunction (one_proposal, ["Write", $[ "AutomaticConfiguration":true ]])
);
y2milestone ("Script %1 returned %2", one_proposal, result);
last_client = one_proposal;
});
}
foreach (map one_autoconf_call, proposal_scripts_to_call, {
nr_of_steps = nr_of_steps +
// Proposals have two steps, scripts only one
((one_autoconf_call["type"]:"" == "proposals" ? 2:1) * size (one_autoconf_call["items"]:[]));
});
SetWizardContents();
// items per step
integer nr_of_items = 0;
foreach (map one_autoconf_call, proposal_scripts_to_call, {
if (one_autoconf_call["icon"]:"" != "") {
Wizard::SetTitleIcon (one_autoconf_call["icon"]:"");
} else {
// generic YaST icon fallback
Wizard::SetTitleIcon ("yast");
}
string type = one_autoconf_call["type"]:"";
nr_of_items = ((one_autoconf_call["type"]:"" == "proposals" ? 2:1) * size (one_autoconf_call["items"]:[]));
string label = one_autoconf_call["label"]:_("Automatic configuration...");
y2milestone ("Steps: %1, Label: %2", nr_of_steps, label);
switch (type) {
case "scripts":
CallScripts (one_autoconf_call["items"]:[]);
break;
case "proposals":
CallProposals (one_autoconf_call["items"]:[]);
break;
y2error ("Unknown script type '%1'", type);
}
});
y2milestone ("automatic_configuration finished");
// Set to 100%
UI::ChangeWidget (`id ("one_set_progress"), `Value, nr_of_items);
UI::ChangeWidget (`id ("autoconf_progress"), `Value, nr_of_steps);
if (test_mode) Wizard::CloseDialog();
return `auto;
}
ACC SHELL 2018