Skip to content

Commit 4590e2a

Browse files
authored
Merge pull request #1846 from feliperuhland/issue-1734-scale-method
Added scale method to the Service model.
2 parents 766d890 + 663c608 commit 4590e2a

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

docker/models/services.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import copy
2-
from docker.errors import create_unexpected_kwargs_error
3-
from docker.types import TaskTemplate, ContainerSpec
2+
from docker.errors import create_unexpected_kwargs_error, InvalidArgument
3+
from docker.types import TaskTemplate, ContainerSpec, ServiceMode
44
from .resource import Model, Collection
55

66

@@ -105,6 +105,25 @@ def logs(self, **kwargs):
105105
)
106106
return self.client.api.service_logs(self.id, is_tty=is_tty, **kwargs)
107107

108+
def scale(self, replicas):
109+
"""
110+
Scale service container.
111+
112+
Args:
113+
replicas (int): The number of containers that should be running.
114+
115+
Returns:
116+
``True``if successful.
117+
"""
118+
119+
if 'Global' in self.attrs['Spec']['Mode'].keys():
120+
raise InvalidArgument('Cannot scale a global container')
121+
122+
service_mode = ServiceMode('replicated', replicas)
123+
return self.client.api.update_service(self.id, self.version,
124+
service_mode,
125+
fetch_current_spec=True)
126+
108127

109128
class ServiceCollection(Collection):
110129
"""Services on the Docker server."""

tests/integration/models_services_test.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
from .. import helpers
66
from .base import TEST_API_VERSION
7+
from docker.errors import InvalidArgument
8+
from docker.types.services import ServiceMode
79

810

911
class ServiceTest(unittest.TestCase):
@@ -227,6 +229,50 @@ def test_scale_service(self):
227229
spec = service.attrs['Spec']['TaskTemplate']['ContainerSpec']
228230
assert spec.get('Command') == ['sleep', '300']
229231

232+
def test_scale_method_service(self):
233+
client = docker.from_env(version=TEST_API_VERSION)
234+
service = client.services.create(
235+
# create arguments
236+
name=helpers.random_name(),
237+
# ContainerSpec arguments
238+
image="alpine",
239+
command="sleep 300",
240+
)
241+
tasks = []
242+
while len(tasks) == 0:
243+
tasks = service.tasks()
244+
assert len(tasks) == 1
245+
service.scale(2)
246+
while len(tasks) == 1:
247+
tasks = service.tasks()
248+
assert len(tasks) >= 2
249+
# check that the container spec is not overridden with None
250+
service.reload()
251+
spec = service.attrs['Spec']['TaskTemplate']['ContainerSpec']
252+
assert spec.get('Command') == ['sleep', '300']
253+
254+
def test_scale_method_global_service(self):
255+
client = docker.from_env(version=TEST_API_VERSION)
256+
mode = ServiceMode('global')
257+
service = client.services.create(
258+
name=helpers.random_name(),
259+
image="alpine",
260+
command="sleep 300",
261+
mode=mode
262+
)
263+
tasks = []
264+
while len(tasks) == 0:
265+
tasks = service.tasks()
266+
assert len(tasks) == 1
267+
with self.assertRaises(InvalidArgument,
268+
msg='Cannot scale a global container'):
269+
service.scale(2)
270+
271+
assert len(tasks) == 1
272+
service.reload()
273+
spec = service.attrs['Spec']['TaskTemplate']['ContainerSpec']
274+
assert spec.get('Command') == ['sleep', '300']
275+
230276
@helpers.requires_api_version('1.25')
231277
def test_restart_service(self):
232278
client = docker.from_env(version=TEST_API_VERSION)

0 commit comments

Comments
 (0)