Merge ~afreiberger/charm-mongodb:blacken-20.08 into charm-mongodb: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)
Reviewer Review Type Date Requested Status
Xav Paice (community) Approve
Review via email: mp+388523@code.launchpad.net
To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

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
1diff --git a/.jujuignore b/.jujuignore
2deleted file mode 100644
3index b7f1399..0000000
4--- a/.jujuignore
5+++ /dev/null
6@@ -1 +0,0 @@
7-.build
8\ No newline at end of file
9diff --git a/actions/backup.py b/actions/backup.py
10index 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})
50diff --git a/actions/backup_test.py b/actions/backup_test.py
51index 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()
89diff --git a/hooks/hooks.py b/hooks/hooks.py
90index 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))
2299diff --git a/tests/functional/tests/tests_mongodb.py b/tests/functional/tests/tests_mongodb.py
2300index 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 )
2313diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
2314index 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")
2324diff --git a/tests/unit/test_hooks.py b/tests/unit/test_hooks.py
2325index 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)
2962diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
2963index 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
3029diff --git a/tests/unit/test_write_log_rotate_config.py b/tests/unit/test_write_log_rotate_config.py
3030index 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)
3074diff --git a/tox.ini b/tox.ini
3075index 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]

Subscribers

People subscribed via source and target branches

to all changes: