[molecule] move code to plugins, implement fuzzy iso_remaster plugin
This commit is contained in:
+7
-514
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/python -O
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
# Molecule Disc Image builder for Sabayon Linux
|
||||
# Copyright (C) 2009 Fabio Erculiani
|
||||
#
|
||||
@@ -16,523 +16,16 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
from __future__ import with_statement
|
||||
import os
|
||||
import shutil
|
||||
from molecule.i18n import _
|
||||
from molecule.output import red, brown, blue, green, purple, darkgreen, \
|
||||
darkred, bold, darkblue, readtext
|
||||
import molecule.utils
|
||||
from molecule.output import brown, darkgreen
|
||||
from molecule.specs.skel import GenericExecutionStep
|
||||
|
||||
# This is an interface that has to be reimplemented in order to make
|
||||
# it doing something useful
|
||||
class GenericHandlerInterface:
|
||||
|
||||
class Runner(GenericExecutionStep):
|
||||
|
||||
def __init__(self, spec_path, metadata):
|
||||
from molecule import Output, Config
|
||||
self.Output = Output
|
||||
self.Config = Config
|
||||
self.spec_path = spec_path
|
||||
self.metadata = metadata
|
||||
self.spec_name = os.path.basename(self.spec_path)
|
||||
|
||||
def pre_run(self):
|
||||
raise NotImplementedError("this needs to be reimplemented")
|
||||
|
||||
def run(self):
|
||||
raise NotImplementedError("this needs to be reimplemented")
|
||||
|
||||
def post_run(self):
|
||||
raise NotImplementedError("this needs to be reimplemented")
|
||||
|
||||
def kill(self):
|
||||
raise NotImplementedError("this needs to be reimplemented")
|
||||
|
||||
class MirrorHandler(GenericHandlerInterface):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericHandlerInterface.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
|
||||
# creating destination chroot dir
|
||||
self.source_dir = self.metadata['source_chroot']
|
||||
self.dest_dir = os.path.join(
|
||||
self.metadata['destination_chroot'],"chroot",
|
||||
os.path.basename(self.source_dir)
|
||||
)
|
||||
if not os.path.isdir(self.dest_dir):
|
||||
os.makedirs(self.dest_dir,0755)
|
||||
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("mirroring running"),
|
||||
)
|
||||
)
|
||||
# running sync
|
||||
args = [self.Config['mirror_syncer']]
|
||||
args.extend(self.Config['mirror_syncer_builtin_args'])
|
||||
args.extend(self.metadata.get('extra_rsync_parameters',[]))
|
||||
args.extend([self.source_dir+"/*",self.dest_dir])
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("spawning"),args,
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.exec_cmd(args)
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("mirroring failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("mirroring completed successfully"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
class ChrootHandler(GenericHandlerInterface):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericHandlerInterface.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
self.source_dir = self.metadata['source_chroot']
|
||||
self.dest_dir = os.path.join(
|
||||
self.metadata['destination_chroot'],"chroot",
|
||||
os.path.basename(self.source_dir)
|
||||
)
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
|
||||
# write release file
|
||||
release_file = self.metadata.get('release_file')
|
||||
if isinstance(release_file,basestring) and release_file:
|
||||
if release_file[0] == os.sep: release_file = release_file[len(os.sep):]
|
||||
release_file = os.path.join(self.dest_dir,release_file)
|
||||
if os.path.lexists(release_file) and not os.path.isfile(release_file):
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("release file creation failed, not a file"),
|
||||
release_file,
|
||||
)
|
||||
)
|
||||
return 1
|
||||
release_string = self.metadata.get('release_string','')
|
||||
release_version = self.metadata.get('release_version','')
|
||||
release_desc = self.metadata.get('release_desc','')
|
||||
file_string = "%s %s %s\n" % (release_string,release_version,release_desc,)
|
||||
try:
|
||||
f = open(release_file,"w")
|
||||
f.write(file_string)
|
||||
f.flush()
|
||||
f.close()
|
||||
except (IOError,OSError,), e:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("release file creation failed, system error"),
|
||||
release_file,e,
|
||||
)
|
||||
)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),
|
||||
darkred(self.spec_name),_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("hooks running"),
|
||||
)
|
||||
)
|
||||
|
||||
# run inner chroot script
|
||||
exec_script = self.metadata.get('inner_chroot_script')
|
||||
if exec_script:
|
||||
if os.path.isfile(exec_script) and os.access(exec_script,os.R_OK):
|
||||
|
||||
while 1:
|
||||
tmp_dir = os.path.join(self.dest_dir,
|
||||
str(molecule.utils.get_random_number()))
|
||||
if not os.path.lexists(tmp_dir):
|
||||
break
|
||||
|
||||
os.makedirs(tmp_dir)
|
||||
tmp_exec = os.path.join(tmp_dir,"inner_exec")
|
||||
shutil.copy2(exec_script,tmp_exec)
|
||||
os.chmod(tmp_exec,0755)
|
||||
dest_exec = tmp_exec[len(self.dest_dir):]
|
||||
if not dest_exec.startswith("/"):
|
||||
dest_exec = "/%s" % (dest_exec,)
|
||||
|
||||
rc = molecule.utils.exec_chroot_cmd([dest_exec], self.dest_dir,
|
||||
self.metadata.get('prechroot',[]))
|
||||
os.remove(tmp_exec)
|
||||
os.rmdir(tmp_dir)
|
||||
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("inner chroot hook failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
# run outer chroot script
|
||||
exec_script = self.metadata.get('outer_chroot_script')
|
||||
if exec_script:
|
||||
os.environ['CHROOT_DIR'] = self.source_dir
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("spawning"),[exec_script],
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.exec_cmd([exec_script])
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("outer chroot hook failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
# now remove paths to empty
|
||||
empty_paths = self.metadata.get('paths_to_empty',[])
|
||||
for mypath in empty_paths:
|
||||
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)
|
||||
|
||||
# now remove paths to remove (...)
|
||||
remove_paths = self.metadata.get('paths_to_remove',[])
|
||||
|
||||
# setup sandbox
|
||||
sb_dirs = [self.dest_dir]
|
||||
sb_env = {
|
||||
'SANDBOX_WRITE': ':'.join(sb_dirs),
|
||||
}
|
||||
myenv = os.environ.copy()
|
||||
myenv.update(sb_env)
|
||||
|
||||
for mypath in remove_paths:
|
||||
mypath = self.dest_dir+mypath
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("removing dir"),mypath,
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.remove_path_sandbox(mypath, sb_env)
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("removal failed for"),mypath,rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("hooks completed succesfully"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
class CdrootHandler(GenericHandlerInterface):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericHandlerInterface.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
|
||||
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.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):
|
||||
os.makedirs(self.dest_root,0755)
|
||||
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("compressing chroot"),
|
||||
)
|
||||
)
|
||||
args = [self.Config['chroot_compressor']]
|
||||
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:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("chroot compression failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("chroot compressed successfully"),
|
||||
)
|
||||
)
|
||||
|
||||
# merge dir
|
||||
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
|
||||
|
||||
class IsoHandler(GenericHandlerInterface):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericHandlerInterface.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
|
||||
# setup paths
|
||||
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" % (
|
||||
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" % (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)
|
||||
)
|
||||
|
||||
# run outer chroot script
|
||||
exec_script = self.metadata.get('pre_iso_script')
|
||||
if exec_script:
|
||||
os.environ['SOURCE_CHROOT_DIR'] = self.source_chroot
|
||||
os.environ['CHROOT_DIR'] = self.chroot_dir
|
||||
os.environ['CDROOT_DIR'] = self.source_path
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("spawning"),[exec_script],
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.exec_cmd([exec_script])
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("outer chroot hook failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("building ISO image"),
|
||||
)
|
||||
)
|
||||
|
||||
args = [self.Config['iso_builder']]
|
||||
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[:32],'"'])
|
||||
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)
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("ISO image build failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("built ISO image"),self.dest_iso,
|
||||
)
|
||||
)
|
||||
if os.path.isfile(self.dest_iso) and os.access(self.dest_iso,os.R_OK):
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("generating md5 for"),self.dest_iso,
|
||||
)
|
||||
)
|
||||
digest = molecule.utils.md5sum(self.dest_iso)
|
||||
md5file = self.dest_iso+".md5"
|
||||
with open(md5file,"w") as f:
|
||||
f.write("%s %s\n" % (digest,os.path.basename(self.dest_iso),))
|
||||
f.flush()
|
||||
return 0
|
||||
|
||||
|
||||
class Runner(GenericHandlerInterface):
|
||||
|
||||
def __init__(self, spec_path, metadata):
|
||||
GenericHandlerInterface.__init__(self, spec_path, metadata)
|
||||
self.execution_order = [MirrorHandler,ChrootHandler,CdrootHandler,IsoHandler]
|
||||
GenericExecutionStep.__init__(self, spec_path, metadata)
|
||||
self.execution_order = metadata['__plugin__'].get_execution_steps()
|
||||
|
||||
def pre_run(self):
|
||||
return 0
|
||||
|
||||
@@ -15,252 +15,3 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
import os
|
||||
import molecule.utils
|
||||
|
||||
class GenericSpecFunctions:
|
||||
|
||||
def ne_string(self, x):
|
||||
return x, 'raw_unicode_escape'
|
||||
|
||||
def ne_list(self, x):
|
||||
return x
|
||||
|
||||
def always_valid(self, *args):
|
||||
return True
|
||||
|
||||
def valid_path(self, x):
|
||||
return os.path.lexists(x)
|
||||
|
||||
def valid_file(self, x):
|
||||
return os.path.isfile(x)
|
||||
|
||||
def valid_dir(self, x):
|
||||
return os.path.isdir(x)
|
||||
|
||||
def ve_string_stripper(self, x):
|
||||
return unicode(x,'raw_unicode_escape').strip()
|
||||
|
||||
def ve_string_splitter(self, x):
|
||||
return unicode(x,'raw_unicode_escape').strip().split()
|
||||
|
||||
def valid_exec(self, x):
|
||||
molecule.utils.is_exec_available(x)
|
||||
return x
|
||||
|
||||
def valid_exec_first_list_item(self, x):
|
||||
if not x:
|
||||
return False
|
||||
myx = x[0]
|
||||
molecule.utils.is_exec_available(myx)
|
||||
return True
|
||||
|
||||
def valid_ascii(self, x):
|
||||
try:
|
||||
x = str(x)
|
||||
return x
|
||||
except (UnicodeDecodeError, UnicodeEncodeError,):
|
||||
return ''
|
||||
|
||||
def valid_path_string(self, x):
|
||||
try:
|
||||
os.path.split(x)
|
||||
except OSError:
|
||||
return False
|
||||
return True
|
||||
|
||||
def valid_path_list(self, x):
|
||||
return [y.strip() for y in \
|
||||
unicode(x,'raw_unicode_escape').split(",") if \
|
||||
valid_path_string(y) and y.strip()]
|
||||
|
||||
class GenericSpec(GenericSpecFunctions):
|
||||
|
||||
EXECUTION_STRATEGY_KEY = "execution_strategy"
|
||||
|
||||
@staticmethod
|
||||
def execution_strategy():
|
||||
"""
|
||||
Return a string that describes the supported execution strategy.
|
||||
Such as "remaster", "livecd", etc.
|
||||
|
||||
@return: execution strategy string id
|
||||
@rtype: string
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def vital_parameters(self):
|
||||
"""
|
||||
Return a list of vital .spec file parameters
|
||||
|
||||
@return: list of vital .spec file parameters
|
||||
@rtype: list
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def parser_data_path(self):
|
||||
"""
|
||||
Return a dictionary containing parameter names as key and
|
||||
dict containing keys 've' and 'cb' which values are three
|
||||
callable functions that respectively do value extraction (ve),
|
||||
value verification (cb) and value modding (mod).
|
||||
|
||||
@return: data path dictionary (see ChrootSpec code for more info)
|
||||
@rtype: dict
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
class LivecdSpec(GenericSpec):
|
||||
|
||||
@staticmethod
|
||||
def execution_strategy():
|
||||
return "livecd"
|
||||
|
||||
def vital_parameters(self):
|
||||
return [
|
||||
"release_string",
|
||||
"source_chroot",
|
||||
"destination_iso_directory",
|
||||
"destination_livecd_root",
|
||||
]
|
||||
|
||||
def parser_data_path(self):
|
||||
return {
|
||||
'prechroot': {
|
||||
'cb': self.valid_exec_first_list_item,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'release_string': {
|
||||
'cb': self.ne_string, # validation callback
|
||||
've': self.ve_string_stripper, # value extractor
|
||||
},
|
||||
'release_version': {
|
||||
'cb': self.ne_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'release_desc': {
|
||||
'cb': self.ne_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'release_file': {
|
||||
'cb': self.ne_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'source_chroot': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_chroot': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'extra_rsync_parameters': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'merge_destination_chroot': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'outer_chroot_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'inner_chroot_script': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_livecd_root': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'merge_livecd_root': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'extra_mksquashfs_parameters': {
|
||||
'cb': self.always_valid,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'extra_mkisofs_parameters': {
|
||||
'cb': self.always_valid,
|
||||
've': self.ve_string_splitter,
|
||||
'mod': self.ve_string_splitter,
|
||||
},
|
||||
'pre_iso_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_directory': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_image_name': {
|
||||
'cb': self.valid_ascii,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'paths_to_remove': {
|
||||
'cb': self.ne_list,
|
||||
've': self.valid_path_list,
|
||||
},
|
||||
'paths_to_empty': {
|
||||
'cb': self.ne_list,
|
||||
've': self.valid_path_list,
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
||||
class RemasterSpec(GenericSpec):
|
||||
|
||||
@staticmethod
|
||||
def execution_strategy():
|
||||
return "iso_remaster"
|
||||
|
||||
def vital_parameters(self):
|
||||
return [
|
||||
"source_iso",
|
||||
"destination_iso_directory",
|
||||
]
|
||||
|
||||
def parser_data_path(self):
|
||||
return {
|
||||
'prechroot': {
|
||||
'cb': self.valid_exec_first_list_item,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'source_iso': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'outer_chroot_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'inner_chroot_script': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'extra_mkisofs_parameters': {
|
||||
'cb': self.always_valid,
|
||||
've': self.ve_string_splitter,
|
||||
'mod': self.ve_string_splitter,
|
||||
},
|
||||
'pre_iso_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_directory': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_image_name': {
|
||||
'cb': self.valid_ascii,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
}
|
||||
|
||||
# FIXME: this will need to be pluggable (and plugin factory is required)
|
||||
SPEC_PLUGS = dict((x.execution_strategy(), x,) for x in \
|
||||
(LivecdSpec, RemasterSpec))
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Molecule Disc Image builder for Sabayon Linux
|
||||
# Copyright (C) 2009 Fabio Erculiani
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
from molecule.specs.plugins.builtin import LivecdSpec
|
||||
from molecule.specs.plugins.remaster import RemasterSpec
|
||||
|
||||
# FIXME: this will need to be pluggable (and plugin factory is required)
|
||||
SPEC_PLUGS = dict((x.execution_strategy(), x,) for x in \
|
||||
(LivecdSpec, RemasterSpec))
|
||||
@@ -0,0 +1,606 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Molecule Disc Image builder for Sabayon Linux
|
||||
# Copyright (C) 2009 Fabio Erculiani
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from molecule.i18n import _
|
||||
from molecule.output import red, brown, blue, green, purple, darkgreen, \
|
||||
darkred, bold, darkblue, readtext
|
||||
import molecule.utils
|
||||
from molecule.specs.skel import GenericExecutionStep, GenericSpec
|
||||
|
||||
class MirrorHandler(GenericExecutionStep):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericExecutionStep.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
|
||||
# creating destination chroot dir
|
||||
self.source_dir = self.metadata['source_chroot']
|
||||
self.dest_dir = os.path.join(
|
||||
self.metadata['destination_chroot'],"chroot",
|
||||
os.path.basename(self.source_dir)
|
||||
)
|
||||
if not os.path.isdir(self.dest_dir):
|
||||
os.makedirs(self.dest_dir,0755)
|
||||
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("mirroring running"),
|
||||
)
|
||||
)
|
||||
# running sync
|
||||
args = [self.Config['mirror_syncer']]
|
||||
args.extend(self.Config['mirror_syncer_builtin_args'])
|
||||
args.extend(self.metadata.get('extra_rsync_parameters',[]))
|
||||
args.extend([self.source_dir+"/*",self.dest_dir])
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("spawning"),args,
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.exec_cmd(args)
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("mirroring failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("MirrorHandler"),darkred(self.spec_name),
|
||||
_("mirroring completed successfully"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
class ChrootHandler(GenericExecutionStep):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericExecutionStep.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
self.source_dir = self.metadata['source_chroot']
|
||||
self.dest_dir = os.path.join(
|
||||
self.metadata['destination_chroot'],"chroot",
|
||||
os.path.basename(self.source_dir)
|
||||
)
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
|
||||
# write release file
|
||||
release_file = self.metadata.get('release_file')
|
||||
if isinstance(release_file,basestring) and release_file:
|
||||
if release_file[0] == os.sep: release_file = release_file[len(os.sep):]
|
||||
release_file = os.path.join(self.dest_dir,release_file)
|
||||
if os.path.lexists(release_file) and not os.path.isfile(release_file):
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("release file creation failed, not a file"),
|
||||
release_file,
|
||||
)
|
||||
)
|
||||
return 1
|
||||
release_string = self.metadata.get('release_string','')
|
||||
release_version = self.metadata.get('release_version','')
|
||||
release_desc = self.metadata.get('release_desc','')
|
||||
file_string = "%s %s %s\n" % (release_string,release_version,release_desc,)
|
||||
try:
|
||||
f = open(release_file,"w")
|
||||
f.write(file_string)
|
||||
f.flush()
|
||||
f.close()
|
||||
except (IOError,OSError,), e:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("release file creation failed, system error"),
|
||||
release_file,e,
|
||||
)
|
||||
)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),
|
||||
darkred(self.spec_name),_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("hooks running"),
|
||||
)
|
||||
)
|
||||
|
||||
# run inner chroot script
|
||||
exec_script = self.metadata.get('inner_chroot_script')
|
||||
if exec_script:
|
||||
if os.path.isfile(exec_script) and os.access(exec_script,os.R_OK):
|
||||
|
||||
while 1:
|
||||
tmp_dir = os.path.join(self.dest_dir,
|
||||
str(molecule.utils.get_random_number()))
|
||||
if not os.path.lexists(tmp_dir):
|
||||
break
|
||||
|
||||
os.makedirs(tmp_dir)
|
||||
tmp_exec = os.path.join(tmp_dir,"inner_exec")
|
||||
shutil.copy2(exec_script,tmp_exec)
|
||||
os.chmod(tmp_exec,0755)
|
||||
dest_exec = tmp_exec[len(self.dest_dir):]
|
||||
if not dest_exec.startswith("/"):
|
||||
dest_exec = "/%s" % (dest_exec,)
|
||||
|
||||
rc = molecule.utils.exec_chroot_cmd([dest_exec], self.dest_dir,
|
||||
self.metadata.get('prechroot',[]))
|
||||
os.remove(tmp_exec)
|
||||
os.rmdir(tmp_dir)
|
||||
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("inner chroot hook failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
# run outer chroot script
|
||||
exec_script = self.metadata.get('outer_chroot_script')
|
||||
if exec_script:
|
||||
os.environ['CHROOT_DIR'] = self.source_dir
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("spawning"),[exec_script],
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.exec_cmd([exec_script])
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("outer chroot hook failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
# now remove paths to empty
|
||||
empty_paths = self.metadata.get('paths_to_empty',[])
|
||||
for mypath in empty_paths:
|
||||
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)
|
||||
|
||||
# now remove paths to remove (...)
|
||||
remove_paths = self.metadata.get('paths_to_remove',[])
|
||||
|
||||
# setup sandbox
|
||||
sb_dirs = [self.dest_dir]
|
||||
sb_env = {
|
||||
'SANDBOX_WRITE': ':'.join(sb_dirs),
|
||||
}
|
||||
myenv = os.environ.copy()
|
||||
myenv.update(sb_env)
|
||||
|
||||
for mypath in remove_paths:
|
||||
mypath = self.dest_dir+mypath
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("removing dir"),mypath,
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.remove_path_sandbox(mypath, sb_env)
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s: %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("removal failed for"),mypath,rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("hooks completed succesfully"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
class CdrootHandler(GenericExecutionStep):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericExecutionStep.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
|
||||
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.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):
|
||||
os.makedirs(self.dest_root,0755)
|
||||
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("compressing chroot"),
|
||||
)
|
||||
)
|
||||
args = [self.Config['chroot_compressor']]
|
||||
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:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("chroot compression failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("chroot compressed successfully"),
|
||||
)
|
||||
)
|
||||
|
||||
# merge dir
|
||||
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
|
||||
|
||||
class IsoHandler(GenericExecutionStep):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericExecutionStep.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
|
||||
# setup paths
|
||||
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" % (
|
||||
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" % (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)
|
||||
)
|
||||
|
||||
# run outer chroot script
|
||||
exec_script = self.metadata.get('pre_iso_script')
|
||||
if exec_script:
|
||||
os.environ['SOURCE_CHROOT_DIR'] = self.source_chroot
|
||||
os.environ['CHROOT_DIR'] = self.chroot_dir
|
||||
os.environ['CDROOT_DIR'] = self.source_path
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("spawning"),[exec_script],
|
||||
)
|
||||
)
|
||||
rc = molecule.utils.exec_cmd([exec_script])
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("outer chroot hook failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("building ISO image"),
|
||||
)
|
||||
)
|
||||
|
||||
args = [self.Config['iso_builder']]
|
||||
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[:32],'"'])
|
||||
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)
|
||||
if rc != 0:
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("ISO image build failed"),rc,
|
||||
)
|
||||
)
|
||||
return rc
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("built ISO image"),self.dest_iso,
|
||||
)
|
||||
)
|
||||
if os.path.isfile(self.dest_iso) and os.access(self.dest_iso,os.R_OK):
|
||||
self.Output.updateProgress("[%s|%s] %s: %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("generating md5 for"),self.dest_iso,
|
||||
)
|
||||
)
|
||||
digest = molecule.utils.md5sum(self.dest_iso)
|
||||
md5file = self.dest_iso+".md5"
|
||||
with open(md5file,"w") as f:
|
||||
f.write("%s %s\n" % (digest,os.path.basename(self.dest_iso),))
|
||||
f.flush()
|
||||
return 0
|
||||
|
||||
class LivecdSpec(GenericSpec):
|
||||
|
||||
@staticmethod
|
||||
def execution_strategy():
|
||||
return "livecd"
|
||||
|
||||
def vital_parameters(self):
|
||||
return [
|
||||
"release_string",
|
||||
"source_chroot",
|
||||
"destination_iso_directory",
|
||||
"destination_livecd_root",
|
||||
]
|
||||
|
||||
def parser_data_path(self):
|
||||
return {
|
||||
'prechroot': {
|
||||
'cb': self.valid_exec_first_list_item,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'release_string': {
|
||||
'cb': self.ne_string, # validation callback
|
||||
've': self.ve_string_stripper, # value extractor
|
||||
},
|
||||
'release_version': {
|
||||
'cb': self.ne_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'release_desc': {
|
||||
'cb': self.ne_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'release_file': {
|
||||
'cb': self.ne_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'source_chroot': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_chroot': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'extra_rsync_parameters': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'merge_destination_chroot': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'outer_chroot_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'inner_chroot_script': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_livecd_root': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'merge_livecd_root': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'extra_mksquashfs_parameters': {
|
||||
'cb': self.always_valid,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'extra_mkisofs_parameters': {
|
||||
'cb': self.always_valid,
|
||||
've': self.ve_string_splitter,
|
||||
'mod': self.ve_string_splitter,
|
||||
},
|
||||
'pre_iso_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_directory': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_image_name': {
|
||||
'cb': self.valid_ascii,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'paths_to_remove': {
|
||||
'cb': self.ne_list,
|
||||
've': self.valid_path_list,
|
||||
},
|
||||
'paths_to_empty': {
|
||||
'cb': self.ne_list,
|
||||
've': self.valid_path_list,
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
def get_execution_steps(self):
|
||||
return [MirrorHandler, ChrootHandler, CdrootHandler, IsoHandler]
|
||||
@@ -0,0 +1,189 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Molecule Disc Image builder for Sabayon Linux
|
||||
# Copyright (C) 2009 Fabio Erculiani
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
from molecule.i18n import _
|
||||
from molecule.output import red, brown, blue, green, purple, darkgreen, \
|
||||
darkred, bold, darkblue, readtext
|
||||
from molecule.specs.skel import GenericExecutionStep, GenericSpec
|
||||
|
||||
class IsoUnpackHandler(GenericExecutionStep):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
GenericExecutionStep.__init__(self, *args, **kwargs)
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoUnpackHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
# FIXME: make it working
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoUnpackHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def kill(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoUnpackHandler"),darkred(self.spec_name),
|
||||
_("executing kill"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoUnpackHandler"),darkred(self.spec_name),
|
||||
_("iso unpacker running"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
from molecule.specs.plugins.builtin import ChrootHandler as BuiltinChrootHandler
|
||||
class ChrootHandler(BuiltinChrootHandler):
|
||||
|
||||
# INFO: Make external chroot, internal chroot hooks execution working
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def post_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("executing post_run"),
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("ChrootHandler"),darkred(self.spec_name),
|
||||
_("hooks running"),
|
||||
)
|
||||
)
|
||||
# FIXME: make parent method working
|
||||
return 0
|
||||
|
||||
|
||||
from molecule.specs.plugins.builtin import CdrootHandler as BuiltinCdrootHandler
|
||||
class CdrootHandler(BuiltinCdrootHandler):
|
||||
|
||||
# INFO: create cdroot dir back, compress chroot
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
# FIXME: make parent method working
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("CdrootHandler"),darkred(self.spec_name),
|
||||
_("compressing chroot"),
|
||||
)
|
||||
)
|
||||
# FIXME: make parent method working
|
||||
return 0
|
||||
|
||||
from molecule.specs.plugins.builtin import IsoHandler as BuiltinIsoHandler
|
||||
class IsoHandler(BuiltinIsoHandler):
|
||||
|
||||
def pre_run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("executing pre_run"),
|
||||
)
|
||||
)
|
||||
# FIXME: make parent method working
|
||||
return 0
|
||||
|
||||
def run(self):
|
||||
self.Output.updateProgress("[%s|%s] %s" % (
|
||||
blue("IsoHandler"),darkred(self.spec_name),
|
||||
_("building ISO image"),
|
||||
)
|
||||
)
|
||||
# FIXME: make parent method working
|
||||
return 0
|
||||
|
||||
class RemasterSpec(GenericSpec):
|
||||
|
||||
@staticmethod
|
||||
def execution_strategy():
|
||||
return "iso_remaster"
|
||||
|
||||
def vital_parameters(self):
|
||||
return [
|
||||
"source_iso",
|
||||
"destination_iso_directory",
|
||||
]
|
||||
|
||||
def parser_data_path(self):
|
||||
return {
|
||||
'prechroot': {
|
||||
'cb': self.valid_exec_first_list_item,
|
||||
've': self.ve_string_splitter,
|
||||
},
|
||||
'source_iso': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'outer_chroot_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'inner_chroot_script': {
|
||||
'cb': self.valid_path_string,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'extra_mkisofs_parameters': {
|
||||
'cb': self.always_valid,
|
||||
've': self.ve_string_splitter,
|
||||
'mod': self.ve_string_splitter,
|
||||
},
|
||||
'pre_iso_script': {
|
||||
'cb': self.valid_exec,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_directory': {
|
||||
'cb': self.valid_dir,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
'destination_iso_image_name': {
|
||||
'cb': self.valid_ascii,
|
||||
've': self.ve_string_stripper,
|
||||
},
|
||||
}
|
||||
|
||||
def get_execution_steps(self):
|
||||
return [IsoUnpackHandler, ChrootHandler, CdrootHandler, IsoHandler]
|
||||
Reference in New Issue
Block a user