4
4
and hardware constraints.
5
5
"""
6
6
from abc import ABC , abstractmethod
7
- from typing import List , Dict
7
+ from typing import List , Dict , cast
8
8
from ja .common .message .base import Serializable
9
9
10
10
11
- class MountPoint :
11
+ class MountPoint ( Serializable ) :
12
12
"""!
13
13
A mount point consists of:
14
14
1. A directory to be mounted(@source_path).
@@ -21,18 +21,38 @@ def __init__(self, source_path: str, mount_path: str):
21
21
@param source_path The host directory to be mounted.
22
22
@param mount_path The target path in the container to mount at.
23
23
"""
24
+ self ._source_path = source_path
25
+ self ._mount_path = mount_path
26
+
27
+ def __eq__ (self , other : object ) -> bool :
28
+ if isinstance (other , MountPoint ):
29
+ return self .source_path == other .source_path and self .mount_path == other .mount_path
30
+ else :
31
+ return False
24
32
25
33
@property
26
34
def source_path (self ) -> str :
27
35
"""!
28
36
@return The directory to be mounted.
29
37
"""
38
+ return self ._source_path
30
39
31
40
@property
32
41
def mount_path (self ) -> str :
33
42
"""!
34
43
@return The path where the directory should be mounted.
35
44
"""
45
+ return self ._mount_path
46
+
47
+ def to_dict (self ) -> Dict [str , object ]:
48
+ return {"source_path" : self .source_path , "mount_path" : self .mount_path }
49
+
50
+ @classmethod
51
+ def from_dict (cls , property_dict : Dict [str , object ]) -> "MountPoint" :
52
+ source_path = cls ._get_str_from_dict (property_dict = property_dict , key = "source_path" )
53
+ mount_path = cls ._get_str_from_dict (property_dict = property_dict , key = "mount_path" )
54
+ cls ._assert_all_properties_used (property_dict )
55
+ return MountPoint (source_path = source_path , mount_path = mount_path )
36
56
37
57
38
58
class IDockerContext (Serializable , ABC ):
@@ -41,19 +61,83 @@ class IDockerContext(Serializable, ABC):
41
61
run a job in.
42
62
"""
43
63
64
+ def __eq__ (self , other : object ) -> bool :
65
+ if isinstance (other , IDockerContext ):
66
+ return self .dockerfile_source == other .dockerfile_source and self .mount_points == other .mount_points
67
+ else :
68
+ return False
69
+
70
+ @property
44
71
@abstractmethod
45
- def get_dockerfile_source (self ) -> str :
72
+ def dockerfile_source (self ) -> str :
46
73
"""!
47
74
@return The string contents of a Dockerfile which can be used to build
48
75
the docker image.
49
76
"""
50
77
78
+ @property
51
79
@abstractmethod
52
- def get_mount_points (self ) -> List [MountPoint ]:
80
+ def mount_points (self ) -> List [MountPoint ]:
53
81
"""!
54
82
@return A list of all mount points for the job.
55
83
"""
56
84
85
+ @classmethod
86
+ @abstractmethod
87
+ def from_dict (cls , property_dict : Dict [str , object ]) -> "IDockerContext" :
88
+ pass
89
+
90
+
91
+ class DockerContext (IDockerContext ):
92
+ """
93
+ An implementation of the IDockerContext interface
94
+ """
95
+ def __init__ (self , dockerfile_source : str , mount_points : List [MountPoint ]):
96
+ """
97
+ @param dockerfile_source: The string contents of a Dockerfile which can be used to build the docker image.
98
+ @param mount_points: A list of all mount points for the job.
99
+ """
100
+ self ._dockerfile_source = dockerfile_source
101
+ self ._mount_points = mount_points
102
+
103
+ @property
104
+ def dockerfile_source (self ) -> str :
105
+ return self ._dockerfile_source
106
+
107
+ @property
108
+ def mount_points (self ) -> List [MountPoint ]:
109
+ return self ._mount_points
110
+
111
+ def to_dict (self ) -> Dict [str , object ]:
112
+ return_dict : Dict [str , object ] = dict ()
113
+ return_dict ["dockerfile_source" ] = self .dockerfile_source
114
+ return_dict ["mount_points" ] = [_mount_point .to_dict () for _mount_point in self .mount_points ]
115
+ return return_dict
116
+
117
+ @classmethod
118
+ def from_dict (cls , property_dict : Dict [str , object ]) -> IDockerContext :
119
+ dockerfile_source = cls ._get_str_from_dict (property_dict = property_dict , key = "dockerfile_source" )
120
+
121
+ prop : object = cls ._get_from_dict (property_dict = property_dict , key = "mount_points" )
122
+ if not isinstance (prop , list ):
123
+ cls ._raise_error_wrong_type (
124
+ key = "mount_points" , expected_type = "List[MountPoint]" ,
125
+ actual_type = prop .__class__ .__name__
126
+ )
127
+ object_list = cast (List [object ], prop )
128
+ mount_point_list : List [MountPoint ] = []
129
+ for _object in object_list :
130
+ if not isinstance (_object , dict ):
131
+ cls ._raise_error_wrong_type (
132
+ key = "mount_points" , expected_type = "List[MountPoint]" ,
133
+ actual_type = "List[object]"
134
+ )
135
+ mount_point_list .append (MountPoint .from_dict (
136
+ cast (Dict [str , object ], _object )
137
+ ))
138
+ cls ._assert_all_properties_used (property_dict )
139
+ return DockerContext (dockerfile_source = dockerfile_source , mount_points = mount_point_list )
140
+
57
141
58
142
class DockerConstraints (Serializable ):
59
143
"""
@@ -62,9 +146,21 @@ class DockerConstraints(Serializable):
62
146
def __init__ (self , cpu_threads : int = - 1 , memory : int = 1 ):
63
147
"""!
64
148
Create a new set of Docker constraints.
65
- @param cpu_threads Initial value of @cpu_threads.
66
- @param memory The value of @memory.
149
+ @param cpu_threads Initial value of @cpu_threads. -1 if unknown. Must be > 0 if set to exact number.
150
+ @param memory The value of @memory, must be > 0 .
67
151
"""
152
+ self ._cpu_threads = - 1
153
+ if cpu_threads != - 1 :
154
+ self .cpu_threads = cpu_threads
155
+ if memory < 1 :
156
+ raise ValueError ("Cannot set memory to %s because this value is < 1." % memory )
157
+ self ._memory = memory
158
+
159
+ def __eq__ (self , other : object ) -> bool :
160
+ if isinstance (other , DockerConstraints ):
161
+ return self .cpu_threads == other .cpu_threads and self .memory == other .memory
162
+ else :
163
+ return False
68
164
69
165
@property
70
166
def cpu_threads (self ) -> int :
@@ -73,6 +169,7 @@ def cpu_threads(self) -> int:
73
169
-1 means that the amount of threads is not set, in which case the
74
170
number of threads will be determined when scheduling the job.
75
171
"""
172
+ return self ._cpu_threads
76
173
77
174
@cpu_threads .setter
78
175
def cpu_threads (self , count_threads : int ) -> None :
@@ -81,16 +178,29 @@ def cpu_threads(self, count_threads: int) -> None:
81
178
If the number of cpu threads is already set(i.e it is not equal to -1),
82
179
this will raise a RuntimeError.
83
180
"""
181
+ if self ._cpu_threads != - 1 :
182
+ raise RuntimeError ("cpu_threads can only be set once." )
183
+ elif count_threads < 1 :
184
+ raise ValueError ("Cannot set cpu_threads to %s because this value is < 1." % count_threads )
185
+ else :
186
+ self ._cpu_threads = count_threads
84
187
85
188
@property
86
189
def memory (self ) -> int :
87
190
"""!
88
191
@return The maximum amount of RAM in MB to allocate for this container.
89
192
"""
193
+ return self ._memory
90
194
91
195
def to_dict (self ) -> Dict [str , object ]:
92
- pass
196
+ return_dict : Dict [str , object ] = dict ()
197
+ return_dict ["cpu_threads" ] = self .cpu_threads
198
+ return_dict ["memory" ] = self .memory
199
+ return return_dict
93
200
94
201
@classmethod
95
202
def from_dict (cls , property_dict : Dict [str , object ]) -> "DockerConstraints" :
96
- pass
203
+ cpu_threads = cls ._get_int_from_dict (property_dict = property_dict , key = "cpu_threads" )
204
+ memory = cls ._get_int_from_dict (property_dict = property_dict , key = "memory" )
205
+ cls ._assert_all_properties_used (property_dict )
206
+ return DockerConstraints (cpu_threads = cpu_threads , memory = memory )
0 commit comments