Skip to content

feat: prebaked platform VM#2251

Merged
JanPokorny merged 5 commits intomainfrom
janpokorny/feat-agentstack-cli-prebaked-platform-vm
Mar 6, 2026
Merged

feat: prebaked platform VM#2251
JanPokorny merged 5 commits intomainfrom
janpokorny/feat-agentstack-cli-prebaked-platform-vm

Conversation

@JanPokorny
Copy link
Collaborator

@JanPokorny JanPokorny commented Feb 27, 2026

Summary

  • Switch from Ubuntu (commercial, by Canonical) to Debian (non-commercial)
  • Pre-bake Microshift, kubectl, Helm, crictl etc. into the base VM image (reduces first-time install times and CI times)
  • Cache VM by source content hash (skips rebuilding locally and in CI)
  • Reduce VM download size by stripping the image down to bare minimum
  • On WSL, use a custom distribution based on the VM image, configured to no longer appear in Start menu and Windows Terminal
  • Merge CI tasks under a single workflow to better manage task dependencies and save processing time

Documentation

  • No Docs Needed:

If this PR adds new feature or changes existing. Make sure documentation is adjusted accordingly. If the docs is not needed, please explain why.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant enhancement to the Agent Stack platform by enabling the use of prebaked VM images for both Lima and WSL environments. This change aims to drastically reduce the initial setup and startup time of the platform by providing images with Microshift, Helm, and other essential components already installed. The agentstack-cli has been updated to leverage these new images, offering options for specifying custom image paths. A new dedicated project has been added to manage the building process of these prebaked VM images.

Highlights

  • Prebaked VM Images Introduced: This pull request introduces the concept of prebaked VM images for Lima (macOS/Linux) and WSL (Windows), aiming to significantly reduce platform startup times by pre-installing essential components like Microshift and Helm.
  • CLI Integration for Custom Images: The agentstack-cli has been updated to support specifying custom prebaked Lima (--lima-image) and WSL (--wsl-image) images via command-line arguments or environment variables, allowing users to leverage their own optimized images.
  • VM Provisioning Logic Refactored: The internal VM provisioning logic in platform.py was refactored to remove the sync_vm_files function and adapt to the use of prebaked images, including new logic for importing WSL images and detecting existing Kubernetes platforms.
  • New Image Building Project: A new project, apps/agentstack-platform-vm, has been added to the repository. This project contains the necessary scripts and configuration to build the prebaked Lima (.qcow2) and WSL (.tar.gz) VM images.
  • Dependency Updates: Several Python dependencies in uv.lock have been updated to their latest versions, including certifi, faker, fastapi, openai, opentelemetry-instrumentation-openai, and pyrefly.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • apps/agentstack-cli/src/agentstack_cli/commands/platform.py
    • Removed the sync_vm_files function.
    • Added lima_image and wsl_image options to the start_cmd function.
    • Modified VM provisioning logic to use specified Lima/WSL images or default cloud images, and to import WSL images if provided.
    • Updated Kubernetes platform detection and initialization to expect a prebaked image.
    • Removed dynamic Helm installation, assuming it is pre-installed.
  • apps/agentstack-cli/uv.lock
    • Updated certifi from 2026.1.4 to 2026.2.25.
    • Updated faker from 40.4.0 to 40.5.1.
    • Updated fastapi from 0.131.0 to 0.133.1.
    • Updated openai from 2.21.0 to 2.24.0.
    • Updated opentelemetry-instrumentation-openai from 0.52.4 to 0.52.5.
    • Updated pyrefly from 0.53.0 to 0.54.0.
  • apps/agentstack-platform-vm/README.md
    • Added a new README file describing the Agent Stack Platform VM Image Builder project.
  • apps/agentstack-platform-vm/build.sh
    • Added a new shell script to build prebaked Lima (.qcow2) and WSL (.tar.gz) VM images.
  • apps/agentstack-platform-vm/common/etc/apt/sources.list.d/cri-o.list
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/common/etc/apt/sources.list.d/cri-o.list.
  • apps/agentstack-platform-vm/common/etc/apt/sources.list.d/kubernetes.list
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/common/etc/apt/sources.list.d/kubernetes.list.
  • apps/agentstack-platform-vm/common/etc/containers/registries.conf.d/200-microshift-local.conf
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/common/etc/containers/registries.conf.d/200-microshift-local.conf.
  • apps/agentstack-platform-vm/common/etc/crio/crio.conf.d/14-microshift-cni.conf
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/common/etc/crio/crio.conf.d/14-microshift-cni.conf.
  • apps/agentstack-platform-vm/common/etc/microshift/config.yaml
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/common/etc/microshift/config.yaml.
  • apps/agentstack-platform-vm/common/etc/resolv.conf-override
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/wsl/etc/resolv.conf-override.
  • apps/agentstack-platform-vm/common/etc/systemd/system/kubectl-port-forward@.service
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/common/etc/systemd/system/kubectl-port-forward@.service.
  • apps/agentstack-platform-vm/common/etc/wsl.conf
    • Renamed from apps/agentstack-cli/src/agentstack_cli/data/vm/wsl/etc/wsl.conf.
  • apps/agentstack-platform-vm/provision.sh
    • Added a new shell script for provisioning the VM with MicroShift, Helm, and pre-pulling container images.
  • apps/agentstack-platform-vm/tasks.toml
    • Added a new tasks.toml file defining the agentstack-platform-vm:build task.
  • mise.toml
    • Included the new apps/agentstack-platform-vm/tasks.toml in the project configuration.
  • tasks.toml
    • Added agentstack-platform-vm:build as a dependency.
    • Modified the platform start command to pass IMAGE_ARGS for Lima/WSL images.
