The short answer is jhack show-stored yourapp/0
. The long answer follows.
Background
A unit’s local stored state is backed by a SQLite3 file located at /var/lib/juju/agents/unit-yourapp-0/charm/.unit-state.db
.
After operator/1057 you need sudo
to view it. For example:
sudo sqlite3 /var/lib/juju/agents/unit-cos-proxy-0/charm/.unit-state.db .schema
CREATE TABLE snapshot (handle TEXT PRIMARY KEY, data BLOB);
CREATE TABLE notice (
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
event_path TEXT,
observer_path TEXT,
method_name TEXT);
CREATE TABLE sqlite_sequence(name,seq);
One-liners
ops
creates a table per Object
, so we can find all the interesting names with .dump
and convert it into a yaml:
sudo sqlite3 /var/lib/juju/agents/unit-cos-proxy-0/charm/.unit-state.db .dump \
| grep "INSERT INTO snapshot VALUES" \
| awk -F"[']" '{print "\""$2"\""":", "\""$4"\""}' \
| yq
But that would give you pickled-hexlified data, such as:
"COSProxyCharm/StoredStateData[_stored]": "80049576000000000000007d94288c0c686176655f67726166616e6194898c0f686176655f64617368626f6172647394898c0f686176655f70726f6d65746865757394888c0c686176655f7461726765747394898c09686176655f6e72706594888c09686176655f6c6f6b6994898c0d686176655f66696c65626561749489752e"
"StoredStateData[_stored]": "80049515000000000000007d948c0b6576656e745f636f756e74944d4e01732e"
We can unhexlify and unpickle with a short python script:
sudo sqlite3 /var/lib/juju/agents/unit-cos-proxy-0/charm/.unit-state.db .dump \
| grep "INSERT INTO snapshot VALUES" \
| awk -F"[']" '{print "\""$2"\""":", "\""$4"\""}' \
| python3 -c "import sys,yaml,pickle,binascii; stored=yaml.safe_load(sys.stdin.read()); print(yaml.safe_dump({k: pickle.loads(binascii.unhexlify(bytes(v, 'utf8'))) for k, v in stored.items()}))"
Which prints:
COSProxyCharm/StoredStateData[_stored]:
have_dashboards: false
have_filebeat: false
have_grafana: false
have_loki: false
have_nrpe: true
have_prometheus: true
have_targets: false
StoredStateData[_stored]:
event_count: 334
To do this outside of the vm/container, and without pre-installing sqlite3, you could use python all the way:
juju ssh cos-proxy/0 "sudo python3 -c \"import sqlite3,re,pickle,binascii,yaml; db=sqlite3.connect('/var/lib/juju/agents/unit-cos-proxy-0/charm/.unit-state.db', isolation_level=None); matches=filter(None,map(lambda l: re.match('INSERT.+VALUES.\'([^,]+)\',X\'([^\']+)\'',l), db.iterdump())); print(yaml.safe_dump({m.group(1): pickle.loads(binascii.unhexlify(bytes(m.group(2), 'utf8'))) for m in matches}))\""