Hi everybody,
There is an issue which I cannot figure out which is the best way to solve it. In fact I do not know if it’s an issue in my code (most likely), or it’s an issue/feature of juju/ops.
I am working on mysql-operator charm. The mysql image I’m using lets us configure the MYSQL_ROOT_PASSWORD
through environment variables, so if I run:
$ juju deploy -n 3 ./mysql.charm --config MYSQL_ROOT_PASSWORD=SecretPass --resource mysql-image=ubuntu/mysql:latest
I will have 3 units running MySQL with root user having the same password: SecretPass
. That’s make sense, and everything works.
In the charm code I have:
if config.get("MYSQL_ROOT_PASSWORD"):
self._stored.mysql_setup["MYSQL_ROOT_PASSWORD"] = config[
"MYSQL_ROOT_PASSWORD"
]
env_config["MYSQL_ROOT_PASSWORD"] = config["MYSQL_ROOT_PASSWORD"] # Password from env variable
else:
env_config["MYSQL_ROOT_PASSWORD"] = self.mysql_root_password # Randomly generated password
and build the pod_spec using the env_config
dictionary:
pod_spec = {
"version": 3,
"containers": [
{
"name": self.app.name,
"imageDetails": image_info,
"ports": [
{"containerPort": config["port"], "protocol": "TCP"}
],
"envConfig": self.env_config,
...
But if I do not send the MYSQL_ROOT_PASSWORD
and run:
$ juju deploy -n 3 ./mysql.charm --resource mysql-image=ubuntu/mysql:latest
the charm code will generate a random password for root user:
password = "".join(
random.choice(ascii_letters + digits) for x in range(20)
)
self._stored.mysql_setup["MYSQL_ROOT_PASSWORD"] = password
and set it to the pod_spec
.
From what I understand, the first execution (leader unit) will generate a password, set it to the pod_spec
and use this specs to generate the 3 units even though this code is executed once per unit.
In each execution the generated password is stored in the StoredState
object so we can use it later in the readinessProbe and livenessProbe:
"readinessProbe": {
"exec": {
"command": [
"mysqladmin",
"ping",
"-u",
"root",
"-p{}".format(self.mysql_root_password),
]
},
"initialDelaySeconds": 20,
"periodSeconds": 5,
},
But these probes only works ok in the leader unit which stores the password that was used to build the pod_spec for the 3 units. AFAIK the Storedstate
object stores data the charm needs persisted across invocations of the same unit.
So at this point I have these doubts to tackle the solution:
- Is there a way to store data across invocations of different units? (so we can generate the password in the leader unit, and get it from the other units)
- Is there a way to build the units using slightly different pod_specs? (so we can have different password for each unit)
- May be the solution will be making the
--config MYSQL_ROOT_PASSWORD=SecretPass
parameter mandatory during the deployment…
Thanks!
Jose