All Classes Functions
docker_driver.py
1 import requests
2 
3 import logging
4 from contextlib import contextmanager
5 
6 import docker
7 
8 from hypervisor_base import HypervisorBase
9 import errors
10 
11 logger = logging.getLogger(__name__)
12 
13 ##
14 #
15 # @class DockerDriver
16 # @brief docker driver for nfio.
17 #
18 # This class provides methods for managing docker containers.
19 #
20 class DockerDriver(HypervisorBase):
21 
22  ##
23  #
24  # @brief Instantiates a DockerDriver object.
25  #
26  # @note This method initializes a set of values for configuring
27  # the docker-py remote API client.
28  #
29  # @property __port is the port number used for remote API invocation.
30  # @property __version is the version number for the report API.
31  # @property __dns_list is the list of DNS server(s) used by each container.
32  #
33  def __init__(self):
34  self.__port = '4444'
35  self.__version = '1.15'
36  self.__dns_list = ['8.8.8.8']
37 
38  @contextmanager
39  ##
40  #
41  # @beief convert docker-py exceptions to nfio exceptions
42  #
43  # This code block is used to catch docker-py docker-py exceptions
44  # (from error.py), log them, and then raise nfio related
45  # exceptions.
46  #
47  # @param nfioError A Exception type from nfio's errors module
48  #
49  def _error_handling(self, nfioError):
50  try:
51  yield
52  except Exception, ex:
53  logger.error(ex.message, exc_info=False)
54  raise nfioError
55 
56  ##
57  #
58  # @brief checks whether a string is empty or None
59  #
60  # @param string input string
61  #
62  # @returns True if string is empty, otherwise False
63  #
64  def _is_empty(self, string):
65  return string is None or string.strip() == ""
66 
67  def _validate_host(self, host):
68  if self._is_empty(host):
70 
71  def _validate_image_name(self, image_name):
72  if self._is_empty(image_name):
74 
75  def _validate_cont_name(self, cont_name):
76  if self._is_empty(cont_name):
78  ## check to see if there is any container with name cont_name
79  #nameExists = False
80  #dcx = self._get_client(host)
81  #containers = dcx.containers()
82  #for container in containers:
83  # for cont_name in container['Names']:
84  # # docker container names includes a leading '/'!
85  # if vnf_fullname == cont_name[1:].encode('ascii'):
86  # nameExists = True
87  #if not nameExist:
88  # raise errors.VNFNotFoundError
89 
90  ##
91  #
92  # Returns a Docker client.
93  #
94  # @param host IP address or hostname of the host (physical/virtual)
95  # where docker containers will be deployed
96  #
97  # @return A docker client object that can be used to communicate
98  # with the docker daemon on the host
99  #
100  def _get_client(self, host):
101  self._validate_host(host)
103  return docker.Client(
104  base_url="http://" +
105  host +
106  ":" +
107  self.__port,
108  version=self.__version)
109 
110  def _lookup_vnf(self, host, user, vnf_name):
111  self._validate_host(host)
112  vnf_fullname = user + '-' + vnf_name
113  self._validate_cont_name(vnf_fullname)
114  dcx = self._get_client(host)
116  inspect_data = dcx.inspect_container(container=vnf_fullname)
117  return dcx, vnf_fullname, inspect_data
118 
119  ##
120  #
121  # Returns a container's ID.
122  #
123  # @param host IP address or hostname of the machine where
124  # the docker container is deployed
125  # @param user name of the user who owns the VNF
126  # @param vnf_name name of the VNF instance whose ID is being queried
127  #
128  # @return docker container ID.
129  #
130  def get_id(self, host, user, vnf_name):
131  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
132  return inspect_data['Id'].encode('ascii')
133 
134  ##
135  #
136  # Returns a container's IP address.
137  #
138  # @param host IP address or hostname of the machine where
139  # the docker container is deployed
140  # @param user name of the user who owns the VNF
141  # @param vnf_name name of the VNF instance whose ID is being queried
142  #
143  # @return docker container's IP.
144  #
145  def get_ip(self, host, user, vnf_name):
146  if self.guest_status(host, user, vnf_name) != 'running':
148  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
149  return inspect_data['NetworkSettings']['IPAddress'].encode('ascii')
150 
151  ##
152  #
153  # Deploys a docker container.
154  #
155  #
156  # @param host IP address or hostname of the machine where
157  # the docker container is to be deployed
158  # @param user name of the user who owns the VNF
159  # @param image_name docker image name for the VNF
160  # @param vnf_name name of the VNF instance
161  # @param is_privileged if True then the container is deployed in
162  # privileged mode
163  #
164  # @returns docker container ID
165  #
166  def deploy(self, host, user, image_name, vnf_name, is_privileged=True):
167  self._validate_host(host)
168  self._validate_image_name(image_name)
169  vnf_fullname = user + '-' + vnf_name
170  self._validate_cont_name(vnf_fullname)
171  dcx = self._get_client(host)
172  host_config = dict()
173  if is_privileged:
174  host_config['Privileged'] = True
176  container = dcx.create_container(
177  image=image_name,
178  hostname=host,
179  name=vnf_fullname,
180  host_config=host_config)
181  return container['Id']
182 
183  ##
184  #
185  # Starts a docker container.
186  #
187  # @param host IP address or hostname of the machine/VM where
188  # the docker container is deployed
189  # @param user name of the user
190  # @param vnf_name name of the VNF
191  # @param is_privileged if True then the container is started in
192  # privileged mode
193  #
194  def start(self, host, user, vnf_name, is_privileged=True):
195  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
197  dcx.start(container=vnf_fullname,
198  dns=self.__dns_list,
199  privileged=is_privileged)
200 
201  ##
202  #
203  # Restarts a docker container.
204  #
205  # @param host IP address or hostname of the machine/VM where
206  # the docker container is deployed
207  # @param user name of the user
208  # @param vnf_name name of the VNF
209  #
210  def restart(self, host, user, vnf_name):
211  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
213  dcx.restart(container=vnf_fullname)
214 
215  ##
216  #
217  # Stops a docker container.
218  #
219  # @param host IP address or hostname of the machine/VM where
220  # the docker container is deployed
221  # @param user name of the user
222  # @param vnf_name name of the VNF
223  #
224  def stop(self, host, user, vnf_name):
225  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
227  dcx.stop(container=vnf_fullname)
228 
229  ##
230  #
231  # Pauses a docker container.
232  #
233  # @param host IP address or hostname of the machine/VM where
234  # the docker container is deployed
235  # @param user name of the user
236  # @param vnf_name name of the VNF
237  #
238  def pause(self, host, user, vnf_name):
239  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
241  dcx.pause(container=vnf_fullname)
242 
243  ##
244  # Unpauses a docker container.
245  #
246  # @param host IP address or hostname of the machine/VM where
247  # the docker container is deployed
248  # @param user name of the user
249  # @param vnf_name name of the VNF
250  #
251  def unpause(self, host, user, vnf_name):
252  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
254  dcx.unpause(container=vnf_fullname)
255 
256  ##
257  #
258  # Destroys a docker container.
259  #
260  # @param host IP address or hostname of the machine/VM where
261  # the docker container is deployed
262  # @param user name of the user
263  # @param vnf_name name of the VNF
264  # @param force if set to False then a running VNF will not
265  # be destroyed. default is True
266  #
267  def destroy(self, host, user, vnf_name, force=True):
268  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
270  dcx.remove_container(container=vnf_fullname, force=force)
271 
272  ##
273  #
274  # Executed commands inside a docker container.
275  #
276  # @param host IP address or hostname of the machine/VM where
277  # the docker container is deployed
278  # @param user name of the user
279  # @param vnf_name name of the VNF
280  # @param cmd the command to execute inside the container
281  #
282  # @returns The output of the command passes as cmd
283  #
284  def execute_in_guest(self, host, user, vnf_name, cmd):
285  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
286  if self.guest_status(host, user, vnf_name) != 'running':
289  response = dcx.execute(vnf_fullname,
290  ["/bin/bash", "-c", cmd], stdout=True, stderr=False)
291  return response
292 
293  ##
294  #
295  # Returns the status of a docker container.
296  #
297  # @param host IP address or hostname of the machine/VM where
298  # the docker container is deployed
299  # @param user name of the user
300  # @param vnf_name name of the VNF
301  #
302  # @returns current state of the docker container
303  #
304  def guest_status(self, host, user, vnf_name):
305  dcx, vnf_fullname, inspect_data = self._lookup_vnf(host, user, vnf_name)
306  return inspect_data['State']['Status'].encode('ascii')
def destroy
Destroys a docker container.
def _error_handling
convert docker-py exceptions to nfio exceptions
def get_ip
Returns a container's IP address.
def stop
Stops a docker container.
def pause
Pauses a docker container.
def restart
Restarts a docker container.
def get_id
Returns a container's ID.
def execute_in_guest
Executed commands inside a docker container.
def start
Starts a docker container.
def _is_empty
checks whether a string is empty or None
def unpause
Unpauses a docker container.
def _get_client
Returns a Docker client.
def guest_status
Returns the status of a docker container.
def deploy
Deploys a docker container.