summaryrefslogtreecommitdiffstats
path: root/src/boot-env/OpenSLX/MakeInitRamFS/Engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/boot-env/OpenSLX/MakeInitRamFS/Engine')
-rw-r--r--src/boot-env/OpenSLX/MakeInitRamFS/Engine/Base.pm453
-rw-r--r--src/boot-env/OpenSLX/MakeInitRamFS/Engine/PBS.pm42
-rw-r--r--src/boot-env/OpenSLX/MakeInitRamFS/Engine/Preboot.pm143
-rw-r--r--src/boot-env/OpenSLX/MakeInitRamFS/Engine/SlxBoot.pm264
4 files changed, 902 insertions, 0 deletions
diff --git a/src/boot-env/OpenSLX/MakeInitRamFS/Engine/Base.pm b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/Base.pm
new file mode 100644
index 00000000..b09543dc
--- /dev/null
+++ b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/Base.pm
@@ -0,0 +1,453 @@
+# Copyright (c) 2006..2010 - OpenSLX GmbH
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# MakeInitialRamFS::Engine::Base.pm
+# - provides basic driver engine for MakeInitialRamFS API.
+# -----------------------------------------------------------------------------
+package OpenSLX::MakeInitRamFS::Engine::Base;
+
+use strict;
+use warnings;
+use Switch;
+
+use File::Basename;
+use POSIX qw(strftime);
+
+use OpenSLX::Basics;
+use OpenSLX::LibScanner;
+use OpenSLX::OSPlugin::Roster;
+use OpenSLX::Utils;
+
+################################################################################
+### interface methods
+################################################################################
+sub new
+{
+ my $class = shift;
+ my $params = shift || {};
+
+ checkParams($params, {
+ 'attrs' => '!',
+ 'debug-level' => '?',
+ 'export-name' => '!',
+ 'export-uri' => '!',
+ 'initramfs' => '!',
+ 'kernel-params' => '!',
+ 'kernel-version' => '!',
+ 'plugins' => '!',
+ 'root-path' => '!',
+ 'slx-version' => '!',
+ 'system-name' => '!',
+ 'preboot-id' => '?',
+ 'boot-uri' => '?',
+ } );
+
+ my $self = $params;
+
+ $self->{'system-name'} =~ m{^([^\-]+)-([^:\-]+)}
+ or die "unable to extract distro-info from $self->{'system-name'}!";
+
+ $self->{'distro-name'} = lc($1);
+ $self->{'distro-ver'} = $2;
+
+ my $fullDistroName = lc($1) . '-' . $2;
+
+ $self->{distro} = loadDistroModule({
+ distroName => $fullDistroName,
+ distroScope => 'OpenSLX::MakeInitRamFS::Distro',
+ });
+ if (!$self->{distro}) {
+ die _tr(
+ 'unable to load any MakeInitRamFS::Distro module for system %s!',
+ $self->{'system-name'}
+ );
+ }
+
+ $self->{'lib-scanner'}
+ = OpenSLX::LibScanner->new({ 'root-path' => $self->{'root-path'} });
+
+ $self->{'suggested-kernel-modules'} = [];
+ $self->{'filtered-kernel-modules'} = [];
+
+ return bless $self, $class;
+}
+
+sub execute
+{
+ my $self = shift;
+ my $dryRun = shift;
+
+ $self->_collectCMDs();
+
+ vlog(1, _tr("creating initramfs '%s' ...", $self->{'initramfs'}));
+ $self->_executeCMDs() unless $dryRun;
+
+ return;
+}
+
+sub haveKernelParam
+{
+ my $self = shift;
+ my $param = shift;
+
+ return ref $param eq 'Regexp'
+ ? grep { $_ =~ $param } @{ $self->{'kernel-params'} }
+ : grep { $_ eq $param } @{ $self->{'kernel-params'} };
+}
+
+sub addKernelParams
+{
+ my $self = shift;
+
+ push @{ $self->{'kernel-params'} }, @_;
+
+ return;
+}
+
+sub kernelParams
+{
+ my $self = shift;
+
+ return @{ $self->{'kernel-params'} };
+}
+
+sub addKernelModules
+{
+ my $self = shift;
+
+ push @{ $self->{'suggested-kernel-modules'} }, @_;
+
+ return;
+}
+
+################################################################################
+### implementation methods
+################################################################################
+sub _executeCMDs
+{
+ my $self = shift;
+
+ foreach my $cmd (@{$self->{CMDs}}) {
+ if (ref($cmd) eq 'HASH') {
+ vlog(3, "writing $cmd->{file}");
+ my $flags = defined $cmd->{mode} ? { mode => $cmd->{mode} } : undef;
+ spitFile($cmd->{file}, $cmd->{content}, $flags);
+ }
+ else {
+ vlog(3, "executing: $cmd");
+ if (slxsystem($cmd)) {
+ die _tr(
+ "unable to execute shell-cmd\n\t%s", $cmd
+ );
+ }
+ }
+ }
+
+ return;
+}
+
+sub addCMD
+{
+ my $self = shift;
+ my $cmd = shift;
+
+ push @{$self->{CMDs}}, $cmd;
+
+ return;
+}
+
+sub _findBinary
+{
+ my $self = shift;
+ my $binary = shift;
+
+ my @binDirs = qw(
+ bin sbin usr/bin usr/sbin usr/local/bin usr/local/sbin usr/bin/X11
+ );
+ foreach my $binDir (@binDirs) {
+ my $binPath = "$self->{'root-path'}/$binDir/$binary";
+ return $binPath if -f $binPath && -x $binPath;
+ }
+
+ return;
+}
+
+sub _addFilteredKernelModules
+{
+ my $self = shift;
+
+ push @{ $self->{'filtered-kernel-modules'} }, @_;
+
+ return;
+}
+
+sub _copyKernelModules
+{
+ my $self = shift;
+
+ # read modules.dep and use it to determine module dependencies
+ my $sourcePath = "$self->{'root-path'}/lib/modules/$self->{'kernel-version'}";
+ my @modulesDep = slurpFile("$sourcePath/modules.dep")
+ or die _tr('unable to open %s!', "$sourcePath/modules.dep");
+ my (%dependentModules, %modulePath, %modulesToBeCopied);
+ foreach my $modulesDep (@modulesDep) {
+ next if $modulesDep !~ m{^(.+?)/([^/]+)\.ko:\s*(.*?)\s*$};
+ my $path = $1;
+ if (substr($path, 0, 5) ne '/lib/') {
+ # some distros (e.g. ubuntu-9) use a local path instead of an
+ # absolute path, we need to make it absolute:
+ $path = "/lib/modules/$self->{'kernel-version'}/$path";
+ }
+ my $module = $2;
+ my $dependentsList = $3;
+ my $fullModulePath = "$path/$module.ko";
+ $modulePath{$module} = [] if !exists $modulePath{$module};
+ push @{$modulePath{$module}}, $fullModulePath;
+ $dependentModules{$fullModulePath} = [
+ map {
+ if (substr($_, 0, 5) ne '/lib/') {
+ # some distros (e.g. ubuntu-9) use a local path instead of an
+ # absolute path, we need to make it absolute:
+ $_ = "/lib/modules/$self->{'kernel-version'}/$_";
+ }
+ $_;
+ }
+ split ' ', $dependentsList
+ ];
+ }
+
+ my $targetPath
+ = "$self->{'build-path'}/lib/modules/$self->{'kernel-version'}";
+ $self->addCMD("mkdir -p $targetPath");
+ $self->addCMD("cp -p $sourcePath/modules.* $targetPath/");
+
+ # add a couple of kernel modules that we expect to be used in stage3
+ # (some of these modules do not exist on all distros, so they will be
+ # filtered out again by the respective distro object):
+ my @kernelModules = qw(
+ af_packet unix hid hid-bright usbhid uhci-hcd ohci-hcd vesafb fbcon
+ );
+ push @kernelModules, @{ $self->{'suggested-kernel-modules'} };
+
+ push @kernelModules, split ' ', $self->{attrs}->{ramfs_fsmods};
+ push @kernelModules, split ' ', $self->{attrs}->{ramfs_miscmods};
+ push @kernelModules, split ' ', $self->{attrs}->{ramfs_nicmods};
+
+ if ($self->{attrs}->{ramfs_nicmods} =~ m{virtio}i) {
+ push @kernelModules, qw( virtio_pci virtio_net );
+ }
+
+ # a function that determines dependent modules recursively
+ my $addDependentsSub;
+ $addDependentsSub = sub {
+ my $modulePath = shift;
+ foreach my $dependentModule (@{$dependentModules{$modulePath}}) {
+ next if $modulesToBeCopied{$dependentModule};
+ $modulesToBeCopied{$dependentModule} = 1;
+ $addDependentsSub->($dependentModule);
+ }
+ };
+
+ # start with the given kernel modules (names) and build a list of all
+ # required modules
+ foreach my $kernelModule (@kernelModules) {
+ if (!$modulePath{$kernelModule}) {
+ if (! grep { $_ eq $kernelModule }
+ @{ $self->{'filtered-kernel-modules'} }
+ ) {
+ warn _tr(
+ 'kernel module "%s" not found (in modules.dep)',
+ $kernelModule
+ );
+ }
+ }
+ foreach my $modulePath (@{$modulePath{$kernelModule}}) {
+ next if $modulesToBeCopied{$modulePath};
+ $modulesToBeCopied{$modulePath} = 1;
+ $addDependentsSub->($modulePath);
+ }
+ }
+
+ # build a list of required firmwares out of the list of modules - not
+ # totally optimal
+ my @firmwares;
+ $self->addCMD("mkdir -p $self->{'build-path'}/lib/firmware/$self->{'kernel-version'}");
+ foreach my $moduleToBeCopied(%modulesToBeCopied) {
+ $moduleToBeCopied =~ /.*\/(.*?)$/;
+ # implies usage of switch
+ vlog(1,$1);
+ switch ($1){
+ case "e100.ko" {push @firmwares, split ' ', "e100"}
+ case "iwlwifi" {
+ push @firmwares, split ' ',
+ "iwlwifi-3945-1.ucode iwlwifi-3945-2.ucode iwlwifi-4965-1.ucode iwlwifi-4965-2.ucode iwlwifi-5000-1.ucode"
+ }
+ case "tg3.ko" {push @firmwares, split ' ', "tigon/"}
+ # modules required for graphic adaptors (bootsplash, Xorg)
+ case "radeon.ko" {push @firmwares, split ' ', "radeon/"}
+ case "mga.ko" {push @firmwares, split ' ', "matrox/"}
+ case "r128.ko" {push @firmwares, split ' ', "r128/"}
+ }
+ }
+ # copy all the firmwares that we think are required
+ foreach my $firmwareToBeCopied (@firmwares) {
+ my $source = followLink(
+ "$self->{'root-path'}/lib/firmware/$self->{'kernel-version'}/$firmwareToBeCopied", $self->{'root-path'}
+ );
+ if (-e $source){
+ my $target = "$self->{'build-path'}/lib/firmware/";
+
+ $self->addCMD("cp -pr --dereference $source $target");
+ } else {
+ vlog(3,"unable to find $source for copying purposes");
+ }
+ }
+
+ # copy all the modules that we think are required
+ foreach my $moduleToBeCopied (sort keys %modulesToBeCopied) {
+ my $source = followLink(
+ "$self->{'root-path'}$moduleToBeCopied", $self->{'root-path'}
+ );
+ my $target = "$self->{'build-path'}$moduleToBeCopied";
+ my ($targetdir) = $target =~m/(.*\/).*$/;
+ vlog(5,"Trying to make directory: $targetdir");
+ $self->addCMD("mkdir -p $targetdir");
+ $self->addCMD("cp -p --dereference $source $target");
+ }
+
+ return;
+}
+
+sub _platformSpecificFileFor
+{
+ my $self = shift;
+ my $binary = shift;
+
+ if ($self->{'system-name'} =~ m{64}) {
+ return $binary . '.x86_64';
+ }
+ return $binary . '.i586';
+}
+
+sub _writeInitramfsSetup
+{
+ my $self = shift;
+
+ # generate initramfs-setup file containing attributes that are
+ # relevant for the initramfs only (before there's a root-FS):
+ my $initramfsAttrs = {
+ 'host_name' => 'slx-client', # just to have something at all
+ 'ramfs_fsmods' => $self->{attrs}->{ramfs_fsmods} || '',
+ 'ramfs_miscmods' => $self->{attrs}->{ramfs_miscmods} || '',
+ 'ramfs_nicmods' => $self->{attrs}->{ramfs_nicmods} || '',
+ 'ramfs_firmmods' => $self->{attrs}->{ramfs_firmmods} || '',
+ 'rootfs' => $self->{'export-uri'} || '',
+ 'hw_local_disk' => $self->{attrs}->{hw_local_disk} || '',
+ };
+ my $content = "# attributes set by slxconfig-demuxer:\n";
+ foreach my $attr (keys %$initramfsAttrs) {
+ $content .= qq[$attr="$initramfsAttrs->{$attr}"\n];
+ }
+ $self->addCMD( {
+ file => "$self->{'build-path'}/etc/initramfs-setup",
+ content => $content
+ } );
+
+ return;
+}
+
+sub _writeSlxSystemConf
+{
+ my $self = shift;
+
+ # generate slxsystem.conf file with variables that are needed
+ # in stage3 init.
+ # TODO: either put this stuff into initramfs-setup or find another solution
+ my $date = strftime("%d.%m.%Y", localtime);
+ my $slxConf = unshiftHereDoc(<<" End-of-Here");
+ slxconf_date=$date
+ slxconf_kernver=$self->{'kernel-version'}
+ slxconf_listnwmod="$self->{attrs}->{ramfs_nicmods}"
+ slxconf_distro_name=$self->{'distro-name'}
+ slxconf_distro_ver=$self->{'distro-ver'}
+ slxconf_system_name=$self->{'system-name'}
+ slxconf_slxver="$self->{'slx-version'}"
+ End-of-Here
+ $self->addCMD( {
+ file => "$self->{'build-path'}/etc/slxsystem.conf",
+ content => $slxConf
+ } );
+
+ # check if default directories available and copy them to /etc
+ my $defaultDirConfig = "$self->{'root-path'}/etc/opt/openslx/openslx.conf";
+ my $configTargetPath = "$self->{'build-path'}/etc";
+ #my $defaultConfVer = slurpFile("$defaultDirConfig");
+ #my $actConfVer = "Version 0.2";
+
+ if (-r $defaultDirConfig) {
+ $self->addCMD("cp -p $defaultDirConfig $configTargetPath/");
+# if ($defaultConfVer =~ m{$actConfVer}) {
+# warn _tr(
+# "Your version of default dir file (openslx.conf) is to old!\n".
+# "Eventually the system won't work.\n" .
+# "Please run install, update or clone of this system again!\n");
+# }
+ } else {
+ die _tr(
+ "No default directories defined!\n" .
+ "Please run install, update or clone of this system again!\n");
+ }
+
+ return;
+}
+
+sub _calloutToPlugins
+{
+ my $self = shift;
+
+ my $pluginInitdPath = "$self->{'build-path'}/etc/plugin-init.d";
+ my $initHooksPath = "$self->{'build-path'}/etc/init-hooks";
+ $self->addCMD("mkdir -p $pluginInitdPath $initHooksPath");
+
+ foreach my $pluginName (@{$self->{'plugins'}}) {
+ my $plugin = OpenSLX::OSPlugin::Roster->getPlugin($pluginName);
+ next if !$plugin;
+
+ # create a hash only containing the attributes relating to the
+ # current plugin
+ my $allAttrs = $self->{attrs};
+ my %pluginAttrs;
+ for my $attrName (grep { $_ =~ m{^${pluginName}::} } keys %$allAttrs) {
+ $pluginAttrs{$attrName} = $allAttrs->{$attrName};
+ }
+
+ # let plugin setup itself in the initramfs
+ $plugin->setupPluginInInitramfs(\%pluginAttrs, $self);
+ }
+ return;
+}
+
+sub _createInitRamFS
+{
+ my $self = shift;
+
+ my $buildPath = $self->{'build-path'};
+ $self->addCMD("chroot $buildPath ldconfig");
+ $self->addCMD(
+ "cd $buildPath "
+ . "&& find . "
+ . "| cpio -H newc --quiet --create "
+ . "| gzip -9 >$self->{initramfs}"
+ );
+
+ return;
+}
+
+1;
diff --git a/src/boot-env/OpenSLX/MakeInitRamFS/Engine/PBS.pm b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/PBS.pm
new file mode 100644
index 00000000..571057ad
--- /dev/null
+++ b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/PBS.pm
@@ -0,0 +1,42 @@
+# Copyright (c) 2009 - OpenSLX GmbH
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# MakeInitialRamFS::Engine::PBS.pm
+# - provides driver engine for MakeInitialRamFS API, implementing the
+# base of all preboot variants.
+# -----------------------------------------------------------------------------
+package OpenSLX::MakeInitRamFS::Engine::PBS;
+
+use strict;
+use warnings;
+
+use base qw(OpenSLX::MakeInitRamFS::Engine::Preboot);
+
+use OpenSLX::Basics;
+use OpenSLX::Utils;
+
+sub _copyPrebootSpecificFiles
+{
+ my $self = shift;
+
+ # write secondary rootfs-layer (including init) on top of base layer
+ my $prebootRootfs
+ = "$openslxConfig{'base-path'}/share/boot-env/preboot/uclib-rootfs";
+ $self->addCMD("rsync -rlpt $prebootRootfs/ $self->{'build-path'}");
+
+ # overwrite preboot defaults
+ my $pbsRootfs
+ = "$openslxConfig{'base-path'}/share/boot-env/pbs/uclib-rootfs";
+ $self->addCMD("rsync -rlpt $pbsRootfs/ $self->{'build-path'}");
+
+ return 1;
+}
+
+1;
diff --git a/src/boot-env/OpenSLX/MakeInitRamFS/Engine/Preboot.pm b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/Preboot.pm
new file mode 100644
index 00000000..aecfd00f
--- /dev/null
+++ b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/Preboot.pm
@@ -0,0 +1,143 @@
+# Copyright (c) 2006-2008 - OpenSLX GmbH
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# MakeInitialRamFS::Engine::Preboot.pm
+# - provides driver engine for MakeInitialRamFS API, implementing the
+# base of all preboot variants.
+# -----------------------------------------------------------------------------
+package OpenSLX::MakeInitRamFS::Engine::Preboot;
+
+use strict;
+use warnings;
+
+use base qw(OpenSLX::MakeInitRamFS::Engine::Base);
+
+use OpenSLX::Basics;
+use OpenSLX::Utils;
+
+################################################################################
+### implementation methods
+################################################################################
+sub _collectCMDs
+{
+ my $self = shift;
+
+ $self->{CMDs} = [];
+
+ $self->_setupBuildPath();
+
+ $self->_writeInitramfsSetup();
+ $self->_writeSlxSystemConf();
+
+ $self->_copyUclibcRootfs();
+ $self->_copyPrebootSpecificFiles();
+
+ $self->{distro}->applyChanges($self);
+
+ $self->_copyKernelModules();
+
+ $self->_createInitRamFS();
+
+ return;
+}
+
+sub _setupBuildPath
+{
+ my $self = shift;
+
+ my $buildPath = "$openslxConfig{'temp-path'}/slx-initramfs";
+ $self->addCMD("rm -rf $buildPath");
+
+ my @stdFolders = qw(
+ bin
+ dev
+ etc
+ lib
+ mnt
+ proc
+ root
+ sbin
+ sys
+ tmp
+ var/lib
+ var/run
+ );
+ $self->addCMD(
+ 'mkdir -p ' . join(' ', map { "$buildPath/$_"; } @stdFolders)
+ );
+
+ $self->{'build-path'} = $buildPath;
+
+ return;
+}
+
+sub _writeInitramfsSetup
+{
+ my $self = shift;
+
+ # generate initramfs-setup file containing attributes that are
+ # relevant for the initramfs only (before there's a root-FS) -
+ # this override adds the name of the client such that the booting
+ # system has an ID to use for accessing the corresponding boot environment
+ # on the server
+ my $initramfsAttrs = {
+ 'host_name' => 'slx-client', # just to have something at all
+ 'ramfs_miscmods' => $self->{attrs}->{ramfs_miscmods} || '',
+ 'ramfs_nicmods' => $self->{attrs}->{ramfs_nicmods} || '',
+ 'ramfs_firmmods' => $self->{attrs}->{ramfs_firmmods} || '',
+ 'preboot_id' => $self->{'preboot-id'} || '',
+ 'boot_uri' => $self->{'boot-uri'} || '',
+ };
+ my $content = "# attributes set by slxconfig-demuxer:\n";
+ foreach my $attr (keys %$initramfsAttrs) {
+ $content .= qq[$attr="$initramfsAttrs->{$attr}"\n];
+ }
+ $self->addCMD( {
+ file => "$self->{'build-path'}/etc/initramfs-setup",
+ content => $content
+ } );
+
+ return;
+}
+
+sub _copyUclibcRootfs
+{
+ my $self = shift;
+
+ my $uclibcRootfs = "$openslxConfig{'base-path'}/share/uclib-rootfs";
+
+ my @excludes = qw(
+ );
+
+ # exclude strace unless this system is in debug mode
+ if (!$self->{'debug-level'}) {
+ push @excludes, 'strace';
+ }
+
+ my $exclOpts = join ' ', map { "--exclude $_" } @excludes;
+
+ $self->addCMD("rsync $exclOpts -rlpt $uclibcRootfs/ $self->{'build-path'}");
+
+ return 1;
+}
+
+sub _copyPrebootSpecificFiles
+{
+ my $self = shift;
+
+ # write secondary rootfs-layer (including init) on top of base layer
+ my $prebootRootfs
+ = "$openslxConfig{'base-path'}/share/boot-env/preboot/uclib-rootfs";
+ $self->addCMD("rsync -rlpt $prebootRootfs/ $self->{'build-path'}");
+
+ return 1;
+}
+
+1;
diff --git a/src/boot-env/OpenSLX/MakeInitRamFS/Engine/SlxBoot.pm b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/SlxBoot.pm
new file mode 100644
index 00000000..1334c444
--- /dev/null
+++ b/src/boot-env/OpenSLX/MakeInitRamFS/Engine/SlxBoot.pm
@@ -0,0 +1,264 @@
+# Copyright (c) 2006-2008 - OpenSLX GmbH
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# MakeInitialRamFS::Engine::SlxBoot.pm
+# - provides driver engine for MakeInitialRamFS API, implementing the
+# standard slx boot behaviour (i.e. booting a system remotely).
+# -----------------------------------------------------------------------------
+package OpenSLX::MakeInitRamFS::Engine::SlxBoot;
+
+use strict;
+use warnings;
+
+use base qw(OpenSLX::MakeInitRamFS::Engine::Base);
+
+use File::Find;
+
+use OpenSLX::Basics;
+use OpenSLX::Utils;
+
+################################################################################
+### implementation methods
+################################################################################
+sub _collectCMDs
+{
+ my $self = shift;
+
+ $self->{CMDs} = [];
+
+ $self->_setupBuildPath();
+
+ $self->_addRequiredFSMods();
+
+ $self->_writeInitramfsSetup();
+ $self->_writeSlxSystemConf();
+
+ $self->_copyUclibcRootfs();
+ $self->_copyHwinfo();
+ $self->_copyDistroSpecificFiles();
+ $self->_copyInitramfsFiles();
+
+ $self->_copyPreAndPostinitFiles();
+
+ $self->_calloutToPlugins();
+
+ $self->{distro}->applyChanges($self);
+
+ $self->_copyKernelModules();
+
+ $self->_createInitRamFS();
+
+ return;
+}
+
+sub _setupBuildPath
+{
+ my $self = shift;
+
+ my $buildPath = "$openslxConfig{'temp-path'}/slx-initramfs";
+ $self->addCMD("rm -rf $buildPath");
+
+ my @stdFolders = qw(
+ bin
+ dev
+ etc
+ etc/init-hooks
+ lib
+ mnt
+ proc
+ root
+ sbin
+ sys
+ tmp
+ usr/share
+ var/lib
+ var/lib/nfs/state
+ var/run
+ );
+ $self->addCMD(
+ 'mkdir -p ' . join(' ', map { "$buildPath/$_"; } @stdFolders)
+ );
+
+ $self->{'build-path'} = $buildPath;
+
+ return;
+}
+
+sub _copyDistroSpecificFiles
+{
+ my $self = shift;
+
+ my $distroSpecsPath = "$openslxConfig{'base-path'}/share/distro-specs";
+
+ my $distroName = $self->{'distro-name'};
+ my $distroVer = $self->{'distro-ver'};
+
+ # concatenate default- and distro-specific functions into one file
+ my $functions = slurpFile("$distroSpecsPath/$distroName/functions-default");
+ $functions .= "\n";
+ $functions .= slurpFile(
+ "$distroSpecsPath/$distroName/functions-$distroVer",
+ { failIfMissing => 0 }
+ );
+ $self->addCMD( {
+ file => "$self->{'build-path'}/etc/distro-functions",
+ content => $functions,
+ } );
+
+ return 1;
+}
+
+sub _copyUclibcRootfs
+{
+ my $self = shift;
+
+ my $uclibcRootfs = "$openslxConfig{'base-path'}/share/uclib-rootfs";
+
+ my @excludes = qw(
+ dialog
+ kexec
+ libcurses.so*
+ libncurses.so*
+ mconf
+ );
+
+ # exclude strace unless this system is in debug mode
+ if (!$self->{'debug-level'}) {
+ push @excludes, 'strace';
+ }
+
+ my $exclOpts = join ' ', map { "--exclude $_" } @excludes;
+
+ $self->addCMD("rsync $exclOpts -rlpt $uclibcRootfs/ $self->{'build-path'}");
+
+ return 1;
+}
+
+sub _copyHwinfo
+{
+ my $self = shift;
+
+ my $baseDir = "$openslxConfig{'base-path'}/share/ramfstools/hwinfo";
+
+ my $version = $self->{distro}->determineMatchingHwinfoVersion(
+ $self->{'distro-ver'}
+ );
+
+ # copy db modifications
+ $self->addCMD("tar xfz $baseDir/db/hwinfo.db.tgz -C $self->{'build-path'}/");
+
+ $self->addCMD("cp $baseDir/bin/hwinfo-$version $self->{'build-path'}/usr/bin/hwinfo");
+ my $libHD = "libhd.so.$version";
+ $self->addCMD("cp $baseDir/lib/$libHD $self->{'build-path'}/usr/lib");
+ my $libName = $libHD;
+ while($libName =~ s{\.\d+$}{}g) {
+ $self->addCMD("ln -sf $libHD $self->{'build-path'}/usr/lib/$libName");
+ }
+
+ return 1;
+}
+
+sub _copyInitramfsFiles
+{
+ my $self = shift;
+
+ my $initramfsPath = "$openslxConfig{'base-path'}/share/initramfs";
+
+ find(
+ {
+ wanted => sub {
+ my $len = length($initramfsPath);
+ my $file = $File::Find::name;
+ my $relName = length($file) > $len ? substr($file, $len+1) : '';
+ if (-d) {
+ $self->addCMD("mkdir -p $self->{'build-path'}/$relName");
+ } elsif (-l $file) {
+ my $target = readlink $file;
+ $self->addCMD(
+ "ln -sf $target $self->{'build-path'}/$relName"
+ );
+ } elsif (qx{file $file} =~ m{ELF}) {
+ $self->addCMD(
+ "cp -p $file $self->{'build-path'}/$relName"
+ );
+ } else {
+ my $text = slurpFile($file, { 'io-layer' => 'bytes' } );
+
+ # replace macros
+ # TODO: find out what these mean and maybe find a
+ # different, better solution
+ my %macro = (
+ 'COMDIRINDXS' => '/tmp/scratch /var/lib/nobody',
+ # keep serverip as it is (it is handled by init itself)
+ 'serverip' => '@@@serverip@@@',
+ );
+ $text =~ s{\@\@\@([^\@]+)\@\@\@}{
+ if (!exists $macro{$1}) {
+ warn _tr(
+ 'unknown macro @@@%s@@@ found in %s',
+ $1, $File::Find::name
+ );
+ '';
+ } else {
+ $macro{$1};
+ }
+ }eogms;
+
+ # force shebang with ash (deprecated with new busybox)
+ #$text =~ s{\A#!\s*/bin/.+?$}{#!/bin/ash}ms;
+
+ $self->addCMD( {
+ file => "$self->{'build-path'}/$relName",
+ content => $text,
+ mode => (-x $file ? 0755 : undef),
+ } );
+ }
+ },
+ no_chdir => 1,
+ },
+ $initramfsPath
+ );
+
+ return;
+}
+
+sub _copyPreAndPostinitFiles
+{
+ my $self = shift;
+
+ foreach my $cfg (
+ 'default/initramfs/preinit.local',
+ "$self->{'system-name'}/initramfs/preinit.local",
+ 'default/initramfs/postinit.local',
+ "$self->{'system-name'}/initramfs/postinit.local"
+ ) {
+ my $cfgPath = "$openslxConfig{'private-path'}/config/$cfg";
+ next if !-f $cfgPath;
+ $self->addCMD("cp -p $cfgPath $self->{'build-path'}/bin/");
+ }
+ return;
+}
+
+sub _addRequiredFSMods
+{
+ my $self = shift;
+
+ my $osExportEngine = instantiateClass("OpenSLX::OSExport::Engine");
+ $osExportEngine->initializeFromExisting($self->{'export-name'});
+ my $fsMods = $self->{attrs}->{ramfs_fsmods} || '';
+ foreach my $fsMod ($osExportEngine->requiredFSMods()) {
+ $fsMods .= " $fsMod" if $fsMods !~ m{$fsMod};
+ }
+ $self->{attrs}->{ramfs_fsmods} = $fsMods;
+
+ return;
+}
+
+1;