def checkpoint_setup(cp, manifest_server_obj): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """Sets up and defines all checkpoints. All checkpoints must have an entry (in chronological order) here. format: step_setup( message, name, [dataset list]) message: the message to print to the screen to indicate the step name: ascii name for the step. dataset list: list with the names of the datasets to snapshot """ finalizer_script_list = get_manifest_list(manifest_server_obj, FINALIZER_SCRIPT_NAME) # Set up a checkpoint for each finalizer script specified. for script in finalizer_script_list: checkpoint_message = get_manifest_value(manifest_server_obj, FINALIZER_SCRIPT_NAME_TO_CHECKPOINT_MESSAGE % script) checkpoint_name = get_manifest_value(manifest_server_obj, FINALIZER_SCRIPT_NAME_TO_CHECKPOINT_NAME % script) if checkpoint_name is None : dc_log = logging.getLogger(DC_LOGGER_NAME) dc_log.error("The checkpoint name to use for the " \ "finalizer script %s is missing." % script) dc_log.error("Please check your manifest file.") return -1 if checkpoint_message is None: checkpoint_message = "Executing " + script cp.step_setup(checkpoint_message, checkpoint_name, [cp.get_build_area_dataset() + BUILD_DATA]) return 0
def queue_up_finalizer_script(cp, finalizer_obj, manifest_server_obj, script): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """Queue up the designated finalizer script.""" # Args list gets returned as a single string which can contain multiple # args, if the args list exists. Split into individual args, accounting # for the possibility of an empty list. script_args = get_manifest_list(manifest_server_obj, FINALIZER_SCRIPT_NAME_TO_ARGSLIST % script) ret = finalizer_obj.register(script, script_args) cp.incr_current_step() return (ret)
ENTRY = [] ENTRY.append("title " + RELEASE) ENTRY.append("\tkernel$ /platform/i86pc/kernel/$ISADIR/unix") ENTRY.append("\tmodule$ /platform/i86pc/$ISADIR/boot_archive") ENTRIES.append(ENTRY) ENTRY = [] ENTRY.append("title Boot from Hard Disk") ENTRY.append("\trootnoverify (hd0)") ENTRY.append("\tchainloader +1") ENTRIES.append(ENTRY) # This all assumes that data is returned from the manifest in the order it is # provided. Otherwise, lines within an entry could be out of order. ENTRY_NAMES = get_manifest_list(MANIFEST_READER_OBJ, GRUB_ENTRY_TITLE_SUFFIX) for name in ENTRY_NAMES: ENTRY = [] ENTRY.append("title " + RELEASE + " " + name) lines = get_manifest_list(MANIFEST_READER_OBJ, GRUB_ENTRY_LINES % name) for line in lines: ENTRY.append("\t" + line) position_str = get_manifest_value(MANIFEST_READER_OBJ, GRUB_ENTRY_POSITION % name) # Put at the end of the list if no position stated. if position_str is None: ENTRIES.append(ENTRY) else: try:
"boot archive build area"), file=sys.stderr) raise try: os.mkdir(BA_BUILD) except OSError: print("Error creating boot archive build area", file=sys.stderr) raise FILELIST_NAME = TMP_DIR + "/filelist" # create filelist for use in transfer module FILELIST = open(FILELIST_NAME, 'w') # get list of files in boot archive from contents file BA_FILELIST = get_manifest_list(MANIFEST_READER_OBJ, BOOT_ARCHIVE_CONTENTS_BASE_INCLUDE_TO_TYPE_FILE) # write the list of files to a file for use by the transfer module try: for item in BA_FILELIST: FILELIST.write(item + '\n') finally: FILELIST.close() # use transfer module to copy files from pkg image area to the boot archive # staging area STATUS = tm_perform_transfer([(TM_ATTR_MECHANISM, TM_PERFORM_CPIO), (TM_CPIO_ACTION, TM_CPIO_LIST), (TM_CPIO_LIST_FILE, FILELIST_NAME), (TM_CPIO_DST_MNTPT, BA_BUILD), (TM_CPIO_SRC_MNTPT, PKG_IMG_PATH)])
def add_finalizer_scripts(cp, manifest_server_obj, finalizer_obj): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """Check to see if the finalizer script should be executed. It should only be executed if 1) checkpointing is available/on and 2) the steps to pause or resume at don't exclude it. Input: manifest_server_obj - Manifest server object finalizer_obj - finalizer object Returns: SUCCESS - no error GENERAL_ERR - unable to register one or more finalizer script """ dc_log = logging.getLogger(DC_LOGGER_NAME) # assume no error, if there's an error, this will be set to 1 ret = SUCCESS finalizer_script_list = get_manifest_list(manifest_server_obj, FINALIZER_SCRIPT_NAME) resumestep = cp.get_resume_step() pausestep = cp.get_pause_step() stop_on_err = get_manifest_boolean(manifest_server_obj, STOP_ON_ERR) if stop_on_err is None: # this should never happen, since default module should have # taken care of filling in the default value of true stop_on_err = 1 for script in finalizer_script_list: if not script: continue if not cp.get_checkpointing_avail(): # Queue up the finalizer script and return if (queue_up_finalizer_script(cp, finalizer_obj, manifest_server_obj, script)): dc_log.error("Failed to register finalizer " \ "script: " + script) if (stop_on_err): return GENERAL_ERR else: ret = GENERAL_ERR continue currentstep = cp.get_current_step() if currentstep == pausestep: # Pause after checkpointing. This means we queue up the # checkpoint script but not the finalizer script. if (queue_up_checkpoint_script(cp, finalizer_obj)): dc_log.error("Failed to register checkpoint " \ "script with finalizer module") if (stop_on_err): return GENERAL_ERR else: ret = GENERAL_ERR return (ret) if currentstep > resumestep: # We're past the resume step and we have checkpointing, # so register the checkpointing script and the finalizer # script. if (queue_up_checkpoint_script(cp, finalizer_obj)): dc_log.error("Failed to register checkpoint " \ "script with finalizer module") if (stop_on_err): return GENERAL_ERR else: ret = GENERAL_ERR if (queue_up_finalizer_script(cp, finalizer_obj, manifest_server_obj, script)): dc_log.error("Failed to register finalizer " \ "script: " + script) if (stop_on_err): return GENERAL_ERR else: ret = GENERAL_ERR continue elif currentstep == resumestep: # At the specified step to resume from. # Register the rollback script and the finalizer script. if (queue_up_rollback_script(cp, finalizer_obj)): dc_log.error("Failed to register rollback " \ "script with finalizer module") if (stop_on_err): return GENERAL_ERR else: ret = GENERAL_ERR if (queue_up_finalizer_script(cp, finalizer_obj, manifest_server_obj, script)): dc_log.error("Failed to register finalizer " \ "script: " + script) if (stop_on_err): return GENERAL_ERR else: ret = GENERAL_ERR continue else: # We're not yet to the specified resume step so # increment our step counter and continue on. cp.incr_current_step() continue return (ret)
def compress(src, dst): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ fiocompress files in the dst. The files listed in boot/solaris/filelist.ramdisk and files in usr/kernel are recopied because we can't have them compressed. Args: src : directory files are copied to dst from. dst : directory to fiocompress files in. Returns: N/A Raises: Exception """ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ os.chdir(src) # # Create list of boot archive files/directories. # Since passed with '.' relative path, find() generates paths # starting with './' # ba_flist = find(["."]) errors = False # # Assemble list of files/directories which are not eligible for compression. # Start with the files/dirs in filelist.ramdisk. # # Make sure that relative path start with './', so that exclusion algorithm # below works as expected. # rdfd = open("boot/solaris/filelist.ramdisk", 'r') uc_list = [] for filename in rdfd: if not filename.startswith('./'): filename = os.path.join('./', filename) uc_list.append(filename.strip()) rdfd.close() # Append ./usr/kernel directory uc_list.append("./usr/kernel") # Add (regular) files specified in manifest with fiocompress="false" # Verify that they are non-zero-length, regular files first. manflist = get_manifest_list( MANIFEST_READER_OBJ, BOOT_ARCHIVE_CONTENTS_BASE_INCLUDE_NOCOMPRESS) if manflist: status = 0 for nc_file in manflist: if not nc_file.startswith('./'): nc_file = os.path.join('./', nc_file) try: stat_out = os.lstat(nc_file) except OSError, err: print >> sys.stderr, ( sys.argv[0] + ": Couldn't stat %s to mark as " + "uncompressed in boot_archive: %s") % (nc_file, err.strerror) status = 1 continue mode = stat_out.st_mode if (stat.S_ISREG(mode) and not (stat_out.st_size == 0)): uc_list.append(nc_file) else: print >> sys.stderr, (sys.argv[0] + ": " + "Couldn't mark " + nc_file + " as uncompressed in boot_archive: " + "not a non-zero-sized regular file") status = 1 if (status != 0): raise Exception, (sys.argv[0] + ": Error building " "list of uncompressed boot_archive files.")
# Initialize the IPS area. Use the default publisher. print("Initializing the IPS package image area: " + \ PKG_IMG_MNT_PT, file=sys.stderr) print("Setting preferred publisher: " + PKG_AUTH, file=sys.stderr) print("\tOrigin repository: " + PKG_URL, file=sys.stderr) STATUS = ips_init(PKG_URL, PKG_AUTH, PKG_IMG_MNT_PT) if STATUS != TM_E_SUCCESS: raise Exception(sys.argv[0] + ": Unable to initialize the IPS image") # Keep a list of authorities to cleanup at the end. UNSET_AUTH_LIST.append(PKG_AUTH) # If the user specified any mirrors for the default publisher, # set them in the IPS image using the pkg set-publisher -m command. MIRROR_URL_LIST = dcu.get_manifest_list(MANIFEST_SERVER_OBJ, DEFAULT_MIRROR_URL) for mirror_url in MIRROR_URL_LIST: print("\tMirror repository: " + mirror_url, file=sys.stderr) STATUS = ips_set_auth(mirror_url, PKG_AUTH, PKG_IMG_MNT_PT, mirr_cmd=TM_IPS_SET_MIRROR, refresh_flag=True) if STATUS != TM_E_SUCCESS: print("Unable to set the IPS image mirror", file=sys.stderr) if QUIT_ON_PKG_FAILURE == 'true': raise Exception(sys.argv[0] + ": Unable to set the IPS image mirror") # Keep a list of mirrors to cleanup at the end. UNSET_MIRROR_LIST.append((mirror_url, PKG_AUTH))
def compress(src, dst): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ fiocompress files in the dst. The files listed in boot/solaris/filelist.ramdisk and files in usr/kernel are recopied because we can't have them compressed. Args: src : directory files are copied to dst from. dst : directory to fiocompress files in. Returns: N/A Raises: Exception """ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ os.chdir(src) # # Create list of boot archive files/directories. # Since passed with '.' relative path, find() generates paths # starting with './' # ba_flist = find(["."]) errors = False # # Assemble list of files/directories which are not eligible for compression. # Start with the files/dirs in filelist.ramdisk. # # Make sure that relative path start with './', so that exclusion algorithm # below works as expected. # rdfd = open("boot/solaris/filelist.ramdisk", 'r') uc_list = [] for filename in rdfd: if not filename.startswith('./'): filename = os.path.join('./', filename) uc_list.append(filename.strip()) rdfd.close() # Append ./usr/kernel directory uc_list.append("./usr/kernel") # Add (regular) files specified in manifest with fiocompress="false" # Verify that they are non-zero-length, regular files first. manflist = get_manifest_list(MANIFEST_READER_OBJ, BOOT_ARCHIVE_CONTENTS_BASE_INCLUDE_NOCOMPRESS) if manflist: status = 0 for nc_file in manflist: if not nc_file.startswith('./'): nc_file = os.path.join('./', nc_file) try: stat_out = os.lstat(nc_file) except OSError as err: print((sys.argv[0] + ": Couldn't stat %s to mark as " + "uncompressed in boot_archive: %s") % ( nc_file, err.strerror), file=sys.stderr) status = 1 continue mode = stat_out.st_mode if (stat.S_ISREG(mode) and not (stat_out.st_size == 0)): uc_list.append(nc_file) else: print((sys.argv[0] + ": " + "Couldn't mark " + nc_file + " as uncompressed in boot_archive: " + "not a non-zero-sized regular file"), file=sys.stderr) status = 1 if (status != 0): raise Exception(sys.argv[0] + ": Error building " "list of uncompressed boot_archive files.") # Get expanded uncompressed list exp_uc_flist = find(uc_list) # # Create set of entries to be compressed by differentiating following sets: # - set describing whole boot archive # - set of entries not eligible for compression # compress_fset = set(ba_flist) - set(exp_uc_flist) # # Enumerate through set of entries eligible for compression and compress # those entries which meet all of the following criteria: # # - it is a regular file # - size > 0 # - it is NOT a hardlink # for cfile in compress_fset: # strip off the trailing \n cpio_file = cfile.strip() if os.access(cpio_file, os.F_OK): stat_out = os.lstat(cpio_file) mode = stat_out.st_mode if (stat.S_ISREG(mode) and not (stat_out.st_size == 0) and (stat_out.st_nlink < 2)): cmd = FIOCOMPRESS + " -mc " + cpio_file + \ " " + dst + "/" + cpio_file status = os.system(cmd) if (status != 0): print((sys.argv[0] + ": error compressing file " + cpio_file + ": " + os.strerror(status >> 8)), file=sys.stderr) errors = True if (errors): raise Exception(sys.argv[0] + ": Error processing " + "compressed boot_archive files")