--- name: jhack description: Expert assistant for Juju charm development using jhack utilities. Use when debugging charms, inspecting relations, syncing code, replaying events, testing scenarios, or performing rapid development iterations. Keywords include jhack, Juju debugging, charm testing, relation inspection, event replay, sync, tail, fire, show-relation, show-stored. license: Apache-2.0 compatibility: Requires jhack and juju installed locally. Network access needed for model operations. allowed-tools: Bash(jhack:*) Bash(juju:*) Read --- # Jhack Development Assistant Expert guidance for using jhack utilities to streamline Juju charm development, debugging, and testing. ## What is Jhack? Jhack is a collection of developer utilities that make charm development faster and easier by: - Providing shortcuts for common operations - Enabling rapid code iteration without redeployment - Visualising charm state and relations - Capturing and replaying real events - Simplifying debugging workflows ## Core Workflows ### Inspecting Charm State ```bash # View relation databags jhack show-relation myapp postgresql jhack show-relation myapp:database postgresql:database # Specific endpoints # View charm stored state jhack show-stored myapp/0 jhack show-stored myapp/leader # Leader unit # List integration endpoints jhack list-endpoints myapp # Get charm version info jhack charm-info myapp/0 ``` **`show-relation`** displays what data charms are sharing in a relation as a formatted table, making debugging integration issues much easier. **`show-stored`** shows the persistent state stored by the charm (via `StoredState` in Ops framework). ### Live Development with Sync ```bash # Sync local source to running unit (watch mode) jhack sync src/ myapp/0 # Sync specific directories jhack sync --src=./src --src=./lib myapp/0 # One-time sync (no watching) jhack sync --no-watch src/ myapp/0 ``` **Use case:** Edit code locally, jhack automatically pushes changes to the running unit. Combined with `jhack utils fire`, you can test changes in seconds without repacking and redeploying. **For packed charm sync:** Use `jhack charm sync-packed` ### Monitoring Events ```bash # Watch all events in real-time jhack tail # Watch specific unit jhack tail myapp/0 # Watch with debug output jhack tail -d myapp/0 # Filter by event type jhack tail --filter=config-changed ``` **`tail`** provides a colour-coded, hierarchical view of charm events as they fire, showing: - Event names - Handler execution - Nested events (e.g., relation-changed triggering config-changed) - Timing information ### Firing Events Manually ```bash # Fire a specific event jhack utils fire myapp/0 config-changed jhack utils fire myapp/0 database-relation-changed # Fire with specific relation jhack fire myapp/0 upgrade-charm # Speed up update-status for testing jhack ffwd myapp --interval=10s # Every 10 seconds jhack ffwd myapp --stop # Reset to normal ``` **Use case:** Test specific event handlers without waiting for natural triggers or performing manual operations. ### Event Replay (Advanced) ```bash # Install recorder on unit jhack replay install myapp/0 # List captured events jhack replay list myapp/0 # Replay a specific event jhack replay emit myapp/0 5 # Replay event #5 # Dump event data jhack replay dump myapp/0 5 # Purge recorded events jhack replay purge myapp/0 ``` **Use case:** Capture real production events (with all their context and data) and replay them for debugging or testing. ### Scenario Testing ```bash # Capture current state as scenario jhack scenario snapshot myapp/0 > state.json # Apply a state to a unit jhack scenario state-apply myapp/0 state.json ``` **Integration with ops-scenario:** Use `snapshot` to capture real charm state, then use it in unit tests with the Ops state-transition (unit) testing framework. ### Charm Manipulation ```bash # Update packed charm with local files jhack charm update myapp.charm src/ # Sync packed charm continuously jhack charm sync-packed --src=./src --charm=myapp.charm # Lobotomize charm (prevent event processing) jhack charm lobotomy myapp/0 # Enable jhack charm lobotomy myapp/0 --undo # Disable # Force unit to become leader jhack utils elect myapp/1 # Make unit 1 the leader ``` **`lobotomy`** is useful for freezing a charm's behavior during debugging - it prevents the charm from processing any events. ### Pebble Commands (K8s Charms) ```bash # Run pebble commands on remote units jhack pebble -c mycontainer myapp/0 plan jhack pebble -c mycontainer myapp/0 services jhack pebble -c mycontainer myapp/0 logs myservice jhack pebble -c mycontainer myapp/0 exec "ls -la /" ``` **Shortcut for:** `juju ssh --container=mycontainer myapp/0 -- pebble ` ### Debugging and Logs ```bash # Unified log view (charm + containers) jhack debug-log myapp/0 # Execute Python in charm context jhack script myapp/0 myscript.py # Evaluate expression jhack eval myapp/0 "self.unit.status" ``` **`script`** and **`eval`** let you run arbitrary Python code in the context of a live charm, with access to the charm instance. ### Destructive Operations ```bash # Safe removal with pattern matching jhack nuke myapp # Remove application jhack nuke "test-*" # Remove all apps matching pattern jhack nuke --model=mymodel --all # Nuke entire model # Kill stuck hook execution jhack kill myapp/0 # Auto-resolve all error states (use carefully!) jhack utils this-is-fine ``` **Safety:** All destructive commands require confirmation unless you enable devmode: `jhack conf set devmode=true` ### Chaos Testing ```bash # Stress test charm through rapid changes jhack chaos mancioppi myapp --duration=300 # 5 minutes jhack chaos flicker myapp # Rapid scaling up/down ``` **Use case:** Identify race conditions and state management issues by rapidly scaling, relating, and modifying charms. ## Common Workflows ### Rapid Development Iteration 1. Deploy charm: `juju deploy ./myapp.charm` 2. Start sync: `jhack sync src/ myapp/0` 3. Edit code locally 4. Fire event to test: `jhack utils fire myapp/0 config-changed` 5. Watch events: `jhack tail myapp/0 -d` 6. Inspect state: `jhack show-stored myapp/0` **Result:** Test changes in seconds instead of minutes. ### Debugging Integration Issues 1. Check relation data: `jhack show-relation myapp postgresql` 2. Fire relation event: `jhack utils fire myapp/0 database-relation-changed` 3. Watch handler execution: `jhack tail myapp/0 -d` 4. Inspect stored state: `jhack show-stored myapp/0` ### Capturing Production Issues 1. Install recorder: `jhack replay install myapp/0` 2. Wait for issue to occur 3. List events: `jhack replay list myapp/0` 4. Dump problematic event: `jhack replay dump myapp/0 ` 5. Replay locally: `jhack replay emit myapp/0 ` ### Testing Leadership Changes 1. Check current leader: `juju status` 2. Force different unit to lead: `jhack utils elect myapp/1` 3. Test leader-specific behavior 4. Watch events: `jhack tail myapp` ## Command Quick Reference ```bash # Inspection jhack show-relation # View relation data jhack show-stored # View stored state jhack tail [unit] # Watch events jhack charm-info # Charm version info # Development jhack sync # Sync code to unit jhack utils fire # Fire event manually jhack ffwd --interval=10s # Speed up update-status # Replay jhack replay install # Install recorder jhack replay list # List events jhack replay emit # Replay event # Scenario jhack scenario snapshot # Capture state jhack scenario state-apply # Apply state # Pebble (K8s) jhack pebble -c # Debugging jhack debug-log # Unified logs jhack eval # Evaluate in charm context jhack script