Merge ~afreiberger/charm-mongodb:blacken-20.08 into charm-mongodb:master
- Git
- lp:~afreiberger/charm-mongodb
- blacken-20.08
- Merge into master
Proposed by Drew Freiberger
Status: | Merged |
---|---|
Merge reported by: | Drew Freiberger |
Merged at revision: | 25b1bd5fad7364c7bc82a1b6e01a3eca6b1fd2db |
Proposed branch: | ~afreiberger/charm-mongodb:blacken-20.08 |
Merge into: | charm-mongodb:master |
Prerequisite: | ~afreiberger/charm-mongodb:makefile-20.08 |
Diff against target: | 3105 lines (+852/-805) 10 files modified actions/backup.py (+5/-8) actions/backup_test.py (+15/-7) dev/null (+0/-1) hooks/hooks.py (+583/-573) tests/functional/tests/tests_mongodb.py (+2/-1) tests/unit/__init__.py (+3/-2) tests/unit/test_hooks.py (+215/-183) tests/unit/test_utils.py (+14/-13) tests/unit/test_write_log_rotate_config.py (+12/-13) tox.ini (+3/-4) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Xav Paice (community) | Approve | ||
Review via email: |
Commit message
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 : | # |
Revision history for this message

🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Unable to determine commit message from repository - please click "Set commit message" and enter the commit message manually.
Revision history for this message

Xav Paice (xavpaice) wrote : | # |
LGTM, one minor comment but non-blocking.
review: Approve
Revision history for this message

Drew Freiberger (afreiberger) wrote : | # |
removing .jujuignore is intended, it shouldn't have been added in prior commit 46ff090, but don't want to rebase all three changes.
Revision history for this message

🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change has no commit message, setting status to needs review.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/.jujuignore b/.jujuignore |
2 | deleted file mode 100644 |
3 | index b7f1399..0000000 |
4 | --- a/.jujuignore |
5 | +++ /dev/null |
6 | @@ -1 +0,0 @@ |
7 | -.build |
8 | \ No newline at end of file |
9 | diff --git a/actions/backup.py b/actions/backup.py |
10 | index 0930eab..a5682be 100644 |
11 | --- a/actions/backup.py |
12 | +++ b/actions/backup.py |
13 | @@ -1,11 +1,12 @@ |
14 | import shlex |
15 | import subprocess |
16 | import os |
17 | + |
18 | try: |
19 | from charmhelpers.core.hookenv import action_get, action_set, action_fail |
20 | except ImportError: |
21 | - subprocess.check_call(['apt-get', 'install', '-y', 'python3-pip']) |
22 | - subprocess.check_call(['pip3', 'install', 'charmhelpers']) |
23 | + subprocess.check_call(["apt-get", "install", "-y", "python3-pip"]) |
24 | + subprocess.check_call(["pip3", "install", "charmhelpers"]) |
25 | from charmhelpers.core.hookenv import action_get, action_set, action_fail |
26 | |
27 | |
28 | @@ -14,10 +15,7 @@ def mkdir(dir): |
29 | |
30 | |
31 | def execute(command, current_working_directory): |
32 | - return subprocess.check_output( |
33 | - shlex.split(command), |
34 | - cwd=current_working_directory, |
35 | - ) |
36 | + return subprocess.check_output(shlex.split(command), cwd=current_working_directory) |
37 | |
38 | |
39 | def dump(): |
40 | @@ -49,8 +47,7 @@ def backup_command(cmd, args, dir): |
41 | output = execute(command, dir) |
42 | action_set({"output": output}) |
43 | except subprocess.CalledProcessError as e: |
44 | - action_set({"error_code": e.returncode, |
45 | - "exception": e, "output": e.output}) |
46 | + action_set({"error_code": e.returncode, "exception": e, "output": e.output}) |
47 | action_fail(str(e)) |
48 | except Exception as e: |
49 | action_set({"exception": e}) |
50 | diff --git a/actions/backup_test.py b/actions/backup_test.py |
51 | index b5f1d33..916024e 100644 |
52 | --- a/actions/backup_test.py |
53 | +++ b/actions/backup_test.py |
54 | @@ -36,19 +36,27 @@ class TestBackups(unittest.TestCase): |
55 | |
56 | backup.mkdir.assert_called_once_with("this/dir") |
57 | backup.execute.assert_called_once_with("mongodump -arg1 -arg2", "this/dir") |
58 | - backup.action_set.assert_has_calls([ |
59 | - call({"command": "mongodump -arg1 -arg2", "working-dir": "this/dir"}), |
60 | - call({"output": "output"})]) |
61 | + backup.action_set.assert_has_calls( |
62 | + [ |
63 | + call({"command": "mongodump -arg1 -arg2", "working-dir": "this/dir"}), |
64 | + call({"output": "output"}), |
65 | + ] |
66 | + ) |
67 | |
68 | def test_restore(self): |
69 | backup.restore() |
70 | |
71 | backup.mkdir.assert_called_once_with("this/dir") |
72 | backup.execute.assert_called_once_with("mongorestore -arg1 -arg2", "this/dir") |
73 | - backup.action_set.assert_has_calls([ |
74 | - call({"command": "mongorestore -arg1 -arg2", "working-dir": "this/dir"}), |
75 | - call({"output": "output"})]) |
76 | + backup.action_set.assert_has_calls( |
77 | + [ |
78 | + call( |
79 | + {"command": "mongorestore -arg1 -arg2", "working-dir": "this/dir"} |
80 | + ), |
81 | + call({"output": "output"}), |
82 | + ] |
83 | + ) |
84 | |
85 | |
86 | -if __name__ == '__main__': |
87 | +if __name__ == "__main__": |
88 | unittest.main() |
89 | diff --git a/hooks/hooks.py b/hooks/hooks.py |
90 | index 0c7798b..4ba26fb 100755 |
91 | --- a/hooks/hooks.py |
92 | +++ b/hooks/hooks.py |
93 | @@ -1,9 +1,9 @@ |
94 | #!/usr/bin/env python3 |
95 | -''' |
96 | +""" |
97 | Created on Aug 1, 2012 |
98 | |
99 | @author: negronjl |
100 | -''' |
101 | +""" |
102 | |
103 | import collections |
104 | import distutils |
105 | @@ -21,9 +21,9 @@ try: |
106 | import yaml # flake8: noqa |
107 | except ImportError: |
108 | if sys.version_info.major == 2: |
109 | - subprocess.check_call(['apt-get', 'install', '-y', 'python-yaml']) |
110 | + subprocess.check_call(["apt-get", "install", "-y", "python-yaml"]) |
111 | else: |
112 | - subprocess.check_call(['apt-get', 'install', '-y', 'python3-yaml']) |
113 | + subprocess.check_call(["apt-get", "install", "-y", "python3-yaml"]) |
114 | import yaml |
115 | |
116 | from os import chmod |
117 | @@ -36,11 +36,7 @@ from yaml.constructor import ConstructorError |
118 | from charmhelpers.core.decorators import retry_on_exception |
119 | from charmhelpers.payload.execd import execd_preinstall |
120 | |
121 | -from charmhelpers.fetch import ( |
122 | - add_source, |
123 | - apt_update, |
124 | - apt_install |
125 | -) |
126 | +from charmhelpers.fetch import add_source, apt_update, apt_install |
127 | |
128 | from charmhelpers.core.host import ( |
129 | service, |
130 | @@ -70,9 +66,7 @@ from charmhelpers.core.hookenv import ( |
131 | application_version_set, |
132 | ) |
133 | |
134 | -from charmhelpers.contrib.hahelpers.cluster import ( |
135 | - peer_units |
136 | -) |
137 | +from charmhelpers.contrib.hahelpers.cluster import peer_units |
138 | |
139 | try: |
140 | from pymongo import MongoClient |
141 | @@ -88,13 +82,13 @@ except ImportError: |
142 | try: |
143 | import pip # flake8: noqa |
144 | except ImportError: |
145 | - apt_install('python3-pip', fatal=True) |
146 | + apt_install("python3-pip", fatal=True) |
147 | import pip # flake8: noqa |
148 | |
149 | try: |
150 | import distro # flake8: noqa |
151 | except ImportError: |
152 | - pip.main(['install', "distro"]) |
153 | + pip.main(["install", "distro"]) |
154 | import distro # flake8: noqa |
155 | |
156 | from charmhelpers.contrib.charmsupport.nrpe import NRPE |
157 | @@ -111,7 +105,7 @@ default_mongos_list = "/etc/mongos.list" |
158 | default_wait_for = 3 |
159 | default_max_tries = 7 |
160 | |
161 | -INSTALL_PACKAGES = ['mongodb-server', 'python3-yaml'] |
162 | +INSTALL_PACKAGES = ["mongodb-server", "python3-yaml"] |
163 | |
164 | # number of seconds init_replset will pause while looping to check if |
165 | # replicaset is initialized |
166 | @@ -143,32 +137,32 @@ was_i_primary = False |
167 | |
168 | def is_bionic_or_greater(): |
169 | current_version = distro.linux_distribution()[1] |
170 | - if distutils.version.LooseVersion(current_version) >= \ |
171 | - distutils.version.LooseVersion('18.04'): |
172 | + if distutils.version.LooseVersion( |
173 | + current_version |
174 | + ) >= distutils.version.LooseVersion("18.04"): |
175 | return True |
176 | |
177 | |
178 | -def port_check(host=None, port=None, protocol='TCP'): |
179 | +def port_check(host=None, port=None, protocol="TCP"): |
180 | if host is None or port is None: |
181 | juju_log("port_check: host and port must be defined.") |
182 | - return(False) |
183 | - if protocol.upper() == 'TCP': |
184 | + return False |
185 | + if protocol.upper() == "TCP": |
186 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
187 | - elif protocol.upper() == 'UDP': |
188 | + elif protocol.upper() == "UDP": |
189 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
190 | else: |
191 | juju_log("port_check: Unrecognized protocol %s" % protocol) |
192 | - return(False) |
193 | + return False |
194 | try: |
195 | s.connect((host, int(port))) |
196 | s.shutdown(socket.SHUT_RDWR) |
197 | juju_log("port_check: %s:%s/%s is open" % (host, port, protocol)) |
198 | - return(True) |
199 | + return True |
200 | except Exception as e: |
201 | - juju_log("port_check: Unable to connect to %s:%s/%s." % |
202 | - (host, port, protocol)) |
203 | + juju_log("port_check: Unable to connect to %s:%s/%s." % (host, port, protocol)) |
204 | juju_log("port_check: Exception: %s" % str(e)) |
205 | - return(False) |
206 | + return False |
207 | |
208 | |
209 | # update_service_ports: Convenience function that evaluate the old and new |
210 | @@ -177,7 +171,7 @@ def port_check(host=None, port=None, protocol='TCP'): |
211 | def update_service_ports(old_service_ports=None, new_service_ports=None): |
212 | juju_log("update_service_ports") |
213 | if old_service_ports is None or new_service_ports is None: |
214 | - return(None) |
215 | + return None |
216 | for port in old_service_ports: |
217 | if port not in new_service_ports: |
218 | juju_log("closing port: %d" % int(port)) |
219 | @@ -197,7 +191,7 @@ def regex_sub(pat_replace=None, data=None): |
220 | new_data = data |
221 | for (pattern, replace) in pat_replace: |
222 | new_data = re.sub(pattern, replace, data, 0, re.MULTILINE) |
223 | - return(new_data) |
224 | + return new_data |
225 | |
226 | |
227 | def update_file(filename=None, new_data=None, old_data=None): |
228 | @@ -206,21 +200,22 @@ def update_file(filename=None, new_data=None, old_data=None): |
229 | retVal = False |
230 | try: |
231 | if old_data != new_data: |
232 | - with open(filename, 'w') as f: |
233 | + with open(filename, "w") as f: |
234 | f.write(new_data) |
235 | retVal = True |
236 | except Exception as e: |
237 | juju_log(str(e)) |
238 | retVal = False |
239 | finally: |
240 | - return(retVal) |
241 | + return retVal |
242 | |
243 | |
244 | def process_check(pid=None): |
245 | try: |
246 | if pid is not None: |
247 | - cmd_line = subprocess.check_output('ps -p %d -o cmd h' % |
248 | - int(pid), shell=True) |
249 | + cmd_line = subprocess.check_output( |
250 | + "ps -p %d -o cmd h" % int(pid), shell=True |
251 | + ) |
252 | retVal = (pid, cmd_line) |
253 | else: |
254 | juju_log("process_check: pid not defined.") |
255 | @@ -229,22 +224,20 @@ def process_check(pid=None): |
256 | juju_log("process_check exception: %s" % str(e)) |
257 | retVal = (None, None) |
258 | finally: |
259 | - juju_log("process_check returs pid: %s and cmd_line: %s" % |
260 | - retVal) |
261 | - return(retVal) |
262 | + juju_log("process_check returs pid: %s and cmd_line: %s" % retVal) |
263 | + return retVal |
264 | |
265 | |
266 | def process_check_pidfile(pidfile=None): |
267 | if pidfile is not None and os.path.exists(pidfile): |
268 | - return(process_check(open(pidfile).read())) |
269 | + return process_check(open(pidfile).read()) |
270 | else: |
271 | juju_log("process_check_pidfile: undefined or non-existant pidfile.") |
272 | - return((None, None)) |
273 | + return (None, None) |
274 | |
275 | |
276 | def is_valid_ip(bind_ip): |
277 | - if bind_ip == unit_get("private-address") or \ |
278 | - bind_ip == unit_get("public-address"): |
279 | + if bind_ip == unit_get("private-address") or bind_ip == unit_get("public-address"): |
280 | return True |
281 | return False |
282 | |
283 | @@ -252,12 +245,14 @@ def is_valid_ip(bind_ip): |
284 | def choose_bind_ip(bind_ip): |
285 | default_value, localhost = "0.0.0.0", "127.0.0.1" |
286 | known_values = collections.defaultdict(lambda: False) |
287 | - known_values.update({ |
288 | - "0.0.0.0": default_value, |
289 | - "all": default_value, |
290 | - "localhost": localhost, |
291 | - "127.0.0.1": localhost, |
292 | - }) |
293 | + known_values.update( |
294 | + { |
295 | + "0.0.0.0": default_value, |
296 | + "all": default_value, |
297 | + "localhost": localhost, |
298 | + "127.0.0.1": localhost, |
299 | + } |
300 | + ) |
301 | |
302 | if known_values[bind_ip]: |
303 | return known_values[bind_ip] |
304 | @@ -282,7 +277,7 @@ class TimeoutException(Exception): |
305 | ############################################################################### |
306 | def mongodb_conf(config_data=None): # noqa: C901 |
307 | if config_data is None: |
308 | - return(None) |
309 | + return None |
310 | config = [] |
311 | |
312 | # header |
313 | @@ -291,28 +286,25 @@ def mongodb_conf(config_data=None): # noqa: C901 |
314 | |
315 | # dbpath |
316 | # Create the directory if not there already |
317 | - subprocess.call(['mkdir', '-p', '%s' % config_data['dbpath']]) |
318 | + subprocess.call(["mkdir", "-p", "%s" % config_data["dbpath"]]) |
319 | # Make sure the mongodb user has access to it |
320 | - subprocess.call(['chown', '-R', 'mongodb:mongodb', config_data['dbpath']]) |
321 | - config.append("dbpath=%s" % config_data['dbpath']) |
322 | + subprocess.call(["chown", "-R", "mongodb:mongodb", config_data["dbpath"]]) |
323 | + config.append("dbpath=%s" % config_data["dbpath"]) |
324 | config.append("") |
325 | config.append("ipv6=true") |
326 | |
327 | # logpath |
328 | # Create the directory if not there already |
329 | - subprocess.call(['mkdir', |
330 | - '-p', |
331 | - '%s' % os.path.dirname(config_data['logpath'])]) |
332 | - subprocess.call(['chown', |
333 | - '-R', |
334 | - 'mongodb:mongodb', |
335 | - os.path.dirname(config_data['logpath'])]) |
336 | - |
337 | - config.append("logpath=%s" % config_data['logpath']) |
338 | + subprocess.call(["mkdir", "-p", "%s" % os.path.dirname(config_data["logpath"])]) |
339 | + subprocess.call( |
340 | + ["chown", "-R", "mongodb:mongodb", os.path.dirname(config_data["logpath"])] |
341 | + ) |
342 | + |
343 | + config.append("logpath=%s" % config_data["logpath"]) |
344 | config.append("") |
345 | |
346 | # log_append |
347 | - if config_data['logappend']: |
348 | + if config_data["logappend"]: |
349 | config.append("logappend=true") |
350 | config.append("") |
351 | |
352 | @@ -322,67 +314,67 @@ def mongodb_conf(config_data=None): # noqa: C901 |
353 | config.append("") |
354 | |
355 | # port |
356 | - config.append("port = %d" % config_data['port']) |
357 | + config.append("port = %d" % config_data["port"]) |
358 | config.append("") |
359 | |
360 | # journal |
361 | - if config_data['journal']: |
362 | + if config_data["journal"]: |
363 | config.append("journal=true") |
364 | config.append("") |
365 | |
366 | # cpu |
367 | - if config_data['cpu']: |
368 | + if config_data["cpu"]: |
369 | config.append("cpu = true") |
370 | config.append("") |
371 | |
372 | # auth |
373 | - if config_data['auth']: |
374 | + if config_data["auth"]: |
375 | config.append("auth = true") |
376 | config.append("") |
377 | |
378 | # verbose |
379 | - if config_data['verbose']: |
380 | + if config_data["verbose"]: |
381 | config.append("verbose = true") |
382 | config.append("") |
383 | |
384 | # objcheck |
385 | - if config_data['objcheck']: |
386 | + if config_data["objcheck"]: |
387 | config.append("objcheck = true") |
388 | config.append("") |
389 | |
390 | # quota |
391 | - if config_data['quota']: |
392 | + if config_data["quota"]: |
393 | config.append("quota = true") |
394 | - config.append("quotaFiles = {}".format(config_data['quotafiles'])) |
395 | + config.append("quotaFiles = {}".format(config_data["quotafiles"])) |
396 | config.append("") |
397 | |
398 | if not is_bionic_or_greater(): |
399 | # diaglog |
400 | - config.append("diaglog = %d" % config_data['diaglog']) |
401 | + config.append("diaglog = %d" % config_data["diaglog"]) |
402 | config.append("") |
403 | # nohttpinterface |
404 | - if config_data['web_admin_ui']: |
405 | + if config_data["web_admin_ui"]: |
406 | config.append("rest = true") |
407 | config.append("") |
408 | |
409 | # noscripting |
410 | - if config_data['noscripting']: |
411 | + if config_data["noscripting"]: |
412 | config.append("noscripting = true") |
413 | config.append("") |
414 | |
415 | # notablescan |
416 | - if config_data['notablescan']: |
417 | + if config_data["notablescan"]: |
418 | config.append("notablescan = true") |
419 | config.append("") |
420 | |
421 | # noprealloc |
422 | - if config_data['noprealloc']: |
423 | + if config_data["noprealloc"]: |
424 | config.append("noprealloc = true") |
425 | config.append("") |
426 | |
427 | # nssize |
428 | - if config_data['nssize'] != "default": |
429 | - config.append("nssize = %s" % config_data['nssize']) |
430 | + if config_data["nssize"] != "default": |
431 | + config.append("nssize = %s" % config_data["nssize"]) |
432 | config.append("") |
433 | |
434 | # Set either replica-set or master, depending upon whether the |
435 | @@ -391,40 +383,39 @@ def mongodb_conf(config_data=None): # noqa: C901 |
436 | # charm will use replica-set replication. The user may opt to |
437 | # do master/slave replication or sharding as a different form |
438 | # of scaleout. |
439 | - if is_relation_made('replica-set'): |
440 | - config.append("replSet = %s" % config_data['replicaset']) |
441 | + if is_relation_made("replica-set"): |
442 | + config.append("replSet = %s" % config_data["replicaset"]) |
443 | config.append("") |
444 | else: |
445 | - if config_data['master'] == "self": |
446 | + if config_data["master"] == "self": |
447 | config.append("master = true") |
448 | config.append("") |
449 | else: |
450 | config.append("slave = true") |
451 | - config.append("source = %s" % config_data['master']) |
452 | + config.append("source = %s" % config_data["master"]) |
453 | config.append("") |
454 | |
455 | # arbiter |
456 | - if config_data['arbiter'] != "disabled" and \ |
457 | - config_data['arbiter'] != "enabled": |
458 | - config.append("arbiter = %s" % config_data['arbiter']) |
459 | + if config_data["arbiter"] != "disabled" and config_data["arbiter"] != "enabled": |
460 | + config.append("arbiter = %s" % config_data["arbiter"]) |
461 | config.append("") |
462 | |
463 | # autoresync |
464 | - if config_data['autoresync']: |
465 | + if config_data["autoresync"]: |
466 | config.append("autoresync") |
467 | config.append("") |
468 | |
469 | # oplogSize |
470 | - if config_data['oplogSize'] != "default": |
471 | - config.append("oplogSize = %s" % config_data['oplogSize']) |
472 | + if config_data["oplogSize"] != "default": |
473 | + config.append("oplogSize = %s" % config_data["oplogSize"]) |
474 | config.append("") |
475 | |
476 | # extra config options |
477 | - if config_data['extra_config_options'] != "none": |
478 | - for config_option in config_data['extra_config_options'].split(','): |
479 | + if config_data["extra_config_options"] != "none": |
480 | + for config_option in config_data["extra_config_options"].split(","): |
481 | config.append(config_option) |
482 | |
483 | - return('\n'.join(config)) |
484 | + return "\n".join(config) |
485 | |
486 | |
487 | def get_current_mongo_config(): |
488 | @@ -434,65 +425,61 @@ def get_current_mongo_config(): |
489 | :returns dict: key/value pairs of the configuration file. |
490 | """ |
491 | results = {} |
492 | - with open(default_mongodb_config, 'r') as f: |
493 | + with open(default_mongodb_config, "r") as f: |
494 | for line in f: |
495 | line = line.strip() |
496 | |
497 | # Skip over comments, blank lines, and any other line |
498 | # that appears to not contain a key = value pair. |
499 | - if line.startswith('#') or '=' not in line: |
500 | + if line.startswith("#") or "=" not in line: |
501 | continue |
502 | |
503 | - key, value = line.split('=', 1) |
504 | + key, value = line.split("=", 1) |
505 | results[key.strip()] = value.strip() |
506 | return results |
507 | |
508 | |
509 | def mongo_client(host=None, command=None): |
510 | if host is None or command is None: |
511 | - return(False) |
512 | + return False |
513 | else: |
514 | - cmd_line = 'mongo' |
515 | - cmd_line += ' --host %s' % host |
516 | - cmd_line += ' --eval \'printjson(%s)\'' % command |
517 | + cmd_line = "mongo" |
518 | + cmd_line += " --host %s" % host |
519 | + cmd_line += " --eval 'printjson(%s)'" % command |
520 | juju_log("Executing: %s" % cmd_line, level=DEBUG) |
521 | - return(subprocess.call(cmd_line, shell=True) == 0) |
522 | + return subprocess.call(cmd_line, shell=True) == 0 |
523 | |
524 | |
525 | -def mongo_client_smart(host='localhost', command=None): |
526 | - ''' |
527 | +def mongo_client_smart(host="localhost", command=None): |
528 | + """ |
529 | Rework of mongo_client function, it retries the command |
530 | MONGO_CLIENT_RETRIES times |
531 | |
532 | :param host: The host to connect to. Defaults to localhost |
533 | :param command: The command to be executed. Can't be None |
534 | :returns True if command succeeded, False if it failed |
535 | - ''' |
536 | + """ |
537 | |
538 | if command is None: |
539 | return False |
540 | |
541 | - cmd_line = ['mongo', '--quiet', '--host', host, |
542 | - '--eval', 'printjson(%s)' % command] |
543 | + cmd_line = ["mongo", "--quiet", "--host", host, "--eval", "printjson(%s)" % command] |
544 | juju_log("mongo_client_smart executing: %s" % str(cmd_line), level=DEBUG) |
545 | |
546 | for i in range(MONGO_CLIENT_RETRIES): |
547 | try: |
548 | cmd_output = subprocess.check_output(cmd_line).decode("utf8") |
549 | - juju_log('mongo_client_smart executed, output: %s' % |
550 | - cmd_output) |
551 | - if json.loads(cmd_output)['ok'] == 1: |
552 | + juju_log("mongo_client_smart executed, output: %s" % cmd_output) |
553 | + if json.loads(cmd_output)["ok"] == 1: |
554 | return True |
555 | except subprocess.CalledProcessError as err: |
556 | - juju_log('mongo_client_smart failed: %s' % |
557 | - err.output, |
558 | - level=DEBUG) |
559 | + juju_log("mongo_client_smart failed: %s" % err.output, level=DEBUG) |
560 | pass |
561 | finally: |
562 | time.sleep(1.5) |
563 | |
564 | # At this point, the command failed |
565 | - juju_log('mongo_client_smart failed executing: %s', level=WARNING) |
566 | + juju_log("mongo_client_smart failed executing: %s", level=WARNING) |
567 | return False |
568 | |
569 | |
570 | @@ -501,46 +488,44 @@ def init_replset(): |
571 | # Use my IP at rs.initiate(), voids issues with invalid (and/or |
572 | # not resolvable by peers) hostnames |
573 | |
574 | - rset = config_data['replicaset'] |
575 | - addr = unit_get('private-address') |
576 | - port = config_data['port'] |
577 | + rset = config_data["replicaset"] |
578 | + addr = unit_get("private-address") |
579 | + port = config_data["port"] |
580 | |
581 | - init = '{_id: "%s", members: [{_id: 0, host: "%s:%s"}]} ' % (rset, |
582 | - addr, |
583 | - port) |
584 | + init = '{_id: "%s", members: [{_id: 0, host: "%s:%s"}]} ' % (rset, addr, port) |
585 | |
586 | - retVal = mongo_client('localhost', 'rs.initiate(%s)' % init) |
587 | + retVal = mongo_client("localhost", "rs.initiate(%s)" % init) |
588 | time.sleep(1) # give mongod some time to become primary |
589 | - c = MongoClient('localhost') |
590 | + c = MongoClient("localhost") |
591 | while True: |
592 | try: |
593 | - r = run_admin_command(c, 'replSetGetStatus') |
594 | - mongo_state = r['myState'] |
595 | - juju_log('init_replset: myState: %s' % mongo_state) |
596 | + r = run_admin_command(c, "replSetGetStatus") |
597 | + mongo_state = r["myState"] |
598 | + juju_log("init_replset: myState: %s" % mongo_state) |
599 | if mongo_state == MONGO_PRIMARY: # we're primary! |
600 | break |
601 | - elif mongo_state in (MONGO_STARTUP, |
602 | - MONGO_STARTUP2, |
603 | - MONGO_SECONDARY |
604 | - ): # we are still initializing |
605 | + elif mongo_state in ( |
606 | + MONGO_STARTUP, |
607 | + MONGO_STARTUP2, |
608 | + MONGO_SECONDARY, |
609 | + ): # we are still initializing |
610 | continue |
611 | else: |
612 | - juju_log('init_replset: Unexpected replicaSet state: %s' % |
613 | - mongo_state) |
614 | + juju_log("init_replset: Unexpected replicaSet state: %s" % mongo_state) |
615 | retVal = False |
616 | break |
617 | except OperationFailure as e: |
618 | - juju_log('init_replset: OperationFailure: %s' % e, DEBUG) |
619 | - if 'Received replSetInitiate' in str(e): |
620 | + juju_log("init_replset: OperationFailure: %s" % e, DEBUG) |
621 | + if "Received replSetInitiate" in str(e): |
622 | continue |
623 | else: |
624 | - juju_log('init_replset: Unhandled OperationFailure %s' % e) |
625 | + juju_log("init_replset: Unhandled OperationFailure %s" % e) |
626 | raise |
627 | finally: |
628 | time.sleep(INIT_CHECK_DELAY) |
629 | |
630 | juju_log("init_replset returns: %s" % retVal, level=DEBUG) |
631 | - return(retVal) |
632 | + return retVal |
633 | |
634 | |
635 | def run_admin_command(client, cmdstr): |
636 | @@ -556,49 +541,49 @@ def join_replset(master_node=None, host=None): |
637 | # localhost. |
638 | # However, that might break other code calling this method. |
639 | # This will wait charm rewrite. |
640 | - juju_log("join_replset: master_node: %s, host: %s" % |
641 | - (master_node, host)) |
642 | + juju_log("join_replset: master_node: %s, host: %s" % (master_node, host)) |
643 | if master_node is None or host is None: |
644 | retVal = False |
645 | else: |
646 | retVal = rs_add(host) |
647 | juju_log("join_replset returns: %s" % retVal, level=DEBUG) |
648 | - return(retVal) |
649 | + return retVal |
650 | |
651 | |
652 | def leave_replset(master_node=None, host=None): |
653 | - juju_log("leave_replset: master_node: %s, host: %s" % |
654 | - (master_node, host)) |
655 | + juju_log("leave_replset: master_node: %s, host: %s" % (master_node, host)) |
656 | if master_node is None or host is None: |
657 | retVal = False |
658 | else: |
659 | retVal = mongo_client(master_node, 'rs.remove("%s")' % host) |
660 | juju_log("leave_replset returns: %s" % retVal, level=DEBUG) |
661 | - return(retVal) |
662 | + return retVal |
663 | |
664 | |
665 | def enable_replset(replicaset_name=None): |
666 | retVal = False |
667 | if replicaset_name is None: |
668 | - juju_log('enable_replset: replicaset_name is None, exiting', |
669 | - level=DEBUG) |
670 | + juju_log("enable_replset: replicaset_name is None, exiting", level=DEBUG) |
671 | try: |
672 | - juju_log('enable_replset: Enabling replicaset configuration:') |
673 | + juju_log("enable_replset: Enabling replicaset configuration:") |
674 | |
675 | current_config = get_current_mongo_config() |
676 | config_data = dict(config()) |
677 | |
678 | - if 'replSet' in current_config and \ |
679 | - current_config['replSet'] == config_data['replicaset']: |
680 | - juju_log('enable_replset: replica set is already enabled', |
681 | - level=DEBUG) |
682 | + if ( |
683 | + "replSet" in current_config |
684 | + and current_config["replSet"] == config_data["replicaset"] |
685 | + ): |
686 | + juju_log("enable_replset: replica set is already enabled", level=DEBUG) |
687 | else: |
688 | - juju_log('enable_replset: enabling replicaset %s' % |
689 | - config_data['replicaset'], level=DEBUG) |
690 | + juju_log( |
691 | + "enable_replset: enabling replicaset %s" % config_data["replicaset"], |
692 | + level=DEBUG, |
693 | + ) |
694 | mongodb_config = mongodb_conf(config_data) |
695 | retVal = update_file(default_mongodb_config, mongodb_config) |
696 | |
697 | - juju_log('enable_replset will return: %s' % str(retVal), level=DEBUG) |
698 | + juju_log("enable_replset will return: %s" % str(retVal), level=DEBUG) |
699 | |
700 | except Exception as e: |
701 | juju_log(str(e), level=WARNING) |
702 | @@ -613,32 +598,29 @@ def remove_replset_from_upstart(): |
703 | try: |
704 | mongodb_init_config = open(default_mongodb_init_config).read() |
705 | |
706 | - if re.search(' --replSet', mongodb_init_config, |
707 | - re.MULTILINE) is not None: |
708 | - mongodb_init_config = re.sub(r' --replSet .\w+', '', |
709 | - mongodb_init_config) |
710 | + if re.search(" --replSet", mongodb_init_config, re.MULTILINE) is not None: |
711 | + mongodb_init_config = re.sub(r" --replSet .\w+", "", mongodb_init_config) |
712 | retVal = update_file(default_mongodb_init_config, mongodb_init_config) |
713 | except Exception as e: |
714 | juju_log(str(e)) |
715 | retVal = False |
716 | finally: |
717 | - return(retVal) |
718 | + return retVal |
719 | |
720 | |
721 | def step_down_replset_primary(): |
722 | """Steps down the primary |
723 | """ |
724 | - retVal = mongo_client('localhost', 'rs.stepDown()') |
725 | + retVal = mongo_client("localhost", "rs.stepDown()") |
726 | for i in range(MONGO_CLIENT_RETRIES): |
727 | if not am_i_primary(): |
728 | - juju_log("step_down_replset_primary returns: %s" % retVal, |
729 | - level=DEBUG) |
730 | - return(retVal) |
731 | + juju_log("step_down_replset_primary returns: %s" % retVal, level=DEBUG) |
732 | + return retVal |
733 | # If we are still primary wait a bit more for step down |
734 | time.sleep(1.5) |
735 | |
736 | # Raise an error if we exhausted the maximum amount of trials |
737 | - raise TimeoutException('Unable to step down the primary') |
738 | + raise TimeoutException("Unable to step down the primary") |
739 | |
740 | |
741 | def remove_rest_from_upstart(): |
742 | @@ -646,23 +628,21 @@ def remove_rest_from_upstart(): |
743 | """ |
744 | try: |
745 | mongodb_init_config = open(default_mongodb_init_config).read() |
746 | - if re.search(' --rest ', mongodb_init_config, |
747 | - re.MULTILINE) is not None: |
748 | - mongodb_init_config = regex_sub([(' --rest ', ' ')], |
749 | - mongodb_init_config) |
750 | + if re.search(" --rest ", mongodb_init_config, re.MULTILINE) is not None: |
751 | + mongodb_init_config = regex_sub([(" --rest ", " ")], mongodb_init_config) |
752 | retVal = update_file(default_mongodb_init_config, mongodb_init_config) |
753 | except Exception as e: |
754 | juju_log(str(e)) |
755 | retVal = False |
756 | finally: |
757 | - return(retVal) |
758 | + return retVal |
759 | |
760 | |
761 | def update_daemon_options(daemon_options=None): |
762 | if is_bionic_or_greater(): |
763 | if daemon_options and daemon_options != "none": |
764 | daemon_opts = 'DAEMON_OPTS="{0}"\n'.format(daemon_options) |
765 | - return(update_file(mongodb_env_config, daemon_opts)) |
766 | + return update_file(mongodb_env_config, daemon_opts) |
767 | else: |
768 | if os.path.exists(mongodb_env_config): |
769 | os.remove(mongodb_env_config) |
770 | @@ -672,95 +652,93 @@ def update_daemon_options(daemon_options=None): |
771 | pat_replace = [] |
772 | if daemon_options is None or daemon_options == "none": |
773 | pat_replace.append( |
774 | - (' --config /etc/mongodb.conf.*', |
775 | - ' --config /etc/mongodb.conf; fi')) |
776 | + (" --config /etc/mongodb.conf.*", " --config /etc/mongodb.conf; fi") |
777 | + ) |
778 | else: |
779 | pat_replace.append( |
780 | - (' --config /etc/mongodb.conf.*', |
781 | - ' --config /etc/mongodb.conf %s; fi' % daemon_options)) |
782 | + ( |
783 | + " --config /etc/mongodb.conf.*", |
784 | + " --config /etc/mongodb.conf %s; fi" % daemon_options, |
785 | + ) |
786 | + ) |
787 | regex_sub(pat_replace, mongodb_init_config) |
788 | - return(update_file(default_mongodb_init_config, mongodb_init_config)) |
789 | + return update_file(default_mongodb_init_config, mongodb_init_config) |
790 | |
791 | |
792 | def enable_arbiter(master_node=None, host=None): |
793 | - juju_log("enable_arbiter: master_node: %s, host: %s" % |
794 | - (master_node, host)) |
795 | + juju_log("enable_arbiter: master_node: %s, host: %s" % (master_node, host)) |
796 | if master_node is None or host is None: |
797 | retVal = False |
798 | else: |
799 | - retVal = mongo_client(master_node, "rs.addArb(\"%s\")" % host) |
800 | + retVal = mongo_client(master_node, 'rs.addArb("%s")' % host) |
801 | juju_log("enable_arbiter returns: %s" % retVal) |
802 | - return(retVal) |
803 | + return retVal |
804 | |
805 | |
806 | def configsvr_status(wait_for=default_wait_for, max_tries=default_max_tries): |
807 | config_data = config() |
808 | current_try = 0 |
809 | |
810 | - while (process_check_pidfile('/var/run/mongodb/configsvr.pid') != ( |
811 | - None, None)) and not port_check( |
812 | - unit_get('private-address'), |
813 | - config_data['config_server_port']) and current_try < max_tries: |
814 | + while ( |
815 | + (process_check_pidfile("/var/run/mongodb/configsvr.pid") != (None, None)) |
816 | + and not port_check( |
817 | + unit_get("private-address"), config_data["config_server_port"] |
818 | + ) |
819 | + and current_try < max_tries |
820 | + ): |
821 | |
822 | juju_log("configsvr_status: Waiting for Config Server to be ready ...") |
823 | time.sleep(wait_for) |
824 | current_try += 1 |
825 | - retVal = (process_check_pidfile('/var/run/mongodb/configsvr.pid') != (None, None) |
826 | - ) == port_check(unit_get('private-address'), |
827 | - config_data['config_server_port']) is True |
828 | + retVal = ( |
829 | + (process_check_pidfile("/var/run/mongodb/configsvr.pid") != (None, None)) |
830 | + == port_check(unit_get("private-address"), config_data["config_server_port"]) |
831 | + is True |
832 | + ) |
833 | if retVal: |
834 | - return(process_check_pidfile('/var/run/mongodb/configsvr.pid')) |
835 | + return process_check_pidfile("/var/run/mongodb/configsvr.pid") |
836 | else: |
837 | - return((None, None)) |
838 | + return (None, None) |
839 | |
840 | |
841 | def configsvr_ready(wait_for=default_wait_for, max_tries=default_max_tries): |
842 | - return(configsvr_status(wait_for, max_tries) != (None, None)) |
843 | + return configsvr_status(wait_for, max_tries) != (None, None) |
844 | |
845 | |
846 | def disable_configsvr(port=None): |
847 | if port is None: |
848 | juju_log("disable_configsvr: port not defined.") |
849 | - return(False) |
850 | + return False |
851 | try: |
852 | - config_server_port = config('config_server_port') |
853 | - pid = open('/var/run/mongodb/configsvr.pid').read() |
854 | + config_server_port = config("config_server_port") |
855 | + pid = open("/var/run/mongodb/configsvr.pid").read() |
856 | os.kill(int(pid), signal.SIGTERM) |
857 | - os.unlink('/var/run/mongodb/configsvr.pid') |
858 | + os.unlink("/var/run/mongodb/configsvr.pid") |
859 | retVal = True |
860 | except Exception as e: |
861 | - juju_log('no config server running ...') |
862 | + juju_log("no config server running ...") |
863 | juju_log("Exception: %s" % str(e)) |
864 | retVal = False |
865 | finally: |
866 | juju_log("disable_configsvr returns %s" % retVal) |
867 | close_port(config_server_port) |
868 | - return(retVal) |
869 | + return retVal |
870 | |
871 | |
872 | -def enable_configsvr(config_data, wait_for=default_wait_for, |
873 | - max_tries=default_max_tries): |
874 | +def enable_configsvr( |
875 | + config_data, wait_for=default_wait_for, max_tries=default_max_tries |
876 | +): |
877 | if config_data is None: |
878 | juju_log("enable_configsvr: config_data not defined.") |
879 | - return(False) |
880 | + return False |
881 | |
882 | # Stop any running config servers |
883 | disable_configsvr(config_data["config_server_port"]) |
884 | |
885 | # Make sure dbpath and logpath exist |
886 | + subprocess.call(["mkdir", "-p", "%s" % config_data["config_server_dbpath"]]) |
887 | subprocess.call( |
888 | - [ |
889 | - 'mkdir', |
890 | - '-p', |
891 | - '%s' % config_data['config_server_dbpath'] |
892 | - ] |
893 | - ) |
894 | - subprocess.call( |
895 | - [ |
896 | - 'mkdir', |
897 | - '-p', |
898 | - '%s' % os.path.dirname(config_data['config_server_logpath']) |
899 | - ] |
900 | + ["mkdir", "-p", "%s" % os.path.dirname(config_data["config_server_logpath"])] |
901 | ) |
902 | |
903 | # Start the config server |
904 | @@ -768,9 +746,9 @@ def enable_configsvr(config_data, wait_for=default_wait_for, |
905 | cmd_line = "mongod" |
906 | cmd_line += " --configsvr" |
907 | cmd_line += " --bind_ip {}".format(choose_bind_ip(config_data["bind_ip"])) |
908 | - cmd_line += " --port %d" % config_data['config_server_port'] |
909 | - cmd_line += " --dbpath %s" % config_data['config_server_dbpath'] |
910 | - cmd_line += " --logpath %s" % config_data['config_server_logpath'] |
911 | + cmd_line += " --port %d" % config_data["config_server_port"] |
912 | + cmd_line += " --dbpath %s" % config_data["config_server_dbpath"] |
913 | + cmd_line += " --logpath %s" % config_data["config_server_logpath"] |
914 | cmd_line += " --pidfilepath /var/run/mongodb/configsvr.pid" |
915 | cmd_line += " --replSet {}".format(config_data["replicaset"]) |
916 | cmd_line += " --fork" |
917 | @@ -778,99 +756,101 @@ def enable_configsvr(config_data, wait_for=default_wait_for, |
918 | |
919 | retVal = configsvr_ready(wait_for, max_tries) |
920 | if retVal: |
921 | - open_port(config_data['config_server_port']) |
922 | - if config_data['web_admin_ui']: |
923 | - port = int(config_data['config_server_port']) + 1000 |
924 | + open_port(config_data["config_server_port"]) |
925 | + if config_data["web_admin_ui"]: |
926 | + port = int(config_data["config_server_port"]) + 1000 |
927 | open_port(port) |
928 | juju_log("enable_configsvr returns: %s" % retVal) |
929 | - return(retVal) |
930 | + return retVal |
931 | |
932 | |
933 | def mongos_status(wait_for=default_wait_for, max_tries=default_max_tries): |
934 | config_data = config() |
935 | current_try = 0 |
936 | - while (process_check_pidfile('/var/run/mongodb/mongos.pid') != ( |
937 | - None, None)) and not port_check( |
938 | - unit_get('private-address'), |
939 | - config_data['mongos_port']) and current_try < max_tries: |
940 | + while ( |
941 | + (process_check_pidfile("/var/run/mongodb/mongos.pid") != (None, None)) |
942 | + and not port_check(unit_get("private-address"), config_data["mongos_port"]) |
943 | + and current_try < max_tries |
944 | + ): |
945 | |
946 | juju_log("mongos_status: Waiting for Mongo shell to be ready ...") |
947 | time.sleep(wait_for) |
948 | current_try += 1 |
949 | - retVal = \ |
950 | - (process_check_pidfile('/var/run/mongodb/mongos.pid') != ( |
951 | - None, None)) == port_check( |
952 | - unit_get('private-address'), |
953 | - config_data['mongos_port']) is True |
954 | + retVal = ( |
955 | + (process_check_pidfile("/var/run/mongodb/mongos.pid") != (None, None)) |
956 | + == port_check(unit_get("private-address"), config_data["mongos_port"]) |
957 | + is True |
958 | + ) |
959 | |
960 | if retVal: |
961 | - return(process_check_pidfile('/var/run/mongodb/mongos.pid')) |
962 | + return process_check_pidfile("/var/run/mongodb/mongos.pid") |
963 | else: |
964 | - return((None, None)) |
965 | + return (None, None) |
966 | |
967 | |
968 | def mongos_ready(wait_for=default_wait_for, max_tries=default_max_tries): |
969 | - return(mongos_status(wait_for, max_tries) != (None, None)) |
970 | + return mongos_status(wait_for, max_tries) != (None, None) |
971 | |
972 | |
973 | def disable_mongos(port=None): |
974 | if port is None: |
975 | juju_log("disable_mongos: port not defined") |
976 | - return(False) |
977 | + return False |
978 | try: |
979 | - pid = open('/var/run/mongodb/mongos.pid').read() |
980 | + pid = open("/var/run/mongodb/mongos.pid").read() |
981 | os.kill(int(pid), signal.SIGTERM) |
982 | - os.unlink('/var/run/mongodb/mongos.pid') |
983 | + os.unlink("/var/run/mongodb/mongos.pid") |
984 | retVal = True |
985 | except Exception as e: |
986 | - juju_log('no mongo router running ...') |
987 | + juju_log("no mongo router running ...") |
988 | juju_log("Exception: %s" % str(e)) |
989 | retVal = False |
990 | finally: |
991 | juju_log("disable_mongos returns %s" % retVal) |
992 | close_port(port) |
993 | - return(retVal) |
994 | + return retVal |
995 | |
996 | |
997 | -def enable_mongos(config_data=None, config_servers=None, replicaset=None, |
998 | - wait_for=default_wait_for, max_tries=default_max_tries): |
999 | +def enable_mongos( |
1000 | + config_data=None, |
1001 | + config_servers=None, |
1002 | + replicaset=None, |
1003 | + wait_for=default_wait_for, |
1004 | + max_tries=default_max_tries, |
1005 | +): |
1006 | juju_log("enable_mongos") |
1007 | if config_data is None or config_servers is None: |
1008 | juju_log("enable_mongos: config_data and config_servers are mandatory") |
1009 | - return(False) |
1010 | + return False |
1011 | if not isinstance(config_servers, list): |
1012 | juju_log("enable_mongos: config_servers must be a list") |
1013 | - return(False) |
1014 | + return False |
1015 | if len(config_servers) < 3: |
1016 | # MongoDB 3.2 deprecates the use of three mirrored mongod instances |
1017 | # for config servers. |
1018 | juju_log("enable_mongos: Not enough config servers yet...") |
1019 | - return(True) |
1020 | + return True |
1021 | disable_mongos() |
1022 | # Make sure logpath exist |
1023 | subprocess.call( |
1024 | - [ |
1025 | - 'mkdir', |
1026 | - '-p', |
1027 | - '%s' % os.path.dirname(config_data['mongos_logpath']) |
1028 | - ] |
1029 | + ["mkdir", "-p", "%s" % os.path.dirname(config_data["mongos_logpath"])] |
1030 | ) |
1031 | cmd_line = "mongos" |
1032 | - cmd_line += " --logpath %s" % config_data['mongos_logpath'] |
1033 | + cmd_line += " --logpath %s" % config_data["mongos_logpath"] |
1034 | cmd_line += " --pidfilepath /var/run/mongodb/mongos.pid" |
1035 | - cmd_line += " --port %d" % config_data['mongos_port'] |
1036 | + cmd_line += " --port %d" % config_data["mongos_port"] |
1037 | cmd_line += " --fork" |
1038 | # Note(aluria): --configdb used to have a list of comma-separated |
1039 | # server:port values. Such list now needs to be prepended by |
1040 | # repSetConfigName/ |
1041 | - cmd_line += ' --configdb {}/{}'.format(replicaset, ','.join(config_servers[0:3])) |
1042 | + cmd_line += " --configdb {}/{}".format(replicaset, ",".join(config_servers[0:3])) |
1043 | juju_log("enable_mongos: cmd_line: %s" % cmd_line) |
1044 | subprocess.call(cmd_line, shell=True) |
1045 | retVal = mongos_ready(wait_for, max_tries) |
1046 | if retVal: |
1047 | - open_port(config_data['mongos_port']) |
1048 | + open_port(config_data["mongos_port"]) |
1049 | juju_log("enable_mongos returns: %s" % retVal) |
1050 | - return(retVal) |
1051 | + return retVal |
1052 | |
1053 | |
1054 | def load_config_servers(mongos_list=None): |
1055 | @@ -878,42 +858,45 @@ def load_config_servers(mongos_list=None): |
1056 | retVal = [line.strip() for line in open(mongos_list).readlines()] |
1057 | else: |
1058 | retVal = [] |
1059 | - return(retVal) |
1060 | + return retVal |
1061 | |
1062 | |
1063 | def restart_mongod(wait_for=default_wait_for, max_tries=default_max_tries): |
1064 | - my_hostname = unit_get('private-address') |
1065 | - my_port = config('port') |
1066 | + my_hostname = unit_get("private-address") |
1067 | + my_port = config("port") |
1068 | current_try = 0 |
1069 | |
1070 | - service('stop', 'mongodb') |
1071 | - if os.path.exists('/var/lib/mongodb/mongod.lock'): |
1072 | - os.remove('/var/lib/mongodb/mongod.lock') |
1073 | + service("stop", "mongodb") |
1074 | + if os.path.exists("/var/lib/mongodb/mongod.lock"): |
1075 | + os.remove("/var/lib/mongodb/mongod.lock") |
1076 | |
1077 | - if not service('start', 'mongodb'): |
1078 | + if not service("start", "mongodb"): |
1079 | return False |
1080 | |
1081 | - while (service('status', 'mongodb') and not port_check( |
1082 | - my_hostname, my_port) and current_try < max_tries): |
1083 | + while ( |
1084 | + service("status", "mongodb") |
1085 | + and not port_check(my_hostname, my_port) |
1086 | + and current_try < max_tries |
1087 | + ): |
1088 | juju_log( |
1089 | "restart_mongod: Waiting for MongoDB to be ready ({}/{})".format( |
1090 | - current_try, max_tries)) |
1091 | + current_try, max_tries |
1092 | + ) |
1093 | + ) |
1094 | time.sleep(wait_for) |
1095 | current_try += 1 |
1096 | |
1097 | - return( |
1098 | - (service('status', 'mongodb') == port_check(my_hostname, |
1099 | - my_port)) is True) |
1100 | + return (service("status", "mongodb") == port_check(my_hostname, my_port)) is True |
1101 | |
1102 | |
1103 | def backup_cronjob(disable=False): |
1104 | """Generate the cronjob to backup with mongodump.""" |
1105 | - juju_log('Setting up cronjob') |
1106 | + juju_log("Setting up cronjob") |
1107 | config_data = config() |
1108 | - backupdir = config_data['backup_directory'] |
1109 | - bind_ip = config_data['bind_ip'] |
1110 | - cron_file = '/etc/cron.d/mongodb' |
1111 | - cron_runtime = '@daily' |
1112 | + backupdir = config_data["backup_directory"] |
1113 | + bind_ip = config_data["bind_ip"] |
1114 | + cron_file = "/etc/cron.d/mongodb" |
1115 | + cron_runtime = "@daily" |
1116 | |
1117 | # Disable or not remove it and regenerate it with new config data. |
1118 | if exists(cron_file): |
1119 | @@ -921,137 +904,143 @@ def backup_cronjob(disable=False): |
1120 | |
1121 | if not disable: |
1122 | tpl_data = { |
1123 | - 'backup_copies': config_data['backup_copies_kept'], |
1124 | - 'backup_directory': backupdir, |
1125 | - 'unique_name': os.environ.get('JUJU_UNIT_NAME', bind_ip), |
1126 | - 'bind_ip': bind_ip, |
1127 | - 'port': config_data['port'], |
1128 | + "backup_copies": config_data["backup_copies_kept"], |
1129 | + "backup_directory": backupdir, |
1130 | + "unique_name": os.environ.get("JUJU_UNIT_NAME", bind_ip), |
1131 | + "bind_ip": bind_ip, |
1132 | + "port": config_data["port"], |
1133 | } |
1134 | |
1135 | - script_filename = '/var/lib/mongodb/cronbackup.py' |
1136 | - script_template = 'templates/backup.py.tpl' |
1137 | + script_filename = "/var/lib/mongodb/cronbackup.py" |
1138 | + script_template = "templates/backup.py.tpl" |
1139 | |
1140 | - juju_log('Writing out cronbackup.py') |
1141 | + juju_log("Writing out cronbackup.py") |
1142 | with open(script_template) as handle: |
1143 | template = Template(handle.read()) |
1144 | rendered = template.substitute(tpl_data) |
1145 | |
1146 | - with open(script_filename, 'w') as output: |
1147 | + with open(script_filename, "w") as output: |
1148 | output.writelines(rendered) |
1149 | chmod(script_filename, 0o755) |
1150 | |
1151 | - juju_log('Installing cron.d/mongodb') |
1152 | + juju_log("Installing cron.d/mongodb") |
1153 | |
1154 | if exists(cron_file): |
1155 | remove(cron_file) |
1156 | |
1157 | - with open(cron_file, 'w') as output: |
1158 | - output.write(""" |
1159 | + with open(cron_file, "w") as output: |
1160 | + output.write( |
1161 | + """ |
1162 | SHELL=/bin/bash |
1163 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin |
1164 | |
1165 | %s ubuntu python %s |
1166 | |
1167 | -""" % (cron_runtime, script_filename)) |
1168 | +""" |
1169 | + % (cron_runtime, script_filename) |
1170 | + ) |
1171 | |
1172 | |
1173 | ############################################################################### |
1174 | # Hook functions |
1175 | ############################################################################### |
1176 | -@hooks.hook('install.real') |
1177 | +@hooks.hook("install.real") |
1178 | def install_hook(): |
1179 | - juju_log('Begin install hook.') |
1180 | + juju_log("Begin install hook.") |
1181 | execd_preinstall() |
1182 | - status_set('maintenance', 'Installing packages') |
1183 | + status_set("maintenance", "Installing packages") |
1184 | juju_log("Installing mongodb") |
1185 | - add_source(config('source'), config('key')) |
1186 | + add_source(config("source"), config("key")) |
1187 | |
1188 | apt_update(fatal=True) |
1189 | apt_install(packages=INSTALL_PACKAGES, fatal=True) |
1190 | |
1191 | |
1192 | -@hooks.hook('config-changed') |
1193 | +@hooks.hook("config-changed") |
1194 | def config_changed(): # noqa: C901 |
1195 | juju_log("Entering config_changed") |
1196 | - status_set('maintenance', 'Configuring unit') |
1197 | + status_set("maintenance", "Configuring unit") |
1198 | config_data = config() |
1199 | juju_log("config_data: {}".format(config_data), level=DEBUG) |
1200 | mongodb_config_hash = file_hash(default_mongodb_config) |
1201 | mongodb_config = open(default_mongodb_config).read() |
1202 | |
1203 | - if config_data.changed('volume-ephemeral-storage') or \ |
1204 | - config_data.changed('volume-map') or \ |
1205 | - config_data.changed('volume-dev-regexp'): |
1206 | + if ( |
1207 | + config_data.changed("volume-ephemeral-storage") |
1208 | + or config_data.changed("volume-map") |
1209 | + or config_data.changed("volume-dev-regexp") |
1210 | + ): |
1211 | config_changed_volume() |
1212 | |
1213 | # current ports |
1214 | - current_mongodb_port = re.search(r'^#*port\s+=\s+(\w+)', |
1215 | - mongodb_config, |
1216 | - re.MULTILINE).group(1) |
1217 | + current_mongodb_port = re.search( |
1218 | + r"^#*port\s+=\s+(\w+)", mongodb_config, re.MULTILINE |
1219 | + ).group(1) |
1220 | |
1221 | current_web_admin_ui_port = int(current_mongodb_port) + 1000 |
1222 | - new_web_admin_ui_port = int(config_data['port']) + 1000 |
1223 | + new_web_admin_ui_port = int(config_data["port"]) + 1000 |
1224 | |
1225 | - juju_log("Configured mongodb port: {}".format(current_mongodb_port), |
1226 | - level=DEBUG) |
1227 | - public_address = unit_get('public-address') |
1228 | + juju_log("Configured mongodb port: {}".format(current_mongodb_port), level=DEBUG) |
1229 | + public_address = unit_get("public-address") |
1230 | juju_log("unit's public_address: {}".format(public_address), level=DEBUG) |
1231 | - private_address = unit_get('private-address') |
1232 | + private_address = unit_get("private-address") |
1233 | juju_log("unit's private_address: {}".format(private_address), level=DEBUG) |
1234 | |
1235 | # Update mongodb configuration file |
1236 | mongodb_config = mongodb_conf(config_data) |
1237 | update_file(default_mongodb_config, mongodb_config) |
1238 | |
1239 | - if config_data['backups_enabled']: |
1240 | + if config_data["backups_enabled"]: |
1241 | backup_cronjob() |
1242 | else: |
1243 | backup_cronjob(disable=True) |
1244 | |
1245 | # web_admin_ui |
1246 | - if config_data['web_admin_ui']: |
1247 | + if config_data["web_admin_ui"]: |
1248 | open_port(new_web_admin_ui_port) |
1249 | else: |
1250 | close_port(current_web_admin_ui_port) |
1251 | |
1252 | # replicaset_master |
1253 | - if config_data['replicaset_master'] != "auto": |
1254 | - enable_replset(config_data['replicaset']) |
1255 | - join_replset(config_data['replicaset_master']) |
1256 | + if config_data["replicaset_master"] != "auto": |
1257 | + enable_replset(config_data["replicaset"]) |
1258 | + join_replset(config_data["replicaset_master"]) |
1259 | |
1260 | # extra demon options |
1261 | - update_daemon_options(config_data['extra_daemon_options']) |
1262 | + update_daemon_options(config_data["extra_daemon_options"]) |
1263 | |
1264 | # write mongodb logrotate configuration file |
1265 | write_logrotate_config(config_data) |
1266 | |
1267 | # restart mongodb if the configuration file has changed. |
1268 | if file_hash(default_mongodb_config) != mongodb_config_hash: |
1269 | - status_set('maintenance', 'Restarting mongod') |
1270 | + status_set("maintenance", "Restarting mongod") |
1271 | restart_mongod() |
1272 | |
1273 | # attach to replSet ( if needed ) |
1274 | - if config_data['replicaset_master'] != "auto": |
1275 | - join_replset(config_data['replicaset_master'], private_address) |
1276 | + if config_data["replicaset_master"] != "auto": |
1277 | + join_replset(config_data["replicaset_master"], private_address) |
1278 | |
1279 | # arbiter |
1280 | - if config_data['replicaset_master'] != 'auto': |
1281 | - if config_data['arbiter'] != "disabled" and\ |
1282 | - config_data['replicaset_master'] != "auto": |
1283 | - if config_data['arbiter'] == 'enable': |
1284 | - enable_arbiter(config_data['replicaset_master'], |
1285 | - "%s:%s" % (private_address, |
1286 | - config_data['port'])) |
1287 | + if config_data["replicaset_master"] != "auto": |
1288 | + if ( |
1289 | + config_data["arbiter"] != "disabled" |
1290 | + and config_data["replicaset_master"] != "auto" |
1291 | + ): |
1292 | + if config_data["arbiter"] == "enable": |
1293 | + enable_arbiter( |
1294 | + config_data["replicaset_master"], |
1295 | + "%s:%s" % (private_address, config_data["port"]), |
1296 | + ) |
1297 | else: |
1298 | - enable_arbiter(config_data['replicaset_master'], |
1299 | - config_data['arbiter']) |
1300 | + enable_arbiter(config_data["replicaset_master"], config_data["arbiter"]) |
1301 | |
1302 | # expose necessary ports |
1303 | - update_service_ports([current_mongodb_port], [config_data['port']]) |
1304 | + update_service_ports([current_mongodb_port], [config_data["port"]]) |
1305 | |
1306 | - if config_data['web_admin_ui']: |
1307 | + if config_data["web_admin_ui"]: |
1308 | current_web_admin_ui_port = int(current_mongodb_port) + 1000 |
1309 | - new_web_admin_ui_port = int(config_data['port']) + 1000 |
1310 | + new_web_admin_ui_port = int(config_data["port"]) + 1000 |
1311 | close_port(current_web_admin_ui_port) |
1312 | open_port(new_web_admin_ui_port) |
1313 | |
1314 | @@ -1065,12 +1054,11 @@ def config_changed(): # noqa: C901 |
1315 | juju_log("config_changed: Exception: %s" % str(e)) |
1316 | |
1317 | if configsvr_pid is not None: |
1318 | - configsvr_port = re.search(r'--port (\w+)', |
1319 | - configsvr_cmd_line).group(2) |
1320 | + configsvr_port = re.search(r"--port (\w+)", configsvr_cmd_line).group(2) |
1321 | disable_configsvr(configsvr_port) |
1322 | - enable_configsvr(config_data['config_server_port']) |
1323 | + enable_configsvr(config_data["config_server_port"]) |
1324 | else: |
1325 | - open_port(config_data['config_server_port']) |
1326 | + open_port(config_data["config_server_port"]) |
1327 | |
1328 | # update mongos information and port |
1329 | try: |
1330 | @@ -1082,90 +1070,93 @@ def config_changed(): # noqa: C901 |
1331 | juju_log("config_changed: Exceptions: %s" % str(e)) |
1332 | |
1333 | if mongos_pid is not None: |
1334 | - mongos_port = re.search(r'--port (\w+)', mongos_cmd_line).group(1) |
1335 | + mongos_port = re.search(r"--port (\w+)", mongos_cmd_line).group(1) |
1336 | disable_mongos(mongos_port) |
1337 | - enable_mongos(config_data['mongos_port']) |
1338 | + enable_mongos(config_data["mongos_port"]) |
1339 | else: |
1340 | - open_port(config_data['mongos_port']) |
1341 | + open_port(config_data["mongos_port"]) |
1342 | |
1343 | update_nrpe_config() |
1344 | application_version_set(get_mongod_version()) |
1345 | update_status() |
1346 | |
1347 | juju_log("About to leave config_changed", level=DEBUG) |
1348 | - return(True) |
1349 | + return True |
1350 | |
1351 | |
1352 | -@hooks.hook('start') |
1353 | +@hooks.hook("start") |
1354 | def start_hook(): |
1355 | juju_log("start_hook") |
1356 | retVal = restart_mongod() |
1357 | juju_log("start_hook returns: %s" % retVal) |
1358 | - return(retVal) |
1359 | + return retVal |
1360 | |
1361 | |
1362 | -@hooks.hook('stop') |
1363 | +@hooks.hook("stop") |
1364 | def stop_hook(): |
1365 | juju_log("stop_hook") |
1366 | try: |
1367 | - retVal = service('stop', 'mongodb') |
1368 | - os.remove('/var/lib/mongodb/mongod.lock') |
1369 | + retVal = service("stop", "mongodb") |
1370 | + os.remove("/var/lib/mongodb/mongod.lock") |
1371 | # FIXME Need to check if this is still needed |
1372 | except Exception as e: |
1373 | juju_log(str(e)) |
1374 | retVal = False |
1375 | finally: |
1376 | juju_log("stop_hook returns: %s" % retVal) |
1377 | - return(retVal) |
1378 | + return retVal |
1379 | |
1380 | |
1381 | -@hooks.hook('database-relation-joined') |
1382 | +@hooks.hook("database-relation-joined") |
1383 | def database_relation_joined(): |
1384 | juju_log("database_relation_joined") |
1385 | - my_hostname = unit_get('private-address') |
1386 | - my_port = config('port') |
1387 | - my_replset = config('replicaset') |
1388 | + my_hostname = unit_get("private-address") |
1389 | + my_port = config("port") |
1390 | + my_replset = config("replicaset") |
1391 | juju_log("my_hostname: %s" % my_hostname) |
1392 | juju_log("my_port: %s" % my_port) |
1393 | juju_log("my_replset: %s" % my_replset) |
1394 | - relation_data = {'hostname': my_hostname, |
1395 | - 'port': my_port, |
1396 | - 'type': 'database', |
1397 | - 'version': get_mongod_version(), |
1398 | - } |
1399 | + relation_data = { |
1400 | + "hostname": my_hostname, |
1401 | + "port": my_port, |
1402 | + "type": "database", |
1403 | + "version": get_mongod_version(), |
1404 | + } |
1405 | |
1406 | - if len(peer_units('replica-set')) > 1: |
1407 | - relation_data['replset'] = my_replset |
1408 | + if len(peer_units("replica-set")) > 1: |
1409 | + relation_data["replset"] = my_replset |
1410 | |
1411 | relation_set(relation_id(), relation_data) |
1412 | |
1413 | |
1414 | -@hooks.hook('replica-set-relation-joined') |
1415 | +@hooks.hook("replica-set-relation-joined") |
1416 | def replica_set_relation_joined(): |
1417 | juju_log("replica_set_relation_joined-start") |
1418 | - my_hostname = unit_get('private-address') |
1419 | - my_port = config('port') |
1420 | - my_replset = config('replicaset') |
1421 | + my_hostname = unit_get("private-address") |
1422 | + my_port = config("port") |
1423 | + my_replset = config("replicaset") |
1424 | |
1425 | - my_install_order = os.environ['JUJU_UNIT_NAME'].split('/')[1] |
1426 | + my_install_order = os.environ["JUJU_UNIT_NAME"].split("/")[1] |
1427 | juju_log("my_hostname: %s" % my_hostname) |
1428 | juju_log("my_port: %s" % my_port) |
1429 | juju_log("my_replset: %s" % my_replset) |
1430 | juju_log("my_install_order: %s" % my_install_order) |
1431 | # do not restart mongodb if config has not changed |
1432 | if enable_replset(my_replset): |
1433 | - juju_log('Restarting mongodb after config change (enable replset)', |
1434 | - level=DEBUG) |
1435 | - status_set('maintenance', 'Restarting mongod to enable replicaset') |
1436 | + juju_log("Restarting mongodb after config change (enable replset)", level=DEBUG) |
1437 | + status_set("maintenance", "Restarting mongod to enable replicaset") |
1438 | restart_mongod() |
1439 | |
1440 | - relation_set(relation_id(), { |
1441 | - 'hostname': my_hostname, |
1442 | - 'port': my_port, |
1443 | - 'replset': my_replset, |
1444 | - 'install-order': my_install_order, |
1445 | - 'type': 'replset', |
1446 | - }) |
1447 | + relation_set( |
1448 | + relation_id(), |
1449 | + { |
1450 | + "hostname": my_hostname, |
1451 | + "port": my_port, |
1452 | + "replset": my_replset, |
1453 | + "install-order": my_install_order, |
1454 | + "type": "replset", |
1455 | + }, |
1456 | + ) |
1457 | |
1458 | update_status() |
1459 | juju_log("replica_set_relation_joined-finish") |
1460 | @@ -1173,24 +1164,29 @@ def replica_set_relation_joined(): |
1461 | |
1462 | def rs_add(host): |
1463 | if not is_bionic_or_greater(): |
1464 | - return mongo_client_smart('localhost', 'rs.add("%s")' % host) |
1465 | + return mongo_client_smart("localhost", 'rs.add("%s")' % host) |
1466 | |
1467 | command = 'rs.add("%s")' % host |
1468 | if host is None: |
1469 | raise ValueError("missing host") |
1470 | else: |
1471 | - cmd_line = ['mongo', '--quiet', '--host', "localhost", |
1472 | - '--eval', 'printjson(%s)' % command] |
1473 | + cmd_line = [ |
1474 | + "mongo", |
1475 | + "--quiet", |
1476 | + "--host", |
1477 | + "localhost", |
1478 | + "--eval", |
1479 | + "printjson(%s)" % command, |
1480 | + ] |
1481 | juju_log("Executing: %s" % cmd_line, level=DEBUG) |
1482 | run(cmd_line) |
1483 | |
1484 | for i in range(MONGO_CLIENT_RETRIES): |
1485 | - c = MongoClient('localhost') |
1486 | + c = MongoClient("localhost") |
1487 | subprocess.check_output(cmd_line) |
1488 | - r = run_admin_command(c, 'replSetGetStatus') |
1489 | + r = run_admin_command(c, "replSetGetStatus") |
1490 | members = r["members"] |
1491 | - ok = [m for m in members |
1492 | - if m['name'] == host and m['state'] == MONGO_SECONDARY] |
1493 | + ok = [m for m in members if m["name"] == host and m["state"] == MONGO_SECONDARY] |
1494 | if ok: |
1495 | return ok |
1496 | |
1497 | @@ -1200,26 +1196,27 @@ def rs_add(host): |
1498 | |
1499 | |
1500 | def am_i_primary(): |
1501 | - c = MongoClient('localhost') |
1502 | + c = MongoClient("localhost") |
1503 | for i in range(10): |
1504 | try: |
1505 | - r = run_admin_command(c, 'replSetGetStatus') |
1506 | + r = run_admin_command(c, "replSetGetStatus") |
1507 | pretty_r = pprint.pformat(r) |
1508 | - juju_log('am_i_primary: replSetGetStatus returned: %s' % pretty_r, |
1509 | - level=DEBUG) |
1510 | - return r['myState'] == MONGO_PRIMARY |
1511 | + juju_log( |
1512 | + "am_i_primary: replSetGetStatus returned: %s" % pretty_r, level=DEBUG |
1513 | + ) |
1514 | + return r["myState"] == MONGO_PRIMARY |
1515 | except OperationFailure as e: |
1516 | - juju_log('am_i_primary: OperationError: %s' % str(e), level=DEBUG) |
1517 | - if 'replSetInitiate - should come online shortly' in str(e): |
1518 | + juju_log("am_i_primary: OperationError: %s" % str(e), level=DEBUG) |
1519 | + if "replSetInitiate - should come online shortly" in str(e): |
1520 | # replSet initialization in progress |
1521 | continue |
1522 | - elif 'EMPTYCONFIG' in str(e): |
1523 | + elif "EMPTYCONFIG" in str(e): |
1524 | # replication not initialized yet |
1525 | return False |
1526 | - elif 'no replset config has been received' in str(e): |
1527 | + elif "no replset config has been received" in str(e): |
1528 | # replication not initialized yet (Mongo3.4+) |
1529 | return False |
1530 | - elif 'not running with --replSet' in str(e): |
1531 | + elif "not running with --replSet" in str(e): |
1532 | # replicaset not configured |
1533 | return False |
1534 | else: |
1535 | @@ -1228,7 +1225,7 @@ def am_i_primary(): |
1536 | time.sleep(1.5) |
1537 | |
1538 | # Raise an error if we exhausted the maximum amount of trials |
1539 | - raise TimeoutException('Unable to determine if local unit is primary') |
1540 | + raise TimeoutException("Unable to determine if local unit is primary") |
1541 | |
1542 | |
1543 | def get_replicaset_status(): |
1544 | @@ -1241,24 +1238,26 @@ def get_replicaset_status(): |
1545 | or can be the string of an exception while getting the status |
1546 | """ |
1547 | |
1548 | - c = MongoClient('localhost') |
1549 | + c = MongoClient("localhost") |
1550 | try: |
1551 | - r = run_admin_command(c, 'replSetGetStatus') |
1552 | - for member in r['members']: |
1553 | - if 'self' in member: |
1554 | - return member['stateStr'] |
1555 | + r = run_admin_command(c, "replSetGetStatus") |
1556 | + for member in r["members"]: |
1557 | + if "self" in member: |
1558 | + return member["stateStr"] |
1559 | |
1560 | # if 'self' was not found in the output, then log a warning and print |
1561 | # the output given by replSetGetStatus |
1562 | r_pretty = pprint.pformat(r) |
1563 | - juju_log('get_replicaset_status() failed to get replicaset state: ' |
1564 | - '%s' % r_pretty, level=WARNING) |
1565 | - return 'Unknown replica set state' |
1566 | + juju_log( |
1567 | + "get_replicaset_status() failed to get replicaset state: %s" % r_pretty, |
1568 | + level=WARNING, |
1569 | + ) |
1570 | + return "Unknown replica set state" |
1571 | |
1572 | except OperationFailure as e: |
1573 | - juju_log('get_replicaset_status() exception: %s' % str(e), DEBUG) |
1574 | - if 'not running with --replSet' in str(e): |
1575 | - return 'not in replicaset' |
1576 | + juju_log("get_replicaset_status() exception: %s" % str(e), DEBUG) |
1577 | + if "not running with --replSet" in str(e): |
1578 | + return "not in replicaset" |
1579 | else: |
1580 | return str(e) |
1581 | |
1582 | @@ -1268,8 +1267,8 @@ def get_mongod_version(): |
1583 | Mainly used for application_set_version in config-changed hook |
1584 | """ |
1585 | |
1586 | - c = MongoClient('localhost', serverSelectionTimeoutMS=60000) |
1587 | - return c.server_info()['version'] |
1588 | + c = MongoClient("localhost", serverSelectionTimeoutMS=60000) |
1589 | + return c.server_info()["version"] |
1590 | |
1591 | |
1592 | # Retry until the replica set is in active state, |
1593 | @@ -1279,301 +1278,302 @@ def get_mongod_version(): |
1594 | @retry_on_exception(num_retries=45, base_delay=1) |
1595 | def wait_until_replset_is_active(): |
1596 | status = update_status() |
1597 | - if status != 'active': |
1598 | - raise Exception('ReplicaSet not active: {}'.format(status)) |
1599 | + if status != "active": |
1600 | + raise Exception("ReplicaSet not active: {}".format(status)) |
1601 | |
1602 | |
1603 | -@hooks.hook('replica-set-relation-changed') |
1604 | +@hooks.hook("replica-set-relation-changed") |
1605 | def replica_set_relation_changed(): |
1606 | - private_address = unit_get('private-address') |
1607 | - remote_hostname = relation_get('hostname') |
1608 | + private_address = unit_get("private-address") |
1609 | + remote_hostname = relation_get("hostname") |
1610 | |
1611 | - juju_log('replica_set_relation_changed-start') |
1612 | - juju_log('local unit: %s, joining_unit: %s' % (private_address, |
1613 | - remote_hostname), |
1614 | - level=DEBUG) |
1615 | + juju_log("replica_set_relation_changed-start") |
1616 | + juju_log( |
1617 | + "local unit: %s, joining_unit: %s" % (private_address, remote_hostname), |
1618 | + level=DEBUG, |
1619 | + ) |
1620 | |
1621 | if remote_hostname is None: |
1622 | - juju_log('Joiner not ready yet... bailing out') |
1623 | + juju_log("Joiner not ready yet... bailing out") |
1624 | return |
1625 | |
1626 | # Initialize the replicaset - we do this only on the leader! |
1627 | if is_leader(): |
1628 | - juju_log('Initializing replicaset') |
1629 | - status_set('maintenance', 'Initializing replicaset') |
1630 | + juju_log("Initializing replicaset") |
1631 | + status_set("maintenance", "Initializing replicaset") |
1632 | init_replset() |
1633 | |
1634 | - unit = "%s:%s" % (private_address, config('port')) |
1635 | - unit_remote = "%s:%s" % (remote_hostname, relation_get('port')) |
1636 | + unit = "%s:%s" % (private_address, config("port")) |
1637 | + unit_remote = "%s:%s" % (remote_hostname, relation_get("port")) |
1638 | |
1639 | # If this is primary, add joined unit to replicaset |
1640 | if am_i_primary(): |
1641 | - juju_log('Adding new secondary... %s' % unit_remote, level=DEBUG) |
1642 | + juju_log("Adding new secondary... %s" % unit_remote, level=DEBUG) |
1643 | join_replset(unit, unit_remote) |
1644 | |
1645 | wait_until_replset_is_active() |
1646 | - juju_log('replica_set_relation_changed-finish') |
1647 | + juju_log("replica_set_relation_changed-finish") |
1648 | |
1649 | |
1650 | -@hooks.hook('replica-set-relation-departed') |
1651 | +@hooks.hook("replica-set-relation-departed") |
1652 | def replica_set_relation_departed(): |
1653 | - juju_log('replica_set_relation_departed-start') |
1654 | + juju_log("replica_set_relation_departed-start") |
1655 | |
1656 | if not am_i_primary(): |
1657 | - juju_log('replica_set_relation_departed-finish') |
1658 | + juju_log("replica_set_relation_departed-finish") |
1659 | return |
1660 | |
1661 | - unit_address, unit_port = unit_get('private-address'), config('port') |
1662 | - remote_address = relation_get('private-address') |
1663 | - remote_port = relation_get('port') |
1664 | + unit_address, unit_port = unit_get("private-address"), config("port") |
1665 | + remote_address = relation_get("private-address") |
1666 | + remote_port = relation_get("port") |
1667 | |
1668 | # If I am the unit being removed, step me down from being primary |
1669 | if (unit_address, unit_port) == (remote_address, remote_port): |
1670 | - juju_log('Stepping down from being primary...') |
1671 | + juju_log("Stepping down from being primary...") |
1672 | global was_i_primary |
1673 | was_i_primary = True |
1674 | - mongo_client('localhost', 'rs.stepDown()') |
1675 | - juju_log('replica_set_relation_departed-finish') |
1676 | + mongo_client("localhost", "rs.stepDown()") |
1677 | + juju_log("replica_set_relation_departed-finish") |
1678 | return |
1679 | |
1680 | - unit = "%s:%s" % (unit_get('private-address'), |
1681 | - config('port')) |
1682 | - unit_remote = "%s:%s" % (relation_get('hostname'), |
1683 | - relation_get('port')) |
1684 | + unit = "%s:%s" % (unit_get("private-address"), config("port")) |
1685 | + unit_remote = "%s:%s" % (relation_get("hostname"), relation_get("port")) |
1686 | |
1687 | leave_replset(unit, unit_remote) |
1688 | - juju_log('Removed %s from replicaset' % unit_remote) |
1689 | - juju_log('replica_set_relation_departed-finish') |
1690 | + juju_log("Removed %s from replicaset" % unit_remote) |
1691 | + juju_log("replica_set_relation_departed-finish") |
1692 | |
1693 | |
1694 | -@hooks.hook('replica-set-relation-broken') |
1695 | +@hooks.hook("replica-set-relation-broken") |
1696 | def replica_set_relation_broken(): |
1697 | - juju_log('replica_set_relation_broken-start') |
1698 | + juju_log("replica_set_relation_broken-start") |
1699 | |
1700 | if am_i_primary(): |
1701 | - juju_log('I was primary - removing myself via new primary.', 'DEBUG') |
1702 | - mongo_client('localhost', 'rs.stepDown()') |
1703 | - time.sleep(15) # give some time to for re-election to happen |
1704 | + juju_log("I was primary - removing myself via new primary.", "DEBUG") |
1705 | + mongo_client("localhost", "rs.stepDown()") |
1706 | + time.sleep(15) # give some time to for re-election to happen |
1707 | |
1708 | - c = MongoClient('localhost') |
1709 | - r = c.admin.command('isMaster') |
1710 | + c = MongoClient("localhost") |
1711 | + r = c.admin.command("isMaster") |
1712 | |
1713 | try: |
1714 | - master_node = r['primary'] |
1715 | + master_node = r["primary"] |
1716 | except KeyError: |
1717 | pass |
1718 | |
1719 | - if 'master_node' in locals(): # unit is part of replicaset, remove it! |
1720 | - unit = "%s:%s" % (unit_get('private-address'), config('port')) |
1721 | - juju_log('Removing myself via %s' % (master_node), 'DEBUG') |
1722 | + if "master_node" in locals(): # unit is part of replicaset, remove it! |
1723 | + unit = "%s:%s" % (unit_get("private-address"), config("port")) |
1724 | + juju_log("Removing myself via %s" % (master_node), "DEBUG") |
1725 | leave_replset(master_node, unit) |
1726 | |
1727 | - juju_log('replica_set_relation_broken-finish') |
1728 | + juju_log("replica_set_relation_broken-finish") |
1729 | |
1730 | |
1731 | -@hooks.hook('data-relation-joined') |
1732 | +@hooks.hook("data-relation-joined") |
1733 | def data_relation_joined(): |
1734 | juju_log("data_relation_joined") |
1735 | |
1736 | - return relation_set(relation_id(), |
1737 | - {'mountpoint': '/srv/juju/mongodb-data'}) |
1738 | + return relation_set(relation_id(), {"mountpoint": "/srv/juju/mongodb-data"}) |
1739 | |
1740 | |
1741 | -@hooks.hook('data-relation-changed') |
1742 | +@hooks.hook("data-relation-changed") |
1743 | def data_relation_changed(): |
1744 | juju_log("data_relation_changed") |
1745 | |
1746 | if volume_get_id_for_storage_subordinate() is None: |
1747 | juju_log("mountpoint from storage subordinate not ready, let's wait") |
1748 | - return(True) |
1749 | + return True |
1750 | |
1751 | config_changed_volume() |
1752 | |
1753 | |
1754 | -@hooks.hook('data-relation-departed') |
1755 | +@hooks.hook("data-relation-departed") |
1756 | def data_relation_departed(): |
1757 | juju_log("data_relation_departed") |
1758 | - return(config_changed_volume()) |
1759 | + return config_changed_volume() |
1760 | |
1761 | |
1762 | -@hooks.hook('configsvr-relation-joined') |
1763 | +@hooks.hook("configsvr-relation-joined") |
1764 | def configsvr_relation_joined(): |
1765 | juju_log("configsvr_relation_joined") |
1766 | - my_hostname = unit_get('private-address') |
1767 | - my_port = config('config_server_port') |
1768 | - my_install_order = os.environ['JUJU_UNIT_NAME'].split('/')[1] |
1769 | - my_replicaset = config('replicaset') |
1770 | - relation_set(relation_id(), { |
1771 | - 'hostname': my_hostname, |
1772 | - 'port': my_port, |
1773 | - 'install-order': my_install_order, |
1774 | - 'replset': my_replicaset, |
1775 | - 'type': 'configsvr', |
1776 | - }) |
1777 | - |
1778 | - |
1779 | -@hooks.hook('configsvr-relation-changed') |
1780 | + my_hostname = unit_get("private-address") |
1781 | + my_port = config("config_server_port") |
1782 | + my_install_order = os.environ["JUJU_UNIT_NAME"].split("/")[1] |
1783 | + my_replicaset = config("replicaset") |
1784 | + relation_set( |
1785 | + relation_id(), |
1786 | + { |
1787 | + "hostname": my_hostname, |
1788 | + "port": my_port, |
1789 | + "install-order": my_install_order, |
1790 | + "replset": my_replicaset, |
1791 | + "type": "configsvr", |
1792 | + }, |
1793 | + ) |
1794 | + |
1795 | + |
1796 | +@hooks.hook("configsvr-relation-changed") |
1797 | def configsvr_relation_changed(): |
1798 | juju_log("configsvr_relation_changed") |
1799 | config_data = config() |
1800 | - my_port = config_data['config_server_port'] |
1801 | + my_port = config_data["config_server_port"] |
1802 | disable_configsvr(my_port) |
1803 | retVal = enable_configsvr(config_data) |
1804 | juju_log("configsvr_relation_changed returns: %s" % retVal) |
1805 | - return(retVal) |
1806 | + return retVal |
1807 | |
1808 | |
1809 | -@hooks.hook('mongos-cfg-relation-joined') |
1810 | -@hooks.hook('mongos-relation-joined') |
1811 | +@hooks.hook("mongos-cfg-relation-joined") |
1812 | +@hooks.hook("mongos-relation-joined") |
1813 | def mongos_relation_joined(): |
1814 | juju_log("mongos_relation_joined") |
1815 | - my_hostname = unit_get('private-address') |
1816 | - my_port = config('mongos_port') |
1817 | - my_install_order = os.environ['JUJU_UNIT_NAME'].split('/')[1] |
1818 | - my_replicaset = config('replicaset') |
1819 | - relation_set(relation_id(), { |
1820 | - 'hostname': my_hostname, |
1821 | - 'port': my_port, |
1822 | - 'install-order': my_install_order, |
1823 | - 'replset': my_replicaset, |
1824 | - 'type': 'mongos' |
1825 | - }) |
1826 | - |
1827 | - |
1828 | -@hooks.hook('mongos-cfg-relation-changed') |
1829 | -@hooks.hook('mongos-relation-changed') |
1830 | + my_hostname = unit_get("private-address") |
1831 | + my_port = config("mongos_port") |
1832 | + my_install_order = os.environ["JUJU_UNIT_NAME"].split("/")[1] |
1833 | + my_replicaset = config("replicaset") |
1834 | + relation_set( |
1835 | + relation_id(), |
1836 | + { |
1837 | + "hostname": my_hostname, |
1838 | + "port": my_port, |
1839 | + "install-order": my_install_order, |
1840 | + "replset": my_replicaset, |
1841 | + "type": "mongos", |
1842 | + }, |
1843 | + ) |
1844 | + |
1845 | + |
1846 | +@hooks.hook("mongos-cfg-relation-changed") |
1847 | +@hooks.hook("mongos-relation-changed") |
1848 | def mongos_relation_changed(): |
1849 | juju_log("mongos_relation_changed") |
1850 | config_data = config() |
1851 | retVal = False |
1852 | |
1853 | - hostname = relation_get('hostname') |
1854 | - port = relation_get('port') |
1855 | - replicaset = relation_get('replset') |
1856 | - rel_type = relation_get('type') |
1857 | + hostname = relation_get("hostname") |
1858 | + port = relation_get("port") |
1859 | + replicaset = relation_get("replset") |
1860 | + rel_type = relation_get("type") |
1861 | if hostname is None or port is None or rel_type is None: |
1862 | - juju_log("mongos_relation_changed: relation data not ready.", |
1863 | - level=DEBUG) |
1864 | + juju_log("mongos_relation_changed: relation data not ready.", level=DEBUG) |
1865 | return |
1866 | - if rel_type == 'configsvr': |
1867 | + if rel_type == "configsvr": |
1868 | config_servers = load_config_servers(default_mongos_list) |
1869 | juju_log("Adding config server: %s:%s" % (hostname, port), level=DEBUG) |
1870 | if hostname and port and "{}:{}".format(hostname, port) not in config_servers: |
1871 | config_servers.append("%s:%s" % (hostname, port)) |
1872 | - disable_mongos(config_data['mongos_port']) |
1873 | + disable_mongos(config_data["mongos_port"]) |
1874 | retVal = enable_mongos(config_data, config_servers, replicaset) |
1875 | if retVal: |
1876 | - update_file(default_mongos_list, '\n'.join(config_servers)) |
1877 | - elif rel_type == 'database': |
1878 | + update_file(default_mongos_list, "\n".join(config_servers)) |
1879 | + elif rel_type == "database": |
1880 | if mongos_ready(): |
1881 | - mongos_host = "%s:%s" % ( |
1882 | - unit_get('private-address'), |
1883 | - config('mongos_port')) |
1884 | - shard_command1 = "sh.addShard(\"%s:%s\")" % (hostname, port) |
1885 | + mongos_host = "%s:%s" % (unit_get("private-address"), config("mongos_port")) |
1886 | + shard_command1 = 'sh.addShard("%s:%s")' % (hostname, port) |
1887 | mongo_client(mongos_host, shard_command1) |
1888 | - replicaset = relation_get('replset') |
1889 | - shard_command2 = "sh.addShard(\"%s/%s:%s\")" % \ |
1890 | - (replicaset, hostname, port) |
1891 | + replicaset = relation_get("replset") |
1892 | + shard_command2 = 'sh.addShard("%s/%s:%s")' % (replicaset, hostname, port) |
1893 | mongo_client(mongos_host, shard_command2) |
1894 | |
1895 | else: |
1896 | - juju_log("mongos_relation_change: undefined rel_type: %s" % rel_type, |
1897 | - level=DEBUG) |
1898 | + juju_log( |
1899 | + "mongos_relation_change: undefined rel_type: %s" % rel_type, level=DEBUG |
1900 | + ) |
1901 | return |
1902 | |
1903 | juju_log("mongos_relation_changed returns: %s" % retVal, level=DEBUG) |
1904 | |
1905 | |
1906 | -@hooks.hook('mongos-relation-broken') |
1907 | +@hooks.hook("mongos-relation-broken") |
1908 | def mongos_relation_broken(): |
1909 | config_servers = load_config_servers(default_mongos_list) |
1910 | - for member in relations_of_type('mongos'): |
1911 | - hostname = relation_get('hostname', member) |
1912 | - port = relation_get('port', member) |
1913 | - if '%s:%s' % (hostname, port) in config_servers: |
1914 | - config_servers.remove('%s:%s' % (hostname, port)) |
1915 | + for member in relations_of_type("mongos"): |
1916 | + hostname = relation_get("hostname", member) |
1917 | + port = relation_get("port", member) |
1918 | + if "%s:%s" % (hostname, port) in config_servers: |
1919 | + config_servers.remove("%s:%s" % (hostname, port)) |
1920 | |
1921 | - update_file(default_mongos_list, '\n'.join(config_servers)) |
1922 | + update_file(default_mongos_list, "\n".join(config_servers)) |
1923 | |
1924 | |
1925 | -@hooks.hook('nrpe-external-master-relation-joined', |
1926 | - 'nrpe-external-master-relation-changed') |
1927 | +@hooks.hook( |
1928 | + "nrpe-external-master-relation-joined", "nrpe-external-master-relation-changed" |
1929 | +) |
1930 | def update_nrpe_config(): |
1931 | # Find out if nrpe set nagios_hostname |
1932 | hostname = None |
1933 | host_context = None |
1934 | - for rel in relations_of_type('nrpe-external-master'): |
1935 | - if 'nagios_hostname' in rel: |
1936 | - hostname = rel['nagios_hostname'] |
1937 | - host_context = rel['nagios_host_context'] |
1938 | + for rel in relations_of_type("nrpe-external-master"): |
1939 | + if "nagios_hostname" in rel: |
1940 | + hostname = rel["nagios_hostname"] |
1941 | + host_context = rel["nagios_host_context"] |
1942 | break |
1943 | nrpe = NRPE(hostname=hostname) |
1944 | - apt_install('python3-dbus') |
1945 | + apt_install("python3-dbus") |
1946 | |
1947 | if host_context: |
1948 | current_unit = "%s:%s" % (host_context, local_unit()) |
1949 | else: |
1950 | current_unit = local_unit() |
1951 | |
1952 | - if lsb_release()['DISTRIB_RELEASE'] > '15.04': |
1953 | - check_mongo_script = 'check_systemd.py mongodb' |
1954 | + if lsb_release()["DISTRIB_RELEASE"] > "15.04": |
1955 | + check_mongo_script = "check_systemd.py mongodb" |
1956 | else: |
1957 | - check_mongo_script = 'check_upstart_job mongodb' |
1958 | + check_mongo_script = "check_upstart_job mongodb" |
1959 | |
1960 | nrpe.add_check( |
1961 | - shortname='mongodb', |
1962 | - description='process check {%s}' % current_unit, |
1963 | + shortname="mongodb", |
1964 | + description="process check {%s}" % current_unit, |
1965 | check_cmd=check_mongo_script, |
1966 | ) |
1967 | |
1968 | nrpe.write() |
1969 | |
1970 | |
1971 | -@hooks.hook('upgrade-charm') |
1972 | +@hooks.hook("upgrade-charm") |
1973 | def uprade_charm(): |
1974 | - juju_log('upgrade-charm: removing --replset from upstart script') |
1975 | + juju_log("upgrade-charm: removing --replset from upstart script") |
1976 | remove_replset_from_upstart() |
1977 | - juju_log('upgrade-charm: removing --rest from upstart script') |
1978 | + juju_log("upgrade-charm: removing --rest from upstart script") |
1979 | remove_rest_from_upstart() |
1980 | |
1981 | |
1982 | -@hooks.hook('update-status') |
1983 | +@hooks.hook("update-status") |
1984 | def update_status(): |
1985 | """ |
1986 | Returns: workload_state (so that some hooks know they need to re-run |
1987 | update_status if needed) |
1988 | """ |
1989 | |
1990 | - workload = 'active' |
1991 | - status = 'Unit is ready' |
1992 | + workload = "active" |
1993 | + status = "Unit is ready" |
1994 | |
1995 | - if is_relation_made('replica-set'): |
1996 | + if is_relation_made("replica-set"): |
1997 | # only check for replica-set state if the relation was made which means |
1998 | # more than 1 units were deployed and peer related. |
1999 | mongo_status = get_replicaset_status() |
2000 | - if mongo_status in ('PRIMARY', 'SECONDARY'): |
2001 | - workload = 'active' |
2002 | - status = 'Unit is ready as ' + mongo_status |
2003 | - elif mongo_status in ('not in replicaset',): |
2004 | - workload = 'active' |
2005 | - status = 'Unit is ready, ' + mongo_status |
2006 | + if mongo_status in ("PRIMARY", "SECONDARY"): |
2007 | + workload = "active" |
2008 | + status = "Unit is ready as " + mongo_status |
2009 | + elif mongo_status in ("not in replicaset"): |
2010 | + workload = "active" |
2011 | + status = "Unit is ready, " + mongo_status |
2012 | else: |
2013 | - workload = 'maintenance' |
2014 | + workload = "maintenance" |
2015 | status = mongo_status |
2016 | - juju_log('mongo_status is unknown: {}'.format(status), level=DEBUG) |
2017 | + juju_log("mongo_status is unknown: {}".format(status), level=DEBUG) |
2018 | |
2019 | - juju_log('Setting workload: {} - {}'.format(workload, status), level=DEBUG) |
2020 | + juju_log("Setting workload: {} - {}".format(workload, status), level=DEBUG) |
2021 | status_set(workload, status) |
2022 | |
2023 | return workload |
2024 | |
2025 | |
2026 | def run(command, exit_on_error=True): |
2027 | - '''Run a command and return the output.''' |
2028 | + """Run a command and return the output.""" |
2029 | try: |
2030 | juju_log(command) |
2031 | - return subprocess.check_output( |
2032 | - command, stderr=subprocess.STDOUT, shell=True) |
2033 | + return subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) |
2034 | except subprocess.CalledProcessError as e: |
2035 | juju_log("status=%d, output=%s" % (e.returncode, e.output)) |
2036 | if exit_on_error: |
2037 | @@ -1594,9 +1594,9 @@ def volume_get_volid_from_volume_map(): |
2038 | config_data = config() |
2039 | volume_map = {} |
2040 | try: |
2041 | - volume_map = yaml.load(config_data['volume-map'].strip()) |
2042 | + volume_map = yaml.load(config_data["volume-map"].strip()) |
2043 | if volume_map: |
2044 | - juju_unit_name = os.environ['JUJU_UNIT_NAME'] |
2045 | + juju_unit_name = os.environ["JUJU_UNIT_NAME"] |
2046 | volid = volume_map.get(juju_unit_name) |
2047 | juju_log("Juju unit name: %s Volid:%s" % (juju_unit_name, volid)) |
2048 | return volid |
2049 | @@ -1631,15 +1631,13 @@ def volume_mount_point_from_volid(volid): |
2050 | def volume_get_id_for_storage_subordinate(): |
2051 | # storage charm is a subordinate so we should only ever have one |
2052 | # relation_id for the data relation |
2053 | - ids = relation_ids('data') |
2054 | + ids = relation_ids("data") |
2055 | if len(ids) > 0: |
2056 | - mountpoint = relation_get('mountpoint', |
2057 | - os.environ['JUJU_UNIT_NAME'], |
2058 | - ids[0]) |
2059 | + mountpoint = relation_get("mountpoint", os.environ["JUJU_UNIT_NAME"], ids[0]) |
2060 | |
2061 | - juju_log('mountpoint: %s' % (mountpoint,)) |
2062 | + juju_log("mountpoint: %s" % (mountpoint)) |
2063 | if mountpoint and os.path.exists(mountpoint): |
2064 | - return mountpoint.split('/')[-1] |
2065 | + return mountpoint.split("/")[-1] |
2066 | |
2067 | |
2068 | # Do we have a valid storage state? |
2069 | @@ -1652,14 +1650,15 @@ def volume_get_volume_id(): |
2070 | if volid: |
2071 | return volid |
2072 | |
2073 | - ephemeral_storage = config_data['volume-ephemeral-storage'] |
2074 | + ephemeral_storage = config_data["volume-ephemeral-storage"] |
2075 | volid = volume_get_volid_from_volume_map() |
2076 | - juju_unit_name = os.environ['JUJU_UNIT_NAME'] |
2077 | - if ephemeral_storage in [True, 'yes', 'Yes', 'true', 'True']: |
2078 | + juju_unit_name = os.environ["JUJU_UNIT_NAME"] |
2079 | + if ephemeral_storage in [True, "yes", "Yes", "true", "True"]: |
2080 | if volid: |
2081 | juju_log( |
2082 | "volume-ephemeral-storage is True, but" |
2083 | - "volume-map[{!r}] -> {}".format(juju_unit_name, volid)) |
2084 | + "volume-map[{!r}] -> {}".format(juju_unit_name, volid) |
2085 | + ) |
2086 | return None |
2087 | else: |
2088 | return "--ephemeral" |
2089 | @@ -1667,8 +1666,8 @@ def volume_get_volume_id(): |
2090 | if not volid: |
2091 | juju_log( |
2092 | "volume-ephemeral-storage is False, but " |
2093 | - "no volid found for volume-map[{!r}]".format( |
2094 | - juju_unit_name)) |
2095 | + "no volid found for volume-map[{!r}]".format(juju_unit_name) |
2096 | + ) |
2097 | return None |
2098 | juju_log("Volid:%s" % (volid)) |
2099 | return volid |
2100 | @@ -1687,7 +1686,8 @@ def config_changed_volume(): |
2101 | juju_log( |
2102 | "Disabled and stopped mongodb service, " |
2103 | "because of broken volume configuration - check " |
2104 | - "'volume-ephemeral-storage' and 'volume-map'") |
2105 | + "'volume-ephemeral-storage' and 'volume-map'" |
2106 | + ) |
2107 | sys.exit(1) |
2108 | if volume_is_permanent(volid): |
2109 | # config_changed_volume_apply will stop the service if it finds |
2110 | @@ -1701,7 +1701,8 @@ def config_changed_volume(): |
2111 | juju_log("current mounted volumes: {}".format(mounts)) |
2112 | juju_log( |
2113 | "Disabled and stopped mongodb service " |
2114 | - "(config_changed_volume_apply failure)") |
2115 | + "(config_changed_volume_apply failure)" |
2116 | + ) |
2117 | sys.exit(1) |
2118 | |
2119 | |
2120 | @@ -1709,14 +1710,13 @@ def config_changed_volume(): |
2121 | # shell helper |
2122 | def volume_init_and_mount(volid): |
2123 | juju_log("Initialize and mount volume") |
2124 | - command = ("scripts/volume-common.sh call " |
2125 | - "volume_init_and_mount %s" % volid) |
2126 | + command = "scripts/volume-common.sh call volume_init_and_mount %s" % volid |
2127 | run(command) |
2128 | return True |
2129 | |
2130 | |
2131 | def volume_get_all_mounted(): |
2132 | - command = ("mount |egrep /srv/juju") |
2133 | + command = "mount |egrep /srv/juju" |
2134 | status, output = subprocess.getstatusoutput(command) |
2135 | if status != 0: |
2136 | return None |
2137 | @@ -1736,20 +1736,20 @@ def volume_get_all_mounted(): |
2138 | def config_changed_volume_apply(): # noqa: C901 is too complex (12) |
2139 | config_data = config() |
2140 | data_directory_path = config_data["dbpath"] |
2141 | - assert(data_directory_path) |
2142 | + assert data_directory_path |
2143 | volid = volume_get_volume_id() |
2144 | if volid: |
2145 | volid_from_subordinate = volume_get_id_for_storage_subordinate() |
2146 | if volume_is_permanent(volid) and not volid_from_subordinate: |
2147 | if not volume_init_and_mount(volid): |
2148 | - juju_log( |
2149 | - "volume_init_and_mount failed, not applying changes") |
2150 | + juju_log("volume_init_and_mount failed, not applying changes") |
2151 | return False |
2152 | |
2153 | if not os.path.exists(data_directory_path): |
2154 | juju_log( |
2155 | "mongodb data dir {} not found, " |
2156 | - "not applying changes.".format(data_directory_path)) |
2157 | + "not applying changes.".format(data_directory_path) |
2158 | + ) |
2159 | return False |
2160 | |
2161 | mount_point = volume_mount_point_from_volid(volid) |
2162 | @@ -1757,18 +1757,21 @@ def config_changed_volume_apply(): # noqa: C901 is too complex (12) |
2163 | if not mount_point: |
2164 | juju_log( |
2165 | "invalid mount point from volid = {}, " |
2166 | - "not applying changes.".format(mount_point)) |
2167 | + "not applying changes.".format(mount_point) |
2168 | + ) |
2169 | return False |
2170 | |
2171 | if os.path.islink(data_directory_path): |
2172 | juju_log( |
2173 | "mongodb data dir '%s' already points " |
2174 | - "to %s, skipping storage changes." % (data_directory_path, |
2175 | - new_mongo_dir)) |
2176 | + "to %s, skipping storage changes." |
2177 | + % (data_directory_path, new_mongo_dir) |
2178 | + ) |
2179 | juju_log( |
2180 | "existing-symlink: to fix/avoid UID changes from " |
2181 | "previous units, doing: " |
2182 | - "chown -R mongodb:mongodb {}".format(new_mongo_dir)) |
2183 | + "chown -R mongodb:mongodb {}".format(new_mongo_dir) |
2184 | + ) |
2185 | run("chown -R mongodb:mongodb %s" % new_mongo_dir) |
2186 | return True |
2187 | |
2188 | @@ -1791,41 +1794,47 @@ def config_changed_volume_apply(): # noqa: C901 is too complex (12) |
2189 | juju_log("stop_hook() failed - can't migrate data.") |
2190 | return False |
2191 | if not os.path.exists(new_mongo_dir) or new_mongo_dir_just_created: |
2192 | - juju_log("migrating mongo data {}/ -> {}/".format( |
2193 | - data_directory_path, new_mongo_dir)) |
2194 | + juju_log( |
2195 | + "migrating mongo data {}/ -> {}/".format( |
2196 | + data_directory_path, new_mongo_dir |
2197 | + ) |
2198 | + ) |
2199 | # void copying PID file to perm storage (shouldn't be any...) |
2200 | - command = "rsync -a {}/ {}/".format( |
2201 | - data_directory_path, new_mongo_dir) |
2202 | + command = "rsync -a {}/ {}/".format(data_directory_path, new_mongo_dir) |
2203 | juju_log("run: {}".format(command)) |
2204 | run(command) |
2205 | try: |
2206 | - os.rename(data_directory_path, "{}-{}".format( |
2207 | - data_directory_path, int(time.time()))) |
2208 | - juju_log("NOTICE: symlinking {} -> {}".format( |
2209 | - new_mongo_dir, data_directory_path)) |
2210 | + os.rename( |
2211 | + data_directory_path, |
2212 | + "{}-{}".format(data_directory_path, int(time.time())), |
2213 | + ) |
2214 | + juju_log( |
2215 | + "NOTICE: symlinking {} -> {}".format(new_mongo_dir, data_directory_path) |
2216 | + ) |
2217 | os.symlink(new_mongo_dir, data_directory_path) |
2218 | juju_log( |
2219 | "after-symlink: to fix/avoid UID changes from " |
2220 | "previous units, doing: " |
2221 | - "chown -R mongodb:mongodb {}".format(new_mongo_dir)) |
2222 | + "chown -R mongodb:mongodb {}".format(new_mongo_dir) |
2223 | + ) |
2224 | run("chown -R mongodb:mongodb {}".format(new_mongo_dir)) |
2225 | return True |
2226 | except OSError: |
2227 | - juju_log("failed to symlink {} -> {}".format( |
2228 | - data_directory_path, mount_point)) |
2229 | + juju_log( |
2230 | + "failed to symlink {} -> {}".format(data_directory_path, mount_point) |
2231 | + ) |
2232 | return False |
2233 | else: |
2234 | - juju_log( |
2235 | - "Invalid volume storage configuration, not applying changes") |
2236 | + juju_log("Invalid volume storage configuration, not applying changes") |
2237 | return False |
2238 | |
2239 | |
2240 | # Write mongodb-server logrotate configuration |
2241 | -def write_logrotate_config(config_data, |
2242 | - conf_file='/etc/logrotate.d/mongodb-server'): |
2243 | +def write_logrotate_config(config_data, conf_file="/etc/logrotate.d/mongodb-server"): |
2244 | |
2245 | - juju_log('Writing {}.'.format(conf_file)) |
2246 | - contents = dedent(""" |
2247 | + juju_log("Writing {}.".format(conf_file)) |
2248 | + contents = dedent( |
2249 | + """ |
2250 | {logpath} {{ |
2251 | {logrotate-frequency} |
2252 | rotate {logrotate-rotate} |
2253 | @@ -1835,30 +1844,31 @@ def write_logrotate_config(config_data, |
2254 | compress |
2255 | notifempty |
2256 | missingok |
2257 | - }}""") |
2258 | + }}""" |
2259 | + ) |
2260 | contents = contents.format(**config_data) |
2261 | try: |
2262 | - with open(conf_file, 'w') as f: |
2263 | + with open(conf_file, "w") as f: |
2264 | f.write(contents) |
2265 | except IOError: |
2266 | - juju_log('Could not write {}.'.format(conf_file)) |
2267 | + juju_log("Could not write {}.".format(conf_file)) |
2268 | return False |
2269 | return True |
2270 | |
2271 | |
2272 | -@hooks.hook('pre-series-upgrade') |
2273 | +@hooks.hook("pre-series-upgrade") |
2274 | def pre_series_upgrade(): |
2275 | juju_log("Running prepare series upgrade hook", "INFO") |
2276 | if am_i_primary(): |
2277 | step_down_replset_primary() |
2278 | - service('stop', 'mongodb') |
2279 | + service("stop", "mongodb") |
2280 | status_set( |
2281 | "blocked", |
2282 | - "Ready for do-release-upgrade and reboot. " |
2283 | - "Set complete when finished.") |
2284 | + "Ready for do-release-upgrade and reboot. Set complete when finished.", |
2285 | + ) |
2286 | |
2287 | |
2288 | -@hooks.hook('post-series-upgrade') |
2289 | +@hooks.hook("post-series-upgrade") |
2290 | def post_series_upgrade(): |
2291 | juju_log("Running complete series upgrade hook", "INFO") |
2292 | update_status() |
2293 | @@ -1872,4 +1882,4 @@ if __name__ == "__main__": |
2294 | try: |
2295 | hooks.execute(sys.argv) |
2296 | except UnregisteredHookError as e: |
2297 | - juju_log('Unknown hook {} - skipping'.format(e)) |
2298 | + juju_log("Unknown hook {} - skipping".format(e)) |
2299 | diff --git a/tests/functional/tests/tests_mongodb.py b/tests/functional/tests/tests_mongodb.py |
2300 | index dc50d8d..bf80b65 100644 |
2301 | --- a/tests/functional/tests/tests_mongodb.py |
2302 | +++ b/tests/functional/tests/tests_mongodb.py |
2303 | @@ -115,7 +115,8 @@ class ReplicatedMongodbCharmTest(MongodbCharmTestBase): |
2304 | ] |
2305 | |
2306 | def extract(member_dict): |
2307 | - # Extract a subset of membership info as a frozenset. Name is ipaddr:port, health a float and stateStr a str |
2308 | + # Extract a subset of membership info as a frozenset. |
2309 | + # Name is ipaddr:port, health a float and stateStr a str |
2310 | return frozenset( |
2311 | v for k, v in member_dict.items() if k in ["name", "health", "stateStr"] |
2312 | ) |
2313 | diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py |
2314 | index 5dd2748..e515754 100644 |
2315 | --- a/tests/unit/__init__.py |
2316 | +++ b/tests/unit/__init__.py |
2317 | @@ -1,3 +1,4 @@ |
2318 | import sys |
2319 | -sys.path.append('hooks') |
2320 | -sys.path.append('unit_tests') |
2321 | + |
2322 | +sys.path.append("hooks") |
2323 | +sys.path.append("unit_tests") |
2324 | diff --git a/tests/unit/test_hooks.py b/tests/unit/test_hooks.py |
2325 | index e97ef91..b036f06 100644 |
2326 | --- a/tests/unit/test_hooks.py |
2327 | +++ b/tests/unit/test_hooks.py |
2328 | @@ -17,17 +17,16 @@ import hooks |
2329 | # hooks.some_func(). Invoking the the interface change relations will cause |
2330 | # the hooks context to be created outside of the normal mockery. |
2331 | TO_PATCH = [ |
2332 | - 'relation_id', |
2333 | - 'relation_get', |
2334 | - 'relation_set', |
2335 | - 'unit_get', |
2336 | - 'juju_log', |
2337 | - 'config', |
2338 | + "relation_id", |
2339 | + "relation_get", |
2340 | + "relation_set", |
2341 | + "unit_get", |
2342 | + "juju_log", |
2343 | + "config", |
2344 | ] |
2345 | |
2346 | |
2347 | class MongoHooksTest(CharmTestCase): |
2348 | - |
2349 | def setUp(self): |
2350 | super(MongoHooksTest, self).setUp(hooks, TO_PATCH) |
2351 | |
2352 | @@ -38,23 +37,27 @@ class MongoHooksTest(CharmTestCase): |
2353 | self.config.side_effect = self.test_config.get |
2354 | self.relation_get.side_effect = self.test_relation.get |
2355 | |
2356 | - @patch.object(hooks, 'is_relation_made') |
2357 | - @patch.object(hooks, 'get_replicaset_status') |
2358 | - @patch.object(hooks, 'restart_mongod') |
2359 | - @patch.object(hooks, 'enable_replset') |
2360 | + @patch.object(hooks, "is_relation_made") |
2361 | + @patch.object(hooks, "get_replicaset_status") |
2362 | + @patch.object(hooks, "restart_mongod") |
2363 | + @patch.object(hooks, "enable_replset") |
2364 | # Note: patching the os.environ dictionary in-line here so there's no |
2365 | # additional parameter sent into the function |
2366 | - @patch.dict('os.environ', JUJU_UNIT_NAME='fake-unit/0') |
2367 | - def test_replica_set_relation_joined(self, mock_enable_replset, |
2368 | - mock_restart, mock_get_replset_status, |
2369 | - mock_is_rel_made): |
2370 | - self.unit_get.return_value = 'private.address' |
2371 | - self.test_config.set('port', '1234') |
2372 | - self.test_config.set('replicaset', 'fake-replicaset') |
2373 | - self.relation_id.return_value = 'fake-relation-id' |
2374 | + @patch.dict("os.environ", JUJU_UNIT_NAME="fake-unit/0") |
2375 | + def test_replica_set_relation_joined( |
2376 | + self, |
2377 | + mock_enable_replset, |
2378 | + mock_restart, |
2379 | + mock_get_replset_status, |
2380 | + mock_is_rel_made, |
2381 | + ): |
2382 | + self.unit_get.return_value = "private.address" |
2383 | + self.test_config.set("port", "1234") |
2384 | + self.test_config.set("replicaset", "fake-replicaset") |
2385 | + self.relation_id.return_value = "fake-relation-id" |
2386 | |
2387 | mock_enable_replset.return_value = False |
2388 | - mock_get_replset_status.return_value = 'PRIMARY' |
2389 | + mock_get_replset_status.return_value = "PRIMARY" |
2390 | mock_is_rel_made.return_value = True |
2391 | |
2392 | hooks.replica_set_relation_joined() |
2393 | @@ -63,13 +66,15 @@ class MongoHooksTest(CharmTestCase): |
2394 | # was not enabled. |
2395 | self.assertFalse(mock_restart.called) |
2396 | |
2397 | - exp_rel_vals = {'hostname': 'private.address', |
2398 | - 'port': '1234', |
2399 | - 'replset': 'fake-replicaset', |
2400 | - 'install-order': '0', |
2401 | - 'type': 'replset'} |
2402 | + exp_rel_vals = { |
2403 | + "hostname": "private.address", |
2404 | + "port": "1234", |
2405 | + "replset": "fake-replicaset", |
2406 | + "install-order": "0", |
2407 | + "type": "replset", |
2408 | + } |
2409 | # Check that the relation data was set as we expect it to be set. |
2410 | - self.relation_set.assert_called_with('fake-relation-id', exp_rel_vals) |
2411 | + self.relation_set.assert_called_with("fake-relation-id", exp_rel_vals) |
2412 | |
2413 | mock_enable_replset.reset_mock() |
2414 | self.relation_set.reset_mock() |
2415 | @@ -78,24 +83,31 @@ class MongoHooksTest(CharmTestCase): |
2416 | hooks.replica_set_relation_joined() |
2417 | |
2418 | self.assertTrue(mock_restart.called) |
2419 | - self.relation_set.assert_called_with('fake-relation-id', exp_rel_vals) |
2420 | - |
2421 | - @patch.object(hooks, 'run_admin_command') |
2422 | - @patch.object(hooks, 'MongoClient') |
2423 | - @patch.object(hooks, 'config') |
2424 | - @patch.object(hooks, 'mongo_client') |
2425 | - @patch('time.sleep') |
2426 | - def test_init_repl_set(self, mock_sleep, mock_mongo_client_fn, |
2427 | - mock_config, mock_mongo_client, |
2428 | - mock_run_admin_command): |
2429 | + self.relation_set.assert_called_with("fake-relation-id", exp_rel_vals) |
2430 | + |
2431 | + @patch.object(hooks, "run_admin_command") |
2432 | + @patch.object(hooks, "MongoClient") |
2433 | + @patch.object(hooks, "config") |
2434 | + @patch.object(hooks, "mongo_client") |
2435 | + @patch("time.sleep") |
2436 | + def test_init_repl_set( |
2437 | + self, |
2438 | + mock_sleep, |
2439 | + mock_mongo_client_fn, |
2440 | + mock_config, |
2441 | + mock_mongo_client, |
2442 | + mock_run_admin_command, |
2443 | + ): |
2444 | mock_mongo_client_fn.return_value = False |
2445 | |
2446 | - mock_config.return_value = {'replicaset': 'foo', |
2447 | - 'private-address': 'mongo.local', |
2448 | - 'port': '12345'} |
2449 | + mock_config.return_value = { |
2450 | + "replicaset": "foo", |
2451 | + "private-address": "mongo.local", |
2452 | + "port": "12345", |
2453 | + } |
2454 | |
2455 | # Put the OK state (1) at the end and check the loop. |
2456 | - ret_values = [{'myState': x} for x in [0, 2, 5, 1]] |
2457 | + ret_values = [{"myState": x} for x in [0, 2, 5, 1]] |
2458 | mock_run_admin_command.side_effect = ret_values |
2459 | |
2460 | hooks.init_replset() |
2461 | @@ -104,8 +116,10 @@ class MongoHooksTest(CharmTestCase): |
2462 | self.assertEqual(len(ret_values) + 1, mock_sleep.call_count) |
2463 | |
2464 | mock_run_admin_command.reset_mock() |
2465 | - exc = [OperationFailure('Received replSetInitiate'), |
2466 | - OperationFailure('unhandled')] |
2467 | + exc = [ |
2468 | + OperationFailure("Received replSetInitiate"), |
2469 | + OperationFailure("unhandled"), |
2470 | + ] |
2471 | mock_run_admin_command.side_effect = exc |
2472 | |
2473 | try: |
2474 | @@ -116,78 +130,82 @@ class MongoHooksTest(CharmTestCase): |
2475 | |
2476 | self.assertEqual(2, mock_run_admin_command.call_count) |
2477 | |
2478 | - @patch.object(hooks, 'run') |
2479 | - @patch.object(hooks, 'juju_log') |
2480 | - @patch.object(hooks, 'is_bionic_or_greater') |
2481 | - @patch.object(hooks, 'mongo_client_smart') |
2482 | - def test_join_replset(self, mock_mongo_client, mock_is_bionic_or_greater, mock_juju_log, mock_run): |
2483 | + @patch.object(hooks, "run") |
2484 | + @patch.object(hooks, "juju_log") |
2485 | + @patch.object(hooks, "is_bionic_or_greater") |
2486 | + @patch.object(hooks, "mongo_client_smart") |
2487 | + def test_join_replset( |
2488 | + self, mock_mongo_client, mock_is_bionic_or_greater, mock_juju_log, mock_run |
2489 | + ): |
2490 | # Test with OS version not bionic or greater first. |
2491 | mock_is_bionic_or_greater.return_value = False |
2492 | hooks.join_replset() |
2493 | self.assertFalse(mock_mongo_client.called) |
2494 | |
2495 | mock_mongo_client.reset_mock() |
2496 | - hooks.join_replset(master_node='mongo.local') |
2497 | + hooks.join_replset(master_node="mongo.local") |
2498 | self.assertFalse(mock_mongo_client.called) |
2499 | |
2500 | mock_mongo_client.reset_mock() |
2501 | - hooks.join_replset(host='fake-host') |
2502 | + hooks.join_replset(host="fake-host") |
2503 | self.assertFalse(mock_mongo_client.called) |
2504 | |
2505 | mock_mongo_client.reset_mock() |
2506 | - hooks.join_replset(master_node='mongo.local', host='fake-host') |
2507 | - mock_mongo_client.assert_called_with('localhost', |
2508 | - 'rs.add("fake-host")') |
2509 | + hooks.join_replset(master_node="mongo.local", host="fake-host") |
2510 | + mock_mongo_client.assert_called_with("localhost", 'rs.add("fake-host")') |
2511 | # Also test with bionic or greater. |
2512 | old_mcr = hooks.MONGO_CLIENT_RETRIES |
2513 | hooks.MONGO_CLIENT_RETRIES = 0 |
2514 | mock_is_bionic_or_greater.return_value = True |
2515 | mock_mongo_client.reset_mock() |
2516 | - hooks.join_replset(master_node='mongo.local', host='fake-host') |
2517 | - expected_run = ['mongo', '--quiet', '--host', "localhost", '--eval', 'printjson(rs.add("fake-host"))'] |
2518 | + hooks.join_replset(master_node="mongo.local", host="fake-host") |
2519 | + expected_run = [ |
2520 | + "mongo", |
2521 | + "--quiet", |
2522 | + "--host", |
2523 | + "localhost", |
2524 | + "--eval", |
2525 | + 'printjson(rs.add("fake-host"))', |
2526 | + ] |
2527 | mock_run.assert_called_with(expected_run) |
2528 | # Restore mongo client retries for other tests. |
2529 | hooks.MONGO_CLIENT_RETRIES = old_mcr |
2530 | |
2531 | - @patch.object(hooks, 'mongo_client') |
2532 | + @patch.object(hooks, "mongo_client") |
2533 | def test_leave_replset(self, mock_mongo_client): |
2534 | hooks.leave_replset() |
2535 | self.assertFalse(mock_mongo_client.called) |
2536 | |
2537 | mock_mongo_client.reset_mock() |
2538 | - hooks.leave_replset(master_node='mongo.local') |
2539 | + hooks.leave_replset(master_node="mongo.local") |
2540 | self.assertFalse(mock_mongo_client.called) |
2541 | |
2542 | mock_mongo_client.reset_mock() |
2543 | - hooks.leave_replset(host='fake-host') |
2544 | + hooks.leave_replset(host="fake-host") |
2545 | self.assertFalse(mock_mongo_client.called) |
2546 | |
2547 | mock_mongo_client.reset_mock() |
2548 | - hooks.leave_replset('mongo.local', 'fake-host') |
2549 | - mock_mongo_client.assert_called_with('mongo.local', |
2550 | - 'rs.remove("fake-host")') |
2551 | - |
2552 | - @patch.object(hooks, 'apt_install') |
2553 | - @patch.object(hooks, 'apt_update') |
2554 | - @patch.object(hooks, 'add_source') |
2555 | - @patch.dict('os.environ', CHARM_DIR='/tmp/charm/dir') |
2556 | - def test_install_hook(self, mock_add_source, mock_apt_update, |
2557 | - mock_apt_install): |
2558 | - self.test_config.set('source', 'fake-source') |
2559 | - self.test_config.set('key', 'fake-key') |
2560 | + hooks.leave_replset("mongo.local", "fake-host") |
2561 | + mock_mongo_client.assert_called_with("mongo.local", 'rs.remove("fake-host")') |
2562 | + |
2563 | + @patch.object(hooks, "apt_install") |
2564 | + @patch.object(hooks, "apt_update") |
2565 | + @patch.object(hooks, "add_source") |
2566 | + @patch.dict("os.environ", CHARM_DIR="/tmp/charm/dir") |
2567 | + def test_install_hook(self, mock_add_source, mock_apt_update, mock_apt_install): |
2568 | + self.test_config.set("source", "fake-source") |
2569 | + self.test_config.set("key", "fake-key") |
2570 | |
2571 | hooks.install_hook() |
2572 | - mock_add_source.assert_called_with('fake-source', 'fake-key') |
2573 | + mock_add_source.assert_called_with("fake-source", "fake-key") |
2574 | mock_apt_update.assert_called_with(fatal=True) |
2575 | - mock_apt_install.assert_called_with(packages=hooks.INSTALL_PACKAGES, |
2576 | - fatal=True) |
2577 | - |
2578 | - @patch.object(hooks, 'run_admin_command') |
2579 | - @patch.object(hooks, 'MongoClient') |
2580 | - @patch('time.sleep') |
2581 | - def test_am_i_primary(self, mock_sleep, mock_mongo_client, |
2582 | - mock_run_admin_cmd): |
2583 | - mock_run_admin_cmd.side_effect = [{'myState': x} for x in range(5)] |
2584 | + mock_apt_install.assert_called_with(packages=hooks.INSTALL_PACKAGES, fatal=True) |
2585 | + |
2586 | + @patch.object(hooks, "run_admin_command") |
2587 | + @patch.object(hooks, "MongoClient") |
2588 | + @patch("time.sleep") |
2589 | + def test_am_i_primary(self, mock_sleep, mock_mongo_client, mock_run_admin_cmd): |
2590 | + mock_run_admin_cmd.side_effect = [{"myState": x} for x in range(5)] |
2591 | expected_results = [True if x == 1 else False for x in range(5)] |
2592 | |
2593 | # Check expected return values each time... |
2594 | @@ -195,54 +213,52 @@ class MongoHooksTest(CharmTestCase): |
2595 | rv = hooks.am_i_primary() |
2596 | self.assertEqual(exp, rv) |
2597 | |
2598 | - @patch.object(hooks, 'run_admin_command') |
2599 | - @patch.object(hooks, 'MongoClient') |
2600 | - @patch('time.sleep') |
2601 | - def test_am_i_primary_too_many_attempts(self, mock_sleep, |
2602 | - mock_mongo_client, |
2603 | - mock_run_admin_cmd): |
2604 | - msg = 'replSetInitiate - should come online shortly' |
2605 | - mock_run_admin_cmd.side_effect = [OperationFailure(msg) |
2606 | - for x in range(10)] |
2607 | + @patch.object(hooks, "run_admin_command") |
2608 | + @patch.object(hooks, "MongoClient") |
2609 | + @patch("time.sleep") |
2610 | + def test_am_i_primary_too_many_attempts( |
2611 | + self, mock_sleep, mock_mongo_client, mock_run_admin_cmd |
2612 | + ): |
2613 | + msg = "replSetInitiate - should come online shortly" |
2614 | + mock_run_admin_cmd.side_effect = [OperationFailure(msg) for x in range(10)] |
2615 | |
2616 | try: |
2617 | hooks.am_i_primary() |
2618 | - self.assertTrue(False, 'Expected failure.') |
2619 | + self.assertTrue(False, "Expected failure.") |
2620 | except hooks.TimeoutException: |
2621 | self.assertEqual(mock_run_admin_cmd.call_count, 10) |
2622 | pass |
2623 | |
2624 | - @patch.object(hooks, 'run_admin_command') |
2625 | - @patch.object(hooks, 'MongoClient') |
2626 | - @patch('time.sleep') |
2627 | - def test_am_i_primary_operation_failures(self, mock_sleep, |
2628 | - mock_mongo_client, |
2629 | - mock_run_admin_cmd): |
2630 | - msg = 'EMPTYCONFIG' |
2631 | + @patch.object(hooks, "run_admin_command") |
2632 | + @patch.object(hooks, "MongoClient") |
2633 | + @patch("time.sleep") |
2634 | + def test_am_i_primary_operation_failures( |
2635 | + self, mock_sleep, mock_mongo_client, mock_run_admin_cmd |
2636 | + ): |
2637 | + msg = "EMPTYCONFIG" |
2638 | mock_run_admin_cmd.side_effect = OperationFailure(msg) |
2639 | rv = hooks.am_i_primary() |
2640 | self.assertTrue(mock_run_admin_cmd.called) |
2641 | self.assertFalse(rv) |
2642 | |
2643 | mock_run_admin_cmd.reset_mock() |
2644 | - msg = 'not running with --replSet' |
2645 | + msg = "not running with --replSet" |
2646 | mock_run_admin_cmd.side_effect = OperationFailure(msg) |
2647 | rv = hooks.am_i_primary() |
2648 | self.assertTrue(mock_run_admin_cmd.called) |
2649 | self.assertFalse(rv) |
2650 | |
2651 | mock_run_admin_cmd.reset_mock() |
2652 | - mock_run_admin_cmd.side_effect = OperationFailure('unexpected failure') |
2653 | + mock_run_admin_cmd.side_effect = OperationFailure("unexpected failure") |
2654 | try: |
2655 | hooks.am_i_primary() |
2656 | self.assertFalse(True, "Expected OperationFailure to be raised") |
2657 | except OperationFailure: |
2658 | self.assertTrue(mock_run_admin_cmd.called) |
2659 | |
2660 | - @patch('time.sleep') |
2661 | - @patch('subprocess.check_output') |
2662 | - def test_mongo_client_smart_no_command(self, mock_check_output, |
2663 | - mock_sleep): |
2664 | + @patch("time.sleep") |
2665 | + @patch("subprocess.check_output") |
2666 | + def test_mongo_client_smart_no_command(self, mock_check_output, mock_sleep): |
2667 | rv = hooks.mongo_client_smart() |
2668 | self.assertFalse(rv) |
2669 | self.assertEqual(0, mock_check_output.call_count) |
2670 | @@ -250,74 +266,82 @@ class MongoHooksTest(CharmTestCase): |
2671 | mock_check_output.reset_mock() |
2672 | mock_check_output.return_value = b'{"ok": 1}' |
2673 | |
2674 | - rv = hooks.mongo_client_smart(command='fake-cmd') |
2675 | + rv = hooks.mongo_client_smart(command="fake-cmd") |
2676 | self.assertTrue(rv) |
2677 | - mock_check_output.assert_called_once_with(['mongo', '--quiet', |
2678 | - '--host', 'localhost', |
2679 | - '--eval', |
2680 | - 'printjson(fake-cmd)']) |
2681 | + mock_check_output.assert_called_once_with( |
2682 | + ["mongo", "--quiet", "--host", "localhost", "--eval", "printjson(fake-cmd)"] |
2683 | + ) |
2684 | |
2685 | - @patch('time.sleep') |
2686 | - @patch('subprocess.check_output') |
2687 | + @patch("time.sleep") |
2688 | + @patch("subprocess.check_output") |
2689 | def test_mongo_client_smart_error_cases(self, mock_ck_output, mock_sleep): |
2690 | - mock_ck_output.side_effect = [CalledProcessError(1, 'cmd', |
2691 | - output='fake-error') |
2692 | - for x in range(11)] |
2693 | - rv = hooks.mongo_client_smart(command='fake-cmd') |
2694 | + mock_ck_output.side_effect = [ |
2695 | + CalledProcessError(1, "cmd", output="fake-error") for x in range(11) |
2696 | + ] |
2697 | + rv = hooks.mongo_client_smart(command="fake-cmd") |
2698 | self.assertFalse(rv) |
2699 | |
2700 | - @patch('subprocess.call') |
2701 | + @patch("subprocess.call") |
2702 | def test_mongo_client(self, mock_subprocess): |
2703 | rv = hooks.mongo_client() |
2704 | self.assertFalse(rv) |
2705 | self.assertEqual(0, mock_subprocess.call_count) |
2706 | |
2707 | mock_subprocess.reset_mock() |
2708 | - rv = hooks.mongo_client(host='fake-host') |
2709 | + rv = hooks.mongo_client(host="fake-host") |
2710 | self.assertFalse(rv) |
2711 | self.assertEqual(0, mock_subprocess.call_count) |
2712 | |
2713 | mock_subprocess.reset_mock() |
2714 | - rv = hooks.mongo_client(command='fake-command') |
2715 | + rv = hooks.mongo_client(command="fake-command") |
2716 | self.assertFalse(rv) |
2717 | self.assertEqual(0, mock_subprocess.call_count) |
2718 | |
2719 | mock_subprocess.reset_mock() |
2720 | mock_subprocess.return_value = 0 |
2721 | - rv = hooks.mongo_client(host='fake-host', command='fake-command') |
2722 | - expected_cmd = ("mongo --host %s --eval 'printjson(%s)'" |
2723 | - % ('fake-host', 'fake-command')) |
2724 | + rv = hooks.mongo_client(host="fake-host", command="fake-command") |
2725 | + expected_cmd = "mongo --host %s --eval 'printjson(%s)'" % ( |
2726 | + "fake-host", |
2727 | + "fake-command", |
2728 | + ) |
2729 | mock_subprocess.assert_called_once_with(expected_cmd, shell=True) |
2730 | self.assertTrue(rv) |
2731 | |
2732 | mock_subprocess.reset_mock() |
2733 | mock_subprocess.return_value = 1 |
2734 | - rv = hooks.mongo_client(host='fake-host', command='fake-command') |
2735 | - expected_cmd = ("mongo --host %s --eval 'printjson(%s)'" |
2736 | - % ('fake-host', 'fake-command')) |
2737 | + rv = hooks.mongo_client(host="fake-host", command="fake-command") |
2738 | + expected_cmd = "mongo --host %s --eval 'printjson(%s)'" % ( |
2739 | + "fake-host", |
2740 | + "fake-command", |
2741 | + ) |
2742 | mock_subprocess.assert_called_once_with(expected_cmd, shell=True) |
2743 | self.assertFalse(rv) |
2744 | |
2745 | - @patch.object(hooks, 'is_relation_made') |
2746 | - @patch.object(hooks, 'run_admin_command') |
2747 | - @patch.object(hooks, 'is_leader') |
2748 | - @patch.object(hooks, 'get_replicaset_status') |
2749 | - @patch.object(hooks, 'am_i_primary') |
2750 | - @patch.object(hooks, 'init_replset') |
2751 | - @patch.object(hooks, 'relation_get') |
2752 | - @patch.object(hooks, 'peer_units') |
2753 | - @patch.object(hooks, 'join_replset') |
2754 | - @patch.object(hooks, 'unit_get') |
2755 | - def test_replica_set_relation_changed(self, mock_unit_get, |
2756 | - mock_join_replset, mock_peer_units, |
2757 | - mock_relation_get, mock_init_replset, |
2758 | - mock_is_primary, |
2759 | - mock_get_replset_status, |
2760 | - mock_is_leader, |
2761 | - mock_run_admin_cmd, |
2762 | - mock_is_rel_made): |
2763 | + @patch.object(hooks, "is_relation_made") |
2764 | + @patch.object(hooks, "run_admin_command") |
2765 | + @patch.object(hooks, "is_leader") |
2766 | + @patch.object(hooks, "get_replicaset_status") |
2767 | + @patch.object(hooks, "am_i_primary") |
2768 | + @patch.object(hooks, "init_replset") |
2769 | + @patch.object(hooks, "relation_get") |
2770 | + @patch.object(hooks, "peer_units") |
2771 | + @patch.object(hooks, "join_replset") |
2772 | + @patch.object(hooks, "unit_get") |
2773 | + def test_replica_set_relation_changed( |
2774 | + self, |
2775 | + mock_unit_get, |
2776 | + mock_join_replset, |
2777 | + mock_peer_units, |
2778 | + mock_relation_get, |
2779 | + mock_init_replset, |
2780 | + mock_is_primary, |
2781 | + mock_get_replset_status, |
2782 | + mock_is_leader, |
2783 | + mock_run_admin_cmd, |
2784 | + mock_is_rel_made, |
2785 | + ): |
2786 | # set the unit_get('private-address') |
2787 | - mock_unit_get.return_value = 'juju-local-unit-0.local' |
2788 | + mock_unit_get.return_value = "juju-local-unit-0.local" |
2789 | mock_relation_get.return_value = None |
2790 | |
2791 | # Test when remote hostname is None, should not join |
2792 | @@ -326,10 +350,10 @@ class MongoHooksTest(CharmTestCase): |
2793 | |
2794 | # Test remote hostname is valid, but master is somehow not defined |
2795 | mock_join_replset.reset_mock() |
2796 | - mock_relation_get.return_value = 'juju-local-unit-0' |
2797 | + mock_relation_get.return_value = "juju-local-unit-0" |
2798 | mock_is_leader.return_value = False |
2799 | - mock_run_admin_cmd.return_value = {'myState': hooks.MONGO_PRIMARY} |
2800 | - mock_get_replset_status.return_value = 'PRIMARY' |
2801 | + mock_run_admin_cmd.return_value = {"myState": hooks.MONGO_PRIMARY} |
2802 | + mock_get_replset_status.return_value = "PRIMARY" |
2803 | mock_is_rel_made.return_value = True |
2804 | |
2805 | hooks.replica_set_relation_changed() |
2806 | @@ -339,7 +363,7 @@ class MongoHooksTest(CharmTestCase): |
2807 | # Test when not oldest peer, don't init replica set |
2808 | mock_join_replset.reset_mock() |
2809 | mock_init_replset.reset_mock() |
2810 | - mock_peer_units.return_value = ['mongodb/1', 'mongodb/2'] |
2811 | + mock_peer_units.return_value = ["mongodb/1", "mongodb/2"] |
2812 | |
2813 | hooks.replica_set_relation_changed() |
2814 | |
2815 | @@ -347,21 +371,21 @@ class MongoHooksTest(CharmTestCase): |
2816 | |
2817 | # Test when its also the PRIMARY |
2818 | mock_relation_get.reset_mock() |
2819 | - mock_relation_get.side_effect = ['juju-remote-unit-0', '12345'] |
2820 | + mock_relation_get.side_effect = ["juju-remote-unit-0", "12345"] |
2821 | mock_is_primary.reset_mock() |
2822 | mock_is_primary.return_value = True |
2823 | mock_join_replset.reset_mock() |
2824 | |
2825 | hooks.replica_set_relation_changed() |
2826 | - call1 = call('juju-local-unit-0.local:27017', |
2827 | - 'juju-remote-unit-0:12345') |
2828 | + call1 = call("juju-local-unit-0.local:27017", "juju-remote-unit-0:12345") |
2829 | mock_join_replset.assert_has_calls([call1]) |
2830 | |
2831 | - @patch.object(hooks, 'unit_get') |
2832 | - @patch.object(hooks, 'leave_replset') |
2833 | - @patch.object(hooks, 'am_i_primary') |
2834 | - def test_replica_set_relation_departed(self, mock_am_i_primary, |
2835 | - mock_leave_replset, mock_unit_get): |
2836 | + @patch.object(hooks, "unit_get") |
2837 | + @patch.object(hooks, "leave_replset") |
2838 | + @patch.object(hooks, "am_i_primary") |
2839 | + def test_replica_set_relation_departed( |
2840 | + self, mock_am_i_primary, mock_leave_replset, mock_unit_get |
2841 | + ): |
2842 | mock_am_i_primary.return_value = False |
2843 | hooks.replica_set_relation_departed() |
2844 | |
2845 | @@ -369,25 +393,29 @@ class MongoHooksTest(CharmTestCase): |
2846 | |
2847 | mock_am_i_primary.reset_mock() |
2848 | mock_am_i_primary.return_value = True |
2849 | - mock_unit_get.return_value = 'juju-local' |
2850 | + mock_unit_get.return_value = "juju-local" |
2851 | |
2852 | - self.test_relation.set({'hostname': 'juju-remote', |
2853 | - 'port': '27017'}) |
2854 | + self.test_relation.set({"hostname": "juju-remote", "port": "27017"}) |
2855 | mock_leave_replset.reset_mock() |
2856 | |
2857 | hooks.replica_set_relation_departed() |
2858 | |
2859 | - call1 = call('juju-local:27017', 'juju-remote:27017') |
2860 | + call1 = call("juju-local:27017", "juju-remote:27017") |
2861 | mock_leave_replset.assert_has_calls([call1]) |
2862 | |
2863 | - @patch('time.sleep') |
2864 | - @patch.object(hooks, 'MongoClient') |
2865 | - @patch.object(hooks, 'unit_get') |
2866 | - @patch.object(hooks, 'leave_replset') |
2867 | - @patch.object(hooks, 'am_i_primary') |
2868 | - def test_replica_set_relation_broken(self, mock_am_i_primary, |
2869 | - mock_leave_replset, mock_unit_get, |
2870 | - mock_MongoClient, mock_sleep): |
2871 | + @patch("time.sleep") |
2872 | + @patch.object(hooks, "MongoClient") |
2873 | + @patch.object(hooks, "unit_get") |
2874 | + @patch.object(hooks, "leave_replset") |
2875 | + @patch.object(hooks, "am_i_primary") |
2876 | + def test_replica_set_relation_broken( |
2877 | + self, |
2878 | + mock_am_i_primary, |
2879 | + mock_leave_replset, |
2880 | + mock_unit_get, |
2881 | + mock_MongoClient, |
2882 | + mock_sleep, |
2883 | + ): |
2884 | |
2885 | mock_am_i_primary.return_value = False |
2886 | hooks.replica_set_relation_broken() |
2887 | @@ -405,12 +433,8 @@ class MongoHooksTest(CharmTestCase): |
2888 | |
2889 | three =four |
2890 | """ |
2891 | - expected = { |
2892 | - 'key': 'value', |
2893 | - 'one': 'two', |
2894 | - 'three': 'four' |
2895 | - } |
2896 | - with mock_open('/etc/mongodb.conf', test_config): |
2897 | + expected = {"key": "value", "one": "two", "three": "four"} |
2898 | + with mock_open("/etc/mongodb.conf", test_config): |
2899 | results = hooks.get_current_mongo_config() |
2900 | self.assertEqual(results, expected) |
2901 | |
2902 | @@ -438,14 +462,16 @@ class MongoHooksTest(CharmTestCase): |
2903 | os.unlink(mocked_upstart.name) |
2904 | |
2905 | @patch("subprocess.call") |
2906 | - @patch.object(hooks, 'is_relation_made') |
2907 | - @patch.object(hooks, 'is_bionic_or_greater') |
2908 | - def test_mongodb_conf(self, mock_is_bionic_or_greater, mock_is_relation_made, *args): |
2909 | + @patch.object(hooks, "is_relation_made") |
2910 | + @patch.object(hooks, "is_bionic_or_greater") |
2911 | + def test_mongodb_conf( |
2912 | + self, mock_is_bionic_or_greater, mock_is_relation_made, *args |
2913 | + ): |
2914 | mock_is_bionic_or_greater.return_value = False |
2915 | mock_is_relation_made.return_value = False |
2916 | tmpdir = tempfile.mkdtemp() |
2917 | - self.test_config.set('dbpath', os.path.join(tmpdir, 'db')) |
2918 | - self.test_config.set('logpath', os.path.join(tmpdir, 'log')) |
2919 | + self.test_config.set("dbpath", os.path.join(tmpdir, "db")) |
2920 | + self.test_config.set("logpath", os.path.join(tmpdir, "log")) |
2921 | try: |
2922 | mongodb_conf = hooks.mongodb_conf(self.test_config.get_all()) |
2923 | finally: |
2924 | @@ -470,18 +496,22 @@ diaglog = 0 |
2925 | rest = true |
2926 | |
2927 | master = true |
2928 | -""".format(tmpdir=tmpdir) |
2929 | +""".format( |
2930 | + tmpdir=tmpdir |
2931 | + ) |
2932 | self.assertEqual(mongodb_conf, expected) |
2933 | |
2934 | @patch("subprocess.call") |
2935 | - @patch.object(hooks, 'is_relation_made') |
2936 | - @patch.object(hooks, 'is_bionic_or_greater') |
2937 | - def test_mongodb_conf_bionic(self, mock_is_bionic_or_greater, mock_is_relation_made, *args): |
2938 | + @patch.object(hooks, "is_relation_made") |
2939 | + @patch.object(hooks, "is_bionic_or_greater") |
2940 | + def test_mongodb_conf_bionic( |
2941 | + self, mock_is_bionic_or_greater, mock_is_relation_made, *args |
2942 | + ): |
2943 | mock_is_bionic_or_greater.return_value = True |
2944 | mock_is_relation_made.return_value = False |
2945 | tmpdir = tempfile.mkdtemp() |
2946 | - self.test_config.set('dbpath', os.path.join(tmpdir, 'db')) |
2947 | - self.test_config.set('logpath', os.path.join(tmpdir, 'log')) |
2948 | + self.test_config.set("dbpath", os.path.join(tmpdir, "db")) |
2949 | + self.test_config.set("logpath", os.path.join(tmpdir, "log")) |
2950 | try: |
2951 | mongodb_conf = hooks.mongodb_conf(self.test_config.get_all()) |
2952 | finally: |
2953 | @@ -502,5 +532,7 @@ port = 27017 |
2954 | journal=true |
2955 | |
2956 | master = true |
2957 | -""".format(tmpdir=tmpdir) |
2958 | +""".format( |
2959 | + tmpdir=tmpdir |
2960 | + ) |
2961 | self.assertEqual(mongodb_conf, expected) |
2962 | diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py |
2963 | index 583cce2..627f6bd 100644 |
2964 | --- a/tests/unit/test_utils.py |
2965 | +++ b/tests/unit/test_utils.py |
2966 | @@ -10,48 +10,49 @@ from mock import patch |
2967 | |
2968 | @contextmanager |
2969 | def mock_open(filename, contents=None): |
2970 | - ''' Slightly simpler mock of open to return contents for filename ''' |
2971 | + """ Slightly simpler mock of open to return contents for filename """ |
2972 | + |
2973 | def mock_file(*args): |
2974 | if args[0] == filename: |
2975 | return io.StringIO(contents) |
2976 | else: |
2977 | return open(*args) |
2978 | - with patch('builtins.open', mock_file): |
2979 | + |
2980 | + with patch("builtins.open", mock_file): |
2981 | yield |
2982 | |
2983 | |
2984 | def load_config(): |
2985 | - ''' |
2986 | + """ |
2987 | Walk backwords from __file__ looking for config.yaml, load and return the |
2988 | 'options' section' |
2989 | - ''' |
2990 | + """ |
2991 | config = None |
2992 | f = __file__ |
2993 | while config is None: |
2994 | d = os.path.dirname(f) |
2995 | - if os.path.isfile(os.path.join(d, 'config.yaml')): |
2996 | - config = os.path.join(d, 'config.yaml') |
2997 | + if os.path.isfile(os.path.join(d, "config.yaml")): |
2998 | + config = os.path.join(d, "config.yaml") |
2999 | break |
3000 | f = d |
3001 | |
3002 | if not config: |
3003 | - logging.error('Could not find config.yaml in any parent directory ' |
3004 | - 'of %s. ' % f) |
3005 | + logging.error("Could not find config.yaml in any parent directory of %s." % f) |
3006 | raise Exception |
3007 | |
3008 | - return yaml.safe_load(open(config).read())['options'] |
3009 | + return yaml.safe_load(open(config).read())["options"] |
3010 | |
3011 | |
3012 | def get_default_config(): |
3013 | - ''' |
3014 | + """ |
3015 | Load default charm config from config.yaml return as a dict. |
3016 | If no default is set in config.yaml, its value is None. |
3017 | - ''' |
3018 | + """ |
3019 | default_config = {} |
3020 | config = load_config() |
3021 | for k, v in config.items(): |
3022 | - if 'default' in v: |
3023 | - default_config[k] = v['default'] |
3024 | + if "default" in v: |
3025 | + default_config[k] = v["default"] |
3026 | else: |
3027 | default_config[k] = None |
3028 | return default_config |
3029 | diff --git a/tests/unit/test_write_log_rotate_config.py b/tests/unit/test_write_log_rotate_config.py |
3030 | index ef1cd98..aa93772 100644 |
3031 | --- a/tests/unit/test_write_log_rotate_config.py |
3032 | +++ b/tests/unit/test_write_log_rotate_config.py |
3033 | @@ -6,28 +6,27 @@ import hooks |
3034 | |
3035 | |
3036 | class TestWriteLogrotateConfigFile(unittest.TestCase): |
3037 | - |
3038 | def test_success(self): |
3039 | - logpath = '/tmp/foo/foo.log' |
3040 | + logpath = "/tmp/foo/foo.log" |
3041 | config_data = { |
3042 | - 'logpath': logpath, |
3043 | - 'logrotate-frequency': 'daily', |
3044 | - 'logrotate-maxsize': '5G', |
3045 | - 'logrotate-rotate': 5, |
3046 | + "logpath": logpath, |
3047 | + "logrotate-frequency": "daily", |
3048 | + "logrotate-maxsize": "5G", |
3049 | + "logrotate-rotate": 5, |
3050 | } |
3051 | fd, temp_fn = tempfile.mkstemp() |
3052 | os.close(fd) |
3053 | - with mock.patch('hooks.juju_log') as mock_juju_log: |
3054 | - with mock.patch('hooks.open', create=True) as mock_open: |
3055 | + with mock.patch("hooks.juju_log") as mock_juju_log: |
3056 | + with mock.patch("hooks.open", create=True) as mock_open: |
3057 | mock_open.return_value = mock.MagicMock() |
3058 | hooks.write_logrotate_config(config_data, temp_fn) |
3059 | os.unlink(temp_fn) |
3060 | - mock_juju_log.assert_called_once_with('Writing {}.'.format(temp_fn)) |
3061 | - mock_open.assert_called_once_with(temp_fn, 'w') |
3062 | + mock_juju_log.assert_called_once_with("Writing {}.".format(temp_fn)) |
3063 | + mock_open.assert_called_once_with(temp_fn, "w") |
3064 | mock_file = mock_open().__enter__() |
3065 | call_args = mock_file.write.call_args[0][0] |
3066 | self.assertTrue(mock_file.write.called) |
3067 | self.assertIn(logpath, call_args) |
3068 | - self.assertIn('daily', call_args) |
3069 | - self.assertIn('maxsize 5G', call_args) |
3070 | - self.assertIn('rotate 5', call_args) |
3071 | + self.assertIn("daily", call_args) |
3072 | + self.assertIn("maxsize 5G", call_args) |
3073 | + self.assertIn("rotate 5", call_args) |
3074 | diff --git a/tox.ini b/tox.ini |
3075 | index cce4a51..8f76c62 100644 |
3076 | --- a/tox.ini |
3077 | +++ b/tox.ini |
3078 | @@ -25,7 +25,7 @@ passenv = |
3079 | [testenv:lint] |
3080 | commands = |
3081 | flake8 |
3082 | -#TODO black --check --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod)/" . |
3083 | + black --check --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod)/" . |
3084 | deps = |
3085 | black |
3086 | flake8 |
3087 | @@ -35,7 +35,7 @@ deps = |
3088 | flake8-colors |
3089 | |
3090 | [flake8] |
3091 | -ignore = E402,E226,W504 |
3092 | +ignore = E402,E226,W503,W504 |
3093 | exclude = |
3094 | .git, |
3095 | __pycache__, |
3096 | @@ -44,8 +44,7 @@ exclude = |
3097 | mod, |
3098 | .build |
3099 | |
3100 | -#TODO max-line-length = 88 |
3101 | -max-line-length = 120 |
3102 | +max-line-length = 88 |
3103 | max-complexity = 10 |
3104 | |
3105 | [testenv:unit] |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.