Use python for the core snap configure hook

Background

The recent addition of the pi-config to the core snap showed that shell is not the ideal language for a more complex configuration. For complexer scripts it is hard to read, hard to test and needs tools like sed/awk which have their own challenges.

Proposal

Rewrite the configure hook in python - there is https://github.com/snapcore/core/pull/24 for this.

Open question

Ogra raised the concern that python is too slow in the PR (https://github.com/snapcore/core/pull/24#issuecomment-291883421). We could use go instead, this would require:

  • redo the python rewrite work (one-off only)
  • build the configure binary on a per-arch basis from source (also one-off)

Alternatively we could just go with the pyhton version and if it turns out its too slow (or the hooks grows massively) we do the porting work then.

Data:

On the pi2:

hello python

real	0m1.205s
user	0m0.092s
sys	0m1.008s
hello python

real	0m0.092s
user	0m0.068s
sys	0m0.020s
hello sh
real	0m0.133s
user	0m0.000s
sys	0m0.108s
hello sh
real	0m0.006s
user	0m0.004s
sys	0m0.004s

So python is ~10x slower than shell. On a (very) cold cache python takes ~1s to start and 10x faster on a hot cache.

right, i’m not so much in the “keep shell at any price” camp here (even though i personally would prefer that) than i am in the “dont use python on embedded low end HW if you can avoid it” camp.

technically any other language would do …

given that we do all our other work in go, and that we switched to it for snapd due to performance issues with python on exactly such HW, it might be the natural choice here.

1 Like

Without getting into why there is gadget specific code in the core snap’s configure hook let me just say that some numbers to evaluate the impact would speak lengths here (the shell vs python).

The added benefit of moving away from shell is that there is some unit testing going on.

1 Like

as i said, i’m not opposed to move away from shell …

but did anyone even test the new configure hook (which iterates over a gazillion of gadget options for only one board we are likely not even running on) on something like a beaglebone ? snap set/get are already processing quite slow even on a multicore pi3

we have a ton of bugs open to add config options to core, all of them will be processed on each call of the config hook regardless (due to the current design of snapctl)… it will quickly grow.

1 Like

FWIW the shell is out of the question; we tried writing this in shell and making it do what we need was deemed too brittle/hard/impossible. The question is not whether shell is ok; the question is what to use instead.

2 Likes

My gut feeling is that Go is the right answer here, not because of timing (1s only on updates isn’t much), but because we have good processes and practices around it already, and it’s also slightly safer to use it in this context (no runtime dependencies, etc).

Also, this would mean reusing code between snapd and the hook, which we know is useful. Just a few days ago we were discussing how to validate the scheduling option. It would be trivial to do without duplication if we had it in Go.

In terms of how to do that, I suggest shipping the hook with snapd proper, perhaps as an implementation detail of snapctl. So the hook becomes just a shell script that calls that one command, and then there’s really nothing else to worry about in terms of when to update, how to build and bundle the hook for the proper architecture, etc.

How does that sound?

3 Likes