Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial work to enable having blankspace partition in a separate loca…

…tion. Untested.

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.
  • Loading branch information...
commit 4a5463bc0faac2a31f266bc61e5637be831939ed 1 parent e76e91f
Michael Paterson authored
1  control/etc/workspace-control/images.conf
View
@@ -28,7 +28,6 @@ securelocaldir: secureimages
# - 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 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 var directory (see "dirs.conf")
85 control/src/python/workspacecontrol/defaults/imageprocurement/propagate_common.py
View
@@ -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")
@@ -184,7 +186,44 @@ 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:
+ raise InvalidConfig("no images->%s configuration" % (confname))
+ # Alternatively
+ #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 +310,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 +336,7 @@ def process_after_shutdown(self, local_file_set):
self._unpropagate(l_files)
self._destroy_instance_dir()
+ self._destroy_blankspace_dir()
# --------------------------------------------------------------------------
@@ -314,6 +355,7 @@ def process_after_destroy(self, local_file_set):
"""
self._destroy_instance_dir()
+ self._destroy_blankspace_dir()
# --------------------------------------------------------------------------
@@ -359,6 +401,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(sc_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 +429,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_blankspacedir()
+ if os.path.exists(vmdir):
+ return
+ self.c.log.info("Creating VM's blankspace directory: %s" % blankspacedir)
+ os.mkdir(blankspacedir)
+ os.chmod(vmdir, 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)
+ shutuil.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)
@@ -476,7 +542,7 @@ def _blankspace(self, l_files):
if l_file._blankspace == 0:
continue
- cmd = "%s %s %s" % (self.blankcreate_path, l_file.path, l_file._blankspace)
+ cmd = "%s %s %s" % (self.blankcreate_path, l_file.blankspacepath, l_file._blankspace)
self.c.log.debug("running '%s'" % cmd)
if self.c.dryrun:
self.c.log.debug("(dryrun, not running that)")
@@ -492,7 +558,7 @@ def _blankspace(self, l_files):
errmsg += ": %d ::: output:\n%s" % (ret, output)
raise EnvironmentProblem(errmsg)
else:
- self.c.log.info("blank partition of size %dMB created at '%s'" % (l_file._blankspace, l_file.path))
+ self.c.log.info("blank partition of size %dMB created at '%s'" % (l_file._blankspace, l_file.blankspacepath))
# --------------------------------------------------------------------------
# _process_image_args(), IMPL of common validation/preparation functionality
@@ -627,6 +693,7 @@ def _one_imagestr(self, logstr, imgstr, unprop=False, new_unprop=None):
# These are the fields the LocalFile interface expects:
lf.path = None
+ lf.blankspacepath = None
lf.mountpoint = None # not set in this method
lf.rootdisk = False # not set in this method
lf.editable = True
@@ -746,14 +813,14 @@ def _one_imagestr_blankcreate(self, lf, imgstr):
except:
raise InvalidInput("blank partition name is expected to have embedded size")
- lf.path = self._derive_instance_dir()
- lf.path = os.path.join(lf.path, blank_filename)
+ lf.blankspacepath = self._derive_blankspace_dir()
+ lf.blankspacepath = os.path.join(lf.blankspacepath, blank_filename)
- if os.path.exists(lf.path):
- raise InvalidInput("blank partition is going to be created but the file exists already: '%s'" % lf.path)
+ if os.path.exists(lf.blankspacepath):
+ raise InvalidInput("blank partition is going to be created but the file exists already: '%s'" % lf.blankspacepath)
if self.c.trace:
- self.c.log.debug("partition of size %dM is going to be created (blankcreate) at '%s'" % (lf._blankspace, lf.path))
+ self.c.log.debug("partition of size %dM is going to be created (blankcreate) at '%s'" % (lf._blankspace, lf.blankspacepath))
def _one_imagestr_propagation(self, lf, imgstr, unprop, new_unprop):
Please sign in to comment.
Something went wrong with that request. Please try again.