Merge ~elmo/juju-lint:master into juju-lint:master

Proposed by James Troup
Status: Merged
Approved by: Xav Paice
Approved revision: 7130a6d34f8c4391d4aa4203f790ee1b46a48c0b
Merged at revision: 3824e72b41e58a89d0dc250a2524d83ff50cb416
Proposed branch: ~elmo/juju-lint:master
Merge into: juju-lint:master
Diff against target: 76 lines (+60/-0)
1 file modified
jujulint.py (+60/-0)
Reviewer Review Type Date Requested Status
Xav Paice (community) Approve
Review via email: mp+353540@code.launchpad.net

Commit message

Add checking of {machine,workload,application,juju}-status

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
Xav Paice (xavpaice) wrote :
review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 3824e72b41e58a89d0dc250a2524d83ff50cb416

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/jujulint.py b/jujulint.py
2index 81cc53b..8250e23 100755
3--- a/jujulint.py
4+++ b/jujulint.py
5@@ -265,6 +265,64 @@ def map_charms(applications, model):
6 model.app_to_charm[app] = charm
7
8
9+def check_status(what, status, expected):
10+ if isinstance(expected, str):
11+ expected = [expected]
12+ if status.get("current") not in expected:
13+ logging.error("%s has status '%s' (since: %s, message: %s); {We expected: %s}"
14+ % (what, status.get("current"), status.get("since"),
15+ status.get("message"), expected))
16+
17+
18+def check_status_pair(name, status_type, data_d):
19+ if status_type in ["machine", "container"]:
20+ primary = "machine-status"
21+ primary_expected = "running"
22+ juju_expected = "started"
23+ elif status_type in ["unit", "subordinate"]:
24+ primary = "workload-status"
25+ primary_expected = ["active", "unknown"]
26+ juju_expected = "idle"
27+ elif status_type in ["application"]:
28+ primary = "application-status"
29+ primary_expected = ["active", "unknown"]
30+ juju_expected = None
31+
32+ check_status("%s %s" % (status_type.title(), name), data_d[primary],
33+ expected=primary_expected)
34+ if juju_expected:
35+ check_status("Juju on %s %s" % (status_type, name),
36+ data_d["juju-status"],
37+ expected=juju_expected)
38+
39+
40+def check_statuses(juju_status, applications):
41+ for machine_name in juju_status["machines"]:
42+ check_status_pair(machine_name, "machine", juju_status["machines"][machine_name])
43+ for container_name in juju_status["machines"][machine_name].get("container", []):
44+ check_status_pair(container_name, "container",
45+ juju_status["machines"][machine_name][container_name])
46+
47+ for app_name in juju_status[applications]:
48+ check_status_pair(app_name, "application",
49+ juju_status[applications][app_name])
50+ for unit_name in juju_status[applications][app_name].get("units", []):
51+ check_status_pair(unit_name, "unit",
52+ juju_status[applications][app_name]["units"][unit_name])
53+ # This is noisy and only covers a very theoretical corner case
54+ # where a misbehaving or malicious leader unit sets the
55+ # application-status to OK despite one or more units being in error
56+ # state.
57+ #
58+ # We could revisit this later by splitting it into two passes and
59+ # only warning about individual subordinate units if the
60+ # application-status for the subordinate claims to be OK.
61+ #
62+ # for subordinate_name in juju_status[applications][app_name]["units"][unit_name].get("subordinates", []):
63+ # check_status_pair(subordinate_name, "subordinate",
64+ # juju_status[applications][app_name]["units"][unit_name]["subordinates"][subordinate_name])
65+
66+
67 def lint(filename, lint_rules):
68 model = ModelInfo()
69
70@@ -286,6 +344,8 @@ def lint(filename, lint_rules):
71 check_subs(model, lint_rules)
72 check_charms(model, lint_rules)
73
74+ check_statuses(j, applications)
75+
76 results(model)
77
78

Subscribers

People subscribed via source and target branches