def _add_container_metadata(self) -> None: ''' Adds container metadata to run metadata assets. ''' logger.emlog('# Looking for container metadata...') # Skip any image activators that do not have build metadata. if not cntrimg.activator().requires_img_activation(): iact = self.args.image_activator logger.log(F'# Note: the {iact} activator has no metadata\n') return imgdir = self.inflated_cntrimg_path # The subdirectory where container metadata are stored. buildl = os.path.join( imgdir, constants.METADATA_DIR, constants.SERVICE_LOG_NAME ) # Don't error out if the image doesn't have our metadata. if not os.path.exists(buildl): logger.log('# Note: container image provides no metadata\n') return logger.log(F'# Adding metadata from {imgdir}\n') mdatadir = 'container' metadata.add_asset(metadata.FileAsset(buildl, mdatadir))
def _runi(cmds: List[str], echo: bool = True, preaction: ActionCb = None, postaction: ActionCb = None, user_data: Any = None) -> None: ''' Private run dispatch. ''' capture = postaction is not None cmdstr = ' '.join(cmds) if preaction is not None: preargs = {'command': cmdstr, 'user_data': user_data} preaction(**preargs) stime = utils.now() coutput = cntrimg.activator().run(cmds, echo=echo, capture=capture) etime = utils.now() if postaction is not None: postargs = { 'command': cmdstr, 'exectime': etime - stime, 'output': coutput, 'user_data': user_data } postaction(**postargs)
def _stage_container_image(self) -> None: ''' TODO(skg) Add proper description. Stages container images. ''' imgp = self.args.image # The 'we don't need or want to stage paths.' if not cntrimg.activator().requires_img_activation(): return if self.args.do_not_stage: # We know that imgp cannot be None. hlps = 'Unstaged executions require access to ' \ 'an image directory path.' if not os.path.isdir(imgp): estr = F'{imgp} is not a directory. Cannot continue.\n{hlps}' raise RuntimeError(estr) self.inflated_cntrimg_path = imgp logger.log(F'# Image path: {imgp}') cntrimg.activator().set_img_path(imgp) return # The 'stage' path. logger.emlog('# Staging container image...') hlps = 'Staged executions require access to an image tarball path.' istf = False try: istf = tarfile.is_tarfile(imgp) except Exception as exception: estr = F'{exception}. Cannot continue.\n{hlps}' raise RuntimeError(estr) from exception # We do this check here so we can raise an exception that isn't caught # above because it produces redundant error messages. is_tarfile() can # raise exceptions, so that's what the above try/except block is for. if not istf: raise RuntimeError( F'{imgp} is not a tarball. Cannot continue.\n{hlps}' ) self.inflated_cntrimg_path = _ImageStager().stage(imgp) # Let the user and image activator know about the image's path. logger.log(F'# Staged image path: {self.inflated_cntrimg_path}') cntrimg.activator().set_img_path(self.inflated_cntrimg_path)
def build_information() -> List[str]: ''' Returns a list of strings containing captured container and application build information. If build information is not available, an empty list is returned. ''' buildl = os.path.join( cntrimg.activator().get_img_path(), constants.METADATA_DIR, constants.SERVICE_LOG_NAME ) if not os.path.exists(buildl): return [] return utils.cat(buildl)
def capture( cmd: str, check_exit_code: bool = True ) -> str: ''' Executes the provided command and returns a string with the command's output. See run() for exceptions. ''' runo = cntrimg.activator().run( [cmd], echo=False, verbose=False, capture=True, check_exit_code=check_exit_code ) return utils.chomp(str().join(runo))
def _runi( # pylint: disable=too-many-arguments cmds: List[str], echo: bool = True, check_exit_code: bool = True, preaction: ActionCb = None, postaction: ActionCb = None, user_data: Any = None ) -> None: ''' Private run dispatch. ''' capture_output = postaction is not None cmdstr = ' '.join(cmds) if preaction is not None: preargs = { 'command': cmdstr, 'user_data': user_data } preaction(**preargs) stime = utils.now() coutput = cntrimg.activator().run( cmds, echo=echo, capture=capture_output, check_exit_code=check_exit_code ) etime = utils.now() if postaction is not None: postargs = { 'command': cmdstr, 'start_time': stime, 'end_time': etime, 'exectime': (etime - stime).total_seconds(), 'output': coutput, 'user_data': user_data } postaction(**postargs)