From ab8b23a5ca2781185ec8f97ffcda1e9ff061e5b6 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Mon, 24 Jan 2005 15:32:54 +0000 Subject: [PATCH] - Moved installation workflow routines out of installation.ycp - Adapted arguments of installation clients - Enhanced control file and made it more readable (arguments of clients are clearer now) svn path=/trunk/installation/; revision=20855 --- POTFILES | 5 +- configure.in.in | 7 +- control/Makefile.am | 1 - control/control.PROF.xml | 111 +++--- control/control.xml | 120 ++++--- doc/README.installer | 3 + general/inst_congratulate.ycp | 3 +- general/inst_doit.ycp | 19 +- general/inst_fam.ycp | 6 +- general/inst_release_notes.ycp | 5 +- general/inst_suseconfig.ycp | 15 +- general/installation.ycp | 248 ++------------ modules/GetArgs.ycp | 49 +++ modules/Hooks.ycp | 4 +- modules/Makefile.am | 1 + modules/ProductControl.ycp | 531 +++++++++++++++++++++-------- package/yast2-installation.changes | 8 + proposal/inst_proposal.ycp | 81 +++-- proposal/test_proposal.ycp | 15 +- x11/inst_x11.ycp | 10 +- 20 files changed, 682 insertions(+), 560 deletions(-) create mode 100644 modules/GetArgs.ycp diff --git a/POTFILES b/POTFILES index 6f9cbcec7..b488a87d2 100644 --- a/POTFILES +++ b/POTFILES @@ -1 +1,4 @@ -./control/control.glade +control/control.PROF.glade +control/control.SLES.glade +control/control.SLD.glade +control/control.glade diff --git a/configure.in.in b/configure.in.in index 29d28c203..647e27dca 100644 --- a/configure.in.in +++ b/configure.in.in @@ -13,7 +13,12 @@ @YAST2-CHECKS-TESTSUITE@ ## Nasty hack: xgettext doesn't work for XML files, so let's symlink it -( cd control; ln -sf control.xml control.glade ) +( cd control; + for xml in `ls *.xml`; do + ln -sf $xml `basename $xml .xml`.glade + done + ) +find control -name *.glade > POTFILES AX_CHECK_DOCBOOK diff --git a/control/Makefile.am b/control/Makefile.am index c3917d399..d55f3156b 100644 --- a/control/Makefile.am +++ b/control/Makefile.am @@ -7,7 +7,6 @@ productdir = /var/lib/YaST2 control_DATA = \ control.xml \ - control.SLES.xml \ control.dtd product_DATA = ProductFeatures diff --git a/control/control.PROF.xml b/control/control.PROF.xml index 26d358778..8751f6ead 100644 --- a/control/control.PROF.xml +++ b/control/control.PROF.xml @@ -30,7 +30,7 @@ textdomain="control" installation,demo,autoinstallation initial - initial + initial hwinfo mode @@ -47,7 +47,7 @@ textdomain="control" normal - dirinstall + dirinstall normal dirinstall_options @@ -57,7 +57,7 @@ textdomain="control" normal - uml + uml normal uml_source @@ -70,7 +70,7 @@ textdomain="control" update - initial + initial normal update @@ -84,7 +84,7 @@ textdomain="control" update initial - initial + initial hwinfo mode @@ -99,7 +99,7 @@ textdomain="control" - network + network continue,normal @@ -134,7 +134,7 @@ textdomain="control" - hardware + hardware continue x11 @@ -150,7 +150,6 @@ textdomain="control" - false,false all initial @@ -158,19 +157,21 @@ textdomain="control" info - false,true language - false,true,true + no + yes + + yes + true - true,true proposal - initial + initial do_resize @@ -198,7 +199,6 @@ textdomain="control" - false,false all initial @@ -208,18 +208,15 @@ textdomain="control" info - false,true repair - false,true,true - false,false all initial @@ -227,7 +224,8 @@ textdomain="control" screen_shot - false,true,true + yes + false language true @@ -235,8 +233,7 @@ textdomain="control" proposal - true,true - initial + initial @@ -260,7 +257,6 @@ textdomain="control" - false,false all initial @@ -270,10 +266,10 @@ textdomain="control" info - false,true - false,true,true + yes + false language true @@ -281,8 +277,7 @@ textdomain="control" proposal - true,true - initial + initial @@ -309,7 +304,8 @@ textdomain="control" update - false,false + false + false all @@ -323,31 +319,35 @@ textdomain="control" ask_net_test - true,true + true + true do_net_test - true,true + true + true you - true,true + true + true suseconfig - false,false release_notes - true,true + true + true congratulate - true,true + true + true @@ -356,7 +356,8 @@ textdomain="control" installation - false,false + false + false all @@ -376,13 +377,15 @@ textdomain="control" root - false,true + false + true proposal - true,true - network + true + true + network fam @@ -390,48 +393,54 @@ textdomain="control" ask_net_test - true,true + true + true do_net_test - true,true + true + true you - true,true + true + true auth - true,true + true + true user - true,true + true + true - suseconfig - false,false release_notes - true,true + true + true proposal - true,true - hardware + true + true + hardware congratulate - true,true + true + true @@ -440,14 +449,14 @@ textdomain="control" autoinstallation - false,false all + false + false info - false,true @@ -463,7 +472,7 @@ textdomain="control" proposal true,true - initial + initial @@ -489,7 +498,8 @@ textdomain="control" - false,false + false + false all continue @@ -517,7 +527,6 @@ textdomain="control" x11 - false,false diff --git a/control/control.xml b/control/control.xml index 12c0c29b9..24b57ae58 100644 --- a/control/control.xml +++ b/control/control.xml @@ -28,9 +28,9 @@ textdomain="control" - installation,demo,autoinst + installation,demo,autoinstallation initial - initial + initial hwinfo mode @@ -47,7 +47,7 @@ textdomain="control" normal - dirinstall + dirinstall normal dirinstall_options @@ -57,7 +57,7 @@ textdomain="control" normal - uml + uml normal uml_source @@ -68,27 +68,23 @@ textdomain="control" - + update - initial + initial normal - hwinfo - mode - media - rootpart update packages backup language - keyboard + update initial - initial + initial hwinfo mode @@ -103,7 +99,7 @@ textdomain="control" - network + network continue,normal @@ -138,7 +134,7 @@ textdomain="control" - hardware + hardware continue x11 @@ -154,7 +150,6 @@ textdomain="control" - false,false all initial @@ -162,18 +157,18 @@ textdomain="control" info - false,true language - false,true,true + no + yes true - proposal - true,true,`initial + proposal + initial do_resize @@ -201,7 +196,6 @@ textdomain="control" - false,false all initial @@ -211,18 +205,15 @@ textdomain="control" info - false,true repair - false,true,true - false,false all initial @@ -230,7 +221,8 @@ textdomain="control" screen_shot - false,true,true + yes + false language true @@ -238,7 +230,7 @@ textdomain="control" proposal - true,true,`initial + initial @@ -262,7 +254,6 @@ textdomain="control" - false,false all initial @@ -272,10 +263,10 @@ textdomain="control" info - false,true - false,true,true + yes + false language true @@ -283,7 +274,7 @@ textdomain="control" proposal - true,true,`initial + initial @@ -310,7 +301,8 @@ textdomain="control" update - false,false + false + false all @@ -324,31 +316,35 @@ textdomain="control" ask_net_test - true,true + true + true do_net_test - true,true + true + true you - true,true + true + true suseconfig - false,false release_notes - true,true + true + true congratulate - true,true + true + true @@ -357,7 +353,8 @@ textdomain="control" installation - false,false + false + false all @@ -377,12 +374,15 @@ textdomain="control" root - false,true + false + true proposal - true,true,`network + true + true + network fam @@ -390,63 +390,70 @@ textdomain="control" ask_net_test - true,true + true + true do_net_test - true,true + true + true you - true,true + true + true auth - true,true + true + true user - true,true + true + true - suseconfig - false,false release_notes - true,true + true + true proposal - true,true,`hardware + true + true + hardware congratulate - true,true + true + true initial - autoinst + autoinstallation - false,false all + false + false info - false,true @@ -461,7 +468,8 @@ textdomain="control" proposal - true,true,`initial + true,true + initial @@ -487,12 +495,13 @@ textdomain="control" - false,false + false + false all continue - autoinst + autoinstallation netsetup @@ -515,7 +524,6 @@ textdomain="control" x11 - false,false diff --git a/doc/README.installer b/doc/README.installer index c131573cb..692e01dcf 100644 --- a/doc/README.installer +++ b/doc/README.installer @@ -1,3 +1,6 @@ + +note: This is outdated, needs an update. (nashif@suse.de) + README.installer ---------------- diff --git a/general/inst_congratulate.ycp b/general/inst_congratulate.ycp index e4e2c6e62..696539417 100644 --- a/general/inst_congratulate.ycp +++ b/general/inst_congratulate.ycp @@ -16,6 +16,7 @@ import "Wizard"; import "Popup"; import "Label"; + import "GetArgs"; // show button "start control center"? @@ -92,7 +93,7 @@ after Finish is pressed. Note: The Control Center does not have a back bu return to this installation sequence.

