--- /dev/null
+#!/usr/bin/python
+
+# Maintained in full by:
+# Catalyst Team <catalyst@gentoo.org>
+# Release Engineering Team <releng@gentoo.org>
+# Copyright 2013 Brian Dolbec <dolsen@gentoo.org>
+
+'''resume.py
+
+Performs autoresume tracking file operations such as
+set, unset, is_set, is_unset, enabled, clear_all
+'''
+
+import os
+import shutil
+from stat import ST_UID, ST_GID, ST_MODE
+import traceback
+
+from catalyst.fileops import ensure_dirs, pjoin, listdir_files
+from catalyst.support import touch
+
+
+class AutoResumeError(Exception):
+ def __init__(self, message, print_traceback=False):
+ if message:
+ if print_traceback:
+ (type,value)=sys.exc_info()[:2]
+ if value!=None:
+ print
+ print "Traceback values found. listing..."
+ print traceback.print_exc(file=sys.stdout)
+ print "!!! catalyst: AutoResumeError " + message
+ print
+
+
+class AutoResume(object):
+ '''Class for tracking and handling all aspects of
+ the autoresume option and related files.
+ '''
+
+
+ def __init__(self, basedir, mode=0755):
+ self.basedir = basedir
+ ensure_dirs(basedir, mode=mode, fatal=True)
+ self._points = {}
+ self._init_points_()
+
+
+ def _init_points_(self):
+ '''Internal function which reads the autoresume directory and
+ for existing autoresume points and adds them to our _points variable
+ '''
+ existing = listdir_files(self.basedir, False)
+ for point in existing:
+ self._points[point] = pjoin(self.basedir, point)
+
+
+ def enable(self, point, data=None):
+ '''Sets the resume point 'ON'
+
+ @param point: string. name of the resume point to enable
+ @param data: string of information to store, or None
+ @return boolean
+ '''
+ if point in self._points and not data:
+ return True
+ fname = pjoin(self.basedir, point)
+ if data:
+ with open(fname,"w") as myf:
+ myf.write(data)
+ else:
+ try:
+ touch(fname)
+ self._points[point] = fname
+ except Exception as e:
+ print AutoResumeError(str(e))
+ return False
+ return True
+
+
+ def get(self, point, no_lf=True):
+ '''Gets any data stored inside a resume point
+
+ @param point: string. name of the resume point to enable
+ @return data: string of information stored, or None
+ '''
+ if point in self._points:
+ try:
+ with open(self._points[point], 'r') as myf:
+ data = myf.read()
+ if data and no_lf:
+ data = data.replace('\n', '')
+ except OSError as e:
+ print AutoResumeError(str(e))
+ return None
+ return data
+ return None
+
+
+ def disable(self, point):
+ '''Sets the resume point 'OFF'
+
+ @param point: string. name of the resume point to disable
+ @return boolean
+ '''
+ if point not in self._points:
+ return True
+ try:
+ os.unlink(self._points[point])
+ self._points.pop(point)
+ except Exception as e:
+ print AutoResumeError(str(e))
+ return False
+ return True
+
+
+ def is_enabled(self, point):
+ '''Returns True if the resume point 'ON'
+
+ @param point: string. name of the resume point enabled
+ @return boolean
+ '''
+ return point in self._points
+
+
+ def is_disabled(self, point):
+ '''Returns True if the resume point 'OFF'
+
+ @param point: string. name of the resume point not enabled
+ @return boolean
+ '''
+ return point not in self._points
+
+
+ @property
+ def enabled(self):
+ '''Returns a list of enabled points
+ '''
+ return list(self._points)
+
+
+ def clear_all(self):
+ '''Clear all active resume points
+
+ @return boolean
+ '''
+ try:
+ print "Emptying directory---", self.basedir
+ """
+ stat the dir, delete the dir, recreate the dir and set
+ the proper perms and ownership
+ """
+ mystat=os.stat(self.basedir)
+ if os.uname()[0] == "FreeBSD":
+ cmd("chflags -R noschg " + self.basedir,\
+ "Could not remove immutable flag for file "\
+ + self.basedir)
+ shutil.rmtree(self.basedir)
+ ensure_dirs(self.basedir, 0755)
+ os.chown(self.basedir,mystat[ST_UID],mystat[ST_GID])
+ os.chmod(self.basedir,mystat[ST_MODE])
+ self._points = {}
+ except Exception as e:
+ print AutoResumeError(str(e))
+ return False
+ return True
from catalyst.defaults import target_mounts
from catalyst.lock import LockDir
from catalyst.fileops import ensure_dirs, pjoin
+from catalyst.base.resume import AutoResume
class StageBase(TargetBase, ClearBase, GenBase):
"""
self.settings["target_path"]=normpath(self.settings["storedir"]+\
"/builds/"+self.settings["target_subpath"]+".tar.bz2")
if "autoresume" in self.settings["options"]\
- and os.path.exists(self.settings["autoresume_path"]+\
- "setup_target_path"):
+ and self.resume.is_enabled("setup_target_path"):
print \
"Resume point detected, skipping target path setup operation..."
else:
# cmd("rm -f "+self.settings["target_path"],\
# "Could not remove existing file: "\
# +self.settings["target_path"],env=self.env)
- touch(self.settings["autoresume_path"]+"setup_target_path")
+ self.resume.enable("setup_target_path")
ensure_dirs(self.settings["storedir"] + "/builds/")
self.settings["version_stamp"]+"/")
if "autoresume" in self.settings["options"]:
print "The autoresume path is " + self.settings["autoresume_path"]
- ensure_dirs(self.settings["autoresume_path"], mode=0755)
+ self.resume = AutoResume(self.settings["autoresume_path"], mode=0755)
def set_controller_file(self):
self.settings["controller_file"]=normpath(self.settings["shdir"] + "/" +
def unpack(self):
unpack=True
- clst_unpack_hash=read_from_clst(self.settings["autoresume_path"]+\
- "unpack")
+ clst_unpack_hash = self.resume.get("unpack")
if "seedcache" in self.settings["options"]:
if os.path.isdir(self.settings["source_path"]):
if "autoresume" in self.settings["options"]:
if os.path.isdir(self.settings["source_path"]) \
- and os.path.exists(self.settings["autoresume_path"]+"unpack"):
+ and self.resume.is_enabled("unpack"):
""" Autoresume is valid, SEEDCACHE is valid """
unpack=False
invalid_snapshot=False
invalid_snapshot=True
elif os.path.isdir(self.settings["source_path"]) \
- and not os.path.exists(self.settings["autoresume_path"]+\
- "unpack"):
+ and self.resume.is_disabled("unpack"):
""" Autoresume is invalid, SEEDCACHE """
unpack=True
invalid_snapshot=False
cmd(unpack_cmd,error_msg,env=self.env)
if "source_path_hash" in self.settings:
- myf=open(self.settings["autoresume_path"]+"unpack","w")
- myf.write(self.settings["source_path_hash"])
- myf.close()
+ self.resume.enable("unpack",
+ data=self.settings["source_path_hash"])
else:
- touch(self.settings["autoresume_path"]+"unpack")
+ self.resume.enable("unpack")
else:
print "Resume point detected, skipping unpack operation..."
def unpack_snapshot(self):
unpack=True
- snapshot_hash=read_from_clst(self.settings["autoresume_path"]+\
- "unpack_portage")
+ snapshot_hash = self.resume.get("unpack_portage")
if "snapcache" in self.settings["options"]:
snapshot_cache_hash=\
if "autoresume" in self.settings["options"] \
and os.path.exists(self.settings["chroot_path"]+\
self.settings["portdir"]) \
- and os.path.exists(self.settings["autoresume_path"]\
- +"unpack_portage") \
+ and self.resume.is_enabled("unpack_portage") \
and self.settings["snapshot_path_hash"] == snapshot_hash:
print \
"Valid Resume point detected, skipping unpack of portage tree..."
myf.close()
else:
print "Setting snapshot autoresume point"
- myf=open(self.settings["autoresume_path"]+"unpack_portage","w")
- myf.write(self.settings["snapshot_path_hash"])
- myf.close()
+ self.resume.enable("unpack_portage",
+ data=self.settings["snapshot_path_hash"])
if "snapcache" in self.settings["options"]:
self.snapshot_lock_object.unlock()
def config_profile_link(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+\
- "config_profile_link"):
+ and self.resume.is_enabled("config_profile_link"):
print \
"Resume point detected, skipping config_profile_link operation..."
else:
self.settings["chroot_path"] +
self.settings["port_conf"] + "/make.profile",
"Error creating profile link",env=self.env)
- touch(self.settings["autoresume_path"]+"config_profile_link")
+ self.resume.enable("config_profile_link")
def setup_confdir(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+\
- "setup_confdir"):
+ and self.resume.is_enabled("setup_confdir"):
print "Resume point detected, skipping setup_confdir operation..."
else:
if "portage_confdir" in self.settings:
self.settings["chroot_path"] + self.settings["port_conf"],
"Error copying %s" % self.settings["port_conf"],
env=self.env)
- touch(self.settings["autoresume_path"]+"setup_confdir")
+ self.resume.enable("setup_confdir")
def portage_overlay(self):
""" We copy the contents of our overlays to /usr/local/portage """
self.override_cxxflags()
self.override_ldflags()
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"chroot_setup"):
+ and self.resume.is_enabled("chroot_setup"):
print "Resume point detected, skipping chroot_setup operation..."
else:
print "Setting up chroot..."
self.settings["make_conf"])
cmd("cp " + makepath + " " + makepath + ".catalyst",\
"Could not backup " + self.settings["make_conf"],env=self.env)
- touch(self.settings["autoresume_path"]+"chroot_setup")
+ self.resume.enable("chroot_setup")
def fsscript(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"fsscript"):
+ and self.resume.is_enabled("fsscript"):
print "Resume point detected, skipping fsscript operation..."
else:
if "fsscript" in self.settings:
if os.path.exists(self.settings["controller_file"]):
cmd(self.settings["controller_file"]+\
" fsscript","fsscript script failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"fsscript")
+ self.resume.enable("fsscript")
def rcupdate(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"rcupdate"):
+ and self.resume.is_enabled("rcupdate"):
print "Resume point detected, skipping rcupdate operation..."
else:
if os.path.exists(self.settings["controller_file"]):
cmd(self.settings["controller_file"]+" rc-update",\
"rc-update script failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"rcupdate")
+ self.resume.enable("rcupdate")
def clean(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"clean"):
+ and self.resume.is_enabled("clean"):
print "Resume point detected, skipping clean operation..."
else:
for x in self.settings["cleanables"]:
if os.path.exists(self.settings["controller_file"]):
cmd(self.settings["controller_file"]+" clean",\
"clean script failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"clean")
+ self.resume.enable("clean")
def empty(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"empty"):
+ and self.resume.is_enabled("empty"):
print "Resume point detected, skipping empty operation..."
else:
if self.settings["spec_prefix"]+"/empty" in self.settings:
ensure_dirs(myemp, mode=0755)
os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
os.chmod(myemp,mystat[ST_MODE])
- touch(self.settings["autoresume_path"]+"empty")
+ self.resume.enable("empty")
def remove(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"remove"):
+ and self.resume.is_enabled("remove"):
print "Resume point detected, skipping remove operation..."
else:
if self.settings["spec_prefix"]+"/rm" in self.settings:
if os.path.exists(self.settings["controller_file"]):
cmd(self.settings["controller_file"]+\
" clean","Clean failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"remove")
+ self.resume.enable("remove")
except:
self.unbind()
raise
def preclean(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"preclean"):
+ and self.resume.is_enabled("preclean"):
print "Resume point detected, skipping preclean operation..."
else:
try:
if os.path.exists(self.settings["controller_file"]):
cmd(self.settings["controller_file"]+\
" preclean","preclean script failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"preclean")
+ self.resume.enable("preclean")
except:
self.unbind()
def capture(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"capture"):
+ and self.resume.is_enabled("capture"):
print "Resume point detected, skipping capture operation..."
else:
""" Capture target in a tarball """
self.gen_contents_file(self.settings["target_path"])
self.gen_digest_file(self.settings["target_path"])
- touch(self.settings["autoresume_path"]+"capture")
+ self.resume.enable("capture")
def run_local(self):
#print "run_local()"
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"run_local"):
+ and self.resume.is_enabled("run_local"):
print "Resume point detected, skipping run_local operation..."
else:
try:
print "run_local() starting controller script..."
cmd(self.settings["controller_file"]+" run",\
"run script failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"run_local")
+ self.resume.enable("run_local")
else:
print "run_local() no controller_file found...", self.settings["controller_file"]
def unmerge(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"unmerge"):
+ and self.resume.is_enabled("unmerge"):
print "Resume point detected, skipping unmerge operation..."
else:
if self.settings["spec_prefix"]+"/unmerge" in self.settings:
except CatalystError:
self.unbind()
raise
- touch(self.settings["autoresume_path"]+"unmerge")
+ self.resume.enable("unmerge")
def target_setup(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"target_setup"):
+ and self.resume.is_enabled("target_setup"):
print "Resume point detected, skipping target_setup operation..."
else:
print "Setting up filesystems per filesystem type"
cmd(self.settings["controller_file"]+\
" target_image_setup "+ self.settings["target_path"],\
"target_image_setup script failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"target_setup")
+ self.resume.enable("target_setup")
def setup_overlay(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"setup_overlay"):
+ and self.resume.is_enabled("setup_overlay"):
print "Resume point detected, skipping setup_overlay operation..."
else:
if self.settings["spec_prefix"]+"/overlay" in self.settings:
self.settings["target_path"],\
self.settings["spec_prefix"]+"overlay: "+x+\
" copy failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"setup_overlay")
+ self.resume.enable("setup_overlay")
def create_iso(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"create_iso"):
+ and self.resume.is_enabled("create_iso"):
print "Resume point detected, skipping create_iso operation..."
else:
""" Create the ISO """
env=self.env)
self.gen_contents_file(self.settings["iso"])
self.gen_digest_file(self.settings["iso"])
- touch(self.settings["autoresume_path"]+"create_iso")
+ self.resume.enable("create_iso")
else:
print "WARNING: livecd/iso was not defined."
print "An ISO Image will not be created."
def build_packages(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+\
- "build_packages"):
+ and self.resume.is_enabled("build_packages"):
print "Resume point detected, skipping build_packages operation..."
else:
if self.settings["spec_prefix"]+"/packages" in self.settings:
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+\
- "build_packages"):
+ and self.resume.is_enabled("build_packages"):
print "Resume point detected, skipping build_packages operation..."
else:
mypack=\
cmd(self.settings["controller_file"]+\
" build_packages "+mypack,\
"Error in attempt to build packages",env=self.env)
- touch(self.settings["autoresume_path"]+"build_packages")
+ self.resume.enable("build_packages")
except CatalystError:
self.unbind()
raise CatalystError(self.settings["spec_prefix"]+\
def build_kernel(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"build_kernel"):
+ and self.resume.is_enabled("build_kernel"):
print "Resume point detected, skipping build_kernel operation..."
else:
if "boot/kernel" in self.settings:
env=self.env)
for kname in mynames:
self._build_kernel(kname=kname)
- touch(self.settings["autoresume_path"]+"build_kernel")
+ self.resume.enable("build_kernel")
except CatalystError:
self.unbind()
raise CatalystError(
def _build_kernel(self, kname):
"Build a single configured kernel by name"
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]\
- +"build_kernel_"+kname):
+ and self.resume.is_enabled("build_kernel_"+kname):
print "Resume point detected, skipping build_kernel for "+kname+" operation..."
return
self._copy_kernel_config(kname=kname)
cmd("rm -R "+self.settings["chroot_path"]+\
"/tmp/initramfs_overlay/",env=self.env)
- touch(self.settings["autoresume_path"]+\
- "build_kernel_"+kname)
+ self.resume.is_enabled("build_kernel_"+kname)
"""
Execute the script that cleans up the kernel build
def bootloader(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+"bootloader"):
+ and self.resume.is_enabled("bootloader"):
print "Resume point detected, skipping bootloader operation..."
else:
try:
cmd(self.settings["controller_file"]+\
" bootloader " + self.settings["target_path"],\
"Bootloader script failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"bootloader")
+ self.resume.enable("bootloader")
except CatalystError:
self.unbind()
raise CatalystError("Script aborting due to error.")
def livecd_update(self):
if "autoresume" in self.settings["options"] \
- and os.path.exists(self.settings["autoresume_path"]+\
- "livecd_update"):
+ and self.resume.is_enabled("livecd_update"):
print "Resume point detected, skipping build_packages operation..."
else:
try:
cmd(self.settings["controller_file"]+\
" livecd-update","livecd-update failed.",env=self.env)
- touch(self.settings["autoresume_path"]+"livecd_update")
+ self.resume.enable("livecd_update")
except CatalystError:
self.unbind()