Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions dev/archery/archery/docker/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,16 +433,24 @@ def _push(service):
else:
return self._execute_compose(*args, service['name'])

service = self.config.get(service_name)

if user is not None:
login_args = ['--username', user, '--password-stdin']
login_kwargs = {'input': password.encode()}
image = service['image']
# [[HOST[:PORT]/]NAMESPACE/]REPOSITORY[:TAG]
components = image.split('/', 3)
if len(components) == 3:
server = components[0]
login_args.append(server)
try:
# TODO(kszucs): have an option for a prompt
self._execute_docker('login', '-u', user, '-p', password)
self._execute_docker('login', *login_args, **login_kwargs)
except subprocess.CalledProcessError:
# hide credentials
msg = f'Failed to push `{service_name}`, check the passed credentials'
raise RuntimeError(msg) from None

service = self.config.get(service_name)
for ancestor in service['ancestors']:
_push(self.config.get(ancestor))
_push(service)
Expand Down
49 changes: 34 additions & 15 deletions dev/archery/archery/docker/tests/test_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,39 +140,39 @@

services:
conda-cpp:
image: org/conda-cpp
image: ${REPO}:conda-cpp
build:
context: .
dockerfile: ci/docker/conda-cpp.dockerfile
conda-python:
image: org/conda-python
image: ${REPO}:conda-python
build:
context: .
dockerfile: ci/docker/conda-cpp.dockerfile
args:
python: 3.8
conda-python-pandas:
image: org/conda-python-pandas
image: ${REPO}:conda-python-pandas
build:
context: .
dockerfile: ci/docker/conda-python-pandas.dockerfile
conda-python-dask:
image: org/conda-python-dask
image: ${REPO}:conda-python-dask
ubuntu-cpp:
image: org/ubuntu-cpp
image: ${REPO}:ubuntu-cpp
build:
context: .
dockerfile: ci/docker/ubuntu-${UBUNTU}-cpp.dockerfile
ubuntu-cpp-cmake32:
image: org/ubuntu-cpp-cmake32
image: ${REPO}:ubuntu-cpp-cmake32
ubuntu-c-glib:
image: org/ubuntu-c-glib
image: ${REPO}:ubuntu-c-glib
environment:
<<: [*sccache]
ubuntu-ruby:
image: org/ubuntu-ruby
image: ${REPO}:ubuntu-ruby
ubuntu-cuda:
image: org/ubuntu-cuda
image: ${REPO}:ubuntu-cuda
environment:
CUDA_ENV: 1
OTHER_ENV: 2
Expand All @@ -182,6 +182,7 @@
"""

arrow_compose_env = {
'REPO': 'apache/arrow',
'UBUNTU': '20.04', # overridden below
'PYTHON': '3.8',
'PANDAS': 'latest',
Expand Down Expand Up @@ -484,7 +485,7 @@ def test_compose_run_with_resource_limits(arrow_compose_path):
"--cpuset-cpus=0,1",
"--memory=7g",
"--memory-swap=7g",
"org/conda-cpp"
"apache/arrow:conda-cpp"
]),
]
compose = DockerCompose(arrow_compose_path)
Expand All @@ -493,18 +494,36 @@ def test_compose_run_with_resource_limits(arrow_compose_path):


def test_compose_push(arrow_compose_path):
compose = DockerCompose(arrow_compose_path, params=dict(PYTHON='3.9'))
compose = DockerCompose(arrow_compose_path, params=dict(PYTHON="3.9"))
expected_env = PartialEnv(PYTHON="3.9")
expected_calls = [
mock.call(["docker", "login", "--username", "user",
"--password-stdin"], input=b"pass", check=True),
]
for image in ["conda-cpp", "conda-python", "conda-python-pandas"]:
expected_calls.append(
mock.call(["docker", "compose", f"--file={compose.config.path}",
"push", image], check=True, env=expected_env)
)
with assert_subprocess_calls(expected_calls):
compose.push("conda-python-pandas", user="user", password="pass")


def test_compose_push_custom_server(arrow_compose_path):
compose = DockerCompose(arrow_compose_path, params=dict(
PYTHON="3.9", REPO="ghcr.io/apache/arrow-dev"))
expected_env = PartialEnv(PYTHON="3.9")
expected_calls = [
mock.call(["docker", "login", "-u", "user", "-p", "pass"], check=True),
mock.call(["docker", "login", "--username", "user", "--password-stdin",
"ghcr.io"], input=b"pass", check=True),
]
for image in ["conda-cpp", "conda-python", "conda-python-pandas"]:
expected_calls.append(
mock.call(["docker", "compose", f"--file={compose.config.path}",
"push", image], check=True, env=expected_env)
)
with assert_subprocess_calls(expected_calls):
compose.push('conda-python-pandas', user='user', password='pass')
compose.push("conda-python-pandas", user="user", password="pass")


def test_compose_error(arrow_compose_path):
Expand Down Expand Up @@ -533,7 +552,7 @@ def test_image_with_gpu(arrow_compose_path):
"-e", "CUDA_ENV=1",
"-e", "OTHER_ENV=2",
"-v", "/host:/container",
"org/ubuntu-cuda",
"apache/arrow:ubuntu-cuda",
"/bin/bash", "-c", "echo 1 > /tmp/dummy && cat /tmp/dummy",
]
]
Expand All @@ -560,7 +579,7 @@ def test_service_info(arrow_compose_path):
compose = DockerCompose(arrow_compose_path)
service = compose.config.raw_config["services"]["conda-cpp"]
assert compose.info(service) == [
" image: org/conda-cpp",
" image: ${REPO}:conda-cpp",
" build",
" context: .",
" dockerfile: ci/docker/conda-cpp.dockerfile"
Expand Down