<div dir="ltr"><div>I am working on writing a Juju charm to deploy the Discourse discussion forum software using their new docker image install process.  This was my first charm, and I'm writing it in Go, because I like Go.  This means I can't use the python charm helpers, but since I don't actually know what they do, that doesn't bother me much :)  Also, it's a good test to see how hard it is to write the charm without the helpers.</div>
<div><br></div><div>Now that I know all the quirks, I think my second charm would be a lot easier to write than my first.  There's just a lot to ingest for that first charm.  However, even this first charm was not that bad.  Now, I have been working on Juju-core for a year, so I know how a lot of stuff works that outsiders would not.  There were still some hurdles to cross, which I detail below, but most were just annoyances, not show stoppers.  </div>
<div><br></div><div>Sorry for the length and the randomness, this is based on notes taken as I was working on the charm in small chunks of time over several days.</div><div><br></div><div><br></div><div>I started by looking at the Charm Walkthrough... this was actually a mistake, because that skips over some parts above it in the docs (namely metadata.yaml, /hooks, and config.yaml)... and I thought I was starting from the beginning and didn't see anything about those things, and so didn't think they were documented.  This is partially my fault for not looking through the docs more carefully, but... maybe the walkthrough should talk about those things first? :)</div>
<div><br></div><div><div>Have I mentioned how much I hate YAML?  Is it possible to write the config in JSON or something instead?  JSON's no picnic either, but at least it doesn't care about white space.  I'd recommend TOML, but I doubt the conservative dev-ops people would go for it.  Ideally we'd support all three (and other formats if people wanted).<br>

</div><div><div><br></div><div>The docs on <a href="https://juju.ubuntu.com/docs/authors-hook-environment.html#hook-tools" target="_blank">hook tools</a> is missing one very important piece of information:  "hook tools are executables that exist in the $PATH on the machine where the unit is deployed" ... it took me a while to understand that these were actual executables I could run from my hook's code and not like functions or something from somewhere (where?).  <br>

</div><div><br><div>We should document where the charm files are actually deployed on disk.  I ended up figuring this out from one of the screenshots of charm debugging which had the path shown, but there were times when I just wanted to ssh into the machine and make sure the charm was deploying the stuff I thought it was deploying.</div>
<div><br></div><div>Deploying a local charm is needlessly complex. Why do I need to create a special directory structure, move my code under there, set --repository and write local:<foo> and even then it has to go scanning through the directory, looking for a charm with the right name in the metadata.yaml.  Why can't I just say "deploy the charm in <this> directory"? e.g.   juju deploy --local=<path>  Bam, done.</div>
<div><br></div><div>The docs says the <a href="https://juju.ubuntu.com/docs/authors-hook-environment.html#environment-variables" target="_blank">environment variables</a> are "always available" except... they're not.  They're not when I SSH into the machine.  They're not set when I do juju debug-hooks either (at least before a hook fires).  The reason this confused me is that most of these environment variables seem like they should be static, and could easily just be set all the time, so I sort of assumed they were.  Now that I think about it, they really can't be set all the time, in the case of hulk-smashed charms, etc... but newbie charm authors won't be thinking of that. We should make it more clear that these environment variables are only available to the code running the hook when the hook is actively running.</div>

<div><br></div><div>Why does the config file for juju-deploy --config need to have servicename:  at the beginning of the file?  Of course it's for that servicename, that's why I gave it to this deploy command.  If there's no top-level value, just assume the whole thing is for this service.  This took me a while to figure out... I sort of assumed the config file was just an easy shorthand so I didn't have to type a bunch of stuff out on the command line.</div>

<div><br></div><div><div>It's really annoying to have to type the unit name for debug-hooks, rather than just the service.  I don't care what unit, they're all the same, right?  And if there's just one (which is most of the time when you're debugging), me telling you which unit is spurious anyway... just go to the only one that exists.  Also, juju debug-hooks says you're supposed to give it the hook name, but it doesn't seem like that actually does anything.  I can leave it off and it seems to have the exact same behavior.  <br>
</div></div><div><br></div><div><div>Juju debug-hooks is really confusing:</div></div><div><br></div><div>When my install hook was broken, and I did juju debug-hooks <unit> install ....it brings me into a remote terminal prompt with zero information, no files in the local directory, and nothing else to tell me what to do.   I went back to look at the docs and it said I had to run juju resolved --retry <hook>.  So I exited out of the prompt back to my local machine, ran juju resolved --retry install and then ran juju debug-hooks <unit> install again and... same stupid thing.  What the docs didn't make clear is that I had to leave the debug session open, and then in a different terminal on my local machine run juju resolved --retry install, and then... boom, hey, look, useful information in my debug-hooks session.  It would have been nice if something useful had been printed out there in the first place.<br>
</div>
<div><br></div><div>Ideally, if there's only one broken hook on one broken service, all I should need to do is type "juju debug-hooks" and have it do the right thing (which would be the equivalent of the current juju debug-hooks <unit-name> <hook> and then in another terminal juju resolved <hook> --retry).<br>
</div><div><br></div><div>The text that gets printed out when a hook starts debugging is confusing:</div><div><br></div><div>"You need to execute hooks manually if you want them to run for trapped events."</div>
<div>What does execute them manually mean?  (I presume it means "run the script/executable from the command prompt".... but that could be worded better.  </div>
<div>What the heck is a trapped event?  I presume it means "a hook that was told to fire, but is instead triggering your debugging session".  Why call them events here and "hook firing" everywhere else?</div>

<div><br></div><div>Juju resolved is a bad name for a command... Resolved is an adjective, commands should be verbs that tell the computer what to do.  How about juju resolve install or at least juju set-resolved install.  Yes, I know some DVCS's use resolved as a command too - that doesn't make it a good idea.<br>
</div><div><br></div><div>....All that and I still haven't even gotten into relations at all.  Maybe that'll come in a later revision of the charm, and another long email ;)</div><div><br></div><div>-Nate</div><div>
<br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div></div></div></div>