[05:09] morning all [09:10] goooooooooooooooooooooooooooooooooooooooood morning! [09:11] morning Chipaca . it seems Guido was against main scripts inside packages [09:11] I'm not sure why they created __main__.py then. [09:19] jam: is this related to the 'cannot import commands' thing? [09:20] Chipaca, yes. You can see my investigation on mattermost, but basically when running the primary script [09:20] your __name__ is __main__ which means you aren't part of a __package__ [09:21] facubatista: I just opened latest/beta, and moved latest/edge to it, so people can use that and we can open master to edge in due course [09:21] jam: lol [09:23] jam: another LOL is that jujuignores aren't gitignores [09:24] Chipaca, probably closer to bzr ignores I would guess [09:24] and the only gitignore python implementations seem to be terrible [09:24] e.g. https://github.com/mherrmann/gitignore_parser [09:24] 'A spec-compliant gitignore parser for Python' [09:25] Chipaca, also, something to consider, one reason git ignores work well, is because you can create an exception with an explicit 'git add' but you can't do that for charms unless we have some sort of manifest [09:25] has an open issue about 'foo' matching 'barfoo' [09:25] and the author says "I have no idea LOL" [09:25] Chipaca, I have no idea... always a good response :) [09:25] and it has no tests [09:25] even though it's based on a different project that does has tests, but hasn't seen work in years [09:25] (to the point that it's only been tested on 3.5) [09:26] and that summarises how far i got yesterday before hating the world and going to sleep :) [09:27] Chipaca, don't hate the world, hate the... players ? [09:28] jam: I shall hate the world, by the power of synecdoche! [09:32] going back to jujuignore, it's a SMOP to translate https://github.com/juju/charm's jujuignore.go (and jujuignore_test.go) to python for our use [09:32] but I don't think I can make it for release [09:32] so I propose we look for a .jujuignore and bail out if it exists [09:33] Chipaca, so what about .gitignore ? [09:33] Switch and use 'git ls' ? [09:33] or just do .jujuignore but otherwise add everything since that matches juju deploy ? [09:34] jam: well, that's the other approach [09:34] i was thinking of getting .gitignore parsing to work, which should be a day of work on top of one of the se projects [09:34] these* [09:34] Chipaca, I'd go for 'juju deploy' over most other things, because that is setting the precedence [09:34] * jam goes to make coffee [09:35] fair [09:35] ok, let's do that [09:35] i should be able to do that :) [09:35] i don't think i can do that and 'charmcraft init' in four days though :) [09:41] Chipaca, can you split off pieces that I can help with? [09:41] eg, the jujuignore parser I could do while you focus on other things [09:41] jam: you also have plenty on your plate already :) [09:42] Chipaca, indeed, but charmcraft release happens frist [09:42] first [09:45] jam: ok let's do it [09:46] Chipaca, ok, I'll put together a jujuignore.py for charmcraft [09:50] meanwhile i'll poke the init beast [09:51] facubatista: WRT --system, it's *probably* easier to try with --system and if it fails try again without [10:02] jam, facubatista: meeting [10:17] jam: in setup.py, set zip_safe=False [10:18] we can sort out the why and the how later :) [10:21] Chipaca, to make it do what? It still doesn't solve the problem that you can't run "python ./charmcraft' because the import paths are wrong [10:21] You *can* run python -m charmcraft for whatever reason [10:21] jam: ah, for 'python setup.py install' to work, i meant [10:21] Chipaca, does zip_safe=false actually fix that? It seems like you still wouldn't have a 'charmcraft' you could drop in your path [10:21] work as in result in a working 'charmcraft' script [10:22] it does fix that, yes [10:22] that's the only difference between what 'setup.py install' and 'pip install' does [10:24] jam: python ./charmcraft (and just 'python charmcraft') work as long as your PYTHONPATH includes . [10:24] jam: (which it shouldn't by default) [10:24] Chipaca, but isn't that bad behavior? [10:25] Chipaca, so my goal was to 'build something' and then symlink a 'charmcraft' into my 'bin' directory so I can just run it [10:25] that feels like something that should work [10:25] if zip_safe=false gets us there, that seems ek [10:25] ok [10:25] jam: zip_safe=False gets you a charmcraft script in the venv's bin, which you should be able to symlink [10:26] i haven't tried that [10:27] Chipaca, I just did and it works [10:27] well, with venv active, let me try without [10:27] yep [10:27] terrible news then [10:27] :) [10:28] jam: getting __main__.py to dtrt when it can find itself but not the package is a matter of tweaking sys.path, which is ugly but ok [10:28] and if we do that we might be able to move the entry point to that? dunno :) [10:29] at which point we get eggs back [10:29] but, not for now [10:29] now, for init [10:29] zip_safe does what I wanted [10:29] and is small [11:35] ¡Muy buenos días a todos! [11:36] Chipaca, ok with edge->beta, thanks [11:44] oh drat, lunch [11:44] facubatista: buen día seor! [11:44] but also, lunch [12:45] siiigh [13:18] Chipaca, ? [13:18] facubatista: sigh [13:19] facubatista: :) [13:19] little frustrations with jinja [13:19] :) [14:17] Chipaca, what's wrong with jinja ? [14:17] facubatista, reviewed your 'release' pr. I had a couple questions about divergence from snapcraft's CLI. [14:17] If it is intentional, then go with it. [14:17] jam: it prunes the last \n when generating a file, and i hadn't spotted the option to turn that off :) [14:18] Chipaca, https://stackoverflow.com/questions/36870953/jinja2-how-to-remove-trailing-newline [14:18] it seems '-%' the '-' is relevant [14:20] Chipaca, and/or 'trim_blocks=True' 'lstrip_blocks=True' (or false) in Python [14:20] jam: nah, it was the keep_trailing_newline option on the environment i was missing [14:20] not in th eblocks [14:20] 's all sorted now :) [14:20] Chipaca, as long as there is yet-another-way to do it [14:20] :) [14:21] * jam aways [14:21] those options you mentio are about trimming the whitespace around {%s, as opposed to trimming the whitespace at the bottom of the file [14:21] anyway, yeah, all sorted [14:21] also i can't type [14:39] jam: the problem about "No module named 'charmcraft.commands'" kept on bugging me, but i figured it out: eggs don't like new-style namespace packages [14:40] jam: easiest fix for our woes: drop an __init__.pu in charmcraft/commands/ [14:40] facubatista: is there a reason for not having that __init__ beyond "wasn't needed"? [14:40] jam: an __init__.py probably works better [14:41] than a .pu [14:41] what even is a pu [14:41] no don't answer [14:43] Chipaca, I used that __init__.py so you can do this elegant thing in main.py: [14:43] from charmcraft.commands import version, build, store [14:43] store.ReleaseCommand, store.StatusCommand, [14:44] facubatista: which __init__.py? [14:44] * Chipaca puzzled [14:44] charmcraft.commands.store [14:44] oh, wait [14:44] you mean charmcraft/commands/__init__.py ? [14:44] yes [14:44] there's not such thing [14:44] exactly [14:44] and that breaks things :) [14:45] nothing serious i don't think, but it does [14:45] facubatista: that's why 'python setup.py install' doesn't work [14:45] Chipaca, it's not needed theorically [14:45] facubatista: because that builds an egg, and eggs don't like new-style namespace packages [14:45] stupid rotten eggs [14:46] bah, it's supposed to be fixed in https://bugs.python.org/issue17633 but something's still off [14:46] because just dropping __init__.py in there fixes it :) [14:47] facubatista: the other alternative is zip_safe=False on setup.py/setup, but that's less nice i think [14:50] Chipaca, I just did ./setup.py install --prefix=/tmp/foo [14:50] which left me a lib/python3.8/site-packages/charmcraft-0.2.0-py3.8.egg in that dir [14:50] I unzipped that egg [14:50] and it has all the files ok in it [14:50] facubatista: yes. But try running the script that you get from that install. [14:51] you get [14:51] ModuleNotFoundError: No module named 'charmcraft.commands' [14:51] from ...charmcraft.egg/charmcraft/main.py [14:51] line 25 [14:51] which was puzzling because that comes right after 'from charmcraft import __version__' [14:52] and commands is right there in the egg [14:52] Chipaca, actually, https://paste.ubuntu.com/p/xzPhxjXgQN/ [14:53] facubatista: i'm assuming prefix=/tmp/foo means you're not getting the egg added to your import path [14:53] facubatista: so try again with PYTHONPATH=/the/charmcraft.egg [14:53] 11:53:38|facundo@blackfx:/tmp/foo$ PYTHONPATH=lib/python3.8/site-packages/ bin/charmcraft [14:54] File "/tmp/foo/lib/python3.8/site-packages/charmcraft-0.2.0-py3.8.egg/charmcraft/main.py", line 25, in [14:54] ModuleNotFoundError: No module named 'charmcraft.commands' [14:54] k [14:57] facubatista: so that's what jam spotted yesterday, and is fixed by making commands not be a namespace package [14:59] Chipaca, ok [15:00] facubatista: (please confirm) :) [15:00] Chipaca, confirm what? that it works? or that the theory is solid? I don't know enough of that corner, don't want to spend a couple of hours reading about it unless necessary [15:01] facubatista: that dropping an __init__.py into commands makes it work [15:01] facubatista: but, eh, we can dig next week or the other [15:01] or i can propose a pr, innit [15:01] just a silly thing really, it was bugging me [15:02] Chipaca, I don't care about it, people should be using snapcraft or the branch from github :p [15:02] s/snapcraft/the snap/ [15:02] Chipaca, and IMO nobody should never ever do "sudo pip install" [15:03] pip install would've worked because it doesn't make eggs :) [15:03] I wonder why :) [15:04] facubatista: i agree, but i also don't want things to break in strange ways [15:04] Chipaca, more reasons! is adding quirks to our code good for the corner case of somebody installing running setup.py? [15:04] Chipaca, as you wish [15:04] facubatista: we can't control how peple use our stuff :-) [15:04] we can only control what happens when they do [15:05] Chipaca, but we have to prioritize where we invest our scarce time [15:05] * Chipaca invests it in diophantine equations [15:06] * facubatista invests in elephants equestrianism [15:28] Hello everyone, I'd like to know if there's an alternative for unitdata.kv in the operator framework. If not what is the best way to save information pertinent to units [15:34] alejdg: I'm afraid I don't know what unitdata.kv is [15:35] alejdg: how would you do the thing in the absence of the operator framework? [15:36] Chipaca: hey, this is what I'm referring to: https://charm-helpers.readthedocs.io/en/latest/api/charmhelpers.core.unitdata.html [15:38] alejdg: that sounds like something you'd do using _stored = StoredState() on the charm class [15:38] alejdg: not sure doing deltas of config is a good pattern, but if you need to do it that's how you'd go about it [15:40] that'll give you per unit stored state. In the class's __init__ you'd do e.g. self._stored.set_default("some-kv", {}), and then you'd use self._stored["some-kv"] in the hook handlers [15:40] nice I'll try that [15:41] I'm doing that with some config data that comes from a relation. [15:41] maybe there's a better practice for it? [15:41] alejdg: and you definitely need to react to _changes_ to that data, as opposed to the data itself? [15:44] Chipaca: That data doesn't change once the relation has sent it [15:45] alejdg: ah so you're not looking for the "delta these things" feature, just the storing the data for later use? [15:46] then _stored is definitely what you want :-) [15:46] gotcha, thanks a lot! [15:57] alejdg: the 'set_default' thing is possibly the only non-obvious bit of it, where if you forget to do that and instead do the more obvious self._stored["some-kv"] = {} in the __init__, then you're overwriting it every time [17:37] How do I add an event? I added in init `self.framework.observe(self.on.restart_iscsi_services, self.on_restart_iscsi_services)`, I have a function defined `def on_restart_iscsi_services(self, event):`, and I added an actions.yaml file with `restart-iscsi-services` in it. But I get the error that ` File "./src/charm.py", line 47, in __init__ [17:37] self.framework.observe(self.on.restart_iscsi_services, self.on_restart_iscsi_services) [17:37] AttributeError: 'CharmEvents' object has no attribute 'restart_iscsi_services'` [17:38] I was looking at the example from https://github.com/openstack-charmers/charm-ceph-iscsi and they didn't add anything else than that for their actions [17:38] I want a user to be able to do : juju run-action restart-iscsi-services [18:01] crodriguez, let me see [18:09] facubatista, jam told me it is because I'm missing _action at the end [18:09] crodriguez, oh, right, I didn't remember that [18:10] there's not really an easy way to know that lol [18:10] crodriguez, our documentation status makes me sad [18:11] me too :/ [18:11] another question :) is there an easy way to set some configuration parameters as mandatory? Wondering if there is a reusable component somewhere or if I should code it myself [18:28] I don't think there's anything in the operator for that [18:37] ok. Is there a way to stop the code execution after setting "self.unit.status = BlockedStatus" ? [18:37] the charm keeps on executing so the status gets cleared up really quickly [18:45] "return"? [18:45] crodriguez, I mean, if you set to blocked, and right away you do something and it gets unblocked it's fine, right? [18:46] or if you go to blocked and want to stop doing things until another event arrives, just return to exit the method? [19:30] ah yeah I guess I could true/false on the check_mandatory_config function, and then exit on_install() with return depending on the result [19:44] So in reactive I would do something like event A triggers B, when B completed -> trigger C, etc. and that way I would avoid having a really long function doing B+C. Can I do the same with the framework.observe? [19:45] currently I have on.config_changed -> render_config . I would like to trigger something when render_config is completed [20:38] crodriguez, have a function that does B, then another function that does C; then create a function that is hooked to event A, which calls B() and then C() [20:39] I mean, it's something that can be solved simply enough at a Python level, doesn't need to have infrastructure for it [20:43] yeah it can be. I just got used to set states in reactive and triggers things with these states, I was wondering if there is an equivalent here [21:23] facubatista, I see options to set active, maintenance, blocked, but no option to set a charm in error state ? https://github.com/canonical/operator/blob/master/ops/model.py#L770 [22:02] crodriguez: exiting with failure does that [22:02] i don't think you can 'set' error state otherwise [22:03] but i'm no expert :) [22:19] jam, ^ :) [22:20] crodriguez, sorry, I was off already [22:20] (didn't see your message before) [22:47] oh hey :) no problem, notifications aren't great on my side neither. I think it would be good to be able to set an error state sometimes. It allows to set a message more explicit than "config-changed failed"