From bb4b0af7f5c3b030d74f22021e5c3cc20ad17fe1 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Wed, 13 Jan 2010 16:52:45 +0000 Subject: [PATCH] first draft of a deployment-friendly bootmanager attempt to make some sense of the various locations used move the nodeconfig script, as well as the plc.d script, into bootmanager, where it belongs --- Makefile | 36 +++++++++---- bootmanager.spec | 46 ++++++++-------- build.sh | 111 ++++++++++++++++++-------------------- nodeconfig/boot/index.php | 84 +++++++++++++++++++++++++++++ plc.d/bootmanager | 46 ++++++++++++++++ 5 files changed, 233 insertions(+), 90 deletions(-) create mode 100755 nodeconfig/boot/index.php create mode 100755 plc.d/bootmanager diff --git a/Makefile b/Makefile index 7cb8a65..7769042 100644 --- a/Makefile +++ b/Makefile @@ -2,26 +2,42 @@ # $Id: Makefile 682 2007-07-19 09:00:25Z thierry $ # -########## make sync PLCHOST=hostname -########## make sync PLCHOST=hostname +########## sync +# 2 forms are supported +# (*) if your plc root context has direct ssh access: +# make sync PLC=private.one-lab.org +# (*) otherwise, entering through the root context +# make sync PLCHOST=testbox1.inria.fr GUEST=vplc03.inria.fr + +ifdef GUEST ifdef PLCHOST -ifdef VSERVER -PLCSSH:=root@$(PLCHOST):/vservers/$(VSERVER) +SSHURL:=root@$(PLCHOST):/vservers/$(GUEST) +SSHCOMMAND:=ssh root@$(PLCHOST) vserver $(GUEST) +endif endif +ifdef PLC +SSHURL:=root@$(PLC):/ +SSHCOMMAND:=ssh root@$(PLC) endif -LOCAL_RSYNC_EXCLUDES := --exclude '*.pyc' --exclude debug_root_ssh_key +LOCAL_RSYNC_EXCLUDES := --exclude '*.pyc' RSYNC_EXCLUDES := --exclude .svn --exclude CVS --exclude '*~' --exclude TAGS $(LOCAL_RSYNC_EXCLUDES) RSYNC_COND_DRY_RUN := $(if $(findstring n,$(MAKEFLAGS)),--dry-run,) RSYNC := rsync -a -v $(RSYNC_COND_DRY_RUN) $(RSYNC_EXCLUDES) +DEPLOYMENT ?= regular + sync: -ifeq (,$(PLCSSH)) - echo "sync: You must define PLCHOST and VSERVER on the command line" - echo " e.g. make sync PLCHOST=private.one-lab.org VSERVER=myplc01" ; exit 1 +ifeq (,$(SSHURL)) + @echo "sync: You must define, either PLC, or PLCHOST & GUEST, on the command line" + @echo " you can optionnally define DEPLOYMENT too, it defaults to 'regular'" + @echo " e.g. make sync PLC=boot.onelab.eu DEPLOYMENT=alpha" + @echo " or make sync PLCHOST=testbox1.inria.fr GUEST=vplc03.inria.fr" + @exit 1 else - +$(RSYNC) source $(PLCSSH)/usr/share/bootmanager/ - ssh root@$(PLCHOST) vserver $(VSERVER) exec service plc start bootmanager + $(SSHCOMMAND) mkdir -p /usr/share/bootmanager/$(DEPLOYMENT) + +$(RSYNC) build.sh source $(SSHURL)/usr/share/bootmanager/$(DEPLOYMENT) + $(SSHCOMMAND) service plc start bootmanager endif ########## diff --git a/bootmanager.spec b/bootmanager.spec index cd56d51..8dc4eb5 100644 --- a/bootmanager.spec +++ b/bootmanager.spec @@ -3,7 +3,9 @@ # %define url $URL$ -%define name bootmanager +%define nodefamily %{pldistro}-%{_arch} + +%define name bootmanager-%{nodefamily} %define version 4.3 %define taglevel 16 @@ -22,13 +24,18 @@ License: BSD Group: System Environment/Base Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +BuildArch: noarch Requires: tar, gnupg, sharutils, bzip2, pypcilib Requires: PLCAPI >= 4.3 - # the python code packaged in these are shipped on the node as well Requires: pypcilib pyplnet monitor-runlevelagent +# plc.d/bootmanager is moving +Conflicts: myplc <= 4.3.37 +# nodeconfig/boot/index.php is moving +Conflicts: nodeconfig <= 4.3.7 + AutoReqProv: no %define debug_package %{nil} @@ -46,10 +53,18 @@ gcc -shared -fPIC -ldl -Os -o source/libc-opendir-hack.so source/libc-opendir-ha rm -rf $RPM_BUILD_ROOT # Install source so that it can be rebuilt -find build.sh source | cpio -p -d -u $RPM_BUILD_ROOT/%{_datadir}/%{name}/ +find build.sh source | cpio -p -d -u $RPM_BUILD_ROOT/%{_datadir}/%{name}/regular/ + +install -m 644 README $RPM_BUILD_ROOT/%{_datadir}/%{name}/README -touch bootmanager.sh -install -D -m 755 bootmanager.sh $RPM_BUILD_ROOT/var/www/html/boot/bootmanager.sh +# formerly in the nodeconfig module +install -m 755 nodeconfig/boot/index.php $RPM_BUILD_ROOT/var/www/html/boot/index.php + +# formerly in the MyPLC module +install -m 755 plc.d/bootmanager $RPM_BUILD_ROOT/etc/pld.c/bootmanager + +#touch bootmanager.sh +#install -D -m 755 bootmanager.sh $RPM_BUILD_ROOT/var/www/html/boot/bootmanager.sh # This is only required for 2.x bootcds. install -D -m 644 support-files/uudecode.gz $RPM_BUILD_ROOT/var/www/html/boot/uudecode.gz @@ -57,32 +72,21 @@ install -D -m 644 support-files/uudecode.gz $RPM_BUILD_ROOT/var/www/html/boot/uu %clean rm -rf $RPM_BUILD_ROOT -# If run under sudo -if [ -n "$SUDO_USER" ] ; then - # Allow user to delete the build directory - chown -h -R $SUDO_USER . - # Some temporary cdroot files like /var/empty/sshd and - # /usr/bin/sudo get created with non-readable permissions. - find . -not -perm +0600 -exec chmod u+rw {} \; - # Allow user to delete the built RPM(s) - chown -h -R $SUDO_USER %{_rpmdir}/%{_arch} -fi - %post -cat < - BootManager-4.3-16 diff --git a/build.sh b/build.sh index 411111c..f9df9bc 100755 --- a/build.sh +++ b/build.sh @@ -11,49 +11,72 @@ # Copyright (C) 2004-2007 The Trustees of Princeton University # # $Id: build.sh,v 1.5 2006/04/03 19:40:55 mlhuang Exp $ +# $URL$ # # Source PLC configuration -if [ -f /etc/planetlab/plc_config ] ; then - . /etc/planetlab/plc_config -else - PLC_BOOT_HOST=boot.planet-lab.org - PLC_API_HOST=www.planet-lab.org - PLC_API_PATH=PLCAPI -fi +. /etc/planetlab/plc_config # Do not tolerate errors set -e -NODEGROUP=$1 +# this is set by plc.d/bootmanager +DEPLOYMENT=$1 BOOTSTRAPDIR="/boot" -if [ -n "$NODEGROUP" ] ; then - BOOTSTRAPDIR="/boot/$NODEGROUP" -fi - # Change to our source directory -srcdir=$(cd $(dirname $0) && pwd -P) +cd $(dirname $0) # Translate configuration file -sed -i -e "s|SUPPORT_FILE_DIR=.*|SUPPORT_FILE_DIR=$BOOTSTRAPDIR|" $srcdir/source/configuration +sed -i -e "s|SUPPORT_FILE_DIR=.*|SUPPORT_FILE_DIR=$BOOTSTRAPDIR|" source/configuration # Source bootmanager configuration . $srcdir/source/configuration -# Write boot script. plc_www/boot/index.php writes this script out -# after a nonce check. +# Write boot script. nodeconfig/boot/index.php retrieves the contents of this script +# after checking the node id + +BMDIR=/var/www/html/bootmanager +mkdir -p $BMDIR + +DEST_SCRIPT="$BMDIR/${DEPLOYMENT}_bootmanager.sh" +# Remove the old version or any sym links prior to re-writing +rm -f ${DEST_SCRIPT} +rm -f ${DEST_SCRIPT}.sgn + + +# hard code 443 here. +sed -i -e "s@^BOOT_API_SERVER.*@BOOT_API_SERVER=https://$PLC_API_HOST:443/$PLC_API_PATH/@" source/configuration + +sed -i -e "s@^BOOT_SERVER.*@BOOT_SERVER=$PLC_BOOT_HOST@" source/configuration +if [ "$PLC_MONITOR_ENABLED" = "1" ]; then + MONITOR_SERVER=$PLC_MONITOR_HOST +else + MONITOR_SERVER=$PLC_BOOT_HOST +fi +sed -i -e "s@^MONITOR_SERVER.*@MONITOR_SERVER=$MONITOR_SERVER@" source/configuration + +install -D -m 644 $PLC_BOOT_CA_SSL_CRT source/cacert/$PLC_BOOT_HOST/cacert.pem +if [ -f $PLC_MONITOR_CA_SSL_CRT ] ; then + install -D -m 644 $PLC_MONITOR_CA_SSL_CRT source/cacert/$PLC_MONITOR_HOST/cacert.pem +fi -DEST_SCRIPT=bootmanager.sh -if [ -n "$NODEGROUP" ] ; then - DEST_SCRIPT="${NODEGROUP}_bootmanager.sh" - # Remove the old version or any sym links prior to re-writing - rm -f ${DEST_SCRIPT} - rm -f ${DEST_SCRIPT}.sgn +# Replace the default debug SSH key +if [ -f "$PLC_DEBUG_SSH_KEY_PUB" ] ; then + install -D -m 644 "$PLC_DEBUG_SSH_KEY_PUB" source/debug_files/debug_root_ssh_key fi -cat > $DEST_SCRIPT < $DEST_SCRIPT #!/bin/bash # # PlanetLab Boot Manager $VERSION @@ -74,52 +97,21 @@ if [ ! -x \$UUDECODE ]; then chmod +x \$UUDECODE fi +($UUDECODE | /bin/tar -C /tmp -xj) << _EOF_ EOF -echo '($UUDECODE | /bin/tar -C /tmp -xj) << _EOF_' >> $DEST_SCRIPT - -# XXX Currently, the value of PLC_API_PORT is set to 80 by default, so -# that the portions of the web site that still use oldapi can continue -# to work. However, the Boot Manager supports HTTPS access, which we -# want to remain the default, so hard code 443 here. -sed -i -e "s@^BOOT_API_SERVER.*@BOOT_API_SERVER=https://$PLC_API_HOST:443/$PLC_API_PATH/@" \ - $srcdir/source/configuration - -sed -i -e "s@^BOOT_SERVER.*@BOOT_SERVER=$PLC_BOOT_HOST@" $srcdir/source/configuration -if [ "$PLC_MONITOR_ENABLED" = "1" ]; then - MONITOR_SERVER=$PLC_MONITOR_HOST -else - MONITOR_SERVER=$PLC_BOOT_HOST -fi -sed -i -e "s@^MONITOR_SERVER.*@MONITOR_SERVER=$MONITOR_SERVER@" $srcdir/source/configuration - -install -D -m 644 $PLC_BOOT_CA_SSL_CRT $srcdir/source/cacert/$PLC_BOOT_HOST/cacert.pem -if [ -f $PLC_MONITOR_CA_SSL_CRT ] ; then - install -D -m 644 $PLC_MONITOR_CA_SSL_CRT $srcdir/source/cacert/$PLC_MONITOR_HOST/cacert.pem -fi - -# Replace the default debug SSH key -if [ -f "$PLC_DEBUG_SSH_KEY_PUB" ] ; then - install -D -m 644 "$PLC_DEBUG_SSH_KEY_PUB" $srcdir/source/debug_files/debug_root_ssh_key -fi - -# Add python code from the following packages -# make sure they are in the 'Requires' header of the specfile -required_rpms="pypcilib pyplnet monitor-runlevelagent" -extra_libs=`mktemp -d "/tmp/.bootmanager.XXXXXX"` -mkdir $extra_libs/source -cp -p $(rpm -ql $required_rpms | grep -v '\.py[co]$') $extra_libs/source # Embed the uuencoded tarball in the script tar -cj -C $srcdir source/ -C $extra_libs source/ | uuencode -m - >> $DEST_SCRIPT -# Remove temp directory -rm -fr $extra_libs - +# wrap up the script echo '_EOF_' >> $DEST_SCRIPT echo 'cd /tmp/source' >> $DEST_SCRIPT echo 'chmod +x BootManager.py && ./BootManager.py' >> $DEST_SCRIPT +# Remove temp directory +rm -fr $extra_libs + # Sign the whole script, if the keyring is on this machine. if [ -f "$PLC_ROOT_GPG_KEY" -a -f "$PLC_ROOT_GPG_KEY_PUB" ] ; then gpg --homedir=/root \ @@ -131,3 +123,4 @@ if [ -f "$PLC_ROOT_GPG_KEY" -a -f "$PLC_ROOT_GPG_KEY_PUB" ] ; then else echo "Warning: Remember to sign $PWD/$DEST_SCRIPT!" >&2 fi + diff --git a/nodeconfig/boot/index.php b/nodeconfig/boot/index.php new file mode 100755 index 0000000..81ec490 --- /dev/null +++ b/nodeconfig/boot/index.php @@ -0,0 +1,84 @@ + +// Copyright (C) 2006 The Trustees of Princeton University +// +// $Id$ $ +// + +// Get admin API handle +require_once 'plc_api.php'; +global $adm; + +// location for signed scripts +$bmdir="/var/www/html/bootmanager"; + +// Default bootmanager +$bootmanager = "bootmanager.sh.sgn"; + +// Look up the node +$interfaces = $adm->GetInterfaces(array('ip' => $_SERVER['REMOTE_ADDR'])); +if (!empty($interfaces)) { + $nodes = $adm->GetNodes(array($interfaces[0]['node_id'])); + if (!empty($nodes)) { + $node = $nodes[0]; + } +} + +if (isset($node)) { + // Allow very old nodes that do not have a node key in their + // configuration files to use their "boot nonce" instead. The boot + // nonce is a random value generated by the node itself and POSTed + // by the Boot CD when it requests the Boot Manager. This is + // obviously not very secure, so we only allow it to be used if the + // requestor IP is the same as the IP address we have on record for + // the node. + + // 3.x CDs post 'version', 2.x CDs post 'id'. + if (!empty($_REQUEST['version'])) { + $version = trim($_REQUEST['version']); + } elseif (!empty($_REQUEST['id'])) { + $version = trim($_REQUEST['id']); + } else { + $version = "2.0"; + } + + if (empty($node['key']) && !empty($_REQUEST['nonce'])) { + // 3.x CDs post the boot nonce in ASCII hex. 2.x CDs post it in binary. + if (strstr($version, "2.0") === FALSE) { + // 3.x CDs post a trailing newline...sigh + $nonce = trim($_REQUEST['nonce']); + } else { + $nonce = bin2hex($_REQUEST['nonce']); + } + $adm->UpdateNode($node['node_id'], array('boot_nonce' => $nonce)); + } + + // Custom bootmanager for the node, e.g. + // planetlab-1.cs.princeton.edu_bootmanager.sh.sgn + $bootmanagers = array(strtolower($node['hostname']) . "_" . $bootmanager); + + // Custom bootmanager for the deployment tag, e.g. + + if (!empty($node['nodegroup_ids'])) { + $nodegroups = $adm->GetNodeDeployment($node['nodegroup_ids']); + foreach ($nodegroups as $nodegroup) { + $bootmanagers[] = strtolower($nodegroup['groupname']) . "_" . $bootmanager; + } + } +} + +// Default bootmanager +$bootmanagers[] = "regular_" . $bootmanager; + +foreach ($bootmanagers as $bootmanager) { + $candidate=$bmdir . "/" . $bootmanager; + if (file_exists($candidate)) { + readfile($candidate); + exit(); + } +} + +?> diff --git a/plc.d/bootmanager b/plc.d/bootmanager new file mode 100755 index 0000000..19b6e03 --- /dev/null +++ b/plc.d/bootmanager @@ -0,0 +1,46 @@ +#!/bin/bash +# +# priority: 1100 +# +# Rebuild the Boot Manager +# +# Mark Huang +# Copyright (C) 2006 The Trustees of Princeton University +# +# $Id$ +# + +# Source function library and configuration +. /etc/plc.d/functions +. /etc/planetlab/plc_config + +# Be verbose +set -x + +case "$1" in + start) + if [ "$PLC_BOOT_ENABLED" != "1" -a \ + "$PLC_WWW_ENABLED" != "1" ] ; then + exit 0 + fi + + shopt -s nullglob + for topdir in /usr/share/bootmanager/* ; do + [ -d "$topdir" ] || continue + deployment=$(basename $topdir) + if [ "$deployment" = "regular" ] ; then + dialog $"Rebuilding Boot Manager" + $topdir/build.sh regular + check + else + dialog $"Rebuilding Boot Manager for deployment $deployment" + $topdir/build.sh $deployment + check + fi + done + + result "$MESSAGE" + ;; +esac + +exit $ERRORS -- 2.43.0