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 __init__(self, app_spec, destination=None, cli_answers=None, answers_file=None): """ init function for NuleculeManager. Sets a few instance variables. Args: app_spec: either a path to an unpacked nulecule app or a container image name where a nulecule can be found destination: where to unpack a nulecule to if it isn't local cli_answers: some answer file values provided from cli args answers_file: the location of the answers file """ self.answers = copy.deepcopy(DEFAULT_ANSWERS) self.cli_answers = cli_answers self.answers_format = None self.answers_file = None # The path to an answer file self.app_path = None # The path where the app resides or will reside self.image = None # The container image to pull the app from # Adjust app_spec, destination, and answer file paths if absolute. if os.path.isabs(app_spec): app_spec = Utils.get_real_abspath(app_spec) if destination and os.path.isabs(destination): destination = Utils.get_real_abspath(destination) if answers_file and os.path.isabs(answers_file): answers_file = Utils.get_real_abspath(answers_file) # If the user doesn't want the files copied to a permanent # location then he provides 'none'. If that is the case we'll # use a temporary directory if destination and destination.lower() == 'none': logger.debug("'none' destination requested. Using tmp dir") destination = tempfile.mkdtemp(prefix='atomicapp') # Determine if the user passed us an image or a path to an app if not os.path.exists(app_spec): self.image = app_spec else: self.app_path = app_spec # Doesn't really make much sense to provide an app path and destination, # but if they want to we'll simply just copy the files for them if self.app_path and destination: Utils.copy_dir(self.app_path, destination, update=True) self.app_path = destination # If the user provided an image, make sure we have a destination if self.image: if destination: self.app_path = destination else: self.app_path = Utils.getNewAppCacheDir(self.image) logger.debug("NuleculeManager init app_path: %s", self.app_path) logger.debug("NuleculeManager init image: %s", self.image) # Create the app_path if it doesn't exist yet if not os.path.isdir(self.app_path): os.makedirs(self.app_path) # Set where the main nulecule file should be self.main_file = os.path.join(self.app_path, MAIN_FILE) # Process answers. self.answers_file = answers_file self._process_answers()
def __init__(self, app_spec, destination=None, cli_answers=None, answers_file=None): """ init function for NuleculeManager. Sets a few instance variables. Args: app_spec: either a path to an unpacked nulecule app or a container image name where a nulecule can be found destination: where to unpack a nulecule to if it isn't local cli_answers: some answer file values provided from cli args answers_file: the location of the answers file """ self.answers = copy.deepcopy(DEFAULT_ANSWERS) self.cli_answers = cli_answers self.answers_format = None self.answers_file = None # The path to an answer file self.app_path = None # The path where the app resides or will reside self.image = None # The container image to pull the app from # Adjust app_spec, destination, and answer file paths if absolute. if os.path.isabs(app_spec): app_spec = Utils.get_real_abspath(app_spec) if destination and os.path.isabs(destination): destination = Utils.get_real_abspath(destination) if answers_file and os.path.isabs(answers_file): answers_file = Utils.get_real_abspath(answers_file) # If the user doesn't want the files copied to a permanent # location then he provides 'none'. If that is the case we'll # use a temporary directory if destination and destination.lower() == 'none': logger.debug("'none' destination requested. Using tmp dir") destination = tempfile.mkdtemp(prefix='atomicapp') # Determine if the user passed us an image or a path to an app if not os.path.exists(app_spec): self.image = app_spec else: self.app_path = app_spec # Doesn't really make much sense to provide an app path and destination, # but if they want to we'll simply just copy the files for them if self.app_path and destination: Utils.copy_dir(self.app_path, destination, update=True) self.app_path = destination # If the user provided an image, make sure we have a destination if self.image: if destination: self.app_path = destination else: self.app_path = Utils.getNewAppCacheDir(self.image) logger.debug("NuleculeManager init app_path: %s", self.app_path) logger.debug("NuleculeManager init image: %s", self.image) # Create the app_path if it doesn't exist yet if not os.path.isdir(self.app_path): os.makedirs(self.app_path) # Set where the main nulecule file should be self.main_file = os.path.join(self.app_path, MAIN_FILE) # Process answers. self.answers_file = answers_file self._process_answers()
def extract(self, image, source, dest, update=False): """ Extracts content from a directory in a Docker image to 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 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 dummy container 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 tmpdir tmpdir = '/tmp/nulecule-{}'.format(uuid.uuid1()) cp_cmd = [ self.docker_cli, 'cp', '%s:/%s' % (container_id, source), tmpdir ] logger.debug('Copying data from Docker container: %s' % ' '.join(cp_cmd)) subprocess.call(cp_cmd) # There has been some inconsistent behavior where docker cp # will either copy out the entire dir /APP_ENT_PATH/*files* or # it will copy out just /*files* without APP_ENT_PATH. Detect # that here and adjust accordingly. src = os.path.join(tmpdir, APP_ENT_PATH) if not os.path.exists(src): src = 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(src, 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 logger.debug('Copying nulecule data from %s to %s' % (src, dest)) Utils.copy_dir(src, dest, update) logger.debug('Removing tmp dir: %s' % tmpdir) Utils.rm_dir(tmpdir) # Clean up dummy container rm_cmd = [self.docker_cli, 'rm', '-f', container_id] logger.debug('Removing Docker container: %s' % ' '.join(rm_cmd)) subprocess.call(rm_cmd)
def extract(self, image, source, dest, update=False): """ Extracts content from a directory in a Docker image to 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 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 dummy container 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 tmpdir tmpdir = "/tmp/nulecule-{}".format(uuid.uuid1()) cp_cmd = [self.docker_cli, "cp", "%s:/%s" % (container_id, source), tmpdir] logger.debug("Copying data from docker container: %s" % " ".join(cp_cmd)) subprocess.check_output(cp_cmd) # There has been some inconsistent behavior where docker cp # will either copy out the entire dir /APP_ENT_PATH/*files* or # it will copy out just /*files* without APP_ENT_PATH. Detect # that here and adjust accordingly. src = os.path.join(tmpdir, APP_ENT_PATH) if not os.path.exists(src): src = 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(src, 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 logger.debug("Copying nulecule data from %s to %s" % (src, dest)) Utils.copy_dir(src, dest, update) logger.debug("Removing tmp dir: %s" % tmpdir) Utils.rm_dir(tmpdir) # Clean up dummy container rm_cmd = [self.docker_cli, "rm", "-f", container_id] logger.debug("Removing docker container: %s" % " ".join(rm_cmd)) subprocess.check_output(rm_cmd)
def __init__(self, app_spec, destination=None, answers_file=None): """ init function for NuleculeManager. Sets a few instance variables. Args: app_spec: either a path to an unpacked nulecule app or a container image name where a nulecule can be found destination: where to unpack a nulecule to if it isn't local """ # Let's pass in a default format for our answers self.answers = copy.deepcopy(DEFAULT_ANSWERS) self.answers_format = None self.answers_file = None # The path to an answer file self.app_path = None # The path where the app resides or will reside self.image = None # The container image to pull the app from # Adjust app_spec, destination, and answer file paths if absolute. if os.path.isabs(app_spec): app_spec = os.path.join(Utils.getRoot(), app_spec.lstrip('/')) if destination and os.path.isabs(destination): destination = os.path.join(Utils.getRoot(), destination.lstrip('/')) if answers_file and os.path.isabs(answers_file): answers_file = os.path.join(Utils.getRoot(), answers_file.lstrip('/')) # If the user doesn't want the files copied to a permanent # location then he provides 'none'. If that is the case we'll # use a temporary directory if destination and destination.lower() == 'none': logger.debug("'none' destination requested. Using tmp dir") destination = tempfile.mkdtemp(prefix='atomicapp') # Determine if the user passed us an image or a path to an app if not os.path.exists(app_spec): self.image = app_spec else: self.app_path = app_spec # Doesn't really make much sense to provide an app path and destination, # but if they want to we'll simply just copy the files for them if self.app_path and destination: Utils.copy_dir(self.app_path, destination, update=True) self.app_path = destination # If the user provided an image, make sure we have a destination if self.image: if destination: self.app_path = destination else: self.app_path = Utils.getNewAppCacheDir(self.image) logger.debug("NuleculeManager init app_path: %s", self.app_path) logger.debug("NuleculeManager init image: %s", self.image) # Set where the main nulecule file should be self.main_file = os.path.join(self.app_path, MAIN_FILE) # If user provided a path to answers then make sure it exists. If they # didn't provide one then use the one in the app dir if it exists. if answers_file: self.answers_file = answers_file if not os.path.isfile(self.answers_file): raise NuleculeException( "Path for answers doesn't exist: %s" % self.answers_file) else: if os.path.isfile(os.path.join(self.app_path, ANSWERS_FILE)): self.answers_file = os.path.join(self.app_path, ANSWERS_FILE) # TODO: put this in a better place in the future. # If we are running inside of an openshift pod then override # some of the config by detecting some values from the environment if Utils.running_on_openshift(): self.answers[GLOBAL_CONF]['provider'] = 'openshift' self.answers[GLOBAL_CONF]['accesstoken'] = os.environ['TOKEN_ENV_VAR'] self.answers[GLOBAL_CONF]['namespace'] = os.environ['POD_NAMESPACE'] self.answers[GLOBAL_CONF]['providerapi'] = \ Utils.get_openshift_api_endpoint_from_env()