1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# frozen_string_literal: true
module ContainerRegistry
class Tag
include Gitlab::Utils::StrongMemoize
attr_reader :repository, :name
delegate :registry, :client, to: :repository
delegate :revision, :short_revision, to: :config_blob, allow_nil: true
def initialize(repository, name)
@repository = repository
@name = name
end
def valid?
manifest.present?
end
def latest?
name == "latest"
end
def v1?
manifest && manifest['schemaVersion'] == 1
end
def v2?
manifest && manifest['schemaVersion'] == 2
end
def manifest
strong_memoize(:manifest) do
client.repository_manifest(repository.path, name)
end
end
def path
"#{repository.path}:#{name}"
end
def location
"#{repository.location}:#{name}"
end
def [](key)
return unless manifest
manifest[key]
end
def digest
strong_memoize(:digest) do
client.repository_tag_digest(repository.path, name)
end
end
def config_blob
return unless manifest && manifest['config']
strong_memoize(:config_blob) do
repository.blob(manifest['config'])
end
end
def config
return unless config_blob&.data
strong_memoize(:config) do
ContainerRegistry::Config.new(self, config_blob)
end
end
def created_at
return unless config
strong_memoize(:created_at) do
DateTime.rfc3339(config['created'])
rescue ArgumentError
nil
end
end
def layers
return unless manifest
strong_memoize(:layers) do
layers = manifest['layers'] || manifest['fsLayers']
layers.map do |layer|
repository.blob(layer)
end
end
end
def put(digests)
repository.client.put_tag(repository.path, name, digests)
end
# rubocop: disable CodeReuse/ActiveRecord
def total_size
return unless layers
layers.map(&:size).sum if v2?
end
# rubocop: enable CodeReuse/ActiveRecord
# 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
return unless digest
client.delete_repository_tag_by_digest(repository.path, digest)
end
end
end
|