From 318ad3cefeed74b074b6ed2c676809245c514e10 Mon Sep 17 00:00:00 2001 From: Hongbin Lu Date: Sun, 1 Mar 2015 22:40:30 +0000 Subject: [PATCH] Correctly delete replica controller The correct way to delete a rc should be: 1. Resize the rc to 0. 2. Delete all pods in the rc. 3. Delete the rc. So, we should use 'kubectl stop rc id' to completely delete a rc. This command will first resize a rc to 0 and then delete all pods, before deleting the rc. Change-Id: I3666606f15440942c192aa81635899fa135d036d Closes-Bug: 1424304 --- doc/source/dev/dev-quickstart.rst | 2 +- .../conductor/handlers/common/kube_utils.py | 8 +++---- magnum/conductor/handlers/kube.py | 2 +- magnum/tests/conductor/handlers/test_kube.py | 24 +++++++++++++++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/doc/source/dev/dev-quickstart.rst b/doc/source/dev/dev-quickstart.rst index 23259226da..0d25faad6e 100644 --- a/doc/source/dev/dev-quickstart.rst +++ b/doc/source/dev/dev-quickstart.rst @@ -109,7 +109,7 @@ required action is to install kubectl manually. Install binary distribution of kubectl distributed by Google:: - wget https://github.com/GoogleCloudPlatform/kubernetes/releases/download/v0.7.0/kubernetes.tar.gz + wget https://github.com/GoogleCloudPlatform/kubernetes/releases/download/v0.11.0/kubernetes.tar.gz tar -xzvf kubernetes.tar.gz sudo cp -a kubernetes/platforms/linux/amd64/kubectl /usr/bin/kubectl diff --git a/magnum/conductor/handlers/common/kube_utils.py b/magnum/conductor/handlers/common/kube_utils.py index 47cf882deb..3462f924a8 100644 --- a/magnum/conductor/handlers/common/kube_utils.py +++ b/magnum/conductor/handlers/common/kube_utils.py @@ -262,15 +262,15 @@ class KubeClient(object): return False return True - def rc_delete(self, master_address, name): - LOG.debug("rc_delete %s" % name) + def rc_stop(self, master_address, name): + LOG.debug("rc_stop %s" % name) try: - out, err = utils.trycmd('kubectl', 'delete', 'rc', name, + out, err = utils.trycmd('kubectl', 'stop', 'rc', name, '-s', master_address) if err: return False except Exception as e: - LOG.error(_LE("Couldn't delete rc %(rc)s due to error %(error)s") + LOG.error(_LE("Couldn't stop rc %(rc)s due to error %(error)s") % {'rc': name, 'error': e}) return False return True diff --git a/magnum/conductor/handlers/kube.py b/magnum/conductor/handlers/kube.py index a375512d16..f9b4edc590 100644 --- a/magnum/conductor/handlers/kube.py +++ b/magnum/conductor/handlers/kube.py @@ -224,7 +224,7 @@ class Handler(object): k8s_master_url = _retrieve_k8s_master_url(context, rc) if _object_has_stack(context, rc): # trigger a kubectl command - status = self.kube_cli.rc_delete(k8s_master_url, rc.name) + status = self.kube_cli.rc_stop(k8s_master_url, rc.name) if not status: return None # call the rc object to persist in db diff --git a/magnum/tests/conductor/handlers/test_kube.py b/magnum/tests/conductor/handlers/test_kube.py index e78f414f4c..f3e259d2a7 100644 --- a/magnum/tests/conductor/handlers/test_kube.py +++ b/magnum/tests/conductor/handlers/test_kube.py @@ -248,3 +248,27 @@ class TestKube(base.TestCase): self.kube_handler.rc_create({}, expected_rc) mock_kube_cli.rc_create.assert_called_once_with( expected_master_url, expected_rc) + + @patch('magnum.conductor.handlers.kube._object_has_stack') + @patch('magnum.conductor.handlers.kube._retrieve_k8s_master_url') + @patch('magnum.objects.ReplicationController.get_by_uuid') + def test_rc_delete_with_success(self, + mock_rc_get_by_uuid, + mock_retrieve_k8s_master_url, + mock_object_has_stack): + expected_master_url = 'master_address' + mock_rc = mock.MagicMock() + mock_rc.name = 'test-rc' + mock_rc.uuid = 'test-uuid' + mock_rc_get_by_uuid.return_value = mock_rc + + mock_retrieve_k8s_master_url.return_value = expected_master_url + mock_object_has_stack.return_value = True + with patch.object(self.kube_handler, 'kube_cli') as mock_kube_cli: + mock_kube_cli.rc_stop.return_value = True + + self.kube_handler.rc_delete(self.context, mock_rc.uuid) + + mock_kube_cli.rc_stop.assert_called_once_with( + expected_master_url, mock_rc.name) + mock_rc.destroy.assert_called_once_with(self.context)