@@ -154,6 +154,104 @@ def hard(self, value):
154154 self ['Hard' ] = value
155155
156156
157+ class DeviceRequest (DictType ):
158+ """
159+ Create a device request to be used with
160+ :py:meth:`~docker.api.container.ContainerApiMixin.create_host_config`.
161+
162+ Args:
163+
164+ driver (str): Which driver to use for this device. Optional.
165+ count (int): Number or devices to request. Optional.
166+ Set to -1 to request all available devices.
167+ device_ids (list): List of strings for device IDs. Optional.
168+ Set either ``count`` or ``device_ids``.
169+ capabilities (list): List of lists of strings to request
170+ capabilities. Optional. The global list acts like an OR,
171+ and the sub-lists are AND. The driver will try to satisfy
172+ one of the sub-lists.
173+ Available capabilities for the ``nvidia`` driver can be found
174+ `here <https://github.com/NVIDIA/nvidia-container-runtime>`_.
175+ options (dict): Driver-specific options. Optional.
176+ """
177+
178+ def __init__ (self , ** kwargs ):
179+ driver = kwargs .get ('driver' , kwargs .get ('Driver' ))
180+ count = kwargs .get ('count' , kwargs .get ('Count' ))
181+ device_ids = kwargs .get ('device_ids' , kwargs .get ('DeviceIDs' ))
182+ capabilities = kwargs .get ('capabilities' , kwargs .get ('Capabilities' ))
183+ options = kwargs .get ('options' , kwargs .get ('Options' ))
184+
185+ if driver is None :
186+ driver = ''
187+ elif not isinstance (driver , six .string_types ):
188+ raise ValueError ('DeviceRequest.driver must be a string' )
189+ if count is None :
190+ count = 0
191+ elif not isinstance (count , int ):
192+ raise ValueError ('DeviceRequest.count must be an integer' )
193+ if device_ids is None :
194+ device_ids = []
195+ elif not isinstance (device_ids , list ):
196+ raise ValueError ('DeviceRequest.device_ids must be a list' )
197+ if capabilities is None :
198+ capabilities = []
199+ elif not isinstance (capabilities , list ):
200+ raise ValueError ('DeviceRequest.capabilities must be a list' )
201+ if options is None :
202+ options = {}
203+ elif not isinstance (options , dict ):
204+ raise ValueError ('DeviceRequest.options must be a dict' )
205+
206+ super (DeviceRequest , self ).__init__ ({
207+ 'Driver' : driver ,
208+ 'Count' : count ,
209+ 'DeviceIDs' : device_ids ,
210+ 'Capabilities' : capabilities ,
211+ 'Options' : options
212+ })
213+
214+ @property
215+ def driver (self ):
216+ return self ['Driver' ]
217+
218+ @driver .setter
219+ def driver (self , value ):
220+ self ['Driver' ] = value
221+
222+ @property
223+ def count (self ):
224+ return self ['Count' ]
225+
226+ @count .setter
227+ def count (self , value ):
228+ self ['Count' ] = value
229+
230+ @property
231+ def device_ids (self ):
232+ return self ['DeviceIDs' ]
233+
234+ @device_ids .setter
235+ def device_ids (self , value ):
236+ self ['DeviceIDs' ] = value
237+
238+ @property
239+ def capabilities (self ):
240+ return self ['Capabilities' ]
241+
242+ @capabilities .setter
243+ def capabilities (self , value ):
244+ self ['Capabilities' ] = value
245+
246+ @property
247+ def options (self ):
248+ return self ['Options' ]
249+
250+ @options .setter
251+ def options (self , value ):
252+ self ['Options' ] = value
253+
254+
157255class HostConfig (dict ):
158256 def __init__ (self , version , binds = None , port_bindings = None ,
159257 lxc_conf = None , publish_all_ports = False , links = None ,
@@ -176,7 +274,7 @@ def __init__(self, version, binds=None, port_bindings=None,
176274 volume_driver = None , cpu_count = None , cpu_percent = None ,
177275 nano_cpus = None , cpuset_mems = None , runtime = None , mounts = None ,
178276 cpu_rt_period = None , cpu_rt_runtime = None ,
179- device_cgroup_rules = None ):
277+ device_cgroup_rules = None , device_requests = None ):
180278
181279 if mem_limit is not None :
182280 self ['Memory' ] = parse_bytes (mem_limit )
@@ -536,6 +634,19 @@ def __init__(self, version, binds=None, port_bindings=None,
536634 )
537635 self ['DeviceCgroupRules' ] = device_cgroup_rules
538636
637+ if device_requests is not None :
638+ if version_lt (version , '1.40' ):
639+ raise host_config_version_error ('device_requests' , '1.40' )
640+ if not isinstance (device_requests , list ):
641+ raise host_config_type_error (
642+ 'device_requests' , device_requests , 'list'
643+ )
644+ self ['DeviceRequests' ] = []
645+ for req in device_requests :
646+ if not isinstance (req , DeviceRequest ):
647+ req = DeviceRequest (** req )
648+ self ['DeviceRequests' ].append (req )
649+
539650
540651def host_config_type_error (param , param_value , expected ):
541652 error_msg = 'Invalid type for {0} param: expected {1} but found {2}'
0 commit comments