Charm problems with bash hooks


#1

I’m working on a new beginner level tutorial series covering “hooks”.

Draft material is here:
https://github.com/erik78se/Tutorial-Build-a-quick-charm

When writing this tutorial I’ve made some assumptions:

  1. charm-tools is the way to enter charming
  2. Using “bash” to learn about hooks is the best start for a beginner with none or little python experience (trying to win-over traditional sysadmins to juju).
  3. Not mixing in anything about reactive concepts at all at this place since its the “hooks” that I want to have all focus on.

I’ll soon post in the Users category about this, but there are a number of things that makes the tutorials be very “buggy” which I think can be done better.

So, let me describe some context for the issues:

  • I’m using charm 2.5.2 to create a charm from template:
    charm create -t bash my-tweaks

The generated charm is populated with the following files & hooks:

├── config.yaml
├── hooks
│   ├── config-changed
│   ├── install
│   ├── relation-name-relation-broken
│   ├── relation-name-relation-changed
│   ├── relation-name-relation-departed
│   ├── relation-name-relation-joined
│   ├── start
│   ├── stop
│   └── upgrade-charm
├── icon.svg
├── metadata.yaml
├── README.ex
└── revision

Here we go:

Problem 1: I have to create an empty hook file called: “hook.template” for the charm to build which makes no sense what-so-ever. Its non trivial to figure out this workaround to create a trivial bash charm. https://github.com/juju/charm-tools/issues/98

Suggested fix: Make sure that no python or reactive pieces are needed to create “bash” charms. Anyone not familiar with advanced charming with reactive and python will give up at this stage.

Problem 2: A few hooks are not added to the hooks directory that causes error at various places in the event cycle and state transitions for juju.

The missing hooks I have found missing so far while performing “juju deploy”, “juju upgrade-charm” etc. are:

  • Missing “leader-elected” : fails “juju deploy”
  • Missing “leader-settings-changed” : fails “juju upgrade-charm”
  • Missing “update-status” : juju fails when charm is actually deployed

E.g. Using standard procedures for installing and upgrading a bash charm will fail and its non trivial to figure out why and how. This will make a beginner level charmer give up on juju. https://github.com/juju/charm-tools/issues/503

Suggested fix: Don’t allow a juju deploy to “fail”/“error” with charms not implementing each and every hook unless strictly needed to complete run of the state machine. Instead allow a deploy to move on alerting that there are missing hooks present. Be nice also to programmers that are not 1337.

Problem 3: The “install” hook is populated with code which always will fail. It contains “apt-get install charmname” which causes the charm to break per default. https://github.com/juju/charm-tools/issues/504

Suggested fix: Add content to the install script that actually make sense, such as "status-set active “Ready” or/and an url reference to the available hook-tools. https://docs.jujucharms.com/2.5/en/reference-hook-tools

Problem 4: When running “charm proof”, it complains about “layer.yaml” missing. Is this really needed for bash-charms? https://github.com/juju/charm-tools/issues/506

Suggested fix: Not sure why this is a warning for a bash charm.

Problem 5: This closed bug still prevails and causes confusion https://github.com/juju/charm-tools/issues/502

Problem 6: Its not good that the produced charms from “charm create” always produces non-usable metadata.yaml as I try to describe here: https://github.com/juju/charm-tools/issues/505

@pmatulis @rick_h


‘Reactive’ vs ‘Hooks’
[Tutorial] Charm development (Beginner, part 1)
#2

It’s been a while since I did a plain bash charm but I’m confused. If you go the bash/hook route then there’s no need to build. You just deploy the directory. I think that some of these issues is mixing the reactive steps, like build, with what turns into a non-reactive charm.

I’m confused. Juju will just gladly ignore, without error, any hooks that don’t exist. Do you have the example charm that errored in this way? When you say it errored, do you mean it logged an error or that the status output went into an error state?

Thanks for the feedback. We’ll definitely take a look. There’s a balance between having clear errors on the default content to help nudge a charmer to edit the right things for their charm in a step by step direction, but also sensible defaults that there’s room for improvement on.


#3

Thanx @rick_h I wonder if there is a better way to approach hooks. Is python better?


#4

I’m confused. Juju will just gladly ignore, without error, any hooks that don’t exist. Do you have the example charm that errored in this way? When you say it errored, do you mean it logged an error or that the status output went into an error state?

This was completely new to me. I tested the approach, which turned me towards a completely new and - alot simpler path! I will be able to produce a fundamentally more easier tutorial given this information.

Is the “charm build” step ONLY required when you do reactive charms?

Thanx @rick_h


#5

exactly, you can have a simple non-reactive charm where you just juju deploy from a directory and it’s zipped up and sent over. We use this “ubuntu-lite” charm a lot for testing things as it’s a lot faster without the python deps and such, for instance.

Note you can just

charm pull https://jujucharms.com/u/jameinel/ubuntu-lite/7 && juju deploy ./ubuntu-lite

And any edits you make you just upgrade-charm to get a new zip made and pushed up to the controller.


#6

Thanx @rick_h.

I tried exploring the “python path” and ended up in another issue =/

https://github.com/juju/charm-tools/issues/507


#7

Hmm, yea looks like the template is putting out a py2 env vs a py3. I think it should be fairly compatible but probably not as thoroughly tested. You could try updated the shebang on those to a py3 env and see what happens. Or you could make sure the install hook installs python 2 and update it’s shebang only so that it runs py3 to get going but then setups the environment so the rest of things can be py2 safely.


#8

Oh, I’m not sure how to do all this and this "charm create -t templating thing really needs some love since its really killing me every time.

The assumption I make, using this “charm create” as a good start for new charms is currently a minefield. When I write tutorials I’ve kind of relied on this mechanism to get consistent starting points…


#9

Oh, another discovery here…

I found that charmhelpers needs to be “separately” / “explicitly” installed via my python charm code.

The “charm create -t python my-python-charm” produces code which looks like this:

.
├── config.yaml
├── hooks
│   ├── install
│   ├── setup.py
│   ├── start
│   ├── stop
│   ├── update-status
│   ├── upgrade-charm
├── icon.svg
├── metadata.yaml
└── README

In the generated file: setup.py

There is code that looks like this:

def pre_install():
    """
    Do any setup required before the install hook.
    """
    install_charmhelpers()


def install_charmhelpers():
    """
    Install the charmhelpers library, if not present.
    """
    try:
        import charmhelpers  # noqa
    except ImportError:
        import subprocess
        subprocess.check_call(['apt-get', 'install', '-y', 'python-pip'])
        subprocess.check_call(['pip', 'install', 'charmhelpers'])

Is there no other less patchworked ways of creating skeleton python charms that also would work on other OS:es than Ubuntu (using apt) ?