Skip to content

Commit cb48c2e

Browse files
committed
feat: python-libjuju without AllWatcher
refactor all things! demo! use both async (old) and wrapped async (new) to get same data cleanup🧼 shorter helper thread code wip note about exposed Simon says implement Application.exposed typed decorator for the win wip plain decorator works better cleanup🧼 name is entity id wip fix: missing file type up .wait_for_idle() better code style write down next steps chore: refactor jrpc response type coercion for testing chore: refactor jrpc response type coercion for testing, missing files chore: document different ways .wait_for_idle(...) may be called chore: refactor for testability chore: wip / squash me chore: clarify wait for idle params chore: clarify wait for idle params wip chore: more hookup chore: mock out everything needed for old idle loop chore: refactor test setup chore: more tests chore: start on app and unit counting mechanics chore: more app and unit counting mechanics reimplement unset status back fill chore: refactor legacy loop, fix error condition; note that status compounding is ineffective chore: refactor new loop checker, note to do chore: kidna finish the idle loop, hopefully? chore: fill in wait_for_at_least_units=N chore: wait_for_exact_units chore: exact and at least units are exclusive cleanup🧼
1 parent c58ec9d commit cb48c2e

19 files changed

+1735
-191
lines changed

example.py

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import logging
2+
import pprint
3+
4+
from juju import jasyncio
5+
from juju.model import Model
6+
7+
8+
async def main() -> None:
9+
m = Model()
10+
await m.connect(model_name="testm")
11+
# from juju.client._client import CharmsFacade
12+
# f = CharmsFacade.from_connection(m.connection())
13+
# rv = await f.CharmInfo("local:noble/fake-ingress-0")
14+
# print(rv)
15+
# print()
16+
17+
#rv = await f.ApplicationsInfo(entities=[{"tag": "application-database"}])
18+
#print(rv)
19+
#print()
20+
21+
for app_name, app in m.applications.items():
22+
pprint.pprint(app.model.state.state["application"][app_name][-1])
23+
print(f"""{app_name}:
24+
name............... {app.name!r}
25+
charm_name......... {app.charm_name!r}
26+
exposed............ {app.exposed!r}
27+
charm_url.......... {app.charm_url!r}
28+
owner_tag.......... {app.owner_tag!r}
29+
life............... {app.life!r}
30+
min_units.......... {app.min_units!r}
31+
constraints["arch"] {app.constraints["arch"]!r}
32+
subordinate........ {app.subordinate!r}
33+
status............. {app.status!r}
34+
workload_version... {app.workload_version!r}
35+
""")
36+
for u in app.units:
37+
print(f"{u.name}: {u.agent_status!r} {u.workload_status!r}")
38+
39+
await m.wait_for_idle()
40+
41+
await m.disconnect()
42+
43+
44+
class SymbolFilter(logging.Filter):
45+
DEBUG = '🐛'
46+
INFO = 'ℹ️'
47+
WARNING = '⚠️'
48+
ERROR = '❌'
49+
CRITICAL = '🔥'
50+
51+
def filter(self, record):
52+
record.symbol = getattr(self, record.levelname, '#')
53+
# FIXME can control log record origin here if needed
54+
return True
55+
56+
57+
if __name__ == "__main__":
58+
# FIXME why is level=DEBUG broken?
59+
#logging.basicConfig(level="INFO", format="%(symbol)s %(message)s")
60+
#logging.root.addFilter(SymbolFilter())
61+
jasyncio.run(main())

fullstatus.json

+322
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
{
2+
"request-id": 7,
3+
"response": {
4+
"applications": {
5+
"grafana-agent-k8s": {
6+
"base": {
7+
"channel": "22.04/stable",
8+
"name": "ubuntu"
9+
},
10+
"can-upgrade-to": "",
11+
"charm": "ch:arm64/jammy/grafana-agent-k8s-75",
12+
"charm-channel": "latest/stable",
13+
"charm-profile": "",
14+
"charm-version": "",
15+
"endpoint-bindings": {
16+
"": "alpha",
17+
"certificates": "alpha",
18+
"grafana-cloud-config": "alpha",
19+
"grafana-dashboards-consumer": "alpha",
20+
"grafana-dashboards-provider": "alpha",
21+
"logging-consumer": "alpha",
22+
"logging-provider": "alpha",
23+
"metrics-endpoint": "alpha",
24+
"peers": "alpha",
25+
"receive-ca-cert": "alpha",
26+
"send-remote-write": "alpha",
27+
"tracing": "alpha"
28+
},
29+
"exposed": false,
30+
"int": 1,
31+
"life": "",
32+
"meter-statuses": null,
33+
"provider-id": "4ecc75be-f038-4452-b1af-640d1b46f1c6",
34+
"public-address": "10.152.183.55",
35+
"relations": {
36+
"peers": [
37+
"grafana-agent-k8s"
38+
]
39+
},
40+
"status": {
41+
"data": {},
42+
"info": "installing agent",
43+
"kind": "",
44+
"life": "",
45+
"since": "2024-09-30T07:44:15.63582531Z",
46+
"status": "waiting",
47+
"version": ""
48+
},
49+
"subordinate-to": [],
50+
"units": {
51+
"grafana-agent-k8s/0": {
52+
"address": "10.1.121.164",
53+
"agent-status": {
54+
"data": {},
55+
"info": "",
56+
"kind": "",
57+
"life": "",
58+
"since": "2024-09-30T07:44:15.469295423Z",
59+
"status": "idle",
60+
"version": "3.5.1"
61+
},
62+
"charm": "",
63+
"leader": true,
64+
"machine": "",
65+
"opened-ports": [],
66+
"provider-id": "grafana-agent-k8s-0",
67+
"public-address": "",
68+
"subordinates": null,
69+
"workload-status": {
70+
"data": {},
71+
"info": "Missing incoming (\"requires\") relation: metrics-endpoint|logging-provider|grafana-dashboards-consumer",
72+
"kind": "",
73+
"life": "",
74+
"since": "2024-09-30T07:43:41.649319444Z",
75+
"status": "blocked",
76+
"version": ""
77+
},
78+
"workload-version": "0.35.2"
79+
}
80+
},
81+
"workload-version": "0.35.2"
82+
},
83+
"hexanator": {
84+
"base": {
85+
"channel": "24.04/stable",
86+
"name": "ubuntu"
87+
},
88+
"can-upgrade-to": "",
89+
"charm": "local:noble/hexanator-1",
90+
"charm-profile": "",
91+
"charm-version": "",
92+
"endpoint-bindings": {
93+
"": "alpha",
94+
"ingress": "alpha",
95+
"rate-limit": "alpha"
96+
},
97+
"exposed": false,
98+
"int": 1,
99+
"life": "",
100+
"meter-statuses": null,
101+
"provider-id": "b5efccf2-5a15-41a0-af0f-689a8d93a129",
102+
"public-address": "10.152.183.113",
103+
"relations": {},
104+
"status": {
105+
"data": {},
106+
"info": "",
107+
"kind": "",
108+
"life": "",
109+
"since": "2024-09-30T00:12:47.878239549Z",
110+
"status": "active",
111+
"version": ""
112+
},
113+
"subordinate-to": [],
114+
"units": {
115+
"hexanator/0": {
116+
"address": "10.1.121.184",
117+
"agent-status": {
118+
"data": {},
119+
"info": "",
120+
"kind": "",
121+
"life": "",
122+
"since": "2024-09-30T00:13:16.731257044Z",
123+
"status": "idle",
124+
"version": "3.5.1"
125+
},
126+
"charm": "",
127+
"leader": true,
128+
"machine": "",
129+
"opened-ports": [],
130+
"provider-id": "hexanator-0",
131+
"public-address": "",
132+
"subordinates": null,
133+
"workload-status": {
134+
"data": {},
135+
"info": "",
136+
"kind": "",
137+
"life": "",
138+
"since": "2024-09-30T00:12:47.878239549Z",
139+
"status": "active",
140+
"version": ""
141+
},
142+
"workload-version": ""
143+
}
144+
},
145+
"workload-version": ""
146+
},
147+
"mysql-test-app": {
148+
"base": {
149+
"channel": "22.04/stable",
150+
"name": "ubuntu"
151+
},
152+
"can-upgrade-to": "",
153+
"charm": "ch:arm64/jammy/mysql-test-app-62",
154+
"charm-channel": "latest/edge",
155+
"charm-profile": "",
156+
"charm-version": "",
157+
"endpoint-bindings": {
158+
"": "alpha",
159+
"application-peers": "alpha",
160+
"database": "alpha",
161+
"mysql": "alpha"
162+
},
163+
"exposed": false,
164+
"int": 2,
165+
"life": "",
166+
"meter-statuses": null,
167+
"provider-id": "4338786a-a337-4779-820d-679a59ba1665",
168+
"public-address": "10.152.183.118",
169+
"relations": {
170+
"application-peers": [
171+
"mysql-test-app"
172+
]
173+
},
174+
"status": {
175+
"data": {},
176+
"info": "installing agent",
177+
"kind": "",
178+
"life": "",
179+
"since": "2024-09-30T07:48:25.106109123Z",
180+
"status": "waiting",
181+
"version": ""
182+
},
183+
"subordinate-to": [],
184+
"units": {
185+
"mysql-test-app/0": {
186+
"address": "10.1.121.142",
187+
"agent-status": {
188+
"data": {},
189+
"info": "",
190+
"kind": "",
191+
"life": "",
192+
"since": "2024-10-01T00:15:03.216904329Z",
193+
"status": "idle",
194+
"version": "3.5.1"
195+
},
196+
"charm": "",
197+
"leader": true,
198+
"machine": "",
199+
"opened-ports": [],
200+
"provider-id": "mysql-test-app-0",
201+
"public-address": "",
202+
"subordinates": null,
203+
"workload-status": {
204+
"data": {},
205+
"info": "",
206+
"kind": "",
207+
"life": "",
208+
"since": "2024-09-30T07:47:54.212959856Z",
209+
"status": "waiting",
210+
"version": ""
211+
},
212+
"workload-version": "0.0.2"
213+
},
214+
"mysql-test-app/1": {
215+
"address": "10.1.121.190",
216+
"agent-status": {
217+
"data": {},
218+
"info": "",
219+
"kind": "",
220+
"life": "",
221+
"since": "2024-09-30T23:49:39.923901864Z",
222+
"status": "idle",
223+
"version": "3.5.1"
224+
},
225+
"charm": "",
226+
"machine": "",
227+
"opened-ports": [],
228+
"provider-id": "mysql-test-app-1",
229+
"public-address": "",
230+
"subordinates": null,
231+
"workload-status": {
232+
"data": {},
233+
"info": "",
234+
"kind": "",
235+
"life": "",
236+
"since": "2024-09-30T07:47:54.211414881Z",
237+
"status": "waiting",
238+
"version": ""
239+
},
240+
"workload-version": "0.0.2"
241+
}
242+
},
243+
"workload-version": "0.0.2"
244+
}
245+
},
246+
"branches": {},
247+
"controller-timestamp": "2024-10-01T07:25:22.51380313Z",
248+
"machines": {},
249+
"model": {
250+
"available-version": "",
251+
"cloud-tag": "cloud-microk8s",
252+
"meter-status": {
253+
"color": "",
254+
"message": ""
255+
},
256+
"model-status": {
257+
"data": {},
258+
"info": "",
259+
"kind": "",
260+
"life": "",
261+
"since": "2024-09-27T08:21:45.368693216Z",
262+
"status": "available",
263+
"version": ""
264+
},
265+
"name": "testm",
266+
"region": "localhost",
267+
"sla": "unsupported",
268+
"type": "caas",
269+
"version": "3.5.1"
270+
},
271+
"offers": {},
272+
"relations": [
273+
{
274+
"endpoints": [
275+
{
276+
"application": "grafana-agent-k8s",
277+
"name": "peers",
278+
"role": "peer",
279+
"subordinate": false
280+
}
281+
],
282+
"id": 0,
283+
"interface": "grafana_agent_replica",
284+
"key": "grafana-agent-k8s:peers",
285+
"scope": "global",
286+
"status": {
287+
"data": {},
288+
"info": "",
289+
"kind": "",
290+
"life": "",
291+
"since": "2024-09-30T07:43:31.018463595Z",
292+
"status": "joined",
293+
"version": ""
294+
}
295+
},
296+
{
297+
"endpoints": [
298+
{
299+
"application": "mysql-test-app",
300+
"name": "application-peers",
301+
"role": "peer",
302+
"subordinate": false
303+
}
304+
],
305+
"id": 1,
306+
"interface": "application-peers",
307+
"key": "mysql-test-app:application-peers",
308+
"scope": "global",
309+
"status": {
310+
"data": {},
311+
"info": "",
312+
"kind": "",
313+
"life": "",
314+
"since": "2024-09-30T07:47:52.823202648Z",
315+
"status": "joined",
316+
"version": ""
317+
}
318+
}
319+
],
320+
"remote-applications": {}
321+
}
322+
}

0 commit comments

Comments
 (0)