コード例 #1
0
    def push(self):
        """Pushes a built charm to Charmstore"""

        if "override-push" in self.opts:
            self.echo("Override push found, running in place of charm push.")
            script(
                self.opts["override-push"],
                cwd=self.src_path,
                charm=self.name,
                namespace=self.namespace,
                echo=self.echo,
            )
            return

        self.echo(f"Pushing built {self.dst_path} to {self.entity}")

        out = retry_call(
            capture,
            fargs=[["charm", "push", self.dst_path, self.entity]],
            fkwargs={"check": True},
            delay=2,
            backoff=2,
            exceptions=CalledProcessError,
        )
        self.echo(f"Charm push returned: {out}")
        # Output includes lots of ansi escape sequences from the docker push,
        # and we only care about the first line, which contains the url as yaml.
        out = yaml.safe_load(out.stdout.decode().strip().splitlines()[0])
        self.new_entity = out["url"]
        self.echo(f"Setting {self.new_entity} metadata: {self.commit}")
        cmd_ok(["charm", "set", self.new_entity, f"commit={self.commit}"],
               echo=self.echo)
コード例 #2
0
    def charm_build(self):
        """Perform a build against charm/bundle."""
        lxc = os.environ.get("charmcraft_lxc")
        ret = SimpleNamespace(ok=False)
        if "override-build" in self.opts:
            self.echo("Override build found, running in place of charm build.")
            ret = script(
                self.opts["override-build"],
                cwd=self.src_path,
                charm=self.name,
                echo=self.echo,
            )
        elif self.reactive:
            args = "-r --force -i https://localhost"
            if self.store == "ch":
                args += " --charm-file"
            else:
                self.dst_path = str(self.build.build_dir / self.name)
            self.echo(f"Building with: charm build {args}")
            ret = CharmCmd(self).build(*args.split(), _cwd=self.src_path)
        elif lxc:
            self.echo(f"Building in container {lxc}")
            repository = f"https://github.com/{self.downstream}"
            charmcraft_script = (
                "#!/bin/bash -eux\n"
                f"source {Path(__file__).parent / 'charmcraft-lib.sh'}\n"
                f"ci_charmcraft_pack {lxc} {repository} {self.branch} {self.opts.get('subdir', '')}\n"
                f"ci_charmcraft_copy {lxc} {self.dst_path}\n")
            ret = script(charmcraft_script, echo=self.echo)
        else:
            self.echo("No 'charmcraft_lxc' container available")

        if not ret.ok:
            self.echo("Failed to build, aborting")
            raise BuildException(f"Failed to build {self.name}")
コード例 #3
0
    def charm_build(self):
        """Perform charm build against charm/bundle"""
        if "override-build" in self.opts:
            self.echo("Override build found, running in place of charm build.")
            ret = script(
                self.opts["override-build"],
                cwd=self.src_path,
                charm=self.name,
                echo=self.echo,
            )
        elif self.legacy_charm:
            cmd = "charm build -r --force -i https://localhost"
            self.echo(f"Building with: {cmd}")
            ret = cmd_ok(
                cmd,
                cwd=self.src_path,
                echo=self.echo,
            )
        else:
            cmd = f"charmcraft build -f {self.src_path}"
            self.echo(f"Building with: {cmd}")
            ret = cmd_ok(
                cmd,
                cwd=self.build.build_dir,
                echo=self.echo,
            )

        if not ret.ok:
            self.echo("Failed to build, aborting")
            raise SystemExit(f"Failed to build {self.name}")
