def extract_nulecule_data(self, image, source, dest, update=False): """ Extract the Nulecule contents from a container into a destination directory. Args: image (str): Docker image name source (str): Source directory in Docker image to copy from dest (str): Path to destination directory on host update (bool): Update destination directory if it exists when True Returns: None """ logger.info( 'Extracting Nulecule data from image %s to %s' % (image, dest)) if self.dryrun: return # Create a temporary directory for extraction tmpdir = '/tmp/nulecule-{}'.format(uuid.uuid1()) self.extract_files(image, source=source, dest=tmpdir) # If the application already exists locally then need to # make sure the local app id is the same as the one requested # on the command line. mainfile = os.path.join(dest, MAIN_FILE) tmpmainfile = os.path.join(tmpdir, MAIN_FILE) if os.path.exists(mainfile): existing_id = Utils.getAppId(mainfile) new_id = Utils.getAppId(tmpmainfile) cockpit_logger.info("Loading app_id %s" % new_id) if existing_id != new_id: raise NuleculeException( "Existing app (%s) and requested app (%s) differ" % (existing_id, new_id)) # If app exists and no update requested then move on if update: logger.info("App exists locally. Performing update...") else: logger.info("App exists locally and no update requested") return # Copy files from tmpdir into place logger.debug('Copying nulecule data from %s to %s' % (tmpdir, dest)) Utils.copy_dir(tmpdir, dest, update) # Clean up tmpdir logger.debug('Removing tmp dir: %s' % tmpdir) Utils.rm_dir(tmpdir) # Set the proper permissions on the extracted folder Utils.setFileOwnerGroup(dest)
def extract_nulecule_data(self, image, source, dest, update=False): """ Extract the Nulecule contents from a container into a destination directory. Args: image (str): Docker image name source (str): Source directory in Docker image to copy from dest (str): Path to destination directory on host update (bool): Update destination directory if it exists when True Returns: None """ logger.info("Extracting Nulecule data from image %s to %s" % (image, dest)) if self.dryrun: return # Create a temporary directory for extraction tmpdir = "/tmp/nulecule-{}".format(uuid.uuid1()) self.extract_files(image, source=source, dest=tmpdir) # If the application already exists locally then need to # make sure the local app id is the same as the one requested # on the command line. mainfile = os.path.join(dest, MAIN_FILE) tmpmainfile = os.path.join(tmpdir, MAIN_FILE) if os.path.exists(mainfile): existing_id = Utils.getAppId(mainfile) new_id = Utils.getAppId(tmpmainfile) cockpit_logger.info("Loading app_id %s" % new_id) if existing_id != new_id: raise NuleculeException("Existing app (%s) and requested app (%s) differ" % (existing_id, new_id)) # If app exists and no update requested then move on if update: logger.info("App exists locally. Performing update...") else: logger.info("App exists locally and no update requested") return # Copy files from tmpdir into place logger.debug("Copying nulecule data from %s to %s" % (tmpdir, dest)) Utils.copy_dir(tmpdir, dest, update) # Clean up tmpdir logger.debug("Removing tmp dir: %s" % tmpdir) Utils.rm_dir(tmpdir) # Set the proper permissions on the extracted folder Utils.setFileOwnerGroup(dest)
def extract_files(self, image, source, dest): """ Extracts a directory/file in a Docker image to a specified destination. Args: image (str): Docker image name source (str): Source directory in Docker image to copy from dest (str): Path to destination directory on host Returns: None """ logger.info( 'Copying files from image %s:%s to %s' % (image, source, dest)) if self.dryrun: return # Create a dummy container in order to retrieve the file(s) run_cmd = [ self.docker_cli, 'create', '--entrypoint', '/bin/true', image] logger.debug('Creating docker container: %s' % ' '.join(run_cmd)) container_id = subprocess.check_output(run_cmd).strip() # Copy files out of dummy container to the destination directory cp_cmd = [self.docker_cli, 'cp', '%s:/%s' % (container_id, source), dest] logger.debug( 'Copying data from docker container: %s' % ' '.join(cp_cmd)) try: subprocess.check_output(cp_cmd, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: raise DockerException('Copying data from docker container failed: %s. \n%s' % (cp_cmd, e.output)) # Clean up dummy container rm_cmd = [self.docker_cli, 'rm', '-f', container_id] logger.debug('Removing docker container: %s' % ' '.join(rm_cmd)) try: subprocess.check_output(rm_cmd) except subprocess.CalledProcessError as e: raise DockerException('Removing docker container failed: %s. \n%s' % (rm_cmd, e.output)) # Set the proper permissions on the extracted folder Utils.setFileOwnerGroup(dest)
def _write_answers(self, path, answers, answers_format): """ Write answers data to file. Args: path (str): path to answers file to write to answers (dict): Answers data answers_format (str): Format to use to dump answers data to file, e.g., json Returns: None """ logger.debug("Writing answers to file.") logger.debug("FILE: %s", path) logger.debug("ANSWERS: %s", answers) anymarkup.serialize_file(answers, path, format=answers_format) # Make sure that the permission of the file is set to the current user Utils.setFileOwnerGroup(path)
def _write_answers(self, path, answers, answers_format): """ Write answers data to file. Args: path (str): path to answers file to write to answers (dict): Answers data answers_format (str): Format to use to dump answers data to file, e.g., json Returns: None """ logger.debug("Writing answers to file.") logger.debug("FILE: %s", path) logger.debug("ANSWERS: %s", answers) logger.debug("ANSWERS FORMAT: %s", answers_format) anymarkup.serialize_file(answers, path, format=answers_format) # Make sure that the permission of the file is set to the current user Utils.setFileOwnerGroup(path)
def extract_files(self, image, source, dest): """ Extracts a directory/file in a Docker image to a specified destination. Args: image (str): Docker image name source (str): Source directory in Docker image to copy from dest (str): Path to destination directory on host Returns: None """ logger.info("Copying files from image %s:%s to %s" % (image, source, dest)) if self.dryrun: return # Create a dummy container in order to retrieve the file(s) run_cmd = [self.docker_cli, "create", "--entrypoint", "/bin/true", image] logger.debug("Creating docker container: %s" % " ".join(run_cmd)) container_id = subprocess.check_output(run_cmd).strip() # Copy files out of dummy container to the destination directory cp_cmd = [self.docker_cli, "cp", "%s:/%s" % (container_id, source), dest] logger.debug("Copying data from docker container: %s" % " ".join(cp_cmd)) try: subprocess.check_output(cp_cmd, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: raise DockerException("Copying data from docker container failed: %s. \n%s" % (cp_cmd, e.output)) # Clean up dummy container rm_cmd = [self.docker_cli, "rm", "-f", container_id] logger.debug("Removing docker container: %s" % " ".join(rm_cmd)) try: subprocess.check_output(rm_cmd) except subprocess.CalledProcessError as e: raise DockerException("Removing docker container failed: %s. \n%s" % (rm_cmd, e.output)) # Set the proper permissions on the extracted folder Utils.setFileOwnerGroup(dest)
def load_external_application(self, dryrun=False, update=False): """ Loads an external application for the NuleculeComponent. Args: dryrun (bool): When True, skips pulling an external application. update (bool): When True, it ignores an already pulled external application, and tries to pull the external application and update the existing one. Returns: A Nulecule instance or None """ nulecule = None external_app_path = os.path.join( self.basepath, EXTERNAL_APP_DIR, self.name) if os.path.isdir(external_app_path) and not update: logger.info( 'Found existing external application: %s ' 'Loading: ' % self.name) nulecule = Nulecule.load_from_path( external_app_path, dryrun=dryrun, update=update, namespace=self.namespace) elif not dryrun: logger.info('Pulling external application: %s' % self.name) nulecule = Nulecule.unpack( self.source, external_app_path, config=self.config, namespace=self.namespace, dryrun=dryrun, update=update ) # When pulling an external application, make sure that the # "external" folder is owned by the respective user extracting it # by providing the basepath of the extraction Utils.setFileOwnerGroup(self.basepath) self._app = nulecule cockpit_logger.info("Copied app successfully.")