Merge lp:~adam-collard/charm-helpers/sysv-service-pause into lp:charm-helpers

Proposed by Adam Collard
Status: Merged
Merged at revision: 443
Proposed branch: lp:~adam-collard/charm-helpers/sysv-service-pause
Merge into: lp:charm-helpers
Diff against target: 176 lines (+106/-23)
2 files modified
charmhelpers/core/host.py (+32/-16)
tests/core/test_host.py (+74/-7)
To merge this branch: bzr merge lp:~adam-collard/charm-helpers/sysv-service-pause
Reviewer Review Type Date Requested Status
Chris Glass (community) Approve
Alberto Donato (community) Approve
Review via email: mp+270373@code.launchpad.net

Description of the change

Adds support for SysV init scripts to service_pause() and service_resume().

Detection of Upstart vs. SysV init matches that in contrib/charmsupport/nrpe.py. SystemD is left as an exercise for the future, but we'll at least note its absence by raising an exception when we fail to identify either Upstart or SysV.

To post a comment you must log in.
Revision history for this message
Alberto Donato (ack) wrote :

+1, nice

review: Approve
Revision history for this message
Adam Collard (adam-collard) :
Revision history for this message
Chris Glass (tribaal) wrote :

Looks great! Thanks! +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/core/host.py'
2--- charmhelpers/core/host.py 2015-08-18 21:06:39 +0000
3+++ charmhelpers/core/host.py 2015-09-08 09:56:04 +0000
4@@ -63,32 +63,48 @@
5 return service_result
6
7
8-def service_pause(service_name, init_dir=None):
9+def service_pause(service_name, init_dir="/etc/init", initd_dir="/etc/init.d"):
10 """Pause a system service.
11
12 Stop it, and prevent it from starting again at boot."""
13- if init_dir is None:
14- init_dir = "/etc/init"
15 stopped = service_stop(service_name)
16- # XXX: Support systemd too
17- override_path = os.path.join(
18- init_dir, '{}.override'.format(service_name))
19- with open(override_path, 'w') as fh:
20- fh.write("manual\n")
21+ upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
22+ sysv_file = os.path.join(initd_dir, service_name)
23+ if os.path.exists(upstart_file):
24+ override_path = os.path.join(
25+ init_dir, '{}.override'.format(service_name))
26+ with open(override_path, 'w') as fh:
27+ fh.write("manual\n")
28+ elif os.path.exists(sysv_file):
29+ subprocess.check_call(["update-rc.d", service_name, "disable"])
30+ else:
31+ # XXX: Support SystemD too
32+ raise ValueError(
33+ "Unable to detect {0} as either Upstart {1} or SysV {2}".format(
34+ service_name, upstart_file, sysv_file))
35 return stopped
36
37
38-def service_resume(service_name, init_dir=None):
39+def service_resume(service_name, init_dir="/etc/init",
40+ initd_dir="/etc/init.d"):
41 """Resume a system service.
42
43 Reenable starting again at boot. Start the service"""
44- # XXX: Support systemd too
45- if init_dir is None:
46- init_dir = "/etc/init"
47- override_path = os.path.join(
48- init_dir, '{}.override'.format(service_name))
49- if os.path.exists(override_path):
50- os.unlink(override_path)
51+ upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
52+ sysv_file = os.path.join(initd_dir, service_name)
53+ if os.path.exists(upstart_file):
54+ override_path = os.path.join(
55+ init_dir, '{}.override'.format(service_name))
56+ if os.path.exists(override_path):
57+ os.unlink(override_path)
58+ elif os.path.exists(sysv_file):
59+ subprocess.check_call(["update-rc.d", service_name, "enable"])
60+ else:
61+ # XXX: Support SystemD too
62+ raise ValueError(
63+ "Unable to detect {0} as either Upstart {1} or SysV {2}".format(
64+ service_name, upstart_file, sysv_file))
65+
66 started = service_start(service_name)
67 return started
68
69
70=== modified file 'tests/core/test_host.py'
71--- tests/core/test_host.py 2015-08-18 20:52:11 +0000
72+++ tests/core/test_host.py 2015-09-08 09:56:04 +0000
73@@ -108,10 +108,14 @@
74 service.assert_called_with('restart', service_name)
75
76 @patch.object(host, 'service')
77- def test_pauses_a_service(self, service):
78+ def test_pauses_an_upstart_service(self, service):
79 service_name = 'foo-service'
80 service.side_effect = [True]
81- tempdir = mkdtemp(prefix="test_pauses_a_service")
82+ tempdir = mkdtemp(prefix="test_pauses_an_upstart_service")
83+ conf_path = os.path.join(tempdir, "{}.conf".format(service_name))
84+ # Just needs to exist
85+ with open(conf_path, "w") as fh:
86+ fh.write("")
87 self.addCleanup(rmtree, tempdir)
88 self.assertTrue(host.service_pause(service_name, init_dir=tempdir))
89
90@@ -122,11 +126,44 @@
91 override_contents = fh.read()
92 self.assertEqual("manual\n", override_contents)
93
94- @patch.object(host, 'service')
95- def test_resumes_a_service(self, service):
96- service_name = 'foo-service'
97- service.side_effect = [True]
98- tempdir = mkdtemp(prefix="test_resumes_a_service")
99+ @patch('subprocess.check_call')
100+ @patch.object(host, 'service')
101+ def test_pauses_a_sysv_service(self, service, check_call):
102+ service_name = 'foo-service'
103+ service.side_effect = [True]
104+ tempdir = mkdtemp(prefix="test_pauses_a_sysv_service")
105+ sysv_path = os.path.join(tempdir, service_name)
106+ # Just needs to exist
107+ with open(sysv_path, "w") as fh:
108+ fh.write("")
109+ self.addCleanup(rmtree, tempdir)
110+ self.assertTrue(host.service_pause(
111+ service_name, init_dir=tempdir, initd_dir=tempdir))
112+
113+ service.assert_called_with('stop', service_name)
114+ check_call.assert_called_with(["update-rc.d", service_name, "disable"])
115+
116+ @patch.object(host, 'service')
117+ def test_pause_with_unknown_service(self, service):
118+ service_name = 'foo-service'
119+ service.side_effect = [True]
120+ tempdir = mkdtemp(prefix="test_pauses_with_unknown_service")
121+ self.addCleanup(rmtree, tempdir)
122+ exception = self.assertRaises(
123+ ValueError, host.service_pause,
124+ service_name, init_dir=tempdir, initd_dir=tempdir)
125+ self.assertIn(
126+ "Unable to detect {0}".format(service_name), str(exception))
127+ self.assertIn(tempdir, str(exception))
128+
129+ @patch.object(host, 'service')
130+ def test_resumes_an_upstart_service(self, service):
131+ service_name = 'foo-service'
132+ service.side_effect = [True]
133+ tempdir = mkdtemp(prefix="test_resumes_an_upstart_service")
134+ conf_path = os.path.join(tempdir, "{}.conf".format(service_name))
135+ with open(conf_path, "w") as fh:
136+ fh.write("")
137 self.addCleanup(rmtree, tempdir)
138 self.assertTrue(host.service_resume(service_name, init_dir=tempdir))
139
140@@ -135,6 +172,36 @@
141 tempdir, "{}.override".format(service_name))
142 self.assertFalse(os.path.exists(override_path))
143
144+ @patch('subprocess.check_call')
145+ @patch.object(host, 'service')
146+ def test_resumes_a_sysv_service(self, service, check_call):
147+ service_name = 'foo-service'
148+ service.side_effect = [True]
149+ tempdir = mkdtemp(prefix="test_resumes_a_sysv_service")
150+ sysv_path = os.path.join(tempdir, service_name)
151+ # Just needs to exist
152+ with open(sysv_path, "w") as fh:
153+ fh.write("")
154+ self.addCleanup(rmtree, tempdir)
155+ self.assertTrue(host.service_resume(
156+ service_name, init_dir=tempdir, initd_dir=tempdir))
157+
158+ service.assert_called_with('start', service_name)
159+ check_call.assert_called_with(["update-rc.d", service_name, "enable"])
160+
161+ @patch.object(host, 'service')
162+ def test_resume_with_unknown_service(self, service):
163+ service_name = 'foo-service'
164+ service.side_effect = [True]
165+ tempdir = mkdtemp(prefix="test_resumes_with_unknown_service")
166+ self.addCleanup(rmtree, tempdir)
167+ exception = self.assertRaises(
168+ ValueError, host.service_resume,
169+ service_name, init_dir=tempdir, initd_dir=tempdir)
170+ self.assertIn(
171+ "Unable to detect {0}".format(service_name), str(exception))
172+ self.assertIn(tempdir, str(exception))
173+
174 @patch.object(host, 'service')
175 def test_reloads_a_service(self, service):
176 service_name = 'foo-service'

Subscribers

People subscribed via source and target branches