[03:56] morning all [07:49] this may or may not be an operator specific problem but i'll ask here - how would one ensure a container is secured with TLS? Should the operator framework create an ingress or is that a Juju thing? jam you may know? [07:50] I would have imagined that the operator pod would form a http relation with the ingress perhaps? [07:51] I've set the charm options juju-external-hostname and kubernetes-ingress-allow-http=true however I'm not seeing any ingresses being created! [07:55] note - I am using microk8s not charmed k8s [08:03] t0mb0: The answer depends on the charm and the interface being used indeed.. TLS is used by several independent protocols (we're doing IRC over TLS just now) [08:04] t0mb0: Is the question specific to microk8s? [08:05] t0mb0, have you done "microk8s enable ingress" ? [08:05] https://microk8s.io/docs/addons [08:06] I believe for Juju itself you need to enable "dns" and "storage" but if the applications you're deploying need other K8s services like an ingress controller, then you need to have those enabled as well. [08:10] Morning jam [08:10] morning niemeyer [08:16] jam, thanks! I believe microk8s enable ingress was what I was looking for [08:17] thanks for your input too niemeyer [08:25] t0mb0: np, glad it's sorted [08:44] hi Chipaca . just in time for me to step out for lunch :) [08:45] jam: good morning! buen provecho :) [08:55] > We should be consistent on ordering. However, I do believe 'unittest.assertEqual' assumes (expected, actual) ordering. Because if you do: [08:55] jam: Added another comment there.. I don't think that's true. [08:56] Let's please keep the usual obtained, expected order.. even the examples in unittest.py itself order like that. [09:03] Also: https://github.com/python/cpython/tree/3.7/Lib/unittest/test [09:07] niemeyer: what should I see in that link? [09:07] Tests? :) [09:07] Chipaca: It's the tests for unittest itself [09:07] ah, gotcha [09:07] Chipaca: All of them follow obtained, expected.. [09:08] So it'd be slightly awkward if the author intended the opposite [09:08] i wonder why they chose the diff to go in the opposite direction then [09:08] Chipaca: I don't see it as reversed [09:09] Chipaca: I actually don't even know what I expect myself in that sense, though, to be honest [09:11] fair [09:11] so my first hit for: "python unittest assertEqual expected" was that it was "expected, actual" according to xUnit conventions [09:12] Python itself carefully says "first, second" [09:12] jam: Not so carefully, though.. just read the docstrings of these functions [09:12] but the diff does read backward in my head for that. (this has been added / missing relative to?) [09:13] self.assertEqual(the_exception.error_code, 3) [09:13] This is in the docstring of assert raises [09:14] I find ("foo" == var) inverted given years of reading it the other way around, but I wouldn't mind adapting if we were following a pattern.. But we are not.. we'd both be making it awkward based on common style, and on the intended form of the testing library we use, so I'm -1 on it [09:15] jam: Isn't xunit coming from Java? [09:17] https://bugs.python.org/issue10573 seems to be the bug, mfoord raised the issue of ordering so you get appropriate diffs [09:17] https://mail.python.org/pipermail/python-dev/2010-December/106954.html is Guido's comment on it [09:18] (old, new) matches diff and matches (expected, actual), but intentionally using "first, second" in the code instead. [09:18] so, its fine, we can go with unittest's convention, but it does mean that all the diffs are "how expected differs from actual" rather than "how actual differs from expected" [09:19] This second link makes me sad.. [09:19] It's a glimpse of poor leadership.. [09:20] "Yeah, we do use that ordering in our code everywhere, but people elsewhere use different conventions.. so we don't care.. do whatever." [09:21] Multiply that by 3 decades, and bingo.. [09:23] there is also https://youtrack.jetbrains.com/issue/PY-26471 for the ordering in PyCharm. [09:24] And their example tutorial actually puts it as assertEqual(foo, 10), but then prints Expected: 'foo', Actual: 10. [09:24] First, Second at least tells you where to look and makes you actually figure out which is expected and what is actual. [09:24] I'll clean up Harness. [09:24] to conform [09:25] Haha, priceless :P [09:42] PR operator#235 opened: test/test_harness.py: Fix the ordering to assume actual/expected [11:01] Muy buenos días a todos! [11:01] morning facubatista [11:01] hola jam [11:11] Morning Facundo [11:13] hola niemeyer :) [11:53] jam, I don't understand your comment about not replacing 'juju_exec_path' in Chipaca's branch [11:54] facubatista, juju_exec_path = juju_exec_path.parent / dispatch_path [11:54] jam, IIUC, we need to check if the juju_exec_path exist *and if it's not ourselves* (that check still missing), and only then execute it... but if we decide to execute it, we'll replace it, right? [11:54] If you replace it, it becomes harder to tell "if it is ourself" [11:55] jam, but that verification should be done before [11:56] facubatista, well, I would expect to be done right around that point, as that is the point you are seeing if it exists and what it points at [11:56] yes that check is still missing, fwiw [11:57] if juju_exec_path.exists() and juju_exec_path.resolve() != Path(sys.argv[0]).resolve(): [11:57] jam, I'd do something like ^ [11:57] facubatista, sure. my point was that juju_exec_path was already Path(sys.argv[0]), so you could just use it if you don't replace the var first. [11:58] ack [12:09] Hi guys, is there currently a path to retrieve the ip address of a unit? Model seems to hint you have to traverse the BindingMapping of the full model if you want so [12:14] pekkari: I don't think there is another way [12:15] pekkari: i'm not even sure there is an ip address of a unit without reference to a binding, so it's not clear to me this is a deficiency [12:24] pekkari, in the juju model, you might be deployed to a machine that has multiple network cards and the operator wants different applications on different interfaces, so you have to go via the binding so the operator can tell you how that piece is configured. [12:24] there is no "one true IP" for a unit as a whole [12:27] yeah, multiple addresses is certainly something I understand, I'm just struggling to find from a charm event the way up to an ip address related to the binding of the relation we run on [12:31] pekkari, def _on_changed(self, event): self.model.get_binding(relation_name).network ? [12:31] are you in a Charm, or in a separate component ? [12:32] binding key can be a relation as well, so if you wanted [12:32] jam that may be it [12:32] self.model.get_binding(event.relation) [12:32] I'm in a charm, defining the on_identity_service_relation_joined, and there I need the ip of the binding it talks to keystone [12:33] pekkari, I don't think you tell Keystone about the network details to keystone. I would expect you to tell keystone about some other binding. [12:34] erm no, this charm tells it's ip address in the binding to keystone to setup the endpoint url [12:34] pekkari, OS traditionally had public/private/admin bindings to describe the application you were deploying, so that would be, self.model.get_binding('public') [12:35] pekkari, I would expect that a sysadmin would configure the binding of the keystone endpoint to "how keystone should talk to my app" but what you want to tell Keystone is "how should other apps (eg neutron/nova/etc) talk to my app" [12:35] which is not the binding of the relationship to keystone, but a different binding on your charm. [12:36] that is very true, however hardcoding the public binding makes me wonder if there is a better way to put it [12:37] certainly may not be a problem, at the end of the day, you only want the service to be reached in public space [12:38] pekkari, if its your charm, you define what endpoint you are advertising to keystone [12:38] it may be right jam, as long as if you want another you can simply configure the public binding to point to another space [12:38] if it is "all openstack charms", then you can pass in the name of the public binding in __init__ and have your code track that. [12:39] pekkari, correct. that is the point of having an endpoint that sysadmins can bind [12:39] thanks for the guidance! [12:53] * facubatista brb [12:53] PR operator#235 closed: test/test_harness.py: Fix the ordering to assume actual/expected [12:57] facubatista: didn't #209 fix #198 ? [12:57] PR #209: Enable stderr logging if JUJU_DEBUG is set [12:57] Issue #198: DEBUG log messages not emitted [12:57] jam: or you :) [12:58] Chipaca, no. I didn't do both at the same time. We still only put INFO messages to juju-log, as it wasn't clear to me if we wanted to change that behavior. I wasn't clear why we didn't default to DEBUG from the start, so I needed to understand that first. [12:59] its a trivial change to change the level of that logger [12:59] Chipaca, https://paste.ubuntu.com/p/3xf4gPctxV/ [12:59] its just a question of why was it at INFO to start with, and if we chose to change it, is a small fix for 198 [13:04] jam, Chipaca, we want that by default only INFO messages go to juju, and if charm developer decides to send DEBUG too, to be achievable (users always can control the level they see through `juju debug-log`, anyway) [13:04] for that behaviour to happen, we need: [13:04] - the juju handler to be in DEBUG level [13:04] - the logger to be in INFO by default <-- this is what the charm developer can control [13:05] I still didn't prepare a branch for #198 because I still do not understand how the charm code could change the log level according to something external, and if we could do that automatically [13:05] Issue #198: DEBUG log messages not emitted [13:06] (so the charm would emit INFO or DEBUG according to something, not harcoded) [13:14] facubatista, so if we call 'juju-log' then Juju itself will filter based on 'juju model-config logging-config' [13:14] facubatista, we could ask for a way for juju to tell us a given unit's logging config, if we wanted to avoid triggering juju-log in the first place [13:15] jam, but we'd need to ask that for every message, right? as it may change at anytime [13:15] facubatista, so it can, but I could say that we don't notice a change inside a single hook execution [13:17] jam, I like that optimization! JujuLogHandler will stop executing an external process for each message if it makes no sense [13:17] jam, and all we need to do for that is set the level in JujuLogHandler according to what the config of the unit [13:17] facubatista, it would need a juju change, so we'd have to deal with versions-of-juju, etc. [13:18] if we have it, we use it [13:18] facubatista: jam: i think it's an optimisation we can add when/if juju gets the feature [13:19] it's a good way also to "control the level of the charm"? [13:19] or there's a better way? [13:19] my point is: [13:20] I have 5 units with 5 charms; I call `juju debug-log` with level in DEBUG because I want to see debug messages of *one* of those charms, the rest I want to see them in INFO ... which is the best way to achieve that? [13:21] jam, which is the unit's logging level by default? [13:24] facubatista: juju debug-log --include=theunit ? [13:24] The '--include' and '--exclude' options filter by entity. The entity can be [13:24] a machine, unit, or application for vm models, but can be application only [13:24] for k8s models. [13:28] Chipaca, that will not show me the other ones ... my point is seeing all of them, one in DEBUG the rest in INFO [13:28] jam, how do I change the unit's logging config? [13:29] facubatista, 'juju model-config logging-config="unit.?=INFO"' [13:29] by default 'unit=DEBUG' [13:29] you can do [13:29] 'juju model-config logging-config' [13:29] to see what the default ais [13:30] =INFO;unit=DEBUG [13:30] root? [13:44] juju model-config "logging-config==INFO;unit.unit-postgresql-0=DEBUG;unit=INFO" [13:44] facubatista, ^^ [13:56] parallalysed == paralysed by parallelism [14:09] niemeyer, https://github.com/canonical/operator/pull/196 still needs your follow up review [14:09] PR #196: Factor out the Harness changes for test_model.py [14:09] facubatista, I think #230 doesn't have a comment from you yet. but I think I addressed Chipaca's comments. [14:09] PR #230: Testing harness no events for own data [14:10] niemeyer, looking at 196, I see a couple things that I think have been superseded. wait on that one until tomorrow. [14:11] jam: ack [14:11] Id like to land 230 and then clean up the diff [14:12] jam, will check [14:12] th [14:12] thx [14:13] travis is slow today [14:13] i guess it's because we share org with something else [14:13] jam: Added a comment in #230 [14:13] PR #230: Testing harness no events for own data [14:14] jam: As I said, looks reasonable overall.. was just curious about that small detail [14:15] how reasonable would it be to make it so that, if you execute your charm directly with no JUJU_ stuff defined (or maybe the trigger is running it from a terminal) you get an interactive session? [14:16] like ipython with the charm already built for you to play with [14:16] Chipaca, so there are a bunch of bits that you'd need (what is your unit name, what app are you, what is your config, etc). that makes it a bit hard to be initialized and interactive without sufficient context to know what to actually do [14:16] what 'hook' are you wanting to run right now. [14:16] Chipaca: That sounds like a pretty cool idea [14:16] jam: Imagine dropping it in a shell with a Harness [14:17] that would be neat [14:17] if we could do it without a harness even better (but yeah that'd require _some_ JUJU_ stuff [14:17] um [14:17] niemeyer, I think having a good way to do that is great. I don't think 'dispatch' would quite be the entry point for that. [14:17] does 'juju ssh' give you JUJU_ things? [14:18] Chipaca, 'juju run --unit X' does, IIRC [14:18] jam: It might error out nicely saying "Hey, you are not in a juju environment.. if you wanna play, try dispatch --foobar" [14:18] yeah something like that [14:18] all the things :) [14:18] Chipaca: Not sure we could do without a harness.. as jam mentioned, there's a bunch of things required. It's hard to do something when there's no data, no CLIs, no ... [14:18] yep [14:19] i'll try to spec it out a bit more so we can discuss (mostly just with examples of what i'd like to see) [14:19] now that i know it's not completely zany :) [14:20] Thanks for that [14:37] niemeyer, so 'relation.data[entity]' doesn't load that entities data until you do something with it. It actually doesn't even load the data if you do "relation.data[entity]['foo'] = 'bar'" because it doesn't need to know the old content of foo to set it to bar [14:37] it only loads it if you access foo, or iterate or len(relation.data[entity]) [14:38] jam: Makes sense. Would you mind to add a short note stating that, just to remind the next reader? [14:38] sure [14:38] Thanks! [14:40] niemeyer, I confirmed with some debug statements inside the _load when you wouldn't want it to be loaded. :) [14:41] * jam heads for EOD [14:43] Cheers [14:43] jam: Have a good EOD [15:04] * Chipaca shakes fist at multipass [15:07] * facubatista -> lunch [15:14] stub: 👋 [15:15] stub: is there a usable-for-simple-stuff postgres interface I could use? [16:00] facubatista: 2FA shenanigans, i'll be there as soon as it lets me [16:01] wait, google signed me out everywhere again [16:01] sigh [16:09] facubatista: I'm guessing something's come up at your end as well. Let's reschedule. [16:10] Issue operator#231 closed: Harness: Has errors on charms which define action handlers [16:10] PR operator#232 closed: ops.testing.Harness actions metadata support. (#231) [16:11] Chipaca: Is there something holding #203 back still? [16:11] PR #203: ops, test: revert the EventSet change, make EventsBase ObjectEvents [16:11] niemeyer: a review? (and now a deconflict also) [16:11] We should make a push to these old PRs through or out [16:12] Chipaca: My +1 has 12 days [16:14] Chipaca, grrr, had the alarm off, sorry [16:14] * facubatista is back [16:29] facubatista: huh [16:29] facubatista: https://github.com/canonical/operator/blob/master/test/test_framework.py#L773 [16:29] is a bit weird [16:29] I think you meant FooEvent(EventBase) [17:04] I'm mostly-EOD. Might pop in later to tinker with dispatch a little as i'm behind on where i wanted to be. [17:04] 👋 [17:09] * facubatista brb [20:01] niemeyer, did you read this? https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points [20:05] facubatista: I hadn't, will look in detail tomorrow, thanks! [20:06] :) [21:22] * facubatista eods [21:59] PR operator#203 closed: ops, test: revert the EventSet change, make EventsBase ObjectEvents === narindergupta is now known as narinderguptamac