44and hardware constraints.
55"""
66from abc import ABC , abstractmethod
7- from typing import List , Dict
7+ from typing import List , Dict , cast
88from ja .common .message .base import Serializable
99
1010
11- class MountPoint :
11+ class MountPoint ( Serializable ) :
1212 """!
1313 A mount point consists of:
1414 1. A directory to be mounted(@source_path).
@@ -21,18 +21,38 @@ def __init__(self, source_path: str, mount_path: str):
2121 @param source_path The host directory to be mounted.
2222 @param mount_path The target path in the container to mount at.
2323 """
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
2432
2533 @property
2634 def source_path (self ) -> str :
2735 """!
2836 @return The directory to be mounted.
2937 """
38+ return self ._source_path
3039
3140 @property
3241 def mount_path (self ) -> str :
3342 """!
3443 @return The path where the directory should be mounted.
3544 """
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 )
3656
3757
3858class IDockerContext (Serializable , ABC ):
@@ -41,19 +61,83 @@ class IDockerContext(Serializable, ABC):
4161 run a job in.
4262 """
4363
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
4471 @abstractmethod
45- def get_dockerfile_source (self ) -> str :
72+ def dockerfile_source (self ) -> str :
4673 """!
4774 @return The string contents of a Dockerfile which can be used to build
4875 the docker image.
4976 """
5077
78+ @property
5179 @abstractmethod
52- def get_mount_points (self ) -> List [MountPoint ]:
80+ def mount_points (self ) -> List [MountPoint ]:
5381 """!
5482 @return A list of all mount points for the job.
5583 """
5684
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+
57141
58142class DockerConstraints (Serializable ):
59143 """
@@ -62,9 +146,21 @@ class DockerConstraints(Serializable):
62146 def __init__ (self , cpu_threads : int = - 1 , memory : int = 1 ):
63147 """!
64148 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 .
67151 """
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
68164
69165 @property
70166 def cpu_threads (self ) -> int :
@@ -73,6 +169,7 @@ def cpu_threads(self) -> int:
73169 -1 means that the amount of threads is not set, in which case the
74170 number of threads will be determined when scheduling the job.
75171 """
172+ return self ._cpu_threads
76173
77174 @cpu_threads .setter
78175 def cpu_threads (self , count_threads : int ) -> None :
@@ -81,16 +178,29 @@ def cpu_threads(self, count_threads: int) -> None:
81178 If the number of cpu threads is already set(i.e it is not equal to -1),
82179 this will raise a RuntimeError.
83180 """
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
84187
85188 @property
86189 def memory (self ) -> int :
87190 """!
88191 @return The maximum amount of RAM in MB to allocate for this container.
89192 """
193+ return self ._memory
90194
91195 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
93200
94201 @classmethod
95202 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