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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# frozen_string_literal: true
module ContainerRegistry
class Tag
include Gitlab::Utils::StrongMemoize
attr_reader :repository, :name
attr_writer :created_at
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 @created_at if @created_at
strong_memoize(:memoized_created_at) do
next unless config
DateTime.rfc3339(config['created'])
rescue ArgumentError
nil
end
end
# this function will set and memoize a created_at
# to avoid a #config_blob call.
def force_created_at_from_iso8601(string_value)
date =
begin
DateTime.iso8601(string_value)
rescue ArgumentError
nil
end
instance_variable_set(ivar(:memoized_created_at), date)
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.sum(&:size) 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
|