Beispiel #1
0
def _purge_pre_oci_tag(tag, context, allow_non_expired=False):
  assert tag.repository_id == context.repository.id

  if not allow_non_expired:
    assert tag.lifetime_end_ts is not None
    assert tag.lifetime_end_ts <= pre_oci_tag.get_epoch_timestamp()

  # If it exists, GC the tag manifest.
  try:
    tag_manifest = TagManifest.select().where(TagManifest.tag == tag).get()
    _garbage_collect_legacy_manifest(tag_manifest.id, context)
  except TagManifest.DoesNotExist:
    pass

  # Add the tag's legacy image to be GCed.
  context.add_legacy_image_id(tag.image_id)

  with db_transaction():
    # Reload the tag and verify its lifetime_end_ts has not changed.
    try:
      reloaded_tag = db_for_update(RepositoryTag.select().where(RepositoryTag.id == tag.id)).get()
    except RepositoryTag.DoesNotExist:
      return False

    assert reloaded_tag.id == tag.id
    assert reloaded_tag.repository_id == context.repository.id
    if reloaded_tag.lifetime_end_ts != tag.lifetime_end_ts:
      return False

    # Delete mapping rows.
    TagToRepositoryTag.delete().where(TagToRepositoryTag.repository_tag == reloaded_tag).execute()

    # Delete the tag.
    reloaded_tag.delete_instance()
Beispiel #2
0
Datei: tag.py Projekt: zhill/quay
def get_tag_manifest_digests(tags):
    """ Returns a map from tag ID to its associated manifest digest, if any. """
    if not tags:
        return dict()

    manifests = TagManifest.select(
        TagManifest.tag,
        TagManifest.digest).where(TagManifest.tag << [t.id for t in tags])

    return {manifest.tag_id: manifest.digest for manifest in manifests}
Beispiel #3
0
Datei: tag.py Projekt: zhill/quay
def _load_repo_manifests(namespace, repo_name, allow_dead=False):
    query = (TagManifest.select(
        TagManifest,
        RepositoryTag).join(RepositoryTag).join(Image).join(Repository).join(
            Namespace, on=(Namespace.id == Repository.namespace_user)).where(
                Repository.name == repo_name, Namespace.username == namespace))

    if not allow_dead:
        query = _tag_alive(query)

    return query
Beispiel #4
0
Datei: gc.py Projekt: kleesc/quay
def _garbage_collect_legacy_manifest(legacy_manifest_id, context):
    assert legacy_manifest_id is not None

    # Add the labels to be GCed.
    query = TagManifestLabel.select().where(
        TagManifestLabel.annotated == legacy_manifest_id)
    for manifest_label in query:
        context.add_label_id(manifest_label.label_id)

    # Delete the tag manifest.
    with db_transaction():
        try:
            tag_manifest = TagManifest.select().where(
                TagManifest.id == legacy_manifest_id).get()
        except TagManifest.DoesNotExist:
            return False

        assert tag_manifest.id == legacy_manifest_id
        assert tag_manifest.tag.repository_id == context.repository.id

        # Delete any label mapping rows.
        (TagManifestLabelMap.delete().where(
            TagManifestLabelMap.tag_manifest == legacy_manifest_id).execute())

        # Delete the label rows.
        TagManifestLabel.delete().where(
            TagManifestLabel.annotated == legacy_manifest_id).execute()

        # Delete the mapping row if it exists.
        try:
            tmt = (TagManifestToManifest.select().where(
                TagManifestToManifest.tag_manifest == tag_manifest).get())
            context.add_manifest_id(tmt.manifest_id)
            tmt_deleted = tmt.delete_instance()
            if tmt_deleted:
                gc_table_rows_deleted.labels(
                    table="TagManifestToManifest").inc()
        except TagManifestToManifest.DoesNotExist:
            pass

        # Delete the tag manifest.
        tag_manifest_deleted = tag_manifest.delete_instance()
        if tag_manifest_deleted:
            gc_table_rows_deleted.labels(table="TagManifest").inc()
    return True
Beispiel #5
0
def restore_tag_to_manifest(repo_obj, tag_name, manifest_digest):
    """
    Restores a tag to a specific manifest digest.
    """
    with db_transaction():
        # Verify that the manifest digest already existed under this repository under the
        # tag.
        try:
            tag_manifest = (TagManifest.select(
                TagManifest, RepositoryTag,
                Image).join(RepositoryTag).join(Image).where(
                    RepositoryTag.repository == repo_obj).where(
                        RepositoryTag.name == tag_name).where(
                            TagManifest.digest == manifest_digest).get())
        except TagManifest.DoesNotExist:
            raise DataModelException(
                "Cannot restore to unknown or invalid digest")

        # Lookup the existing image, if any.
        try:
            existing_image = get_repo_tag_image(repo_obj, tag_name)
        except DataModelException:
            existing_image = None

        docker_image_id = tag_manifest.tag.image.docker_image_id
        oci_manifest = None
        try:
            oci_manifest = Manifest.get(repository=repo_obj,
                                        digest=manifest_digest)
        except Manifest.DoesNotExist:
            pass

        # Change the tag and tag manifest to point to the updated image.
        updated_tag = create_or_update_tag_for_repo(repo_obj,
                                                    tag_name,
                                                    docker_image_id,
                                                    reversion=True,
                                                    oci_manifest=oci_manifest)
        tag_manifest.tag = updated_tag
        tag_manifest.save()
        return existing_image
def upgrade(op, tables, tester):
    # Backfill migration removed.
    if not tester.is_testing:
        assert TagManifest.select().count() == 0