[PATCH 0/6 V2] Discover Kimchi peers using openSLP

v1 -> V2: - Update docs/API.md - Expose federation on /config/capabilities Aline Manera (6): Update kimchi.config values according to command line input Delete http_port from /config API as it is not in use anymore Add federation option to Kimchi config file Discover Kimchi peers using openSLP Add documentation on how to enable federation on Kimchi Expose federation on /config/capabilities docs/API.md | 11 ++++++++- docs/README-federation.md | 27 +++++++++++++++++++++ src/kimchi.conf.in | 4 +++ src/kimchi/config.py.in | 1 + src/kimchi/control/peers.py | 29 ++++++++++++++++++++++ src/kimchi/mockmodel.py | 14 ++++++++--- src/kimchi/model/config.py | 6 ++--- src/kimchi/model/peers.py | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/kimchi/server.py | 1 - src/kimchid.in | 36 +++++++++++++++++---------- tests/test_rest.py | 19 +++++++++------ 11 files changed, 177 insertions(+), 30 deletions(-) create mode 100644 docs/README-federation.md create mode 100644 src/kimchi/control/peers.py create mode 100644 src/kimchi/model/peers.py -- 1.9.3

Kimchi allows users to change some configuration values by command line. Those values override the kimchi.conf values. That way we need to properly update kimchi.config.config to provide the accurate data for whole application. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- src/kimchid.in | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/kimchid.in b/src/kimchid.in index d3d398f..fc889a3 100644 --- a/src/kimchid.in +++ b/src/kimchid.in @@ -26,12 +26,11 @@ sys.path.insert(1, '@pythondir@') from optparse import OptionParser import kimchi.server -import kimchi.config +import kimchi.config as config -from kimchi.config import config, paths -if not paths.installed: - sys.path.append(paths.prefix) +if not config.paths.installed: + sys.path.append(config.paths.prefix) ACCESS_LOG = "kimchi-access.log" ERROR_LOG = "kimchi-error.log" @@ -42,13 +41,13 @@ def main(options): if not os.geteuid() == 0: sys.exit("\nMust be root to run this script. Exiting ...\n") - host = config.get("server", "host") - port = config.get("server", "port") - ssl_port = config.get("server", "ssl_port") - cherrypy_port = config.get("server", "cherrypy_port") - runningEnv = config.get('server', 'environment') - logDir = config.get("logging", "log_dir") - logLevel = config.get("logging", "log_level") + host = config.config.get("server", "host") + port = config.config.get("server", "port") + ssl_port = config.config.get("server", "ssl_port") + cherrypy_port = config.config.get("server", "cherrypy_port") + runningEnv = config.config.get("server", "environment") + logDir = config.config.get("logging", "log_dir") + logLevel = config.config.get("logging", "log_level") parser = OptionParser() parser.add_option('--host', type="string", default=host, @@ -73,9 +72,16 @@ def main(options): help="Run server in mock model") (options, args) = parser.parse_args() + # Update config.config with the command line values + # So the whole application will have access to accurate values + for sec in config.config.sections(): + for item in config.config.options(sec): + if hasattr(options, item): + config.config.set(sec, item, str(getattr(options, item))) + # Add non-option arguments - setattr(options, 'ssl_cert', config.get('server', 'ssl_cert')) - setattr(options, 'ssl_key', config.get('server', 'ssl_key')) + setattr(options, 'ssl_cert', config.config.get('server', 'ssl_cert')) + setattr(options, 'ssl_key', config.config.get('server', 'ssl_key')) kimchi.server.main(options) -- 1.9.3

