Exemple #1
0
 def promote(self, from_channel="unpublished", to_channel="edge"):
     self.echo(
         f"Promoting :: {self.entity:^35} :: from:{from_channel} to: {to_channel}"
     )
     charm_id = sh.charm.show(self.entity, "--channel", from_channel, "id")
     charm_id = yaml.safe_load(charm_id.stdout.decode())
     resources_args = []
     try:
         resources = sh.charm(
             "list-resources",
             charm_id["id"]["Id"],
             channel=from_channel,
             format="yaml",
         )
         resources = yaml.safe_load(resources.stdout.decode())
         if resources:
             resources_args = [(
                 "--resource",
                 "{}-{}".format(resource["name"], resource["revision"]),
             ) for resource in resources]
     except sh.ErrorReturnCode:
         self.echo("No resources for {}".format(charm_id))
     sh.charm.release(charm_id["id"]["Id"], "--channel", to_channel,
                      *resources_args)
     self.echo(
         f"Setting {charm_id['id']['Id']} permissions for read everyone")
     cmd_ok(
         ["charm", "grant", charm_id["id"]["Id"], "--acl=read", "everyone"],
         echo=self.echo,
     )
Exemple #2
0
    def promote_all(self, from_channel="unpublished", to_channel="edge"):
        for charm_map in self.artifacts:
            for charm_name, charm_opts in charm_map.items():
                if not any(match in self.filter_by_tag
                           for match in charm_opts["tags"]):
                    continue

                charm_entity = f"cs:~{charm_opts['namespace']}/{charm_name}"
                click.echo(
                    f"Promoting :: {charm_entity:^35} :: from:{from_channel} to: {to_channel}"
                )
                charm_id = sh.charm.show(charm_entity, "--channel",
                                         from_channel, "id")
                charm_id = yaml.safe_load(charm_id.stdout.decode())
                resources_args = []
                try:
                    resources = sh.charm(
                        "list-resources",
                        charm_id["id"]["Id"],
                        channel=from_channel,
                        format="yaml",
                    )
                    resources = yaml.safe_load(resources.stdout.decode())
                    if resources:
                        resources_args = [(
                            "--resource",
                            "{}-{}".format(resource["name"],
                                           resource["revision"]),
                        ) for resource in resources]
                except sh.ErrorReturnCode_1:
                    click.echo("No resources for {}".format(charm_id))
                sh.charm.release(charm_id["id"]["Id"], "--channel", to_channel,
                                 *resources_args)
Exemple #3
0
    def has_changed(self):
        """Determine if the charm/layers commits have changed since last publish to charmstore"""
        if not self.legacy_charm:
            # Operator framework charms won't have a .build.manifest and it's
            # sufficient to just compare the charm repo's commit rev.
            try:
                extra_info = yaml.safe_load(
                    sh.charm(
                        "show",
                        self.full_entity,
                        "extra-info",
                        format="yaml",
                    ).stdout.decode())["extra-info"]
                old_commit = extra_info.get("commit")
                new_commit = self.commit
                changed = new_commit != old_commit
            except sh.ErrorReturnCode:
                changed = True
                old_commit = None
                new_commit = None
            if changed:
                self.echo(
                    f"Changes found: {new_commit} (new) != {old_commit} (old)")
            else:
                self.echo(
                    f"No changes found: {new_commit} (new) == {old_commit} (old)"
                )
            return changed

        charmstore_build_manifest = None
        resp = self.download(".build.manifest")
        if resp.ok:
            charmstore_build_manifest = resp.json()

        if not charmstore_build_manifest:
            self.echo(
                "No build.manifest located, unable to determine if any changes occurred."
            )
            return True

        current_build_manifest = [{
            "rev": curr["rev"],
            "url": curr["url"]
        } for curr in self.build.db["pull_layer_manifest"]]

        # Check the current git cloned charm repo commit and add that to
        # current pull-layer-manifest as that would no be known at the
        # time of pull_layers
        current_build_manifest.append({"rev": self.commit, "url": self.name})

        the_diff = [
            i for i in charmstore_build_manifest["layers"]
            if i not in current_build_manifest
        ]
        if the_diff:
            self.echo("Changes found:")
            self.echo(the_diff)
            return True
        self.echo(f"No changes found, not building a new {self.entity}")
        return False
