Skip to main content

borescope

A natural shell for debugging Juju Kubernetes workload containers.

Kubernetes charm workload containers usually run a rock with no shell — so when something breaks, juju ssh --container=workload … drops you nowhere useful. borescope gives you a prompt that feels like bash but talks to the container's Pebble instead of a real shell:

$ borescope myapp/0
pebble:/# ls /var/log/myapp
pebble:/# tail -f /var/log/myapp/error.log
pebble:/# ps -ef
pebble:/# services
pebble:/# logs --follow myapp
pebble:/# plan
pebble:/# exit

No setup ceremony: borescope picks up your current Juju controller/model and uses your existing juju authority — if you can juju ssh to the unit, borescope works; if you can't, it fails the same way.

Install

From the snap store:

sudo snap install borescope
sudo snap connect borescope:juju-client-observe
sudo snap connect borescope:ssh-keys

The two snap connect calls are required today and will go away once the snap store grants the auto-connect declarations (#31). Without them, borescope can't read your ~/.local/share/juju to find your controller, and juju ssh can't see your SSH keys.

A few things to know about the snap:

  • It bundles its own juju (currently juju/4/stable), so it works even without juju installed on the host.
  • It reads your ~/.local/share/juju (JUJU_DATA) read-only via the juju-client-observe interface, then copies it into a writable per-snap directory at startup. Run juju login / juju switch outside borescope — changes made inside a borescope session don't propagate back to the host JUJU_DATA.

Or from PyPI:

uv tool install borescope    # or: uvx borescope, pipx install borescope

Usage

borescope <unit>                       # default (first) workload container
borescope <unit> --container=<name>    # a specific workload container
borescope --model <model> <unit>
borescope <unit> --command "services"  # one-shot, no REPL (for scripts)
borescope <unit> --snapshot            # dump container state as JSON

Documentation

Full documentation — a tutorial, how-to guides, and CLI/command reference — is at https://tonyandrewmeyer.github.io/borescope/.

The docs are plain Markdown under docs/src/, built into static HTML with a small script (no docs framework). To build them locally:

uv run python docs/src/_build.py     # or: tox -e docs

See docs/README.md for the authoring rules.

How it works

borescope is three thin, independently-testable layers:

  • Transport — talks to a Pebble. The primary backend (CliTransport) reaches the workload's Pebble through the charm container — juju ssh <unit> (the charm container always has a shell) pointed at the workload's socket, which Juju mounts there at /charm/containers/<name>/pebble.socket. This works even against rocks with no shell (the shell lives in the charm container, not the rock) and stays entirely within your Juju authority — no kubectl or cluster-admin. It drives pebble via shimmer (a drop-in ops.pebble.Client over the Pebble CLI). When the Pebble socket is directly reachable (running inside the charm, or a local Pebble), SocketTransport uses the real ops.pebble.Client HTTP API instead.
  • Discovery — turns a unit reference into the right Pebble: confirms the unit, reads the charm's metadata.yaml for workload container names, and sanity-checks the container is alive. Everything uses your Juju model access — no kubectl / cluster-admin.
  • Shell — a small REPL: cd/pwd, path-aware tab completion, history, and a minimal command set. Pebble's own vocabulary (services, logs, plan, …) is first-class, not hidden behind a pebble prefix. For anything else, exec <cmd> runs a binary that's already in the container.

Scope

borescope is for Kubernetes charms (which run Pebble). Machine charms already have a real shell and are out of scope. It deliberately ships a minimal command set and grows on request — if a tool exists in the container, reach it with exec.

Metadata

Release files for borescope 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for borescope 1.1.0
File Size Uploaded
borescope-1.1.0.tar.gz 95.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for borescope 1.1.0
File Interpreter ABI Platform
borescope-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 160.4 kB

Release files / borescope-1.1.0.tar.gz

Download URL borescope-1.1.0.tar.gz
Size 95.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d9c41007c6089a63fb7ea87dca58dffc7a3a7a3da3757ce29c4478dc3c385190
BLAKE2b-256 checksum
How to use checksums
23ead4affba083ee0ca60e0ec79e7ecc12c321b909512a1486c7e283125cf548
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

Release files / borescope-1.1.0-py3-none-any.whl

Download URL borescope-1.1.0-py3-none-any.whl
Size 64.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
00063fea66a90109a5405ddf13f766add150cdfdadc4eb2518e8c2ad50b9b232
BLAKE2b-256 checksum
How to use checksums
7a349c8d9ceceff1a12d0951a328696370a079807d041b2169f40a2cbf686f4d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page