Пример #1
0
def change_username(user_id, new_username):
    (username_valid, username_issue) = validate_username(new_username)
    if not username_valid:
        raise InvalidUsernameException("Invalid username %s: %s" %
                                       (new_username, username_issue))

    with db_transaction():
        # Reload the user for update
        user = db_for_update(User.select().where(User.id == user_id)).get()

        # Rename the robots
        for robot in db_for_update(
                _list_entity_robots(user.username,
                                    include_metadata=False,
                                    include_token=False)):
            _, robot_shortname = parse_robot_username(robot.username)
            new_robot_name = format_robot_username(new_username,
                                                   robot_shortname)
            robot.username = new_robot_name
            robot.save()

        # Rename the user
        user.username = new_username
        user.save()

        # Remove any prompts for username.
        remove_user_prompt(user, "confirm_username")

        return user
Пример #2
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()
Пример #3
0
def _purge_oci_tag(tag, context, allow_non_expired=False):
  assert tag.repository_id == context.repository.id

  if not allow_non_expired:
    assert tag.lifetime_end_ms is not None
    assert tag.lifetime_end_ms <= oci_tag.get_epoch_timestamp_ms()

  # Add the manifest to be GCed.
  context.add_manifest_id(tag.manifest_id)

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

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

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

    # Delete the tag.
    tag.delete_instance()
Пример #4
0
def replace_service_key(old_kid, kid, jwk, metadata, expiration_date):
    try:
        with db_transaction():
            key = db_for_update(
                ServiceKey.select().where(ServiceKey.kid == old_kid)).get()
            key.metadata.update(metadata)

            ServiceKey.create(
                name=key.name,
                kid=kid,
                service=key.service,
                jwk=jwk,
                metadata=key.metadata,
                expiration_date=expiration_date,
                rotation_duration=key.rotation_duration,
                approval=key.approval,
            )
            key.delete_instance()
    except ServiceKey.DoesNotExist:
        raise ServiceKeyDoesNotExist

    _notify_superusers(key)
    delete_all_notifications_by_path_prefix(
        "/service_key_approval/{0}".format(old_kid))
    _gc_expired(key.service)
Пример #5
0
Файл: user.py Проект: zhill/quay
def mark_namespace_for_deletion(user, queues, namespace_gc_queue, force=False):
    """ Marks a namespace (as referenced by the given user) for deletion. A queue item will be added
      to delete the namespace's repositories and storage, while the namespace itself will be
      renamed, disabled, and delinked from other tables.
  """
    if not user.enabled:
        return None

    if not force and not user.organization:
        # Ensure that the user is not the sole admin for any organizations. If so, then the user
        # cannot be deleted before those organizations are deleted or reassigned.
        organizations = get_solely_admined_organizations(user)
        if len(organizations) > 0:
            message = (
                "Cannot delete %s as you are the only admin for organizations: "
                % user.username)
            for index, org in enumerate(organizations):
                if index > 0:
                    message = message + ", "

                message = message + org.username

            raise DataModelException(message)

    # Delete all queue items for the user.
    for queue in queues:
        queue.delete_namespaced_items(user.username)

    # Delete non-repository related items. This operation is very quick, so we can do so here.
    _delete_user_linked_data(user)

    with db_transaction():
        original_username = user.username
        user = db_for_update(User.select().where(User.id == user.id)).get()

        # Mark the namespace as deleted and ready for GC.
        try:
            marker = DeletedNamespace.create(
                namespace=user,
                original_username=original_username,
                original_email=user.email)
        except IntegrityError:
            return

        # Disable the namespace itself, and replace its various unique fields with UUIDs.
        user.enabled = False
        user.username = str(uuid4())
        user.email = str(uuid4())
        user.save()

    # Add a queueitem to delete the namespace.
    marker.queue_id = namespace_gc_queue.put(
        [str(user.id)],
        json.dumps({
            "marker_id": marker.id,
            "original_username": original_username,
        }),
    )
    marker.save()
    return marker.id
Пример #6
0
Файл: tag.py Проект: zhill/quay
def delete_tag(namespace_name, repository_name, tag_name, now_ms=None):
    now_ms = now_ms or get_epoch_timestamp_ms()
    now_ts = int(now_ms / 1000)

    with db_transaction():
        try:
            query = _tag_alive(
                RepositoryTag.select(
                    RepositoryTag, Repository).join(Repository).join(
                        Namespace,
                        on=(Repository.namespace_user == Namespace.id)).where(
                            Repository.name == repository_name,
                            Namespace.username == namespace_name,
                            RepositoryTag.name == tag_name,
                        ),
                now_ts,
            )
            found = db_for_update(query).get()
        except RepositoryTag.DoesNotExist:
            msg = "Invalid repository tag '%s' on repository '%s/%s'" % (
                tag_name,
                namespace_name,
                repository_name,
            )
            raise DataModelException(msg)

        found.lifetime_end_ts = now_ts
        found.save()

        try:
            oci_tag_query = TagToRepositoryTag.select().where(
                TagToRepositoryTag.repository_tag == found)
            oci_tag = db_for_update(oci_tag_query).get().tag
            oci_tag.lifetime_end_ms = now_ms
            oci_tag.save()
        except TagToRepositoryTag.DoesNotExist:
            pass

        return found
