Skip to content

Commit 7159395

Browse files
balasankarcRobert Marshall
authored andcommitted
Enable skopeo for container releases
- Adds option that enables container copies with skopeo instead of pull the image, re-tag, and then push it - Retains current pull/re-tag/push behavior as default Related https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5673 Signed-off-by: Balasankar 'Balu' C <[email protected]>
1 parent ef895d0 commit 7159395

File tree

7 files changed

+189
-54
lines changed

7 files changed

+189
-54
lines changed

lib/gitlab/build/gitlab_image.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@ def self.dockerhub_image_name
1212
def self.gitlab_registry_image_name
1313
Build::Info::Package.name
1414
end
15+
16+
def self.source_image_address
17+
gitlab_registry_image_address(tag: Build::Info::Docker.tag)
18+
end
1519
end
1620
end

lib/gitlab/build/image.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require_relative '../util'
2+
require_relative '../skopeo_helper'
23
require_relative '../docker_operations'
34
require_relative 'info/docker'
45

@@ -40,6 +41,20 @@ def tag_and_push_to_dockerhub(final_tag, initial_tag: Build::Info::Docker.tag)
4041
puts "Pushed #{dockerhub_image_name}:#{final_tag} to Docker Hub"
4142
end
4243

44+
def copy_image_to_dockerhub(final_tag)
45+
source = source_image_address
46+
target = "#{dockerhub_image_name}:#{final_tag}"
47+
48+
SkopeoHelper.login('gitlab-ci-token', Gitlab::Util.get_env('CI_JOB_TOKEN'), Gitlab::Util.get_env('CI_REGISTRY'))
49+
SkopeoHelper.login(Gitlab::Util.get_env('DOCKERHUB_USERNAME'), Gitlab::Util.get_env('DOCKERHUB_PASSWORD'), 'docker.io')
50+
51+
SkopeoHelper.copy_image(source, target)
52+
end
53+
54+
def source_image_address
55+
raise NotImplementedError
56+
end
57+
4358
def write_release_file
4459
contents = Build::Info::Docker.release_file_contents
4560
File.write('docker/RELEASE', contents)

lib/gitlab/build/qa_image.rb

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
require_relative '../skopeo_helper'
21
require_relative 'gitlab_image'
32
require_relative 'image'
43
require_relative 'info/qa'
@@ -15,14 +14,8 @@ def self.gitlab_registry_image_name
1514
"#{Build::GitlabImage.gitlab_registry_image_name}-qa"
1615
end
1716

18-
def self.copy_image_to_dockerhub(final_tag)
19-
source = Build::Info::QA.image
20-
target = "#{dockerhub_image_name}:#{final_tag}"
21-
22-
SkopeoHelper.login('gitlab-ci-token', Gitlab::Util.get_env('CI_JOB_TOKEN'), Gitlab::Util.get_env('CI_REGISTRY'))
23-
SkopeoHelper.login(Gitlab::Util.get_env('DOCKERHUB_USERNAME'), Gitlab::Util.get_env('DOCKERHUB_PASSWORD'), 'docker.io')
24-
25-
SkopeoHelper.copy_image(source, target)
17+
def self.source_image_address
18+
Build::Info::QA.image
2619
end
2720
end
2821
end

lib/gitlab/skopeo_helper.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ def copy_image(source, target)
3434
end
3535

