From 416ab8a37f1b07dc9f6c0fb3ff1a8ff2036510b5 Mon Sep 17 00:00:00 2001 From: Sebastian Schmelzer Date: Thu, 2 Sep 2010 17:50:49 +0200 Subject: change dir structure --- src/installer/OpenSLX/OSSetup/Distro/Base.pm | 371 +++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 src/installer/OpenSLX/OSSetup/Distro/Base.pm (limited to 'src/installer/OpenSLX/OSSetup/Distro/Base.pm') diff --git a/src/installer/OpenSLX/OSSetup/Distro/Base.pm b/src/installer/OpenSLX/OSSetup/Distro/Base.pm new file mode 100644 index 00000000..c356e6d9 --- /dev/null +++ b/src/installer/OpenSLX/OSSetup/Distro/Base.pm @@ -0,0 +1,371 @@ +# 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/ +# ----------------------------------------------------------------------------- +# OSSetup/Distro/Base.pm +# - provides base implementation of the OSSetup Distro API. +# ----------------------------------------------------------------------------- +package OpenSLX::OSSetup::Distro::Base; + +use strict; +use warnings; + +our $VERSION = 1.01; # API-version . implementation-version + +use Fcntl qw(:DEFAULT :flock); +use File::Basename; +use File::Path; +use Scalar::Util qw( weaken ); + +use OpenSLX::Basics; +use OpenSLX::Utils; + +################################################################################ +### interface methods +################################################################################ +sub new +{ + confess "Creating OpenSLX::OSSetup::System::Base-objects directly makes no sense!"; +} + +sub initialize +{ + my $self = shift; + my $engine = shift; + + $self->{'engine'} = $engine; + weaken($self->{'engine'}); + # avoid circular reference between distro and its engine + + if ($engine->{'distro-name'} =~ m[x86_64]) { + # be careful to only try installing 64-bit systems if actually + # running on a 64-bit host, as otherwise we are going to fail later, + # anyway: + my $arch = `uname -m`; + if ($?) { + die _tr("unable to determine architecture of host system (%s)\n", $!); + } + if ($arch !~ m[x86_64]) { + die _tr("you can't install a 64-bit system on a 32-bit host, sorry!\n"); + } + } + + $self->{'stage1a-binaries'} = { + "$openslxConfig{'base-path'}/share/busybox/busybox" => 'bin', + }; + + $self->{'stage1b-faked-files'} = [ + '/etc/mtab', + ]; + + $self->{'stage1c-faked-files'} = [ + ]; + + $self->{'clone-filter'} = " + + /var + - /var/tmp/* + - /var/spool/* + - /var/cache/apt/archives/*.deb + - /var/cache/apt/archives/lock + - /var/cache/apt/archives/partial/* + + /var/cache/apt/archives/partial + - /var/tmp/* + + /var/tmp/apt + - /var/opt/openslx + - /var/lib/vmware + - /var/lib/ntp/* + - /var/run/* + + /var/run/screen + - /var/log/* + + /var/log/apt + - /usr/lib/vmware/modules/* + + /usr + - /tmp/* + + /tmp + - /sys/* + + /sys + + /sbin + - /root/* + + /root + - /proc/* + + /proc + - /opt/openslx + + /opt + - /media/* + + /media + - /mnt/* + + /mnt + + /lib64 + - /lib/ld-uClibc* + + /lib + - /home/* + + /home + - /etc/vmware/* + + /etc/vmware + - /etc/vmware-installer + - /etc/grub* + - /etc/shadow* + - /etc/samba/secrets.tdb + - /etc/resolv.conf.* + - /etc/opt/openslx + + /etc/opt/openslx + - /etc/exports* + - /etc/X11/xorg.* + - /etc/X11/XF86* + + /etc + - /dev/* + + /dev + + /boot + + /bin + - /* + - .svn + - .git + - .*.cmd + - *~ + - *lost+found* + - *.old + - *.bak + "; + + return; +} + +sub fixPrerequiredFiles +{ +} + +sub startSession +{ + my $self = shift; + my $osDir = shift; + + # setup a fixed locale environment to avoid warnings about unset locales + # (like for instance shown by apt-get) + $ENV{LC_ALL} = 'POSIX'; + + # ensure that a couple of important devices exist + my %devInfo = ( + mem => { type => 'c', major => '1', minor => '1' }, + null => { type => 'c', major => '1', minor => '3' }, + zero => { type => 'c', major => '1', minor => '5' }, + random => { type => 'c', major => '1', minor => '8' }, + urandom => { type => 'c', major => '1', minor => '9' }, + kmsg => { type => 'c', major => '1', minor => '11' }, + tty => { type => 'c', major => '5', minor => '0' }, + console => { type => 'c', major => '5', minor => '1' }, + ptmx => { type => 'c', major => '5', minor => '2' }, + ); + if (!-e "$osDir/dev" && !mkpath("$osDir/dev")) { + die _tr("unable to create folder '%s' (%s)\n", "$osDir/dev", $!); + } + foreach my $dev (keys %devInfo) { + my $info = $devInfo{$dev}; + if (!-e "$osDir//dev/$dev") { + if (slxsystem( + "mknod $osDir//dev/$dev $info->{type} $info->{major} $info->{minor}" + )) { + croak(_tr("unable to create dev-node '%s'! (%s)", $dev, $!)); + } + } + } + + # enter chroot jail + chrootInto($osDir); + $ENV{PATH} = join(':', @{$self->getDefaultPathList()}); + + # mount /proc (if we have 'mount' available) + if (qx{which mount 2>/dev/null}) { + if (!-e '/proc' && !mkpath('/proc')) { + die _tr("unable to create folder '%s' (%s)\n", "$osDir/proc", $!); + } + if (slxsystem("mount -t proc proc '/proc'")) { + warn _tr("unable to mount '%s' (%s)\n", "$osDir/proc", $!); + } + if (!-e '/dev/pts' && !mkpath('/dev/pts')) { + die _tr("unable to create folder '%s' (%s)\n", "$osDir/dev/pts", $!); + } + if (slxsystem("mount -t devpts devpts '/dev/pts'")) { + warn _tr("unable to mount '%s' (%s)\n", "$osDir/dev/pts", $!); + } + } + + return 1; +} + +sub finishSession +{ + my $self = shift; + + # umount /proc, /dev/pts (if we have 'umount' available) + if (qx{which umount 2>/dev/null}) { + if (slxsystem("umount /proc")) { + warn _tr("unable to umount '%s' (%s)\n", "/proc", $!); + } + if (slxsystem("umount /dev/pts")) { + warn _tr("unable to umount '%s' (%s)\n", "/dev/pts", $!); + } + } + + return 1; +} + +sub getDefaultPathList +{ + my $self = shift; + + return [ qw( + /sbin + /usr/sbin + /usr/local/sbin + /usr/local/bin + /usr/bin + /bin + /usr/bin/X11 + /usr/X11R6/bin + /opt/kde3/bin + /opt/gnome/bin + ) ]; +} + +sub updateDistroConfig +{ + if (slxsystem("ldconfig")) { + die _tr("unable to run ldconfig (%s)", $!); + } +} + +sub pickKernelFile +{ + my $self = shift; + my $kernelPath = shift; + + my $newestKernelFile; + my $newestKernelFileSortKey = ''; + my $kernelPattern = '{vmlinuz,kernel-genkernel-x86}-*'; + foreach my $kernelFile (glob("$kernelPath/$kernelPattern")) { + next unless $kernelFile =~ m{ + (?:vmlinuz|x86)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?-(\d+(?:\.\d+)?) + }x; + my $sortKey + = sprintf("%02d.%02d.%02d.%02d-%2.1f", $1, $2, $3, $4||0, $5); + if ($newestKernelFileSortKey lt $sortKey) { + $newestKernelFile = $kernelFile; + $newestKernelFileSortKey = $sortKey; + } + } + + if (!defined $newestKernelFile) { + die _tr("unable to pick a kernel-file from path '%s'!", $kernelPath); + } + return $newestKernelFile; +} + +sub preSystemInstallationHook +{ +} + +sub postSystemInstallationHook +{ +} + +sub setPasswordForUser +{ + my $self = shift; + my $username = shift; + my $password = shift; + + my $hashedPassword = $self->hashPassword($password); + + my $writePasswordFunction = sub { + # now read, change and write shadow-file in atomic manner: + my $shadowFile = '/etc/shadow'; + if (!-e $shadowFile) { + spitFile( $shadowFile, ''); + } + slxsystem("cp -r $shadowFile $shadowFile~"); + my $shadowFH; + open($shadowFH, '+<', $shadowFile) + or croak _tr("could not open file '%s'! (%s)", $shadowFile, $!); + flock($shadowFH, LOCK_EX) + or croak _tr("could not lock file '%s'! (%s)", $shadowFile, $!); + my $lastChanged = int(time()/24/60/60); + my $newEntry + = "$username:$hashedPassword:$lastChanged:0:99999:7:::"; + my $content = do { local $/; <$shadowFH> }; + if ($content =~ m{^$username:}ims) { + $content =~ s{^$username:.+?$}{$newEntry}ms; + } else { + $content .= "$newEntry\n"; + } + seek($shadowFH, 0, 0) + or croak _tr("could not seek file '%s'! (%s)", $shadowFile, $!); + print $shadowFH $content + or croak _tr("could not write to file '%s'! (%s)", $shadowFile, $!); + close($shadowFH) + or croak _tr("could not close file '%s'! (%s)", $shadowFile, $!); + unlink "$shadowFile~"; + }; + $self->{engine}->callChrootedFunctionForVendorOS($writePasswordFunction); +} + +sub hashPassword +{ + my $self = shift; + my $password = shift; + + my $busyboxBin = $self->{engine}->busyboxBinary(); + my $hashedPassword = qx{$busyboxBin cryptpw -a md5 $password}; + chomp $hashedPassword; + + return $hashedPassword; +} + +1; +################################################################################ + +=pod + +=head1 NAME + +OpenSLX::OSSetup::System::Base - the base class for all OSSetup backends + +=head1 SYNOPSIS + + package OpenSLX::OSSetup::coolnewOS; + + use vars qw(@ISA $VERSION); + @ISA = ('OpenSLX::OSSetup::Base'); + $VERSION = 1.01; + + use coolnewOS; + + sub new + { + my $class = shift; + my $self = {}; + return bless $self, $class; + } + + # override all methods of OpenSLX::OSSetup::Base in order to implement + # a full OS-setup backend + ... + +I> + +=head1 DESCRIPTION + +This class defines the OSSetup interface for the OpenSLX. + +Aim of the OSSetup abstraction is to make it possible to install a large set +of different operating systems transparently. + +... + +=cut -- cgit v1.2.3-55-g7522