Ejemplo n.º 1
0
    def deploy(self):
        logger.info("Deploying to provider: Docker")
        for container in self._get_containers():
            if re.match(
                    "%s_+%s+_+[a-zA-Z0-9]{12}" %
                (self.default_name, self.namespace), container):
                raise ProviderFailedException(
                    "Namespace with name %s already deployed in Docker" %
                    self.namespace)

        for artifact in self.artifacts:
            artifact_path = os.path.join(self.path, artifact)
            label_run = None
            with open(artifact_path, "r") as fp:
                label_run = fp.read().strip()
            run_args = label_run.split()

            # If --name is provided, do not re-name due to potential linking of containers. Warn user instead.
            # Else use namespace provided within answers.conf
            if '--name' in run_args:
                logger.info(
                    "WARNING: Using --name provided within artifact file.")
            else:
                run_args.insert(
                    run_args.index('run') + 1, "--name=%s_%s_%s" %
                    (self.default_name, self.namespace, Utils.getUniqueUUID()))

            cmd = run_args
            if self.dryrun:
                logger.info("DRY-RUN: %s", " ".join(cmd))
            else:
                subprocess.check_call(cmd)
Ejemplo n.º 2
0
    def extract(self, image, src, dest, namespace, update=True):
        """
        Extract contents of a container image from 'src' in container
        to 'dest' in host.

        Args:
            image (str): Name of container image
            src (str): Source path in container
            dest (str): Destination path in host
            update (bool): Update existing destination, if True
        """
        if os.path.exists(dest) and not update:
            return
        cleaned_image_name = Utils.sanitizeName(image)
        pod_name = '{}-{}'.format(cleaned_image_name, Utils.getUniqueUUID())
        container_name = cleaned_image_name

        # Pull (if needed) image and bring up a container from it
        # with 'sleep 3600' entrypoint, just to extract content from it
        artifact = {
            'apiVersion': 'v1',
            'kind': 'Pod',
            'metadata': {
                'name': pod_name
            },
            'spec': {
                'containers': [
                    {
                        'image': image,
                        'command': [
                            'sleep',
                            '3600'
                        ],
                        'imagePullPolicy': 'IfNotPresent',
                        'name': container_name
                    }
                ],
                'restartPolicy': 'Always'
            }
        }

        self.create(artifact, namespace)
        try:
            self._wait_till_pod_runs(namespace, pod_name, timeout=300)

            # Archive content from the container and dump it to tmpfile
            tmpfile = '/tmp/atomicapp-{pod}.tar.gz'.format(pod=pod_name)

            self._execute(
                namespace, pod_name, container_name,
                'tar -cz --directory {} ./'.format('/' + src),
                outfile=tmpfile
            )
        finally:
            # Delete created pod
            self.delete(artifact, namespace)

        # Extract archive data
        tar = tarfile.open(tmpfile, 'r:gz')
        tar.extractall(dest)
Ejemplo n.º 3
0
    def init(self):
        self.namespace = DEFAULT_NAMESPACE
        self.default_name = DEFAULT_CONTAINER_NAME

        logger.debug("Given config: %s", self.config)
        if self.config.get("namespace"):
            self.namespace = self.config.get("namespace")
        logger.debug("Namespace: %s", self.namespace)

        if "image" in self.config:
            self.image = Utils.sanitizeName(self.config.get("image"))
        else:
            self.image = Utils.getUniqueUUID()
            logger.warning(
                "The artifact name has not been provided within Nulecule, using a UUID instead"
            )
            logger.debug(
                "No image name found for artifact, using UUID %s in container name"
                % self.image)

        if self.dryrun:
            logger.info("DRY-RUN: Did not check Docker version compatibility")
        else:
            cmd_check = ["docker", "version"]
            try:
                docker_version = subprocess.check_output(cmd_check).split("\n")
            except Exception as ex:
                raise ProviderFailedException(ex)

            client = ""
            server = ""
            for line in docker_version:
                if line.startswith("Client API version"):
                    client = line.split(":")[1]
                if line.startswith("Server API version"):
                    server = line.split(":")[1]

            if client > server:
                msg = (
                    "Docker version in app image (%s) is higher than the one "
                    "on host (%s). Please update your host." %
                    (client, server))
                raise ProviderFailedException(msg)