3636
puts "\nCopying image `#{source}` to `#{target}`"
37-
status = system(*%W[skopeo copy docker://#{source} docker://#{target}])
37+
38+
# The --all flag is used to support multi-arch, so we can copy all images
39+
# with a single command
40+
status = system(*%W[skopeo copy --all docker://#{source} docker://#{target}])
3841

3942
raise "Failed to copy image." unless status
4043
end

lib/gitlab/tasks/docker_tasks.rake

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,50 @@ namespace :docker do
3838

3939
task :stable do
4040
Gitlab::Util.section('docker:push:stable') do
41-
Build::GitlabImage.tag_and_push_to_dockerhub(Build::Info::Docker.tag)
41+
if Gitlab::Util.get_env('USE_SKOPEO_FOR_DOCKER_RELEASE') == 'true'
42+
Build::GitlabImage.copy_image_to_dockerhub(Build::Info::Docker.tag)
43+
else
44+
Build::GitlabImage.tag_and_push_to_dockerhub(Build::Info::Docker.tag)
45+
end
4246
end
4347
end
4448

4549
# Special tags
4650
task :nightly do
51+
next unless Build::Check.is_nightly?
52+
4753
Gitlab::Util.section('docker:push:nightly') do
48-
Build::GitlabImage.tag_and_push_to_dockerhub('nightly') if Build::Check.is_nightly?
54+
if Gitlab::Util.get_env('USE_SKOPEO_FOR_DOCKER_RELEASE') == 'true'
55+
Build::GitlabImage.copy_image_to_dockerhub('nightly')
56+
else
57+
Build::GitlabImage.tag_and_push_to_dockerhub('nightly')
58+
end
4959
end
5060
end
5161

5262
# push as :rc tag, the :rc is always the latest tagged release
5363
task :rc do
64+
next unless Build::Check.is_latest_tag?
65+
5466
Gitlab::Util.section('docker:push:rc') do
55-
Build::GitlabImage.tag_and_push_to_dockerhub('rc') if Build::Check.is_latest_tag?
67+
if Gitlab::Util.get_env('USE_SKOPEO_FOR_DOCKER_RELEASE') == 'true'
68+
Build::GitlabImage.copy_image_to_dockerhub('rc')
69+
else
70+
Build::GitlabImage.tag_and_push_to_dockerhub('rc')
71+
end
5672
end
5773
end
5874

5975
# push as :latest tag, the :latest is always the latest stable release
6076
task :latest do
77+
next unless Build::Check.is_latest_stable_tag?
78+
6179
Gitlab::Util.section('docker:push:latest') do
62-
Build::GitlabImage.tag_and_push_to_dockerhub('latest') if Build::Check.is_latest_stable_tag?
80+
if Gitlab::Util.get_env('USE_SKOPEO_FOR_DOCKER_RELEASE') == 'true'
81+
Build::GitlabImage.copy_image_to_dockerhub('latest')
82+
else
83+
Build::GitlabImage.tag_and_push_to_dockerhub('latest')
84+
end
6385
end
6486
end
6587

@@ -78,6 +100,11 @@ namespace :docker do
78100
desc "Pull Docker Image from Registry"
79101
namespace :pull do
80102
task :staging do
103+
if Gitlab::Util.get_env('USE_SKOPEO_FOR_DOCKER_RELEASE') == 'true'
104+
puts "USE_SKOPEO_FOR_DOCKER_RELEASE is set. So skipping pulling image."
105+
next
106+
end
107+
81108
Gitlab::Util.section('docker:pull:staging') do
82109
DockerOperations.authenticate("gitlab-ci-token", Gitlab::Util.get_env("CI_JOB_TOKEN"), Gitlab::Util.get_env('CI_REGISTRY'))
83110
Build::GitlabImage.pull

spec/lib/gitlab/skopeo_helper_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
it 'calls skopeo copy command with correct arguments' do
3434
allow(Open3).to receive(:popen2e).with(*%w[skopeo inspect docker://foobar]).and_yield(nil, double(read: 'dummy_output'), double(value: double(success?: true)))
3535

36-
expect(described_class).to receive(:system).with(*%w[skopeo copy docker://foobar docker://dummy-target])
36+
expect(described_class).to receive(:system).with(*%w[skopeo copy --all docker://foobar docker://dummy-target])
3737

3838
described_class.copy_image('foobar', 'dummy-target')
3939
end

spec/lib/gitlab/tasks/docker_tasks_spec.rb

Lines changed: 132 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,32 @@
3030
allow(ENV).to receive(:[]).and_call_original
3131
end
3232

33-
it 'pulls in correct image' do
34-
allow(ENV).to receive(:[]).with('CI_REGISTRY_IMAGE').and_return('dev.gitlab.org:5005/gitlab/omnibus-gitlab')
35-
allow(Build::Info::Package).to receive(:name).and_return('gitlab-ce')
36-
allow(Build::Info::Docker).to receive(:tag).and_return('9.0.0')
37-
allow(DockerOperations).to receive(:authenticate).and_return(true)
33+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is set' do
34+
before do
35+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'true')
36+
end
37+
38+
it 'does not pull image' do
39+
expect(Docker::Image).not_to receive(:create).with('fromImage' => 'dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0')
40+
Rake::Task['docker:pull:staging'].invoke
41+
end
42+
end
3843

39-
expect(Docker::Image).to receive(:create).with('fromImage' => 'dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0')
40-
Rake::Task['docker:pull:staging'].invoke
44+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is not set' do
45+
before do
46+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'false')
47+
end
48+
49+
it 'pulls in correct image' do
50+
allow(ENV).to receive(:[]).with('CI_REGISTRY_IMAGE').and_return('dev.gitlab.org:5005/gitlab/omnibus-gitlab')
51+
allow(Build::Info::Package).to receive(:name).and_return('gitlab-ce')
52+
allow(Build::Info::Docker).to receive(:tag).and_return('9.0.0')
53+
allow(DockerOperations).to receive(:authenticate).and_return(true)
54+
allow(SkopeoHelper).to receive(:login).and_return(true)
55+
56+
expect(Docker::Image).to receive(:create).with('fromImage' => 'dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0')
57+
Rake::Task['docker:pull:staging'].invoke
58+
end
4159
end
4260
end
4361

@@ -46,11 +64,7 @@
4664
let(:dummy_creds) { { username: "test", password: "test" } }
4765

4866
before do
49-
Rake::Task['docker:push:staging'].reenable
5067
Rake::Task['docker:push:stable'].reenable
51-
Rake::Task['docker:push:nightly'].reenable
52-
Rake::Task['docker:push:rc'].reenable
53-
Rake::Task['docker:push:latest'].reenable
5468

5569
allow(ENV).to receive(:[]).and_call_original
5670
allow(ENV).to receive(:[]).with('CI_REGISTRY_IMAGE').and_return('dev.gitlab.org:5005/gitlab/omnibus-gitlab')
@@ -61,44 +75,123 @@
6175
allow(Docker::Image).to receive(:get).and_return(dummy_image)
6276
allow(Docker).to receive(:creds).and_return(dummy_creds)
6377
allow(dummy_image).to receive(:tag).and_return(true)
78+
allow(SkopeoHelper).to receive(:login).and_return(true)
79+
allow(SkopeoHelper).to receive(:copy_image).and_return(true)
6480
end
6581

66-
it 'pushes to staging correctly' do
67-
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0')
68-
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:foo-bar')
69-
Rake::Task['docker:push:staging'].invoke
70-
end
82+
describe 'docker:push:staging' do
83+
before do
84+
Rake::Task['docker:push:staging'].reenable
85+
end
7186

72-
it 'pushes nightly images correctly' do
73-
allow(Build::Check).to receive(:is_nightly?).and_return(true)
74-
75-
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'gitlab/gitlab-ce:nightly')
76-
Rake::Task['docker:push:nightly'].invoke
87+
it 'pushes to staging correctly' do
88+
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0')
89+
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:foo-bar')
90+
Rake::Task['docker:push:staging'].invoke
91+
end
7792
end
7893

79-
it 'pushes latest images correctly' do
80-
allow(Build::Check).to receive(:is_latest_stable_tag?).and_return(true)
81-
82-
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'gitlab/gitlab-ce:latest')
83-
Rake::Task['docker:push:latest'].invoke
94+
describe 'docker:push:nightly' do
95+
before do
96+
Rake::Task['docker:push:nightly'].reenable
97+
allow(Build::Check).to receive(:is_nightly?).and_return(true)
98+
end
99+
100+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is set' do
101+
before do
102+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'true')
103+
end
104+
105+
it 'copies nightly images correctly' do
106+
expect(SkopeoHelper).to receive(:copy_image).with('dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0', 'gitlab/gitlab-ce:nightly')
107+
Rake::Task['docker:push:nightly'].invoke
108+
end
109+
end
110+
111+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is not set' do
112+
before do
113+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'false')
114+
end
115+
116+
it 'pushes nightly images correctly' do
117+
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'gitlab/gitlab-ce:nightly')
118+
Rake::Task['docker:push:nightly'].invoke
119+
end
120+
end
84121
end
85122

86-
it 'pushes rc images correctly' do
87-
allow(Build::Check).to receive(:is_latest_tag?).and_return(true)
88-
89-
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'gitlab/gitlab-ce:rc')
90-
Rake::Task['docker:push:rc'].invoke
123+
describe 'docker:push:latest' do
124+
before do
125+
Rake::Task['docker:push:latest'].reenable
126+
allow(Build::Check).to receive(:is_latest_stable_tag?).and_return(true)
127+
end
128+
129+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is set' do
130+
before do
131+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'true')
132+
end
133+
134+
it 'copies latest images correctly' do
135+
expect(SkopeoHelper).to receive(:copy_image).with('dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0', 'gitlab/gitlab-ce:latest')
136+
Rake::Task['docker:push:latest'].invoke
137+
end
138+
end
139+
140+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is not set' do
141+
before do
142+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'false')
143+
end
144+
145+
it 'pushes latest images correctly' do
146+
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'gitlab/gitlab-ce:latest')
147+
Rake::Task['docker:push:latest'].invoke
148+
end
149+
end
91150
end
92151

