Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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()