Activity
  • The pull request is currently marked as a work in progress (wip).
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant improvement by adding support for pre-baked platform VM images, aiming to drastically reduce startup times through a new build process and updates to the platform start command. However, it also introduces several critical security vulnerabilities in the platform.py command, including a command injection vulnerability when importing images, multiple path traversal vulnerabilities via the vm_name parameter that could allow overwriting arbitrary files on the host, and the hardcoding of several default credentials and an encryption key. Additionally, there are functional issues such as a potential bug in platform.py where the service enabling logic for k3s incorrectly assumes crio is present, an inconsistency in provision.sh with a hardcoded Helm version instead of using the variable defined in build.sh, and a fragile architecture detection mechanism in tasks.toml. Addressing these security and functional concerns is crucial before merging.

@JanPokorny JanPokorny force-pushed the janpokorny/feat-agentstack-cli-prebaked-platform-vm branch 3 times, most recently from 4dda19f to a759978 Compare March 4, 2026 07:48
@i-am-bee i-am-bee deleted a comment from claude bot Mar 4, 2026
@JanPokorny JanPokorny force-pushed the janpokorny/feat-agentstack-cli-prebaked-platform-vm branch 2 times, most recently from 98b2961 to c509961 Compare March 5, 2026 13:05
Signed-off-by: Jan Pokorný <JenomPokorny@gmail.com>
Signed-off-by: Jan Pokorný <JenomPokorny@gmail.com>
@JanPokorny JanPokorny force-pushed the janpokorny/feat-agentstack-cli-prebaked-platform-vm branch from 03a3b93 to 8ce7284 Compare March 6, 2026 11:46
Signed-off-by: Jan Pokorný <JenomPokorny@gmail.com>
@JanPokorny JanPokorny changed the title wip: prebaked platform VM feat: prebaked platform VM Mar 6, 2026
@JanPokorny JanPokorny marked this pull request as ready for review March 6, 2026 11:48
@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Mar 6, 2026
@JanPokorny JanPokorny requested a review from jezekra1 March 6, 2026 11:59
@JanPokorny
Copy link
Collaborator Author

/gemini review

@JanPokorny
Copy link
Collaborator Author

@claude review

@claude
Copy link

claude bot commented Mar 6, 2026

Claude finished @JanPokorny's task in 3m 2s —— View job


Code Review

  • Gather context
  • Read changed files
  • Analyze issues
  • Post review feedback

Good overall approach — prebaking the VM image is a meaningful improvement to setup times. The refactoring of CI into a single workflow is also cleaner. Here are the findings, roughly ordered by severity.


Bug: WSL image filename mismatch

