Use case for: min-version

Stuart Bishop stuart.bishop at canonical.com
Wed Aug 12 08:55:53 UTC 2015


On 12 August 2015 at 05:02, Jeff Pihach <jeff.pihach at canonical.com> wrote:
> Version checking for features can be dangerous because a commands output or
> availability may change in the future and now your charm also needs a
> "max-version", or "version-range" etc. A more robust solution could be
> something along the lines of a "feature-supported" query which would return
> whether that command is indeed supported in the active environment with the
> necessary syntax.

max-version should be very rare. To need it, you need to have both a
backwards incompatible change in Juju and a charm supporting such a
wide range of Juju versions that you need the multiple codepaths.
Still, I imagine it will happen and hookenv.juju_has_version easily
updated to support a range.

If you want your feature-supported API, now the version number is
exposed in charm-helpers you can easily add such a matrix of feature
flags. It just needs someone interested enough to maintain the list as
it grows and grows over time. I personally think it is impractical,
for exactly the problems you describe. A flag like 'leadership' isn't
very useful. I'm interested in leadership as it behaves in 1.23, or
leadership as implemented in 1.25 with the leader-deposed hook, or
leadership as implemented in 1.24.4 with the HA stability fixes, or
storage as of 1.25 when I can upgrade a service previously using the
block storage broker, or status as of 1.28 when we added more failure
states, or relation-set as of 1.23.3 when the --file argument was
fixed to accept input from stdin. Or most practically, I'm interested
in Juju 1.24 stable because I know I'm using features that did not
exist in 1.23 stable and that is the version I'm running tests with.

And now I think of it, it also makes testing easier (and thus
hopefully improves quality). If you are testing code guarded by both
the leadership and status feature flags, you have 4 code paths to
test. If you are testing code guarded by has_version_1.24, you only
have 2 code paths to test. And you would save time and effort, since
we all know that all versions of Juju implementing unit status also
implement basic leadership. Juju is developed and releases features on
a single trunk, where as for cross browser compatibility you are
supporting a matrix of features enabled or not on dozens of different
branches (one for each browser).

pw = host.genpw()
if feature('leadership'):
    leader_set(dict(password=pw))
else:
    relation_set(password=pw, relid=hookenv.get_peer_relid())
status_set('blocked', 'Connect to {} using password {} to complete
setup'.format(url, pw))
if feature('status'):
    raise SystemExit(0)
else:
    raise SystemExit(1)


I think it is best to add the feature flags you want in your own
charm, using the version number exposed by charm-helpers, rather than
coarse feature flags exposed by charm-helpers or juju that don't
necessarily align with your charm's actual requirements.

As for graceful fallback, its great when you can do it. Both Marco and
I use the same example - status_set. Under 1.23 or earlier, it uses
juju-log. Under 1.24 or higher, it uses status-set. However, if you
look at my original sample code you see that it isn't enough because
you still need to decide what to do next based on the behaviour that
was hidden from you. The graceful fallback practically requires you to
sniff the version if you want to block your units properly.

def block_and_exit(msg):
    hookenv.status_set('blocked', msg)
    if hookenv.has_juju_version('1.24'):
        raise SystemExit(0)  # blocked state for modern juju
    raise SystemExit(1) # error state for older juju

-- 
Stuart Bishop <stuart.bishop at canonical.com>



More information about the Juju-dev mailing list