コード例 #1
0
ファイル: resource.py プロジェクト: rnc/cekit
def create_resource(descriptor, **kwargs):
    """
    Module method responsible for instantiating proper resource object
    based on the provided descriptor.

    In most cases, only descriptor is required to create the object from descriptor.
    In case additional data is required, the kwargs 'dictionary' will be checked
    if the required key exists and will be used in the object constructor.
    """

    if 'image' in descriptor:
        return _ImageContentResource(descriptor)

    if 'path' in descriptor:
        directory = kwargs.pop('directory')

        if not directory:
            raise CekitError((
                "Internal error: cannot instantiate PathResource: {}, directory was not provided, "
                + "please report it: https://github.com/cekit/cekit/issues"
            ).format(descriptor))

        return _PathResource(descriptor, directory)

    if 'url' in descriptor:
        return _UrlResource(descriptor)

    if 'git' in descriptor:
        return _GitResource(descriptor)

    if 'md5' in descriptor:
        return _PlainResource(descriptor)

    raise CekitError("Resource '{}' is not supported".format(descriptor))
コード例 #2
0
    def add(self, artifact):
        if not set(SUPPORTED_HASH_ALGORITHMS).intersection(artifact):
            raise ValueError('Cannot cache Artifact without checksum')

        if self.is_cached(artifact):
            raise CekitError('Artifact is already cached')

        artifact_id = str(uuid.uuid4())

        artifact_file = os.path.expanduser(
            os.path.join(self._cache_dir, artifact_id))
        if not os.path.exists(artifact_file):
            artifact.guarded_copy(artifact_file)

        cache_entry = {
            'names': [artifact['name']],
            'cached_path': artifact_file
        }

        for alg in SUPPORTED_HASH_ALGORITHMS:
            if alg in artifact:
                if not check_sum(artifact_file, alg, artifact[alg]):
                    raise CekitError('Artifact contains invalid checksum!')
                chksum = artifact[alg]
            else:
                chksum = get_sum(artifact_file, alg)
            cache_entry.update({alg: chksum})

        self._update_cache(cache_entry, artifact_id)
        return artifact_id
コード例 #3
0
ファイル: packages.py プロジェクト: vorburger/cekit
    def _get_repo_url(self, descriptor):
        """Retruns repository url from Cekit config files repositories section"""
        configured_repositories = config.get('repositories')

        # We need to remove the custom "__name__" element before we can show
        # which repository keys are defined in the configuration
        configured_repository_names = configured_repositories.keys()

        if '__name__' in configured_repository_names:
            configured_repository_names.remove('__name__')

        if descriptor['name'] not in configured_repositories:
            if configured_repository_names:
                raise CekitError(
                    "Package repository '%s' used in descriptor is not "
                    "available in Cekit configuration file. "
                    "Available repositories: %s" %
                    (descriptor['name'],
                     ' '.join(configured_repository_names)))
            else:
                raise CekitError(
                    "Package repository '%s' used in descriptor is not "
                    "available in Cekit configuration file. " %
                    descriptor['name'])

        return configured_repositories[descriptor['name']]
コード例 #4
0
ファイル: resource.py プロジェクト: ricardozanini/cekit
    def _copy_impl(self, target):
        if not os.path.exists(self.path):
            cache = config.get('common', 'cache_url')

            # If cache_url is specified in Cekit configuration
            # file - try to fetch the 'path' artifact from cacher
            # even if it was not defined as 'url'.
            if cache:
                try:
                    self._download_file(self.path, target)
                    return target
                except Exception as ex:
                    logger.exception(ex)
                    raise CekitError(
                        "Could not download resource '%s' from cache" %
                        self.name)
            else:
                raise CekitError("Could not copy resource '%s', "
                                 "source path does not exist. "
                                 "Make sure you provided correct path" %
                                 self.name)

        logger.debug("Copying repository from '%s' to '%s'." %
                     (self.path, target))
        if os.path.isdir(self.path):
            shutil.copytree(self.path, target)
        else:
            shutil.copy(self.path, target)
        return target
