[PATCH V3 0/3] Fix non persistent network handling

V3: Changes mockmodel and tests (Royce suggestion) V2: Address Ming comments: - Updates API.md - remove useless comments and return V1: Kimchi networks have the same problem storage had. Non persistent networks are not stop, they are removed by libvirt and this causes an error in Kimchi. Rodrigo Trujillo (3): Fix non persistent network handling (backend) Fix non persistent network handling (frontend) Fix non persistent network handling (mockmodel/tests) docs/API.md | 2 ++ src/kimchi/control/networks.py | 3 ++- src/kimchi/mockmodel.py | 7 +++++- src/kimchi/model/networks.py | 3 ++- tests/test_model.py | 1 + tests/test_rest.py | 1 + ui/js/src/kimchi.network.js | 55 ++++++++++++++++++++++++++++-------------- ui/pages/i18n.html.tmpl | 1 + 8 files changed, 52 insertions(+), 21 deletions(-) -- 1.8.5.3

If some network is not persistent and the user tries to stop it, it is going to be removed by libvirt and causes an error in Kimchi. This patch changes the backend in order to get persistent information. Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo@linux.vnet.ibm.com> --- docs/API.md | 2 ++ src/kimchi/control/networks.py | 3 ++- src/kimchi/model/networks.py | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/API.md b/docs/API.md index 2c88a11..4a0a3f2 100644 --- a/docs/API.md +++ b/docs/API.md @@ -505,6 +505,8 @@ A interface represents available interface on host. * interface: The name of a bridge network interface on the host. All traffic on this network will be bridged through the indicated interface. The interface is a bridge or ethernet/bonding device. + * persistent: If 'true', network will persist after a system reboot or be stopped. + All networks created by Kimchi are persistent. * **DELETE**: Remove the Network * **POST**: *See Network Actions* diff --git a/src/kimchi/control/networks.py b/src/kimchi/control/networks.py index 95e8523..b905891 100644 --- a/src/kimchi/control/networks.py +++ b/src/kimchi/control/networks.py @@ -45,4 +45,5 @@ class Network(Resource): 'interface': self.info['interface'], 'subnet': self.info['subnet'], 'dhcp': self.info['dhcp'], - 'state': self.info['state']} + 'state': self.info['state'], + 'persistent': self.info['persistent']} diff --git a/src/kimchi/model/networks.py b/src/kimchi/model/networks.py index 7872a73..63f3136 100644 --- a/src/kimchi/model/networks.py +++ b/src/kimchi/model/networks.py @@ -233,7 +233,8 @@ class NetworkModel(object): 'vms': self._get_vms_attach_to_a_network(name), 'in_use': self._is_network_in_use(name), 'autostart': network.autostart() == 1, - 'state': network.isActive() and "active" or "inactive"} + 'state': network.isActive() and "active" or "inactive", + 'persistent': True if network.isPersistent() else False} def _is_network_in_use(self, name): # The network "default" is used for Kimchi proposal and should not be -- 1.8.5.3