93-
it 'pushes triggered images correctly' do
94-
allow(ENV).to receive(:[]).with('CI_COMMIT_REF_SLUG').and_return('foo-bar')
95-
allow(ENV).to receive(:[]).with('CI_REGISTRY_IMAGE').and_return('registry.gitlab.com/gitlab-org/omnibus-gitlab')
96-
allow(ENV).to receive(:[]).with("IMAGE_TAG").and_return("omnibus-12345")
97-
allow(Build::Info::Docker).to receive(:tag).and_call_original
152+
describe 'docker:push:rc' do
153+
before do
154+
Rake::Task['docker:push:rc'].reenable
155+
allow(Build::Check).to receive(:is_latest_tag?).and_return(true)
156+
end
157+
158+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is set' do
159+
before do
160+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'true')
161+
end
162+
163+
it 'copies rc images correctly' do
164+
expect(SkopeoHelper).to receive(:copy_image).with('dev.gitlab.org:5005/gitlab/omnibus-gitlab/gitlab-ce:9.0.0', 'gitlab/gitlab-ce:rc')
165+
Rake::Task['docker:push:rc'].invoke
166+
end
167+
end
168+
169+
context 'when USE_SKOPEO_FOR_DOCKER_RELEASE is not set' do
170+
before do
171+
stub_env_var('USE_SKOPEO_FOR_DOCKER_RELEASE', 'false')
172+
end
173+
174+
it 'pushes rc images correctly' do
175+
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'gitlab/gitlab-ce:rc')
176+
Rake::Task['docker:push:rc'].invoke
177+
end
178+
end
179+
end
98180