コード例 #5
0
def copy_module_to_target(name, version, target):
    """Copies a module from args.target/repo/... directory into
    args.target/image/modules/... and update module path to be
    the new location

    Arguments:
    name - name of the module to lookup in modules list
    version - version of the module to used
    target - directory where module will be copied

    Returns instance of copied module.
    """
    if not os.path.exists(target):
        os.makedirs(target)
    # FIXME: version checking

    candidates = [m for m in modules if name == m.name]
    if not candidates:
        raise CekitError("Cannot find requested module: '%s'" % name)

    for module in candidates:
        if not version or version == module.get('version', None):
            dest = os.path.join(target, module.name)

            # if module is already copied, check that the version is correct
            if os.path.exists(dest) and version:
                check_module_version(dest, version)

            if not os.path.exists(dest):
                logger.debug("Copying module '%s' to: '%s'" % (name, dest))
                shutil.copytree(module.path, dest)
            return module

    raise CekitError("Cannot find requested module: '%s', version:'%s'." %
                     (name, version))
コード例 #6
0
ファイル: packages.py プロジェクト: rnc/cekit
    def __init__(self, descriptor, descriptor_path):
        self.schema = packages_schema
        self.descriptor_path = descriptor_path
        super(Packages, self).__init__(descriptor)

        # If 'content_sets' and 'content_sets_file' are defined at the same time
        if set(['content_sets',
                'content_sets_file']).issubset(set(descriptor.keys())):
            raise CekitError(
                "You cannot specify 'content_sets' and 'content_sets_file' together in the packages section!"
            )

        # If the 'content_sets_file' key is set and is not None we need to read the specified
        # file and make it available in the 'content_sets' key. The 'content_sets_file' key is removed
        # afterwards.
        if descriptor.get('content_sets_file', None):
            content_sets_file = os.path.join(self.descriptor_path,
                                             descriptor['content_sets_file'])

            if not os.path.exists(content_sets_file):
                raise CekitError("'%s' file not found!" % content_sets_file)

            with open(content_sets_file, 'r') as file_:
                descriptor['content_sets'] = yaml.safe_load(file_)
            del descriptor['content_sets_file']

        self._prepare()
コード例 #7
0
def get_brew_url(md5):
    try:
        LOGGER.debug("Getting brew details for an artifact with '%s' md5 sum" %
                     md5)
        list_archives_cmd = [
            '/usr/bin/brew', 'call', '--json-output', 'listArchives',
            'checksum=%s' % md5, 'type=maven'
        ]
        LOGGER.debug("Executing '%s'." % " ".join(list_archives_cmd))
        archive_yaml = yaml.safe_load(
            subprocess.check_output(list_archives_cmd))

        if not archive_yaml:
            raise CekitError(
                "Artifact with md5 checksum %s could not be found in Brew" %
                md5)

        archive = archive_yaml[0]
        build_id = archive['build_id']
        filename = archive['filename']
        group_id = archive['group_id']
        artifact_id = archive['artifact_id']
        version = archive['version']

        get_build_cmd = [
            'brew', 'call', '--json-output', 'getBuild',
            'buildInfo=%s' % build_id
        ]
        LOGGER.debug("Executing '%s'" % " ".join(get_build_cmd))
        build = yaml.safe_load(subprocess.check_output(get_build_cmd))

        build_states = [
            'BUILDING', 'COMPLETE', 'DELETED', 'FAILED', 'CANCELED'
        ]

        # State 1 means: COMPLETE which is the only success state. Other states are:
        #
        # 'BUILDING': 0
        # 'COMPLETE': 1
        # 'DELETED': 2
        # 'FAILED': 3
        # 'CANCELED': 4
        if build['state'] != 1:
            raise CekitError(
                "Artifact with checksum {} was found in Koji metadata but the build is in incorrect state ({}) making "
                "the artifact not available for downloading anymore".format(
                    md5, build_states[build['state']]))

        package = build['package_name']
        release = build['release']

        url = 'http://download.devel.redhat.com/brewroot/packages/' + package + '/' + \
            version.replace('-', '_') + '/' + release + '/maven/' + \
            group_id.replace('.', '/') + '/' + \
            artifact_id.replace('.', '/') + '/' + version + '/' + filename
    except subprocess.CalledProcessError as ex:
        LOGGER.error("Can't fetch artifacts details from brew: '%s'." %
                     ex.output)
        raise ex
    return url
コード例 #8
0
def load_descriptor(descriptor):
    """ parses descriptor and validate it against requested schema type

    Args:
      descriptor - yaml descriptor or path to a descriptor to be loaded.
      If a path is provided it must be an absolute path. In other case it's
      assumed that it is a yaml descriptor.

    Returns descriptor as a dictionary
    """

    try:
        data = yaml.safe_load(descriptor)
    except Exception as ex:
        raise CekitError('Cannot load descriptor', ex)

    if isinstance(data, basestring):
        LOGGER.debug("Reading descriptor from '{}' file...".format(descriptor))

        if os.path.exists(descriptor):
            with open(descriptor, 'r') as fh:
                return yaml.safe_load(fh)

        raise CekitError(
            "Descriptor could not be found on the '{}' path, please check your arguments!"
            .format(descriptor))

    LOGGER.debug("Reading descriptor directly...")

    return data
コード例 #9
0
    def build(self, build_args=None):
        """After the source files are generated, the container image can be built.
        We're using Docker to build the image currently.
        """
        args = {}
        args['path'] = os.path.join(self.target, 'image')
        args['tag'] = self._tags[0]
        args['pull'] = self._pull

        # Custom tags for the container image
        logger.debug("Building image with tags: '%s'" %
                     "', '".join(self._tags))

        logger.info("Building container image...")

        try:
            last_tag = ""
            out = docker_client.build(**args)
            lastmsg = ""
            for line in out:
                if b'stream' in line:
                    line = yaml.safe_load(line)['stream']
                elif b'status' in line:
                    line = yaml.safe_load(line)['status']
                elif b'errorDetail' in line:
                    line = yaml.safe_load(line)['errorDetail']['message']
                    raise CekitError("Image build failed: '%s'" % line)

                if '---> Running in ' in line:
                    last_tag = line.split(' ')[-1]

                if line != lastmsg:
                    # this prevents poluting cekit log with dowloading/extracting msgs
                    log_msg = ANSI_ESCAPE.sub('', line).strip()
                    for msg in log_msg.split('\n'):
                        logger.info('Docker: %s' % msg)
                    lastmsg = line

            for tag in self._tags[1:]:
                if ':' in tag:
                    img_repo, img_tag = tag.split(":")
                    docker_client.tag(self._tags[0], img_repo, tag=img_tag)
                else:
                    docker_client.tag(self._tags[0], tag)
            logger.info("Image built and available under following tags: %s"
                        % ", ".join(self._tags))

        except Exception as ex:
            if last_tag:
                failed_img = self._tags[0] + '-failed'
                if ':' in failed_img:
                    img_repo, img_tag = failed_img.split(":")
                    docker_client.commit(last_tag, img_repo, tag=img_tag)
                else:
                    docker_client.commit(last_tag, failed_img)

                logger.error("You can look inside the failed image by running "
                             "'docker run --rm -ti %s bash'" % failed_img)
            raise CekitError("Image build failed, see logs above.", ex)