Exemple #4
0
def resource(charm_entity, channel, builder, out_path, resource_spec):
    out_path = Path(out_path)
    resource_spec = yaml.load(Path(resource_spec).read_text())
    resource_spec_fragment = resource_spec.get(charm_entity, None)
    click.echo(resource_spec_fragment)
    if not resource_spec_fragment:
        raise SystemExit('Unable to determine resource spec for entity')

    os.makedirs(str(out_path), exist_ok=True)
    charm_id = sh.charm.show(charm_entity, '--channel', channel, 'id')
    charm_id = yaml.load(charm_id.stdout.decode())
    try:
        resources = sh.charm('list-resources',
                             charm_id['id']['Id'],
                             channel=channel,
                             format='yaml')
    except sh.ErrorReturnCode_1:
        click.echo('No resources found for {}'.format(charm_id))
        return
    resources = yaml.load(resources.stdout.decode())
    builder_sh = Path(builder).absolute()
    click.echo(builder_sh)
    for line in sh.bash(str(builder_sh), _cwd=out_path, _iter=True):
        click.echo(line.strip())
    for line in glob('{}/*'.format(out_path)):
        resource_path = Path(line)
        resource_fn = resource_path.parts[-1]
        resource_key = resource_spec_fragment.get(resource_fn, None)
        if resource_key:
            out = sh.charm.attach(charm_entity, '--channel', channel,
                                  '{}={}'.format(resource_key, resource_path))
            click.echo(out)
Exemple #5
0
 def download():
     for line in sh.charm("pull-source",
                          "-v",
                          "-i",
                          layer_index,
                          layer_name,
                          _iter=True,
                          _bg_exc=False):
         click.echo(f" -- {line.strip()}")
Exemple #6
0
def _resource(charm_entity, channel, builder, out_path, resource_spec):
    out_path = Path(out_path)
    resource_spec = yaml.safe_load(Path(resource_spec).read_text())
    resource_spec_fragment = resource_spec.get(charm_entity, None)
    click.echo(resource_spec_fragment)
    if not resource_spec_fragment:
        raise SystemExit("Unable to determine resource spec for entity")

    os.makedirs(str(out_path), exist_ok=True)
    charm_id = sh.charm.show(charm_entity, "--channel", channel, "id")
    charm_id = yaml.safe_load(charm_id.stdout.decode())
    try:
        resources = sh.charm("list-resources",
                             charm_id["id"]["Id"],
                             channel=channel,
                             format="yaml")
    except sh.ErrorReturnCode_1:
        click.echo("No resources found for {}".format(charm_id))
        return
    resources = yaml.safe_load(resources.stdout.decode())
    builder_sh = Path(builder).absolute()
    click.echo(builder_sh)
    for line in sh.bash(str(builder_sh),
                        _cwd=out_path,
                        _iter=True,
                        _bg_exc=False):
        click.echo(line.strip())
    for line in glob("{}/*".format(out_path)):
        resource_path = Path(line)
        resource_fn = resource_path.parts[-1]
        resource_key = resource_spec_fragment.get(resource_fn, None)
        if resource_key:
            is_attached = False
            is_attached_count = 0
            while not is_attached:
                try:
                    out = sh.charm.attach(
                        charm_entity,
                        "--channel",
                        channel,
                        f"{resource_key}={resource_path}",
                        _err_to_out=True,
                    )
                    is_attached = True
                except sh.ErrorReturnCode_1 as e:
                    click.echo(f"Problem attaching resources, retrying: {e}")
                    is_attached_count += 1
                    if is_attached_count > 10:
                        raise SystemExit(
                            "Could not attach resource and max retry count reached."
                        )
            click.echo(out)
Exemple #7
0
def promote(charm_entity, from_channel, to_channel):
    charm_id = sh.charm.show(charm_entity, '--channel', from_channel, 'id')
    charm_id = yaml.load(charm_id.stdout.decode())
    resources_args = []
    try:
        resources = sh.charm('list-resources',
                             charm_id['id']['Id'],
                             channel=from_channel,
                             format='yaml')
        resources = yaml.load(resources.stdout.decode())
        if resources:
            resources_args = [('--resource',
                               '{}-{}'.format(resource['name'],
                                              resource['revision']))
                              for resource in resources]
    except sh.ErrorReturnCode_1:
        click.echo("No resources for {}".format(charm_id))
    sh.charm.release(charm_id['id']['Id'], '--channel', to_channel,
                     *resources_args)
Exemple #8
0
 def promote(self, from_channel="unpublished", to_channel="edge"):
     click.echo(
         f"Promoting :: {self.entity:^35} :: from:{from_channel} to: {to_channel}"
     )
     charm_id = sh.charm.show(self.entity, "--channel", from_channel, "id")
     charm_id = yaml.safe_load(charm_id.stdout.decode())
     resources_args = []
     try:
         resources = sh.charm(
             "list-resources",
             charm_id["id"]["Id"],
             channel=from_channel,
             format="yaml",
         )
         resources = yaml.safe_load(resources.stdout.decode())
         if resources:
             resources_args = [(
                 "--resource",
                 "{}-{}".format(resource["name"], resource["revision"]),
             ) for resource in resources]
     except sh.ErrorReturnCode:
         click.echo("No resources for {}".format(charm_id))
     sh.charm.release(charm_id["id"]["Id"], "--channel", to_channel,
                      *resources_args)