New feature in Juju 2.8: Controllers can store charm state

As of Juju 2.8, controllers now have the ability to store state on a charm’s behalf via three new hook tools:

As with other hook tools, the state-* family uses a simple key/value API:

  • state-set <key> <value>:
  • state-get <key>: retrieve the value of <key>
  • state-delete: delete a key

Background

Charms are an implementation of the “Operator Pattern”. This means that Juju uses active software agents—visible as jujud processes—to execute charms. Charms, especially those written with the Operator Framework and the Reactive Framework, require the ability to record their current progress on disk.

Making changes to a machine’s local disk can cause problems over time, especially when applications are co-located.

This has inhibited k8s charms on Kubernetes clusters without storage volumes.

A “Stateless Application” is one that can operate without local persistent storage. They’re typically used in a microservices architecture and are excellent candidates for horizontal scaling.

Usage

This feature is available to charms, and is not directly usable by people deploying charms.

To ensure that charms are deployed to models which support this feature, add a requirement within the charm’s metadata.yaml file:

min-juju-version: 2.8

For charms that also wish to be able to be deployed with pre-2.8 models, then they should emulate the behaviour by writing to the charm directory. The StoredState class within the operator framework demonstrates leveraging SQLite for this.

2 Likes

Are there any plans to make this feature available over the API? I can see a ton of great use cases where the Juju Dashboard could benefit from having data set on a controller from charms in a model.

I’m not sure about the API integration, charm state is intended for unit<->controller rather than client<->controller… but you can probably experiment with those use cases using the tools that you have now.

If you can shell out, then you can access charm state:

$ juju exec --application mysql 'state-set mood=ok'
- return-code: 0
  unit: mysql/1
- return-code: 0
  unit: mysql/2
- return-code: 0
  unit: mysql/0

$ juju exec --application mysql 'state-get mood'
- return-code: 0
  stdout: |
    ok
  unit: mysql/1
- return-code: 0
  stdout: |
    ok
  unit: mysql/2
- return-code: 0
  stdout: |
    ok
  unit: mysql/0

State for the user/dashboard is an interesting idea, and the current thinking is to reflect that as what we used to call ‘output variables’. It’s a future cycle thing.

2 Likes