コード例 #10
0
 def check_prerequisities(self):
     try:
         subprocess.check_output(['sudo', 'buildah', 'version'], stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as ex:
         raise CekitError("Buildah build engine needs buildah"
                          " installed and configured, error: %s"
                          % ex.output)
     except Exception as ex:
         raise CekitError("Buildah build engine needs buildah installed and configured!", ex)
コード例 #11
0
    def get_module(self, name, version=None, suppress_warnings=False):
        """
        Returns the module available in registry based on the name and version requested.

        If no modules are found for the requested name, an error is thrown. If version
        requirement could not be satisfied, an error is thrown too.

        If there is a version mismatch, default version is returned. See 'add_module'
        for more information how default versions are defined.

        Args:
            name (str): module name
            version (float or str): module version

        Returns:
            Module object.

        Raises:
            CekitError: If a module is not found or version requirement is not satisfied
        """

        # Get all modules for specied nam
        modules = self._modules.get(name, {})

        # If there are no modules with the requested name, fail
        if not modules:
            raise CekitError(
                "There are no modules with '{}' name available".format(name))

        # If there is no module version requested, get default one
        if version is None:
            default_version = self._defaults.get(name)

            if not default_version:
                raise CekitError(
                    "Internal error: default version for module '{}' could not be found, please report it"
                    .format(name))

            default_module = self.get_module(name, default_version)

            if not suppress_warnings and len(modules) > 1:
                LOGGER.warning(
                    "Module version not specified for '{}' module, using '{}' default version"
                    .format(name, default_version))

            return default_module

        # Finally, get the module for specified version
        module = modules.get(version)

        # If there is no such module, fail
        if not module:
            raise CekitError(
                "Module '{}' with version '{}' could not be found, available versions: {}"
                .format(name, version, ", ".join(list(modules.keys()))))

        return module
コード例 #12
0
ファイル: resource.py プロジェクト: ricardozanini/cekit
    def _download_file(self, url, destination, use_cache=True):
        """ Downloads a file from url and save it as destination """
        if use_cache:
            url = self.__substitute_cache_url(url)

        if not url:
            raise CekitError(
                "Artifact %s cannot be downloaded, no URL provided" %
                self.name)

        logger.debug("Downloading from '%s' as %s" % (url, destination))

        parsedUrl = urlparse(url)

        if parsedUrl.scheme == 'file' or not parsedUrl.scheme:
            if os.path.isdir(parsedUrl.path):
                shutil.copytree(parsedUrl.path, destination)
            else:
                shutil.copy(parsedUrl.path, destination)
        elif parsedUrl.scheme in ['http', 'https']:
            verify = config.get('common', 'ssl_verify')
            if str(verify).lower() == 'false':
                verify = False

            ctx = ssl.create_default_context()

            if not verify:
                ctx.check_hostname = False
                ctx.verify_mode = ssl.CERT_NONE

            res = urlopen(url, context=ctx)

            if res.getcode() != 200:
                raise CekitError("Could not download file from %s" % url)

            try:
                with open(destination, 'wb') as f:
                    while True:
                        chunk = res.read(1048576)  # 1 MB
                        if not chunk:
                            break
                        f.write(chunk)
            except Exception:
                try:
                    logger.debug(
                        "Removing incompletely downloaded '{}' file".format(
                            destination))
                    os.remove(destination)
                except OSError:
                    logger.warning(
                        "An error occurred while removing file '{}'".format(
                            destination))

                raise
        else:
            raise CekitError("Unsupported URL scheme: %s" % (url))
コード例 #13
0
    def _prepare_content_sets(self, content_sets):
        if not content_sets:
            return False

        arch = platform.machine()

        if arch not in content_sets:
            raise CekitError("There are no content_sets defined for platform '{}'!".format(arch))

        repos = ' '.join(content_sets[arch])

        try:
            # ideally this will be API for ODCS, but there is no python3 package for ODCS
            cmd = ['/usr/bin/odcs']
            odcs_service_type = "Fedora"

            if CONFIG.get('common', 'redhat'):
                odcs_service_type = "Red Hat"
                cmd.append('--redhat')

            LOGGER.info("Using {} ODCS service to created composes".format(odcs_service_type))

            cmd.append('create')

            compose = self.image.get('osbs', {}).get(
                'configuration', {}).get('container', {}).get('compose', {})

            if compose.get(Generator.ODCS_HIDDEN_REPOS_FLAG, False):
                cmd.extend(['--flag', Generator.ODCS_HIDDEN_REPOS_FLAG])

            cmd.extend(['pulp', repos])

            LOGGER.debug("Creating ODCS content set via '%s'" % " ".join(cmd))

            output = subprocess.check_output(cmd).decode()
            normalized_output = '\n'.join(output.replace(" u'", " '")
                                          .replace(' u"', ' "')
                                          .split('\n')[1:])

            odcs_result = yaml.safe_load(normalized_output)

            if odcs_result['state'] != 2:
                raise CekitError("Cannot create content set: '%s'"
                                 % odcs_result['state_reason'])

            repo_url = odcs_result['result_repofile']
            return repo_url

        except CekitError as ex:
            raise ex
        except OSError as ex:
            raise CekitError("ODCS is not installed, please install 'odcs-client' package")
        except subprocess.CalledProcessError as ex:
            raise CekitError("Cannot create content set: '%s'" % ex.output)
        except Exception as ex:
            raise CekitError('Cannot create content set!', ex)
コード例 #14
0
 def check_prerequisities(self):
     try:
         subprocess.check_output(
             [self._rhpkg, 'help'], stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as ex:
         raise CekitError("OSBS build engine needs 'rhpkg' tools installed, error: %s"
                          % ex.output)
     except Exception as ex:
         raise CekitError(
             "OSBS build engine needs '%s' tools installed!" % self._rhpkg, ex)
コード例 #15
0
ファイル: docker_builder.py プロジェクト: rnc/cekit
    def _docker_client(self):
        LOGGER.debug("Preparing Docker client...")

        # Default Docker daemon connection timeout 10 minutes
        # It needs to be high enough to allow Docker daemon to export the
        # image for squashing.
        try:
            timeout = int(os.getenv('DOCKER_TIMEOUT', '600'))
        except ValueError:
            raise CekitError(
                "Provided timeout value: '{}' cannot be parsed as integer, exiting."
                .format(os.getenv('DOCKER_TIMEOUT')))

        if timeout <= 0:
            raise CekitError(
                "Provided timeout value needs to be greater than zero, currently: '{}', exiting."
                .format(timeout))

        params = {"version": "1.22"}
        params.update(docker.utils.kwargs_from_env())
        params["timeout"] = timeout

        try:
            client = APIClientClass(**params)
        except docker.errors.DockerException as e:
            LOGGER.error(
                "Could not create Docker client, please make sure that you "
                "specified valid parameters in the 'DOCKER_HOST' environment variable, "
                "examples: 'unix:///var/run/docker.sock', 'tcp://192.168.22.33:1234'"
            )
            raise CekitError("Error while creating the Docker client", e)

        if client and self._valid_docker_connection(client):
            LOGGER.debug("Docker client ready and working")
            LOGGER.debug(client.version())
            return client

        LOGGER.error(
            "Could not connect to the Docker daemon at '{}', please make sure the Docker "
            "daemon is running.".format(client.base_url))

        if client.base_url.startswith('unix'):
            LOGGER.error(
                "Please make sure the Docker socket has correct permissions.")

        if os.environ.get('DOCKER_HOST'):
            LOGGER.error(
                "If Docker daemon is running, please make sure that you specified valid "
                "parameters in the 'DOCKER_HOST' environment variable, examples: "
                "'unix:///var/run/docker.sock', 'tcp://192.168.22.33:1234'. You may "
                "also need to specify 'DOCKER_TLS_VERIFY', and 'DOCKER_CERT_PATH' "
                "environment variables.")

        raise CekitError("Cannot connect to Docker daemon")
コード例 #16
0
 def __init__(self, target):
     """Check if behave and docker is installed properly"""
     self.target = os.path.abspath(target)
     try:
         subprocess.check_output(['behave', '--version'], stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as ex:
         raise CekitError("Test Runner needs 'behave' installed, '%s'" %
                          ex.output)
     except Exception as ex:
         raise CekitError(
             "Test Runner needs behave installed!", ex)
コード例 #17
0
 def check_prerequisities(self):
     try:
         subprocess.check_output(['docker', 'info'],
                                 stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as ex:
         raise CekitError(
             "Docker build engine needs docker installed and configured, error: %s"
             % ex.output)
     except Exception as ex:
         raise CekitError(
             "Docker build engine needs docker installed and configured!",
             ex)
コード例 #18
0
 def __init__(self, target):
     """Check if behave and docker is installed properly"""
     self.target = os.path.abspath(target)
     try:
         # check that we have behave installed
         from behave.__main__ import main as behave_main
     except subprocess.CalledProcessError as ex:
         raise CekitError("Test Runner needs 'behave' installed, '%s'" %
                          ex.output)
     except Exception as ex:
         raise CekitError(
             "Test Runner needs behave installed!", ex)
コード例 #19
0
ファイル: osbs.py プロジェクト: kyguy/cekit
    def _prepare_configuration(self):
        if 'container' in self and 'container_file' in self:
            raise CekitError(
                'You cannot specify container and container_file together!')

        if 'container_file' in self:
            if not os.path.exists(self['container_file']):
                raise CekitError("'%s' file not found!" %
                                 self['container_file'])
            with open(self['container_file'], 'r') as file_:
                self['container'] = yaml.safe_load(file_)
            del self['container_file']
コード例 #20
0
    def _wait_for_osbs_task(self, task_id, current_time=0, timeout=7200):
        """ Default timeout is 2hrs """

        LOGGER.debug("Checking if task {} is finished...".format(task_id))

        # Time between subsequent querying the API
        sleep_time = 20

        if current_time > timeout:
            raise CekitError(
                "Timed out while waiting for the task {} to finish, please check the task logs!"
                .format(task_id))

        # Definition of task states
        states = {
            'free': 0,
            'open': 1,
            'closed': 2,
            'cancelled': 3,
            'assigned': 4,
            'failed': 5
        }

        # Get information about the task
        try:
            json_info = subprocess.check_output(
                [self._koji, "call", "--json-output", "getTaskInfo",
                 task_id]).strip().decode("utf8")
        except subprocess.CalledProcessError as ex:
            raise CekitError(
                "Could not check the task {} result".format(task_id), ex)

        # Parse the returned JSON
        info = json.loads(json_info)

        # Task is closed which means that it was successfully finished
        if info['state'] == states['closed']:
            return True

        # Task is in progress
        if info['state'] == states['free'] or info['state'] == states[
                'open'] or info['state'] == states['assigned']:
            # It's not necessary to query the API so often
            time.sleep(sleep_time)
            return self._wait_for_osbs_task(task_id, current_time + sleep_time,
                                            timeout)

        # In all other cases (failed, cancelled) task did not finish successfully
        raise CekitError(
            "Task {} did not finish successfully, please check the task logs!".
            format(task_id))
コード例 #21
0
    def _validate_steps_requirements(self):
        logger.debug("Validating steps requirements...")

        req_docker = self._requirement_available('docker', True)
        req_docker_py = self._requirement_available('docker-py', True)

        if not (req_docker or req_docker_py):
            self._suggest_package('docker')
            raise CekitError(
                "Could not find Docker client library, see logs above")

        for req in ['behave', 'requests']:
            if not self._requirement_available(req):
                raise CekitError("Handling of test steps requirements "
                                 "failed, see log for more info.")
コード例 #22
0
ファイル: resource.py プロジェクト: ricardozanini/cekit
    def _copy_impl(self, target):
        # First of all try to download the file using cacher if specified
        if config.get('common', 'cache_url'):
            try:
                self._download_file(None, target)
                return target
            except Exception as e:
                logger.debug(str(e))
                logger.warning(
                    "Could not download '{}' artifact using cacher".format(
                        self.name))

        md5 = self.get('md5')

        # Next option is to download it from Brew directly but only if the md5 checkum
        # is provided and we are running with the --redhat switch
        if md5 and config.get('common', 'redhat'):
            logger.debug(
                "Trying to download artifact '{}' from Brew directly".format(
                    self.name))

            try:
                # Generate the URL
                url = get_brew_url(md5)
                # Use the URL to download the file
                self._download_file(url, target, use_cache=False)
                return target
            except Exception as e:
                logger.debug(str(e))
                logger.warning(
                    "Could not download artifact '{}' from Brew".format(
                        self.name))

        raise CekitError("Artifact {} could not be found".format(self.name))
コード例 #23
0
ファイル: artifact.py プロジェクト: rnc/cekit
    def add(self, artifact):
        if not set(SUPPORTED_HASH_ALGORITHMS).intersection(artifact):
            raise ValueError('Cannot cache artifact without checksum')

        if self.cached(artifact):
            raise CekitError('Artifact is already cached!')

        artifact_id = str(uuid.uuid4())

        artifact_file = os.path.expanduser(
            os.path.join(self.cache_dir, artifact_id))
        if not os.path.exists(artifact_file):
            artifact.guarded_copy(artifact_file)

        cache_entry = {
            'names': [artifact['name']],
            'cached_path': artifact_file
        }

        # We should populate the cache entry with checksums for all supported algorithms
        for alg in SUPPORTED_HASH_ALGORITHMS:
            cache_entry.update({alg: get_sum(artifact_file, alg)})

        self._update_cache(cache_entry, artifact_id)
        return artifact_id
コード例 #24
0
ファイル: buildah.py プロジェクト: ricardozanini/cekit
    def run(self):
        """Build container image using buildah."""
        tags = self.params.tags
        cmd = ["/usr/bin/buildah", "build-using-dockerfile"]

        if not tags:
            tags = self.generator.get_tags()

        if self.params.pull:
            cmd.append('--pull-always')

        # Custom tags for the container image
        LOGGER.debug("Building image with tags: '%s'" % "', '".join(tags))

        for tag in tags:
            cmd.extend(["-t", tag])

        LOGGER.info("Building container image...")

        cmd.append(os.path.join(self.target, 'image'))

        LOGGER.debug("Running Buildah build: '%s'" % " ".join(cmd))

        try:
            subprocess.check_call(cmd)

            LOGGER.info("Image built and available under following tags: %s" %
                        ", ".join(tags))
        except:
            raise CekitError("Image build failed, see logs above.")
コード例 #25
0
def check_module_version(path, version):
    descriptor = Module(
        tools.load_descriptor(os.path.join(path, 'module.yaml')), path,
        os.path.dirname(os.path.abspath(os.path.join(path, 'module.yaml'))))
    if hasattr(descriptor, 'version') and descriptor.version != version:
        raise CekitError("Requested conflicting version '%s' of module '%s'" %
                         (version, descriptor['name']))
コード例 #26
0
    def run(self, image, run_tags):
        """Run test suite"""
        cmd = ['behave',
               '--junit',
               '--junit-directory', 'results',
               '-t', '~ignore',
               '--no-skipped',
               '-D', 'IMAGE=%s' % image]

        for tag in run_tags:
            if ':' in tag:
                test_tag = tag.split(':')[0]

            cmd.append('-t')
            if '/' in tag:
                cmd.append("@%s,@%s" % (test_tag.split('/')[0], test_tag))
            else:
                cmd.append(tag)

        # Check if we're running runtests on CI or locally
        # If we run tests locally - skip all features that
        # are marked with the @ci annotation
        if getpass.getuser() != "jenkins":
            cmd.append("-t")
            cmd.append("~ci ")

        logger.debug("Running '%s'" % ' '.join(cmd))
        try:
            subprocess.check_call(cmd,
                                  stderr=subprocess.STDOUT,
                                  cwd=os.path.join(self.target, 'test'))
        except:
            raise CekitError("Test execution failed, please consult output above")
コード例 #27
0
ファイル: artifact.py プロジェクト: rnc/cekit
    def _find_artifact(self, alg, chksum):
        cache = self._get_cache()
        for _, artifact in cache.items():
            if alg in artifact and artifact[alg] == chksum:
                return artifact

        raise CekitError('Artifact is not cached.')
コード例 #28
0
ファイル: osbs.py プロジェクト: vorburger/cekit
    def __init__(self, descriptor):
        self.schemas = configuration_schema
        super(Configuration, self).__init__(descriptor)
        self.skip_merging = ['container', 'container_file']

        if 'container' in self and 'container_file' in self:
            raise CekitError(
                'You cannot specify container and container_file together!')

        if 'container_file' in self:
            if not os.path.exists(self['container_file']):
                raise CekitError("'%s' file not found!" %
                                 self['container_file'])
            with open(self['container_file'], 'r') as file_:
                self['container'] = yaml.safe_load(file_)
            del self['container_file']
コード例 #29
0
    def build(self):
        """After the source siles are generated, the container image can be built.
        We're using Docker to build the image currently.
        """
        tags = self._tags
        cmd = ["docker", "build"]

        if self._pull:
            cmd.append('--pull')

        # Custom tags for the container image
        logger.debug("Building image with tags: '%s'" % "', '".join(tags))

        for tag in tags:
            cmd.extend(["-t", tag])

        logger.info("Building container image...")

        cmd.append(os.path.join(self.target, 'image'))

        logger.debug("Running Docker build: '%s'" % " ".join(cmd))

        try:
            subprocess.check_call(cmd)

            logger.info("Image built and available under following tags: %s" %
                        ", ".join(tags))
        except:
            raise CekitError("Image build failed, see logs above.")
コード例 #30
0
ファイル: image.py プロジェクト: svkcemk/cekit
    def process_install_list(self, source, to_install_list, install_list, module_registry):
        module_overrides = self._image_overrides['modules']
        artifact_overrides = self._image_overrides['artifacts']
        for to_install in to_install_list:
            logger.debug("Preparing module '{}' required by '{}'.".format(
                to_install.name, source.name))
            override = module_overrides.get(to_install.name, None)
            if override:
                if override.version != to_install.version:
                    logger.debug("Module '{}:{}' being overridden with '{}:{}'.".format
                                 (to_install.name, to_install.version, override.name, override.version))
                # apply module override
                to_install = override

            existing = install_list.get(to_install.name, None)
            # see if we've already processed this
            if existing:
                # check for a version conflict
                if existing.version != to_install.version:
                    logger.warning("Module version inconsistency for {}: {} requested, but {} will be used.".format(
                        to_install.name, to_install.version, existing.version))
                continue

            module = module_registry.get_module(to_install.name, to_install.version)
            if not module:
                raise CekitError("Could not locate module %s version %s. Please verify that it is included in one of the "
                                 "specified module repositories." % (to_install.name, to_install.version))

            # collect artifacts and apply overrides
            module_artifacts = Image._to_dict(module.artifacts)
            for artifact in module.artifacts:
                name = artifact.name
                if name in artifact_overrides:
                    override = artifact_overrides[name]
                    self._all_artifacts[name] = override
                    module_artifacts[name] = override
                else:
                    self._all_artifacts[name] = artifact
            module._descriptor['artifacts'] = list(module_artifacts.values())

            # collect package repositories
            for repo in module.packages.repositories:
                name = repo.name
                if not name in self._package_repositories:
                    self._package_repositories[name] = repo

            # incorporate run specification contributed by module
            if module.run:
                # we're looping in order of install, so we want the current module to override whatever we have
                self._module_run = module.run.merge(self._module_run)

            # prevent circular dependencies. we'll move it to the end after processing
            install_list[to_install.name] = to_install

            # process this modules dependencies
            self.process_install_list(module, module.modules.install, install_list, module_registry)

            # move this module to the end of the list.
            install_list.pop(to_install.name)
            install_list[to_install.name] = to_install