-
Notifications
You must be signed in to change notification settings - Fork 193
/
container.py
133 lines (102 loc) · 4.62 KB
/
container.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
from ..exceptions import InvalidChoiceError
from .base import MarathonObject
class MarathonContainer(MarathonObject):
"""Marathon health check.
See https://mesosphere.github.io/marathon/docs/native-docker.html
:param docker: docker field (e.g., {"image": "mygroup/myimage"})'
:type docker: :class:`marathon.models.container.MarathonDockerContainer` or dict
:param str type:
:param port_mappings: New in Marathon v1.5. container.docker.port_mappings moved here.
:type port_mappings: list[:class:`marathon.models.container.MarathonContainerPortMapping`] or list[dict]
:param volumes:
:type volumes: list[:class:`marathon.models.container.MarathonContainerVolume`] or list[dict]
"""
TYPES = ['DOCKER', 'MESOS']
"""Valid container types"""
def __init__(self, docker=None, type='DOCKER', port_mappings=None, volumes=None):
if type not in self.TYPES:
raise InvalidChoiceError('type', type, self.TYPES)
self.type = type
# Marathon v1.5 moved portMappings from within container.docker object directly
# under the container object
if port_mappings:
self.port_mappings = [
pm if isinstance(
pm, MarathonContainerPortMapping) else MarathonContainerPortMapping().from_json(pm)
for pm in (port_mappings or [])
]
if docker:
self.docker = docker if isinstance(docker, MarathonDockerContainer) \
else MarathonDockerContainer().from_json(docker)
self.volumes = [
v if isinstance(
v, MarathonContainerVolume) else MarathonContainerVolume().from_json(v)
for v in (volumes or [])
]
class MarathonDockerContainer(MarathonObject):
"""Docker options.
See https://mesosphere.github.io/marathon/docs/native-docker.html
:param str image: docker image
:param str network:
:param port_mappings:
:type port_mappings: list[:class:`marathon.models.container.MarathonContainerPortMapping`] or list[dict]
:param list[dict] parameters:
:param bool privileged: run container in privileged mode
:param bool force_pull_image: Force a docker pull before launching
"""
NETWORK_MODES = ['BRIDGE', 'HOST', 'USER', 'NONE']
"""Valid network modes"""
def __init__(self, image=None, network=None, port_mappings=None, parameters=None, privileged=None,
force_pull_image=None, **kwargs):
self.image = image
if network:
if network not in self.NETWORK_MODES:
raise InvalidChoiceError(
'network', network, self.NETWORK_MODES)
self.network = network
self.port_mappings = [
pm if isinstance(
pm, MarathonContainerPortMapping) else MarathonContainerPortMapping().from_json(pm)
for pm in (port_mappings or [])
]
self.parameters = parameters or []
self.privileged = privileged or False
self.force_pull_image = force_pull_image or False
class MarathonContainerPortMapping(MarathonObject):
"""Container port mapping.
See https://mesosphere.github.io/marathon/docs/native-docker.html
:param str name:
:param int container_port:
:param int host_port:
:param str protocol:
:param object labels:
"""
PROTOCOLS = ['tcp', 'udp', 'udp,tcp']
"""Valid protocols"""
def __init__(self, name=None, container_port=None, host_port=None, service_port=None, protocol='tcp', labels=None):
self.name = name
self.container_port = container_port
self.host_port = host_port
self.service_port = service_port
if protocol not in self.PROTOCOLS:
raise InvalidChoiceError('protocol', protocol, self.PROTOCOLS)
self.protocol = protocol
self.labels = labels
class MarathonContainerVolume(MarathonObject):
"""Volume options.
See https://mesosphere.github.io/marathon/docs/native-docker.html
:param str container_path: container path
:param str host_path: host path
:param str mode: one of ['RO', 'RW']
:param object persistent: persistent volume options, should be of the form {'size': 1000}
:param object external: external volume options
"""
MODES = ['RO', 'RW']
def __init__(self, container_path=None, host_path=None, mode='RW', persistent=None, external=None):
self.container_path = container_path
self.host_path = host_path
if mode not in self.MODES:
raise InvalidChoiceError('mode', mode, self.MODES)
self.mode = mode
self.persistent = persistent
self.external = external