X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sliver_lxc.py;h=44194ed7d7cba61acd18326738e68026667f2715;hb=ecee05390277f57b02d21ffca0195292bde1defa;hp=7f548b5c196c7de740865b8f11bb704376fc282e;hpb=67cbe5b1dc88eda5766770f876b7f9bc5a4d1d4c;p=nodemanager.git diff --git a/sliver_lxc.py b/sliver_lxc.py index 7f548b5..44194ed 100644 --- a/sliver_lxc.py +++ b/sliver_lxc.py @@ -13,7 +13,7 @@ from string import Template # vsys probably should not be a plugin # the thing is, the right way to handle stuff would be that # if slivers get created by doing a,b,c -# then they sohuld be delted by doing c,b,a +# then they should be deleted by doing c,b,a # the current ordering model for vsys plugins completely fails to capture that from plugins.vsys import removeSliverFromVsys, startService as vsysStartService @@ -25,6 +25,8 @@ from initscript import Initscript from account import Account from sliver_libvirt import Sliver_Libvirt +BTRFS_TIMEOUT=15*60 + class Sliver_LXC(Sliver_Libvirt, Initscript): """This class wraps LXC commands""" @@ -76,6 +78,19 @@ class Sliver_LXC(Sliver_Libvirt, Initscript): logger.verbose ('sliver_lxc: %s create'%(name)) conn = Sliver_Libvirt.getConnection(Sliver_LXC.TYPE) + vref = rec['vref'] + if vref is None: + vref = "lxc-f18-x86_64" + logger.log("sliver_libvirt: %s: WARNING - no vref attached, using hard-wired default %s" % (name,vref)) + + # compute guest arch from vref + # essentially we want x86_64 (default) or i686 here for libvirt + try: + (x,y,arch)=vref.split('-') + arch = "x86_64" if arch.find("64")>=0 else "i686" + except: + arch='x86_64' + # Get the type of image from vref myplc tags specified as: # pldistro = lxc # fcdistro = squeeze @@ -88,10 +103,8 @@ class Sliver_LXC(Sliver_Libvirt, Initscript): if arch == 'i386': arch = 'i686' - vref = rec['vref'] - if vref is None: - vref = "lxc-f18-x86_64" - logger.log("sliver_libvirt: %s: WARNING - no vref attached, using hard-wired default %s" % (name,vref)) + + refImgDir = os.path.join(Sliver_LXC.REF_IMG_BASE_DIR, vref) containerDir = os.path.join(Sliver_LXC.CON_BASE_DIR, name) @@ -102,37 +115,31 @@ class Sliver_LXC(Sliver_Libvirt, Initscript): logger.log('sliver_lxc: %s: ERROR Expected reference image in %s'%(name,refImgDir)) return - # in fedora20 we have some difficulty in properly cleaning up /vservers/ - # also note that running e.g. btrfs subvolume create /vservers/.lvref/image /vservers/foo - # behaves differently, whether /vservers/foo exists or not: - # if /vservers/foo does not exist, it creates /vservers/foo - # but if it does exist, then it creates /vservers/foo/image !! - # so we need to check the expected container rootfs does not exist yet - if not os.path.exists (containerDir): - pass - else: - # if it's empty then let's clean it up - if not os.listdir(containerDir): - # clean up rootfs as userdel will only take care of /home/ - logger.log("sliver_lxc: %s: WARNING cleaning up empty %s"%(name,containerDir)) - command = ['btrfs', 'subvolume', 'delete', containerDir] - logger.log_call(command, timeout=60) - # re-check - if os.path.exists (containerDir): - logger.log('sliver_lxc: %s: ERROR Could not create sliver - could not clean up empty %s'%(name,containerDir)) - return - else: - logger.log('sliver_lxc: %s: ERROR Could not create sliver - could not clean up pre-existing %s'%(name,containerDir)) - return +# this hopefully should be fixed now +# # in fedora20 we have some difficulty in properly cleaning up /vservers/ +# # also note that running e.g. btrfs subvolume create /vservers/.lvref/image /vservers/foo +# # behaves differently, whether /vservers/foo exists or not: +# # if /vservers/foo does not exist, it creates /vservers/foo +# # but if it does exist, then it creates /vservers/foo/image !! +# # so we need to check the expected container rootfs does not exist yet +# # this hopefully could be removed in a future release +# if os.path.exists (containerDir): +# logger.log("sliver_lxc: %s: WARNING cleaning up pre-existing %s"%(name,containerDir)) +# command = ['btrfs', 'subvolume', 'delete', containerDir] +# logger.log_call(command, BTRFS_TIMEOUT) +# # re-check +# if os.path.exists (containerDir): +# logger.log('sliver_lxc: %s: ERROR Could not create sliver - could not clean up empty %s'%(name,containerDir)) +# return # Snapshot the reference image fs (assume the reference image is in its own # subvolume) command = ['btrfs', 'subvolume', 'snapshot', refImgDir, containerDir] - if not logger.log_call(command, timeout=15*60): + if not logger.log_call(command, timeout=BTRFS_TIMEOUT): logger.log('sliver_lxc: ERROR Could not create BTRFS snapshot at', containerDir) return command = ['chmod', '755', containerDir] - logger.log_call(command, timeout=15*60) + logger.log_call(command) # TODO: set quotas... @@ -145,28 +152,28 @@ class Sliver_LXC(Sliver_Libvirt, Initscript): group = grp.getgrnam('slices') except: command = ['/usr/sbin/groupadd', 'slices'] - logger.log_call(command, timeout=15*60) + logger.log_call(command) # Add unix account (TYPE is specified in the subclass) command = ['/usr/sbin/useradd', '-g', 'slices', '-s', Sliver_LXC.SHELL, name, '-p', '*'] - logger.log_call(command, timeout=15*60) + logger.log_call(command) command = ['mkdir', '/home/%s/.ssh'%name] - logger.log_call(command, timeout=15*60) + logger.log_call(command) # Create PK pair keys to connect from the host to the guest without # password... maybe remove the need for authentication inside the # guest? command = ['su', '-s', '/bin/bash', '-c', 'ssh-keygen -t rsa -N "" -f /home/%s/.ssh/id_rsa'%(name)] - logger.log_call(command, timeout=60) + logger.log_call(command) command = ['chown', '-R', '%s.slices'%name, '/home/%s/.ssh'%name] - logger.log_call(command, timeout=30) + logger.log_call(command) command = ['mkdir', '%s/root/.ssh'%containerDir] - logger.log_call(command, timeout=10) + logger.log_call(command) command = ['cp', '/home/%s/.ssh/id_rsa.pub'%name, '%s/root/.ssh/authorized_keys'%containerDir] - logger.log_call(command, timeout=30) + logger.log_call(command) logger.log("creating /etc/slicename file in %s" % os.path.join(containerDir,'etc/slicename')) try: @@ -189,9 +196,9 @@ class Sliver_LXC(Sliver_Libvirt, Initscript): if uid is not None: logger.log("uid is %d" % uid) command = ['mkdir', '%s/home/%s' % (containerDir, name)] - logger.log_call(command, timeout=10) + logger.log_call(command) command = ['chown', name, '%s/home/%s' % (containerDir, name)] - logger.log_call(command, timeout=10) + logger.log_call(command) etcpasswd = os.path.join(containerDir, 'etc/passwd') etcgroup = os.path.join(containerDir, 'etc/group') if os.path.exists(etcpasswd): @@ -215,7 +222,7 @@ class Sliver_LXC(Sliver_Libvirt, Initscript): logger.log_exc("exception while updating /etc/sudoers") # customizations for the user environment - root or slice uid - # we save the whole business in /etc/planetlab.profile + # we save the whole business in /etc/planetlab.profile # and source this file for both root and the slice uid's .profile # prompt for slice owner, + LD_PRELOAD for transparently wrap bind pl_profile=os.path.join(containerDir,"etc/planetlab.profile") @@ -251,7 +258,7 @@ unset pathmunge # if dir is not yet existing let's forget it for now if not os.path.isdir(os.path.dirname(from_root)): continue found=False - try: + try: contents=file(from_root).readlines() for content in contents: if content==enforced_line: found=True @@ -262,7 +269,7 @@ unset pathmunge # in case we create the slice's .profile when writing if from_root.find("/home")>=0: command=['chown','%s:slices'%name,from_root] - logger.log_call(command,timeout=5) + logger.log_call(command) # Lookup for xid and create template after the user is created so we # can get the correct xid based on the name of the slice @@ -330,12 +337,12 @@ unset pathmunge # Remove user after destroy domain to force logout command = ['/usr/sbin/userdel', '-f', '-r', name] - logger.log_call(command, timeout=15*60) + logger.log_call(command) # Remove rootfs of destroyed domain command = ['btrfs', 'subvolume', 'delete', containerDir] - logger.log_call(command, timeout=10) - + logger.log_call(command, timeout=BTRFS_TIMEOUT) + # For some reason I am seeing this : #log_call: running command btrfs subvolume delete /vservers/inri_sl1 #log_call: ERROR: cannot delete '/vservers/inri_sl1' - Device or resource busy @@ -351,10 +358,12 @@ unset pathmunge if not os.path.exists(containerDir): logger.log('sliver_lxc.destroy: %s cleanly destroyed.'%name) else: - logger.log("-TMP-cwd %s : %s"%(name,os.getcwd())) - logger.log("-TMP-lsof %s"%name) - command=['lsof'] - logger.log_call(command) + # we're in / + #logger.log("-TMP-cwd %s : %s"%(name,os.getcwd())) + # also lsof never shows anything relevant; this is painful.. + #logger.log("-TMP-lsof %s"%name) + #command=['lsof'] + #logger.log_call(command) logger.log("-TMP-ls-l %s"%name) command = ['ls', '-l', containerDir] logger.log_call(command)