Skip to content

Commit 618f609

Browse files
kouraulcd
authored andcommitted
GH-47795: [Archery] Add support for custom Docker registry (#47796)
### Rationale for this change `archery docker push` doesn't support custom Docker registry such as ghcr.io. ### What changes are included in this PR? Parse Docker image tag and specify Docker registry name to `docker push` if it's specified in the tag. Docker image tag format: `[HOST[:PORT]/]NAMESPACE/REPOSITORY[:TAG]` See also: https://docs.docker.com/reference/cli/docker/image/tag/#description ### Are these changes tested? Yes. ### Are there any user-facing changes? No. * GitHub Issue: #47795 Authored-by: Sutou Kouhei <kou@clear-code.com> Signed-off-by: Sutou Kouhei <kou@clear-code.com>
1 parent 1f4910b commit 618f609

File tree

2 files changed

+45
-18
lines changed

2 files changed

+45
-18
lines changed

dev/archery/archery/docker/core.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,16 +433,24 @@ def _push(service):
433433
else:
434434
return self._execute_compose(*args, service['name'])
435435

436+
service = self.config.get(service_name)
437+
436438
if user is not None:
439+
login_args = ['--username', user, '--password-stdin']
440+
login_kwargs = {'input': password.encode()}
441+
image = service['image']
442+
# [[HOST[:PORT]/]NAMESPACE/]REPOSITORY[:TAG]
443+
components = image.split('/', 3)
444+
if len(components) == 3:
445+
server = components[0]
446+
login_args.append(server)
437447
try:
438-
# TODO(kszucs): have an option for a prompt
439-
self._execute_docker('login', '-u', user, '-p', password)
448+
self._execute_docker('login', *login_args, **login_kwargs)
440449
except subprocess.CalledProcessError:
441450
# hide credentials
442451
msg = f'Failed to push `{service_name}`, check the passed credentials'
443452
raise RuntimeError(msg) from None
444453

445-
service = self.config.get(service_name)
446454
for ancestor in service['ancestors']:
447455
_push(self.config.get(ancestor))
448456
_push(service)

dev/archery/archery/docker/tests/test_docker.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,39 +140,39 @@
140140
141141
services:
142142
conda-cpp:
143-
image: org/conda-cpp
143+
image: ${REPO}:conda-cpp
144144
build:
145145
context: .
146146
dockerfile: ci/docker/conda-cpp.dockerfile
147147
conda-python:
148-
image: org/conda-python
148+
image: ${REPO}:conda-python
149149
build:
150150
context: .
151151
dockerfile: ci/docker/conda-cpp.dockerfile
152152
args:
153153
python: 3.8
154154
conda-python-pandas:
155-
image: org/conda-python-pandas
155+
image: ${REPO}:conda-python-pandas
156156
build:
157157
context: .
158158
dockerfile: ci/docker/conda-python-pandas.dockerfile
159159
conda-python-dask:
160-
image: org/conda-python-dask
160+
image: ${REPO}:conda-python-dask
161161
ubuntu-cpp:
162-
image: org/ubuntu-cpp
162+
image: ${REPO}:ubuntu-cpp
163163
build:
164164
context: .
165165
dockerfile: ci/docker/ubuntu-${UBUNTU}-cpp.dockerfile
166166
ubuntu-cpp-cmake32:
167-
image: org/ubuntu-cpp-cmake32
167+
image: ${REPO}:ubuntu-cpp-cmake32
168168
ubuntu-c-glib:
169-
image: org/ubuntu-c-glib
169+
image: ${REPO}:ubuntu-c-glib
170170
environment:
171171
<<: [*sccache]
172172
ubuntu-ruby:
173-
image: org/ubuntu-ruby
173+
image: ${REPO}:ubuntu-ruby
174174
ubuntu-cuda:
175-
image: org/ubuntu-cuda
175+
image: ${REPO}:ubuntu-cuda
176176
environment:
177177
CUDA_ENV: 1
178178
OTHER_ENV: 2
@@ -182,6 +182,7 @@
182182
"""
183183

184184
arrow_compose_env = {
185+
'REPO': 'apache/arrow',
185186
'UBUNTU': '20.04', # overridden below
186187
'PYTHON': '3.8',
187188
'PANDAS': 'latest',
@@ -484,7 +485,7 @@ def test_compose_run_with_resource_limits(arrow_compose_path):
484485
"--cpuset-cpus=0,1",
485486
"--memory=7g",
486487
"--memory-swap=7g",
487-
"org/conda-cpp"
488+
"apache/arrow:conda-cpp"
488489
]),
489490
]
490491
compose = DockerCompose(arrow_compose_path)
@@ -493,18 +494,36 @@ def test_compose_run_with_resource_limits(arrow_compose_path):
493494

494495

495496
def test_compose_push(arrow_compose_path):
496-
compose = DockerCompose(arrow_compose_path, params=dict(PYTHON='3.9'))
497+
compose = DockerCompose(arrow_compose_path, params=dict(PYTHON="3.9"))
498+
expected_env = PartialEnv(PYTHON="3.9")
499+
expected_calls = [
500+
mock.call(["docker", "login", "--username", "user",
501+
"--password-stdin"], input=b"pass", check=True),
502+
]
503+
for image in ["conda-cpp", "conda-python", "conda-python-pandas"]:
504+
expected_calls.append(
505+
mock.call(["docker", "compose", f"--file={compose.config.path}",
506+
"push", image], check=True, env=expected_env)
507+
)
508+
with assert_subprocess_calls(expected_calls):
509+
compose.push("conda-python-pandas", user="user", password="pass")
510+
511+
512+
def test_compose_push_custom_server(arrow_compose_path):
513+
compose = DockerCompose(arrow_compose_path, params=dict(
514+
PYTHON="3.9", REPO="ghcr.io/apache/arrow-dev"))
497515
expected_env = PartialEnv(PYTHON="3.9")
498516
expected_calls = [
499-
mock.call(["docker", "login", "-u", "user", "-p", "pass"], check=True),
517+
mock.call(["docker", "login", "--username", "user", "--password-stdin",
518+
"ghcr.io"], input=b"pass", check=True),
500519
]
501520
for image in ["conda-cpp", "conda-python", "conda-python-pandas"]:
502521
expected_calls.append(
503522
mock.call(["docker", "compose", f"--file={compose.config.path}",
504523
"push", image], check=True, env=expected_env)
505524
)
506525
with assert_subprocess_calls(expected_calls):
507-
compose.push('conda-python-pandas', user='user', password='pass')
526+
compose.push("conda-python-pandas", user="user", password="pass")
508527

509528

510529
def test_compose_error(arrow_compose_path):
@@ -533,7 +552,7 @@ def test_image_with_gpu(arrow_compose_path):
533552
"-e", "CUDA_ENV=1",
534553
"-e", "OTHER_ENV=2",
535554
"-v", "/host:/container",
536-
"org/ubuntu-cuda",
555+
"apache/arrow:ubuntu-cuda",
537556
"/bin/bash", "-c", "echo 1 > /tmp/dummy && cat /tmp/dummy",
538557
]
539558
]
@@ -560,7 +579,7 @@ def test_service_info(arrow_compose_path):
560579
compose = DockerCompose(arrow_compose_path)
561580
service = compose.config.raw_config["services"]["conda-cpp"]
562581
assert compose.info(service) == [
563-
" image: org/conda-cpp",
582+
" image: ${REPO}:conda-cpp",
564583
" build",
565584
" context: .",
566585
" dockerfile: ci/docker/conda-cpp.dockerfile"

0 commit comments

Comments
 (0)