4.7 KiB
name, description
| name | description |
|---|---|
| create-workspace | Creates a new sandboxed workspace (isolated dev environment) by adding NixOS configuration for a VM, container, or Incus instance. Use when the user wants to create, set up, or add a new sandboxed workspace. |
Create Sandboxed Workspace
Creates an isolated development environment backed by a VM (microvm.nix), container (systemd-nspawn), or Incus instance. This produces:
- A workspace config file at
machines/<machine>/workspaces/<name>.nix - A registration entry in
machines/<machine>/default.nix
Step 1: Parse Arguments
Extract the workspace name and backend type from $ARGUMENTS. If either is missing, ask the user.
- Name: lowercase alphanumeric with hyphens (e.g.,
my-project) - Type: one of
vm,container, orincus
Step 2: Detect Machine
Run hostname to get the current machine name. Verify that machines/<hostname>/default.nix exists.
If the machine directory doesn't exist, stop and tell the user this machine isn't managed by this flake.
Step 3: Allocate IP Address
Read machines/<hostname>/default.nix to find existing sandboxed-workspace.workspaces entries and their IPs.
All IPs are in the 192.168.83.0/24 subnet. Use these ranges by convention:
| Type | IP Range |
|---|---|
| vm | 192.168.83.10 - .49 |
| container | 192.168.83.50 - .89 |
| incus | 192.168.83.90 - .129 |
Pick the next available IP in the appropriate range. If no workspaces exist yet for that type, use the first IP in the range.
Step 4: Create Workspace Config File
Create machines/<hostname>/workspaces/<name>.nix. Use this template:
{ config, lib, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
# Add packages here
];
}
Ask the user if they want any packages pre-installed.
Create the workspaces/ directory if it doesn't exist.
Important: After creating the file, run git add on it immediately. Nix flakes only see files tracked by git, so new files must be staged before nix build will work.
Step 5: Register Workspace
Edit machines/<hostname>/default.nix to add the workspace entry inside the sandboxed-workspace block.
The entry should look like:
workspaces.<name> = {
type = "<type>";
config = ./workspaces/<name>.nix;
ip = "<allocated-ip>";
};
If sandboxed-workspace block doesn't exist yet, add the full block:
sandboxed-workspace = {
enable = true;
workspaces.<name> = {
type = "<type>";
config = ./workspaces/<name>.nix;
ip = "<allocated-ip>";
};
};
The machine also needs networking.sandbox.upstreamInterface set. Check if it exists; if not, ask the user for their primary network interface name (they can find it with ip route show default).
Do not set hostKey — it gets auto-generated on first boot and can be added later.
Step 6: Verify Build
Run a build to check for configuration errors:
nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel --no-link
If the build fails, fix the configuration and retry.
Step 7: Deploy
Tell the user to deploy by running:
doas nixos-rebuild switch --flake .
Never run this command yourself — it requires privileges.
Step 8: Post-Deploy Info
Tell the user to deploy and then start the workspace so the host key gets generated. Provide these instructions:
Deploy:
doas nixos-rebuild switch --flake .
Starting the workspace:
doas systemctl start <service>
Where <service> is:
- VM:
microvm@<name> - Container:
container@<name> - Incus:
incus-workspace-<name>
Or use the auto-generated shell alias: workspace_<name>_start
Connecting:
ssh googlebot@workspace-<name>
Or use the alias: workspace_<name>
Never run deploy or start commands yourself — they require privileges.
Step 9: Add Host Key
After the user has deployed and started the workspace, add the SSH host key to the workspace config. Do NOT skip this step — always wait for the user to confirm they've started the workspace, then proceed.
- Read the host key from
~/sandboxed/<name>/ssh-host-keys/ssh_host_ed25519_key.pub - Add
hostKey = "<contents>";to the workspace entry inmachines/<hostname>/default.nix - Run the build again to verify
- Tell the user to redeploy with
doas nixos-rebuild switch --flake .
Backend Reference
| VM | Container | Incus | |
|---|---|---|---|
| Isolation | Full kernel (cloud-hypervisor) | Shared kernel (systemd-nspawn) | Unprivileged container |
| Overhead | Higher (separate kernel) | Lower (bind mounts) | Medium |
| Filesystem | virtiofs shares | Bind mounts | Incus-managed |
| Use case | Untrusted code, kernel-level isolation | Fast dev environments | Better security than nspawn |