99-
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'registry.gitlab.com/gitlab-org/omnibus-gitlab/gitlab-ce:omnibus-12345')
100-
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'registry.gitlab.com/gitlab-org/omnibus-gitlab/gitlab-ce:foo-bar')
101-
Rake::Task['docker:push:triggered'].invoke
181+
describe 'docker:push:triggered' do
182+
before do
183+
Rake::Task['docker:push:triggered'].reenable
184+
allow(ENV).to receive(:[]).with('CI_COMMIT_REF_SLUG').and_return('foo-bar')
185+
allow(ENV).to receive(:[]).with('CI_REGISTRY_IMAGE').and_return('registry.gitlab.com/gitlab-org/omnibus-gitlab')
186+
allow(ENV).to receive(:[]).with("IMAGE_TAG").and_return("omnibus-12345")
187+
allow(Build::Info::Docker).to receive(:tag).and_call_original
188+
end
189+
190+
it 'pushes triggered images correctly' do
191+
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'registry.gitlab.com/gitlab-org/omnibus-gitlab/gitlab-ce:omnibus-12345')
192+
expect(dummy_image).to receive(:push).with(dummy_creds, repo_tag: 'registry.gitlab.com/gitlab-org/omnibus-gitlab/gitlab-ce:foo-bar')
193+
Rake::Task['docker:push:triggered'].invoke
194+
end
102195
end
103196
end
104197
end

0 commit comments

Comments
 (0)