コード例 #4
0
    def attach_resources(self):
        out_path = Path(self.src_path) / "tmp"
        os.makedirs(str(out_path), exist_ok=True)
        resource_spec = yaml.safe_load(
            Path(self.build.resource_spec).read_text())
        resources = resource_spec.get(self.entity, {})

        # Build any custom resources.
        resource_builder = self.opts.get("build-resources", None)
        if resource_builder and not resources:
            raise SystemExit(
                "Custom build-resources specified for {self.entity} but no spec found"
            )
        if resource_builder:
            resource_builder = resource_builder.format(
                out_path=out_path,
                src_path=self.src_path,
            )
            self.echo("Running custom build-resources")
            ret = script(resource_builder, echo=self.echo)
            if not ret.ok:
                raise SystemExit("Failed to build custom resources")

        # Pull any `upstream-image` annotated resources.
        for name, details in self._read_metadata_resources().items():
            upstream_image = details.get("upstream-source")
            if details["type"] == "oci-image" and upstream_image:
                self.echo(f"Pulling {upstream_image}...")
                sh.docker.pull(upstream_image)
                resources[name] = upstream_image

        self.echo(f"Attaching resources:\n{pformat(resources)}")
        # Attach all resources.
        for name, resource in resources.items():
            # If the resource is a file, populate the path where it was built.
            # If it's a custom image, it will be in Docker and this will be a no-op.
            resource = resource.format(out_path=out_path)
            retry_call(
                cmd_ok,
                fargs=[[
                    "charm",
                    "attach",
                    self.new_entity,
                    f"{name}={resource}",
                ]],
                fkwargs={
                    "check": True,
                    "echo": self.echo
                },
                delay=2,
                backoff=2,
                tries=15,
                exceptions=CalledProcessError,
            )
コード例 #5
0
    def attach_resources(self):
        """Assemble charm's resources and associate in the store."""
        out_path = Path(self.src_path) / "tmp"
        os.makedirs(str(out_path), exist_ok=True)
        resource_spec = yaml.safe_load(
            Path(self.build.resource_spec).read_text())
        resource_spec = resource_spec.get(self.name, {})

        # Build any custom resources.
        resource_builder = self.opts.get("build-resources", None)
        if resource_builder and not resource_spec:
            raise BuildException(
                f"Custom build-resources specified for {self.name} but no spec found"
            )
        if resource_builder:
            resource_builder = resource_builder.format(
                out_path=out_path,
                src_path=self.src_path,
            )
            self.echo("Running custom build-resources")
            ret = script(resource_builder, echo=self.echo)
            if not ret.ok:
                raise BuildException("Failed to build custom resources")

        for name, details in self._read_metadata_resources().items():
            resource_fmt = resource_spec.get(name)
            if not resource_fmt:
                # ignore pushing a resource not defined in `resource_spec`
                continue
            if details["type"] == "oci-image":
                upstream_source = details.get("upstream-source")
                if upstream_source:
                    # Pull any `upstream-image` annotated resources.
                    self.echo(f"Pulling {upstream_source}...")
                    sh.docker.pull(upstream_source)
                    resource_fmt = upstream_source
                resource_spec[name] = ("image", resource_fmt)
            elif details["type"] == "file":
                resource_spec[name] = (
                    "filepath",
                    resource_fmt.format(out_path=out_path),
                )

        self.echo(f"Attaching resources:\n{pformat(resource_spec)}")
        # Attach all resources.
        for resource_name, resource in resource_spec.items():
            if self.store == "cs":
                _CharmStore(self).upload_resource(self.new_entity,
                                                  resource_name, resource[1])
            elif self.store == "ch":
                _CharmHub(self).upload_resource(self.entity, resource_name,
                                                resource)
コード例 #6
0
    def push(self):
        """Pushes a built charm to Charm store/hub."""
        if "override-push" in self.opts:
            self.echo("Override push found, running in place of charm push.")
            script(
                self.opts["override-push"],
                cwd=self.src_path,
                charm=self.name,
                namespace=self.namespace,
                echo=self.echo,
            )
            return

        self.echo(
            f"Pushing {self.type}({self.name}) from {self.dst_path} to {self.entity}"
        )
        if self.store == "cs":
            cs = _CharmStore(self)
            self.new_entity = cs.upload(self.dst_path, self.entity)
            cs.set(self.new_entity, self.commit)
        elif self.store == "ch":
            self.new_entity = _CharmHub(self).upload(self.dst_path)