Skip to content

feat(templates): add Workshop dev-environment scaffold to machine and kubernetes init profiles - #2

Draft
tonyandrewmeyer wants to merge 1 commit into
mainfrom
workshop-sdk-init-profiles
Draft

feat(templates): add Workshop dev-environment scaffold to machine and kubernetes init profiles#2
tonyandrewmeyer wants to merge 1 commit into
mainfrom
workshop-sdk-init-profiles

Conversation

@tonyandrewmeyer

Copy link
Copy Markdown
Owner

Summary

This is a DRAFT / exploratory change that adds a Canonical Workshop dev-environment scaffold to charmcraft's init templates for the machine and kubernetes profiles. After this change, charmcraft init --profile machine and charmcraft init --profile kubernetes each scaffold a charm project that ships a ready-to-use Workshop dev environment.

Each generated project gains:

  • A root workshop.yaml describing an ephemeral LXD dev environment (base: ubuntu@24.04) wiring up the system, uv, juju (3.6/stable) and charmcraft (latest/stable) Store SDKs plus the in-project project-dev SDK, with unit / pack / integration actions.
  • An in-project, hooks-only project SDK at .workshop/project-dev/sdk.yaml plus setup-base, setup-project and check-health hooks. The SDK is defined in place and has no build-time fields (no base/build-base/platforms/parts); it is configured entirely via the hooks.

How it works

  • The charm is packed inside the workshop with charmcraft pack --destructive-mode — there is no nested build VM. Because destructive-mode packs in the current environment, the workshop base is pinned to ubuntu@24.04 to match the charm template's build-on base.
  • Under --destructive-mode, charmcraft runs as the unprivileged workshop user and cannot apt/snap-install. So:
    • setup-base (runs as root at base-prep time) installs the common charm build tooling and yq.
    • setup-project (runs as root after the project is mounted) parses charmcraft.yaml and pre-installs the charm's declared parts.charm.build-packages (apt) and build-snaps (snap, e.g. astral-uv), then runs uv sync as the workshop user.
    • check-health verifies the workshop user can run charmcraft and import the charm's deps.

Deliberate design decisions / caveats

  • No tox SDK. There is intentionally no published tox SDK referenced anywhere — tox was only ever a local experiment. tox-style steps are run via uv run actions instead.
  • Substrate is external, not in-workshop. Bootstrapping a Juju controller (juju bootstrap localhost) inside an unprivileged workshop container fails today, and Canonical Kubernetes does not come up inside one either. So integration tests target a Juju controller running outside the workshop, reached via a system: SDK tunnel slot (juju-api, endpoint 17070).
  • The controller connection is a manual post-launch step. A system: SDK tunnel slot is not auto-connected, so it cannot go in connections:. The required workshop connect / workshop remount commands are documented in a comment in workshop.yaml instead.
  • kubernetes vs machine. The two profiles' scaffolds are intentionally near-identical. The only differences are wording: the kubernetes workshop.yaml notes that an in-workshop Canonical Kubernetes substrate SDK is the intended future shape but is currently blocked (needs a more-privileged container than Workshop provides), and that juju should point at an external k8s-backed controller.
  • Static SDK directory name. The in-project SDK lives at a static .workshop/project-dev/ path (no templating in paths); the charm name is substituted only inside file contents via the existing {{ name }} init variable.

Implementation notes

  • The three hooks are added to the executables list in charmcraft/application/commands/init.py so they are emitted with the executable bit set, matching how the existing template executables are handled.
  • The init overview docstring's file tree now mentions workshop.yaml and .workshop.

Verification done

  • Built a wheel and confirmed all 10 new template files (including the hidden .workshop/ directory) ship as package data, then installed the wheel into a clean venv and confirmed charmcraft init emits them with the charm name substituted, no leftover template syntax, and executable hooks.
  • ruff check, codespell, and shellcheck (run CI-style over the hook templates, which file detects as shell scripts) all pass.
  • Added a test_workshop_scaffold test and updated BASIC_INIT_FILES; the init test suite passes (pytest tests/integration/commands/test_init.py).

Test plan

  • charmcraft init --profile machine and --profile kubernetes in an empty dir emit workshop.yaml and .workshop/project-dev/...
  • (Future, once a substrate is available) workshop launch + workshop run dev pack + workshop run dev unit / integration against an external controller

https://claude.ai/code/session_013ZAmXXPxcfRBUdjK9thAKD


Generated by Claude Code

… kubernetes init profiles

Scaffold a Canonical Workshop dev environment into the `machine` and
`kubernetes` init profiles: a root `workshop.yaml` and an in-project,
hooks-only project SDK at `.workshop/project-dev/` (sdk.yaml plus
setup-base, setup-project and check-health hooks).

The charm packs inside the workshop via `charmcraft pack --destructive-mode`,
so the base is pinned to ubuntu@24.04 to match the charm's build base and the
setup-project hook pre-installs the charm's declared build-packages/build-snaps
(which the unprivileged workshop user cannot install at pack time). The juju SDK
targets an external controller via a `system:` tunnel slot, since bootstrapping
a controller / Canonical Kubernetes inside an unprivileged workshop container is
blocked today.

The init command marks the three hooks executable, and the init tests assert
the scaffold renders with the charm name, ships no leftover template syntax,
and emits executable hooks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant