Merge lp:~bloodearnest/charms/trusty/apache2/fix-mpm-type into lp:charms/trusty/apache2

Proposed by Simon Davy
Status: Merged
Merged at revision: 65
Proposed branch: lp:~bloodearnest/charms/trusty/apache2/fix-mpm-type
Merge into: lp:charms/trusty/apache2
Diff against target: 162 lines (+98/-10)
5 files modified
Makefile (+2/-1)
hooks/hooks.py (+41/-6)
hooks/tests/test_config_changed.py (+3/-2)
tests/10-bundles-test.py (+1/-1)
tests/20-mpm-test.py (+51/-0)
To merge this branch: bzr merge lp:~bloodearnest/charms/trusty/apache2/fix-mpm-type
Reviewer Review Type Date Requested Status
Tom Haddon Approve
Review via email: mp+252916@code.launchpad.net

Commit message

Fixes configuration of mpm_type is broken on trusty.

Description of the change

Fixes configuration of mpm_type is broken on trusty, which is broken completely.

Apache 2.4 on trusty defaults to mpm_event, and all mpm modules are compiled in, and require explicit a2en/dismodding. The charm was written for precise, and just purged/installed apache2-mpm-{type} package to a) install the module and b) switch the worker type.

In trusty, these packages are just transitional packages that install nothing and do not switch modules.

This change refactors the mpm management to work on trusty, and adds amulet test coverage for *all three* worker types (previously, mpm_event was *not* supported).

To post a comment you must log in.
68. By Simon Davy

make trusty only

Revision history for this message
Tom Haddon (mthaddon) wrote :