"); - Wizard::SetContents (caption, contents, help, (boolean)WFM::Args (0), (boolean)WFM::Args (1)); + Wizard::SetContents (caption, contents, help, GetArgs::enable_back(), GetArgs::enable_next()); Wizard::SetTitleIcon ("SuSEmenu"); Wizard::SetNextButton(`next, Label::FinishButton() ); diff --git a/general/inst_doit.ycp b/general/inst_doit.ycp index 9c6177345..3427331c3 100644 --- a/general/inst_doit.ycp +++ b/general/inst_doit.ycp @@ -18,24 +18,9 @@ import "Label"; - if (Mode::autoinst ()) - { - if (!AutoinstConfig::Confirm) - { - return `next; - } - } + if (Mode::autoinst () && !AutoinstConfig::Confirm) + return `next; - if ( (boolean) WFM::Args(2) ) // going backwards? - { - // This module can only be reached in backward direction if any of the - // subsequent modules failed - creating the partitions, formatting etc. - // - // None of the subsequent interactive dialogs are allowed to have a - // `next button enabled, so there is no chance of getting here manually. - - return `back; - } define void ConfirmLicenses () { if (Mode::autoinst ()) diff --git a/general/inst_fam.ycp b/general/inst_fam.ycp index 5863f0a11..74aaf3799 100644 --- a/general/inst_fam.ycp +++ b/general/inst_fam.ycp @@ -12,11 +12,13 @@ textdomain "installation"; import "ProductFeatures"; + import "ProductControl"; import "Mode"; import "Service"; + import "GetArgs"; /* Called backwards */ - if(WFM::Args(2) == true) + if(GetArgs::going_back()) return `auto; if ( !Mode::update () ) @@ -27,7 +29,7 @@ SCR::Read (.sysconfig.windowmanager.DEFAULT_WM); y2milestone ("Default WM: %1", default_wm); string local_only = ProductFeatures::fam_local_only; - y2milestone ("Fam actiovation: %1", local_only); + y2milestone ("Fam activation: %1", local_only); if (local_only == "always" || local_only == default_wm) { y2milestone ("Setting fam to local_only"); diff --git a/general/inst_release_notes.ycp b/general/inst_release_notes.ycp index 75be438d5..d34fc770e 100644 --- a/general/inst_release_notes.ycp +++ b/general/inst_release_notes.ycp @@ -18,6 +18,7 @@ import "Mode"; import "Misc"; import "Stage"; + import "GetArgs"; /* filename of release notes */ string file = ""; @@ -78,8 +79,8 @@ string help = _("

Here are the release notes for the installed Linux system. They provide a brief summary of new features and changes.

