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 <[email protected]> --- 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 <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
