Permalink
Browse files

Enable having blankspace partition in a separate location

On a cloud setup where large amounts of blankspace are required it was
deemed desireable to have the image directory split from the blankspace
file. This would hopefully allow the IO load to be spread out.

Closes #83 and #86.
  • Loading branch information...
1 parent 1ebff8c commit b3c469d2d98a941641357427cb449ab8f4c1e647 @mhpx mhpx committed with priteau Jan 12, 2012
@@ -24,14 +24,24 @@ localdir: images
securelocaldir: secureimages
+# blankspace partition directory
+# - this directory is where instance specific images that use blankspace
+# will create their partition
+# - this can be the same or separate from the securelocaldir for performance
+# - if this setting is a relative path, it will be resolved from the
+# workspace-control specific var directory (see "dirs.conf")
+
+blankspacedir: secureimages
+
# blankcreate script
-# - this is called when making a blankspace partition. This is not called
-# under sudo. It's just separated into a script for easier replacement or
-# customization.
-# - if this setting is a relative path, it will be resolved from the
+# - this is called when making a blankspace partition. This is not called
+# under sudo. It's just separated into a script for easier replacement or
+# customization.
+# - if left blank if will default to the securelocaldir location
+# - if this setting is a relative path, it will be resolved from the
# workspace-control specific libexec directory (see "dirs.conf")
-# - if this setting is missing or blank, the blankspace functionality will
-# be disabled
+# - if this setting is missing or blank, the blankspace functionality will
+# be disabled
blankcreate: blankcreate.sh
@@ -43,6 +43,7 @@ def __init__(self, params, common):
self.c = common
self.localdir = None
self.securelocaldir = None
+ self.blankspacedir = None
self.adapters = None # dict: {keyword: instance of PropagationAdapter}
@@ -56,7 +57,8 @@ def validate(self):
self.blankcreate_path = None
self._validate_blankspacecreate()
-
+ self.blankspacedir = self._validate_blankspacedir("blankspacedir")
+
self.adapters = {}
cp_path = self.p.get_conf_or_none("propagation", "cp")
@@ -158,7 +160,7 @@ def _validate_securelocaldir(self, confname):
if not os.path.exists(securelocaldir):
self.c.log.warn("%s is configured, but '%s' does not"
- " exist on the filesystem, attemping to create "
+ " exist on the filesystem, attemping to create"
" it" % (confname, securelocaldir))
try:
os.mkdir(securelocaldir)
@@ -184,7 +186,42 @@ def _validate_securelocaldir(self, confname):
self.c.log.debug("secure image directory (per-instance images): %s" % self.securelocaldir)
return securelocaldir
-
+
+ def _validate_blankspacedir(self, confname):
+ blankspacedir = self.p.get_conf_or_none("images", confname)
+ if not blankspacedir:
+ blankspacedir = self.securelocaldir
+
+ if not os.path.isabs(blankspacedir):
+ blankspacedir = self.c.resolve_var_dir(blankspacedir)
+
+ if not os.path.exists(blankspacedir):
+ self.c.log.warn("%s is configured, but '%s' does not"
+ " exist on the filesystem, attemping to create"
+ " it" % (confname, blankspacedir))
+ try:
+ os.mkdir(blankspacedir)
+ os.chmod(blankspacedir, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
+ except:
+ exception_type = sys.exc_type
+ try:
+ exceptname = exception_type.__name__
+ except AttributeError:
+ exceptname = exception_type
+ raise InvalidConfig("Problem creating %s: %s: %s"
+ % (confname, str(exceptname), str(sys.exc_value)))
+ self.c.log.warn("created blankspace dir '%s'" % blankspacedir)
+
+ x = os.access(blankspacedir, os.W_OK | os.X_OK | os.R_OK)
+ if x:
+ self.c.log.debug("'%s' exists on the filesystem and is "
+ "rwx-able" % blankspacedir)
+ else:
+ raise InvalidConfig("'%s' exists on the filesystem but is not rwx"
+ % blankspacedir)
+ self.c.log.debug("blankspace partition directory (per-instance blankspace): %s" % self.blankspacedir)
+ return blankspacedir
+
def _validate_blankspacecreate(self):
blankcreate_path = self.p.get_conf_or_none("images", "blankcreate")
if not blankcreate_path:
@@ -271,6 +308,7 @@ def obtain(self):
if action == ACTIONS.CREATE:
if self._is_blankspace_needed(l_files):
+ self._ensure_blankspace_dir()
self._blankspace(l_files)
local_file_set_cls = self.c.get_class_by_keyword("LocalFileSet")
@@ -296,6 +334,7 @@ def process_after_shutdown(self, local_file_set):
self._unpropagate(l_files)
self._destroy_instance_dir()
+ self._destroy_blankspace_dir()
# --------------------------------------------------------------------------
@@ -314,6 +353,7 @@ def process_after_destroy(self, local_file_set):
"""
self._destroy_instance_dir()
+ self._destroy_blankspace_dir()
# --------------------------------------------------------------------------
@@ -359,6 +399,13 @@ def _derive_instance_dir(self):
raise InvalidInput("The %s argument is required." % wc_args.NAME.long_syntax)
vm_securedir = os.path.join(self.securelocaldir, vm_name)
return vm_securedir
+
+ def _derive_blankspace_dir(self):
+ vm_name = self.p.get_arg_or_none(wc_args.NAME)
+ if not vm_name:
+ raise InvalidInput("The %s argument is required." % wc_args.NAME.long_syntax)
+ vm_blankspacedir = os.path.join(self.blankspacedir, vm_name)
+ return vm_blankspacedir
# --------------------------------------------------------------------------
# IMPLs for actual actions the module takes
@@ -380,6 +427,23 @@ def _destroy_instance_dir(self):
self.c.log.debug("Destroying %s" % vmdir)
shutil.rmtree(vmdir)
self.c.log.info("Destroyed VM's unique directory: %s" % vmdir)
+
+ def _ensure_blankspace_dir(self):
+ blankspacedir = self._derive_blankspace_dir()
+ if os.path.exists(blankspacedir):
+ return
+ self.c.log.info("Creating VM's blankspace directory: %s" % blankspacedir)
+ os.mkdir(blankspacedir)
+ os.chmod(blankspacedir, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
+ self.c.log.debug("created %s" % blankspacedir)
+
+ def _destroy_blankspace_dir(self):
+ blankspacedir = self._derive_blankspace_dir()
+ if not os.path.exists(blankspacedir):
+ return
+ self.c.log.debug("Destroying %s" % blankspacedir)
+ shutil.rmtree(blankspacedir)
+ self.c.log.info("Destroyed VM's unique blankspace directory: %s" % blankspacedir)
def _propagate(self, l_files):
cache_key = self.p.get_arg_or_none(wc_args.CACHECKSUM)
@@ -747,8 +811,8 @@ def _one_imagestr_blankcreate(self, lf, imgstr):
lf._blankspace = int(size)
except:
raise InvalidInput("blank partition name is expected to have embedded size")
-
- lf.path = self._derive_instance_dir()
+
+ lf.path = self._derive_blankspace_dir()
lf.path = os.path.join(lf.path, blank_filename)
if os.path.exists(lf.path):

0 comments on commit b3c469d

Please sign in to comment.