def put(self, namespace, repository, tag): """ Change which image a tag points to or create a new tag. """ if not TAG_REGEX.match(tag): abort(400, TAG_ERROR) repo_ref = registry_model.lookup_repository(namespace, repository) if repo_ref is None: raise NotFound() if "expiration" in request.get_json(): tag_ref = registry_model.get_repo_tag(repo_ref, tag) if tag_ref is None: raise NotFound() expiration = request.get_json().get("expiration") expiration_date = None if expiration is not None: try: expiration_date = datetime.utcfromtimestamp( float(expiration)) except ValueError: abort(400) if expiration_date <= datetime.now(): abort(400) existing_end_ts, ok = registry_model.change_repository_tag_expiration( tag_ref, expiration_date) if ok: if not (existing_end_ts is None and expiration_date is None): log_action( "change_tag_expiration", namespace, { "username": get_authenticated_user().username, "repo": repository, "tag": tag, "namespace": namespace, "expiration_date": expiration_date, "old_expiration_date": existing_end_ts, }, repo_name=repository, ) else: raise InvalidRequest( "Could not update tag expiration; Tag has probably changed" ) if "image" in request.get_json( ) or "manifest_digest" in request.get_json(): existing_tag = registry_model.get_repo_tag( repo_ref, tag, include_legacy_image=True) manifest_or_image = None image_id = None manifest_digest = None if "manifest_digest" in request.get_json(): manifest_digest = request.get_json()["manifest_digest"] manifest_or_image = registry_model.lookup_manifest_by_digest( repo_ref, manifest_digest, require_available=True) else: image_id = request.get_json()["image"] manifest_or_image = registry_model.get_legacy_image( repo_ref, image_id) if manifest_or_image is None: raise NotFound() existing_manifest = ( registry_model.get_manifest_for_tag(existing_tag) if existing_tag else None) existing_manifest_digest = existing_manifest.digest if existing_manifest else None if not registry_model.retarget_tag(repo_ref, tag, manifest_or_image, storage, docker_v2_signing_key): raise InvalidRequest("Could not move tag") username = get_authenticated_user().username log_action( "move_tag" if existing_tag else "create_tag", namespace, { "username": username, "repo": repository, "tag": tag, "namespace": namespace, "image": image_id, "manifest_digest": manifest_digest, "original_manifest_digest": existing_manifest_digest, }, repo_name=repository, ) return "Updated", 201
def put(self, namespace, repository, tag): """ Change which image a tag points to or create a new tag.""" if not TAG_REGEX.match(tag): abort(400, TAG_ERROR) repo_ref = registry_model.lookup_repository(namespace, repository) if repo_ref is None: raise NotFound() if 'expiration' in request.get_json(): tag_ref = registry_model.get_repo_tag(repo_ref, tag) if tag_ref is None: raise NotFound() expiration = request.get_json().get('expiration') expiration_date = None if expiration is not None: try: expiration_date = datetime.utcfromtimestamp( float(expiration)) except ValueError: abort(400) if expiration_date <= datetime.now(): abort(400) existing_end_ts, ok = registry_model.change_repository_tag_expiration( tag_ref, expiration_date) if ok: if not (existing_end_ts is None and expiration_date is None): log_action( 'change_tag_expiration', namespace, { 'username': get_authenticated_user().username, 'repo': repository, 'tag': tag, 'namespace': namespace, 'expiration_date': expiration_date, 'old_expiration_date': existing_end_ts }, repo_name=repository) else: raise InvalidRequest( 'Could not update tag expiration; Tag has probably changed' ) if 'image' in request.get_json( ) or 'manifest_digest' in request.get_json(): existing_tag = registry_model.get_repo_tag( repo_ref, tag, include_legacy_image=True) manifest_or_image = None image_id = None manifest_digest = None if 'image' in request.get_json(): image_id = request.get_json()['image'] manifest_or_image = registry_model.get_legacy_image( repo_ref, image_id) else: manifest_digest = request.get_json()['manifest_digest'] manifest_or_image = registry_model.lookup_manifest_by_digest( repo_ref, manifest_digest, require_available=True) if manifest_or_image is None: raise NotFound() # TODO: Remove this check once fully on V22 existing_manifest_digest = None if existing_tag: existing_manifest = registry_model.get_manifest_for_tag( existing_tag) existing_manifest_digest = existing_manifest.digest if existing_manifest else None if not registry_model.retarget_tag(repo_ref, tag, manifest_or_image, storage, docker_v2_signing_key): raise InvalidRequest('Could not move tag') username = get_authenticated_user().username log_action( 'move_tag' if existing_tag else 'create_tag', namespace, { 'username': username, 'repo': repository, 'tag': tag, 'namespace': namespace, 'image': image_id, 'manifest_digest': manifest_digest, 'original_image': (existing_tag.legacy_image.docker_image_id if existing_tag and existing_tag.legacy_image_if_present else None), 'original_manifest_digest': existing_manifest_digest, }, repo_name=repository) return 'Updated', 201