summaryrefslogtreecommitdiffstats
path: root/src/boot-env/OpenSLX/BootEnvironment/PBS.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/boot-env/OpenSLX/BootEnvironment/PBS.pm')
-rw-r--r--src/boot-env/OpenSLX/BootEnvironment/PBS.pm247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/boot-env/OpenSLX/BootEnvironment/PBS.pm b/src/boot-env/OpenSLX/BootEnvironment/PBS.pm
new file mode 100644
index 00000000..2072884b
--- /dev/null
+++ b/src/boot-env/OpenSLX/BootEnvironment/PBS.pm
@@ -0,0 +1,247 @@
+# Copyright (c) 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/
+# -----------------------------------------------------------------------------
+# BootEnvironment::Preboot.pm
+# - provides general preboot implementation of the BootEnvironment API.
+# -----------------------------------------------------------------------------
+package OpenSLX::BootEnvironment::PBS;
+
+use strict;
+use warnings;
+
+use base qw(OpenSLX::BootEnvironment::Base);
+
+use OpenSLX::MakeInitRamFS::Engine::PBS;
+
+use Clone qw(clone);
+use File::Basename;
+use File::Path;
+
+use Data::Dumper;
+
+use JSON;
+use HTTP::Request::Common;
+use LWP::UserAgent;
+
+use OpenSLX::Basics;
+use OpenSLX::ConfigDB qw(:support);
+use OpenSLX::Utils;
+
+sub initialize
+{
+ my $self = shift;
+ my $params = shift;
+
+ return if !$self->SUPER::initialize($params);
+
+ $self->{'original-path'} = "$openslxConfig{'public-path'}/pbs";
+ $self->{'target-path'} = "$openslxConfig{'public-path'}/pbs.new";
+
+ $self->{'requires-default-client-config'} = 0;
+ # we do not need a default.tgz since there's always an explicit client
+
+
+ if (!$self->{'dry-run'}) {
+ mkpath([$self->{'original-path'}]);
+ rmtree($self->{'target-path'});
+ mkpath("$self->{'target-path'}/client-config");
+ }
+
+ return 1;
+}
+
+sub writeBootloaderMenuFor
+{
+ my $self = shift;
+ my $client = shift;
+ my $externalClientID = shift;
+ my $systemInfos = shift || [];
+
+ my $prebootSystemInfo
+ = clone($self->_pickSystemWithNewestKernel($systemInfos));
+
+ vlog(
+ 0,
+ _tr(
+ "\nsend preboot information for client '%s' to pbs (%s)\n".
+ " (image templates provided based of %s) ...",
+ $client->{name}, $client->{attrs}->{preboot_server}, $prebootSystemInfo->{name}
+ )
+ );
+
+ $self->_createPrebootStuff($client, $prebootSystemInfo);
+
+ my $kernel = "$self->{'target-path'}/imagebase/vmlinuz";
+ my $initramfs = "$self->{'target-path'}/imagebase/initramfs";
+
+ my $kernel_md5 = qx/md5sum $kernel | awk '{print \$1}'/;
+ my $initramfs_md5 = qx/md5sum $initramfs | awk '{print \$1}'/;
+
+ my $data_json = to_json({
+ 'slxinfo' => qx/slxversion/,
+ 'kernel' => basename($prebootSystemInfo->{'kernel-file'}),
+ 'kernel_md5' => trim($kernel_md5),
+ 'initramfs_md5' => trim($initramfs_md5),
+ 'systems' => $systemInfos
+ });
+ my $ua = LWP::UserAgent->new;
+ my $res = $ua->request(POST 'http://pbs.experimental.openslx.org/backend/system/sync', [data => $data_json]);
+
+ if ($res->is_success) {
+ my $resData = from_json($res->content);
+ if ($resData->{'getKernel'} eq 'fresh') {
+ $res = $ua->request(POST 'http://pbs.experimental.openslx.org/backend/system/addkernel',
+ ['kernel' => basename($prebootSystemInfo->{'kernel-file'}),
+ 'kernelFile' => ["$self->{'target-path'}/imagebase/vmlinuz"],
+ 'initramfsFile' => ["$self->{'target-path'}/imagebase/initramfs"],
+ ],
+ 'Content_Type' => 'form-data'
+ );
+
+ print Dumper($res->content);
+
+ } else {
+ if ($resData->{'getKernel'} eq 'update') {
+ $res = $ua->request(POST 'http://pbs.experimental.openslx.org/backend/system/updatekernel',
+ ['kernel' => basename($prebootSystemInfo->{'kernel-file'}),
+ 'kernelFile' => ["$self->{'target-path'}/imagebase/vmlinuz"],
+ ],
+ 'Content_Type' => 'form-data'
+ );
+
+ print Dumper($res->content);
+ } else {
+ # do nothing
+ }
+ if ($resData->{'getInitramfs'} eq 'update') {
+ $res = $ua->request(POST 'http://pbs.experimental.openslx.org/backend/system/updateinitramfs',
+ ['kernel' => basename($prebootSystemInfo->{'kernel-file'}),
+ 'initramfsFile' => ["$self->{'target-path'}/imagebase/initramfs"],
+ ],
+ 'Content_Type' => 'form-data'
+ );
+
+ print Dumper($res->content);
+ } else {
+ # do nothing
+ }
+ }
+ } else {
+ vlog(0, 'communication with pbs failed.. please check and rerun..');
+ }
+
+ return 1;
+}
+
+sub _createPrebootStuff
+{
+ my $self = shift;
+ my $client = shift;
+ my $info = shift;
+
+ my $prebootClass = instantiateClass(
+ "OpenSLX::BootEnvironment::Preboot::Base"
+ );
+
+ my $imagebase = "$self->{'target-path'}/imagebase";
+
+ $prebootClass->initialize($self);
+ $client->{attrs}->{boot_uri} = $client->{attrs}->{preboot_server};
+ mkpath("$imagebase");
+ $self->_makePBSInitRamFS($info, "$imagebase/initramfs", $client);
+
+ my $kernelFile = $info->{'kernel-file'};
+ my $kernelName = basename($kernelFile);
+ slxsystem(qq{cp -p "$kernelFile" "$imagebase/vmlinuz"})
+ unless $self->{'dry-run'};
+
+ return 1;
+}
+
+sub _pickSystemWithNewestKernel
+{
+ my $self = shift;
+ my $systemInfos = shift;
+
+ my $systemWithNewestKernel;
+ my $newestKernelFileSortKey = '';
+ foreach my $system (@$systemInfos) {
+ next unless $system->{'kernel-file'} =~ 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) {
+ $systemWithNewestKernel = $system;
+ $newestKernelFileSortKey = $sortKey;
+ }
+ }
+
+ if (!defined $systemWithNewestKernel) {
+ die _tr("unable to pick a system to be used for preboot!");
+ }
+ return $systemWithNewestKernel;
+}
+
+sub _makePBSInitRamFS
+{
+ my $self = shift;
+ my $info = shift;
+ my $initramfs = shift;
+ my $client = shift;
+
+ my $vendorOS = $info->{'vendor-os'};
+ my $kernelFile = basename(followLink($info->{'kernel-file'}));
+
+ my $attrs = clone($info->{attrs} || {});
+
+ my $bootURI = $client->{attrs}->{boot_uri};
+ if (!$bootURI) {
+ die _tr("client $client->{name} needs an URI in attribute 'boot_uri' to be used for preboot!");
+ }
+
+ chomp(my $slxVersion = qx{slxversion});
+
+ my $params = {
+ 'attrs' => $attrs,
+ 'export-name' => undef,
+ 'export-uri' => undef,
+ 'initramfs' => $initramfs,
+ 'kernel-params'
+ => [ split ' ', ($info->{attrs}->{kernel_params} || '') ],
+ 'kernel-version' => $kernelFile =~ m[-(.+)$] ? $1 : '',
+ 'plugins' => '',
+ 'root-path'
+ => "$openslxConfig{'private-path'}/stage1/$vendorOS->{name}",
+ 'slx-version' => $slxVersion,
+ 'system-name' => $info->{name},
+ 'preboot-id' => $client->{name},
+ 'boot-uri' => $bootURI,
+ };
+
+ # TODO: make debug-level an explicit attribute, it's used in many places!
+ my $kernelParams = $info->{attrs}->{kernel_params} || '';
+ if ($kernelParams =~ m{debug(?:=(\d+))?}) {
+ my $debugLevel = defined $1 ? $1 : '1';
+ $params->{'debug-level'} = $debugLevel;
+ }
+
+ my $makeInitRamFSEngine
+ = OpenSLX::MakeInitRamFS::Engine::PBS->new($params);
+ $makeInitRamFSEngine->execute($self->{'dry-run'});
+
+ # copy back kernel-params, as they might have been changed (by plugins)
+ $info->{attrs}->{kernel_params}
+ = join ' ', $makeInitRamFSEngine->kernelParams();
+
+ return;
+}
+
+1;