# Copyright (c) 2006, 2007 - 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.pm
# - provides driver engine for MakeInitialRamFS API.
# -----------------------------------------------------------------------------
package OpenSLX::MakeInitRamFS::Engine;
use strict;
use warnings;
use File::Find;
use File::Path;
use OpenSLX::Basics;
use OpenSLX::Utils;
################################################################################
### interface methods
################################################################################
sub new
{
my $class = shift;
my $params = shift || {};
checkParams($params, {
'attrs' => '!',
'export-name' => '!',
'export-uri' => '!',
'initramfs' => '!',
'kernel-version' => '!',
'plugins' => '!',
'root-path' => '!',
'slx-version' => '!',
'system-name' => '!',
} );
my $self = $params;
if ($self->{'system-name'} =~ m{^([^\-]+)-([^:\-]+)}) {
$self->{'distro-name'} = $1;
$self->{'distro-ver'} = $2;
}
return bless $self, $class;
}
sub execute
{
my $self = shift;
$self->_setupBuildPath();
$self->_addRequiredFSMods();
$self->_writeInitramfsSetup();
$self->_copyDistroSpecificFiles();
$self->_copyInitramfsFiles();
# foreach my $plugin (@{$self->{'plugin-instances'}}) {
# $plugin->specifyInitramfsAttrs($initramfsAttrs);
# }
return;
}
################################################################################
### implementation methods
################################################################################
sub _setupBuildPath
{
my $self = shift;
my $buildPath = "$openslxConfig{'temp-path'}/slx-initramfs";
rmtree($buildPath);
my @stdFolders = qw(
bin
dev
etc
etc/sysconfig
lib
mnt
proc
root
sys
tmp
usr/share
var/lib
var/lib/nfs/state
var/run
);
mkpath([ map { "$buildPath/$_"; } @stdFolders ]);
link '/bin', "$buildPath/sbin";
$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 configuration into one file
my $config = slurpFile("$distroSpecsPath/$distroName/config-default");
$config .= "\n";
$config .= slurpFile("$distroSpecsPath/$distroName/config-$distroVer");
spitFile("$self->{'build-path'}/etc/sysconfig/config");
# concatenate default- and distro-specific functions into one file
my $functions = slurpFile("$distroSpecsPath/$distroName/functions-default");
$functions .= "\n";
$functions
.= slurpFile("$distroSpecsPath/$distroName/functions-$distroVer");
spitFile("$self->{'build-path'}/etc/distro-functions");
my $defaultsPath = "$distroSpecsPath/$distroName/files-default";
slxsystem("cp -a $defaultsPath $self->{'build-path'}/etc/sysconfig/files");
return 1;
}
sub _copyInitramfsFiles
{
my $self = shift;
my $initramfsPath = "$openslxConfig{'base-path'}/share/initramfs";
find(
{
wanted => sub {
my $len = length($initramfsPath);
my $relName
= length($File::Find::name) > $len
? substr($File::Find::name, $len+1)
: '';
my $file = followLink($File::Find::name);
if (-d) {
mkpath("$self->{'build-path'}/$relName");
} elsif (qx{file $file} =~ m{ELF}) {
slxsystem("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',
'COMETCEXCL' => "XF86Config*\nissue*\nmtab*\nfstab*\n",
'KERNVER' => $self->{'kernel-version'},
);
$text =~ s{\@\@\@([^\@]+)\@\@\@}{
if (!exists $macro{$1}) {
warn "unknown macro \@\@\@$1\@\@\@ found in $File::Find::name";
'';
} else {
$macro{$1};
}
}eogms;
# force sh shebang over to ash
$text =~ s{^#!\s*/bin/sh}{#!/bin/ash};
spitFile("$self->{'build-path'}/$relName", $text);
}
},
no_chdir => 1,
},
$initramfsPath
);
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;
}
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} || '',
'rootfs' => $self->{'export-uri'} || '',
};
my $content = "# attributes set by slxconfig-demuxer:\n";
foreach my $attr (keys %$initramfsAttrs) {
$content .= qq[$attr="$initramfsAttrs->{$attr}"\n];
}
spitFile("$self->{'build-path'}/etc/initramfs-setup", $content);
return;
}
sub _writeSlxSystemConf
{
my $self = shift;
# generate slxsystem.conf file with variables that are needed
# in stage3 init.
# TODO: either put this stuff in 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
spitFile("$self->{'build-path'}/etc/sysconfig/slxsystem.conf", $slxConf);
return;
}
1;
################################################################################
=pod
=head1 NAME
OpenSLX::MakeInitRamFS::Engine
=head1 SYNOPSIS
=head1 DESCRIPTION
...
=cut