Skip to content
Closed
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
10 changes: 8 additions & 2 deletions docker/models/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
NotFound, create_unexpected_kwargs_error
)
from ..types import HostConfig
from ..utils import version_gte
from ..utils import parse_repository_tag, version_gte
from .images import Image
from .resource import Collection, Model

Expand Down Expand Up @@ -541,7 +541,8 @@ def run(self, image, command=None, stdout=True, stderr=False,
'Reticulating spline 1...\\nReticulating spline 2...\\n'

Args:
image (str): The image to run.
image (str): The image to run. If the tag is not specified, it will
be set to "latest".
command (str or list): The command to run in the container.
auto_remove (bool): enable auto-removal of the container on daemon
side when the container's process exits.
Expand Down Expand Up @@ -788,6 +789,11 @@ def run(self, image, command=None, stdout=True, stderr=False,
"""
if isinstance(image, Image):
image = image.id
else:
_, tag = parse_repository_tag(image)
if tag is None:
image += ":latest"

stream = kwargs.pop('stream', False)
detach = kwargs.pop('detach', False)
platform = kwargs.pop('platform', None)
Expand Down
8 changes: 4 additions & 4 deletions tests/integration/models_containers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_run_detach(self):
client = docker.from_env(version=TEST_API_VERSION)
container = client.containers.run("alpine", "sleep 300", detach=True)
self.tmp_containers.append(container.id)
assert container.attrs['Config']['Image'] == "alpine"
assert container.attrs['Config']['Image'] == "alpine:latest"
assert container.attrs['Config']['Cmd'] == ['sleep', '300']

def test_run_with_error(self):
Expand Down Expand Up @@ -187,7 +187,7 @@ def test_get(self):
container = client.containers.run("alpine", "sleep 300", detach=True)
self.tmp_containers.append(container.id)
assert client.containers.get(container.id).attrs[
'Config']['Image'] == "alpine"
'Config']['Image'] == "alpine:latest"

def test_list(self):
client = docker.from_env(version=TEST_API_VERSION)
Expand All @@ -199,7 +199,7 @@ def test_list(self):
assert len(containers) == 1

container = containers[0]
assert container.attrs['Config']['Image'] == 'alpine'
assert container.attrs['Config']['Image'] == 'alpine:latest'
assert container.status == 'running'
assert container.image == client.images.get('alpine')

Expand All @@ -217,7 +217,7 @@ def test_list_sparse(self):
assert len(containers) == 1

container = containers[0]
assert container.attrs['Image'] == 'alpine'
assert container.attrs['Image'] == 'alpine:latest'
assert container.status == 'running'
assert container.image == client.images.get('alpine')
with pytest.raises(docker.errors.DockerException):
Expand Down
30 changes: 25 additions & 5 deletions tests/unit/models_containers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_run(self):
assert out == b'hello world\n'

client.api.create_container.assert_called_with(
image="alpine",
image="alpine:latest",
command="echo hello world",
detach=False,
host_config={'NetworkMode': 'default'}
Expand Down Expand Up @@ -210,7 +210,7 @@ def test_run_detach(self):
assert isinstance(container, Container)
assert container.id == FAKE_CONTAINER_ID
client.api.create_container.assert_called_with(
image='alpine',
image='alpine:latest',
command='sleep 300',
detach=True,
host_config={
Expand All @@ -233,7 +233,27 @@ def test_run_pull(self):

assert container.id == FAKE_CONTAINER_ID
client.api.pull.assert_called_with(
'alpine', platform=None, tag=None, stream=True
'alpine', platform=None, tag="latest", stream=True
)

def test_run_pull_tag(self):
client = make_fake_client()

# raise exception on first call, then return normal value
client.api.create_container.side_effect = [
docker.errors.ImageNotFound(""),
client.api.create_container.return_value
]

container = client.containers.run(
'alpine:1.0',
'sleep 300',
detach=True
)

assert container.id == FAKE_CONTAINER_ID
client.api.pull.assert_called_with(
'alpine', platform=None, tag="1.0", stream=True
)

def test_run_with_error(self):
Expand Down Expand Up @@ -296,7 +316,7 @@ def test_run_remove(self):
client.api.remove_container.assert_not_called()
client.api.create_container.assert_called_with(
command=None,
image='alpine',
image='alpine:latest',
detach=True,
host_config={'AutoRemove': True,
'NetworkMode': 'default'}
Expand All @@ -308,7 +328,7 @@ def test_run_remove(self):
client.api.remove_container.assert_not_called()
client.api.create_container.assert_called_with(
command=None,
image='alpine',
image='alpine:latest',
detach=True,
host_config={'AutoRemove': True,
'NetworkMode': 'default'}
Expand Down