diff --git a/molecule/handlers.py b/molecule/handlers.py index a6fb1c1..0b97e65 100644 --- a/molecule/handlers.py +++ b/molecule/handlers.py @@ -165,7 +165,7 @@ class ChrootHandler(GenericHandlerInterface): # now remove paths to empty empty_paths = self.metadata.get('paths_to_empty',[]) for mypath in empty_paths: - mypath = os.path.join(self.dest_dir,mypath) + mypath = self.dest_dir+mypath self.Output.updateProgress("[%s|%s] %s: %s" % (blue("ChrootHandler"),darkred(self.spec_name),_("emptying dir"),mypath,)) if os.path.isdir(mypath): molecule.utils.empty_dir(mypath) @@ -173,9 +173,8 @@ class ChrootHandler(GenericHandlerInterface): # now remove paths to remove (...) remove_paths = self.metadata.get('paths_to_remove',[]) for mypath in remove_paths: - mypath = os.path.join(self.dest_dir,mypath) + mypath = self.dest_dir+mypath self.Output.updateProgress("[%s|%s] %s: %s" % (blue("ChrootHandler"),darkred(self.spec_name),_("removing dir"),mypath,)) - if not os.path.lexists(mypath): continue rc = molecule.utils.remove_path(mypath) if rc != 0: self.Output.updateProgress("[%s|%s] %s: %s: %s" % (blue("ChrootHandler"),darkred(self.spec_name),_("removal failed for"),mypath,rc,)) @@ -194,7 +193,7 @@ class CdrootHandler(GenericHandlerInterface): self.Output.updateProgress("[%s|%s] %s" % (blue("CdrootHandler"),darkred(self.spec_name),_("preparing environment"),)) self.source_chroot = os.path.join(self.metadata['destination_chroot'],"chroot",os.path.basename(self.metadata['source_chroot'])) - self.dest_root = os.path.join(self.Config['destination_livecd_root'],"livecd",os.path.basename(self.metadata['source_chroot'])) + self.dest_root = os.path.join(self.metadata['destination_livecd_root'],"livecd",os.path.basename(self.metadata['source_chroot'])) if os.path.isdir(self.dest_root): molecule.utils.empty_dir(self.dest_root) if not os.path.isdir(self.dest_root): @@ -214,12 +213,13 @@ class CdrootHandler(GenericHandlerInterface): self.Output.updateProgress("[%s|%s] %s" % (blue("CdrootHandler"),darkred(self.spec_name),_("compressing chroot"),)) args = [self.Config['chroot_compressor']] - args.extend(self.Config['chroot_compressor_builtin_args']) - args.extend(self.metadata.get('extra_mksquashfs_parameters',[])) comp_output = self.Config['chroot_compressor_output_file'] if "chroot_compressor_output_file" in self.metadata: comp_output = self.metadata.get('chroot_compressor_output_file') + comp_output = os.path.join(self.dest_root,comp_output) args.extend([self.source_chroot,comp_output]) + args.extend(self.Config['chroot_compressor_builtin_args']) + args.extend(self.metadata.get('extra_mksquashfs_parameters',[])) self.Output.updateProgress("[%s|%s] %s: %s" % (blue("CdrootHandler"),darkred(self.spec_name),_("spawning"),args,)) rc = molecule.utils.exec_cmd(args) if rc != 0: @@ -228,13 +228,35 @@ class CdrootHandler(GenericHandlerInterface): self.Output.updateProgress("[%s|%s] %s" % (blue("CdrootHandler"),darkred(self.spec_name),_("chroot compressed successfully"),)) # merge dir - merge_dir = self.Config['merge_livecd_root'] - self.Output.updateProgress("[%s|%s] %s %s" % (blue("CdrootHandler"),darkred(self.spec_name),_("merging livecd root"),merge_dir,)) - try: - shutil.copytree(merge_dir,self.dest_root) - except shutil.error, e: - self.Output.updateProgress("[%s|%s] %s: %s" % (blue("CdrootHandler"),darkred(self.spec_name),_("error during livecd root copy"),e,)) - return 1 + merge_dir = self.metadata.get('merge_livecd_root') + if merge_dir: + if os.path.isdir(merge_dir): + self.Output.updateProgress("[%s|%s] %s %s" % ( + blue("CdrootHandler"),darkred(self.spec_name), + _("merging livecd root"),merge_dir,) + ) + import stat + content = os.listdir(merge_dir) + for mypath in content: + mysource = os.path.join(merge_dir,mypath) + mydest = os.path.join(self.dest_root,mypath) + copystat = False + + if os.path.islink(mysource): + tolink = os.readlink(mysource) + os.symlink(tolink,mydest) + elif os.path.isfile(mysource) or os.path.islink(mysource): + copystat = True + shutil.copy2(mysource,mydest) + elif os.path.isdir(mysource): + copystat = True + shutil.copytree(mysource,mydest) + + if copystat: + user = os.stat(mysource)[stat.ST_UID] + group = os.stat(mysource)[stat.ST_GID] + os.chown(mydest,user,group) + shutil.copystat(mysource,mydest) return 0 @@ -247,19 +269,22 @@ class IsoHandler(GenericHandlerInterface): self.Output.updateProgress("[%s|%s] %s" % (blue("IsoHandler"),darkred(self.spec_name),_("executing pre_run"),)) # setup paths - self.source_path = os.path.join(self.Config['destination_livecd_root'],"livecd",os.path.basename(self.metadata['source_chroot'])) + self.source_path = os.path.join(self.metadata['destination_livecd_root'],"livecd",os.path.basename(self.metadata['source_chroot'])) dest_iso_dir = self.metadata['destination_iso_directory'] if not os.path.isdir(dest_iso_dir): os.makedirs(dest_iso_dir,0755) dest_iso_filename = self.metadata.get('destination_iso_image_name') + release_string = self.metadata.get('release_string','') + release_version = self.metadata.get('release_version','') + release_desc = self.metadata.get('release_desc','') if not dest_iso_filename: - dest_iso_filename = "%s_%s_%s.iso" ( - self.metadata.get('release_string','').replace(' ','_'), - self.metadata.get('release_version','').replace(' ','_'), - self.metadata.get('release_desc','').replace(' ','_'), + dest_iso_filename = "%s_%s_%s.iso" % ( + release_string.replace(' ','_'), + release_version.replace(' ','_'), + release_desc.replace(' ','_'), ) self.dest_iso = os.path.join(dest_iso_dir,dest_iso_filename) - self.iso_title = "%s %s %s" % (self.metadata.get('release_string',''), self.metadata.get('release_version',''), self.metadata.get('release_desc',''),) + self.iso_title = "%s %s %s" % (release_string, release_version, release_desc,) self.source_chroot = self.metadata['source_chroot'] self.chroot_dir = os.path.join(self.metadata['destination_chroot'],"chroot",os.path.basename(self.source_chroot)) @@ -292,7 +317,7 @@ class IsoHandler(GenericHandlerInterface): args.extend(self.Config['iso_builder_builtin_args']) args.extend(self.metadata.get('extra_mkisofs_parameters',[])) if self.iso_title.strip(): - args.extend(["-V",self.iso_title]) + args.extend(["-V",'"',self.iso_title,'"']) args.extend(['-o',self.dest_iso,self.source_path]) self.Output.updateProgress("[%s|%s] %s: %s" % (blue("IsoHandler"),darkred(self.spec_name),_("spawning"),args,)) rc = molecule.utils.exec_cmd(args) diff --git a/molecule/settings.py b/molecule/settings.py index 7f9db5e..215a6ca 100644 --- a/molecule/settings.py +++ b/molecule/settings.py @@ -115,6 +115,9 @@ class SpecParser: def __init__(self, filepath): def ne_string(x): + return x,'raw_unicode_escape' + + def ne_list(x): return x def always_valid(*args): @@ -130,14 +133,14 @@ class SpecParser: return os.path.isdir(x) def ve_string_stripper(x): - return x.strip() + return unicode(x,'raw_unicode_escape').strip() def ve_string_splitter(x): - return x.strip().split() + return unicode(x,'raw_unicode_escape').strip().split() def valid_exec(x): molecule.utils.is_exec_available(x) - return True + return x def valid_ascii(x): try: @@ -154,12 +157,13 @@ class SpecParser: return True def valid_path_list(x): - return [x for x in x.split(",") if valid_path_string(x)] + return [y.strip() for y in unicode(x,'raw_unicode_escape').split(",") if valid_path_string(y) and y.strip()] self.vital_parameters = [ "release_string", "source_chroot", "destination_iso_directory", + "destination_livecd_root", ] self.parser_data_path = { 'prechroot': { @@ -221,6 +225,7 @@ class SpecParser: 'extra_mkisofs_parameters': { 'cb': always_valid, 've': ve_string_splitter, + 'mod': ve_string_splitter, }, 'pre_iso_script': { 'cb': valid_exec, @@ -235,12 +240,12 @@ class SpecParser: 've': ve_string_stripper, }, 'paths_to_remove': { - 'cb': valid_path_list, - 've': ve_string_stripper, + 'cb': ne_list, + 've': valid_path_list, }, 'paths_to_empty': { - 'cb': valid_path_list, - 've': ve_string_stripper, + 'cb': ne_list, + 've': valid_path_list, }, } @@ -267,7 +272,11 @@ class SpecParser: def validate_parse(self, mydata): for param in self.vital_parameters: if param not in mydata: - raise SpecFileError("SpecFileError: '%s' missing or invalid '%s' parameter, it's vital. Your specification file is incomplete!" % (self.filepath,param,)) + raise SpecFileError( + "SpecFileError: '%s' missing or invalid" + " '%s' parameter, it's vital. Your specification" + " file is incomplete!" % (self.filepath,param,) + ) def __generic_parser(self, filepath): with open(filepath,"r") as f: diff --git a/molecule/utils.py b/molecule/utils.py index 42edeeb..9136dec 100644 --- a/molecule/utils.py +++ b/molecule/utils.py @@ -21,6 +21,7 @@ from __future__ import with_statement import os import time import subprocess +import shutil from molecule.exception import EnvironmentError def get_year(): @@ -72,7 +73,7 @@ def empty_dir(dest_dir): # using subprocess.call to not care about wildcards def remove_path(path): - return subprocess.call('rm -rf "%s"' % (path,), shell = True) + return subprocess.call('rm -rf %s' % (path,), shell = True) def get_random_number(): return abs(hash(os.urandom(2)))%99999