Ejemplo n.º 4
0
    def init(self):
        self.namespace = DEFAULT_NAMESPACE
        self.default_name = DEFAULT_CONTAINER_NAME

        logger.debug("Given config: %s", self.config)
        if self.config.get("namespace"):
            self.namespace = self.config.get("namespace")
        logger.debug("Namespace: %s", self.namespace)

        if "image" in self.config:
            self.image = Utils.sanitizeName(self.config.get("image"))
        else:
            self.image = Utils.getUniqueUUID()
            logger.warning("The artifact name has not been provided within Nulecule, using a UUID instead")
            logger.debug("No image name found for artifact, using UUID %s in container name" % self.image)

        if self.dryrun:
            logger.info("DRY-RUN: Did not check Docker version compatibility")
        else:
            cmd_check = ["docker", "version"]
            try:
                docker_version = subprocess.check_output(cmd_check).split("\n")
            except Exception as ex:
                raise ProviderFailedException(ex)

            client = ""
            server = ""
            for line in docker_version:
                if line.startswith("Client API version"):
                    client = line.split(":")[1]
                if line.startswith("Server API version"):
                    server = line.split(":")[1]

            if client > server:
                msg = (
                    "Docker version in app image (%s) is higher than the one "
                    "on host (%s). Please update your host." % (client, server)
                )
                raise ProviderFailedException(msg)
Ejemplo n.º 5
0
    def run(self):
        logger.info("Deploying to provider: Docker")
        for container in self._get_containers():
            if re.match("%s_+%s+_+[a-zA-Z0-9]{12}" % (self.namespace, self.image), container):
                raise ProviderFailedException("Container with name %s-%s already deployed in Docker" % (self.namespace, self.image))

        for artifact in self.artifacts:
            artifact_path = os.path.join(self.path, artifact)
            label_run = None
            with open(artifact_path, "r") as fp:
                label_run = fp.read().strip()
                # if docker-run provided as multiline command
                label_run = ' '.join(label_run.split('\\\n'))
            run_args = label_run.split()

            # If --name is provided, do not re-name due to potential linking of containers. Warn user instead.
            # Else use namespace provided within answers.conf
            if '--name' in run_args:
                logger.info("WARNING: Using --name provided within artifact file.")
            else:
                run_args.insert(run_args.index('run') + 1, "--name=%s_%s_%s" % (self.namespace, self.image, Utils.getUniqueUUID()))

            cmd = run_args
            if self.dryrun:
                logger.info("DRY-RUN: %s", " ".join(cmd))
            else:
                subprocess.check_call(cmd)
Ejemplo n.º 6
0
    def run(self):
        logger.info("Deploying to provider: Docker")
        for container in self._get_containers():
            if re.match("%s_+%s+_+[a-zA-Z0-9]{12}" % (self.namespace, self.image), container):
                raise ProviderFailedException("Container with name %s-%s already deployed in Docker" % (self.namespace, self.image))

        for artifact in self.artifacts:
            artifact_path = os.path.join(self.path, artifact)
            label_run = None
            with open(artifact_path, "r") as fp:
                label_run = fp.read().strip()
                # if docker-run provided as multiline command
                label_run = ' '.join(label_run.split('\\\n'))
            run_args = label_run.split()

            # If --name is provided, do not re-name due to potential linking of containers. Warn user instead.
            # Else use namespace provided within answers.conf
            if '--name' in run_args:
                logger.warning("WARNING: Using --name provided within artifact file.")
            else:
                run_args.insert(run_args.index('run') + 1, "--name=%s_%s_%s" % (self.namespace, self.image, Utils.getUniqueUUID()))

            cmd = run_args
            if self.dryrun:
                logger.info("DRY-RUN: %s", " ".join(cmd))
            else:
                try:
                    subprocess.check_output(cmd)
                except subprocess.CalledProcessError as e:
                    raise DockerException("%s. \n%s" % (cmd, e.output))