test: cover AWS desktop targets
This commit is contained in:
parent
343ca7baa9
commit
59afa7d720
@ -7,7 +7,9 @@
|
||||
- Added `--desktop`, `--browser`, and `crabbox vnc` for optional Linux UI/browser leases, including loopback-only VNC with per-lease passwords and headless browser support without a desktop.
|
||||
- Added static macOS/Windows VNC endpoint discovery, including SSH-tunneled loopback VNC and trusted static direct VNC on `host:5900`.
|
||||
- Added `crabbox vnc --open` to start the SSH tunnel and launch the local VNC client for managed desktop leases.
|
||||
- Added `crabbox screenshot` to save a PNG from a Linux desktop lease without opening a VNC client.
|
||||
- Added managed AWS Windows desktop leases with OpenSSH, Git for Windows, loopback TightVNC, per-lease VNC passwords, and `crabbox vnc`.
|
||||
- Added AWS macOS desktop lease plumbing for EC2 Mac Dedicated Hosts, including Screen Sharing setup and per-lease credentials.
|
||||
- Added `crabbox screenshot` to save a PNG from a desktop lease without opening a VNC client.
|
||||
- Added a minimal XFCE desktop profile with panel/window manager for managed VNC leases.
|
||||
- Clarified static macOS/Windows VNC as existing-host access, not Crabbox-created boxes, so `--open` no longer launches an OS credential prompt unless `--host-managed` is passed.
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ For the full mental model, see [How Crabbox Works](docs/how-it-works.md). For th
|
||||
- **Trusted AWS images.** Operators can create AMIs from active brokered AWS leases and promote a known-good image as the coordinator default.
|
||||
- **Cost guardrails.** Per-lease and monthly spend caps. Live pricing from EC2 Spot history or Hetzner server-type prices, with static fallbacks. `crabbox usage` summarizes spend by user, org, provider, and type.
|
||||
- **GitHub Actions hydration.** `crabbox actions hydrate` registers a leased box as an ephemeral Actions runner, so the repo's own workflow installs runtimes, services, and secrets. Crabbox does not parse Actions YAML.
|
||||
- **Interactive desktop and browser leases.** `--browser` provisions Chrome or Chromium for headless automation, `--desktop` provisions Xvfb/Openbox/x11vnc for visible UI and tunnel-only VNC takeover, and QA systems such as Mantis own scenario logic, screenshots, and PR evidence.
|
||||
- **Interactive desktop and browser leases.** `--browser` provisions Chrome or Chromium for headless automation, `--desktop` provisions visible UI with tunnel-only VNC takeover on managed Linux, AWS Windows, and AWS EC2 Mac targets, and QA systems such as Mantis own scenario logic, screenshots, and PR evidence.
|
||||
- **Hardened coordinator auth.** GitHub browser login, owner-scoped leases, admin-only routes, optional GitHub team allowlists, Cloudflare Access JWT verification, and service-token support keep normal use and operator automation separate.
|
||||
- **OpenClaw plugin.** The repo root is a native OpenClaw plugin for box lifecycle operations: `crabbox_run`, `crabbox_warmup`, `crabbox_status`, `crabbox_list`, and `crabbox_stop`. Run inspection stays in the CLI and Crabbox skill.
|
||||
- **Operator surface.** `doctor`, `init`, `status`, `inspect`, `list`, `usage`, `history`, `logs`, `results`, `cache`, `admin`, `cleanup`, plus `--json` output where it matters.
|
||||
|
||||
20
docs/cli.md
20
docs/cli.md
@ -114,6 +114,15 @@ crabbox run --provider ssh --target windows --windows-mode normal --static-host
|
||||
crabbox run --provider ssh --target windows --windows-mode wsl2 --static-host win-dev.local -- pnpm test
|
||||
```
|
||||
|
||||
Create managed AWS desktop boxes:
|
||||
|
||||
```sh
|
||||
crabbox warmup --provider aws --target windows --desktop --market on-demand
|
||||
CRABBOX_AWS_MAC_HOST_ID=h-... crabbox warmup --provider aws --target macos --desktop --market on-demand
|
||||
crabbox vnc --id blue-lobster
|
||||
crabbox screenshot --id blue-lobster --output desktop.png
|
||||
```
|
||||
|
||||
Inspect pool:
|
||||
|
||||
```sh
|
||||
@ -333,6 +342,17 @@ static:
|
||||
workRoot: C:\crabbox
|
||||
```
|
||||
|
||||
AWS EC2 Mac target:
|
||||
|
||||
```yaml
|
||||
provider: aws
|
||||
target: macos
|
||||
aws:
|
||||
macHostId: h-0123456789abcdef0
|
||||
capacity:
|
||||
market: on-demand
|
||||
```
|
||||
|
||||
`windows.mode: normal` runs native PowerShell over OpenSSH and syncs with a tar
|
||||
archive. `windows.mode: wsl2` runs commands through `wsl.exe --exec bash -lc`
|
||||
and uses rsync inside WSL2, so `static.workRoot` should be a WSL path.
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# screenshot
|
||||
|
||||
`crabbox screenshot` captures a PNG from a Linux desktop lease without opening a
|
||||
VNC client.
|
||||
`crabbox screenshot` captures a PNG from a desktop lease without opening a VNC
|
||||
client.
|
||||
|
||||
```sh
|
||||
crabbox warmup --desktop
|
||||
@ -11,7 +11,9 @@ crabbox screenshot --id blue-lobster --output desktop.png
|
||||
|
||||
The command resolves and touches the lease like `crabbox ssh`, verifies that the
|
||||
lease has `desktop=true`, waits for the loopback desktop/VNC service, then
|
||||
streams a PNG over SSH from `DISPLAY=:99`.
|
||||
streams a PNG over SSH. Linux captures `DISPLAY=:99`, Windows captures the
|
||||
primary desktop with PowerShell/.NET drawing APIs, and macOS uses
|
||||
`screencapture`.
|
||||
|
||||
If `--output` is omitted, Crabbox writes:
|
||||
|
||||
@ -19,10 +21,10 @@ If `--output` is omitted, Crabbox writes:
|
||||
crabbox-<slug-or-id>-screenshot.png
|
||||
```
|
||||
|
||||
Screenshots are currently supported for Linux desktop leases. Static macOS and
|
||||
Windows targets are existing host machines, not Crabbox-created desktops, so
|
||||
`screenshot` rejects those targets instead of capturing your local or home-host
|
||||
desktop by accident.
|
||||
Static macOS and Windows targets are existing host machines, not Crabbox-created
|
||||
desktops, so `screenshot` rejects those targets instead of capturing your local
|
||||
or home-host desktop by accident. Managed AWS Windows and AWS macOS desktop
|
||||
leases are Crabbox-created boxes and can be captured by lease id or slug.
|
||||
|
||||
Flags:
|
||||
|
||||
|
||||
@ -26,10 +26,11 @@ Keep the tunnel process running while connected.
|
||||
```
|
||||
|
||||
Run the tunnel command in another terminal, then connect your VNC client to the
|
||||
printed `localhost:<port>` endpoint. Managed Linux desktop leases use a
|
||||
per-lease VNC password stored on the runner under `/var/lib/crabbox`; the
|
||||
password is retrieved over SSH only when `vnc` is called. It is not stored in
|
||||
provider labels or run history.
|
||||
printed `localhost:<port>` endpoint. Managed desktop leases use a per-lease VNC
|
||||
password stored on the runner. Linux stores it under `/var/lib/crabbox`, Windows
|
||||
under `C:\ProgramData\crabbox`, and macOS under `/var/db/crabbox`; the password
|
||||
is retrieved over SSH only when `vnc` is called. It is not stored in provider
|
||||
labels or run history.
|
||||
|
||||
Use `--open` to let Crabbox start the SSH tunnel, open the local VNC URL, and
|
||||
print the tunnel process ID. Keep that tunnel process alive while connected.
|
||||
@ -55,14 +56,24 @@ Security boundary:
|
||||
|
||||
- VNC is never exposed directly to the public internet.
|
||||
- Managed Linux binds x11vnc to `127.0.0.1:5900` on the runner.
|
||||
- Managed Windows installs TightVNC and connects through the SSH tunnel.
|
||||
- Managed macOS enables Screen Sharing and connects through the SSH tunnel.
|
||||
- Crabbox does not add provider firewall or security-group ingress for VNC.
|
||||
- Brokered leases use SSH tunnels only. Static hosts may also use direct
|
||||
operator-managed VNC when `host:5900` is already reachable.
|
||||
|
||||
Provider behavior:
|
||||
|
||||
- Brokered and direct AWS/Hetzner leases are Linux-only in this release. They
|
||||
support `vnc` only when created with `--desktop`.
|
||||
- Brokered and direct Hetzner leases support Linux VNC only when created with
|
||||
`--desktop`.
|
||||
- Brokered and direct AWS Linux leases support VNC when created with
|
||||
`--desktop`.
|
||||
- Brokered and direct AWS native Windows leases support VNC when created with
|
||||
`--target windows --desktop`. Crabbox installs OpenSSH, Git for Windows, and
|
||||
TightVNC through EC2Launch user data.
|
||||
- Brokered and direct AWS macOS leases support VNC when created with
|
||||
`--target macos --desktop --market on-demand` and an EC2 Mac Dedicated Host id
|
||||
from `CRABBOX_AWS_MAC_HOST_ID` or `aws.macHostId`.
|
||||
- Static Linux can participate if the operator already configured Xvfb and
|
||||
loopback-bound x11vnc.
|
||||
- Static macOS can participate when Screen Sharing or another VNC-compatible
|
||||
@ -70,8 +81,8 @@ Provider behavior:
|
||||
`host:5900`. This reuses an existing Mac; it does not create a macOS Crabbox.
|
||||
Credentials are host-managed.
|
||||
- Static native Windows can participate when a VNC server is already available
|
||||
on `127.0.0.1:5900` over SSH or directly on `host:5900`. Crabbox does not
|
||||
create a Windows Crabbox, or install or configure the Windows VNC server.
|
||||
on `127.0.0.1:5900` over SSH or directly on `host:5900`. Static Windows is
|
||||
still host-managed; managed Windows VNC is AWS-only.
|
||||
- Blacksmith Testbox does not support managed VNC in this release.
|
||||
|
||||
Flags:
|
||||
|
||||
@ -7,6 +7,8 @@ crabbox warmup --class beast
|
||||
crabbox warmup --provider aws --class beast --market on-demand
|
||||
crabbox warmup --browser
|
||||
crabbox warmup --desktop --browser
|
||||
crabbox warmup --provider aws --target windows --desktop --market on-demand
|
||||
crabbox warmup --provider aws --target macos --desktop --market on-demand --type mac2.metal
|
||||
crabbox warmup --actions-runner
|
||||
crabbox warmup --provider blacksmith-testbox --blacksmith-workflow .github/workflows/ci-check-testbox.yml --blacksmith-job test
|
||||
crabbox warmup --provider ssh --target macos --static-host mac-studio.local
|
||||
@ -25,6 +27,18 @@ OpenSSH Server reachable, PowerShell, Git, `tar`, and a writable
|
||||
`static.workRoot`. Restart `sshd` after installing Git so new SSH sessions see
|
||||
the updated PATH.
|
||||
|
||||
With `--provider aws --target windows --desktop`, Crabbox creates a real AWS
|
||||
Windows Server lease. EC2Launch user data installs OpenSSH Server, Git for
|
||||
Windows, TightVNC Server, a per-lease local administrator named `crabbox`, and a
|
||||
loopback VNC password retrievable through `crabbox vnc --id <lease>`.
|
||||
|
||||
With `--provider aws --target macos --desktop`, Crabbox launches an EC2 Mac
|
||||
instance on an already allocated Dedicated Host. Set `CRABBOX_AWS_MAC_HOST_ID`
|
||||
or `aws.macHostId`, use `--market on-demand`, and expect EC2 Mac host lifecycle
|
||||
rules to dominate cleanup and cost. The default SSH user is `ec2-user`; the VNC
|
||||
password printed by `crabbox vnc` is the per-lease macOS account password set by
|
||||
bootstrap.
|
||||
|
||||
On success, `warmup` prints a concise total duration line. Add `--timing-json` to emit a final JSON timing record with provider, lease ID, slug, total duration, and exit code.
|
||||
|
||||
Flags:
|
||||
|
||||
@ -14,8 +14,8 @@ inside that lease.
|
||||
|
||||
The intended contract is:
|
||||
|
||||
- `crabbox warmup --desktop` leases or reuses a Linux machine with the normal
|
||||
Crabbox SSH contract plus a desktop profile;
|
||||
- `crabbox warmup --desktop` leases or reuses a machine with the normal Crabbox
|
||||
SSH contract plus a desktop profile;
|
||||
- `crabbox warmup --browser` leases or reuses a Linux machine with a known
|
||||
browser binary for headless automation;
|
||||
- `crabbox warmup --desktop --browser` combines a visible session with a browser
|
||||
@ -69,16 +69,22 @@ Security rules:
|
||||
|
||||
- never expose VNC directly to the public internet;
|
||||
- prefer SSH local forwarding such as `localhost:5901 -> 127.0.0.1:5900`;
|
||||
- generate per-lease VNC passwords for managed Linux desktop leases;
|
||||
- generate per-lease VNC passwords for managed desktop leases;
|
||||
- redact passwords from logs and run records;
|
||||
- stop desktop services when the lease stops;
|
||||
- keep the normal TTL and idle-timeout lifecycle in force.
|
||||
|
||||
Provider notes:
|
||||
|
||||
- Hetzner and AWS brokered Linux leases are the primary target because Crabbox
|
||||
controls cloud-init and firewall shape there. Brokered macOS and Windows
|
||||
desktop leases do not exist in this release.
|
||||
- Hetzner and AWS brokered Linux leases use cloud-init to install Xvfb, XFCE,
|
||||
x11vnc, and optional Chrome/Chromium.
|
||||
- AWS brokered Windows desktop leases use EC2Launch PowerShell user data to
|
||||
install OpenSSH, Git for Windows, TightVNC, and a local `crabbox`
|
||||
administrator. VNC is reached through the SSH tunnel; the security group only
|
||||
needs SSH.
|
||||
- AWS brokered macOS desktop leases require an allocated EC2 Mac Dedicated Host
|
||||
and On-Demand capacity. Bootstrap enables Screen Sharing for `ec2-user` and
|
||||
stores the generated password on the instance for `crabbox vnc`.
|
||||
- Static SSH Linux hosts can participate when the operator accepts responsibility
|
||||
for packages and display services.
|
||||
- Static macOS hosts are existing Macs, not Crabbox-created boxes. They can
|
||||
@ -94,8 +100,8 @@ Provider notes:
|
||||
- Blacksmith Testbox can run headless browser automation today, but VNC takeover
|
||||
needs a Blacksmith-supported SSH tunnel or connection-info API before Crabbox
|
||||
can offer the same `vnc` command there.
|
||||
- Crabbox-managed macOS and Windows VNC installers are still out of scope for
|
||||
this release.
|
||||
- EC2 Mac host allocation, host scrubbing, and the AWS 24-hour host lifecycle
|
||||
remain operator concerns; Crabbox only launches onto a host id it is given.
|
||||
|
||||
For Mantis, the first consumer should be a Discord QA lane:
|
||||
|
||||
|
||||
@ -13,8 +13,9 @@ hetzner Hetzner Cloud servers
|
||||
aws AWS EC2 one-time Spot instances
|
||||
```
|
||||
|
||||
Brokered Hetzner and AWS leases are Linux targets. macOS and Windows targets use
|
||||
the direct static SSH provider:
|
||||
Brokered Hetzner leases are Linux targets. Brokered AWS supports Linux, native
|
||||
Windows Server, and EC2 Mac when a Dedicated Host is configured. Static SSH
|
||||
still exists for reusing existing macOS and Windows machines:
|
||||
|
||||
```text
|
||||
ssh Existing SSH host selected by static.host
|
||||
@ -34,6 +35,10 @@ AWS behavior:
|
||||
- imports or reuses an EC2 key pair;
|
||||
- creates or reuses the `crabbox-runners` security group with SSH ingress limited to configured CIDRs or the request source IP;
|
||||
- launches one-time Spot instances;
|
||||
- launches AWS Windows Server desktop leases with EC2Launch PowerShell user
|
||||
data, OpenSSH, Git for Windows, and TightVNC when `target=windows`;
|
||||
- launches EC2 Mac leases only with an explicit Dedicated Host id
|
||||
(`CRABBOX_AWS_MAC_HOST_ID` or `aws.macHostId`) and On-Demand capacity;
|
||||
- tags instances, volumes, and Spot requests;
|
||||
- falls back across broad C/M/R instance families for class requests, including account policy and capacity rejections;
|
||||
- can fall back to a small burstable type when account policy rejects the high-core class candidates;
|
||||
@ -64,6 +69,15 @@ standard c7a.8xlarge, c7i.8xlarge, m7a.8xlarge, m7i.8xlarge, c7a.4xlarge
|
||||
fast c7a.16xlarge, c7i.16xlarge, m7a.16xlarge, m7i.16xlarge, c7a.12xlarge, c7a.8xlarge
|
||||
large c7a.24xlarge, c7i.24xlarge, m7a.24xlarge, m7i.24xlarge, r7a.24xlarge, c7a.16xlarge, c7a.12xlarge
|
||||
beast c7a.48xlarge, c7i.48xlarge, m7a.48xlarge, m7i.48xlarge, r7a.48xlarge, c7a.32xlarge, c7i.32xlarge, m7a.32xlarge, c7a.24xlarge, c7a.16xlarge
|
||||
|
||||
AWS Windows
|
||||
standard m7i.large, m7a.large, t3.large
|
||||
fast m7i.xlarge, m7a.xlarge, t3.xlarge
|
||||
large m7i.2xlarge, m7a.2xlarge, t3.2xlarge
|
||||
beast m7i.4xlarge, m7a.4xlarge, m7i.2xlarge
|
||||
|
||||
AWS macOS
|
||||
all mac2.metal unless `--type` is set
|
||||
```
|
||||
|
||||
Direct provider mode still exists when no coordinator is configured. It uses local AWS credentials or `HCLOUD_TOKEN`/`HETZNER_TOKEN` and should stay secondary to the brokered path.
|
||||
|
||||
@ -81,3 +81,45 @@ func TestCloudInitBrowserProfile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAWSUserDataWindowsProfile(t *testing.T) {
|
||||
cfg := baseConfig()
|
||||
cfg.Provider = "aws"
|
||||
cfg.TargetOS = targetWindows
|
||||
cfg.WindowsMode = windowsModeNormal
|
||||
cfg.WorkRoot = `C:\crabbox`
|
||||
got := awsUserData(cfg, "ssh-ed25519 test")
|
||||
for _, want := range []string{
|
||||
"<powershell>",
|
||||
"OpenSSH.Server~~~~0.0.1.0",
|
||||
"administrators_authorized_keys",
|
||||
"Git-2.52.0-64-bit.exe",
|
||||
"tightvnc-2.8.85-gpl-setup-64bit.msi",
|
||||
"VALUE_OF_PASSWORD=$vncPassword",
|
||||
"VALUE_OF_ALLOWLOOPBACK=1",
|
||||
`C:\ProgramData\crabbox\vnc.password`,
|
||||
} {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Fatalf("windows user data missing %q", want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAWSUserDataMacOSProfile(t *testing.T) {
|
||||
cfg := baseConfig()
|
||||
cfg.Provider = "aws"
|
||||
cfg.TargetOS = targetMacOS
|
||||
cfg.SSHUser = "ec2-user"
|
||||
got := awsUserData(cfg, "ssh-ed25519 test")
|
||||
for _, want := range []string{
|
||||
"#!/bin/bash",
|
||||
"/var/db/crabbox/vnc.password",
|
||||
"com.apple.screensharing",
|
||||
"/usr/local/bin/crabbox-ready",
|
||||
"nc -z 127.0.0.1 5900",
|
||||
} {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Fatalf("macOS user data missing %q", want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,3 +28,14 @@ func TestScreenshotRemoteCommandUsesDesktopDisplayAndPNG(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScreenshotRemoteCommandSupportsWindowsAndMacOS(t *testing.T) {
|
||||
windows := screenshotRemoteCommand(SSHTarget{TargetOS: targetWindows, WindowsMode: windowsModeNormal})
|
||||
if !strings.Contains(windows, "System.Windows.Forms") || !strings.Contains(windows, "ImageFormat]::Png") {
|
||||
t.Fatalf("windows screenshot command=%s", windows)
|
||||
}
|
||||
mac := screenshotRemoteCommand(SSHTarget{TargetOS: targetMacOS})
|
||||
if !strings.Contains(mac, "screencapture -x -t png -") {
|
||||
t.Fatalf("mac screenshot command=%s", mac)
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ func validateProviderTarget(cfg Config) error {
|
||||
return nil
|
||||
}
|
||||
if cfg.Provider == "aws" && cfg.TargetOS == targetMacOS {
|
||||
if cfg.AWSMacHostID == "" {
|
||||
if cfg.AWSMacHostID == "" && cfg.Coordinator == "" {
|
||||
return exit(2, "provider=aws target=macos requires CRABBOX_AWS_MAC_HOST_ID or aws.macHostId for an allocated EC2 Mac Dedicated Host")
|
||||
}
|
||||
if cfg.Capacity.Market != "on-demand" {
|
||||
|
||||
@ -30,6 +30,16 @@ func TestVNCLoopbackCheckCommandSupportsWindows(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVNCPasswordCommandSupportsManagedTargets(t *testing.T) {
|
||||
windows := vncPasswordCommand(SSHTarget{TargetOS: targetWindows, WindowsMode: windowsModeNormal})
|
||||
if !strings.Contains(windows, "EncodedCommand") {
|
||||
t.Fatalf("windows password command should be encoded PowerShell: %q", windows)
|
||||
}
|
||||
if got := vncPasswordCommand(SSHTarget{TargetOS: targetMacOS}); got != "cat '/var/db/crabbox/vnc.password'" {
|
||||
t.Fatalf("mac password command=%q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenURLCommandIncludesURL(t *testing.T) {
|
||||
name, args := openURLCommand("vnc://localhost:5901")
|
||||
if name == "" {
|
||||
|
||||
@ -99,7 +99,9 @@ export function leaseConfig(input: LeaseRequest): LeaseConfig {
|
||||
sshPort: input.sshPort ?? "2222",
|
||||
sshFallbackPorts: validPorts(input.sshFallbackPorts ?? ["22"]),
|
||||
providerKey: input.providerKey ?? "crabbox-steipete",
|
||||
workRoot: input.workRoot ?? (target === "windows" && windowsMode === "normal" ? "C:\\crabbox" : "/work/crabbox"),
|
||||
workRoot:
|
||||
input.workRoot ??
|
||||
(target === "windows" && windowsMode === "normal" ? "C:\\crabbox" : "/work/crabbox"),
|
||||
ttlSeconds,
|
||||
idleTimeoutSeconds,
|
||||
keep: input.keep ?? false,
|
||||
|
||||
@ -60,6 +60,7 @@ describe("aws provider", () => {
|
||||
expect(
|
||||
awsLaunchCandidates({
|
||||
class: "beast",
|
||||
target: "linux",
|
||||
serverType: "c7a.48xlarge",
|
||||
serverTypeExplicit: false,
|
||||
}),
|
||||
@ -67,6 +68,7 @@ describe("aws provider", () => {
|
||||
expect(
|
||||
awsLaunchCandidates({
|
||||
class: "beast",
|
||||
target: "linux",
|
||||
serverType: "t3.small",
|
||||
serverTypeExplicit: true,
|
||||
}),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { cloudInit } from "../src/bootstrap";
|
||||
import { awsUserData, cloudInit } from "../src/bootstrap";
|
||||
import type { LeaseConfig } from "../src/config";
|
||||
|
||||
const config: LeaseConfig = {
|
||||
@ -95,4 +95,30 @@ describe("cloud-init bootstrap", () => {
|
||||
expect(got).toContain('test -x "$BROWSER"');
|
||||
expect(got).toContain('"$BROWSER" --version >/dev/null');
|
||||
});
|
||||
|
||||
it("builds Windows EC2Launch user data for managed VNC", () => {
|
||||
const got = awsUserData({
|
||||
...config,
|
||||
target: "windows",
|
||||
workRoot: "C:\\crabbox",
|
||||
});
|
||||
expect(got).toContain("<powershell>");
|
||||
expect(got).toContain("OpenSSH.Server~~~~0.0.1.0");
|
||||
expect(got).toContain("administrators_authorized_keys");
|
||||
expect(got).toContain("tightvnc-2.8.85-gpl-setup-64bit.msi");
|
||||
expect(got).toContain("VALUE_OF_PASSWORD=$vncPassword");
|
||||
expect(got).toContain("VALUE_OF_ALLOWLOOPBACK=1");
|
||||
});
|
||||
|
||||
it("builds macOS user data for managed screen sharing", () => {
|
||||
const got = awsUserData({
|
||||
...config,
|
||||
target: "macos",
|
||||
sshUser: "ec2-user",
|
||||
});
|
||||
expect(got).toContain("#!/bin/bash");
|
||||
expect(got).toContain("/var/db/crabbox/vnc.password");
|
||||
expect(got).toContain("com.apple.screensharing");
|
||||
expect(got).toContain("/usr/local/bin/crabbox-ready");
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
awsInstanceTypeCandidatesForClass,
|
||||
awsInstanceTypeCandidatesForTargetClass,
|
||||
leaseConfig,
|
||||
serverTypeCandidatesForClass,
|
||||
serverTypeForClass,
|
||||
@ -40,6 +41,15 @@ describe("machine class config", () => {
|
||||
"c7a.16xlarge",
|
||||
]);
|
||||
});
|
||||
|
||||
it("maps AWS Windows and macOS classes to compatible families", () => {
|
||||
expect(awsInstanceTypeCandidatesForTargetClass("windows", "standard")).toEqual([
|
||||
"m7i.large",
|
||||
"m7a.large",
|
||||
"t3.large",
|
||||
]);
|
||||
expect(awsInstanceTypeCandidatesForTargetClass("macos", "standard")).toEqual(["mac2.metal"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("lease config", () => {
|
||||
@ -77,13 +87,43 @@ describe("lease config", () => {
|
||||
expect(config.awsRegion).toBe("eu-west-1");
|
||||
});
|
||||
|
||||
it("records linux target defaults and rejects brokered non-linux targets", () => {
|
||||
it("records linux target defaults and rejects unsupported brokered non-linux targets", () => {
|
||||
const config = leaseConfig({ sshPublicKey: "ssh-ed25519 test" });
|
||||
expect(config.target).toBe("linux");
|
||||
expect(config.windowsMode).toBe("normal");
|
||||
expect(() => leaseConfig({ target: "macos", sshPublicKey: "ssh-ed25519 test" })).toThrow(
|
||||
"unsupported target",
|
||||
);
|
||||
expect(() =>
|
||||
leaseConfig({ provider: "hetzner", target: "windows", sshPublicKey: "ssh-ed25519 test" }),
|
||||
).toThrow("unsupported target");
|
||||
});
|
||||
|
||||
it("allows AWS native Windows leases", () => {
|
||||
const config = leaseConfig({
|
||||
provider: "aws",
|
||||
target: "windows",
|
||||
desktop: true,
|
||||
sshPublicKey: "ssh-ed25519 test",
|
||||
});
|
||||
expect(config.serverType).toBe("m7i.4xlarge");
|
||||
expect(config.workRoot).toBe("C:\\crabbox");
|
||||
expect(config.desktop).toBe(true);
|
||||
});
|
||||
|
||||
it("allows AWS macOS leases only with on-demand capacity", () => {
|
||||
expect(() =>
|
||||
leaseConfig({
|
||||
provider: "aws",
|
||||
target: "macos",
|
||||
sshPublicKey: "ssh-ed25519 test",
|
||||
}),
|
||||
).toThrow("capacity.market=on-demand");
|
||||
const config = leaseConfig({
|
||||
provider: "aws",
|
||||
target: "macos",
|
||||
capacity: { market: "on-demand" },
|
||||
sshPublicKey: "ssh-ed25519 test",
|
||||
});
|
||||
expect(config.serverType).toBe("mac2.metal");
|
||||
expect(config.sshUser).toBe("ec2-user");
|
||||
});
|
||||
|
||||
it("preserves exact server type requests", () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user