"); - Wizard::SetContents (caption, contents, help, (boolean)WFM::Args(0), - (boolean)WFM::Args(1)); + Wizard::SetContents (caption, contents, help, GetArgs::enable_back(), + GetArgs::enable_next()); // FIXME: richtext eats return key // UI::SetFocus (`id (`text)); diff --git a/general/inst_suseconfig.ycp b/general/inst_suseconfig.ycp index c8432d4cf..25bf023c0 100644 --- a/general/inst_suseconfig.ycp +++ b/general/inst_suseconfig.ycp @@ -26,10 +26,10 @@ import "Popup"; import "Wizard"; import "Kernel"; + import "GetArgs"; - - if ( size( WFM::Args() ) > 2 && WFM::Args(2) == true ) // going backwards? - return `auto; // don't execute this once more + if ( GetArgs::going_back()) // going backwards? + return `auto; // don't execute this once more boolean reread_inittab = false; @@ -107,17 +107,10 @@ this process can take some time.

); - boolean back_ok = false; - boolean next_ok = false; - if (size (WFM::Args()) > 1) - { - back_ok = (boolean) WFM::Args(0); - next_ok = (boolean) WFM::Args(1); - } Wizard::SetContents( // Dialog title for SuSEconfig dialog _("Writing the system configuration"), - contents, help, back_ok, next_ok); + contents, help, GetArgs::enable_back(), GetArgs::enable_next()); Wizard::DisableAbortButton(); diff --git a/general/installation.ycp b/general/installation.ycp index 770f27004..2394e6e00 100644 --- a/general/installation.ycp +++ b/general/installation.ycp @@ -41,35 +41,29 @@ import "Label"; import "Popup"; import "Report"; - import "Hooks"; - import "Linuxrc"; - - // ====================================================================== + import "Linuxrc"; /** * Re-translate static part of wizard dialog and other predefined messages * after language change */ void retranslateWizardDialog() - { - y2debug( "Retranslating messages" ); - - // Make sure the labels for default function keys are retranslated, too. - // Using Label::DefaultFunctionKeyMap() from Label module. - UI::SetFunctionKeys( Label::DefaultFunctionKeyMap() ); - - // Activate language changes on static part of wizard dialog + { + y2milestone( "Retranslating messages" ); - ProductControl::RetranslateWizardSteps(); - Wizard::RetranslateButtons(); - Wizard::SetFocusToNextButton(); + // Make sure the labels for default function keys are retranslated, too. + // Using Label::DefaultFunctionKeyMap() from Label module. + UI::SetFunctionKeys( Label::DefaultFunctionKeyMap() ); - } - - // ====================================================================== + // Activate language changes on static part of wizard dialog + ProductControl::RetranslateWizardSteps(); + Wizard::RetranslateButtons(); + Wizard::SetFocusToNextButton(); + return; + } // properly set up initial language @@ -99,19 +93,7 @@ UI::RecordMacro( Directory::logdir + "/macro_inst_cont.ycp" ); } - /////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////// - /////// /////// - /////// OO OO OO O OO O /////// - /////// OO OO OO O OO O /////// - /////// O O O O O O O O O O /////// - /////// O O O OOOOOO O O O O /////// - /////// O O O O O O O O /////// - /////// O M O O O O OO /////// - /////// O M O O O O OO /////// - /////// /////// - /////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////// + // Detect mode early to be able to setup steps correctly if (Stage::cont ()) @@ -154,10 +136,13 @@ // UI::WizardCommand() can safely be called even if the respective UI // doesn't support the wizard widget, but for optimization it makes sense // to do expensive operations only when it is available. + list stage_mode = [$["stage": "initial" , "mode": wizard_mode ], - $["stage": "continue", "mode": wizard_mode ], - $["stage": "firstboot", "mode": wizard_mode ]]; + $["stage": "continue", "mode": wizard_mode ], + $["stage": "firstboot", "mode": wizard_mode ]]; + ProductControl::AddWizardSteps(stage_mode); + // classified_user_settings contain secrets, like passwords ... // they should not be logged ! @@ -308,29 +293,7 @@ differ from those in the manual. } - //-------------------------------------------------------------------- - - ////////////////////////////////////////////////////////////////// - // All settings the user does are saved into a map. The submodules - // are called as functions and thus have access to this variable. - // They return `next, `back, `cancel, `again or `auto. - // A submodule that can't be loaded (syntax error) returns nil. - - any former_result = `next; - integer m = 0; // current module - Wizard::SetFocusToNextButton(); - - y2debug("Starting Workflow with \"%1\" \"%2\"", Stage::stage (), Mode::mode ()); - list modules = ProductControl::getModules( - Stage::stage (), - Mode::mode (), - `enabled - ); - - map defaults = ProductControl::getModeDefaults(Stage::stage (), Mode::mode ()); - - y2debug("modules: %1", modules); // skip language dialog if selected in isolinux. (#37679) if (Stage::initial () && SCR::Read (.etc.install_inf.Language)!= nil) @@ -343,174 +306,15 @@ differ from those in the manual. } } - if (size(modules) == 0 ) - { - y2error("No workflow found: %1", modules ); - Report::Error(_("No Workflow defined for this installation mode.")); - return `abort; - } - while ((m >= 0) && (m < size(modules))) - { - map mod = modules[m]:$[]; - term argterm = ProductControl::getTerm( mod, defaults); - boolean retranslate = mod["retranslate"]:false; - - boolean do_continue = false; - - if (!ProductControl::checkArch(mod, defaults)) - { - y2milestone("continue (arch).."); - do_continue = true; - } - - if (ProductControl::checkDisabled(mod)) - { - y2milestone("continue (status).."); - do_continue = true; - } - - if (!mod["update"]:true && Mode::update ()) - { - y2milestone("continue (update).."); - do_continue = true; - } - - if ( do_continue ) - { - if (former_result == `next) m = m + 1; - else m = m - 1; - } - if ( do_continue ) continue; - - // proposal type - symbol type = `dummy; - if (haskey(mod, "type") && mod["type"]:""!="") - { - type = symbolof(toterm(mod["type"]:"dummy")); - argterm = add (argterm, type); - } - y2milestone("Running module: %1 (%2)", argterm, m); - argterm = add (argterm, former_result == `back); - - symbol module_name = symbolof( argterm ); - if ( module_name != `inst_doit ) // This is only a popup - { - Wizard::ClearContents(); - } - - // -------------------------------------- - // Call the wizard dialog - - y2milestone( "Calling %1", argterm ); - // entry hook, (""+symbol is a symbol->string conversion) - Hooks::Checkpoint (sformat("%1", module_name), true); - Hooks::Run (mod["name"]:"", true); - - list args = []; - - integer i = 0; - while (i < size(argterm)) - { - any def = nil; - args[i] = argterm[i]:def; - i = i + 1; - } - - - UI::WizardCommand(`SetCurrentStep( mod["id"]:"" ) ); - ProductControl::CurrentWizardStep = mod["id"]:""; - - symbol result = (symbol) WFM::CallFunction (substring(sformat("%1", module_name), 1), args); - - // Dont call hook scripts after installation is done. (#36831) - if (m < size(modules) - 1) - { - Hooks::Run (mod["name"]:"", false ); - } - else - { - y2milestone("Not running hooks at the end of the installation"); - } - - // This should be safe (#36831) - Hooks::Checkpoint ( mod["name"]:"", false); // exit hook - - if ( retranslate ) // language change very likely - { - retranslateWizardDialog(); - retranslate = false; - } - - // If the module return nil, something basic went wrong. - // We show a stub dialog instead. - if (result == nil) - { - /** - * If workflow module is marked as optional, skip if it returns nil, - * For example, if its not installed. - */ - if (mod["optional"]:false) - { - y2milestone("Skipping optional %1", symbolof(argterm) ); - m = m + 1; - continue; - } - - any r = nil; - r = Popup::ModuleError(sformat("The module %1 does not work.", symbolof(argterm))); - if (r == `next) m = m + 1; - else if (r == `back) m = m - 1; - else if (r != `again) - { - UI::CloseDialog(); - return nil; - } - continue; - } - - if (result == `next) - { - m = m + 1; - } - else if (result == `back) - { - m = m - 1; - } - else if (result == `cancel) - { - break; - } - else if (result == `abort) - { - // Close Sources - Pkg::SourceFinishAll (); - Pkg::TargetFinish (); - - // tell linuxrc that we aborted - Linuxrc::WriteYaSTInf($["Aborted" : "1"]); - break; - } - else if (result == `finish) - { - break; - } - else if (result == `again) - { - continue; // Show same dialog again - } - else if (result == `auto) - { - if (former_result != nil) - { - if (former_result == `next) m = m + 1; - else if (former_result == `back) m = m - 1; - } - continue; - } - former_result = result; + symbol ret = ProductControl::Run(); + if (ret == `abort) + { + // tell linuxrc that we aborted + Linuxrc::WriteYaSTInf($["Aborted" : "1"]); } + // re-enable automatic probing if (!Mode::test ()) @@ -536,7 +340,5 @@ differ from those in the manual. Pkg::TargetFinish(); UI::CloseDialog(); - - if (m <= -1) return `back; - else return `next; + return ret; } diff --git a/modules/GetArgs.ycp b/modules/GetArgs.ycp new file mode 100644 index 000000000..dc2c27680 --- /dev/null +++ b/modules/GetArgs.ycp @@ -0,0 +1,49 @@ +/** + * File: modules/GetArgs.ycp + * Package: yast2 + * Summary: Get client arguments + * Authors: Anas Nashif + * + * $Id: Product.ycp 20401 2004-11-24 15:41:05Z nashif $ + */ + + +{ + + module "GetArgs"; + + map args = $[]; + void Init () { + /* Check arguments */ + args = $[]; + if(size(WFM::Args()) > 0 && is(WFM::Args(0), map)) + { + args = (map) WFM::Args(0); + } + } + + global boolean enable_next() { + Init(); + return args["enable_next"]:false; + } + + global boolean enable_back() { + Init(); + return args["enable_back"]:false; + } + + global boolean going_back() { + Init(); + return args["going_back"]:false; + } + + global string proposal() { + Init(); + return args["proposal"]:""; + } + + global map argmap () { + Init(); + return args; + } +} diff --git a/modules/Hooks.ycp b/modules/Hooks.ycp index 86b8a7b43..0f7208bc9 100644 --- a/modules/Hooks.ycp +++ b/modules/Hooks.ycp @@ -86,7 +86,8 @@ */ global define void Run(string filename, boolean at_entry) { - y2milestone("Running Hook: %1" , filename); + y2debug("Running Hook: %1" , filename); + // do not run scripts twice if (at_entry) { if (WFM::Read (.local.size, sformat("%1/%2_pre.sh", tmp_dir, filename)) > 0) @@ -115,6 +116,7 @@ y2debug("Hook not found: %1/%2_post.{sh,pl}" , tmp_dir, filename); } } + return; } } diff --git a/modules/Makefile.am b/modules/Makefile.am index 9c817faa5..9eb321de3 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -9,6 +9,7 @@ module_DATA = \ Installation.ycp \ ProductControl.ycp \ Product.ycp \ + GetArgs.ycp \ Vendor.ycp EXTRA_DIST = $(module_DATA) diff --git a/modules/ProductControl.ycp b/modules/ProductControl.ycp index 3436aa90f..dcdc07786 100644 --- a/modules/ProductControl.ycp +++ b/modules/ProductControl.ycp @@ -17,18 +17,13 @@ import "Mode"; import "Arch"; import "Stage"; import "Directory"; +import "Label"; +import "Wizard"; +import "Report"; +import "Hooks"; +import "Popup"; - -// current proposal label -global string current_proposal_label = ""; - -// current proposal textdomain -global string current_proposal_textdomain = ""; - -// locked proposal -global list locked_proposals = []; - // The complete parsed control file global map productControl = $[]; @@ -48,15 +43,9 @@ global map software = $[]; global map globals = $[]; -// Control file for firstboot workflow and proposals -// -global string firstboot_control_file = "/usr/share/YaST2/control/firstboot.xml"; - // Location of a custom control file global string custom_control_file = ""; - - // Control file in service packs global string y2update_control_file = "/y2update/control.xml"; @@ -91,6 +80,22 @@ global list DisabledModules = []; global list logfiles = []; +string _client_prefix = "inst_"; + +list stack = []; + + +string first_id = ""; + + +/** + * Set Client Prefix + */ +global define void setClientPrefix(string prefix) { + _client_prefix = prefix; + return; +} + /** * Check if a module is disabled * @param map module map @@ -110,11 +115,13 @@ global define boolean checkDisabled (map mod ) * @param string control file * @return boolean */ -global define boolean Read( string controlfile) +global define boolean ReadControlFile( string controlfile) { productControl = XML::XMLToYCPFile(controlfile); + if (productControl == nil) return false; + workflows = productControl["workflows"]:[]; proposals = productControl["proposals"]:[]; @@ -134,7 +141,9 @@ global define boolean Read( string controlfile) if (haskey(productControl, "software")) { software = productControl["software"]:$[]; + ProductFeatures::base_selection_choice = software["selection_type"]:`auto; + if (size(software["base_selection"]:"") > 0 ) { ProductFeatures::fixed_base_selection = software["base_selection"]:"Minimal"; @@ -256,70 +265,58 @@ global define boolean checkArch(map mod , map def) }; -/** - * Return term to be used to run module - * @param map module data - * @param map default data - * @return term module data with params - */ -global define term getTerm (map mod, map def) ``{ +string getClientName(string name ) { // All client start with "inst_". - string client = ""; - if (Stage::firstboot () || custom_control_file != "") + if ( custom_control_file != "") { - // Firstboot mode has no predefined prefix. Name of module is - // taken as is. This also applies to custom control files used - // for mini workflows, but not installation workflows. - - client = mod["name"]:"dummy"; + return name; } else { - if (issubstring(mod["name"]:"dummy", "inst_")) - { - client = mod["name"]:"dummy"; - } - else - { - client = "inst_" + mod["name"]:"dummy"; - } + if (issubstring(name, _client_prefix)) { + return name; + } else { + client = _client_prefix + name; + return client; + } + } +} +/** + * Return term to be used to run module with CallFunction + * @param map module data + * @param map default data + * @return term module data with params + */ +global define term getClientTerm (map step, map def, any former_result) +{ + string client = getClientName(step["name"]:"dummy"); + term result = toterm(client); + map arguments = $[]; + + foreach(string button, ["enable_back", "enable_next"], ``{ + + string default_setting = def[button]:"yes"; + arguments[button] = step[button]:default_setting == "yes"; + }); - term a = toterm(client); - string arguments = mod["arguments"]:""; - list args = splitstring(arguments, ","); - if (size(args) == 0 ) + if (haskey(step,"proposal")) { - args = splitstring(def["arguments"]:"", ","); + arguments["proposal"] = step["proposal"]:""; } + map other_args = step["arguments"]:$[]; + + if (size(other_args) > 0 ) + arguments = (map)union(arguments, other_args ); + if (is(former_result,symbol) && former_result == `back) + arguments["going_back"] = true; + + result = add(result, arguments); + return result; - foreach(string arg, args, - { - if (arg == "true") - { - a=add(a, true); - } - else if (arg == "false") { - a=add(a, false); - } - else if (findfirstof(arg, "`") != nil) - { - if (findfirstof(arg, "`") == 0) - { - term s = toterm(substring(arg,1)); - symbol ss = symbolof(s); - a=add(a, ss); - } - } - else - { - a=add(a,arg); - } - }); - return a; } @@ -343,7 +340,8 @@ global define map getModeDefaults(string stage, string mode) * @param m Workflow module map * @return void */ -void PrepareScripts(map m) { +void PrepareScripts(map m) +{ string tmp_dir = (string)WFM::Read(.local.tmpdir, []); if (haskey(m,"prescript")) { @@ -489,6 +487,7 @@ global define string getWorkflowLabel(string stage, string mode) * Add Wizard Steps * @param list stagemode A List of maps containing info about complete * installation workflow. + * @return void */ global define void AddWizardSteps(list stagemode) { @@ -507,27 +506,28 @@ global define void AddWizardSteps(list stagemode) string first_id = ""; // UI::WizardCommand(`SetVerboseCommands( true ) ); foreach (map sm , stagemode, ``{ - y2debug( "Adding wizard steps for %1", sm ); - string slabel = getWorkflowLabel(sm["stage"]:"", sm["mode"]:""); - if ( slabel != "" ) + y2debug( "Adding wizard steps for %1", sm ); + string slabel = getWorkflowLabel(sm["stage"]:"", sm["mode"]:""); + if ( slabel != "" ) { - UI::WizardCommand(`AddStepHeading( dgettext( wizard_textdomain, slabel ) ) ); + UI::WizardCommand(`AddStepHeading( dgettext( wizard_textdomain, slabel ) ) ); } - foreach(map m, getModules(sm["stage"]:"", sm["mode"]:"", `enabled), - ``{ - y2debug("Adding wizard step: %1", m ); - if (m["label"]:"" != "") { - if (first_id=="") - { - first_id = m["id"]:""; - } - UI::WizardCommand(`AddStep( dgettext( - wizard_textdomain, - m["label"]:"" ), - m["id"]:"" ) - ); - } - }); + foreach(map m, getModules(sm["stage"]:"", sm["mode"]:"", `enabled), + ``{ + y2debug("Adding wizard step: %1", m ); + if (m["label"]:"" != "") + { + if (first_id=="") + { + first_id = m["id"]:""; + } + UI::WizardCommand(`AddStep( dgettext( + wizard_textdomain, + m["label"]:"" ), + m["id"]:"" ) + ); + } + }); }); UI::WizardCommand(`SetCurrentStep( first_id ) ); @@ -536,6 +536,7 @@ global define void AddWizardSteps(list stagemode) + /** * Update Steps */ @@ -561,21 +562,16 @@ global define void RetranslateWizardSteps() y2debug( "Retranslating wizard steps" ); UpdateWizardSteps( last_stage_mode ); } -}; +} -/** - * Get modules of current Workflow - * @param string stage - * @param string mode - * @return list modules - */ -global define list < list > getProposals( +define list getMatchingProposal( string stage, string mode, string proptype) { y2milestone("Stage: %1 Mode: %2", Stage::stage(), Mode::mode()); + // First we search for proposals for current stage if there are // any. (initial or continue) @@ -586,32 +582,35 @@ global define list < list > getProposals( Check(p["mode"]:"", mode))); // Now we check for architecture - y2debug("Architecture: %1", Arch::architecture () ); + y2debug("Architecture: %1, Proposals: %2", Arch::architecture (), props ); + list arch_proposals = filter(map p, props, ``( - p["type"]:"" == proptype && + p["name"]:"" == proptype && issubstring(p["archs"]:"dummy", Arch::arch_short () ))); y2debug("arch proposals: %1", arch_proposals ); + props = filter(map p, props, ``( - p["archs"]:"" == "all" || !haskey(p, "archs") - ) - ); + p["archs"]:"" == "all" || !haskey(p, "archs") + ) + ); - // If architecture specific proposals available, we continue with those + // If architecture specific proposals are available, we continue with those // and check for proposal type, else we continue with pre arch proposal // list if (size(arch_proposals) > 0 ) { props = filter(map p, arch_proposals, ``( - p["type"]:"" == proptype )); + p["name"]:"" == proptype )); } else { props = filter(map p, props, ``( - p["type"]:"" == proptype )); + p["name"]:"" == proptype )); } + if (size(props)> 1 ) { y2error("Something Wrong happened, more than one proposal after filter: @@ -620,7 +619,21 @@ global define list < list > getProposals( // old style proposal y2milestone ("Proposal modules: %1",props[0, "proposal_modules"]:nil ); + return props; +} + + +/** + * Get modules of current Workflow + * @param string stage + * @param string mode + * @return list modules + */ +global define list < list > getProposals(string stage, string mode, string proptype) { + + list props = getMatchingProposal(stage, mode, proptype); + list< list > final_proposals = maplist(any p, props[0, "proposal_modules"]:[], ``{ string proposal_name = ""; @@ -652,36 +665,54 @@ global define list < list > getProposals( }); - locked_proposals = maplist(string p, props[0, "locked_modules"]:[], ``{ - if (!issubstring(p, "_proposal")) - return(p + "_proposal"); - else - return(p); + + return final_proposals; +} - }); - current_proposal_textdomain = (string) - productControl["textdomain"]:"control"; +/** + * Get Proposal list that can not be changed by the user. + * @return list list of locked proposals + */ +global list getLockedProposals (string stage,string mode,string proptype) { - y2debug( "Using textdomain '%1' for proposals", current_proposal_textdomain); + list props = getMatchingProposal(stage, mode, proptype); + list locked_proposals = maplist(string p, props[0, "locked_modules"]:[], ``{ + if (!issubstring(p, "_proposal")) + return(p + "_proposal"); + else + return(p); - current_proposal_label = props[0, "label"]:""; - y2milestone("Proposal label: %1", current_proposal_label ); + }); + return locked_proposals; +} - return final_proposals; +/** + * Return text domain + */ +global string getProposalTextDomain() { + string current_proposal_textdomain = (string) + productControl["textdomain"]:"control"; + + y2debug( "Using textdomain '%1' for proposals", current_proposal_textdomain); + return current_proposal_textdomain; } /** - * Get Proposal list that cant be changed by the user. - * @return list list of locked proposals + * Return proposal Label */ -global list getLockedProposals () +global map getProposalProperties( string stage, string mode, string proptype +) { - return locked_proposals; + list proposal = getMatchingProposal(stage, mode, proptype); + return proposal[0]:$[]; + } + + /** * Initialize Product Control * @return boolean True on success @@ -689,18 +720,6 @@ global list getLockedProposals () global define boolean Init() { - // FIXME: Hack, with fixed names. Should be changed after SLES. - // #41696: Default control file is the one from 9.1. This is - // only a fallback solution if someone forgets the control.xml - // file in the installation source. Can happen with alot of - // customers used to older products. - if (issubstring(Product::name, "SLES")) - { - packaged_control_file = "/usr/share/YaST2/control/control.SLES.xml"; - } - - - boolean ret = false; current_control_file = ""; list order = @@ -711,11 +730,6 @@ global define boolean Init() packaged_control_file // /usr/share/YaST2/control/control.xml ]; - if (Stage::stage () == "firstboot") - { - order=prepend(order, firstboot_control_file); - } - if ( custom_control_file != "") { order=prepend(order, custom_control_file); @@ -730,19 +744,248 @@ global define boolean Init() } }); - // Just to be sure.. - /* if (current_control_file == "") { - current_control_file = packaged_control_file; // /usr/share/YaST2/control/control.xml + y2error("Control file not found"); + return false; } - */ - y2milestone("Reading controlfile: %1", current_control_file ); - Read( current_control_file ); + y2milestone("Reading control file: %1", current_control_file ); + ReadControlFile( current_control_file ); return (current_control_file != ""); } +/** + * Re-translate static part of wizard dialog and other predefined messages + * after language change + */ +void retranslateWizardDialog() + { + y2milestone( "Retranslating messages 1" ); + + // Make sure the labels for default function keys are retranslated, too. + // Using Label::DefaultFunctionKeyMap() from Label module. + UI::SetFunctionKeys( Label::DefaultFunctionKeyMap() ); + + // Activate language changes on static part of wizard dialog + + ProductControl::RetranslateWizardSteps(); + Wizard::RetranslateButtons(); + Wizard::SetFocusToNextButton(); + return; + } + + + +void addToStack(string name) { + stack=add(stack, name); + return; +} + +global boolean wasRun(string name) +{ + return contains(stack, name); +} + +/** + * Run Workflow + * + */ +global symbol Run() +{ + any former_result = `next; + integer m = 0; // current module + + Wizard::SetFocusToNextButton(); + + y2debug("Starting Workflow with \"%1\" \"%2\"", Stage::stage (), Mode::mode ()); + + list modules = + getModules( Stage::stage (), Mode::mode (), `enabled); + + map defaults = getModeDefaults(Stage::stage (), Mode::mode ()); + + y2debug("modules: %1", modules); + + if (size(modules) == 0 ) + { + y2error("No workflow found: %1", modules ); + Report::Error(_("No Workflow defined for this installation mode.")); + return `abort; + } + + + while ((m >= 0) && (m < size(modules))) + { + map step = modules[m]:$[]; + string step_name = step["name"]:""; + boolean run_in_update_mode = step["update"]:true; // default is true + boolean retranslate = step["retranslate"]:false; + string step_id = step["id"]:""; + + if (m == 0) + { + step["enable_back"] = "no"; + } + + boolean do_continue = false; + + if (!checkArch(step, defaults)) + { + do_continue = true; + } + + if (checkDisabled(step)) + { + do_continue = true; + } + + if (!run_in_update_mode && Mode::update ()) + { + do_continue = true; + } + + if ( do_continue ) + { + if (former_result == `next) m = m + 1; + else m = m - 1; + } + if ( do_continue ) continue; + + + term argterm = getClientTerm( step, defaults, former_result); + y2debug("Running module: %1 (%2)", argterm, m); + + symbol module_name = symbolof( argterm ); + + y2milestone( "Calling %1", argterm ); + + if (!wasRun(step_name)) { + Hooks::Checkpoint (sformat("%1", module_name), true); + Hooks::Run (step_name, true); + + } + + list args = []; + integer i = 0; + while (i < size(argterm)) + { + any def = nil; + args[i] = argterm[i]:def; + i = i + 1; + } + + UI::WizardCommand(`SetCurrentStep( step_id ) ); + CurrentWizardStep = step_id; + + + // Register what step we are going to run + if (!Stage::initial()) + { + if (!SCR::Write (.target.string, "/var/lib/YaST2/step", step_id)) + y2error("Error writing step identifier"); + } + + symbol result = (symbol) WFM::CallFunction (getClientName(step_name), args); + addToStack(step_name); + + + // Remove file if step was run and returned (without a crash); + if (m < size(modules) - 1 && !Stage::initial()) + { + if (SCR::Execute(.target.remove, "/var/lib/YaST2/step")!=0) + y2error("Error removing succesfull step identifier"); + } + + // Dont call hook scripts after installation is done. (#36831) + if (m < size(modules) - 1 && !wasRun(step_name)) + Hooks::Run (step_name, false ); + else + y2milestone("Not running hooks at the end of the installation"); + + // This should be safe (#36831) + Hooks::Checkpoint ( step_name, false); // exit hook + + if ( retranslate ) + { + y2milestone("retranslate"); + retranslateWizardDialog(); + retranslate = false; + } + + // If the module return nil, something basic went wrong. + // We show a stub dialog instead. + if (result == nil) + { + /** + * If workflow module is marked as optional, skip if it returns nil, + * For example, if it is not installed. + */ + if (step["optional"]:false) + { + y2milestone("Skipping optional %1", symbolof(argterm) ); + m = m + 1; + continue; + } + + any r = nil; + r = Popup::ModuleError(sformat("The module %1 does not work.", symbolof(argterm))); + + if (r == `next) m = m + 1; + else if (r == `back) m = m - 1; + else if (r != `again) + { + UI::CloseDialog(); + return nil; + } + continue; + } + + if (result == `next) + { + m = m + 1; + } + else if (result == `back) + { + m = m - 1; + } + else if (result == `cancel) + { + break; + } + else if (result == `abort) + { + break; + } + else if (result == `finish) + { + break; + } + else if (result == `again) + { + continue; // Show same dialog again + } + else if (result == `auto) + { + if (former_result != nil) + { + if (former_result == `next) m = m + 1; + else if (former_result == `back) m = m - 1; + } + continue; + } + former_result = result; + } + if (former_result == `abort) + { + return `abort; + } + + if (m <= -1) return `back; + else return `next; +} + + /** * ProductControl Constructor * @return void @@ -751,7 +994,7 @@ global define void ProductControl() { if (!Init()) { - y2error("No control file found"); + y2error("control file missing"); } return; } diff --git a/package/yast2-installation.changes b/package/yast2-installation.changes index d2086ee8d..fb781aa06 100644 --- a/package/yast2-installation.changes +++ b/package/yast2-installation.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Mon Jan 24 16:29:32 CET 2005 - nashif@suse.de + +- Moved installation workflow routines out of installation.ycp +- Adapted arguments of installation clients +- Enhanced control file and made it more readable (arguments of clients + are clearer now) + ------------------------------------------------------------------- Mon Jan 24 11:27:55 CET 2005 - ms@suse.de diff --git a/proposal/inst_proposal.ycp b/proposal/inst_proposal.ycp index e5f95700c..24efca47c 100644 --- a/proposal/inst_proposal.ycp +++ b/proposal/inst_proposal.ycp @@ -27,6 +27,7 @@ import "Popup"; import "ProductControl"; import "Language"; + import "GetArgs"; define void retranslate_proposal_dialog(); define void load_matching_submodules_list(); @@ -37,18 +38,19 @@ define void set_icon(); define string help_text(); + // values used in defined functions + map proposal_properties = $[]; list submodules = []; list submodules_presentation = []; - string proptype = ""; list locked_modules = []; list titles = []; map submod2id = $[]; map id2submod = $[]; map link2submod = $[]; boolean have_blocker = false; - symbol proposal_mode = nil; + string proposal_mode = ""; // skip if not interactive mode. if (!AutoinstConfig::Confirm && Mode::autoinst ()) { @@ -426,7 +428,6 @@ /** * Load a list of submodules matching the current internal states - * @param mode `initial, `network, or `hardware to indicate which list to use * * @return submodules_list list of submodule names (strings) **/ @@ -437,12 +438,16 @@ modules = ProductControl::getProposals ( Stage::stage (), Mode::mode (), - proptype ); - locked_modules = ProductControl::getLockedProposals (); + proposal_mode ); + + locked_modules = ProductControl::getLockedProposals (Stage::stage (), Mode::mode (), proposal_mode); + y2milestone("getting proposals for stage: \"%1\" mode: \"%2\" proposal type: \"%3\"", Stage::stage (), Mode::mode (), - proptype ); + proposal_mode ); + + proposal_properties = ProductControl::getProposalProperties(Stage::stage (), Mode::mode (), proposal_mode); if (size(modules) == 0 ) { @@ -491,16 +496,20 @@ define void build_dialog () { // headline for installation proposal - string headline = ProductControl::current_proposal_label; + + string headline = proposal_properties["label"]:""; + + y2milestone("headline: %1", headline ); + if ( headline == "") { headline = _("Installation Settings"); } else { - headline = dgettext( ProductControl::current_proposal_textdomain , - ProductControl::current_proposal_label ); + headline = dgettext( ProductControl::getProposalTextDomain() , + headline ); } // icon for installation proposal @@ -535,8 +544,8 @@ term vbox = nil; - if (proposal_mode == `initial || proposal_mode == `uml || - proposal_mode == `dirinstall) + if (proposal_mode == "initial" || proposal_mode == "uml" || + proposal_mode == "dirinstall") { vbox = `VBox( // Help message between headline and installation proposal / settings summary. @@ -565,7 +574,7 @@ } Wizard::SetContents(headline, vbox, help_text(), - (boolean) WFM::Args(0), // have_back_button + GetArgs::enable_back(), // have_back_button false // have_next_button ); set_icon(); @@ -632,9 +641,15 @@ { string icon = "software"; - if ( proposal_mode == `network ) icon = "network"; - else if ( proposal_mode == `hardware ) icon = "printer"; - // else if ( proposal_mode == `uml ) icon = ""; + if ( proposal_mode == "network" ) + icon = "network"; + else if ( proposal_mode == "hardware" ) + icon = "printer"; + else if ( proposal_properties["icon"]:"" != "" ) + icon = proposal_properties["icon"]:""; + + + // else if ( proposal_mode == `uml ) icon = ""; // else if ( proposal_mode == `dirinstall ) icon = ""; Wizard::SetTitleIcon( icon ); @@ -657,7 +672,7 @@ or by using the Change... menu.

"); - if ( proposal_mode == `initial && Mode::installation () ) + if ( proposal_mode == "initial" && Mode::installation () ) { // Help text for installation proposal // General part ("You can change values...") is added as the next paragraph. @@ -686,7 +701,7 @@ Your hard disk has not been modified in any way, so you can still safely abort.

"); } - else if ( proposal_mode == `initial && Mode::update () ) + else if ( proposal_mode == "initial" && Mode::update () ) { // Help text for update proposal // General part ("You can change values...") is added as the next paragraph. @@ -708,7 +723,7 @@ Your hard disk has not been modified in any way, so you can still safely abort.

"); } - else if ( proposal_mode == `network ) + else if ( proposal_mode == "network" ) { // Help text for network configuration proposal // General part ("You can change values...") is added as the next paragraph. @@ -717,7 +732,7 @@ Put the network settings into effect by pressing Next.

") + how_to_change; } - else if ( proposal_mode == `service ) + else if ( proposal_mode == "service" ) { // Help text for service configuration proposal // General part ("You can change values...") is added as the next paragraph. @@ -726,7 +741,7 @@ Put the service settings into effect by pressing Next.

") + how_to_change; } - else if ( proposal_mode == `hardware ) + else if ( proposal_mode == "hardware" ) { // Help text for hardware configuration proposal // General part ("You can change values...") is added as the next paragraph. @@ -735,13 +750,20 @@ Put the hardware settings into effect by pressing Next.

") + how_to_change; } - else if (proposal_mode == `uml) + else if (proposal_mode == "uml") { // Proposal in uml module help_text_string = _("

UML Installation Proposal

") + _("

UML (User Mode Linux) installation allows you to start independent Linux virtual machines in the host system.

"); } + else if (proposal_properties["help"]:"" != "") + { + // Proposal help from control file module + help_text_string = dgettext( ProductControl::getProposalTextDomain() , + proposal_properties["help"]:"") + + how_to_change; + } else { // Generic help text for other proposals (not basic installation or @@ -753,10 +775,11 @@ To use the settings as displayed, press Next. ") + how_to_change; } - if (size(locked_modules) > 0 ) { + if (size(locked_modules) > 0 ) + { help_text_string = help_text_string + _("

Some proposals might be locked by the system administrator and cannot be changed. If you need to change -a proposal that is locked, ask your system administrator

"); +a proposal that is locked, ask your system administrator.

"); } return help_text_string; @@ -782,13 +805,7 @@ a proposal that is locked, ask your system administrator

"); // y2milestone( "Installation step #2" ); - proposal_mode = (symbol) WFM::Args(2); - proptype = substring(sformat("%1", proposal_mode), 1 ); - -/* submodules = ProductControl::getProposals ( - Stage::stage (), - Mode::mode (), - proptype );*/ + proposal_mode = GetArgs::proposal(); // // Get submodule descriptions @@ -960,9 +977,7 @@ resolved before continuing. if ( Stage::stage () == "initial" ) { - input = WFM::CallFunction("inst_doit", [true, // have_back - true, // have_next - false] ); // going_backwards + input = WFM::CallFunction("inst_doit", [] ); } if ( input == `next ) diff --git a/proposal/test_proposal.ycp b/proposal/test_proposal.ycp index 8454bbfd5..be3f6d4a3 100644 --- a/proposal/test_proposal.ycp +++ b/proposal/test_proposal.ycp @@ -15,16 +15,13 @@ import "Wizard"; Stage::Set ("continue"); // Linuxrc::manual () = true; -map symbols = $[ - "hardware": `hardware, - "hw": `hardware, - "net": `network, - "network": `network, - ]; -symbol what = symbols[WFM::Args (0)]:`network; - Wizard::CreateDialog (); -WFM::call ("inst_proposal", [ true, nil, what ]); + +map args = $[]; +args["enable_back"] = true; +args["enable_next"] = nil; +args["proposal"] = WFM::Args (0); +WFM::call ("inst_proposal", [args ]); UI::CloseDialog (); /* EOF */ diff --git a/x11/inst_x11.ycp b/x11/inst_x11.ycp index 113e5b97c..b39263d4e 100644 --- a/x11/inst_x11.ycp +++ b/x11/inst_x11.ycp @@ -22,14 +22,10 @@ STATUS : Development import "Mode"; import "Installation"; import "Arch"; + import "GetArgs"; - boolean next = true; - boolean back = true; - - if (!(boolean)WFM::Args(0)) - back = false; - if (!(boolean)WFM::Args(1)) - next = false; + boolean next = GetArgs::enable_next(); + boolean back = GetArgs::enable_back(); //========================================== // Check if X11 is installed