ACC SHELL

Path : /usr/share/YaST2/include/autoinstall/
File Upload :
Current File : //usr/share/YaST2/include/autoinstall/ask.ycp

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