ACC SHELL
/**
* Module: inst_kickoff.ycp
*
* Authors: Arvin Schnell <arvin@suse.de>
*
* Purpose: Do various tasks before starting with installation of rpms.
*
* $Id: inst_kickoff.ycp 61962 2010-05-06 11:45:24Z jsrain $
*
*/
{
textdomain "packager";
import "Mode";
import "Stage";
import "Linuxrc";
import "Installation";
import "Popup";
import "Directory";
import "ModuleLoading";
import "Initrd";
import "Kernel";
import "Arch";
import "FileUtils";
import "String";
void AcpiToInitrd () {
if (! (Arch::i386 () || Arch::x86_64 () || Arch::ia64 ()))
return;
foreach (string m, ["processor", "thermal", "fan"], {
Initrd::AddModule (m, "");
});
}
// add xen paravirtualized drivers to initrd if thery are selected for installation
void XenPVToInitrd()
{
// is any xen-kmp-* package selected?
if (Pkg::IsSelected("xen-kmp-default")
|| Pkg::IsSelected("xen-kmp-smp")
|| Pkg::IsSelected("xen-kmp-pae")
|| Pkg::IsSelected("xen-kmp-bigsmp")
|| Pkg::IsSelected("xen-kmp-kdump"))
{
// add disk driver
Initrd::AddModule ("xen-vbd", "");
// add network driver
Initrd::AddModule ("xen-vnif", "");
y2milestone("Added Xen PV drivers to initrd, configured drivers: %1", Initrd::ListModules());
}
else
{
y2milestone("No xen-kmp-* package is selected for installation, skipping XEN PV driver installation");
}
}
void HyperVPVToInitrd() {
// is any hyper-v-kmp-* package selected?
if (Pkg::IsSelected("hyper-v-kmp-default")
|| Pkg::IsSelected("hyper-v-kmp-smp")
|| Pkg::IsSelected("hyper-v-kmp-pae")
|| Pkg::IsSelected("hyper-v-kmp-bigsmp")
|| Pkg::IsSelected("hyper-v-kmp-kdump"))
{
// add modules to initrd
Initrd::AddModule ("hv_blkvsc", "");
Initrd::AddModule ("hv_netvsc", "");
Initrd::AddModule ("hv_storvsc", "");
Initrd::AddModule ("hv_vmbus", "");
y2milestone("Added HyperV PV drivers to initrd, configured drivers: %1", Initrd::ListModules());
// it also need to be added to MODULES_LOADED_ON_BOOT
Kernel::AddModuleToLoad ("hv_storvsc");
Kernel::AddModuleToLoad ("hv_netvsc");
y2milestone ("Added hv_storvsc and hv_netvsc to modules loaded on boot");
}
else
{
y2milestone("No hyper-v-kmp-* package is selected for installation, skipping HyperV PV driver installation");
}
}
/**
* Write a fake mtab to the target system since some %post scripts might
* need it.
*/
define void fake_mtab () ``{
y2milestone("Copying /etc/mtab to the target system...");
string tmpdir = (string) SCR::Read (.target.tmpdir);
string mtabname = "/etc/mtab";
string mtab = (string) WFM::Read(.local.string, mtabname);
// remove non-existing mount points
list<string> mtab_lines = splitstring(mtab, "\n");
mtab_lines = filter(string mtab_line, mtab_lines,
{
// parse the line, get the directory name
string dir = regexpsub(mtab_line, "^[^ \t]+[ \t]+([^ \t]*)[ \t]+", "\\1");
if (dir != nil)
{
// check if the directory exists
y2debug("Checking directory %1", dir);
integer exit_status = (integer)WFM::Execute(.local.bash, sformat("ls -d '%1'", String::Quote(dir)));
if (exit_status != 0)
{
y2warning("Excluding nonexisting directory %1", dir);
return false;
}
}
return true;
}
);
// join back the lines
mtab = mergestring(mtab_lines, "\n");
y2milestone("Target /etc/mtab file: %1", mtab);
SCR::Write(.target.string, tmpdir + "/mtab", mtab);
SCR::Execute (.target.bash, "/bin/cat "
+ "'" + String::Quote (tmpdir + "/mtab") + "'"
+ " | /bin/sed \"s: " + Installation::destdir
+ "/: /:\"| /bin/sed \"s: " + Installation::destdir
+ ": /:\" "
+ "> '" + String::Quote (Installation::destdir) + "'" + mtabname);
}
/**
* Remove some old junk.
*/
define void remove_stuff () ``{
// remove old junk, script is in yast2-update
SCR::Execute (.target.bash, Directory::ybindir + "/remove_junk " +
"'" + String::Quote (Installation::destdir) + "'");
// possibly remove /usr/share/info/dir
if (!Pkg::TargetFileHasOwner ("/usr/share/info/dir"))
{
SCR::Execute (.target.remove, Installation::destdir + "/usr/share/info/dir");
}
}
/**
* Handle the backup.
*/
define void backup_stuff () {
if (Installation::update_backup_modified)
{
Pkg::CreateBackups (true);
Pkg::SetBackupPath (Installation::update_backup_path);
SCR::Write (.target.string, Installation::destdir + "/var/lib/YaST2/backup_path",
Installation::update_backup_path);
}
else
{
Pkg::CreateBackups (false);
SCR::Execute (.target.remove, Installation::destdir + "/var/lib/YaST2/backup_path");
}
// Removing all old backups
if (Installation::update_remove_old_backups)
{
y2milestone ("Removing old backups *-*-*.tar.{gz,bz2} from %1", Installation::update_backup_path);
SCR::Execute (.target.bash, "cd '" + String::Quote (Installation::destdir) + "'; " +
"/bin/rm -f " + Installation::update_backup_path + "/*-*-*.tar.{gz,bz2}");
}
// timestamp
string date = timestring ("%Y%m%d", time(), false);
if (true)
{
y2milestone ("Creating backup of %1", Directory::logdir);
string filename = "";
integer num = 0;
while (num < 42)
{
filename = Installation::update_backup_path + "/YaST2-" + date + "-" +
sformat ("%1", num) + ".tar.gz";
if (SCR::Read (.target.size, Installation::destdir + filename) == -1)
break;
num = num + 1;
}
if (SCR::Execute (.target.bash, "cd '" + String::Quote (Installation::destdir) + "'; " +
"/bin/tar czf ." + filename + " " + "var/log/YaST2") != 0)
{
y2error ("backup of %1 to %2 failed", Directory::logdir, filename);
// an error popup
Popup::Error (sformat (_("Backup of %1 failed. See %2 for details."),
Directory::logdir, Directory::logdir + "/y2log"));
}
else
{
SCR::Execute (.target.bash, "cd '" + String::Quote (Installation::destdir) + "'; " +
"/bin/rm -rf var/log/YaST2/*");
}
}
if (Installation::update_backup_sysconfig)
{
// backup /etc/sysconfig
if (SCR::Read (.target.size, Installation::destdir + "/etc/sysconfig") > 0)
{
y2milestone ("backup of /etc/sysconfig");
string filename = "";
integer num = 0;
while (num < 42)
{
filename = Installation::update_backup_path + "/etc.sysconfig-" + date + "-" +
sformat ("%1", num) + ".tar.gz";
if (SCR::Read (.target.size, Installation::destdir + filename) == -1)
break;
num = num + 1;
}
if (SCR::Execute (.target.bash, "cd '" + String::Quote (Installation::destdir) + "'; " +
"/bin/tar czf ." + filename + " " + "etc/sysconfig") != 0)
{
y2error ("backup of %1 to %2 failed", "/etc/sysconfig", filename);
// an error popup
Popup::Error (sformat (_("Backup of %1 failed. See %2 for details."),
"/etc/sysconfig", Directory::logdir + "/y2log"));
}
}
// backup of /etc/rc.config*
else if (SCR::Read (.target.size, Installation::destdir + "/etc/rc.config") > 0 &&
SCR::Read (.target.size, Installation::destdir + "/etc/rc.config.d") > 0)
{
y2milestone ("backup of /etc/rc.config.d");
string filename = "";
integer num = 0;
while (num < 42)
{
filename = Installation::update_backup_path + "/etc.rc.config-" + date + "-" +
sformat ("%1", num) + ".tar.gz";
if (SCR::Read (.target.size, Installation::destdir + filename) == -1)
break;
num = num + 1;
}
if (SCR::Execute (.target.bash, "cd '" + String::Quote (Installation::destdir) + "'; " +
"/bin/tar czf ." + filename + " " +
"etc/rc.config etc/rc.config.d") != 0)
{
y2error ("backup of %1 to %2 failed", "/etc/rc.config", filename);
// an error popup
Popup::Error (sformat (_("Backup of %1 failed. See %2 for details."),
"/etc/rc.config", Directory::logdir + "/y2log"));
}
}
}
// Backup /etc/pam.d/ unconditionally
// bnc #393066
if (Mode::update()) {
string filename = "";
integer num = 0;
while (num < 42) {
filename = Installation::update_backup_path + "/etc.pam.d-" + date + "-" + sformat ("%1", num) + ".tar.gz";
// avoid from filename conflicts
if (! FileUtils::Exists (Installation::destdir + filename))
break;
num = num + 1;
}
string what_to_backup = "etc/pam.d etc/security etc/securetty etc/environment";
// enters the Installation::destdir
// and creates backup of etc/pam.d directory in Installation::update_backup_path
string cmd = sformat (
"cd '%1'; /bin/tar --ignore-failed-read -czf '.%2' %3",
String::Quote (Installation::destdir),
String::Quote (filename),
what_to_backup
);
y2milestone ("Creating backup of %1 in %2", what_to_backup, Installation::destdir + filename);
if (SCR::Execute (.target.bash, cmd) != 0) {
y2error ("backup command failed: %1", cmd);
// an error popup
Popup::Error (sformat (_("Backup of %1 failed. See %2 for details."),
"/etc/pam.d", Directory::logdir + "/y2log"));
}
}
}
/**
* Create /etc/mdadm.conf if it does not exist and it's needed
* bugs: #169710 and #146304
*/
void createmdadm () {
string mdamd_configfile = Installation::destdir + "/etc/mdadm.conf";
// File exists, no need to create it
if (FileUtils::Exists(mdamd_configfile)) {
y2milestone("File /etc/mdadm.conf exists, skipping creation...");
return;
}
// get the current raid configuration
map out = (map) SCR::Execute (.target.bash_output,
"chroot '" + String::Quote (Installation::destdir) + "' " +
"mdadm -Ds");
if (out["exit"]:-1 != 0) {
y2error ("Error occurred while getting raid configuration: %1", out);
return;
}
// There's no current raid configuration, no reason to create that file, bug #169710
if (out["stdout"]:"" == "") {
y2milestone("No raid is currently configured, skipping file creation...");
return;
}
// File format defined in bug #146304
string mdadm_content = "DEV partitions\n" +
out["stdout"]:"" + "\n";
y2milestone ("/etc/mdadm.conf doesn't exist, creating it");
if (! (boolean) SCR::Write (.target.string, mdamd_configfile, mdadm_content)) {
y2error ("Error occurred while creating /etc/mdadm.conf with content '%1'", mdadm_content);
}
}
/**
* Load all network modules. The package sysconfig requires this during
* update.
*/
define void load_network_modules ()
{
list <map> cards = (list <map>) SCR::Read (.probe.netcard);
foreach (map card, cards,
{
list <map> drivers = card["drivers"]:[];
boolean one_active = false;
foreach (map driver, drivers,
{
if (driver["active"]:false)
one_active = true;
});
if (!one_active)
{
string name = drivers[0, "modules", 0, 0]:"";
if (name != "")
ModuleLoading::Load (name, "", "Linux", "",
Linuxrc::manual (), true);
}
});
}
/**
* Calls a local command and returns if successful
*/
define boolean LocalCommand (string command) {
map cmd = (map) WFM::Execute (.local.bash_output, command);
y2milestone ("Command %1 returned: %2", command, cmd);
if (cmd["exit"]:-1 == 0) {
return true;
} else {
if (cmd["stderr"]:"" != "") y2error ("Error: %1", cmd["stderr"]:"");
return false;
}
}
if (!Mode::update ()) {
// fake mtab for rpm post-scripts
fake_mtab ();
}
// Feature #301903, bugzilla #244937
if (Mode::update()) {
// "/" means updating the running system, bugzilla #246389
if (Installation::destdir == "/") {
// When upgrading system, remove devs.rpm just from rpm database
LocalCommand (
"/bin/rpm -q 'devs' && /bin/rpm --nodeps --justdb -e 'devs'"
);
// normal upgrade
} else {
// When upgrading system, remove devs.rpm if installed
LocalCommand (sformat (
"/bin/rpm --root '%1' -q 'devs' && /bin/rpm --nodeps --root '%1' -e 'devs'",
String::Quote (Installation::destdir)
));
// Mount (bind) the current /dev/ to the /installed_system/dev/
LocalCommand (sformat (
"/bin/rm -rf '%1/dev/' && /bin/mkdir -p '%1/dev/' && /bin/mount -v --bind '/dev/' '%1/dev/'",
String::Quote (Installation::destdir)
));
}
}
// installation, for instance...
if (!Mode::update ())
{
// make some directories
SCR::Execute(.target.mkdir, Installation::destdir + "/etc");
SCR::Execute(.target.mkdir, Installation::destdir + Directory::logdir);
if (Installation::dirinstall_installing_into_dir) {
string template_dir= "/var/adm/fillup-templates";
// hack 'pre-req' cyclic dependency between bash, aaa_base, and perl
foreach (string filename, ["passwd", "group", "shadow"], {
string filename_copy_to = sformat ("%1/etc/%2", Installation::destdir, filename);
if (FileUtils::Exists (filename_copy_to)) {
y2milestone ("File %1 exists, not rewriting", filename_copy_to);
} else {
filename = sformat ("%1/%2.aaa_base", template_dir, filename);
y2milestone ("Copying %1 to %2", filename, filename_copy_to);
SCR::Execute (.target.bash,
sformat (
// BNC 441829: /etc/shadow can be symlink
// copying the file contents
// preserving the original file access permissions
"cp --dereference --copy-contents '%1' '%2'",
String::Quote (filename), String::Quote (filename_copy_to)
)
);
}
});
} else {
y2milestone ("Copying users/groups information from the inst-sys to %1", Installation::destdir);
// @see bnc #381227
// @see bnc #440430
// files might have been copied already from image
foreach (string filename, ["/etc/passwd", "/etc/shadow", "/etc/group"], {
string filename_copy_to = sformat ("%1/%2", Installation::destdir, filename);
if (FileUtils::Exists (filename_copy_to)) {
y2milestone ("File %1 exists, not rewriting", filename_copy_to);
} else {
y2milestone ("Copying %1 to %2", filename, filename_copy_to);
SCR::Execute (.target.bash,
sformat (
// BNC 441829: /etc/shadow can be symlink
// copying the file contents
// preserving the original file access permissions
"cp --dereference --copy-contents '%1' '%2'",
String::Quote (filename), String::Quote (filename_copy_to)
)
);
}
});
}
// fake mtab
fake_mtab ();
AcpiToInitrd ();
// F#302660: System installation and upgrade workflow: kernel %post
// calling ins_bootloader write all config files for bootloader
// if (Stage::initial ())
// {
// call it always, it handles installation mode inside
WFM::CallFunction ("inst_bootloader", WFM::Args ());
// }
}
else
{
if (Stage::normal())
{
import "Kernel";
string kernel = Kernel::ComputePackage ();
Kernel::SetInformAboutKernelChange(Pkg::IsSelected (kernel));
SCR::Execute (.target.mkdir, Installation::destdir + Installation::update_backup_path);
backup_stuff ();
createmdadm();
}
else
{
// disable all repositories at the target
Pkg::TargetDisableSources();
// make some directories
SCR::Execute (.target.mkdir, Installation::destdir + Directory::logdir);
SCR::Execute (.target.mkdir, Installation::destdir + Installation::update_backup_path);
// backup some stuff
backup_stuff ();
// remove some stuff
// do not remove when updating running system (#49608)
remove_stuff ();
// set update mode to yes
SCR::Write(.target.string, Installation::destdir + "/var/lib/YaST2/update_mode", "YES");
SCR::Execute (.target.remove, Installation::destdir + "/var/lib/YaST/update.inf");
// check passwd and group of target
SCR::Execute (.target.bash, "/usr/lib/YaST2/bin/update_users_groups " +
"'" + String::Quote (Installation::destdir) + "'");
// create /etc/mdadm.conf if it does not exist
createmdadm();
// load all network modules
load_network_modules ();
// perform actions needed by various bootloaders before packages
// get updated
// Bootloader::PreUpdate ();
// -- this function call does NOTHING!
}
AcpiToInitrd ();
}
// add Xen and HyperV PV drivers to initrd
XenPVToInitrd();
HyperVPVToInitrd();
if (Stage::initial ())
{
// see bug 20627 for original purpose of this line,
// bug 172149 why it was moved here
SCR::Execute (.target.bash, "/bin/echo \"/etc/nothing\" >/proc/sys/kernel/modprobe");
}
return `next;
}
ACC SHELL 2018