apps/microshift-vm/tasks.toml line 89 produces:

./dist/x86_64/microshift-vm-x86_64.wsl

But release.yml line 109 expects:

apps/microshift-vm/dist/x86_64/microshift-vm-x86_64.tar.gz

And platform.py line 398 also expects .tar.gz:

f"https://github.com/i-am-bee/agentstack/releases/download/v{version}/microshift-vm-{arch}.tar.gz"

The release workflow would fail to find the file to upload, and users downloading the default URL would get a 404. The build task just needs to output .tar.gz. Fix this →


Bug: Platform detection failure mode

platform.py lines 429–443 — if neither k3s nor microshift is found in the VM, stdout is empty and .splitlines()[0] raises IndexError. The VM image currently only has MicroShift, but this will surface as a cryptic stack trace if someone passes a custom image that has neither.

.stdout.decode()
.strip()
.splitlines()[0]  # IndexError if empty

Security: No checksum verification on base image download

microshift.pkr.hcl line 49:

iso_checksum = "none"

Skipping checksum verification on the Debian cloud image means a MITM or CDN compromise could silently inject a malicious base image into all locally built VMs and release artifacts. The Debian project publishes SHA256 checksums alongside their images — worth pinning. Fix this →


CI: 10-minute timeout for QEMU VM build is likely insufficient

ci.yml line 63:

timeout-minutes: 10

Building a full VM image with Packer in 10 minutes requires KVM acceleration. GitHub-hosted ubuntu-latest runners sometimes have KVM but it's not guaranteed (nested virt support varies). Without KVM, the task will fall back to tcg (software emulation), which will take 30–90+ minutes. Suggest increasing the timeout or making the job explicitly fail if KVM isn't available.


Architecture: WSL build is x86_64-only

tasks.toml lines 79, 89 hardcode x86_64 paths:

guestmount -a "./dist/x86_64/microshift-vm-x86_64.qcow2" ...
>./dist/x86_64/microshift-vm-x86_64.wsl

ARM64 Windows (Surface Pro X, Copilot+ PCs) runs WSL2 natively. This is a known limitation and fine to keep as a todo, but worth documenting in a comment.


CI: microshift-vm:build:wsl task not tested or cached in CI

The microshift-vm-build CI job only builds the QEMU image. The WSL build (microshift-vm:build:wsl) is only run in the release workflow. This means:

  1. WSL build regressions aren't caught before release
  2. The WSL build isn't cached, so every release rebuilds from scratch

Hardcoded secrets in platform.py

Lines 471–477:

"encryptionKey": "Ovx8qImylfooq4-HNwOzKKDcXLZCB3c_m0JlB9eJBxc=",
"keycloak": {
    "uiClientSecret": "agentstack-ui-secret",
    "serverClientSecret": "agentstack-server-secret",
    "auth": {"adminPassword": "admin"},
},

This is intentional for local dev (auth is disabled, "auth": {"enabled": False}), but a user who accidentally exposes the platform externally would have well-known credentials. A comment noting these are intentional local-dev defaults and not for production would reduce the risk of confusion. Not a blocker given the local-only use case.


Minor: Double blank line

platform.py lines 285–286 — there's an extra blank line between the current_lima_image assignment and the path check. Minor style nit.


Summary

The only issue I'd call a must-fix before merge is the WSL filename mismatch (.wsl vs .tar.gz) — it would cause the release pipeline to fail and break first-time Windows installs. The no-checksum issue is also worth addressing for supply chain hygiene. The rest are improvements or lower-priority concerns.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces changes to the setup environment, agentstack-cli, microshift-vm, helm values, mise configuration, and tasks. The changes include adding inputs for installing VM dependencies and maximizing disk space in the setup environment, modifying the agent metadata extraction process in agentstack-cli, updating dependencies and adding lima and wsl image options in agentstack-cli platform commands, and adding a microshift-vm build task. Review comments highlight security concerns with hardcoded passwords and disabled checksum verification, suggest simplifying the .wslconfig file writing logic, and point out a mismatch in the generated file extension for the WSL image. The reviewer also notes that setting raw = true globally in the [settings] section will disable template expansion and cause tasks that rely on templating to fail.

