Merge lp:~hloeung/ubuntu-repository-cache/only-reload-apache2-when-needed into lp:ubuntu-repository-cache
- only-reload-apache2-when-needed
- Merge into layer-ubuntu-repository-cache
Proposed by
Haw Loeung
Status: | Merged |
---|---|
Approved by: | Haw Loeung |
Approved revision: | 338 |
Merged at revision: | 316 |
Proposed branch: | lp:~hloeung/ubuntu-repository-cache/only-reload-apache2-when-needed |
Merge into: | lp:ubuntu-repository-cache |
Diff against target: |
544 lines (+278/-87) 4 files modified
.bzrignore (+1/-0) .coveragerc (+2/-0) lib/ubuntu_repository_cache/apache.py (+111/-45) tests/unit/test_apache.py (+164/-42) |
To merge this branch: | bzr merge lp:~hloeung/ubuntu-repository-cache/only-reload-apache2-when-needed |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Joel Sing (community) | +1 | Approve | |
Canonical IS Reviewers | Pending | ||
Review via email: mp+398325@code.launchpad.net |
Commit message
Only reload/graceful apache2 when required - LP:1916084
Description of the change
To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
- 333. By Haw Loeung
-
Ignore .juju-persisten
t-config used with config.save()
Revision history for this message
Joel Sing (jsing) wrote : | # |
Generally looks good, but see comments inline.
- 334. By Haw Loeung
-
Don't call apache.start() in service.unpause()
- 335. By Haw Loeung
-
Merge upstream changes
- 336. By Haw Loeung
-
Reworked configure_
remoteip( ) and enable module on install - 337. By Haw Loeung
-
Fixed based on review
Revision history for this message
Haw Loeung (hloeung) : | # |
- 338. By Haw Loeung
-
Fixed to use one set of config keys to retrieve values and check config.changed() as per review
Revision history for this message
Haw Loeung (hloeung) wrote : | # |
> Generally looks good, but see comments inline.
Okay, all addressed. Thanks for the review.
Revision history for this message
Haw Loeung (hloeung) : | # |
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change successfully merged at revision 316
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' | |||
2 | --- .bzrignore 2020-05-07 05:29:31 +0000 | |||
3 | +++ .bzrignore 2021-02-22 22:51:46 +0000 | |||
4 | @@ -1,6 +1,7 @@ | |||
5 | 1 | *.pyc | 1 | *.pyc |
6 | 2 | *.swp | 2 | *.swp |
7 | 3 | *~ | 3 | *~ |
8 | 4 | .juju-persistent-config | ||
9 | 4 | .unit-state.db | 5 | .unit-state.db |
10 | 5 | lib/test.py | 6 | lib/test.py |
11 | 6 | .venv | 7 | .venv |
12 | 7 | 8 | ||
13 | === added file '.coveragerc' | |||
14 | --- .coveragerc 1970-01-01 00:00:00 +0000 | |||
15 | +++ .coveragerc 2021-02-22 22:51:46 +0000 | |||
16 | @@ -0,0 +1,2 @@ | |||
17 | 1 | [run] | ||
18 | 2 | omit = lib/ubuntu_repository_cache/tests/* | ||
19 | 0 | 3 | ||
20 | === modified file 'lib/ubuntu_repository_cache/apache.py' | |||
21 | --- lib/ubuntu_repository_cache/apache.py 2021-02-22 03:11:12 +0000 | |||
22 | +++ lib/ubuntu_repository_cache/apache.py 2021-02-22 22:51:46 +0000 | |||
23 | @@ -41,6 +41,8 @@ | |||
24 | 41 | config = hookenv.config() | 41 | config = hookenv.config() |
25 | 42 | if config['enable_healthcheck']: | 42 | if config['enable_healthcheck']: |
26 | 43 | subprocess.check_call(['a2enmod', 'cgid']) | 43 | subprocess.check_call(['a2enmod', 'cgid']) |
27 | 44 | if config['remoteip_logging']: | ||
28 | 45 | subprocess.check_call(['a2enmod', 'remoteip']) | ||
29 | 44 | 46 | ||
30 | 45 | start() | 47 | start() |
31 | 46 | 48 | ||
32 | @@ -123,20 +125,37 @@ | |||
33 | 123 | return config | 125 | return config |
34 | 124 | 126 | ||
35 | 125 | 127 | ||
37 | 126 | def create_mpm_workerfile(): | 128 | def create_mpm_workerfile(config=None): |
38 | 127 | '''Create the multi-processing module (MPM) configuration''' | 129 | '''Create the multi-processing module (MPM) configuration''' |
39 | 128 | 130 | ||
51 | 129 | config = hookenv.config() | 131 | reload_required = False |
52 | 130 | mpm_context = { | 132 | |
53 | 131 | 'startservers': config['apache2_mpm_startservers'], | 133 | if not config: |
54 | 132 | 'minsparethreads': config['apache2_mpm_minsparethreads'], | 134 | config = hookenv.config() |
55 | 133 | 'maxsparethreads': config['apache2_mpm_maxsparethreads'], | 135 | |
56 | 134 | 'threadlimit': config['apache2_mpm_threadlimit'], | 136 | mpm_configs = [ |
57 | 135 | 'threadsperchild': config['apache2_mpm_threadsperchild'], | 137 | 'maxconnectionsperchild', |
58 | 136 | 'serverlimit': config['apache2_mpm_serverlimit'], | 138 | 'maxrequestworkers', |
59 | 137 | 'maxrequestworkers': config['apache2_mpm_maxrequestworkers'], | 139 | 'maxsparethreads', |
60 | 138 | 'maxconnectionsperchild': config['apache2_mpm_maxconnectionsperchild'], | 140 | 'minsparethreads', |
61 | 139 | } | 141 | 'serverlimit', |
62 | 142 | 'startservers', | ||
63 | 143 | 'threadlimit', | ||
64 | 144 | 'threadsperchild', | ||
65 | 145 | ] | ||
66 | 146 | mpm_context = {} | ||
67 | 147 | for k in mpm_configs: | ||
68 | 148 | cfkey = 'apache2_mpm_{}'.format(k) | ||
69 | 149 | mpm_context[k] = config[cfkey] | ||
70 | 150 | if config.changed(cfkey): | ||
71 | 151 | reload_required = True | ||
72 | 152 | |||
73 | 153 | # We'll only proceed when any one of the MPM configs have changed. | ||
74 | 154 | if not reload_required: | ||
75 | 155 | return reload_required | ||
76 | 156 | |||
77 | 157 | reload_required = True | ||
78 | 158 | |||
79 | 140 | mpm_context = tune_mpm_configs(mpm_context) | 159 | mpm_context = tune_mpm_configs(mpm_context) |
80 | 141 | conf_mpm_worker = '/etc/apache2/conf-available/000mpm-worker.conf' | 160 | conf_mpm_worker = '/etc/apache2/conf-available/000mpm-worker.conf' |
81 | 142 | templating.render('apache2/mpm_worker.template', conf_mpm_worker, mpm_context) | 161 | templating.render('apache2/mpm_worker.template', conf_mpm_worker, mpm_context) |
82 | @@ -148,24 +167,44 @@ | |||
83 | 148 | os.unlink(mods_mpm_worker) | 167 | os.unlink(mods_mpm_worker) |
84 | 149 | os.symlink(conf_mpm_worker, mods_mpm_worker) | 168 | os.symlink(conf_mpm_worker, mods_mpm_worker) |
85 | 150 | 169 | ||
88 | 151 | 170 | return reload_required | |
89 | 152 | def create_security(): | 171 | |
90 | 172 | |||
91 | 173 | def create_security(config=None): | ||
92 | 153 | '''Create the security configuration''' | 174 | '''Create the security configuration''' |
93 | 154 | 175 | ||
100 | 155 | config = hookenv.config() | 176 | reload_required = False |
101 | 156 | security_context = { | 177 | |
102 | 157 | 'server_tokens': config['apache2_server_tokens'], | 178 | if not config: |
103 | 158 | 'server_signature': config['apache2_server_signature'], | 179 | config = hookenv.config() |
104 | 159 | 'trace_enabled': config['apache2_trace_enabled'], | 180 | |
105 | 160 | } | 181 | security_configs = ['server_signature', 'server_tokens', 'trace_enabled'] |
106 | 182 | security_context = {} | ||
107 | 183 | for k in security_configs: | ||
108 | 184 | cfkey = 'apache2_{}'.format(k) | ||
109 | 185 | security_context[k] = config[cfkey] | ||
110 | 186 | if config.changed(cfkey): | ||
111 | 187 | reload_required = True | ||
112 | 188 | |||
113 | 189 | # We'll only proceed when any one of the MPM configs have changed. | ||
114 | 190 | if not reload_required: | ||
115 | 191 | return reload_required | ||
116 | 192 | |||
117 | 193 | reload_required = True | ||
118 | 194 | |||
119 | 161 | templating.render('apache2/security.template', '/etc/apache2/conf-available/security.conf', security_context) | 195 | templating.render('apache2/security.template', '/etc/apache2/conf-available/security.conf', security_context) |
120 | 162 | subprocess.check_call(['a2enconf', 'security']) | 196 | subprocess.check_call(['a2enconf', 'security']) |
124 | 163 | 197 | return reload_required | |
125 | 164 | 198 | ||
126 | 165 | def create_metadata_site(): | 199 | |
127 | 200 | def create_metadata_site(config=None, apache2_conf_path='/etc/apache2'): | ||
128 | 166 | '''Create the site config for serving (or proxying) repository metadata''' | 201 | '''Create the site config for serving (or proxying) repository metadata''' |
129 | 167 | 202 | ||
131 | 168 | config = hookenv.config() | 203 | reload_required = False |
132 | 204 | |||
133 | 205 | if not config: | ||
134 | 206 | config = hookenv.config() | ||
135 | 207 | |||
136 | 169 | apache_context = {} | 208 | apache_context = {} |
137 | 170 | apache_context['DocumentRoot'] = unitdata.kv().get('apache-root') | 209 | apache_context['DocumentRoot'] = unitdata.kv().get('apache-root') |
138 | 171 | apache_context['Sync_Host'] = config['sync-host'] | 210 | apache_context['Sync_Host'] = config['sync-host'] |
139 | @@ -188,38 +227,62 @@ | |||
140 | 188 | apache_context['MetadataProxy'] = metaproxy_conf | 227 | apache_context['MetadataProxy'] = metaproxy_conf |
141 | 189 | apache_context['Enable_Healthcheck'] = config['enable_healthcheck'] | 228 | apache_context['Enable_Healthcheck'] = config['enable_healthcheck'] |
142 | 190 | 229 | ||
148 | 191 | templating.render( | 230 | apache_config_file = os.path.join(apache2_conf_path, 'sites-available', 'archive_ubuntu_com.conf') |
149 | 192 | 'apache2/archive_ubuntu_com.conf', '/etc/apache2/sites-available/archive_ubuntu_com.conf', apache_context | 231 | cur_conf = '' |
150 | 193 | ) | 232 | if os.path.exists(apache_config_file): |
151 | 194 | subprocess.call(['a2ensite', 'archive_ubuntu_com']) | 233 | with open(apache_config_file) as f: |
152 | 195 | start() | 234 | cur_conf = f.read() |
153 | 235 | new_conf = templating.render('apache2/archive_ubuntu_com.conf', apache_config_file, apache_context) | ||
154 | 236 | |||
155 | 237 | if new_conf != cur_conf: | ||
156 | 238 | reload_required = True | ||
157 | 239 | if not os.path.exists(os.path.join(apache2_conf_path, 'sites-enabled', 'archive_ubuntu_com.conf')): | ||
158 | 240 | subprocess.call(['a2ensite', 'archive_ubuntu_com']) | ||
159 | 241 | |||
160 | 242 | return reload_required | ||
161 | 196 | 243 | ||
162 | 197 | 244 | ||
163 | 198 | @util.run_as_user('root') | 245 | @util.run_as_user('root') |
166 | 199 | def configure_remoteip_logging(): | 246 | def configure_remoteip_logging(config=None, apache2_conf_path='/etc/apache2'): |
167 | 200 | config = hookenv.config() | 247 | reload_required = False |
168 | 248 | |||
169 | 249 | if not config: | ||
170 | 250 | config = hookenv.config() | ||
171 | 251 | |||
172 | 252 | if config['remoteip_logging']: | ||
173 | 253 | apache_config_file = os.path.join(apache2_conf_path, 'conf-available', 'remoteip.conf') | ||
174 | 254 | cur_conf = '' | ||
175 | 255 | if os.path.exists(apache_config_file): | ||
176 | 256 | with open(apache_config_file) as f: | ||
177 | 257 | cur_conf = f.read() | ||
178 | 258 | new_conf = templating.render('apache2/remoteip.conf', apache_config_file, {}) | ||
179 | 259 | |||
180 | 260 | if new_conf != cur_conf: | ||
181 | 261 | reload_required = True | ||
182 | 262 | if not os.path.exists(os.path.join(apache2_conf_path, 'conf-enabled', 'remoteip.conf')): | ||
183 | 263 | subprocess.check_call(['a2enconf', 'remoteip']) | ||
184 | 264 | |||
185 | 201 | if config.changed('remoteip_logging'): | 265 | if config.changed('remoteip_logging'): |
186 | 202 | LOG('Apache remoteip_logging changed') | 266 | LOG('Apache remoteip_logging changed') |
188 | 203 | if config['remoteip_logging'] is True: | 267 | if config['remoteip_logging']: |
189 | 204 | subprocess.check_call(['a2enmod', 'remoteip']) | 268 | subprocess.check_call(['a2enmod', 'remoteip']) |
190 | 205 | templating.render('apache2/remoteip.conf', '/etc/apache2/conf-available/remoteip.conf', {}) | ||
191 | 206 | subprocess.check_call(['a2enconf', 'remoteip']) | ||
192 | 207 | LOG('Enabled remoteip logging') | 269 | LOG('Enabled remoteip logging') |
193 | 208 | else: | 270 | else: |
194 | 209 | subprocess.check_call(['a2dismod', 'remoteip']) | 271 | subprocess.check_call(['a2dismod', 'remoteip']) |
195 | 210 | if os.path.exists('/etc/apache2/conf-enabled/remoteip.conf'): | 272 | if os.path.exists('/etc/apache2/conf-enabled/remoteip.conf'): |
196 | 211 | subprocess.check_call(['a2disconf', 'remoteip']) | 273 | subprocess.check_call(['a2disconf', 'remoteip']) |
197 | 212 | LOG('Disabled remoteip logging') | 274 | LOG('Disabled remoteip logging') |
198 | 275 | reload_required = True | ||
199 | 213 | 276 | ||
201 | 214 | start() | 277 | return reload_required |
202 | 215 | 278 | ||
203 | 216 | 279 | ||
204 | 217 | def configure_health_check(config=None): | 280 | def configure_health_check(config=None): |
205 | 281 | reload_required = False | ||
206 | 282 | |||
207 | 218 | if not config: | 283 | if not config: |
208 | 219 | config = hookenv.config() | 284 | config = hookenv.config() |
209 | 220 | 285 | ||
210 | 221 | restart_required = False | ||
211 | 222 | |||
212 | 223 | if config.changed('enable_healthcheck'): | 286 | if config.changed('enable_healthcheck'): |
213 | 224 | LOG('Apache enable_healthcheck changed') | 287 | LOG('Apache enable_healthcheck changed') |
214 | 225 | if config['enable_healthcheck']: | 288 | if config['enable_healthcheck']: |
215 | @@ -231,7 +294,7 @@ | |||
216 | 231 | 294 | ||
217 | 232 | subprocess.check_call([cmd, 'cgid']) | 295 | subprocess.check_call([cmd, 'cgid']) |
218 | 233 | LOG('{} health check endpoint'.format(action)) | 296 | LOG('{} health check endpoint'.format(action)) |
220 | 234 | restart_required = True | 297 | reload_required = True |
221 | 235 | 298 | ||
222 | 236 | subprocess.call(['touch', HEALTH_CHECK_LOG]) | 299 | subprocess.call(['touch', HEALTH_CHECK_LOG]) |
223 | 237 | subprocess.call(['chown', HEALTH_CHECK_LOG_OWNER, HEALTH_CHECK_LOG]) | 300 | subprocess.call(['chown', HEALTH_CHECK_LOG_OWNER, HEALTH_CHECK_LOG]) |
224 | @@ -244,16 +307,19 @@ | |||
225 | 244 | content = f.read() | 307 | content = f.read() |
226 | 245 | host.write_file(path=healthcheck_script, content=content, perms=0o755) | 308 | host.write_file(path=healthcheck_script, content=content, perms=0o755) |
227 | 246 | 309 | ||
229 | 247 | return restart_required | 310 | return reload_required |
230 | 248 | 311 | ||
231 | 249 | 312 | ||
232 | 250 | @util.run_as_user('root') | 313 | @util.run_as_user('root') |
233 | 251 | def render_configs(): | 314 | def render_configs(): |
234 | 252 | '''Render the configuration templates for apache''' | 315 | '''Render the configuration templates for apache''' |
235 | 253 | 316 | ||
236 | 317 | reload_required = False | ||
237 | 318 | |||
238 | 254 | LOG('Rendering apache2 configuration templates') | 319 | LOG('Rendering apache2 configuration templates') |
239 | 255 | config = hookenv.config() | 320 | config = hookenv.config() |
240 | 256 | if config.changed('apache2_mpm_type'): | 321 | if config.changed('apache2_mpm_type'): |
241 | 322 | reload_required = True | ||
242 | 257 | if config['apache2_mpm_type'] == 'worker': | 323 | if config['apache2_mpm_type'] == 'worker': |
243 | 258 | LOG('Using apache2-mpm-worker') | 324 | LOG('Using apache2-mpm-worker') |
244 | 259 | subprocess.check_call(['a2dismod', 'mpm_prefork']) | 325 | subprocess.check_call(['a2dismod', 'mpm_prefork']) |
245 | @@ -264,13 +330,13 @@ | |||
246 | 264 | subprocess.check_call(['a2dismod', 'mpm_worker']) | 330 | subprocess.check_call(['a2dismod', 'mpm_worker']) |
247 | 265 | subprocess.check_call(['a2enmod', 'mpm_prefork']) | 331 | subprocess.check_call(['a2enmod', 'mpm_prefork']) |
248 | 266 | 332 | ||
254 | 267 | create_metadata_site() | 333 | reload_required = create_metadata_site() or reload_required |
255 | 268 | create_mpm_workerfile() | 334 | reload_required = create_mpm_workerfile() or reload_required |
256 | 269 | create_security() | 335 | reload_required = create_security() or reload_required |
257 | 270 | configure_remoteip_logging() | 336 | reload_required = configure_remoteip_logging() or reload_required |
258 | 271 | configure_health_check() | 337 | reload_required = configure_health_check() or reload_required |
259 | 272 | 338 | ||
261 | 273 | start() | 339 | start(start_only=(not reload_required)) |
262 | 274 | 340 | ||
263 | 275 | 341 | ||
264 | 276 | def update_checks(nrpe_config): | 342 | def update_checks(nrpe_config): |
265 | 277 | 343 | ||
266 | === modified file 'tests/unit/test_apache.py' | |||
267 | --- tests/unit/test_apache.py 2021-02-22 02:59:25 +0000 | |||
268 | +++ tests/unit/test_apache.py 2021-02-22 22:51:46 +0000 | |||
269 | @@ -43,11 +43,6 @@ | |||
270 | 43 | self.addCleanup(patcher.stop) | 43 | self.addCleanup(patcher.stop) |
271 | 44 | self.mock_local_unit.return_value = 'mock-ubuntu-repository-cache/0' | 44 | self.mock_local_unit.return_value = 'mock-ubuntu-repository-cache/0' |
272 | 45 | 45 | ||
273 | 46 | patcher = mock.patch('charmhelpers.core.hookenv.config') | ||
274 | 47 | self.mock_config = patcher.start() | ||
275 | 48 | self.addCleanup(patcher.stop) | ||
276 | 49 | self.mock_config.return_value = {'nagios_context': 'juju'} | ||
277 | 50 | |||
278 | 51 | patcher = mock.patch('charmhelpers.core.host.log') | 46 | patcher = mock.patch('charmhelpers.core.host.log') |
279 | 52 | self.mock_log = patcher.start() | 47 | self.mock_log = patcher.start() |
280 | 53 | self.addCleanup(patcher.stop) | 48 | self.addCleanup(patcher.stop) |
281 | @@ -65,46 +60,53 @@ | |||
282 | 65 | @mock.patch('subprocess.check_call') | 60 | @mock.patch('subprocess.check_call') |
283 | 66 | def test_configure_health_check(self, check_call, call, seteuid, setegid, chown, write_file): | 61 | def test_configure_health_check(self, check_call, call, seteuid, setegid, chown, write_file): |
284 | 67 | config = hookenv.Config({'enable_healthcheck': True}) | 62 | config = hookenv.Config({'enable_healthcheck': True}) |
286 | 68 | self.assertEqual(apache.configure_health_check(config), True) | 63 | self.assertTrue(apache.configure_health_check(config)) |
287 | 69 | check_call.assert_called_with(['a2enmod', 'cgid']) | 64 | check_call.assert_called_with(['a2enmod', 'cgid']) |
288 | 70 | 65 | ||
289 | 71 | check_call.reset_mock() | 66 | check_call.reset_mock() |
290 | 72 | config = hookenv.Config({'enable_healthcheck': False}) | 67 | config = hookenv.Config({'enable_healthcheck': False}) |
292 | 73 | self.assertEqual(apache.configure_health_check(config), True) | 68 | self.assertTrue(apache.configure_health_check(config)) |
293 | 74 | check_call.assert_called_with(['a2dismod', 'cgid']) | 69 | check_call.assert_called_with(['a2dismod', 'cgid']) |
294 | 75 | 70 | ||
295 | 71 | # No change | ||
296 | 76 | check_call.reset_mock() | 72 | check_call.reset_mock() |
297 | 77 | config = hookenv.Config({'enable_healthcheck': True}) | 73 | config = hookenv.Config({'enable_healthcheck': True}) |
298 | 78 | config.save() | 74 | config.save() |
299 | 79 | config = hookenv.Config({'enable_healthcheck': True}) | 75 | config = hookenv.Config({'enable_healthcheck': True}) |
301 | 80 | self.assertEqual(apache.configure_health_check(config), False) | 76 | self.assertFalse(apache.configure_health_check(config)) |
302 | 81 | 77 | ||
303 | 82 | @mock.patch('charmhelpers.core.templating.render') | ||
304 | 83 | @mock.patch('lib.ubuntu_repository_cache.apache.start') | 78 | @mock.patch('lib.ubuntu_repository_cache.apache.start') |
305 | 84 | @mock.patch('lib.ubuntu_repository_cache.util.get_failover_host') | 79 | @mock.patch('lib.ubuntu_repository_cache.util.get_failover_host') |
306 | 80 | @mock.patch('os.chown') | ||
307 | 81 | @mock.patch('os.fchown') | ||
308 | 85 | @mock.patch('subprocess.call') | 82 | @mock.patch('subprocess.call') |
310 | 86 | def test_create_metadata_site(self, call, get_failover_host, start, render): | 83 | def test_create_metadata_site(self, call, fchown, chown, get_failover_host, start): |
311 | 87 | get_failover_host.return_value = '10.1.1.1' | 84 | get_failover_host.return_value = '10.1.1.1' |
322 | 88 | self.mock_config.return_value = { | 85 | config = hookenv.Config( |
313 | 89 | 'display-host': 'archive.ubuntu.com', | ||
314 | 90 | 'enable_healthcheck': True, | ||
315 | 91 | 'path-base': 'ubuntu', | ||
316 | 92 | 'sync-host': 'us.archive.ubuntu.com', | ||
317 | 93 | } | ||
318 | 94 | apache.create_metadata_site() | ||
319 | 95 | render.assert_called_with( | ||
320 | 96 | 'apache2/archive_ubuntu_com.conf', | ||
321 | 97 | '/etc/apache2/sites-available/archive_ubuntu_com.conf', | ||
323 | 98 | { | 86 | { |
331 | 99 | 'DocumentRoot': os.path.join(self.tmpdir, 'apache'), | 87 | 'display-host': 'archive.ubuntu.com', |
332 | 100 | 'Sync_Host': 'us.archive.ubuntu.com', | 88 | 'enable_healthcheck': True, |
333 | 101 | 'Display_Host': 'archive.ubuntu.com', | 89 | 'path-base': 'ubuntu', |
334 | 102 | 'Path_Base': 'ubuntu', | 90 | 'sync-host': 'us.archive.ubuntu.com', |
335 | 103 | 'MetadataProxy': '# No failover configured', | 91 | } |
329 | 104 | 'Enable_Healthcheck': True, | ||
330 | 105 | }, | ||
336 | 106 | ) | 92 | ) |
337 | 93 | self.assertTrue(apache.create_metadata_site(config, apache2_conf_path=self.tmpdir)) | ||
338 | 107 | call.assert_called_with(['a2ensite', 'archive_ubuntu_com']) | 94 | call.assert_called_with(['a2ensite', 'archive_ubuntu_com']) |
339 | 95 | chown.assert_called() | ||
340 | 96 | |||
341 | 97 | # No change, no need to reload | ||
342 | 98 | call.reset_mock() | ||
343 | 99 | config.save() | ||
344 | 100 | config = hookenv.Config( | ||
345 | 101 | { | ||
346 | 102 | 'display-host': 'archive.ubuntu.com', | ||
347 | 103 | 'enable_healthcheck': True, | ||
348 | 104 | 'path-base': 'ubuntu', | ||
349 | 105 | 'sync-host': 'us.archive.ubuntu.com', | ||
350 | 106 | } | ||
351 | 107 | ) | ||
352 | 108 | self.assertFalse(apache.create_metadata_site(config, apache2_conf_path=self.tmpdir)) | ||
353 | 109 | call.assert_not_called() | ||
354 | 108 | 110 | ||
355 | 109 | @mock.patch('charmhelpers.core.templating.render') | 111 | @mock.patch('charmhelpers.core.templating.render') |
356 | 110 | @mock.patch('lib.ubuntu_repository_cache.apache.start') | 112 | @mock.patch('lib.ubuntu_repository_cache.apache.start') |
357 | @@ -113,12 +115,14 @@ | |||
358 | 113 | @mock.patch('os.mknod') | 115 | @mock.patch('os.mknod') |
359 | 114 | @mock.patch('subprocess.call') | 116 | @mock.patch('subprocess.call') |
360 | 115 | def test_create_metadata_site_in_failover(self, call, mknod, in_failover, get_failover_host, start, render): | 117 | def test_create_metadata_site_in_failover(self, call, mknod, in_failover, get_failover_host, start, render): |
367 | 116 | self.mock_config.return_value = { | 118 | config = hookenv.Config( |
368 | 117 | 'display-host': 'archive.ubuntu.com', | 119 | { |
369 | 118 | 'enable_healthcheck': True, | 120 | 'display-host': 'archive.ubuntu.com', |
370 | 119 | 'path-base': 'ubuntu', | 121 | 'enable_healthcheck': True, |
371 | 120 | 'sync-host': 'us.archive.ubuntu.com', | 122 | 'path-base': 'ubuntu', |
372 | 121 | } | 123 | 'sync-host': 'us.archive.ubuntu.com', |
373 | 124 | } | ||
374 | 125 | ) | ||
375 | 122 | get_failover_host.return_value = '10.1.1.1' | 126 | get_failover_host.return_value = '10.1.1.1' |
376 | 123 | in_failover.return_value = True | 127 | in_failover.return_value = True |
377 | 124 | 128 | ||
378 | @@ -127,7 +131,7 @@ | |||
379 | 127 | os.mkdir(os.path.join(self.tmpdir, 'apache')) | 131 | os.mkdir(os.path.join(self.tmpdir, 'apache')) |
380 | 128 | os.mkdir(health_check_path) | 132 | os.mkdir(health_check_path) |
381 | 129 | 133 | ||
383 | 130 | apache.create_metadata_site() | 134 | apache.create_metadata_site(config) |
384 | 131 | mknod.assert_called_with(disabled_flag) | 135 | mknod.assert_called_with(disabled_flag) |
385 | 132 | render.assert_called_with( | 136 | render.assert_called_with( |
386 | 133 | 'apache2/archive_ubuntu_com.conf', | 137 | 'apache2/archive_ubuntu_com.conf', |
387 | @@ -148,7 +152,7 @@ | |||
388 | 148 | # If the disabled flag exists, no need to create it. | 152 | # If the disabled flag exists, no need to create it. |
389 | 149 | mknod.reset_mock() | 153 | mknod.reset_mock() |
390 | 150 | open(disabled_flag, 'a').close() | 154 | open(disabled_flag, 'a').close() |
392 | 151 | apache.create_metadata_site() | 155 | apache.create_metadata_site(config) |
393 | 152 | mknod.assert_not_called() | 156 | mknod.assert_not_called() |
394 | 153 | 157 | ||
395 | 154 | @mock.patch('charmhelpers.core.templating.render') | 158 | @mock.patch('charmhelpers.core.templating.render') |
396 | @@ -157,19 +161,21 @@ | |||
397 | 157 | @mock.patch('os.unlink') | 161 | @mock.patch('os.unlink') |
398 | 158 | @mock.patch('subprocess.call') | 162 | @mock.patch('subprocess.call') |
399 | 159 | def test_create_metadata_site_no_failover(self, call, unlink, get_failover_host, start, render): | 163 | def test_create_metadata_site_no_failover(self, call, unlink, get_failover_host, start, render): |
406 | 160 | self.mock_config.return_value = { | 164 | config = hookenv.Config( |
407 | 161 | 'display-host': 'archive.ubuntu.com', | 165 | { |
408 | 162 | 'enable_healthcheck': True, | 166 | 'display-host': 'archive.ubuntu.com', |
409 | 163 | 'path-base': 'ubuntu', | 167 | 'enable_healthcheck': True, |
410 | 164 | 'sync-host': 'us.archive.ubuntu.com', | 168 | 'path-base': 'ubuntu', |
411 | 165 | } | 169 | 'sync-host': 'us.archive.ubuntu.com', |
412 | 170 | } | ||
413 | 171 | ) | ||
414 | 166 | 172 | ||
415 | 167 | health_check_path = os.path.join(self.tmpdir, 'apache', 'health-check') | 173 | health_check_path = os.path.join(self.tmpdir, 'apache', 'health-check') |
416 | 168 | disabled_flag = os.path.join(health_check_path, 'health-check-disabled.flag') | 174 | disabled_flag = os.path.join(health_check_path, 'health-check-disabled.flag') |
417 | 169 | os.mkdir(os.path.join(self.tmpdir, 'apache')) | 175 | os.mkdir(os.path.join(self.tmpdir, 'apache')) |
418 | 170 | os.mkdir(health_check_path) | 176 | os.mkdir(health_check_path) |
419 | 171 | os.mknod(disabled_flag) | 177 | os.mknod(disabled_flag) |
421 | 172 | apache.create_metadata_site() | 178 | apache.create_metadata_site(config) |
422 | 173 | unlink.assert_called_with(disabled_flag) | 179 | unlink.assert_called_with(disabled_flag) |
423 | 174 | 180 | ||
424 | 175 | @mock.patch('charmhelpers.core.host.service_start') | 181 | @mock.patch('charmhelpers.core.host.service_start') |
425 | @@ -204,3 +210,119 @@ | |||
426 | 204 | apache.start(start_only=True) | 210 | apache.start(start_only=True) |
427 | 205 | service_reload.assert_not_called() | 211 | service_reload.assert_not_called() |
428 | 206 | service_start.assert_called_with('apache2') | 212 | service_start.assert_called_with('apache2') |
429 | 213 | |||
430 | 214 | @mock.patch('charmhelpers.core.templating.render') | ||
431 | 215 | @mock.patch('os.symlink') | ||
432 | 216 | @mock.patch('subprocess.check_call') | ||
433 | 217 | def test_create_mpm_workerfile(self, check_call, symlink, render): | ||
434 | 218 | config = hookenv.Config( | ||
435 | 219 | { | ||
436 | 220 | 'apache2_mpm_maxconnectionsperchild': 10000, | ||
437 | 221 | 'apache2_mpm_maxrequestworkers': 0, | ||
438 | 222 | 'apache2_mpm_maxsparethreads': 0, | ||
439 | 223 | 'apache2_mpm_minsparethreads': 0, | ||
440 | 224 | 'apache2_mpm_serverlimit': 0, | ||
441 | 225 | 'apache2_mpm_startservers': 0, | ||
442 | 226 | 'apache2_mpm_threadlimit': 0, | ||
443 | 227 | 'apache2_mpm_threadsperchild': 0, | ||
444 | 228 | } | ||
445 | 229 | ) | ||
446 | 230 | self.assertTrue(apache.create_mpm_workerfile(config)) | ||
447 | 231 | render.assert_called_with( | ||
448 | 232 | 'apache2/mpm_worker.template', | ||
449 | 233 | '/etc/apache2/conf-available/000mpm-worker.conf', | ||
450 | 234 | { | ||
451 | 235 | 'maxconnectionsperchild': 10000, | ||
452 | 236 | 'maxrequestworkers': 512, | ||
453 | 237 | 'maxsparethreads': 512, | ||
454 | 238 | 'minsparethreads': 256, | ||
455 | 239 | 'serverlimit': 1, | ||
456 | 240 | 'startservers': 1, | ||
457 | 241 | 'threadlimit': 512, | ||
458 | 242 | 'threadsperchild': 512, | ||
459 | 243 | }, | ||
460 | 244 | ) | ||
461 | 245 | check_call.assert_called_with(['a2enconf', '000mpm-worker']) | ||
462 | 246 | symlink.assert_called_with( | ||
463 | 247 | '/etc/apache2/conf-available/000mpm-worker.conf', '/etc/apache2/mods-available/mpm_worker.conf' | ||
464 | 248 | ) | ||
465 | 249 | |||
466 | 250 | # No change, no need to reload | ||
467 | 251 | render.reset_mock() | ||
468 | 252 | check_call.reset_mock() | ||
469 | 253 | symlink.reset_mock() | ||
470 | 254 | config.save() | ||
471 | 255 | config = hookenv.Config( | ||
472 | 256 | { | ||
473 | 257 | 'apache2_mpm_maxconnectionsperchild': 10000, | ||
474 | 258 | 'apache2_mpm_maxrequestworkers': 0, | ||
475 | 259 | 'apache2_mpm_maxsparethreads': 0, | ||
476 | 260 | 'apache2_mpm_minsparethreads': 0, | ||
477 | 261 | 'apache2_mpm_serverlimit': 0, | ||
478 | 262 | 'apache2_mpm_startservers': 0, | ||
479 | 263 | 'apache2_mpm_threadlimit': 0, | ||
480 | 264 | 'apache2_mpm_threadsperchild': 0, | ||
481 | 265 | } | ||
482 | 266 | ) | ||
483 | 267 | self.assertFalse(apache.create_mpm_workerfile(config)) | ||
484 | 268 | |||
485 | 269 | @mock.patch('charmhelpers.core.templating.render') | ||
486 | 270 | @mock.patch('subprocess.check_call') | ||
487 | 271 | def test_create_security(self, check_call, render): | ||
488 | 272 | config = hookenv.Config( | ||
489 | 273 | { | ||
490 | 274 | 'apache2_server_tokens': 'OS', | ||
491 | 275 | 'apache2_server_signature': 'On', | ||
492 | 276 | 'apache2_trace_enabled': 'Off', | ||
493 | 277 | } | ||
494 | 278 | ) | ||
495 | 279 | self.assertTrue(apache.create_security(config)) | ||
496 | 280 | render.assert_called_with( | ||
497 | 281 | 'apache2/security.template', | ||
498 | 282 | '/etc/apache2/conf-available/security.conf', | ||
499 | 283 | { | ||
500 | 284 | 'server_tokens': 'OS', | ||
501 | 285 | 'server_signature': 'On', | ||
502 | 286 | 'trace_enabled': 'Off', | ||
503 | 287 | }, | ||
504 | 288 | ) | ||
505 | 289 | check_call.assert_called_with(['a2enconf', 'security']) | ||
506 | 290 | |||
507 | 291 | # No change, no need to reload | ||
508 | 292 | render.reset_mock() | ||
509 | 293 | check_call.reset_mock() | ||
510 | 294 | config.save() | ||
511 | 295 | config = hookenv.Config( | ||
512 | 296 | { | ||
513 | 297 | 'apache2_server_tokens': 'OS', | ||
514 | 298 | 'apache2_server_signature': 'On', | ||
515 | 299 | 'apache2_trace_enabled': 'Off', | ||
516 | 300 | } | ||
517 | 301 | ) | ||
518 | 302 | self.assertFalse(apache.create_security(config)) | ||
519 | 303 | |||
520 | 304 | @mock.patch('os.chown') | ||
521 | 305 | @mock.patch('os.fchown') | ||
522 | 306 | # For @util.run_as_user() | ||
523 | 307 | @mock.patch('os.setegid') | ||
524 | 308 | @mock.patch('os.seteuid') | ||
525 | 309 | @mock.patch('subprocess.check_call') | ||
526 | 310 | def test_configure_remoteip_logging(self, check_call, seteuid, setegid, fchown, chown): | ||
527 | 311 | config = hookenv.Config({'remoteip_logging': True}) | ||
528 | 312 | self.assertTrue(apache.configure_remoteip_logging(config, apache2_conf_path=self.tmpdir)) | ||
529 | 313 | check_call.assert_called_with(['a2enmod', 'remoteip']) | ||
530 | 314 | with open(os.path.join(self.tmpdir, 'conf-available', 'remoteip.conf'), 'r') as f: | ||
531 | 315 | got = f.read() | ||
532 | 316 | with open('templates/apache2/remoteip.conf', 'r') as f: | ||
533 | 317 | want = f.read().strip() | ||
534 | 318 | self.assertEqual(want, got) | ||
535 | 319 | |||
536 | 320 | # No change | ||
537 | 321 | config.save() | ||
538 | 322 | config = hookenv.Config({'remoteip_logging': True}) | ||
539 | 323 | self.assertFalse(apache.configure_remoteip_logging(config, apache2_conf_path=self.tmpdir)) | ||
540 | 324 | |||
541 | 325 | check_call.reset_mock() | ||
542 | 326 | config = hookenv.Config({'remoteip_logging': False}) | ||
543 | 327 | self.assertTrue(apache.configure_remoteip_logging(config, apache2_conf_path=self.tmpdir)) | ||
544 | 328 | check_call.assert_called_with(['a2dismod', 'remoteip']) |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.