Beispiel #1
0
    def __init__(self, descriptor_path, target, overrides):

        self.descriptor = Image(tools.load_descriptor(descriptor_path),
                                os.path.dirname(descriptor_path))
        self.target = target

        if overrides:
            self.descriptor = self.override(overrides)

        logger.info("Initializing image descriptor...")
Beispiel #2
0
def test_merging_description_override():
    desc1 = Image({'name': 'foo', 'version': 1}, None)

    desc2 = Overrides({'name': 'mod1', 'description': 'mod_desc'})

    merged = _merge_descriptors(desc2, desc1)
    assert 'description' in merged
Beispiel #3
0
def test_merging_description_image():
    desc1 = Image({'name': 'foo', 'version': 1}, None)

    desc2 = Module({'name': 'mod1', 'description': 'mod_desc'}, None)

    merged = _merge_descriptors(desc1, desc2)
    assert 'description' not in merged
Beispiel #4
0
    def __init__(self, descriptor_path, target, overrides):
        descriptor = tools.load_descriptor(descriptor_path)

        # if there is a local modules directory and no modules are defined
        # we will inject it for a backward compatibility
        local_mod_path = os.path.join(
            os.path.abspath(os.path.dirname(descriptor_path)), 'modules')
        if os.path.exists(local_mod_path) and 'modules' in descriptor:
            modules = descriptor.get('modules')
            if not modules.get('repositories'):
                modules['repositories'] = [{
                    'path': local_mod_path,
                    'name': 'modules'
                }]
        self.descriptor = Image(descriptor, os.path.dirname(descriptor_path))
        self.target = target

        if overrides:
            self.descriptor = self.override(overrides)

        logger.info("Initializing image descriptor...")
Beispiel #5
0
def test_image():
    image = Image(
        yaml.safe_load("""
    from: foo
    name: test/foo
    version: 1.9
    labels:
      - name: test
        value: val1
      - name: label2
        value: val2
    envs:
      - name: env1
        value: env1val
    """), 'foo')

    assert image['name'] == 'test/foo'
    assert type(image['labels'][0]) == Label
    assert image['labels'][0]['name'] == 'test'
Beispiel #6
0
class Generator(object):

    def __init__(self, descriptor_path, target, overrides):

        self.descriptor = Image(tools.load_descriptor(descriptor_path),
                                os.path.dirname(descriptor_path))
        self.target = target

        if overrides:
            self.descriptor = self.override(overrides)

        logger.info("Initializing image descriptor...")

    def generate_tech_preview(self):
        name = self.descriptor.get('name')
        if '/' in name:
            family, name = name.split('/')
            self.descriptor['name'] = "%s-tech-preview/%s" % (family, name)
        else:
            self.descriptor['name'] = "%s-tech-preview" % name

    def get_tags(self):
        return ["%s:%s" % (self.descriptor['name'], self.descriptor[
            'version']), "%s:latest" % self.descriptor['name']]

    def prepare_modules(self, descriptor=None):
        """Prepare module to be used for Dockerfile generation.
        This means:

        1. Place module to args.target/image/modules/ directory
        2. Fetch its artifacts to target/image/sources directory
        3. Merge modules descriptor with iamge descriptor

        Arguments:
        descriptor: Module descriptor used to dig required modules,
            if descriptor is not provided image descriptor is used.
        """
        if not descriptor:
            descriptor = self.descriptor

        modules = descriptor.get('modules', {}).get('install', {})

        # If descriptor doesn't requires any module we can start merging descriptors
        # and fetching artifacts. There is nothing left to do except for this
        if not modules:
            self.descriptor.merge(descriptor)
            return

        logger.info("Handling modules...")

        for module in modules:
            version = module.get('version', None)

            req_module = copy_module_to_target(module['name'],
                                               version,
                                               os.path.join(self.target, 'image', 'modules'))
            # If there is any required module it needs to be prepared too
            self.prepare_modules(req_module.descriptor)
            self.descriptor.merge(descriptor)

        logger.debug("Modules handled")

    def prepare_artifacts(self):
        """Goes through artifacts section of image descriptor
        and fetches all of them
        """
        if 'artifacts' not in self.descriptor:
            logger.debug("No artifacts to fetch")
            return

        logger.info("Handling artifacts...")
        target_dir = os.path.join(self.target, 'image')

        for artifact in self.descriptor['artifacts']:
            artifact.copy(target_dir)
        logger.debug("Artifacts handled")

    def override(self, overrides_path):
        logger.info("Using overrides file from '%s'." % overrides_path)
        descriptor = Overrides(tools.load_descriptor(overrides_path))
        descriptor.merge(self.descriptor)
        return descriptor

    def render_dockerfile(self):
        """Renders Dockerfile to $target/image/Dockerfile

        Args:
          template_file - a path to jinja2 template file
        """
        logger.info("Rendering Dockerfile...")

        self.descriptor.process_defaults()

        template_file = os.path.join(os.path.dirname(__file__),
                                     'templates',
                                     'template.jinja')
        loader = FileSystemLoader(os.path.dirname(template_file))
        env = Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)
        env.globals['helper'] = TemplateHelper()
        template = env.get_template(os.path.basename(template_file))

        dockerfile = os.path.join(self.target,
                                  'image',
                                  'Dockerfile')
        if not os.path.exists(os.path.dirname(dockerfile)):
            os.makedirs(os.path.dirname(dockerfile))

        with open(dockerfile, 'wb') as f:
            f.write(template.render(
                self.descriptor.descriptor).encode('utf-8'))
        logger.debug("Dockerfile rendered")

    def prepare_repositories(self):
        """Udates descriptor with added repositories"""
        configured_repositories = tools.cfg.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__')

        added_repos = []
        target_dir = os.path.join(self.target, 'image', 'repos')

        for repo in self.descriptor.get('packages', {}).get('repositories', []):
            if repo not in configured_repositories:
                raise ConcreateError("Package repository '%s' used in descriptor is not "
                                     "available in Concreate configuration file. "
                                     "Available repositories: %s"
                                     % (repo, configured_repository_names))

            urls = configured_repositories[repo]

            if urls:
                # we need to do this in this cycle to prevent creation of empty dir
                if not os.path.exists(target_dir):
                    os.makedirs(target_dir)
                logger.info("Handling additional repository files...")

                for url in urls.split(','):
                    Resource.new({'url': url}).copy(target_dir)
                    added_repos.append(os.path.splitext(
                        os.path.basename(url))[0])

                logger.debug("Additional repository files handled")

                self.descriptor['additional_repos'] = added_repos
Beispiel #7
0
def test_image_missing_name():
    with pytest.raises(ConcreateError):
        Image(yaml.safe_load("""
        from: foo
        version: 1.9"""), 'foo')