@JanPokorny
Copy link
Collaborator Author

@claude fix:

  • WSL image name mismatch (also ensure that the CLI arg help properly states that it has a .wsl extension)
  • add microshift-vm folder to vscode workspace definition
  • rename microshift-builder -> microshift-vm in packer config
  • "The logic for writing the updated .wslconfig file is unnecessarily complex." found by Gemini
  • verify Debian image checksum using: https://cdimage.debian.org/cdimage/cloud/trixie/latest/SHA512SUMS
  • set generateResolvConf = false

Question: is the root password "packer" retained in the resulting VM image as Gemini claims? If yes, remove the root password in the resulting VM, as Lima uses cloud-init to inject SSH keys.

@claude
Copy link

claude bot commented Mar 6, 2026

Claude finished @JanPokorny's task in 4m 25s —— View job


Done

  • Gather context and read relevant files
  • Fix WSL image name mismatch + update CLI arg help text
  • Add microshift-vm folder to VSCode workspace definition
  • Rename microshift-buildermicroshift-vm in cloud-init/meta-data
  • Fix unnecessarily complex .wslconfig writing logic
  • Add Debian image checksum verification
  • Set generateResolvConf = false
  • Answer: Is root password "packer" retained + fix

Summary of changes (commit 1524bcb)

WSL image filename — Changed build output in apps/microshift-vm/tasks.toml from .wsl to .tar.gz to be consistent with the download URL in platform.py and the release.yml upload step (which both already expect .tar.gz). release.yml cannot be modified due to workflow file permissions, so .tar.gz is the canonical format. Updated the --wsl-image CLI help text from "Local path or URL to WSL rootfs .tar.gz image""Local path or URL to WSL rootfs image (.tar.gz)" for clarity.

VSCode workspace — Added apps/microshift-vm entry to agentstack.code-workspace.

meta-data hostnamelocal-hostname: microshift-builderlocal-hostname: microshift-vm in cloud-init/meta-data.

.wslconfig write logic — Removed the unnecessary import io + io.StringIO indirection; config.write(f) directly.

Debian image checksum — Replaced iso_checksum = "none" with iso_checksum = local.image_checksum using "file:https://cdimage.debian.org/cdimage/cloud/trixie/latest/SHA512SUMS". Packer will download the SHA512SUMS file and verify the image against it at build time.

generateResolvConf — Set to false in wsl/wsl.conf since platform.py manages /etc/resolv.conf manually from the resolv.conf-override template.

Root passwordYes, Gemini's finding is correct: the "packer" password set by cloud-init/user-data during the build was not removed from /etc/shadow by cloud-init clean --logs. Without the fix, the password would persist in the distributed image. Added passwd -l root just before cloud-init clean --logs in install.sh to lock the root account. Lima injects SSH keys via cloud-init on first boot, so no password is needed; WSL doesn't use SSH at all.
· Branch

- Fix WSL image filename: build outputs .tar.gz (consistent with release.yml and platform.py download URL)
- Update --wsl-image CLI help text to explicitly mention .tar.gz format
- Add microshift-vm to VSCode workspace definition
- Rename local-hostname microshift-builder -> microshift-vm in cloud-init meta-data
- Simplify .wslconfig write logic: remove unnecessary io.StringIO indirection
- Add SHA512SUMS checksum verification for Debian base image in Packer config
- Set generateResolvConf = false in WSL wsl.conf (resolv.conf is managed manually)
- Lock root password (passwd -l root) at end of install.sh to prevent packer build password persisting in distributed image

Co-authored-by: Jan Pokorný <JanPokorny@users.noreply.github.com>
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Mar 6, 2026
@JanPokorny
Copy link
Collaborator Author

@claude Fix: change .tar.gz -> .wsl for custom WSL distro file extension

@claude
Copy link

claude bot commented Mar 6, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

Signed-off-by: Jan Pokorný <JenomPokorny@gmail.com>
@JanPokorny JanPokorny merged commit 6f29365 into main Mar 6, 2026
15 checks passed
@JanPokorny JanPokorny deleted the janpokorny/feat-agentstack-cli-prebaked-platform-vm branch March 6, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants