ACC SHELL

Path : /usr/share/YaST2/clients/
File Upload :
Current File : //usr/share/YaST2/clients/inst_deploy_image.ycp

{
import "Installation";
import "ImageInstallation";
import "Progress";
import "Wizard";
import "SourceManager";
import "String";
import "PackageCallbacks";
import "SlideShow";
import "Report";
import "ProductFeatures";
import "PackagesUI";

textdomain "installation";

// There is nothing to do
if (! Installation::image_installation) {
    y2milestone ("No images have been selected");
    // bnc #395030
    // Use less memory
    ImageInstallation::FreeInternalVariables();
    return `auto;
}

y2milestone ("Deploying images");

SlideShow::MoveToStage( "images" );

list<string> images = ImageInstallation::ImageOrder ();

integer last_image = nil;

integer _last_download_progress = -1;

integer _current_overall_progress = 0;
integer _last_overall_progress = -1;

integer _current_subprogress_start = 0;
integer _current_subprogress_steps = 0;
integer _current_subprogress_total = 0;

integer _current_step_in_subprogress = 0;

string _previous_id = nil;

void SetProgress () {
    integer percent = 100 * _current_step_in_subprogress / _current_subprogress_total;
    SlideShow::SubProgress( percent, nil );
}

void OverallProgressHandler (string id, integer current_step) {
    // new set of steps
    if (_previous_id != id) {
	// reset steps in subprogress
	_current_step_in_subprogress = 0;

	// new settings for new step
	_current_subprogress_start = ImageInstallation::GetProgressLayoutDetails (id, "steps_start_at");
	_current_subprogress_steps = ImageInstallation::GetProgressLayoutDetails (id, "steps_reserved");
	_current_subprogress_total = ImageInstallation::GetProgressLayoutDetails (id, "steps_total");

	// div by zero!
	if (_current_subprogress_total == 0) {
	    y2error ("steps_total=0");
	    _current_subprogress_total = 1;
	}

	y2milestone (
	    "New overall progress ID: %1 (steps_start_at: %2, steps_reserved: %3, steps_total: %4)",
	    id, _current_subprogress_start, _current_subprogress_steps, _current_subprogress_total
	);

	// when deploying images, label is handled separately
	if (id != "deploying_images") {
	    string new_label = ImageInstallation::GetProgressLayoutLabel (id);
	    SlideShow::SubProgressStart( new_label );
	}

	_previous_id = id;
    }

    // incremental
    if (current_step == nil) {
	_current_step_in_subprogress = _current_step_in_subprogress + 1;
    // set to exact number
    } else {
	_current_step_in_subprogress = current_step;
    }

    if (id == "storing_user_prefs" || id == "restoring_user_prefs") {
	SetProgress();
    }

    // Should be 0 - 100%
    _current_overall_progress = _current_subprogress_start +
	(_current_subprogress_steps * _current_step_in_subprogress / _current_subprogress_total);

    // update UI only if nr% has changed
    if (_current_overall_progress > _last_overall_progress) {
	_last_overall_progress = _current_overall_progress;
	SlideShow::StageProgress(_current_overall_progress, nil);
    }
}

integer _steps_for_one_image = 100;
boolean download_handler_hit = false;
string _last_image_downloading = nil;
boolean report_image_downloading = false;

// Not only images but also some helper files are downloaded
// Image installation should report only images
// BNC #449792
void MyStartDownloadHandler (string url, string localfile) {
    map <string, any> current_image = ImageInstallation::GetCurrentImageDetails();
    string current_image_file = current_image["file"]:"";

    // Fetches is (additionally) downloading some other file
    if (current_image_file == nil || current_image_file == "") {
	y2warning ("Uknown image being downloaded: %1", current_image);
	report_image_downloading = false;
	return;
    }

    integer image_filename_length = size (current_image_file);
    // 'http://some.url/directory/image.name' vs. 'directory/image.name'
    string image_url_download = substring (url, size (url) - image_filename_length, image_filename_length);

    // downloading progress is reported only if 
    report_image_downloading = (image_url_download == current_image_file);

    y2milestone ("Downloading started %1, showing progress %2", url, report_image_downloading);
}

boolean MyProgressDownloadHandler (integer percent, integer bps_avg, integer bps_current) {
    // changing settings on the fly
    // ... first when download handler is hit
    //
    // if a repository is remote, there are twice more steps to do (download, deploy)
    // local (or NFS, SMB, ...) access do not use downloader
    if (! download_handler_hit) {
	y2milestone ("DownloadHandler - first hit");
	// twice more steps
	ImageInstallation::AdjustProgressLayout ("deploying_images", (2 * _steps_for_one_image * size (images)), _("Deploying Images..."));
	download_handler_hit = true;
    }

    // See MyStartDownloadHandler
    // BNC #449792
    if (report_image_downloading != true) {
	return true;
    }

    map <string, any> current_image = ImageInstallation::GetCurrentImageDetails();

    if (_last_download_progress < percent) {
	string image_info = current_image["name"]:"";

	// BNC 442286, new image
	// Sometimes it happens that the same image is logged twice
	if (_last_image_downloading != image_info) {
	    y2milestone ("Downloading image: %1", image_info);
	    _last_image_downloading = image_info;
	}

	// unknown image
	if (image_info == "") {
	    image_info = sformat (_("Downloading image at speed %1/s"), String::FormatSize (bps_current));
	} else {
	    image_info = sformat (_("Downloading image %1 at speed %2/s"), image_info, String::FormatSize (bps_current));
	}
	
	SlideShow::SubProgress( percent, image_info );

	integer current_image_nr = current_image["image_nr"]:0;
	integer current_steps = 0;

	if (download_handler_hit) {
	    current_steps = (current_image_nr * 2 * _steps_for_one_image) + percent;
	} else {
	    current_steps = (current_image_nr * _steps_for_one_image) + percent;
	}

	OverallProgressHandler ("deploying_images", current_steps);
    }

    _last_download_progress = percent;

    return true;
}

integer _last_progress = -1;
string _last_image_id = nil;

void SetOneImageProgress (integer current_progress) {
    map <string, any> current_image = ImageInstallation::GetCurrentImageDetails();
    integer max_progress = current_image["max_progress"]:0;

    boolean another_image = false;

    // another file than the previous one
    if (current_image["file"]:"" != _last_image_id) {
	another_image = true;
	_last_image_id = current_image["file"]:"";
	_last_download_progress = -1;
	_last_progress = -1;
    }

    if (max_progress == nil || max_progress == 0) {
	y2milestone ("Can't find max_progress: %1", current_image);
	return;
    }

    // current progress 0 - 100
    integer x_progress = (100 * current_progress / max_progress);
    if (x_progress > 100) x_progress = 100;

    // reset the label
    if (x_progress == 0) {
	string current_image_name = current_image["name"]:"";

	if (current_image_name == "") {
	    current_image_name = _("Deploying image...");
	} else {
	    current_image_name = sformat (_("Deploying image %1..."), current_image_name);
	}

	if (another_image == true) {
	    // one image done (another than the previous one)
	    // BNC #442286
	    SlideShow::SubProgressStart( current_image_name );
	    SlideShow::AppendMessageToInstLog( current_image_name );
	} else {
	    y2warning ("The same image name again: %1 (100 * %2 / %3)", current_image_name, current_progress, max_progress);
	}
    }

    // set current step
    if (x_progress > _last_progress) {
	SlideShow::SubProgress( x_progress, nil );
	_last_progress = x_progress;
	integer current_image_nr = current_image["image_nr"]:0;
	integer current_steps = 0;

	if (download_handler_hit) {
	    current_steps = ((current_image_nr * 2 + 1) * _steps_for_one_image) + x_progress;
	} else {
	    current_steps = (current_image_nr * _steps_for_one_image) + x_progress;
	}

	OverallProgressHandler ("deploying_images", current_steps);
    }
}

void RunPackageManager () {
    y2milestone ("--- running the package manager ---");
    PackagesUI::RunPackageSelector ($["mode":`summaryMode]);
    y2milestone ("--- running the package manager ---");
}

ImageInstallation::SetDeployTarImageProgress (SetOneImageProgress);
ImageInstallation::SetDownloadTarImageProgress (MyProgressDownloadHandler);
ImageInstallation::SetStartDownloadImageProgress (MyStartDownloadHandler);
ImageInstallation::SetOverallDeployingProgress (OverallProgressHandler);

ImageInstallation::AdjustProgressLayout ("deploying_images", (_steps_for_one_image * size (images)), _("Deploying Images..."));

/*
Wizard::SetContents (
    _("Deploying Installation Images"),
    `VBox (
	`ProgressBar (
	    `id ("one_image"),
	    _("Initializing..."),
	    100,
	    0
	),
	`ProgressBar (
	    `id ("deploying_progress"),
	    _("Deploying Images..."),
	    100,
	    0
	)
    ),
    // TRANSLATORS: help idi#1
    _("<p>System images are being deployed. Please wait...</p>") +

    // TRANSLATORS: help idi#2
    _("<p>Installation images are part of the installation media.</p>") +

    // TRANSLATORS: help idi#3
    _("<p>Installation from images is faster than installation from RPM packages
because it does not need to interact with a RPM database, locks etc.
One of the images also contains the joint RPM database and other metadata.</p>
") +

    // TRANSLATORS: help idi#4
    _("<p>If there is no direct access to installation images,
the installation program has to download them first before they are deployed.</p>
"),
    false, false
);
*/

// Stores all states of resolvables
ImageInstallation::StoreAllChanges();

// Reset libzypp
Pkg::TargetFinish ();

Wizard::SetTitleIcon ("yast-inst-mode");

// Set where the images will be downloaded
SourceManager::InstInitSourceMoveDownloadArea();

// Deploy the images
boolean dep_ret = ImageInstallation::DeployImages (images, Installation::destdir, nil);
y2milestone ("DeployImages returned: %1", dep_ret);

// BNC #444209
// false == error
if (dep_ret == false) {
    Report::Error (_("Deploying from images has failed.
Aborting the installation..."));
    y2milestone ("Aborting...");
    return `abort;
// nil   == aborted
} else if (dep_ret == nil) {
    y2milestone ("Aborting...");
    return `abort;
}

y2milestone ("Target image for package selector prepared");

// Load the libzypp state from the system (with images deployed)
PackageCallbacks::RegisterEmptyProgressCallbacks();
Pkg::TargetInitialize (Installation::destdir);
Pkg::TargetLoad ();
PackageCallbacks::RestorePreviousProgressCallbacks();

// Restore the states stored by StoreAllChanges()
if (ImageInstallation::RestoreAllChanges() != true) {
    y2warning ("Aborting...");
    return `abort;
}

// BNC #436842 - debug feature in control file
if (ProductFeatures::GetBooleanFeature("globals", "debug_deploying") == true) {
    // TRANSLATORS: pop-up message
    Report::Message (_("Debugging has been turned on.
YaST will open a package manager for you to check the current status of packages."));
    RunPackageManager();
}

// bnc #395030
// Use less memory
ImageInstallation::FreeInternalVariables();

return `next;

}

ACC SHELL 2018