ACC SHELL

Path : /usr/share/YaST2/include/installation/
File Upload :
Current File : //usr/share/YaST2/include/installation/inst_inc_second.ycp

/**
 * File: include/installation/inst_inc_second.ycp
 * Module: System installation
 * Summary: Functions for second stage
 * Authors: Lukas Ocilka <locilka@suse.cz>
 *
 * $Id: inst_inc_second.ycp 58958 2009-10-07 10:30:38Z jsuchome $
 *
 */
{

    textdomain "installation";

    import "FileUtils";
    import "Popup";
    import "Installation";
    import "Mode";
    import "Language";
    import "Directory";
    import "WorkflowManager";
    import "ProductControl";
    import "Console";
    import "Keyboard";
    import "Service";
    import "Progress";
    import "Wizard";
    import "InstData";

    include "installation/misc.ycp";

    // The order of services is important
    // especially for starting them
    list <string> inst_network_services = ["network", "portmap", "SuSEfirewall2_setup"];

    void AdjustDisabledModules () {
	if (InstData::wizardsteps_disabled_modules == nil) {
	    y2error ("Disabled modules file not defined");
	    return;
	}

	if (! FileUtils::Exists (InstData::wizardsteps_disabled_modules)) {
	    y2milestone ("File %1 doesn't exist, skipping...", InstData::wizardsteps_disabled_modules);
	    return;
	}

	list <string> disabled_modules = (list <string>) SCR::Read (.target.ycp, InstData::wizardsteps_disabled_modules);
	if (disabled_modules == nil) {
	    y2error ("Error reading %1", InstData::wizardsteps_disabled_modules);
	    return;
	}

	foreach (string one_module, disabled_modules, {
	    ProductControl::DisableModule (one_module);
	});

	y2milestone ("Disabled modules set to %1", ProductControl::GetDisabledModules());
    }

    void AdjustDisabledProposals () {
	if (InstData::wizardsteps_disabled_proposals == nil) {
	    y2error ("Disabled proposals file not defined");
	    return;
	}

	if (! FileUtils::Exists (InstData::wizardsteps_disabled_proposals)) {
	    y2milestone ("File %1 doesn't exist, skipping...", InstData::wizardsteps_disabled_proposals);
	    return;
	}

	list <string> disabled_proposals = (list <string>) SCR::Read (.target.ycp, InstData::wizardsteps_disabled_proposals);
	if (disabled_proposals == nil) {
	    y2error ("Error reading %1", InstData::wizardsteps_disabled_proposals);
	    return;
	}

	foreach (string one_proposal, disabled_proposals, {
	    ProductControl::DisableProposal (one_proposal);
	});

	y2milestone ("Disabled proposals set to %1", ProductControl::GetDisabledProposals());
    }

    void AdjustDisabledSubProposals () {
	if (InstData::wizardsteps_disabled_subproposals == nil) {
	    y2error ("Disabled subproposals file not defined");
	    return;
	}

	if (! FileUtils::Exists (InstData::wizardsteps_disabled_subproposals)) {
	    y2milestone ("File %1 doesn't exist, skipping...", InstData::wizardsteps_disabled_subproposals);
	    return;
	}

	map <string, list <string> > disabled_subproposals = (map <string, list <string> >) SCR::Read (.target.ycp, InstData::wizardsteps_disabled_subproposals);
	if (disabled_subproposals == nil) {
	    y2error ("Error reading %1", InstData::wizardsteps_disabled_subproposals);
	    return;
	}

	foreach (string unique_id, list<string> subproposals, disabled_subproposals, {
	    foreach (string one_subproposal,  subproposals, {
	        ProductControl::DisableSubProposal (unique_id, one_subproposal);
	    });
	});

	y2milestone ("Disabled subproposals set to %1", ProductControl::GetDisabledSubProposals());
    }

    void AdjustDisabledACItems () {
	if (InstData::wizardsteps_disabled_ac_items == nil) {
	    y2error ("Disabled AC items file not defined");
	    return;
	}

	if (! FileUtils::Exists (InstData::wizardsteps_disabled_ac_items)) {
	    y2milestone ("File %1 doesn't exist, skipping...", InstData::wizardsteps_disabled_ac_items);
	    return;
	}

	map <string, list <string> > disabled_ac_items = (map <string, list <string> >) SCR::Read (.target.ycp, InstData::wizardsteps_disabled_ac_items);
	if (disabled_ac_items == nil) {
	    y2error ("Error reading %1", InstData::wizardsteps_disabled_ac_items);
	    return;
	}

	foreach (string unique_id, list<string> ac_steps, disabled_ac_items, {
	    foreach (string one_ac_step,  ac_steps, {
	        ProductControl::DisableACItem (unique_id, one_ac_step);
	    });
	});

	y2milestone ("Disabled AC items set to %1", ProductControl::GetDisabledACItems());
    }

    void AdjustDisabledItems () {
	AdjustDisabledModules();
	AdjustDisabledProposals();
	AdjustDisabledSubProposals();
	AdjustDisabledACItems();
    }

    /**
     * Stores the current status of network services into
     * Installation::reboot_net_settings file
     *
     * @param symbol ret containing either `reboot or anything else
     * @see inst_network_services for list of network services
     */
    void StoreNetworkServices (symbol ret) {
	// Store the current status of services
	// bugzilla #258742
	if (ret == `reboot) {
	    map <string, boolean> network_settings = $[];
	    foreach (string one_service, inst_network_services, {
		network_settings[one_service] = (Service::Status (one_service) == 0);
	    });
	    y2milestone ("Storing services status: %1 into %2",
		network_settings, Installation::reboot_net_settings
	    );
	    SCR::Write (.target.ycp, Installation::reboot_net_settings, network_settings);
	} else {
	    if (FileUtils::Exists (Installation::reboot_net_settings))
		SCR::Execute (.target.remove, Installation::reboot_net_settings);
	}
    }

    void InitNetworkServices () {
	y2milestone ("Initializing network services...");

	// no settings stored
	if (! FileUtils::Exists (Installation::reboot_net_settings)) {
	    y2milestone ("File %1 doesn't exist, skipping InitNetworkServices",
		Installation::reboot_net_settings
	    );
	    return;
	}

	map <string, boolean> network_settings =
	    (map <string, boolean>) SCR::Read (.target.ycp, Installation::reboot_net_settings);
	y2milestone ("Adjusting services: %1", network_settings);

	// wrong syntax, wrong settings
	if (network_settings == nil) {
	    y2error ("Cannot read stored network services %1",
		SCR::Read (.target.string, Installation::reboot_net_settings)
	    );
	    return;
	}

	list <string> start_service = [];
	list <string> starting_service = [];

	// leave just services to be enabled
	// that are not running yet and that also exist
	network_settings = filter (string one_service, boolean new_status, network_settings, {
	    if (new_status != true) {
		y2milestone ("Service %1 needn't be started", one_service);
		return false;
	    }

	    integer service_status = Service::Status (one_service);

	    // 0 means running
	    if (service_status == 0) {
		y2milestone ("Service %1 is already running", one_service);
		return false;
	    }

	    // -1 means unknown (which might be correct, package needn't be installed)
	    if (service_status == -1) {
		y2warning ("Service %1 is unknown", one_service);
		return false;
	    }

	    // TRANSLATORS: progress stage, %1 stands for service name
	    start_service = add (start_service, sformat(_("Start service %1"), one_service));
	    // TRANSLATORS: progress stage, %1 stands for service name
	    starting_service = add (starting_service, sformat (_("Starting service %1..."), one_service));

	    return true;
	});

	if (size (network_settings) == 0 || network_settings == nil) {
	    y2milestone ("Nothing to adjust, leaving... %1", network_settings);
	    return;
	}

	Progress::New (
	    // TRANSLATORS: dialog caption
	    _("Adjusting Network Settings"),
	    " ",
	    size (network_settings),
	    start_service,
	    starting_service,
	    // TRANSLATORS: dialog help
	    _("Please wait while network settings are being adjusted...")
	);
	Wizard::SetTitleIcon ("yast-network");
	
	Progress::NextStage ();

	// Adjusting services
	foreach (string one_service, boolean new_status, network_settings, {
	    boolean ret = Service::Start (one_service);
	    y2milestone ("Starting service %1 returned %2", one_service, ret);

	    Progress::NextStage ();
	});
	
	Progress::Finish ();
	y2milestone ("All network services have been adjusted");
    }

    void SetUpdateLanguage () {
        string var_file = Directory::vardir + "/language.ycp";
        if (FileUtils::Exists (var_file)) {
            map var_map = (map) SCR::Read (.target.ycp, var_file);
            string lang = (string) var_map["second_stage_language"]:nil;
            if (lang != nil)
            {
                y2milestone("Setting language to: %1", lang);
                Language::QuickSet (lang);
                y2milestone ("using %1 for second stage", lang);
            }
            else
            {
                y2error("Cannot set language, tmp-file contains: %1", var_map);
            }
            SCR::Execute (.target.remove, var_file);
        }
    }

    /**
     * Checks whether the second stage installation hasn't been aborted or whether
     * it hasn't failed before. FATE #300422.
     *
     * @return symbol what to do, `next means continue
     */
    symbol RerunInstallationIfAborted () {
        // Second stage installation bas been aborted or has failed
        if (FileUtils::Exists (Installation::file_inst_aborted) || FileUtils::Exists (Installation::file_inst_failed)) {
            // popup question (#x1)
            string show_error = _("The previous installation has failed.
Would you like it to continue?

Note: You may have to enter some information again.");
            if (FileUtils::Exists (Installation::file_inst_aborted)) {
                // popup question (#x1)
                show_error = _("The previous installation has been aborted.
Would you like it to continue?

Note: You may have to enter some information again.");

                y2milestone("Case: aborted");
            } else {
                y2milestone("Case: failed");
            }

            if (! Popup::YesNoHeadline (
                // popup headline (#x1)
                _("Starting Installation..."),
                show_error
            )) {
                y2warning ("User didn't want to restart the second stage installation...");
                if (FileUtils::Exists (Installation::file_inst_aborted)) SCR::Execute (.target.remove, Installation::file_inst_aborted);
                if (FileUtils::Exists (Installation::file_inst_failed))  SCR::Execute (.target.remove, Installation::file_inst_failed);
                if (FileUtils::Exists (Installation::run_yast_at_boot))  SCR::Execute (.target.remove, Installation::run_yast_at_boot);

                // skipping the second stage
                return `skipped;
            }
        }

        // Second stage installation is starting just here

        // creating files in case the installation fails
        // they are removed at the end if everything works well
        y2milestone ("Creating files for case if installation fails (reset button)");
        // might be left from the previous run
        if (FileUtils::Exists (Installation::file_inst_aborted)) SCR::Execute (.target.remove, Installation::file_inst_aborted);
        SCR::Execute (.target.bash, sformat ("touch %1", Installation::file_inst_failed));
        SCR::Execute (.target.bash, sformat ("touch %1", Installation::run_yast_at_boot));
        
        return `next;
    }

    void CleanUpRestartFiles () {
        if (FileUtils::Exists (Installation::reboot_file)) {
            y2milestone ("Removing file %1", Installation::reboot_file);
            SCR::Execute (.target.remove, Installation::reboot_file);
        }
        if (FileUtils::Exists (Installation::restart_file)) {
            y2milestone ("Removing file %1", Installation::restart_file);
            SCR::Execute(.target.remove, Installation::restart_file);
        }
        if (FileUtils::Exists (Installation::restart_data_file)) {
            y2milestone ("Removing file %1", Installation::restart_data_file);
            SCR::Execute(.target.remove, Installation::restart_data_file);
        }
    }

    void EnableAutomaticModuleProbing () {
	WFM::Execute (.local.bash, "/bin/echo \"/sbin/modprobe\" >/proc/sys/kernel/modprobe");
    }

    void HandleSecondStageFinishedCorrectly () {
        // remove /etc/install.inf, not needed any more
        SCR::Execute (.target.remove, "/etc/install.inf");
        if (Mode::update ())
        {
            y2milestone("Removing %1", Installation::file_update_mode);
            SCR::Execute(.target.remove, Installation::file_update_mode);
            SCR::Execute(.target.remove, "/var/adm/current_package_descr");
        }
        else if (Mode::live_installation ())
        {
            y2milestone("Removing %1", Installation::file_live_install_mode);
            SCR::Execute(.target.remove, Installation::file_live_install_mode);
        }
        
        if (FileUtils::Exists (Installation::run_yast_at_boot)) {
            y2milestone("Removing %1", Installation::run_yast_at_boot);
            SCR::Execute(.target.remove, Installation::run_yast_at_boot);
        }

        // This file says that the configuration has failed
        // we don't need it anymore
        // FATE #300422
        if (FileUtils::Exists (Installation::file_inst_failed)) {
            y2milestone ("Removing file %1", Installation::file_inst_failed);
            SCR::Execute (.target.remove, Installation::file_inst_failed);
        }

        // This file has the current step of the workflow to be used
        // for crash recovery during installation. It can be deleted when
        // the installation has been completed.
        if (FileUtils::Exists (Installation::current_step)) {
            y2milestone ("Removing file %1", Installation::current_step);
            SCR::Execute (.target.remove, Installation::current_step);
        }

        if (WFM::Read (.local.size, "/usr/share/YaST2/clients/product_post.ycp") > 0)
            WFM::CallFunction ("product_post", [Mode::update ()]);
    }

    void HandleSecondStageAborted () {
        // removing the current step information
        // installation will be started from the very begining
        if (FileUtils::Exists (Installation::current_step)) {
            y2milestone ("Removing file %1", Installation::current_step);
            SCR::Execute (.target.remove, Installation::current_step);
        }

        // not to be identified as failed but aborted
        if (FileUtils::Exists (Installation::file_inst_failed)) {
            y2milestone ("Removing file %1", Installation::file_inst_failed);
            SCR::Execute (.target.remove, Installation::file_inst_failed);
        }

        // creating files saying that YaST will be started after reboot
        // if they don't exist
        y2warning ("Second Stage Installation has been aborted, creating files %1 and %2",
            Installation::run_yast_at_boot, Installation::file_inst_aborted);
        SCR::Execute (.target.bash, sformat ("touch %1", Installation::run_yast_at_boot));
        SCR::Execute (.target.bash, sformat ("touch %1", Installation::file_inst_aborted));
    }

    symbol PrepareYaSTforRestart (symbol ret) {
	// bnc #432005
	// After reboot, YaST will be started (inform user what to do if needed)
	boolean yast_needs_rebooting = false;

        // restarting yast, removing files that identify the user-abort or installation-crash
        // bugzilla #222896
        if (FileUtils::Exists (Installation::file_inst_aborted)) SCR::Execute (.target.remove, Installation::file_inst_aborted);
        if (FileUtils::Exists (Installation::file_inst_failed))  SCR::Execute (.target.remove, Installation::file_inst_failed);

        // creating new files to identify restart
        integer last_step = ProductControl::CurrentStep ();
        integer restarting_step = last_step;

        if (ret == `restart_same_step) {
            last_step = last_step - 1;
            ret = `restart_yast;
        }

	if (ret == `reboot_same_step) {
	    last_step = last_step - 1;
	    ret = `reboot;
	}

        integer next_step = last_step + 1;
        y2milestone ("Creating %1 file with values %2",
            Installation::restart_data_file, [next_step, restarting_step]);
        SCR::Write (.target.string, Installation::restart_data_file,
            sformat ("%1\n%2", next_step, restarting_step));

        if (ret == `reboot) {
            y2milestone ("Creating %1 file", Installation::reboot_file);
            SCR::Execute (.target.bash, sformat (
                "touch %1", Installation::reboot_file));
	    // bnc #432005
	    y2milestone ("YaST needs rebooting");
	    yast_needs_rebooting = true;

        } else if (ret == `restart_yast) {
            y2milestone ("Creating %1 file", Installation::restart_file);
            SCR::Execute (.target.bash, sformat (
                "touch %1", Installation::restart_file));
        }

	WriteSecondStageRequired (yast_needs_rebooting);

        return ret;
    }

    void SetSecondStageInstallation () {
        // Detect mode early to be able to setup steps correctly
        if (FileUtils::Exists (Installation::destdir + Installation::file_update_mode)) {
            Mode::SetMode ("update");
        }
        else if (FileUtils::Exists (Installation::destdir + Installation::file_live_install_mode)) {
            Mode::SetMode ("live_installation");
        }

	SetXENExceptions();

        // during update, set the 'update language' for the 2nd stage
        // FATE #300572
        if (Mode::update ()) {
            SetUpdateLanguage ();
        }

        // Properly setup timezone for continue mode
        import "Timezone";
        Timezone::Set( Timezone::timezone, true );
        Pkg::SetLocale (Language::language);

        UI::RecordMacro( Directory::logdir + "/macro_inst_cont.ycp" );

        // Merge control files of additional products and patterns
        string listname = Installation::destdir + Directory::etcdir + "/control_files/order.ycp";
        if (FileUtils::Exists (listname)) {
            list <string> files = (list<string>) SCR::Read (.target.ycp, listname);

	    string basedir = Installation::destdir + Directory::etcdir + "/control_files/";
	    files = maplist (string one_file, files, {
		return basedir + one_file;
	    });

	    WorkflowManager::SetAllUsedControlFiles (files);
	    WorkflowManager::SetBaseWorkflow (false);
	    WorkflowManager::MergeWorkflows();
	    WorkflowManager::RedrawWizardSteps();
        }
    }

    void SetLanguageAndEncoding () {
        Installation::encoding = Console::Restore();
        Console::Init ();
        if (UI::GetDisplayInfo()["HasFullUtf8Support"]:true)
        {
            Installation::encoding = "UTF-8";
        }

        ////////////////////////////////////////////////////////////
        // activate language settings and console font

        string language = Language::language;

        UI::SetLanguage (language, Installation::encoding);
        WFM::SetLanguage (language, "UTF-8");

        if ( ! Mode::test () )
        {
	    Keyboard::Set (Keyboard::current_kbd);

            // ncurses calls 'dumpkeys | loadkeys --unicode' in UTF-8 locale
            UI::SetKeyboard();
            y2milestone ("lang: %1, encoding %2", language, Installation::encoding);
        }
    }

} //end of include

ACC SHELL 2018