Пример #7
0
def update_service_key(kid, name=None, metadata=None):
  try:
    with db_transaction():
      key = db_for_update(ServiceKey.select().where(ServiceKey.kid == kid)).get()
      if name is not None:
        key.name = name

      if metadata is not None:
        key.metadata.update(metadata)

      key.save()
  except ServiceKey.DoesNotExist:
    raise ServiceKeyDoesNotExist
Пример #8
0
def approve_service_key(kid, approval_type, approver=None, notes=''):
  try:
    with db_transaction():
      key = db_for_update(ServiceKey.select().where(ServiceKey.kid == kid)).get()
      if key.approval is not None:
        raise ServiceKeyAlreadyApproved

      approval = ServiceKeyApproval.create(approver=approver, approval_type=approval_type,
                                           notes=notes)
      key.approval = approval
      key.save()
  except ServiceKey.DoesNotExist:
    raise ServiceKeyDoesNotExist

  delete_all_notifications_by_path_prefix('/service_key_approval/{0}'.format(kid))
  return key
Пример #9
0
def get_existing_repository(namespace_name,
                            repository_name,
                            for_update=False,
                            kind_filter=None):
    query = (Repository.select(Repository, Namespace).join(
        Namespace, on=(Repository.namespace_user == Namespace.id)).where(
            Namespace.username == namespace_name,
            Repository.name == repository_name))

    if kind_filter:
        query = (query.switch(Repository).join(RepositoryKind).where(
            RepositoryKind.name == kind_filter))

    if for_update:
        query = db_for_update(query)

    return query.get()
Пример #10
0
def create_or_update_tag(repo,
                         tag_name,
                         models_ref,
                         manifest_list=None,
                         linked_tag=None,
                         tag_kind="release"):
    Tag = models_ref.Tag

    now_ts = get_epoch_timestamp_ms()
    tag_kind_id = Tag.tag_kind.get_id(tag_kind)
    with db_transaction():
        try:
            tag = db_for_update(
                tag_is_alive(
                    Tag.select().where(Tag.repository == repo,
                                       Tag.name == tag_name,
                                       Tag.tag_kind == tag_kind_id),
                    Tag,
                    now_ts,
                )).get()
            if tag.manifest_list == manifest_list and tag.linked_tag == linked_tag:
                return tag
            tag.lifetime_end = now_ts
            tag.save()
        except Tag.DoesNotExist:
            pass

        try:
            return Tag.create(
                repository=repo,
                manifest_list=manifest_list,
                linked_tag=linked_tag,
                name=tag_name,
                lifetime_start=now_ts,
                lifetime_end=None,
                tag_kind=tag_kind_id,
            )
        except IntegrityError:
            msg = "Tag with name %s and lifetime start %s under repository %s/%s already exists"
            raise TagAlreadyCreatedException(
                msg % (tag_name, now_ts, repo.namespace_user, repo.name))
Пример #11
0
 def _item_by_id_for_update(queue_id):
     return db_for_update(
         QueueItem.select().where(QueueItem.id == queue_id)).get()
Пример #12
0
Файл: tag.py Проект: zhill/quay
def create_or_update_tag_for_repo(repository_id,
                                  tag_name,
                                  tag_docker_image_id,
                                  reversion=False,
                                  oci_manifest=None,
                                  now_ms=None):
    now_ms = now_ms or get_epoch_timestamp_ms()
    now_ts = int(now_ms / 1000)

    with db_transaction():
        try:
            tag = db_for_update(
                _tag_alive(
                    RepositoryTag.select().where(
                        RepositoryTag.repository == repository_id,
                        RepositoryTag.name == tag_name),
                    now_ts,
                )).get()
            tag.lifetime_end_ts = now_ts
            tag.save()

            # Check for an OCI tag.
            try:
                oci_tag = db_for_update(
                    Tag.select().join(TagToRepositoryTag).where(
                        TagToRepositoryTag.repository_tag == tag)).get()
                oci_tag.lifetime_end_ms = now_ms
                oci_tag.save()
            except Tag.DoesNotExist:
                pass
        except RepositoryTag.DoesNotExist:
            pass
        except IntegrityError:
            msg = "Tag with name %s was stale when we tried to update it; Please retry the push"
            raise StaleTagException(msg % tag_name)

        try:
            image_obj = Image.get(Image.docker_image_id == tag_docker_image_id,
                                  Image.repository == repository_id)
        except Image.DoesNotExist:
            raise DataModelException("Invalid image with id: %s" %
                                     tag_docker_image_id)

        try:
            created = RepositoryTag.create(
                repository=repository_id,
                image=image_obj,
                name=tag_name,
                lifetime_start_ts=now_ts,
                reversion=reversion,
            )
            if oci_manifest:
                # Create the OCI tag as well.
                oci_tag = Tag.create(
                    repository=repository_id,
                    manifest=oci_manifest,
                    name=tag_name,
                    lifetime_start_ms=now_ms,
                    reversion=reversion,
                    tag_kind=Tag.tag_kind.get_id("tag"),
                )
                TagToRepositoryTag.create(tag=oci_tag,
                                          repository_tag=created,
                                          repository=repository_id)

            return created
        except IntegrityError:
            msg = "Tag with name %s and lifetime start %s already exists"
            raise TagAlreadyCreatedException(msg % (tag_name, now_ts))