http_port information was used to display the guest console But since we have changed how to redirect user to guest console by adding the ui/pages/websockify/console.html it is not in use anymore. So remove it. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- docs/API.md | 1 - src/kimchi/mockmodel.py | 5 ++--- src/kimchi/model/config.py | 3 +-- src/kimchi/server.py | 1 - tests/test_rest.py | 3 ++- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/API.md b/docs/API.md index ebb6e61..be2fd84 100644 --- a/docs/API.md +++ b/docs/API.md @@ -596,7 +596,6 @@ Contains information about the application environment and configuration. **Methods:** * **GET**: Retrieve configuration information - * http_port: The port number on which the server is listening * display_proxy_port: Port for vnc and spice's websocket proxy to listen on * version: The version of the kimchi service * **POST**: *See Configuration Actions* diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index fc474de..57a58d7 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -918,9 +918,8 @@ class MockModel(object): return disks.get_partition_details(name) def config_lookup(self, name): - return {'http_port': cherrypy.config.nginx_port, - 'display_proxy_port': - kconfig.get('display', 'display_proxy_port'), + return {'display_proxy_port': kconfig.get('display', + 'display_proxy_port'), 'version': config.get_version()} def packagesupdate_get_list(self): diff --git a/src/kimchi/model/config.py b/src/kimchi/model/config.py index 0466f6f..90bb923 100644 --- a/src/kimchi/model/config.py +++ b/src/kimchi/model/config.py @@ -40,8 +40,7 @@ class ConfigModel(object): def lookup(self, name): proxy_port = kconfig.get('display', 'display_proxy_port') - return {'http_port': cherrypy.config.nginx_port, - 'display_proxy_port': proxy_port, + return {'display_proxy_port': proxy_port, 'version': get_version()} diff --git a/src/kimchi/server.py b/src/kimchi/server.py index bca2147..10f5dff 100644 --- a/src/kimchi/server.py +++ b/src/kimchi/server.py @@ -87,7 +87,6 @@ class Server(object): # directly. You must go through the proxy. cherrypy.server.socket_host = '127.0.0.1' cherrypy.server.socket_port = options.cherrypy_port - cherrypy.config.nginx_port = options.port cherrypy.log.screen = True cherrypy.log.access_file = options.access_log diff --git a/tests/test_rest.py b/tests/test_rest.py index 2117399..9066857 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1525,7 +1525,8 @@ class RestTests(unittest.TestCase): def test_config(self): resp = self.request('/config').read() conf = json.loads(resp) - self.assertEquals(port, conf['http_port']) + keys = ["display_proxy_port", "version"] + self.assertEquals(keys, sorted(conf.keys())) def test_capabilities(self): resp = self.request('/config/capabilities').read() -- 1.9.3

It is also allows user to enable/disable the federation feature by the command line: kimchid --federation=[on|off] The default value is: off which means the federation feature will be disabled Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- src/kimchi.conf.in | 4 ++++ src/kimchi/config.py.in | 1 + src/kimchid.in | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/kimchi.conf.in b/src/kimchi.conf.in index ed0270d..2be1a0e 100644 --- a/src/kimchi.conf.in +++ b/src/kimchi.conf.in @@ -26,6 +26,10 @@ # Running environment of the server #environment = production +# Federation feature: register Kimchi server on openSLP and discover peers +# at the same network +#federation = off + [logging] # Log directory #log_dir = @localstatedir@/log/kimchi diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in index fca32ee..d403827 100644 --- a/src/kimchi/config.py.in +++ b/src/kimchi/config.py.in @@ -254,6 +254,7 @@ def _get_config(): config.set("server", "ssl_cert", "") config.set("server", "ssl_key", "") config.set("server", "environment", "production") + config.set("server", "federation", "off") config.add_section("logging") config.set("logging", "log_dir", paths.log_dir) config.set("logging", "log_level", DEFAULT_LOG_LEVEL) diff --git a/src/kimchid.in b/src/kimchid.in index fc889a3..3ed087f 100644 --- a/src/kimchid.in +++ b/src/kimchid.in @@ -46,6 +46,7 @@ def main(options): ssl_port = config.config.get("server", "ssl_port") cherrypy_port = config.config.get("server", "cherrypy_port") runningEnv = config.config.get("server", "environment") + federation = config.config.get("server", "federation") logDir = config.config.get("logging", "log_dir") logLevel = config.config.get("logging", "log_level") @@ -68,6 +69,9 @@ def main(options): help="Error log file") parser.add_option('--environment', default=runningEnv, help="Running environment of kimchi server") + parser.add_option('--federation', default=federation, + help="Register and discover Kimchi peers at the same " + "network using openSLP") parser.add_option('--test', action='store_true', help="Run server in mock model") (options, args) = parser.parse_args() -- 1.9.3

