ACC SHELL
/**
* File: clients/ask.ycp
* Package: Auto-installation
* Author: Uwe Gansert <ug@suse.de>
* Summary: ask for some values in the profile
*
* Changes:
* $Id: ask.ycp 61995 2010-05-11 13:11:47Z ug $
*/
{
import "Profile";
import "UI";
import "Label";
import "Stage";
import "Popup";
define list<any> path2pos( string pa ) {
list<any> pos = [];
foreach( string p, splitstring( pa, "," ), ``{
if( regexpmatch( p, "^[1,2,3,4,5,6,7,8,9,0]+$" ) ) {
integer index = tointeger(p);
pos = add(pos, index);
} else {
pos = add(pos, p);
}
});
return pos;
}
define term createWidget( term widget, string frametitle ) {
term ret = `Left( widget );
return ret;
}
define boolean askDialog() {
boolean mod = false;
map<integer,list> dialogs = $[];
list<integer> keys = [];
integer dialog_cnt = 0;
list<integer> history = [];
foreach( map ask, sort( map x, map y, Profile::current["general","ask-list"]:[], ``( x["element"]:0 < y["element"]:0 ) ), ``{
if( (Stage::initial() && ask["stage"]:"initial" == "initial") ||
(Stage::cont() && ask["stage"]:"initial" == "cont")
) {
dialogs[ask["dialog"]:dialog_cnt] = add( dialogs[ask["dialog"]:dialog_cnt]:[], ask );
if( ! contains( keys, ask["dialog"]:dialog_cnt ) )
keys = add( keys, ask["dialog"]:dialog_cnt );
if( ! haskey( ask, "dialog" ) )
dialog_cnt = dialog_cnt + 1;
}
});
keys = sort( keys );
integer dialogCounter = 0;
integer dialog_nr = keys[dialogCounter]:-1;
integer jumpToDialog = -2;
if( SCR::Read(.target.size, "/tmp/next_dialog") > 0 ) {
string s = (string)(SCR::Read(.target.string, "/tmp/next_dialog"));
s = filterchars( s, "-0123456789" );
jumpToDialog = tointeger(s);
SCR::Execute(.target.remove, "/tmp/next_dialog");
y2milestone("next_dialog file found. Set dialog to %1",jumpToDialog);
}
while( dialog_nr != -1 ) {
y2milestone("dialog_nr = %1",dialog_nr);
y2milestone("dialogCounter = %1",dialogCounter);
y2milestone("jumpToDialog %1",jumpToDialog);
string helptext = "";
string title = "";
string back_label = Label::BackButton();
string ok_label = Label::OKButton();
term dialog_term = `VBox();
term help_term = `Empty();
term title_term = `Empty();
integer element_cnt = 0;
integer timeout = 0;
history = add( history, dialog_nr );
term frameBuffer = nil;
term frameBufferVBox = nil;
string frameBufferTitle = "";
foreach( map ask, (list<map>)dialogs[dialog_nr]:[], ``{
string pathStr = ask["path"]:"";
string type = ask["type"]:"";
string question = ask["question"]:pathStr;
string frametitle = ask["frametitle"]:"";
string entry_id = sformat("%1_%2",dialog_nr, ask["element"]:element_cnt);
element_cnt = element_cnt + 1;
list< map<string,any> > s = ask["selection"]:[];
helptext = helptext + ask["help"]:"";
title = ask["title"]:"";
back_label = ask["back_label"]:back_label;
ok_label = ask["ok_label"]:ok_label;
timeout = ask["timeout"]:0;
mod = true;
if( haskey( ask, "default_value_script" ) ) {
string interpreter = ask["default_value_script", "interpreter"]:"shell";
if( interpreter == "shell" )
interpreter = "/bin/sh";
else if( interpreter == "perl" )
interpreter = "/usr/bin/perl";
string scriptPath = sformat("%1/%2", AutoinstConfig::tmpDir, "ask_default_value_script" );
SCR::Write(.target.string, scriptPath, ask["default_value_script","source"]:"");
map out = (map) SCR::Execute (.target.bash_output, interpreter + " " + scriptPath, $[]);
y2debug("%1", out);
if( out["exit"]:-1 == 0 )
ask["default"] = out["stdout"]:ask["default"]:"";
y2debug("default for '%1' is '%2' after script execution with exit code %3 (%4)", question, ask["default"]:"__undefined__", out["exit"]:-1, out["stderr"]:"");
}
term dlg = `Dummy();
if( type == "boolean" ) {
boolean on=(ask["default"]:nil=="true")?(true):(false);
term widget = `CheckBox(`id(entry_id), `opt(`notify), question,on );
dlg = createWidget( widget, frametitle );
} else if( type == "symbol" ) {
list<any> dummy = [];
foreach( map<string,any> e, s, ``{
boolean on=(e["value"]:`edge_of_dawn==ask["default"]:nil)?(true):(false);
dummy = add( dummy, `item(`id(e["value"]:`none), e["label"]:"",on) );
});
term widget = `ComboBox( `id(entry_id), `opt(`notify), question, dummy );
dlg = createWidget( widget, frametitle );
} else if( type == "static_text" ) {
term widget = `Label( `id(entry_id), ask["default"]:"" );
dlg = createWidget( widget, frametitle );
} else {
if( ask["password"]:false == true ) {
term widget1 = `Password(`id(entry_id), `opt(`notify), question, ask["default"]:"" );
term widget2 = `Password(`id(`pass2), `opt(`notify), "", ask["default"]:"" );
dlg = createWidget( `VBox( widget1, widget2), frametitle );
} else {
if( haskey( ask, "selection" ) ) {
list<any> dummy = [];
foreach( map<string,any> e, s, ``{
boolean on=(e["value"]:""==ask["default"]:nil)?(true):(false);
dummy = add( dummy, `item(`id(e["value"]:""), e["label"]:"",on) );
});
term widget = `ComboBox( `id(entry_id), `opt(`notify), question, dummy );
dlg = createWidget( widget, frametitle );
} else {
term widget = `TextEntry(`id(entry_id), `opt(`notify), question, ask["default"]:"" );
dlg = createWidget( widget, frametitle );
}
}
}
if( frametitle != "" ) {
if( frameBuffer == nil ) {
frameBufferVBox = `VBox( dlg );
} else {
if( frametitle == frameBufferTitle ) {
frameBufferVBox = add( frameBufferVBox, dlg );
} else {
dialog_term = add( dialog_term, frameBuffer );
dialog_term = add( dialog_term, `VSpacing(1) );
frameBufferVBox = `VBox( dlg );
}
}
frameBuffer = `Frame( frametitle, frameBufferVBox );
frameBufferTitle = frametitle;
} else {
if( frameBuffer != nil ) {
dialog_term = add( dialog_term, frameBuffer );
dialog_term = add( dialog_term, `VSpacing(1) );
frameBuffer = nil;
frameBufferVBox = nil;
}
dialog_term = add( dialog_term, dlg );
dialog_term = add( dialog_term, `VSpacing(1) );
}
});
if( frameBuffer != nil )
dialog_term = add( dialog_term, frameBuffer );
if( helptext != "" )
help_term = `HWeight(30, `RichText( helptext ));
if( title != "" )
title_term = `Heading( title );
term backButton = `PushButton(`id(`back), back_label );
UI::OpenDialog(
`opt(`decorated ),
`HBox(
help_term,
`HStretch(),
`HSpacing(1),
`HWeight(70,
`VBox(
title_term,
`VSpacing(1),
`VStretch(),
dialog_term,
`VSpacing(1),
`VStretch(),
`HBox(
`HStretch(),
backButton,
`PushButton(`id(`ok), ok_label )
)
)
),
`HSpacing(1),
`HStretch()
)
);
if( size(history) < 2 )
UI::ChangeWidget(`id(`back) , `Enabled, false);
while (true) {
any ret = nil;
if( timeout == 0 )
ret = UI::UserInput();
else
ret = UI::TimeoutUserInput( timeout * 1000 );
timeout = 0;
if( ret == `ok || ret == `timeout ) {
integer runAgain = 0;
integer element_cnt = 0;
dialogs[dialog_nr] = maplist( map ask, (list<map>)dialogs[dialog_nr]:[], ``{
string file = ask["file"]:"";
map script = ask["script"]:$[];
string entry_id = sformat("%1_%2",dialog_nr, ask["element"]:element_cnt);
element_cnt = element_cnt + 1;
any val = UI::QueryWidget(`id(entry_id), `Value);
if( ask["type"]:"string" == "integer" ) {
val = tointeger((string)val);
} else if( ask["type"]:"string" == "boolean" ) {
val = ( (boolean)val ? "true" : "false" );
}
if( ask["password"]:false == true ) {
string pass2 = (string)UI::QueryWidget(`id(`pass2), `Value);
if( pass2 != (string)val ) {
Popup::Error("The two passwords mismatch.");
runAgain = 1;
}
}
y2debug("question=%1 was answered with val=%2",ask["question"]:"", val);
ask["default"] = val;
list<any> pos = path2pos( ask["path"]:"" );
if( ask["path"]:"" != "" )
Profile::current = Profile::setElementByList( pos, val, Profile::current );
foreach( string p, ask["pathlist"]:[], ``{
list<any> pos = path2pos( p );
Profile::current = Profile::setElementByList( pos, val, Profile::current );
});
if( file != "" ) {
if( ! SCR::Write (.target.string, file, sformat("%1",val)) )
y2milestone("writing answer to %1 failed",file);
}
if( script != $[] ) {
string scriptName = script["filename"]:"ask_script.sh";
string scriptPath = sformat("%1/%2", AutoinstConfig::tmpDir, scriptName );
SCR::Write(.target.string, scriptPath, script["source"]:"echo 'no script'");
string debug = ( script["debug"]:true ? "-x" : "" );
string current_logdir = AutoinstConfig::logs_dir;
if( Stage::initial() ) {
current_logdir = sformat("%1/ask_scripts_log", AutoinstConfig::tmpDir);
SCR::Execute (.target.mkdir, current_logdir);
}
string executionString = "";
if( script["environment"]:false )
executionString = sformat("VAL=\"%5\" /bin/sh %1 %2 2&> %3/%4.log ",
debug, scriptPath, current_logdir, scriptName, AutoinstConfig::ShellEscape((string)val));
else
executionString = sformat("/bin/sh %1 %2 2&> %3/%4.log ", debug, scriptPath, current_logdir, scriptName );
y2milestone("Script Execution command: %1", executionString );
runAgain = runAgain + (integer)SCR::Execute (.target.bash, executionString);
if( script["rerun_on_error"]:false == false )
runAgain = 0;
boolean showFeedback = script["feedback"]:false;
string feedback = "";
if( showFeedback ) {
feedback = (string)SCR::Read(.target.string, current_logdir+"/"+scriptName+".log" );
}
if( size(feedback) > 0 ) {
Popup::LongText("", `RichText(`opt(`plainText), feedback), 40, 15 );
}
if( SCR::Read(.target.size, "/tmp/next_dialog") > 0 ) {
string s = (string)(SCR::Read(.target.string, "/tmp/next_dialog"));
s = filterchars( s, "-0123456789" );
jumpToDialog = tointeger(s);
SCR::Execute(.target.remove, "/tmp/next_dialog");
y2milestone("next_dialog file found. Set dialog to %1",jumpToDialog);
}
};
return ask;
});
if( runAgain == 0 )
break;
} else if( ret == `back ) {
jumpToDialog = history[ size(history)-2 ]:0;
history = remove( history, size(history)-1 );
history = remove( history, size(history)-1 );
break;
}
}
UI::CloseDialog();
if( jumpToDialog != -2 ) {
dialog_nr = jumpToDialog;
jumpToDialog = -2;
integer i = 0;
foreach( integer a, keys, ``{
if( a == dialog_nr ) {
dialogCounter = i;
break;
}
i = i + 1;
});
} else {
dialogCounter = dialogCounter + 1;
dialog_nr = keys[dialogCounter]:-1;
}
y2milestone("E dialog_nr = %1",dialog_nr);
y2milestone("E dialogCounter = %1",dialogCounter);
y2milestone("E jumpToDialog %1",jumpToDialog);
};
return mod;
}
}
ACC SHELL 2018