Esempio n. 1
0
 def __post_init__(self):
     validate_pod_name(self.name)
     validate_pod_version(self.version)
     ASSERT.not_empty(self.images)
     ASSERT.unique(app.name for app in self.apps)
     ASSERT.unique(
         [mount.target for mount in self.mounts] + \
         [overlay.target for overlay in self.overlays]
     )
Esempio n. 2
0
 def __post_init__(self):
     validate_pod_label(self.label)
     ctr_models.validate_pod_version(self.version)
     # Only allow specifying image for pods by name for now.
     ASSERT.all(self.images, lambda image: image.name and image.version)
     # The current implementation does not resolve any unit name
     # conflicts (note that because we include pod id in the unit
     # name, they could only conflict within the same group).
     ASSERT.unique(self.systemd_unit_configs,
                   lambda config: config.unit_name)
Esempio n. 3
0
 def __post_init__(self):
     validate_pod_label(self.label)
     ASSERT.equal(
         _get_label_name(_POD_LABEL_PATTERN, self.label),
         self.pod_config_template.name,
     )
     # Only allow specifying image for pods by name for now.
     ASSERT.all(self.images, lambda image: image.name and image.version)
     # Due to bundle directory layout, image names and volume names
     # are expected to be unique.  (This layout restriction should be
     # not too restrictive in practice.)
     ASSERT.unique(self.images, lambda image: image.name)
     ASSERT.unique(self.volumes, lambda volume: volume.name)
     # We use the same format on local alias as on token name.
     ASSERT.all(self.token_names.keys(), validate_token_name)
     ASSERT.all(self.token_names.values(), validate_token_name)
Esempio n. 4
0
        def validate_assigned_values(self, assigned_values):
            """Validate assigned values.

            * No duplicated assignments.
            * Assigned values are a subset of defined values.
            """
            ASSERT.all(assigned_values, lambda value: isinstance(value, str))
            if self.kind == 'range':
                ASSERT.unique(assigned_values)
                ASSERT.all(
                    assigned_values,
                    lambda value: self.args[0] <= int(value) < self.args[1],
                )
            else:
                ASSERT.equal(self.kind, 'values')
                ASSERT.issubset(
                    g1_collections.Multiset(assigned_values),
                    g1_collections.Multiset(self.args),
                )
            return assigned_values
Esempio n. 5
0
 def __post_init__(self):
     # The current implementation does not resolve any unit name
     # conflicts.
     ASSERT.unique(self.units, lambda unit: unit.name)
     ASSERT.not_any(key.startswith(ENV_PREFIX) for key in self.envs)
Esempio n. 6
0
def define_pod(
    *,
    name: str,
    apps: typing.List[App] = (),
    images: typing.List[str] = (),
    mounts: typing.List[Mount] = (),
    volumes: typing.List[Volume] = (),
    systemd_unit_groups: typing.List[SystemdUnitGroup] = (),
    token_names: typing.Mapping[str, str] = None,
):
    """Define a pod.

    This defines:
    * Parameter: name/version.
    * Rule: name/build.  NOTE: This rule is generally run in the host
      system, not inside a builder pod.
    """
    ASSERT(len(images) <= 1, 'expect at most one image per pod for now: {}')
    # Let's require absolute release labels (because it is quite hard to
    # derive label path for images and volumes from pod label).
    ASSERT.all(images, lambda label: label.startswith('//'))
    ASSERT.all(volumes, lambda volume: volume.label.startswith('//'))
    ASSERT.unique(map(_get_label_name, images))
    ASSERT.unique(_get_label_name(volume.label) for volume in volumes)

    name_prefix = shipyard2.rules.canonicalize_name_prefix(name)
    parameter_version = name_prefix + 'version'
    rule_build = name_prefix + 'build'

    (foreman.define_parameter(parameter_version)\
     .with_doc('pod version'))

    images = list(map(foreman.Label.parse, images))

    @foreman.rule(rule_build)
    @foreman.rule.depend('//pods/bases:build')
    @foreman.rule.depend('//releases:build')
    def build(parameters):
        version = ASSERT.not_none(parameters[parameter_version])
        pod_dir_path = releases.get_output_dir_path(parameters, name, version)
        if (
            pod_dir_path / \
            shipyard2.POD_DIR_RELEASE_METADATA_FILENAME
        ).exists():
            LOG.info('skip: build pod: %s %s', name, version)
            return
        LOG.info('build pod: %s %s', name, version)
        try:
            scripts.mkdir(pod_dir_path)
            releases.generate_release_metadata(
                parameters,
                pod_dir_path / shipyard2.POD_DIR_RELEASE_METADATA_FILENAME,
            )
            _generate_deploy_instruction(
                parameters=parameters,
                pod_dir_path=pod_dir_path,
                name=name,
                version=version,
                apps=apps,
                images=images,
                mounts=mounts,
                volumes=volumes,
                systemd_unit_groups=systemd_unit_groups,
                token_names=token_names,
            )
            _link_images(parameters, pod_dir_path, images)
            _link_volumes(parameters, pod_dir_path, volumes)
        except Exception:
            # Roll back on error.
            scripts.rm(pod_dir_path, recursive=True)
            raise

    for label in images:
        build.depend(str(_images.derive_rule(label)))

    return PodRules(build=build)