Looks good. I've confirmed the issue with the current charm, and that upgrading to this version fixes it so that setting the mpm_type config variable works as expected.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2015-03-09 16:32:43 +0000
+++ Makefile 2015-03-13 16:05:28 +0000
@@ -28,7 +28,8 @@
2828
29lint:29lint:
30 @echo Checking for Python syntax...30 @echo Checking for Python syntax...
31 @flake8 $(HOOKS_DIR) --ignore=E123 --exclude=$(HOOKS_DIR)/charmhelpers && echo OK31 @flake8 $(HOOKS_DIR) --ignore=E123 --exclude=$(HOOKS_DIR)/charmhelpers && echo hooks OK
32 @flake8 tests --ignore=E123 && echo tests OK
3233
33sourcedeps: $(PWD)/config-manager.txt34sourcedeps: $(PWD)/config-manager.txt
34 @echo Updating source dependencies...35 @echo Updating source dependencies...
3536
=== modified file 'hooks/hooks.py'
--- hooks/hooks.py 2015-03-10 19:10:28 +0000
+++ hooks/hooks.py 2015-03-13 16:05:28 +0000
@@ -542,6 +542,45 @@
542 return True542 return True
543543
544544
545MPM_TYPES = ['mpm_worker', 'mpm_prefork', 'mpm_event']
546
547
548def enable_mpm(config):
549 """Enables a particular mpm module.
550
551 Different from simply enabling a module, as one and only one mpm module
552 *must* be enabled.
553 """
554 # only do anything if value has changed, to avoid a needless restart
555 if not config.changed('mpm_type'):
556 return
557
558 mpm_type = config.get('mpm_type', '')
559 name = 'mpm_' + mpm_type
560 if name not in MPM_TYPES:
561 log('bad mpm_type: %s. Falling back to mpm_worker' % mpm_type)
562 name = 'mpm_worker'
563
564 # disable all other mpm modules
565 for mpm in MPM_TYPES:
566 if mpm != name:
567 return_value = subprocess.call(['/usr/sbin/a2dismod', mpm])
568 if return_value != 0:
569 return False
570
571 return_value = subprocess.call(['/usr/sbin/a2enmod', name])
572 if return_value != 0:
573 return False
574
575 if service_apache2("check"):
576 log("Switching mpm module to {}".format(name))
577 service_apache2("restart") # must be a restart to switch mpm
578 return True
579 else:
580 log("Failed to switch mpm module to {}".format(name))
581 return False
582
583
545def config_changed():584def config_changed():
546 relationship_data = {}585 relationship_data = {}
547 config_data = config_get()586 config_data = config_get()
@@ -567,12 +606,8 @@
567 for module in module_list:606 for module in module_list:
568 disable_module(module)607 disable_module(module)
569608
570 if config_data['mpm_type'] == 'worker':609 enable_mpm(config_data)
571 apt_get_install('apache2-mpm-worker')610 # XXX we only configure the worker mpm?
572 apt_get_purge('apache2-mpm-prefork')
573 elif config_data['mpm_type'] == 'prefork':
574 apt_get_install('apache2-mpm-prefork')
575 apt_get_purge('apache2-mpm-worker')
576 create_mpm_workerfile()611 create_mpm_workerfile()
577 create_security()612 create_security()
578613
579614
=== modified file 'hooks/tests/test_config_changed.py'
--- hooks/tests/test_config_changed.py 2015-03-10 19:10:28 +0000
+++ hooks/tests/test_config_changed.py 2015-03-13 16:05:28 +0000
@@ -36,9 +36,10 @@
36 @patch('hooks.get_reverseproxy_data')36 @patch('hooks.get_reverseproxy_data')
37 @patch('hooks.service_apache2')37 @patch('hooks.service_apache2')
38 @patch('hooks.relation_set')38 @patch('hooks.relation_set')
39 @patch('hooks.enable_mpm')
39 def test_config_changed_ensure_empty_site_dir(40 def test_config_changed_ensure_empty_site_dir(
40 self, mock_relation_set, mock_service_apache2,41 self, mock_enable_mpm, mock_relation_set,
41 mock_reverseproxy, mock_config_get,42 mock_service_apache2, mock_reverseproxy, mock_config_get,
42 mock_relations_of_type, mock_relation_ids, mock_log,43 mock_relations_of_type, mock_relation_ids, mock_log,
43 mock_create_mpm_workerfile, mock_create_security, mock_run,44 mock_create_mpm_workerfile, mock_create_security, mock_run,
44 mock_update_nrpe_checks, mock_ship_logrotate_conf,45 mock_update_nrpe_checks, mock_ship_logrotate_conf,
4546
=== modified file 'tests/10-bundles-test.py'
--- tests/10-bundles-test.py 2014-10-29 00:10:14 +0000
+++ tests/10-bundles-test.py 2015-03-13 16:05:28 +0000
@@ -30,4 +30,4 @@
3030
3131
32if __name__ == '__main__':32if __name__ == '__main__':
33 unittest.main()
34\ No newline at end of file33\ No newline at end of file
34 unittest.main()
3535
=== added file 'tests/20-mpm-test.py'
--- tests/20-mpm-test.py 1970-01-01 00:00:00 +0000
+++ tests/20-mpm-test.py 2015-03-13 16:05:28 +0000
@@ -0,0 +1,51 @@
1#!/usr/bin/env python3
2import os
3import time
4import unittest
5import amulet
6
7
8class BundleTest(unittest.TestCase):
9 """ Create a class for testing the charm in the unit test framework. """
10 @classmethod
11 def setUpClass(cls):
12 """ Set up an amulet deployment using the bundle. """
13 d = amulet.Deployment(series='trusty')
14 d.add('apache2', os.path.join(os.path.dirname(__file__), os.pardir))
15 d.setup(180)
16 cls.d = d
17 cls.unit = d.sentry.unit['apache2/0']
18 output, code = cls.unit.run('curl localhost')
19
20 def assert_mpm(self, mpm):
21 cmd = (". /etc/apache2/envvars && apache2 -V 2>/dev/null "
22 "| grep MPM | awk -F: '{print $2}' | xargs")
23 self.d.configure('apache2', {'mpm_type': mpm})
24 self.d.sentry.wait()
25 # the above doesn't seem to work
26 time.sleep(10)
27 # enable default web site so we can check for a valid config
28 output, code = self.unit.run(
29 'a2ensite 000-default.conf && service apache2 reload')
30 time.sleep(10)
31 # enable default web site so we can check for a valid config
32 output, code = self.unit.run(cmd)
33 self.assertEqual(code, 0)
34 self.assertIn(mpm, output)
35 output, code = self.unit.run('curl localhost')
36 if code != 0:
37 raise Exception(output)
38 self.assertEqual(code, 0)
39
40 def test_mpm_worker(self):
41 self.assert_mpm('worker')
42
43 def test_mpm_prefork(self):
44 self.assert_mpm('prefork')
45
46 def test_mpm_event(self):
47 self.assert_mpm('event')
48
49
50if __name__ == '__main__':
51 unittest.main()

Subscribers

People subscribed via source and target branches

to all changes: