Skip to content

Commit

Permalink
Merge pull request #2809 from feliperuhland/add-service-capability
Browse files Browse the repository at this point in the history
Add service capability
  • Loading branch information
aiordache authored Oct 7, 2021
2 parents df59f53 + 7ac8b56 commit 7779b84
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
TEST_API_VERSION ?= 1.39
TEST_ENGINE_VERSION ?= 19.03.13
TEST_API_VERSION ?= 1.41
TEST_ENGINE_VERSION ?= 20.10.05

.PHONY: all
all: test
Expand Down
2 changes: 1 addition & 1 deletion docker/constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys
from .version import version

DEFAULT_DOCKER_API_VERSION = '1.39'
DEFAULT_DOCKER_API_VERSION = '1.41'
MINIMUM_DOCKER_API_VERSION = '1.21'
DEFAULT_TIMEOUT_SECONDS = 60
STREAM_HEADER_SIZE_BYTES = 8
Expand Down
6 changes: 6 additions & 0 deletions docker/models/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ def create(self, image, command=None, **kwargs):
to the service.
privileges (Privileges): Security options for the service's
containers.
cap_add (:py:class:`list`): A list of kernel capabilities to add to
the default set for the container.
cap_drop (:py:class:`list`): A list of kernel capabilities to drop
from the default set for the container.
Returns:
:py:class:`Service`: The created service.
Expand Down Expand Up @@ -277,6 +281,8 @@ def list(self, **kwargs):
# kwargs to copy straight over to ContainerSpec
CONTAINER_SPEC_KWARGS = [
'args',
'cap_add',
'cap_drop',
'command',
'configs',
'dns_config',
Expand Down
19 changes: 18 additions & 1 deletion docker/types/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,18 @@ class ContainerSpec(dict):
containers. Only used for Windows containers.
init (boolean): Run an init inside the container that forwards signals
and reaps processes.
cap_add (:py:class:`list`): A list of kernel capabilities to add to the
default set for the container.
cap_drop (:py:class:`list`): A list of kernel capabilities to drop from
the default set for the container.
"""
def __init__(self, image, command=None, args=None, hostname=None, env=None,
workdir=None, user=None, labels=None, mounts=None,
stop_grace_period=None, secrets=None, tty=None, groups=None,
open_stdin=None, read_only=None, stop_signal=None,
healthcheck=None, hosts=None, dns_config=None, configs=None,
privileges=None, isolation=None, init=None):
privileges=None, isolation=None, init=None, cap_add=None,
cap_drop=None):
self['Image'] = image

if isinstance(command, str):
Expand Down Expand Up @@ -186,6 +191,18 @@ def __init__(self, image, command=None, args=None, hostname=None, env=None,
if init is not None:
self['Init'] = init

if cap_add is not None:
if not isinstance(cap_add, list):
raise TypeError('cap_add must be a list')

self['CapabilityAdd'] = cap_add

if cap_drop is not None:
if not isinstance(cap_drop, list):
raise TypeError('cap_drop must be a list')

self['CapabilityDrop'] = cap_drop


class Mount(dict):
"""
Expand Down
30 changes: 30 additions & 0 deletions tests/integration/api_service_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1356,3 +1356,33 @@ def _update_service(self, svc_id, *args, **kwargs):
self.client.update_service(*args, **kwargs)
else:
raise

@requires_api_version('1.41')
def test_create_service_cap_add(self):
name = self.get_service_name()
container_spec = docker.types.ContainerSpec(
TEST_IMG, ['echo', 'hello'], cap_add=['CAP_SYSLOG']
)
task_tmpl = docker.types.TaskTemplate(container_spec)
svc_id = self.client.create_service(task_tmpl, name=name)
assert self.client.inspect_service(svc_id)
services = self.client.services(filters={'name': name})
assert len(services) == 1
assert services[0]['ID'] == svc_id['ID']
spec = services[0]['Spec']['TaskTemplate']['ContainerSpec']
assert 'CAP_SYSLOG' in spec['CapabilityAdd']

@requires_api_version('1.41')
def test_create_service_cap_drop(self):
name = self.get_service_name()
container_spec = docker.types.ContainerSpec(
TEST_IMG, ['echo', 'hello'], cap_drop=['CAP_SYSLOG']
)
task_tmpl = docker.types.TaskTemplate(container_spec)
svc_id = self.client.create_service(task_tmpl, name=name)
assert self.client.inspect_service(svc_id)
services = self.client.services(filters={'name': name})
assert len(services) == 1
assert services[0]['ID'] == svc_id['ID']
spec = services[0]['Spec']['TaskTemplate']['ContainerSpec']
assert 'CAP_SYSLOG' in spec['CapabilityDrop']
38 changes: 38 additions & 0 deletions tests/integration/models_services_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,41 @@ def test_force_update_service_using_shorthand_method(self):
assert service.force_update()
service.reload()
assert service.version > initial_version

@helpers.requires_api_version('1.41')
def test_create_cap_add(self):
client = docker.from_env(version=TEST_API_VERSION)
name = helpers.random_name()
service = client.services.create(
name=name,
labels={'foo': 'bar'},
image="alpine",
command="sleep 300",
container_labels={'container': 'label'},
cap_add=["CAP_SYSLOG"]
)
assert service.name == name
assert service.attrs['Spec']['Labels']['foo'] == 'bar'
container_spec = service.attrs['Spec']['TaskTemplate']['ContainerSpec']
assert "alpine" in container_spec['Image']
assert container_spec['Labels'] == {'container': 'label'}
assert "CAP_SYSLOG" in container_spec["CapabilityAdd"]

@helpers.requires_api_version('1.41')
def test_create_cap_drop(self):
client = docker.from_env(version=TEST_API_VERSION)
name = helpers.random_name()
service = client.services.create(
name=name,
labels={'foo': 'bar'},
image="alpine",
command="sleep 300",
container_labels={'container': 'label'},
cap_drop=["CAP_SYSLOG"]
)
assert service.name == name
assert service.attrs['Spec']['Labels']['foo'] == 'bar'
container_spec = service.attrs['Spec']['TaskTemplate']['ContainerSpec']
assert "alpine" in container_spec['Image']
assert container_spec['Labels'] == {'container': 'label'}
assert "CAP_SYSLOG" in container_spec["CapabilityDrop"]

0 comments on commit 7779b84

Please sign in to comment.