2018-10-06 23:10:08 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-05-09 19:14:46 +00:00
|
|
|
module ContainerRegistry
|
2016-05-04 12:22:54 +00:00
|
|
|
class Tag
|
2019-01-10 14:22:58 +00:00
|
|
|
include Gitlab::Utils::StrongMemoize
|
|
|
|
|
2016-05-04 12:22:54 +00:00
|
|
|
attr_reader :repository, :name
|
2021-09-21 15:12:11 +00:00
|
|
|
attr_writer :created_at
|
2016-05-04 12:22:54 +00:00
|
|
|
|
2016-05-17 18:20:11 +00:00
|
|
|
delegate :registry, :client, to: :repository
|
2016-06-21 11:08:10 +00:00
|
|
|
delegate :revision, :short_revision, to: :config_blob, allow_nil: true
|
2016-05-17 18:20:11 +00:00
|
|
|
|
2016-05-04 12:22:54 +00:00
|
|
|
def initialize(repository, name)
|
2021-04-19 21:09:27 +00:00
|
|
|
@repository = repository
|
|
|
|
@name = name
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def valid?
|
|
|
|
manifest.present?
|
|
|
|
end
|
|
|
|
|
2019-01-10 14:22:58 +00:00
|
|
|
def latest?
|
|
|
|
name == "latest"
|
|
|
|
end
|
|
|
|
|
2016-06-15 10:53:10 +00:00
|
|
|
def v1?
|
|
|
|
manifest && manifest['schemaVersion'] == 1
|
|
|
|
end
|
|
|
|
|
|
|
|
def v2?
|
|
|
|
manifest && manifest['schemaVersion'] == 2
|
|
|
|
end
|
|
|
|
|
2016-05-04 12:22:54 +00:00
|
|
|
def manifest
|
2019-01-10 14:22:58 +00:00
|
|
|
strong_memoize(:manifest) do
|
|
|
|
client.repository_manifest(repository.path, name)
|
|
|
|
end
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
|
|
|
|
2016-05-09 19:27:06 +00:00
|
|
|
def path
|
|
|
|
"#{repository.path}:#{name}"
|
|
|
|
end
|
|
|
|
|
2017-04-10 11:07:36 +00:00
|
|
|
def location
|
|
|
|
"#{repository.location}:#{name}"
|
|
|
|
end
|
|
|
|
|
2016-05-04 12:22:54 +00:00
|
|
|
def [](key)
|
|
|
|
return unless manifest
|
2016-05-17 14:41:47 +00:00
|
|
|
|
2016-05-04 12:22:54 +00:00
|
|
|
manifest[key]
|
|
|
|
end
|
|
|
|
|
|
|
|
def digest
|
2019-01-10 14:22:58 +00:00
|
|
|
strong_memoize(:digest) do
|
|
|
|
client.repository_tag_digest(repository.path, name)
|
|
|
|
end
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
|
|
|
|
2016-05-04 13:15:16 +00:00
|
|
|
def config_blob
|
2016-05-04 12:22:54 +00:00
|
|
|
return unless manifest && manifest['config']
|
2016-05-17 14:41:47 +00:00
|
|
|
|
2019-01-10 14:22:58 +00:00
|
|
|
strong_memoize(:config_blob) do
|
|
|
|
repository.blob(manifest['config'])
|
|
|
|
end
|
2016-05-04 13:15:16 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def config
|
2019-01-10 14:22:58 +00:00
|
|
|
return unless config_blob&.data
|
2016-05-17 14:41:47 +00:00
|
|
|
|
2019-01-10 14:22:58 +00:00
|
|
|
strong_memoize(:config) do
|
|
|
|
ContainerRegistry::Config.new(self, config_blob)
|
|
|
|
end
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def created_at
|
2021-09-21 15:12:11 +00:00
|
|
|
return @created_at if @created_at
|
2016-05-04 12:22:54 +00:00
|
|
|
return unless config
|
2016-05-17 14:41:47 +00:00
|
|
|
|
2021-09-21 15:12:11 +00:00
|
|
|
strong_memoize(:memoized_created_at) do
|
2019-01-10 14:22:58 +00:00
|
|
|
DateTime.rfc3339(config['created'])
|
2019-12-16 12:07:43 +00:00
|
|
|
rescue ArgumentError
|
|
|
|
nil
|
2019-01-10 14:22:58 +00:00
|
|
|
end
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def layers
|
|
|
|
return unless manifest
|
2016-05-17 14:41:47 +00:00
|
|
|
|
2019-01-10 14:22:58 +00:00
|
|
|
strong_memoize(:layers) do
|
|
|
|
layers = manifest['layers'] || manifest['fsLayers']
|
2016-06-15 10:53:10 +00:00
|
|
|
|
2019-01-10 14:22:58 +00:00
|
|
|
layers.map do |layer|
|
|
|
|
repository.blob(layer)
|
|
|
|
end
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-09-19 11:50:12 +00:00
|
|
|
def put(digests)
|
|
|
|
repository.client.put_tag(repository.path, name, digests)
|
|
|
|
end
|
|
|
|
|
2018-08-27 15:31:01 +00:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2016-05-04 12:22:54 +00:00
|
|
|
def total_size
|
|
|
|
return unless layers
|
2016-05-17 14:41:47 +00:00
|
|
|
|
2016-06-15 10:53:10 +00:00
|
|
|
layers.map(&:size).sum if v2?
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
2018-08-27 15:31:01 +00:00
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2016-05-04 12:22:54 +00:00
|
|
|
|
2019-09-19 11:50:12 +00:00
|
|
|
# Deletes the image associated with this tag
|
|
|
|
# Note this will delete the image and all tags associated with it.
|
|
|
|
# Consider using DeleteTagsService instead.
|
|
|
|
def unsafe_delete
|
2016-05-04 12:22:54 +00:00
|
|
|
return unless digest
|
2016-05-17 14:41:47 +00:00
|
|
|
|
2020-02-12 15:09:37 +00:00
|
|
|
client.delete_repository_tag_by_digest(repository.path, digest)
|
2016-05-04 12:22:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|