ワンクリックで
adding-actions
Implementing Juju actions for operational tasks in charms
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Implementing Juju actions for operational tasks in charms
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Known-good Juju bundle shapes (COS Lite, 12-Factor + COS, Identity Platform, Charmed Kubeflow) — canonical app lists and relation edges
Implementing Juju actions for operational tasks in charms. WHEN: add Juju actions to a charm, implement backup / rotate-credentials / restore actions, declare actions in charmcraft.yaml, write action handlers, test actions with Scenario, run actions with juju run.
Adding and validating charm configuration options. WHEN: add charm configuration options, declare config in charmcraft.yaml, validate config values in config-changed, apply config to a Pebble layer, apply config to a machine charm, write Scenario tests for config.
End-to-end workflow for building ops-framework charms for custom applications (K8s and machine). WHEN: build a custom Juju charm, write src/charm.py with Pebble, write a machine charm with systemd, decide K8s vs machine substrate, scaffold a non-paas-charm with charmcraft init, customise the ops framework charm lifecycle.
Workflow for charming infrastructure software (databases, caches, message brokers, proxies, monitoring). WHEN: charm infrastructure software, charm a database / cache / message broker / proxy / monitoring system, implement peer relations, leader election, primary/replica failover, backup and restore actions, clustering.
Expert guidance for developing, building, testing, and publishing Juju charms using charmcraft. WHEN: edit charmcraft.yaml, run charmcraft pack, run charmcraft init, manage charm libraries, publish a charm to Charmhub, set up multi-base builds, configure relations / config options, set up storage or containers.
| name | adding-actions |
| description | Implementing Juju actions for operational tasks in charms |
| globs | ["actions.yaml","charmcraft.yaml","metadata.yaml","src/charm.py","src/**/charm.py"] |
Juju actions are operator-triggered tasks — think "backup the database", "rotate credentials", or "dump debug info". They run on demand and return structured results.
juju run <unit> <action>Create or edit charmcraft.yaml to declare actions:
actions:
backup:
description: Create a backup of the application data.
params:
path:
type: string
description: Destination path for the backup file.
default: /var/backups
required: [path]
rotate-credentials:
description: Rotate database credentials and update all connected applications.
get-admin-password:
description: Retrieve the current admin password.
Juju action parameters use JSON Schema types:
string — text valuesinteger — whole numbersnumber — floating-point numbersboolean — true/falsearray — lists (with items specifying element type)object — nested structuresimport ops
class MyCharm(ops.CharmBase):
def __init__(self, framework: ops.Framework):
super().__init__(framework)
self.framework.observe(self.on.backup_action, self._on_backup)
self.framework.observe(
self.on.rotate_credentials_action,
self._on_rotate_credentials,
)
self.framework.observe(
self.on.get_admin_password_action,
self._on_get_admin_password,
)
def _on_backup(self, event: ops.ActionEvent):
path = event.params["path"]
try:
backup_id = self._perform_backup(path)
event.set_results({
"backup-id": backup_id,
"path": path,
"status": "success",
})
except FileNotFoundError:
event.fail(f"Backup path does not exist: {path}")
def _on_rotate_credentials(self, event: ops.ActionEvent):
if not self.unit.is_leader():
event.fail("Credential rotation must run on the leader unit.")
return
new_password = self._rotate_db_password()
event.set_results({"status": "rotated"})
def _on_get_admin_password(self, event: ops.ActionEvent):
password = self._get_stored_password()
event.set_results({"password": password})
For actions that take time, use progress logging:
def _on_backup(self, event: ops.ActionEvent):
event.log("Starting backup...")
# Phase 1
self._dump_database(event.params["path"])
event.log("Database dumped, compressing...")
# Phase 2
archive = self._compress_backup(event.params["path"])
event.log("Backup complete.")
event.set_results({"archive": str(archive)})
# Run with default parameters.
juju run my-charm/0 backup
# Run with parameters.
juju run my-charm/0 backup path=/mnt/backups
# Run on the leader.
juju run my-charm/leader get-admin-password
from ops import testing
def test_backup_action():
ctx = testing.Context(MyCharm)
state = testing.State()
out = ctx.run(ctx.on.action("backup", params={"path": "/data"}), state)
assert out.action_results["status"] == "success"
assert "backup-id" in out.action_results
def test_backup_action_invalid_path():
ctx = testing.Context(MyCharm)
state = testing.State()
out = ctx.run(ctx.on.action("backup", params={"path": "/nonexistent"}), state)
assert out.action_failure # Action called event.fail()
Actions are for operator-initiated tasks. Do not use actions for things that should happen automatically (use events/hooks for those).
Return structured results. Use event.set_results() with clear key-value pairs. Callers parse these programmatically.
Fail explicitly. Call event.fail("reason") with a descriptive message when an action cannot complete. Do not silently succeed.
Leader-only actions. Some actions (like credential rotation) should only run on the leader. Check self.unit.is_leader() and fail with a clear message if not.
Use hyphens in action names (e.g., rotate-credentials). Juju converts hyphens to underscores for the Python event name (rotate_credentials_action).
Document parameters clearly in the charmcraft.yaml actions section. Operators rely on juju actions my-charm to understand what is available.
my-action → self.on.my_action_action) and the requirement that every handler call event.set_results() or event.fail() are checked deterministically by charmlint (rules ACT006 and ACT007). Run charmlint to surface these — the skill body no longer recites them.