If some network is not persistent and the user tries to stop it, it is going to be removed by libvirt and causes an error in Kimchi. This patch warns the user with a message in the ui about the situation, avoinding mistakes. Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo@linux.vnet.ibm.com> --- ui/js/src/kimchi.network.js | 55 ++++++++++++++++++++++++++++++--------------- ui/pages/i18n.html.tmpl | 1 + 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js index 1642b99..7a331be 100644 --- a/ui/js/src/kimchi.network.js +++ b/ui/js/src/kimchi.network.js @@ -40,6 +40,7 @@ kimchi.initNetworkListView = function() { } network.interface = data[i].interface ? data[i].interface : null; network.addrSpace = data[i].subnet ? data[i].subnet : null; + network.persistent = data[i].persistent; kimchi.addNetworkItem(network); } }); @@ -77,6 +78,27 @@ kimchi.getNetworkItemHtml = function(network) { return networkItem; }; +kimchi.stopNetwork = function(network,menu) { + $(".network-state", $("#" + network.name)).switchClass("up", "nw-loading"); + $("[nwAct='stop']", menu).addClass("ui-state-disabled"); + kimchi.toggleNetwork(network.name, false, function() { + $("[nwAct='start']", menu).removeClass("hide-action-item"); + $("[nwAct='stop']", menu).addClass("hide-action-item"); + $("[nwAct='stop']", menu).removeClass("ui-state-disabled"); + if (!network.in_use) { + $("[nwAct='delete']", menu).removeClass("ui-state-disabled"); + $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled"); + } + $(".network-state", $("#" + network.name)).switchClass("nw-loading", "down"); + }, function(err) { + $(".network-state", $("#" + network.name)).switchClass("nw-loading", "up"); + if (!network.in_use) { + $("[nwAct='stop']", menu).removeClass("ui-state-disabled"); + } + kimchi.message.error(err.responseJSON.reason); + }); +} + kimchi.addNetworkActions = function(network) { $(".menu-container", "#" + network.name).menu({ position : { @@ -110,24 +132,21 @@ kimchi.addNetworkActions = function(network) { kimchi.message.error(err.responseJSON.reason); }); } else if ($(evt.currentTarget).attr("nwAct") === "stop") { - $(".network-state", $("#" + network.name)).switchClass("up", "nw-loading"); - $("[nwAct='stop']", menu).addClass("ui-state-disabled"); - kimchi.toggleNetwork(network.name, false, function() { - $("[nwAct='start']", menu).removeClass("hide-action-item"); - $("[nwAct='stop']", menu).addClass("hide-action-item"); - $("[nwAct='stop']", menu).removeClass("ui-state-disabled"); - if (!network.in_use) { - $("[nwAct='delete']", menu).removeClass("ui-state-disabled"); - $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled"); - } - $(".network-state", $("#" + network.name)).switchClass("nw-loading", "down"); - }, function(err) { - $(".network-state", $("#" + network.name)).switchClass("nw-loading", "up"); - if (!network.in_use) { - $("[nwAct='stop']", menu).removeClass("ui-state-disabled"); - } - kimchi.message.error(err.responseJSON.reason); - }); + if (!network.persistent) { + var settings = { + title : i18n['KCHAPI6001M'], + content : i18n['KCHNET6004M'], + confirm : i18n['KCHAPI6002M'], + cancel : i18n['KCHAPI6003M'] + }; + kimchi.confirm(settings, function() { + kimchi.stopNetwork(network, menu); + $(evt.currentTarget).parents(".item").remove(); + }, null); + } + else { + kimchi.stopNetwork(network, menu); + } } else if ($(evt.currentTarget).attr("nwAct") === "delete") { kimchi.confirm({ title : i18n['KCHAPI6006M'], diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl index a626759..af2574d 100644 --- a/ui/pages/i18n.html.tmpl +++ b/ui/pages/i18n.html.tmpl @@ -118,6 +118,7 @@ var i18n = { 'KCHNET6001M': "$_("unavailable")", 'KCHNET6002M': "$_("This action will interrupt network connectivity for any virtual machine that depend on this network.")", 'KCHNET6003M': "$_("Create a network")", + 'KCHNET6004M': "$_("This network is not persistent. Instead of stop, this action will permanently delete it. Would you like to continue?")", 'KCHPOOL6001M': "$_("This will permanently delete the storage pool. Would you like to continue?")", 'KCHPOOL6002M': "$_("This storage pool is empty.")", -- 1.8.5.3

This patch adds the persistent information to mockmodel and tests to check if it is true. Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo@linux.vnet.ibm.com> --- src/kimchi/mockmodel.py | 7 ++++++- tests/test_model.py | 1 + tests/test_rest.py | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index faf1049..ba4365f 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -625,7 +625,11 @@ class MockModel(object): if self._is_network_in_use(name): raise InvalidOperation("KCHNET0018E", {'name': name}) - self._get_network(name).info['state'] = 'inactive' + network = _get_network(name) + if not network.info['persistent']: + self.network_delete(name) + + network.info['state'] = 'inactive' def network_delete(self, name): if self._is_network_in_use(name): @@ -1008,6 +1012,7 @@ class MockNetwork(object): 'subnet': '192.168.122.0/24', 'dhcp': {'start': '192.168.122.128', 'stop': '192.168.122.254'}, + 'persistent': True } diff --git a/tests/test_model.py b/tests/test_model.py index 69f9b5b..b8e6d47 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -632,6 +632,7 @@ class ModelTests(unittest.TestCase): self.assertEquals('inactive', networkinfo['state']) self.assertEquals([], networkinfo['vms']) self.assertTrue(networkinfo['autostart']) + self.assertTrue(networkinfo['persistent']) inst.network_activate(name) rollback.prependDefer(inst.network_deactivate, name) diff --git a/tests/test_rest.py b/tests/test_rest.py index 3f2e449..929b7ab 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -1297,6 +1297,7 @@ class RestTests(unittest.TestCase): network = json.loads(request(host, port, '/networks/test-network').read()) self.assertEquals('inactive', network['state']) + self.assertTrue(network['persistent']) # activate the network resp = request(host, port, -- 1.8.5.3

The tests are failing: 127.0.0.1 - - [26/Mar/2014:13:12:47] "GET /networks/test-network HTTP/1.1" 200 271 "" "" [26/Mar/2014:13:12:47] HTTP Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/cherrypy/_cprequest.py", line 656, in respond response.body = self.handler() File "/usr/lib/python2.7/dist-packages/cherrypy/lib/encoding.py", line 188, in __call__ self.body = self.oldhandler(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/cherrypy/_cpdispatch.py", line 34, in __call__ return self.callable(*self.args, **self.kwargs) File "/home/alinefm/kimchi/src/kimchi/control/base.py", line 72, in wrapper ident = fn(*model_args) File "/home/alinefm/kimchi/src/kimchi/mockmodel.py", line 629, in network_deactivate network = _get_network(name) NameError: global name '_get_network' is not defined 127.0.0.1 - - [26/Mar/2014:13:12:47] "POST /networks/test-network/deactivate HTTP/1.1" 500 905 "" "" ====================================================================== FAIL: test_network_action (test_rest.HttpsRestTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/alinefm/kimchi/tests/test_rest.py", line 1314, in test_network_action self.assertEquals('inactive', network['state']) AssertionError: 'inactive' != u'active' ====================================================================== FAIL: test_network_action (test_rest.RestTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/alinefm/kimchi/tests/test_rest.py", line 1314, in test_network_action self.assertEquals('inactive', network['state']) AssertionError: 'inactive' != u'active' ====================================================================== On 03/25/2014 09:32 AM, Rodrigo Trujillo wrote:
V3: Changes mockmodel and tests (Royce suggestion)
V2: Address Ming comments: - Updates API.md - remove useless comments and return
V1: Kimchi networks have the same problem storage had. Non persistent networks are not stop, they are removed by libvirt and this causes an error in Kimchi.
Rodrigo Trujillo (3): Fix non persistent network handling (backend) Fix non persistent network handling (frontend) Fix non persistent network handling (mockmodel/tests)
docs/API.md | 2 ++ src/kimchi/control/networks.py | 3 ++- src/kimchi/mockmodel.py | 7 +++++- src/kimchi/model/networks.py | 3 ++- tests/test_model.py | 1 + tests/test_rest.py | 1 + ui/js/src/kimchi.network.js | 55 ++++++++++++++++++++++++++++-------------- ui/pages/i18n.html.tmpl | 1 + 8 files changed, 52 insertions(+), 21 deletions(-)

Ok, got to fix this Thanks On 03/26/2014 01:20 PM, Aline Manera wrote:
The tests are failing:
127.0.0.1 - - [26/Mar/2014:13:12:47] "GET /networks/test-network HTTP/1.1" 200 271 "" "" [26/Mar/2014:13:12:47] HTTP Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/cherrypy/_cprequest.py", line 656, in respond response.body = self.handler() File "/usr/lib/python2.7/dist-packages/cherrypy/lib/encoding.py", line 188, in __call__ self.body = self.oldhandler(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/cherrypy/_cpdispatch.py", line 34, in __call__ return self.callable(*self.args, **self.kwargs) File "/home/alinefm/kimchi/src/kimchi/control/base.py", line 72, in wrapper ident = fn(*model_args) File "/home/alinefm/kimchi/src/kimchi/mockmodel.py", line 629, in network_deactivate network = _get_network(name) NameError: global name '_get_network' is not defined
127.0.0.1 - - [26/Mar/2014:13:12:47] "POST /networks/test-network/deactivate HTTP/1.1" 500 905 "" ""
====================================================================== FAIL: test_network_action (test_rest.HttpsRestTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/alinefm/kimchi/tests/test_rest.py", line 1314, in test_network_action self.assertEquals('inactive', network['state']) AssertionError: 'inactive' != u'active'
====================================================================== FAIL: test_network_action (test_rest.RestTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/alinefm/kimchi/tests/test_rest.py", line 1314, in test_network_action self.assertEquals('inactive', network['state']) AssertionError: 'inactive' != u'active'
======================================================================
On 03/25/2014 09:32 AM, Rodrigo Trujillo wrote:
V3: Changes mockmodel and tests (Royce suggestion)
V2: Address Ming comments: - Updates API.md - remove useless comments and return
V1: Kimchi networks have the same problem storage had. Non persistent networks are not stop, they are removed by libvirt and this causes an error in Kimchi.
Rodrigo Trujillo (3): Fix non persistent network handling (backend) Fix non persistent network handling (frontend) Fix non persistent network handling (mockmodel/tests)
docs/API.md | 2 ++ src/kimchi/control/host.py:class src/kimchi/control/networks.py | 3 ++- src/kimchi/mockmodel.py | 7 +++++- src/kimchi/model/networks.py | 3 ++- tests/test_model.py | 1 + tests/test_rest.py | 1 + ui/js/src/kimchi.network.js | 55 ++++++++++++++++++++++++++++-------------- ui/pages/i18n.html.tmpl | 1 + 8 files changed, 52 insertions(+), 21 deletions(-)
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
participants (2)
-
Aline Manera
-
Rodrigo Trujillo