Change in vdsm[master]: docker integration: basic exposure of REST/CLI api
mpolednik at redhat.com
mpolednik at redhat.com
Fri Sep 26 11:14:55 UTC 2014
Martin Polednik has uploaded a new change for review.
Change subject: docker integration: basic exposure of REST/CLI api
......................................................................
docker integration: basic exposure of REST/CLI api
This patch, meant as 0th iteration of docker integration,
introduces two new VDSM verbs: dockerCli and dockerRest.
dockerCli is gateway to docker's command line interface, allowing
engine to run arbitrary docker commands.
dockerCli <command>
dockerRest is gateway to docker's REST api (or remote API) via
UNIX socket, allowing engine to run commands from standard docker
remote API (https://docs.docker.com/reference/api/docker_remote_api/)
dockerRest <method> <url>
Change-Id: I6d958be3b56e20df670896b12b1d6302ed59c491
Signed-off-by: Martin Polednik <mpolednik at redhat.com>
---
M client/vdsClient.py
M lib/vdsm/Makefile.am
A lib/vdsm/docker.py
M vdsm.spec.in
M vdsm/API.py
M vdsm/rpc/BindingXMLRPC.py
6 files changed, 99 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/01/33401/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index dafca9e..e3e940d 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -129,6 +129,11 @@
print "\t%s = %s" % (element, representation)
+def printResponse(input_list, pretty=True):
+ for item in input_list:
+ print "\t%s" % (item)
+
+
def printStats(list):
for conf in list:
printConf(conf)
@@ -199,6 +204,8 @@
printStats(response['statsList'])
elif 'info' in response:
printDict(response['info'], self.pretty)
+ elif 'dockerResponse' in response:
+ print response['dockerResponse']
else:
printDict(response['status'], self.pretty)
sys.exit(response['status']['code'])
@@ -524,6 +531,14 @@
def do_getAllVmStats(self, args):
return self.ExecAndExit(self.s.getAllVmStats())
+
+ def do_dockerRest(self, args):
+ method, url = tuple(args[:2])
+ return self.ExecAndExit(self.s.dockerRest(method, url))
+
+ def do_dockerCli(self, args):
+ command = tuple(args)
+ return self.ExecAndExit(self.s.dockerCli(command))
def desktopLogin(self, args):
vmId, domain, user, password = tuple(args[:4])
@@ -2157,6 +2172,14 @@
('',
'Get Statistics info for all existing VMs'
)),
+ 'dockerRest': (serv.do_dockerRest,
+ ('<command> <url>',
+ 'Send request to docker remote API'
+ )),
+ 'dockerCli': (serv.do_dockerCli,
+ ('<command>',
+ 'Send request to docker CLI'
+ )),
'getVGList': (serv.getVGList,
('storageType',
'List of all VGs.'
diff --git a/lib/vdsm/Makefile.am b/lib/vdsm/Makefile.am
index 4bebf28..1585711 100644
--- a/lib/vdsm/Makefile.am
+++ b/lib/vdsm/Makefile.am
@@ -25,6 +25,7 @@
__init__.py \
compat.py \
define.py \
+ docker.py \
exception.py \
ipwrapper.py \
libvirtconnection.py \
diff --git a/lib/vdsm/docker.py b/lib/vdsm/docker.py
new file mode 100644
index 0000000..1038c9d
--- /dev/null
+++ b/lib/vdsm/docker.py
@@ -0,0 +1,55 @@
+import httplib
+import socket
+import threading
+
+from . import utils
+
+_DOCKER_SOCKET = '/var/run/docker.sock'
+_DOCKER_BIN = utils.CommandPath('docker', '/usr/bin/docker',)
+
+
+class UHTTPConnection(httplib.HTTPConnection):
+
+ def __init__(self, path):
+ httplib.HTTPConnection.__init__(self, 'localhost')
+ self.path = path
+
+ def connect(self):
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ sock.connect(self.path)
+ self.sock = sock
+
+
+class Docker(object):
+ _connection = None
+ _docker = None
+ _connection_lock = threading.Lock()
+ _docker_lock = threading.Lock()
+
+ def __call__(self, command, url=None):
+ if url:
+ self._get().request(command, url)
+ return self._get().getresponse().read()
+ else:
+ cmd = [_DOCKER_BIN.cmd]
+ cmd.extend(command)
+ rc, out, err = utils.execCmd(cmd)
+ return out
+
+ def _get(self):
+ with self._connection_lock:
+ if not self._connection:
+ self._connection = UHTTPConnection(_DOCKER_SOCKET)
+
+ return self._connection
+
+ @classmethod
+ def __enter__(cls):
+ with cls._docker_lock:
+ if not cls._docker:
+ cls._docker = Docker()
+
+ return cls._docker
+
+ def __exit__(self, type, value, traceback):
+ pass
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 56d2579..f3300fe 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1202,6 +1202,7 @@
%{python_sitearch}/%{vdsm_name}/config.py*
%{python_sitearch}/%{vdsm_name}/constants.py*
%{python_sitearch}/%{vdsm_name}/define.py*
+%{python_sitearch}/%{vdsm_name}/docker.py*
%{python_sitearch}/%{vdsm_name}/exception.py*
%{python_sitearch}/%{vdsm_name}/ipwrapper.py*
%{python_sitearch}/%{vdsm_name}/libvirtconnection.py*
diff --git a/vdsm/API.py b/vdsm/API.py
index 9c47b5f..bd7b537 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -47,6 +47,7 @@
from virt import vm
from virt import vmstatus
from vdsm.compat import pickle
+from vdsm.docker import Docker
from vdsm.define import doneCode, errCode, Kbytes, Mbytes
import caps
from vdsm.config import config
@@ -1253,6 +1254,14 @@
updateTimestamp()
return {'status': doneCode}
+ def dockerRest(self, command, url):
+ with Docker() as docker:
+ return {'status': doneCode, 'dockerResponse': docker(command, url)}
+
+ def dockerCli(self, command):
+ with Docker() as docker:
+ return {'status': doneCode, 'dockerResponse': docker(command)}
+
def getRoute(self, ip):
"""
Return the name of the device leading to destination IP or the empty
diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index f2dcbdf..a622816 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -571,6 +571,14 @@
api = API.Global()
return api.ping()
+ def dockerRest(self, command, url):
+ api = API.Global()
+ return api.dockerRest(command, url)
+
+ def dockerCli(self, command):
+ api = API.Global()
+ return api.dockerCli(command)
+
def setSafeNetworkConfig(self):
api = API.Global()
return api.setSafeNetworkConfig()
@@ -1019,6 +1027,8 @@
(self.editNetwork, 'editNetwork'),
(self.setupNetworks, 'setupNetworks'),
(self.ping, 'ping'),
+ (self.dockerRest, 'dockerRest'),
+ (self.dockerCli, 'dockerCli'),
(self.setSafeNetworkConfig, 'setSafeNetworkConfig'),
(self.fenceNode, 'fenceNode'),
(self.stop, 'prepareForShutdown'),
--
To view, visit http://gerrit.ovirt.org/33401
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6d958be3b56e20df670896b12b1d6302ed59c491
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpolednik at redhat.com>
More information about the vdsm-patches
mailing list