When federation feature is enabled, Kimchi server will be registered on openSLP service on server starting up. It will expose the Kimchi URL to others Kimchi peers. To discover Kimchi peers in the same network, the following API is provided: GET /peers [ https://ubuntu-vm:8001, https://rhel-vm:8001 ] Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- docs/API.md | 9 +++++++ src/kimchi/control/peers.py | 29 ++++++++++++++++++++++ src/kimchi/mockmodel.py | 6 +++++ src/kimchi/model/peers.py | 59 +++++++++++++++++++++++++++++++++++++++++++++ tests/test_rest.py | 4 +++ 5 files changed, 107 insertions(+) create mode 100644 src/kimchi/control/peers.py create mode 100644 src/kimchi/model/peers.py diff --git a/docs/API.md b/docs/API.md index be2fd84..cb761e5 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1003,3 +1003,12 @@ http://, ftp:// or file:// URL. * enable: Enable the Repository as package source * disable: Disable the Repository as package source + +### Collection: Peers + +**URI:** /peers + +**Methods:** + +* **GET**: Return the list of Kimchi peers in the same network + (It uses openSLP for discovering) diff --git a/src/kimchi/control/peers.py b/src/kimchi/control/peers.py new file mode 100644 index 0000000..f72a38c --- /dev/null +++ b/src/kimchi/control/peers.py @@ -0,0 +1,29 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2014 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +from kimchi.control.base import SimpleCollection +from kimchi.control.utils import UrlSubNode + + +@UrlSubNode("peers", True) +class Peers(SimpleCollection): + def __init__(self, model): + super(Peers, self).__init__(model) + self.role_key = 'peers' + self.admin_methods = ['GET'] diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index 57a58d7..107aef4 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -884,6 +884,12 @@ class MockModel(object): def groups_get_list(self): return ["groupA", "groupB", "groupC", "groupD"] + def peers_get_list(self): + if kconfig.get("server", "federation") == "off": + return [] + + return ["https://serverA:8001", "https://serverB:8001"] + def vms_get_list_by_state(self, state): ret_list = [] for name in self.vms_get_list(): diff --git a/src/kimchi/model/peers.py b/src/kimchi/model/peers.py new file mode 100644 index 0000000..01e9210 --- /dev/null +++ b/src/kimchi/model/peers.py @@ -0,0 +1,59 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2014 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import re +import socket + +from kimchi.config import config +from kimchi.utils import kimchi_log, run_command + + +class PeersModel(object): + def __init__(self, **kargs): + # check federation feature is enabled on Kimchi server + if config.get("server", "federation") == "off": + return + + # register server on openslp + hostname = socket.getfqdn(config.get("server", "host")) + port = config.get("server", "ssl_port") + self.url = hostname + ":" + port + + cmd = ["slptool", "register", + "service:kimchid://%s:%s" % (hostname, port)] + out, error, ret = run_command(cmd) + if len(out) != 0: + kimchi_log.error("Unable to register server on openSLP." + " Details: %s" % out) + + def get_list(self): + # check federation feature is enabled on Kimchi server + if config.get("server", "federation") == "off": + return [] + + peers = [] + cmd = ["slptool", "findsrvs", "service:kimchid"] + out, error, ret = run_command(cmd) + for server in out.strip().split("\n"): + match = re.match("service:kimchid://(.*?),.*", server) + peer = match.group(1) + if peer != self.url: + peers.append("https://" + peer) + + return peers diff --git a/tests/test_rest.py b/tests/test_rest.py index 9066857..a070f14 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1539,6 +1539,10 @@ class RestTests(unittest.TestCase): self.assertIn('update_tool', conf) self.assertIn('repo_mngt_tool', conf) + def test_peers(self): + resp = self.request('/peers').read() + self.assertEquals([], json.loads(resp)) + def test_auth_unprotected(self): hdrs = {'AUTHORIZATION': ''} uris = ['/js/kimchi.min.js', -- 1.9.3

On Tue, 2014-08-26 at 22:16 -0300, Aline Manera wrote:
When federation feature is enabled, Kimchi server will be registered on openSLP service on server starting up. It will expose the Kimchi URL to others Kimchi peers.
To discover Kimchi peers in the same network, the following API is provided:
GET /peers [ https://ubuntu-vm:8001, https://rhel-vm:8001 ]
Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- docs/API.md | 9 +++++++ src/kimchi/control/peers.py | 29 ++++++++++++++++++++++ src/kimchi/mockmodel.py | 6 +++++ src/kimchi/model/peers.py | 59 +++++++++++++++++++++++++++++++++++++++++++++ tests/test_rest.py | 4 +++ 5 files changed, 107 insertions(+) create mode 100644 src/kimchi/control/peers.py create mode 100644 src/kimchi/model/peers.py
diff --git a/docs/API.md b/docs/API.md index be2fd84..cb761e5 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1003,3 +1003,12 @@ http://, ftp:// or file:// URL.
* enable: Enable the Repository as package source * disable: Disable the Repository as package source + +### Collection: Peers + +**URI:** /peers + +**Methods:** + +* **GET**: Return the list of Kimchi peers in the same network + (It uses openSLP for discovering) diff --git a/src/kimchi/control/peers.py b/src/kimchi/control/peers.py new file mode 100644 index 0000000..f72a38c --- /dev/null +++ b/src/kimchi/control/peers.py @@ -0,0 +1,29 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2014 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +from kimchi.control.base import SimpleCollection +from kimchi.control.utils import UrlSubNode + + +@UrlSubNode("peers", True) +class Peers(SimpleCollection): + def __init__(self, model): + super(Peers, self).__init__(model) + self.role_key = 'peers' + self.admin_methods = ['GET'] diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index 57a58d7..107aef4 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -884,6 +884,12 @@ class MockModel(object): def groups_get_list(self): return ["groupA", "groupB", "groupC", "groupD"]
+ def peers_get_list(self): + if kconfig.get("server", "federation") == "off": + return [] + + return ["https://serverA:8001", "https://serverB:8001"] + def vms_get_list_by_state(self, state): ret_list = [] for name in self.vms_get_list(): diff --git a/src/kimchi/model/peers.py b/src/kimchi/model/peers.py new file mode 100644 index 0000000..01e9210 --- /dev/null +++ b/src/kimchi/model/peers.py @@ -0,0 +1,59 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2014 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import re +import socket + +from kimchi.config import config +from kimchi.utils import kimchi_log, run_command + + +class PeersModel(object): + def __init__(self, **kargs): + # check federation feature is enabled on Kimchi server + if config.get("server", "federation") == "off": + return + + # register server on openslp + hostname = socket.getfqdn(config.get("server", "host")) + port = config.get("server", "ssl_port") + self.url = hostname + ":" + port + + cmd = ["slptool", "register", + "service:kimchid://%s:%s" % (hostname, port)]
Why not use the self.url? "service:kimchid://%s" % self.url
+ out, error, ret = run_command(cmd) + if len(out) != 0: + kimchi_log.error("Unable to register server on openSLP." + " Details: %s" % out) + + def get_list(self): + # check federation feature is enabled on Kimchi server + if config.get("server", "federation") == "off": + return [] + + peers = [] + cmd = ["slptool", "findsrvs", "service:kimchid"] + out, error, ret = run_command(cmd) + for server in out.strip().split("\n"): + match = re.match("service:kimchid://(.*?),.*", server) + peer = match.group(1) + if peer != self.url: + peers.append("https://" + peer) + + return peers diff --git a/tests/test_rest.py b/tests/test_rest.py index 9066857..a070f14 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1539,6 +1539,10 @@ class RestTests(unittest.TestCase): self.assertIn('update_tool', conf) self.assertIn('repo_mngt_tool', conf)
+ def test_peers(self): + resp = self.request('/peers').read() + self.assertEquals([], json.loads(resp)) + def test_auth_unprotected(self): hdrs = {'AUTHORIZATION': ''} uris = ['/js/kimchi.min.js',

On 08/29/2014 07:06 PM, Paulo Ricardo Paz Vital wrote:
On Tue, 2014-08-26 at 22:16 -0300, Aline Manera wrote:
When federation feature is enabled, Kimchi server will be registered on openSLP service on server starting up. It will expose the Kimchi URL to others Kimchi peers.
To discover Kimchi peers in the same network, the following API is provided:
GET /peers [ https://ubuntu-vm:8001, https://rhel-vm:8001 ]
Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- docs/API.md | 9 +++++++ src/kimchi/control/peers.py | 29 ++++++++++++++++++++++ src/kimchi/mockmodel.py | 6 +++++ src/kimchi/model/peers.py | 59 +++++++++++++++++++++++++++++++++++++++++++++ tests/test_rest.py | 4 +++ 5 files changed, 107 insertions(+) create mode 100644 src/kimchi/control/peers.py create mode 100644 src/kimchi/model/peers.py
diff --git a/docs/API.md b/docs/API.md index be2fd84..cb761e5 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1003,3 +1003,12 @@ http://, ftp:// or file:// URL.
* enable: Enable the Repository as package source * disable: Disable the Repository as package source + +### Collection: Peers + +**URI:** /peers + +**Methods:** + +* **GET**: Return the list of Kimchi peers in the same network + (It uses openSLP for discovering) diff --git a/src/kimchi/control/peers.py b/src/kimchi/control/peers.py new file mode 100644 index 0000000..f72a38c --- /dev/null +++ b/src/kimchi/control/peers.py @@ -0,0 +1,29 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2014 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +from kimchi.control.base import SimpleCollection +from kimchi.control.utils import UrlSubNode + + +@UrlSubNode("peers", True) +class Peers(SimpleCollection): + def __init__(self, model): + super(Peers, self).__init__(model) + self.role_key = 'peers' + self.admin_methods = ['GET'] diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index 57a58d7..107aef4 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -884,6 +884,12 @@ class MockModel(object): def groups_get_list(self): return ["groupA", "groupB", "groupC", "groupD"]
+ def peers_get_list(self): + if kconfig.get("server", "federation") == "off": + return [] + + return ["https://serverA:8001", "https://serverB:8001"] + def vms_get_list_by_state(self, state): ret_list = [] for name in self.vms_get_list(): diff --git a/src/kimchi/model/peers.py b/src/kimchi/model/peers.py new file mode 100644 index 0000000..01e9210 --- /dev/null +++ b/src/kimchi/model/peers.py @@ -0,0 +1,59 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2014 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import re +import socket + +from kimchi.config import config +from kimchi.utils import kimchi_log, run_command + + +class PeersModel(object): + def __init__(self, **kargs): + # check federation feature is enabled on Kimchi server + if config.get("server", "federation") == "off": + return + + # register server on openslp + hostname = socket.getfqdn(config.get("server", "host")) + port = config.get("server", "ssl_port") + self.url = hostname + ":" + port + + cmd = ["slptool", "register", + "service:kimchid://%s:%s" % (hostname, port)] Why not use the self.url? "service:kimchid://%s" % self.url
ACK. Check v3.
+ out, error, ret = run_command(cmd) + if len(out) != 0: + kimchi_log.error("Unable to register server on openSLP." + " Details: %s" % out) + + def get_list(self): + # check federation feature is enabled on Kimchi server + if config.get("server", "federation") == "off": + return [] + + peers = [] + cmd = ["slptool", "findsrvs", "service:kimchid"] + out, error, ret = run_command(cmd) + for server in out.strip().split("\n"): + match = re.match("service:kimchid://(.*?),.*", server) + peer = match.group(1) + if peer != self.url: + peers.append("https://" + peer) + + return peers diff --git a/tests/test_rest.py b/tests/test_rest.py index 9066857..a070f14 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1539,6 +1539,10 @@ class RestTests(unittest.TestCase): self.assertIn('update_tool', conf) self.assertIn('repo_mngt_tool', conf)
+ def test_peers(self): + resp = self.request('/peers').read() + self.assertEquals([], json.loads(resp)) + def test_auth_unprotected(self): hdrs = {'AUTHORIZATION': ''} uris = ['/js/kimchi.min.js',

README-federation.md is specific for the federation feature. It explains how to install openSLP and enable federation on Kimchi. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- docs/README-federation.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 docs/README-federation.md diff --git a/docs/README-federation.md b/docs/README-federation.md new file mode 100644 index 0000000..fdf4aed --- /dev/null +++ b/docs/README-federation.md @@ -0,0 +1,27 @@ +Kimchi Project - Federation Feature +=================================== + +Federation feature is a mechanism to discover Kimchi peers in the same network. +It uses openSLP tool (http://www.openslp.org/) to register and find the Kimchi +servers. + +By default this feature is disabled on Kimchi as it is not critical for KVM +virtualization and requires additional software installation. + +To enable it, do the following: + +1) Install openslp and openslp-server packages +2) openSLP uses port 427 (UDP) and port 427 (TCP) so make sure to open those + ports in your firewall configuration +3) Start slpd service and make sure it is up while running Kimchi +4) Enable federation on Kimchi by editing the /etc/kimchi/kimchi.conf file: + + federation = on + +5) Then restart Kimchi service + +The Kimchi server will be registered on openSLP on server starting up and will +be found by other Kimchi peers (with federation feature enabled) in the same +network. + +Enjoy! -- 1.9.3

That way we can properly update the UI when federation is enabled or not Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- docs/API.md | 1 + src/kimchi/mockmodel.py | 3 ++- src/kimchi/model/config.py | 3 ++- tests/test_rest.py | 12 +++++------- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/API.md b/docs/API.md index cb761e5..42eabd2 100644 --- a/docs/API.md +++ b/docs/API.md @@ -627,6 +627,7 @@ creation. system; False, otherwise * repo_mngt_tool: 'deb', 'yum' or None - when the repository management tool is not identified + * federation: 'on' if federation feature is enabled, 'off' otherwise. * **POST**: *See Configuration Actions* **Actions (POST):** diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index 107aef4..ae87541 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -74,7 +74,8 @@ class MockModel(object): 'screenshot': True, 'system_report_tool': True, 'update_tool': True, - 'repo_mngt_tool': 'yum'} + 'repo_mngt_tool': 'yum', + 'federation': 'off'} def reset(self): self._mock_vms = {} diff --git a/src/kimchi/model/config.py b/src/kimchi/model/config.py index 90bb923..1c00cfe 100644 --- a/src/kimchi/model/config.py +++ b/src/kimchi/model/config.py @@ -109,7 +109,8 @@ class CapabilitiesModel(object): 'screenshot': VMScreenshot.get_stream_test_result(), 'system_report_tool': bool(report_tool), 'update_tool': update_tool, - 'repo_mngt_tool': repo_mngt_tool} + 'repo_mngt_tool': repo_mngt_tool, + 'federation': kconfig.get("server", "federation")} class DistrosModel(object): diff --git a/tests/test_rest.py b/tests/test_rest.py index a070f14..e97eabb 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1531,13 +1531,11 @@ class RestTests(unittest.TestCase): def test_capabilities(self): resp = self.request('/config/capabilities').read() conf = json.loads(resp) - self.assertIn('libvirt_stream_protocols', conf) - self.assertIn('qemu_stream', conf) - self.assertIn('qemu_spice', conf) - self.assertIn('screenshot', conf) - self.assertIn('system_report_tool', conf) - self.assertIn('update_tool', conf) - self.assertIn('repo_mngt_tool', conf) + + keys = ['libvirt_stream_protocols', 'qemu_stream', 'qemu_spice', + 'screenshot', 'system_report_tool', 'update_tool', + 'repo_mngt_tool', 'federation'] + self.assertEquals(sorted(keys), sorted(conf.keys())) def test_peers(self): resp = self.request('/peers').read() -- 1.9.3
participants (2)
-
Aline Manera
-
Paulo Ricardo Paz Vital