summaryrefslogtreecommitdiffstats
path: root/lib/OpenSLX/Utils.pm
diff options
context:
space:
mode:
authorSebastian Schmelzer2010-09-02 17:50:49 +0200
committerSebastian Schmelzer2010-09-02 17:50:49 +0200
commit416ab8a37f1b07dc9f6c0fb3ff1a8ff2036510b5 (patch)
tree4715f7d742fec50931017f38fe6ff0a89d4ceccc /lib/OpenSLX/Utils.pm
parentFix for the problem reported on the list (sed filter forgotten for the (diff)
downloadcore-416ab8a37f1b07dc9f6c0fb3ff1a8ff2036510b5.tar.gz
core-416ab8a37f1b07dc9f6c0fb3ff1a8ff2036510b5.tar.xz
core-416ab8a37f1b07dc9f6c0fb3ff1a8ff2036510b5.zip
change dir structure
Diffstat (limited to 'lib/OpenSLX/Utils.pm')
-rw-r--r--lib/OpenSLX/Utils.pm701
1 files changed, 0 insertions, 701 deletions
diff --git a/lib/OpenSLX/Utils.pm b/lib/OpenSLX/Utils.pm
deleted file mode 100644
index 6e722c00..00000000
--- a/lib/OpenSLX/Utils.pm
+++ /dev/null
@@ -1,701 +0,0 @@
-# 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/
-# -----------------------------------------------------------------------------
-# Utils.pm
-# - provides utility functions for OpenSLX
-# -----------------------------------------------------------------------------
-package OpenSLX::Utils;
-
-use strict;
-use warnings;
-
-use vars qw(@ISA @EXPORT $VERSION);
-
-use Exporter;
-$VERSION = 1.01;
-@ISA = qw(Exporter);
-
-@EXPORT = qw(
- copyFile fakeFile linkFile
- copyBinaryWithRequiredLibs
- slurpFile spitFile appendFile
- followLink
- unshiftHereDoc
- string2Array trim
- chrootInto
- mergeHash
- getFQDN
- readPassword
- hostIs64Bit
- getAvailableBusyboxApplets
- grabLock
- pathOf
- isInPath
-);
-
-=head1 NAME
-
-OpenSLX::Utils - provides utility functions for OpenSLX.
-
-=head1 DESCRIPTION
-
-This module exports utility functions, which are expected to be used all across
-OpenSLX.
-
-=cut
-
-use Fcntl qw(:DEFAULT :flock);
-use File::Basename;
-use File::Path;
-use Socket;
-use Sys::Hostname;
-use Term::ReadLine;
-
-use OpenSLX::Basics;
-use OpenSLX::ScopedResource;
-
-=head1 PUBLIC FUNCTIONS
-
-=over
-
-=item B<copyFile($fileName, $targetDir, $targetFileName)>
-
-Copies the file specified by I<$fileName> to the folder I<$targetDir>,
-preserving the permissions and optionally renaming it to I<$targetFileName>
-during the process.
-
-If I<$targetDir> does not exist yet, it will be created.
-
-=cut
-
-sub copyFile
-{
- my $fileName = shift || croak 'need to pass in a fileName!';
- my $targetDir = shift || croak 'need to pass in target dir!';
- my $targetFileName = shift || '';
-
- mkpath($targetDir) unless -d $targetDir;
- my $target = "$targetDir/$targetFileName";
- vlog(2, _tr("copying '%s' to '%s'", $fileName, $target));
- if (system("cp -p $fileName $target")) {
- croak(
- _tr(
- "unable to copy file '%s' to dir '%s' (%s)",
- $fileName, $target, $!
- )
- );
- }
- return;
-}
-
-=item B<fakeFile($fullPath)>
-
-Creates the (empty) file I<$fullPath> unless it already exists.
-
-If the parent directory of I<$fullPath> does not exist yet, it will be created.
-
-=cut
-
-sub fakeFile
-{
- my $fullPath = shift || croak 'need to pass in full path!';
-
- return if -e $fullPath;
-
- my $targetDir = dirname($fullPath);
- mkpath($targetDir) unless -d $targetDir;
-
- if (system("touch", $fullPath)) {
- croak(_tr("unable to create file '%s' (%s)", $fullPath, $!));
- }
- return;
-}
-
-=item B<linkFile($linkTarget, $linkName)>
-
-Creates the link I<$linkName> that points to I<$linkTarget>.
-
-If the directory where the new link shall live does not exist yet, it will be
-created.
-
-=cut
-
-sub linkFile
-{
- my $linkTarget = shift || croak 'need to pass in link target!';
- my $linkName = shift || croak 'need to pass in link name!';
-
- my $targetDir = dirname($linkName);
- mkpath($targetDir) unless -d $targetDir;
- if (system("ln -sfn $linkTarget $linkName")) {
- croak(
- _tr(
- "unable to create link '%s' to '%s' (%s)",
- $linkName, $linkTarget, $!
- )
- );
- }
- return;
-}
-
-=item B<slurpFile($fileName, $flags)>
-
-Reads the file specified by <$fileName> and returns the contents.
-
-The optional hash-ref I<$flags> supports the following entries:
-
-=over
-
-=item failIfMissing
-
-Specifies what shall happen if the file does not exist: die (failIfMissing == 1)
-or return an empty string (failIfMissing == 0). Defaults to 1.
-
-=item io-layer
-
-Specifies the Perl-IO-layer that shall be applied to the file (defaults to
-'utf8').
-
-=back
-
-=cut
-
-sub slurpFile
-{
- my $fileName = shift || confess 'need to pass in fileName!';
- my $flags = shift || {};
-
- checkParams($flags, {
- 'failIfMissing' => '?',
- 'io-layer' => '?',
- });
- my $failIfMissing
- = exists $flags->{failIfMissing} ? $flags->{failIfMissing} : 1;
- my $ioLayer = $flags->{'io-layer'} || 'utf8';
-
- my $fh;
- if (!open($fh, "<:$ioLayer", $fileName)) {
- return '' unless $failIfMissing;
- croak _tr("could not open file '%s' for reading! (%s)", $fileName, $!);
- }
- if (wantarray()) {
- my @content = <$fh>;
- close($fh)
- or croak _tr("unable to close file '%s' (%s)\n", $fileName, $!);
- return @content;
- }
- else {
- local $/;
- my $content = <$fh>;
- close($fh)
- or croak _tr("unable to close file '%s' (%s)\n", $fileName, $!);
- return $content;
- }
-}
-
-=item B<spitFile($fileName, $content, $flags)>
-
-Writes the given I<$content> to the file specified by <$fileName>, creating
-the file (and any missing directories) if it does not exist yet.
-
-The optional hash-ref I<$flags> supports the following entries:
-
-=over
-
-=item io-layer
-
-Specifies the Perl-IO-layer that shall be applied to the file (defaults to
-'utf8').
-
-=item mode
-
-Specifies the file mode that shall be applied to the file (via chmod).
-
-=back
-
-=cut
-
-sub spitFile
-{
- my $fileName = shift || croak 'need to pass in a fileName!';
- my $content = shift || '';
- my $flags = shift || {};
-
- checkParams($flags, {
- 'io-layer' => '?',
- 'mode' => '?',
- });
- my $ioLayer = $flags->{'io-layer'} || 'utf8';
-
- my $targetDir = dirname($fileName);
- mkpath($targetDir) unless -d $targetDir;
-
- my $fh;
- open($fh, ">:$ioLayer", $fileName)
- or croak _tr("unable to create file '%s' (%s)\n", $fileName, $!);
- print $fh $content
- or croak _tr("unable to print to file '%s' (%s)\n", $fileName, $!);
- close($fh)
- or croak _tr("unable to close file '%s' (%s)\n", $fileName, $!);
- if (defined $flags->{mode}) {
- chmod $flags->{mode}, $fileName;
- }
- return;
-}
-
-=item B<appendFile($fileName, $content, $flags)>
-
-Appends the given I<$content> to the file specified by <$fileName>, creating
-the file (and any missing directories) if it does not exist yet.
-
-The optional hash-ref I<$flags> supports the following entries:
-
-=over
-
-=item io-layer
-
-Specifies the Perl-IO-layer that shall be applied to the file (defaults to
-'utf8').
-
-=back
-
-=cut
-
-sub appendFile
-{
- my $fileName = shift || croak 'need to pass in a fileName!';
- my $content = shift;
- my $flags = shift || {};
-
- checkParams($flags, {
- 'io-layer' => '?',
- });
- my $ioLayer = $flags->{'io-layer'} || 'utf8';
-
- my $targetDir = dirname($fileName);
- mkpath($targetDir) unless -d $targetDir;
-
- my $fh;
- open($fh, ">>:$ioLayer", $fileName)
- or croak _tr("unable to create file '%s' (%s)\n", $fileName, $!);
- print $fh $content
- or croak _tr("unable to print to file '%s' (%s)\n", $fileName, $!);
- close($fh)
- or croak _tr("unable to close file '%s' (%s)\n", $fileName, $!);
- return;
-}
-
-=item B<followLink($path, $prefixedPath)>
-
-Deeply traverses the given I<$path> until it no longer contains a link and
-returns the resulting file or directory.
-
-If you pass in a I<$prefixedPath>, each link will be resolved relatively to
-that path (useful for example with respect to chroot-environments).
-
-=cut
-
-sub followLink
-{
- my $path = shift || croak 'need to pass in a path!';
- my $prefixedPath = shift || '';
-
- my $target;
- while (-l "$path") {
- $target = readlink "$path";
- if (substr($target, 0, 1) eq '/') {
- $path = "$prefixedPath$target";
- }
- else {
- $path = $prefixedPath . dirname($path) . '/' . $target;
- }
- }
- return $path;
-}
-
-=item B<copyBinaryWithRequiredLibs($params)>
-
-Copies a binary to a specified folder, taking along all the libraries that
-are required by this binary.
-
-The hash-ref I<$params> supports the following entries:
-
-=over
-
-=item binary
-
-The full path to the binary that shall be copied.
-
-=item targetFolder
-
-The full path to the folder where the binary shall be copied to.
-
-=item libTargetFolder
-
-Defines a path relatively to which all required libs will be copied to.
-
-An example: during execution of
-
- copyBinaryWithRequiredLibs({
- binary => '/bin/ls',
- targetFolder => '/tmp/slx-initramfs/bin',
- libTargetFolder => '/tmp/slx-initramfs',
- });
-
-the library C<lib/libc-2.6.1.so> will be copied to
-C</tmp/slx-initramfs/lib/libc-2.6.1.so>.
-
-=item targetName [optional]
-
-If you'd like to rename the binary while copying, you can specify the new name
-in this entry.
-
-=back
-
-=cut
-
-sub copyBinaryWithRequiredLibs {
- my $params = shift;
-
- checkParams($params, {
- 'binary' => '!', # file to copy
- 'targetFolder' => '!', # where file shall be copied to
- 'libTargetFolder' => '!', # base target folder for libs
- 'targetName' => '?', # name of binary in target folder
- });
- copyFile($params->{binary}, $params->{targetFolder}, $params->{targetName});
-
- # determine all required libraries and copy those, too:
- vlog(1, _tr("calling slxldd for $params->{binary}"));
- my $slxlddCmd = "slxldd $params->{binary}";
- vlog(2, "executing: $slxlddCmd");
- my $requiredLibsStr = qx{$slxlddCmd};
- if ($?) {
- die _tr(
- "slxldd couldn't determine the libs required by '%s'! (%s)",
- $params->{binary}, $?
- );
- }
- chomp $requiredLibsStr;
- vlog(2, "slxldd results:\n$requiredLibsStr");
-
- foreach my $lib (split "\n", $requiredLibsStr) {
- my $libDir = dirname($lib);
- my $targetLib = "$params->{libTargetFolder}$libDir";
- next if -e "$targetLib/$lib";
- vlog(3, "copying lib '$lib'");
- copyFile($lib, $targetLib);
- }
- return $requiredLibsStr;
-}
-
-=item B<unshiftHereDoc($content)>
-
-Returns the here-doc (or string) given in I<$content> such that the leading
-whitespace found on the first line will be removed from all lines.
-
-As an example: if you pass in the string
-
- #!/bin/sh
- if [ -n "$be_nice" ]; then
- echo "bummer!" >/etc/passwd
- fi
-
-you will get this:
-
-#!/bin/sh
-if [ -n "$be_nice" ]; then
- echo "bummer!" >/etc/passwd
-fi
-
-=cut
-
-sub unshiftHereDoc
-{
- my $content = shift;
- return $content unless $content =~ m{^(\s+)};
- my $shiftStr = $1;
- $content =~ s[^$shiftStr][]gms;
- return $content;
-}
-
-=item B<string2Array($string)>
-
-Returns the given string split into an array, using newlines as separator.
-
-In the resulting array, empty entries will have been removed and each entry
-will be trimmed of leading or trailing whitespace and comments (lines starting
-with a #).
-
-=cut
-
-sub string2Array
-{
- my $string = shift || '';
-
- my @lines = split m[\n], $string;
- for my $line (@lines) {
- # remove leading and trailing whitespace:
- $line =~ s{^\s*(.*?)\s*$}{$1};
- }
-
- # drop empty lines and comments:
- return grep { length($_) > 0 && $_ !~ m[^\s*#]; } @lines;
-}
-
-=item B<chrootInto($osDir)>
-
-Does a chroot() into the given directory (which is supposed to contain at
-least the fragments of an operating system).
-
-=cut
-
-sub chrootInto
-{
- my $osDir = shift;
-
- vlog(2, "chrooting into $osDir...");
- chdir $osDir
- or die _tr("unable to chdir into '%s' (%s)\n", $osDir, $!);
-
- # ...do chroot
- chroot "."
- or die _tr("unable to chroot into '%s' (%s)\n", $osDir, $!);
- return;
-}
-
-=item B<mergeHash($targetHash, $sourceHash, $fillOnly)>
-
-Deeply copies values from I<$sourceHash> into I<$targetHash>.
-
-If you pass in 1 for I<$fillOnly>, only hash entries that do not exist in
-I<$targetHash> will be copied (C<Merge>-mode), otherwise all values from
-I<$sourceHash> will be copied over (C<Push>-mode).
-
-Returns the resulting I<$targetHash> for convenience.
-
-=cut
-
-sub mergeHash
-{
- my $targetHash = shift;
- my $sourceHash = shift;
- my $fillOnly = shift || 0;
-
- foreach my $key (keys %{$sourceHash}) {
- my $sourceVal = $sourceHash->{$key};
- if (ref($sourceVal) eq 'HASH') {
- if (!exists $targetHash->{$key}) {
- $targetHash->{$key} = {};
- }
- mergeHash($targetHash->{$key}, $sourceVal);
- }
- elsif (ref($sourceVal) eq 'ARRAY') {
- if (!exists $targetHash->{$key}) {
- $targetHash->{$key} = [];
- }
- foreach my $val (@{$sourceHash->{$key}}) {
- my $targetVal = {};
- push @{$targetHash->{$key}}, $targetVal;
- mergeHash($targetVal, $sourceVal);
- }
- }
- else {
- next if $fillOnly && exists $targetHash->{$key};
- $targetHash->{$key} = $sourceVal;
- }
- }
- return $targetHash;
-}
-
-=item B<getFQDN()>
-
-Determines the fully-qualified-domain-name (FQDN) of the computer executing
-this function and returns it.
-
-=cut
-
-sub getFQDN
-{
- my $hostName = hostname();
-
- my $hostAddr = gethostbyname($hostName)
- or die(_tr("unable to get address of host '%s'", $hostName));
- my $FQDN = gethostbyaddr($hostAddr, AF_INET)
- or die(_tr("unable to get dns-name of address '%s'", $hostAddr));
- return $FQDN;
-}
-
-=item B<readPassword($prompt)>
-
-Outputs the given I<$prompt> and then reads a password from the terminal
-(trying to make sure that the characters are not echoed in a readable form).
-
-=cut
-
-sub readPassword
-{
- my $prompt = shift;
-
- my $term = Term::ReadLine->new('slx');
- my $attribs = $term->Attribs;
- $attribs->{redisplay_function} = $attribs->{shadow_redisplay};
-
- return $term->readline($prompt);
-}
-
-=item B<hostIs64Bit()>
-
-Returns 1 if the host (the computer executing this function) is running a
-64-bit OS, 0 if not (i.e. 32-bit).
-
-=cut
-
-sub hostIs64Bit
-{
- my $arch = qx{uname -m};
- return $arch =~ m[64];
-}
-
-=item B<getAvailableBusyboxApplets()>
-
-Returns the list of the applets that is provided by the given busybox binary.
-
-=cut
-
-sub getAvailableBusyboxApplets
-{
- my $busyboxBinary = shift;
-
- my $busyboxHelp = qx{$busyboxBinary --help};
- if ($busyboxHelp !~ m{defined functions:(.+)\z}ims) {
- die "unable to parse busybox --help output:\n$busyboxHelp";
- }
- my $rawAppletList = $1;
- my @busyboxApplets
- = map {
- $_ =~ s{\s+}{}igms;
- $_;
- }
- split m{,}, $rawAppletList;
-
- return @busyboxApplets;
-}
-
-=item grabLock()
-
-=cut
-
-sub grabLock
-{
- my $lockName = shift || die 'you need to pass a lock-name to grabLock()!';
-
- my $lockPath = "$openslxConfig{'private-path'}/locks";
- mkpath($lockPath) unless -e $lockPath;
-
- # drop any trailing slashes from lock name:
- $lockName =~ s{/+$}{};
- my $lockFile = "$lockPath/$lockName";
-
- my $lockFH;
-
- my $lock = OpenSLX::ScopedResource->new({
- name => "lock::$lockName",
- acquire => sub {
- # use a lock-file to implement the actual locking:
- if (-e $lockFile) {
- my $ctime = (stat($lockFile))[10];
- my $now = time();
- if ($now - $ctime > 15 * 60) {
- # existing lock file is older than 15 minutes, we consider
- # that to be a leftover (which shouldn't happen of course)
- # and wipe it:
- unlink $lockFile;
- }
- }
-
- local $| = 1;
- my $waiting;
- while(!(sysopen($lockFH, $lockFile, O_RDWR | O_CREAT | O_EXCL)
- && syswrite($lockFH, getpgrp() . "\n"))) {
- if ($! == 13) {
- die _tr(
- qq[Unable to create lock "%s", giving up!], $lockFile
- );
- } else {
- # check if the lock is owned by our own process group
- # and only block if it isn't (this allows recursive locking)
- my $pgrpOfLock
- = slurpFile($lockFile, { failIfMissing => 0});
- last if $pgrpOfLock && $pgrpOfLock == getpgrp();
-
- # wait for lock to become available
- if (!$waiting) {
- print _tr('waiting for "%s"-lock ', $lockName);
- $waiting = 1;
- }
- else {
- print '.';
- }
- sleep(1);
- }
- }
- print "ok\n" if $waiting;
- 1
- },
- release => sub {
- close($lockFH);
- unlink $lockFile;
- 1
- },
- });
-
- return $lock;
-}
-
-=item B<pathOf()>
-
-Returns the path of a binary it is installed in.
-
-=cut
-
-sub pathOf
-{
- my $binary = shift;
- return qx{which $binary 2>/dev/null};
-}
-
-=item B<isInpath()>
-
-Returns whether a binary is found.
-
-=cut
-
-sub isInPath
-{
- my $binary = shift;
- my $path = pathOf($binary);
-
- return $path ? 1 : 0;
-}
-
-
-sub trim
-{
- my $string = shift;
-
- $string =~ s/^\s+//;
- $string =~ s/\s+$//;
-
- return $string;
-}
-
-
-1;