From 135271d073a8e7ddfe044ba62c35bb4f7a4676b0 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Wed, 27 Feb 2013 13:41:33 +0100 Subject: [PATCH] merged 5.0 (traditional vserver-based) and 5.1 (aka lxc_devel) now retrieves GetNodeFlavour as part of GetNodeDetails and stores result as global vars['node_flavour'] this one now is expected to include the 'virt' tag as either 'vs' or 'lxc' and act accordingly STILL MISSING fsck under btrfs, i.e. * turn off periodic fsck in InstallPartitionDisk, and * explicitly run fsck in ValidateNodeInstall ALSO the MakeInitrd and WriteModprobeConfig steps are turned off with lxc --- Makefile | 6 ++--- bootmanager.spec | 26 +++++++++++++++--- source/BootManager.py | 8 +++++- source/configuration | 8 +++--- source/steps/ChainBootNode.py | 32 ++++++++++++++-------- source/steps/CheckHardwareRequirements.py | 5 ++-- source/steps/GetAndUpdateNodeDetails.py | 23 ++++++++++++++++ source/steps/InstallBootstrapFS.py | 32 +++++++++++----------- source/steps/InstallPartitionDisks.py | 33 ++++++++++++++++------- source/steps/InstallWriteConfig.py | 15 ++++++++--- source/steps/StartDebug.py | 3 ++- source/steps/ValidateNodeInstall.py | 20 +++++++++++--- source/steps/WriteModprobeConfig.py | 2 ++ 13 files changed, 153 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index c2540fa..ee833d3 100644 --- a/Makefile +++ b/Makefile @@ -8,14 +8,14 @@ # $ run export # and cut'n paste the export lines before you run make sync -PLCHOST ?= testplc.onelab.eu +PLCHOSTLXC ?= lxc64-1.pl.sophia.inria.fr ifdef PLC SSHURL:=root@$(PLC):/ SSHCOMMAND:=ssh root@$(PLC) else ifdef PLCHOSTLXC -SSHURL:=root@$(PLCHOST):/var/lib/lxc/$(GUESTNAME)/rootfs +SSHURL:=root@$(PLCHOSTLXC):/var/lib/lxc/$(GUESTNAME)/rootfs SSHCOMMAND:=ssh root@$(PLCHOSTLXC) ssh $(GUESTHOSTNAME) else ifdef PLCHOSTVS @@ -47,6 +47,6 @@ endif ########## tags: - find . -type f | egrep -v 'TAGS|/\.svn/|\.git/|~$$' | xargs etags + find . -type f | egrep -v 'TAGS|DIFF|/\.svn/|\.git/|~$$' | xargs etags .PHONY: tags diff --git a/bootmanager.spec b/bootmanager.spec index 13cb673..bce078f 100644 --- a/bootmanager.spec +++ b/bootmanager.spec @@ -20,12 +20,13 @@ Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildArch: noarch -Requires: tar, gnupg, sharutils, bzip2, pypcilib +Requires: tar, gnupg, sharutils, bzip2 # need the apache user at install-time Requires: httpd -Requires: PLCAPI >= 5.0 -# the python code packaged in these are shipped on the node as well +Requires: plcapi >= 5.2 +# we need to install these on the myplc side too, although this is suboptimal +# b/c this python code gets shipped on the nodes as well Requires: pypcilib pyplnet ### avoid having yum complain about updates, as stuff is moving around @@ -81,15 +82,33 @@ chmod 700 /var/log/bm /etc/plc.d/bootmanager %changelog +* Fri Feb 22 2013 Thierry Parmentelat - bootmanager-5.1-5 +- fix for heterogeneous bootimage/nodeimage + +* Thu Feb 21 2013 Thierry Parmentelat - bootmanager-5.1-4 +- Turn off WriteModprobeConfig for f18 +- enable btrfs quota +- fix very old ssh DSA key generation + +* Tue Oct 16 2012 Thierry Parmentelat - bootmanager-5.1-3 +- run parted with --script to keep it from hanging + * Fri Aug 31 2012 Thierry Parmentelat - bootmanager-5.0-24 - run parted with --script to avoid it to hang +* Wed Jul 18 2012 Thierry Parmentelat - bootmanager-5.1-2 +- pour the 5.0-22 and 5.0-23 features into the lxc mix + * Mon Jul 09 2012 Thierry Parmentelat - bootmanager-5.0-23 - added support for disks larger than 2Tb using gpt instead of msdos * Tue May 15 2012 Thierry Parmentelat - bootmanager-5.0-22 - bootmanager log clearly states duration of download and extraction of node image +* Fri Apr 13 2012 Thierry Parmentelat - bootmanager-5.1-1 +- first working draft for dealing with f16 nodes +- not expected to work with mainline nodes (use 5.0 for that for now) + * Fri Apr 13 2012 Thierry Parmentelat - bootmanager-5.0-21 - no significant change, just checkpoint as 5.1 is addressing lxc @@ -281,4 +300,3 @@ chmod 700 /var/log/bm * Fri Sep 2 2005 Mark Huang - - Initial build. -%define module_current_branch 4.3 diff --git a/source/BootManager.py b/source/BootManager.py index 3c3f1d4..ab64657 100755 --- a/source/BootManager.py +++ b/source/BootManager.py @@ -229,7 +229,13 @@ class BootManager: InstallInit.Run( self.VARS, self.LOG ) ret = ValidateNodeInstall.Run( self.VARS, self.LOG ) if ret == 1: - WriteModprobeConfig.Run( self.VARS, self.LOG ) +# Thierry - feb. 2013 turning off WriteModprobeConfig for now on lxc +# for one thing this won't work at all with f18, as modules.pcimap +# has disappeared (Daniel suggested modules.aliases could be used instead) +# and second, in any case it's been years now that modprobe.conf was deprecated +# so most likely this code has no actual effect + if vars['virt'] == 'vs': + WriteModprobeConfig.Run( self.VARS, self.LOG ) WriteNetworkConfig.Run( self.VARS, self.LOG ) CheckForNewDisks.Run( self.VARS, self.LOG ) SendHardwareConfigToPLC.Run( self.VARS, self.LOG ) diff --git a/source/configuration b/source/configuration index 9f0fe74..5ec5887 100644 --- a/source/configuration +++ b/source/configuration @@ -4,7 +4,7 @@ # the current version of the bootmanager -VERSION=3.2 +VERSION=5.2 # this is the server to contact if we don't have a bootcd DEFAULT_BOOT_SERVER=boot.planet-lab.org @@ -53,7 +53,8 @@ PLCONF_DIR=/etc/planetlab # this sets the size of the root logical volume, # after the root and swap has been created, remaining # goes to the vserver partition -ROOT_SIZE=14G +vs_ROOT_SIZE=14G +lxc_ROOT_SIZE=70G # override the swap size @@ -80,7 +81,8 @@ MINIMUM_DISK_SIZE=17 # total minimum disk size in GB if all usable disks are below this # size, the node cannot be installed -TOTAL_MINIMUM_DISK_SIZE=50 +vs_TOTAL_MINIMUM_DISK_SIZE=50 +lxc_TOTAL_MINIMUM_DISK_SIZE=120 # set of langugase for install (used in /etc/rpm/macros) diff --git a/source/steps/ChainBootNode.py b/source/steps/ChainBootNode.py index 848cb3d..75428aa 100644 --- a/source/steps/ChainBootNode.py +++ b/source/steps/ChainBootNode.py @@ -10,18 +10,17 @@ import string import re import os +import time -import UpdateNodeConfiguration -import MakeInitrd -import StopRunlevelAgent -from Exceptions import * import utils import systeminfo -import BootAPI import notify_messages -import time - +import BootAPI import ModelOptions +from Exceptions import BootManagerException + +import UpdateNodeConfiguration +import StopRunlevelAgent def Run( vars, log ): """ @@ -125,7 +124,9 @@ def Run( vars, log ): utils.sysexec_chroot( SYSIMG_PATH, cmd, log ) # Re-generate initrd right before kexec call - MakeInitrd.Run( vars, log ) + # this is not required anymore on recent depls. + if vars['virt'] == 'vs': + MakeInitrd.Run( vars, log ) # the following step should be done by NM UpdateNodeConfiguration.Run( vars, log ) @@ -151,8 +152,14 @@ def Run( vars, log ): option = 'smp' log.write( "Copying kernel and initrd for booting.\n" ) - utils.sysexec( "cp %s/boot/kernel-boot%s /tmp/kernel" % (SYSIMG_PATH,option), log ) - utils.sysexec( "cp %s/boot/initrd-boot%s /tmp/initrd" % (SYSIMG_PATH,option), log ) + if vars['virt'] == 'vs': + utils.sysexec( "cp %s/boot/kernel-boot%s /tmp/kernel" % (SYSIMG_PATH,option), log ) + utils.sysexec( "cp %s/boot/initrd-boot%s /tmp/initrd" % (SYSIMG_PATH,option), log ) + else: + # Use chroot to call rpm, b/c the bootimage&nodeimage rpm-versions may not work together + kversion = os.popen("chroot %s rpm -qa kernel | tail -1 | cut -c 8-" % SYSIMG_PATH).read().rstrip() + utils.sysexec( "cp %s/boot/vmlinuz-%s /tmp/kernel" % (SYSIMG_PATH,kversion), log ) + utils.sysexec( "cp %s/boot/initramfs-%s.img /tmp/initrd" % (SYSIMG_PATH,kversion), log ) BootAPI.save(vars) @@ -189,7 +196,10 @@ def Run( vars, log ): utils.sysexec_noerr( "killall dhclient", log ) - utils.sysexec_noerr( "umount -a -r -t ext2,ext3", log ) + if vars['virt'] == 'vs': + utils.sysexec_noerr( "umount -a -r -t ext2,ext3", log ) + else: + utils.sysexec_noerr( "umount -a -r -t ext2,ext3,btrfs", log ) utils.sysexec_noerr( "modprobe -r lvm-mod", log ) # modules that should not get unloaded diff --git a/source/steps/CheckHardwareRequirements.py b/source/steps/CheckHardwareRequirements.py index 3e8b0b5..39f8785 100644 --- a/source/steps/CheckHardwareRequirements.py +++ b/source/steps/CheckHardwareRequirements.py @@ -57,8 +57,9 @@ def Run( vars, log ): MINIMUM_DISK_SIZE= int(vars["MINIMUM_DISK_SIZE"]) - TOTAL_MINIMUM_DISK_SIZE= \ - int(vars["TOTAL_MINIMUM_DISK_SIZE"]) + # use vs_ or lxc_variants + varname=vars['virt']+"_TOTAL_MINIMUM_DISK_SIZE" + TOTAL_MINIMUM_DISK_SIZE= int(vars[varname]) SKIP_HARDWARE_REQUIREMENT_CHECK= \ int(vars["SKIP_HARDWARE_REQUIREMENT_CHECK"]) diff --git a/source/steps/GetAndUpdateNodeDetails.py b/source/steps/GetAndUpdateNodeDetails.py index 849e25b..f384239 100644 --- a/source/steps/GetAndUpdateNodeDetails.py +++ b/source/steps/GetAndUpdateNodeDetails.py @@ -6,6 +6,7 @@ # Copyright (c) 2004-2006 The Trustees of Princeton University # All rights reserved. +import sys, traceback import string from Exceptions import * @@ -105,4 +106,26 @@ def Run( vars, log ): vars['INTERFACES']= interfaces + # call getNodeFlavour and store in VARS['node_flavour'] + try: + node_flavour = BootAPI.call_api_function(vars, "GetNodeFlavour", (vars['NODE_ID'], ) ) + nodefamily = node_flavour['nodefamily'] + extensions = node_flavour['extensions'] + plain = node_flavour['plain'] + except: + exc_type, exc_value, exc_traceback = sys.exc_info() + lines=traceback.format_exception(exc_type,exc_value,exc_traceback) + for line in lines: log.write(line) + raise BootManagerException ("Could not call GetNodeFlavour - need PLCAPI-5.2") + + # 'vs' or 'lxc' + vars['virt'] = node_flavour['virt'] + # the basename for downloading nodeimage + vars['nodefamily'] = node_flavour['nodefamily'] + # extensions to be applied on top of the base nodeimage + vars['extensions'] = node_flavour ['extensions'] + # false if compressed image, true if not + vars['plain'] = node_flavour ['plain'] + log.write ("NodeFlavour as returned from PLC: %s\n"%node_flavour) + return 1 diff --git a/source/steps/InstallBootstrapFS.py b/source/steps/InstallBootstrapFS.py index 83de630..7354893 100644 --- a/source/steps/InstallBootstrapFS.py +++ b/source/steps/InstallBootstrapFS.py @@ -7,7 +7,7 @@ # All rights reserved. # expected /proc/partitions format -import os, sys, string +import os, string import popen2 import shutil import traceback @@ -80,27 +80,25 @@ def Run( vars, log ): log.write( "mounting root file system\n" ) utils.sysexec( "mount -t ext3 %s %s" % (PARTITIONS["root"],SYSIMG_PATH), log ) - log.write( "mounting vserver partition in root file system\n" ) + fstype = 'ext3' if vars['virt']=='vs' else 'btrfs' + log.write( "mounting vserver partition in root file system (type %s)\n"%fstype ) utils.makedirs( SYSIMG_PATH + "/vservers" ) - utils.sysexec( "mount -t ext3 %s %s/vservers" % (PARTITIONS["vservers"], - SYSIMG_PATH), log ) + utils.sysexec( "mount -t %s %s %s/vservers" % \ + (fstype, PARTITIONS["vservers"], SYSIMG_PATH), log ) + + if vars['virt']=='lxc': + # NOTE: btrfs quota is supported from version: >= btrfs-progs-0.20 (f18+) + # older versions will not recongize the 'quota' command. + log.write( "Enabling btrfs quota on %s/vservers\n"%SYSIMG_PATH ) + utils.sysexec_noerr( "btrfs quota enable %s/vservers" % SYSIMG_PATH ) vars['ROOT_MOUNTED']= 1 - # call getNodeFlavour - try: - node_flavour = BootAPI.call_api_function(vars, "GetNodeFlavour", (NODE_ID,) ) - nodefamily = node_flavour['nodefamily'] - extensions = node_flavour['extensions'] - plain = node_flavour['plain'] - except: - exc_type, exc_value, exc_traceback = sys.exc_info() - lines=traceback.format_exception(exc_type,exc_value,exc_traceback) - for line in lines: log.write(line) - raise BootManagerException ("Could not call GetNodeFlavour - need PLCAPI-5.0") - - log.write ("Retrieved 'virt' style %s from GetNodeFlavour\n"%node_flavour['virt']) + # this is now retrieved in GetAndUpdateNodeDetails + nodefamily = vars['nodefamily'] + extensions = vars['extensions'] # the 'plain' option is for tests mostly + plain = vars['plain'] if plain: download_suffix=".tar" uncompress_option="" diff --git a/source/steps/InstallPartitionDisks.py b/source/steps/InstallPartitionDisks.py index b469330..f0d3d97 100644 --- a/source/steps/InstallPartitionDisks.py +++ b/source/steps/InstallPartitionDisks.py @@ -41,7 +41,9 @@ def Run( vars, log ): if( len(INSTALL_BLOCK_DEVICES) == 0 ): raise ValueError, "INSTALL_BLOCK_DEVICES is empty" - ROOT_SIZE= vars["ROOT_SIZE"] + # use vs_ROOT_SIZE or lxc_ROOT_SIZE as appropriate + varname=vars['virt']+"_ROOT_SIZE" + ROOT_SIZE= vars[varname] if ROOT_SIZE == "" or ROOT_SIZE == 0: raise ValueError, "ROOT_SIZE invalid" @@ -159,17 +161,28 @@ def Run( vars, log ): # reserved-blocks-percentages filesystems = {"root":5,"vservers":0} - # make the file systems - for fs in filesystems.keys(): - # get the reserved blocks percentage - rbp = filesystems[fs] - devname = PARTITIONS[fs] + # ROOT filesystem is always with ext2 + fs = 'root' + rbp = filesystems[fs] + devname = PARTITIONS[fs] + log.write("formatting %s partition (%s)%s.\n" % (fs,devname,txt)) + utils.sysexec( "mkfs.ext2 -q %s -m %d -j %s" % (option,rbp,devname), log ) + # disable time/count based filesystems checks + utils.sysexec_noerr( "tune2fs -c -1 -i 0 %s" % devname, log) + + # VSERVER filesystem with btrfs to support snapshoting and stuff + fs = 'vservers' + rbp = filesystems[fs] + devname = PARTITIONS[fs] + if vars['virt']=='vs': log.write("formatting %s partition (%s)%s.\n" % (fs,devname,txt)) utils.sysexec( "mkfs.ext2 -q %s -m %d -j %s" % (option,rbp,devname), log ) - - # disable time/count based filesystems checks - for filesystem in ("root","vservers"): - utils.sysexec_noerr( "tune2fs -c -1 -i 0 %s" % PARTITIONS[filesystem], log) + # disable time/count based filesystems checks + utils.sysexec_noerr( "tune2fs -c -1 -i 0 %s" % devname, log) + else: + log.write("formatting %s btrfs partition (%s).\n" % (fs,devname)) + utils.sysexec( "mkfs.btrfs %s" % (devname), log ) + # as of 2013/02 it looks like there's not yet an option to set fsck frequency with btrfs # save the list of block devices in the log log.write( "Block devices used (in lvm): %s\n" % repr(used_devices)) diff --git a/source/steps/InstallWriteConfig.py b/source/steps/InstallWriteConfig.py index d8b5a6e..8ae3f6d 100644 --- a/source/steps/InstallWriteConfig.py +++ b/source/steps/InstallWriteConfig.py @@ -11,7 +11,6 @@ import os, string from Exceptions import * import utils -import systeminfo import BootAPI import ModelOptions @@ -72,8 +71,12 @@ def Run( vars, log ): utils.sysexec_chroot( SYSIMG_PATH, "ln -sf /usr/share/zoneinfo/UTC /etc/localtime", log ) + # clearly this does not depend on vs / lxc but let's keep it simple log.write( "Enabling ntp at boot\n" ) - utils.sysexec_chroot( SYSIMG_PATH, "chkconfig ntpd on", log ) + if vars['virt'] == 'vs': + utils.sysexec_chroot( SYSIMG_PATH, "chkconfig ntpd on", log ) + else: + utils.sysexec_chroot( SYSIMG_PATH, "systemctl enable ntpd.service", log ) log.write( "Creating system directory %s\n" % PLCONF_DIR ) if not utils.makedirs( "%s/%s" % (SYSIMG_PATH,PLCONF_DIR) ): @@ -86,8 +89,12 @@ def Run( vars, log ): PARTITIONS["mapper-swap"] ) fstab.write( "%s / ext3 defaults 1 1\n" % \ PARTITIONS["mapper-root"] ) - fstab.write( "%s /vservers ext3 tagxid,defaults 1 2\n" % \ - PARTITIONS["mapper-vservers"] ) + if vars['virt'] == 'vs': + fstab.write( "%s /vservers ext3 tagxid,defaults 1 2\n" % \ + PARTITIONS["mapper-vservers"] ) + else: + fstab.write( "%s /vservers btrfs defaults 1 2\n" % \ + PARTITIONS["mapper-vservers"] ) fstab.write( "none /proc proc defaults 0 0\n" ) fstab.write( "none /dev/shm tmpfs defaults 0 0\n" ) fstab.write( "none /dev/pts devpts defaults 0 0\n" ) diff --git a/source/steps/StartDebug.py b/source/steps/StartDebug.py index 5cdf8f7..6a9e130 100644 --- a/source/steps/StartDebug.py +++ b/source/steps/StartDebug.py @@ -89,7 +89,8 @@ def Run( vars, log, last_resort = True): key=ssh_dir+"/ssh_host_dsa_key" if not os.path.isfile (key): log.write("Creating host dsa key %s\n"%key) - utils.sysexec( "ssh-keygen -d -f %s -N ''" % key, log ) + # very old versions did 'ssh-keygen -d' instead of 'ssh-keygen -t dsa' + utils.sysexec( "ssh-keygen -t dsa -f %s -N ''" % key, log ) # (over)write sshd config utils.sysexec( "cp -f %s/sshd_config %s/sshd_config" % (ssh_source_files,ssh_dir), log ) diff --git a/source/steps/ValidateNodeInstall.py b/source/steps/ValidateNodeInstall.py index c987170..2f038ec 100644 --- a/source/steps/ValidateNodeInstall.py +++ b/source/steps/ValidateNodeInstall.py @@ -83,7 +83,12 @@ def Run( vars, log ): utils.makedirs( SYSIMG_PATH ) - for filesystem in ("root","vservers"): + # xxx - TODO - need to fsck the btrfs partition + if vars['virt'] == 'vs': + filesystems_tocheck = ['root', 'vservers'] + else: + filesystems_tocheck = ['root'] + for filesystem in filesystems_tocheck: try: # first run fsck to prevent fs corruption from hanging mount... log.write( "fsck %s file system\n" % filesystem ) @@ -122,8 +127,11 @@ def Run( vars, log ): try: VSERVERS_PATH = "%s/vservers" % SYSIMG_PATH utils.makedirs(VSERVERS_PATH) - log.write( "mounting vserver partition in root file system\n" ) - utils.sysexec("mount -t ext3 %s %s" % (PARTITIONS["vservers"], VSERVERS_PATH), log) + log.write( "mounting vservers partition in root file system\n" ) + if vars['virt']=='vs': + utils.sysexec("mount -t ext3 %s %s" % (PARTITIONS["vservers"], VSERVERS_PATH), log) + else: + utils.sysexec("mount -t btrfs %s %s" % (PARTITIONS["vservers"], VSERVERS_PATH), log) except BootManagerException, e: log.write( "BootManagerException during mount of /vservers: %s\n" % str(e) ) return -2 @@ -135,7 +143,11 @@ def Run( vars, log ): # these 2 links are created by our kernel's post-install scriplet log.write("Checking for a custom kernel\n") try: - os.stat("%s/boot/kernel-boot" % SYSIMG_PATH) + if vars['virt'] == 'vs': + os.stat("%s/boot/kernel-boot" % SYSIMG_PATH) + else: + kversion = os.popen("chroot %s rpm -qa kernel | tail -1 | cut -c 8-" % SYSIMG_PATH).read().rstrip() + os.stat("%s/boot/vmlinuz-%s" % (SYSIMG_PATH,kversion)) except OSError, e: log.write( "Couldn't locate base kernel (you might be using the stock kernel).\n") return -3 diff --git a/source/steps/WriteModprobeConfig.py b/source/steps/WriteModprobeConfig.py index 378802d..de1fe85 100644 --- a/source/steps/WriteModprobeConfig.py +++ b/source/steps/WriteModprobeConfig.py @@ -36,6 +36,8 @@ def Run( vars, log, filename = "/etc/modprobe.conf"): # if the network modules are activated in a different order that the # boot cd. + log.write( "\n\nStep: WriteModProbeConfig.\n" ) + # make sure we have this class loaded try: -- 2.43.0