From 9abdd337b5146643084205ad949c017b6ab843a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cumplido?= Date: Mon, 3 Nov 2014 22:46:01 +0000 Subject: [PATCH] Add signal in the kill CLI commando to send a specific signal to the service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raúl Cumplido --- docs/cli.md | 4 +++- fig/cli/main.py | 10 ++++++++-- fig/container.py | 4 ++-- tests/integration/cli_test.py | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/docs/cli.md b/docs/cli.md index 4462575df..822f1b780 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -42,7 +42,9 @@ Get help on a command. ### kill -Force stop service containers. +Force stop running containers by sending a `SIGKILL` signal. Optionally the signal can be passed, for example: + + $ fig kill -s SIGINT ### logs diff --git a/fig/cli/main.py b/fig/cli/main.py index 2ce8cfc32..2f83c1639 100644 --- a/fig/cli/main.py +++ b/fig/cli/main.py @@ -133,9 +133,15 @@ class TopLevelCommand(Command): """ Force stop service containers. - Usage: kill [SERVICE...] + Usage: kill [options] [SERVICE...] + + Options: + -s SIGNAL SIGNAL to send to the container. + Default signal is SIGKILL. """ - project.kill(service_names=options['SERVICE']) + signal = options.get('-s', 'SIGKILL') + + project.kill(service_names=options['SERVICE'], signal=signal) def logs(self, project, options): """ diff --git a/fig/container.py b/fig/container.py index 7e06bde35..0ab755120 100644 --- a/fig/container.py +++ b/fig/container.py @@ -124,8 +124,8 @@ class Container(object): def stop(self, **options): return self.client.stop(self.id, **options) - def kill(self): - return self.client.kill(self.id) + def kill(self, **options): + return self.client.kill(self.id, **options) def restart(self): return self.client.restart(self.id) diff --git a/tests/integration/cli_test.py b/tests/integration/cli_test.py index ceb93f62b..76c0df0f4 100644 --- a/tests/integration/cli_test.py +++ b/tests/integration/cli_test.py @@ -84,6 +84,7 @@ class CLITestCase(DockerClientTestCase): self.command.dispatch(['build', '--no-cache', 'simple'], None) output = mock_stdout.getvalue() self.assertNotIn(cache_indicator, output) + def test_up(self): self.command.dispatch(['up', '-d'], None) service = self.project.get_service('simple') @@ -244,6 +245,40 @@ class CLITestCase(DockerClientTestCase): self.command.dispatch(['rm', '--force'], None) self.assertEqual(len(service.containers(stopped=True)), 0) + def test_kill(self): + self.command.dispatch(['up', '-d'], None) + service = self.project.get_service('simple') + self.assertEqual(len(service.containers()), 1) + self.assertTrue(service.containers()[0].is_running) + + self.command.dispatch(['kill'], None) + + self.assertEqual(len(service.containers(stopped=True)), 1) + self.assertFalse(service.containers(stopped=True)[0].is_running) + + def test_kill_signal_sigint(self): + self.command.dispatch(['up', '-d'], None) + service = self.project.get_service('simple') + self.assertEqual(len(service.containers()), 1) + self.assertTrue(service.containers()[0].is_running) + + self.command.dispatch(['kill', '-s', 'SIGINT'], None) + + self.assertEqual(len(service.containers()), 1) + # The container is still running. It has been only interrupted + self.assertTrue(service.containers()[0].is_running) + + def test_kill_interrupted_service(self): + self.command.dispatch(['up', '-d'], None) + service = self.project.get_service('simple') + self.command.dispatch(['kill', '-s', 'SIGINT'], None) + self.assertTrue(service.containers()[0].is_running) + + self.command.dispatch(['kill', '-s', 'SIGKILL'], None) + + self.assertEqual(len(service.containers(stopped=True)), 1) + self.assertFalse(service.containers(stopped=True)[0].is_running) + def test_restart(self): service = self.project.get_service('simple') container = service.create_container()