From b4e34e661b76ae1dc90198a55ac64dce35040810 Mon Sep 17 00:00:00 2001 From: "spin-stack-website-sync[bot]" <347572492+spin-stack-website-sync[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 03:10:14 +0000 Subject: [PATCH] sources: spin v20261025.01 4534f65212, brand main 31d07eb9b7 Written by sync.yml: versions.yaml bumped by task sources:bump, the reference by task reference. --- public/openapi.json | 256 ++++++++++++++++-- src/assets/shots/workspace.png | Bin 61236 -> 61490 bytes src/assets/shots/workspaces.png | Bin 54029 -> 54058 bytes src/content/docs/reference/api/types.md | 52 +++- .../docs/reference/security/known-gaps.md | 2 +- src/content/docs/reference/security/rules.md | 2 +- src/content/docs/reference/status/index.md | 138 +++++----- src/content/docs/use/dashboard.md | 2 +- src/data/figures.json | 8 +- src/data/reference.json | 8 +- src/data/shots.json | 4 +- versions.yaml | 6 +- 12 files changed, 362 insertions(+), 116 deletions(-) diff --git a/public/openapi.json b/public/openapi.json index 98787ec..6e45cb6 100644 --- a/public/openapi.json +++ b/public/openapi.json @@ -11063,7 +11063,10 @@ "enum": [ "NULL_VALUE" ], - "description": "Represents a JSON `null`.\n\n `NullValue` is a sentinel, using an enum with only one value to represent\n the null value for the `Value` type union.\n\n A field of type `NullValue` with any value other than `0` is considered\n invalid. Most ProtoJSON serializers will emit a Value with a `null_value` set\n as a JSON `null` regardless of the integer value, and so will round trip to\n a `0` value." + "description": "Represents a JSON `null`.\n\n `NullValue` is a sentinel, using an enum with only one value to represent\n the null value for the `Value` type union.\n\n A field of type `NullValue` with any value other than `0` is considered\n invalid. Most ProtoJSON serializers will emit a Value with a `null_value` set\n as a JSON `null` regardless of the integer value, and so will round trip to\n a `0` value.\n\n- `NULL_VALUE`: Null value.", + "x-enum-descriptions": [ + "Null value." + ] }, "google.protobuf.Struct": { "type": "object", @@ -11379,7 +11382,12 @@ "ALLOWED_EMAIL_TYPE_EMAIL", "ALLOWED_EMAIL_TYPE_DOMAIN" ], - "description": "Allowed email type enum" + "description": "Allowed email type enum\n\n- `ALLOWED_EMAIL_TYPE_EMAIL`: Exact email address match\n- `ALLOWED_EMAIL_TYPE_DOMAIN`: Domain suffix match (@domain.com)", + "x-enum-descriptions": [ + "", + "Exact email address match", + "Domain suffix match (@domain.com)" + ] }, "spin.v1.ApproveWorkspaceSignInRequest": { "type": "object", @@ -11681,7 +11689,13 @@ "BURST_MODE_TO_PRESET", "BURST_MODE_TO_HOST" ], - "description": "BurstMode is how a workspace of a preset may grow past what it starts with." + "description": "BurstMode is how a workspace of a preset may grow past what it starts with.\n\n- `BURST_MODE_FIXED`: FIXED starts at the preset's size and stays there.\n- `BURST_MODE_TO_PRESET`: TO_PRESET starts at the preset's burst floor and may grow to its size.\n- `BURST_MODE_TO_HOST`: TO_HOST starts at the preset's burst floor and may grow to everything its host has.", + "x-enum-descriptions": [ + "", + "FIXED starts at the preset's size and stays there.", + "TO_PRESET starts at the preset's burst floor and may grow to its size.", + "TO_HOST starts at the preset's burst floor and may grow to everything its host has." + ] }, "spin.v1.ChangePasswordRequest": { "type": "object", @@ -12062,7 +12076,14 @@ "CONFIG_ITEM_KIND_PRESET", "CONFIG_ITEM_KIND_POLICY" ], - "description": "What one item of the installation's config file is." + "description": "What one item of the installation's config file is.\n\n- `CONFIG_ITEM_KIND_SETTING`: A setting, by its key: registration_mode, default_network_tags, allowed_images...\n- `CONFIG_ITEM_KIND_EMAIL`: An address or domain registration admits, by itself.", + "x-enum-descriptions": [ + "", + "A setting, by its key: registration_mode, default_network_tags, allowed_images...", + "An address or domain registration admits, by itself.", + "", + "" + ] }, "spin.v1.ConfigureGitHubOAuthRequest": { "type": "object", @@ -12932,6 +12953,14 @@ "DEVICE_LOGIN_STATUS_COMPLETE", "DEVICE_LOGIN_STATUS_EXPIRED", "DEVICE_LOGIN_STATUS_DENIED" + ], + "description": "- `DEVICE_LOGIN_STATUS_PENDING`: User hasn't completed login yet\n- `DEVICE_LOGIN_STATUS_COMPLETE`: Login complete, token available\n- `DEVICE_LOGIN_STATUS_EXPIRED`: Device code expired\n- `DEVICE_LOGIN_STATUS_DENIED`: User denied the request", + "x-enum-descriptions": [ + "", + "User hasn't completed login yet", + "Login complete, token available", + "Device code expired", + "User denied the request" ] }, "spin.v1.DiffSnapshotsRequest": { @@ -13337,6 +13366,14 @@ "FILE_CHANGE_KIND_REMOVED", "FILE_CHANGE_KIND_MODIFIED", "FILE_CHANGE_KIND_TYPE_CHANGED" + ], + "description": "- `FILE_CHANGE_KIND_MODIFIED`: The same type on both sides, and a different content, mode, owner or symlink target.", + "x-enum-descriptions": [ + "", + "", + "", + "The same type on both sides, and a different content, mode, owner or symlink target.", + "" ] }, "spin.v1.FileState": { @@ -13404,6 +13441,14 @@ "FILE_TYPE_DIRECTORY", "FILE_TYPE_SYMLINK", "FILE_TYPE_OTHER" + ], + "description": "- `FILE_TYPE_OTHER`: A device, a FIFO or a socket.", + "x-enum-descriptions": [ + "", + "", + "", + "", + "A device, a FIFO or a socket." ] }, "spin.v1.FleetHostVersion": { @@ -17249,7 +17294,12 @@ "OUTSIDE_SHARE_STATE_PREPARING", "OUTSIDE_SHARE_STATE_READY" ], - "description": "OutsideShareState is how far a snapshot's share outside its team is." + "description": "OutsideShareState is how far a snapshot's share outside its team is.\n\n- `OUTSIDE_SHARE_STATE_UNSPECIFIED`: None: the snapshot was never shared outside its team, nor made public.\n- `OUTSIDE_SHARE_STATE_PREPARING`: A host is writing the keys a clone outside the team reads the snapshot with.\n- `OUTSIDE_SHARE_STATE_READY`: Somebody of another team can create a workspace from it.", + "x-enum-descriptions": [ + "None: the snapshot was never shared outside its team, nor made public.", + "A host is writing the keys a clone outside the team reads the snapshot with.", + "Somebody of another team can create a workspace from it." + ] }, "spin.v1.OwnerWord": { "type": "object", @@ -17437,6 +17487,12 @@ "PLATFORM_IMAGE_ARTIFACT_UNSPECIFIED", "PLATFORM_IMAGE_ARTIFACT_BASE", "PLATFORM_IMAGE_ARTIFACT_SUPERVISOR" + ], + "description": "- `PLATFORM_IMAGE_ARTIFACT_BASE`: The machine's base image, every workspace's disk's floor.\n- `PLATFORM_IMAGE_ARTIFACT_SUPERVISOR`: The supervisor extension every workspace is handed.", + "x-enum-descriptions": [ + "", + "The machine's base image, every workspace's disk's floor.", + "The supervisor extension every workspace is handed." ] }, "spin.v1.PlatformImageState": { @@ -17450,6 +17506,16 @@ "PLATFORM_IMAGE_STATE_FAILED", "PLATFORM_IMAGE_STATE_UNAVAILABLE", "PLATFORM_IMAGE_STATE_FOREIGN" + ], + "description": "- `PLATFORM_IMAGE_STATE_UNAVAILABLE`: This build carries nothing to publish.\n- `PLATFORM_IMAGE_STATE_FOREIGN`: The ref names an image somebody else published, which is left as it is.", + "x-enum-descriptions": [ + "", + "", + "", + "", + "", + "This build carries nothing to publish.", + "The ref names an image somebody else published, which is left as it is." ] }, "spin.v1.PlatformLogFieldValuesRequest": { @@ -17518,7 +17584,13 @@ "PORT_ACCESS_WHITELIST", "PORT_ACCESS_PUBLIC" ], - "description": "Who may reach a published port.\n\n Per port rather than per workspace: one workspace serves a demo anyone may see and an\n admin panel only its owner may, and a single setting for both makes the safe answer for\n one the wrong answer for the other.\n\n UNSPECIFIED is not a level and is never stored - the column's CHECK excludes it. A\n request that leaves it at proto3's zero is treated as PRIVATE, which is the direction to\n be wrong in: the cost of failing closed is a confusing error, and the cost of failing\n open is a port somebody published without meaning to." + "description": "Who may reach a published port.\n\n Per port rather than per workspace: one workspace serves a demo anyone may see and an\n admin panel only its owner may, and a single setting for both makes the safe answer for\n one the wrong answer for the other.\n\n UNSPECIFIED is not a level and is never stored - the column's CHECK excludes it. A\n request that leaves it at proto3's zero is treated as PRIVATE, which is the direction to\n be wrong in: the cost of failing closed is a confusing error, and the cost of failing\n open is a port somebody published without meaning to.\n\n- `PORT_ACCESS_PRIVATE`: Only the workspace's owner, who must be signed in.\n- `PORT_ACCESS_WHITELIST`: The owner, and the users the owner granted. See GrantPortAccess.\n- `PORT_ACCESS_PUBLIC`: Anyone, with no session at all. Nothing is asked and nobody is redirected to a login.\n Until the workspace stops or fails: then the port is PRIVATE again, and made public again\n when it is meant to be.", + "x-enum-descriptions": [ + "", + "Only the workspace's owner, who must be signed in.", + "The owner, and the users the owner granted. See GrantPortAccess.", + "Anyone, with no session at all. Nothing is asked and nobody is redirected to a login.\n Until the workspace stops or fails: then the port is PRIVATE again, and made public again\n when it is meant to be." + ] }, "spin.v1.PortGrant": { "type": "object", @@ -17640,6 +17712,14 @@ "PREBUILD_STATE_READY", "PREBUILD_STATE_FAILED", "PREBUILD_STATE_RETIRED" + ], + "description": "- `PREBUILD_STATE_RETIRED`: Superseded and given back: its snapshot is being deleted.", + "x-enum-descriptions": [ + "", + "", + "", + "", + "Superseded and given back: its snapshot is being deleted." ] }, "spin.v1.PreemptionSource": { @@ -17968,7 +18048,13 @@ "REGISTRATION_MODE_WHITELIST", "REGISTRATION_MODE_CLOSED" ], - "description": "Registration mode enum" + "description": "Registration mode enum\n\n- `REGISTRATION_MODE_OPEN`: Anyone can register\n- `REGISTRATION_MODE_WHITELIST`: Only whitelisted emails/domains\n- `REGISTRATION_MODE_CLOSED`: No new registrations", + "x-enum-descriptions": [ + "", + "Anyone can register", + "Only whitelisted emails/domains", + "No new registrations" + ] }, "spin.v1.RegistrationToken": { "type": "object", @@ -18048,7 +18134,13 @@ "REKEY_STATE_COPYING", "REKEY_STATE_READY" ], - "description": "RekeyState is how far a disk's re-key is." + "description": "RekeyState is how far a disk's re-key is.\n\n- `REKEY_STATE_PENDING`: Marked by a revoke: re-keyed once its workspace cannot run.\n- `REKEY_STATE_COPYING`: A host is copying the disk.\n- `REKEY_STATE_READY`: Copied: the workspace is pointed at the copy and the disk deleted on the next pass.", + "x-enum-descriptions": [ + "", + "Marked by a revoke: re-keyed once its workspace cannot run.", + "A host is copying the disk.", + "Copied: the workspace is pointed at the copy and the disk deleted on the next pass." + ] }, "spin.v1.RekeyVolumeRequest": { "type": "object", @@ -19445,6 +19537,12 @@ "SIGNATURE_KIND_UNSPECIFIED", "SIGNATURE_KIND_KEYRING", "SIGNATURE_KIND_ROSTER" + ], + "description": "- `SIGNATURE_KIND_KEYRING`: A user's keyring: the keys that may sign for them (roster.Keyring). Signed with a key of the\n keyring before it; the first, and one started anew, with a key it lists.\n- `SIGNATURE_KIND_ROSTER`: A team's roster: its members, its owners and each member's keyring (roster.Roster). Signed by\n an owner the roster before it lists; the first, by an owner it lists.", + "x-enum-descriptions": [ + "", + "A user's keyring: the keys that may sign for them (roster.Keyring). Signed with a key of the\n keyring before it; the first, and one started anew, with a key it lists.", + "A team's roster: its members, its owners and each member's keyring (roster.Roster). Signed by\n an owner the roster before it lists; the first, by an owner it lists." ] }, "spin.v1.SignedDocument": { @@ -19541,7 +19639,13 @@ "SNAPSHOT_ACCESS_TYPE_SHARED", "SNAPSHOT_ACCESS_TYPE_PUBLIC" ], - "description": "Access type for snapshots" + "description": "Access type for snapshots\n\n- `SNAPSHOT_ACCESS_TYPE_OWNER`: Owner of the source workspace\n- `SNAPSHOT_ACCESS_TYPE_SHARED`: Explicitly shared with user\n- `SNAPSHOT_ACCESS_TYPE_PUBLIC`: Public snapshot", + "x-enum-descriptions": [ + "", + "Owner of the source workspace", + "Explicitly shared with user", + "Public snapshot" + ] }, "spin.v1.SnapshotShare": { "type": "object", @@ -19593,7 +19697,14 @@ "SNAPSHOT_STATE_FAILED", "SNAPSHOT_STATE_DELETING" ], - "description": "How far along a snapshot is. A snapshot is taken by the host serving the volume, so it\n exists before it is usable: CREATING is the window between asking for one and the host\n reporting the commit it published." + "description": "How far along a snapshot is. A snapshot is taken by the host serving the volume, so it\n exists before it is usable: CREATING is the window between asking for one and the host\n reporting the commit it published.\n\n- `SNAPSHOT_STATE_CREATING`: Requested; the host has not published a commit yet\n- `SNAPSHOT_STATE_PUBLISHED`: Usable: a workspace can be created from it", + "x-enum-descriptions": [ + "", + "Requested; the host has not published a commit yet", + "Usable: a workspace can be created from it", + "", + "" + ] }, "spin.v1.Span": { "type": "object", @@ -19819,6 +19930,15 @@ "STATUS_DISAGREEMENT_KIND_HOST_UNREACHABLE", "STATUS_DISAGREEMENT_KIND_VOLUME_REFUSING", "STATUS_DISAGREEMENT_KIND_UNHEALTHY" + ], + "description": "- `STATUS_DISAGREEMENT_KIND_SUPERVISOR_STALE`: The control plane says the workspace runs and the supervisor has gone quiet for longer\n than several heartbeat intervals.\n- `STATUS_DISAGREEMENT_KIND_SUPERVISOR_ABSENT`: The control plane says the workspace runs and no supervisor ever reported.\n- `STATUS_DISAGREEMENT_KIND_HOST_UNREACHABLE`: The host holding this workspace is not ACTIVE, or has stopped heartbeating.\n- `STATUS_DISAGREEMENT_KIND_VOLUME_REFUSING`: The volume under the workspace is refusing to serve.\n- `STATUS_DISAGREEMENT_KIND_UNHEALTHY`: The supervisor reports a failing health check.", + "x-enum-descriptions": [ + "", + "The control plane says the workspace runs and the supervisor has gone quiet for longer\n than several heartbeat intervals.", + "The control plane says the workspace runs and no supervisor ever reported.", + "The host holding this workspace is not ACTIVE, or has stopped heartbeating.", + "The volume under the workspace is refusing to serve.", + "The supervisor reports a failing health check." ] }, "spin.v1.StopWorkspaceRequest": { @@ -19999,6 +20119,15 @@ "STORED_VOLUME_KIND_EXTENSION", "STORED_VOLUME_KIND_UNCLAIMED", "STORED_VOLUME_KIND_ORPHAN" + ], + "description": "- `STORED_VOLUME_KIND_WORKSPACE`: A workspace's disk, now or before.\n- `STORED_VOLUME_KIND_IMAGE`: An image a workspace's disk is cloned from.\n- `STORED_VOLUME_KIND_EXTENSION`: A release of an extension: the supervisor, the VS Code servers.\n- `STORED_VOLUME_KIND_UNCLAIMED`: A volume the database has and nothing names: a clone being made, or a delete not finished.\n- `STORED_VOLUME_KIND_ORPHAN`: Objects under a volume the database does not have.", + "x-enum-descriptions": [ + "", + "A workspace's disk, now or before.", + "An image a workspace's disk is cloned from.", + "A release of an extension: the supervisor, the VS Code servers.", + "A volume the database has and nothing names: a clone being made, or a delete not finished.", + "Objects under a volume the database does not have." ] }, "spin.v1.SubmitSignatureRequest": { @@ -20325,7 +20454,13 @@ "TEAM_ROLE_ADMIN", "TEAM_ROLE_MEMBER" ], - "description": "Team member role enum" + "description": "Team member role enum\n\n- `TEAM_ROLE_OWNER`: Full control, can delete team\n- `TEAM_ROLE_ADMIN`: Can manage members and settings\n- `TEAM_ROLE_MEMBER`: Can create workspaces, view team resources", + "x-enum-descriptions": [ + "", + "Full control, can delete team", + "Can manage members and settings", + "Can create workspaces, view team resources" + ] }, "spin.v1.TeamSecret": { "type": "object", @@ -21244,6 +21379,14 @@ "VS_CODE_SERVER_PUBLISH_STATE_WORKING", "VS_CODE_SERVER_PUBLISH_STATE_PUBLISHED", "VS_CODE_SERVER_PUBLISH_STATE_FAILED" + ], + "description": "- `VS_CODE_SERVER_PUBLISH_STATE_IDLE`: Nothing published since this control plane started.", + "x-enum-descriptions": [ + "", + "Nothing published since this control plane started.", + "", + "", + "" ] }, "spin.v1.ValidateTaskfileRequest": { @@ -21667,7 +21810,17 @@ "WORKSPACE_ACTION_SUSPEND", "WORKSPACE_ACTION_START_FROM_DISK" ], - "description": "WorkspaceAction is an act a person can ask of a workspace." + "description": "WorkspaceAction is an act a person can ask of a workspace.\n\n- `WORKSPACE_ACTION_FORCE_STOP`: Stop without waiting for the guest: also what ends a stop that does not finish.\n- `WORKSPACE_ACTION_SUSPEND`: Put down with its memory, to be resumed where it was.\n- `WORKSPACE_ACTION_START_FROM_DISK`: Boot a suspended workspace from its disk, dropping its memory (StartWorkspaceRequest.from_disk):\n offered when that memory's machine is run by no host (Workspace.memory_machine_gone).", + "x-enum-descriptions": [ + "", + "", + "", + "Stop without waiting for the guest: also what ends a stop that does not finish.", + "", + "", + "Put down with its memory, to be resumed where it was.", + "Boot a suspended workspace from its disk, dropping its memory (StartWorkspaceRequest.from_disk):\n offered when that memory's machine is run by no host (Workspace.memory_machine_gone)." + ] }, "spin.v1.WorkspaceCost": { "type": "object", @@ -21837,6 +21990,32 @@ "WORKSPACE_EVENT_TYPE_SUSPENSION_DUE", "WORKSPACE_EVENT_TYPE_KEPT", "WORKSPACE_EVENT_TYPE_UNRESPONSIVE" + ], + "description": "- `WORKSPACE_EVENT_TYPE_CREATED`: Workspace was created\n- `WORKSPACE_EVENT_TYPE_STARTED`: Workspace was started\n- `WORKSPACE_EVENT_TYPE_STOPPED`: Workspace was stopped; its disk is kept, and no snapshot is taken\n- `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`: Manual snapshot\n- `WORKSPACE_EVENT_TYPE_DELETED`: Workspace was deleted\n- `WORKSPACE_EVENT_TYPE_FAILED`: Workspace start failed\n- `WORKSPACE_EVENT_TYPE_RESTORED`: Its disk was put back to a snapshot\n- `WORKSPACE_EVENT_TYPE_RESUMED`: It went on from a snapshot's memory\n- `WORKSPACE_EVENT_TYPE_BOOTED`: Suspended, its memory could not be resumed, and its disk was booted\n- `WORKSPACE_EVENT_TYPE_QUARANTINED`: An administrator held it: stopped, and startable by nobody until released\n- `WORKSPACE_EVENT_TYPE_UNQUARANTINED`: The hold was released: back to stopped, where it was held from\n- `WORKSPACE_EVENT_TYPE_PLACED`: A workspace that waited for a host was given one, and its disk there\n- `WORKSPACE_EVENT_TYPE_TRASHED`: Deleted into the trash: its disk kept, its owner able to undelete it\n- `WORKSPACE_EVENT_TYPE_UNDELETED`: Taken back out of the trash\n- `WORKSPACE_EVENT_TYPE_MOVED`: Suspended on its host and resumed on another, which had room for what it was granted\n- `WORKSPACE_EVENT_TYPE_DISPLACED`: Its host was drained or went away: suspended there, it is resumed on another on its own\n- `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`: A stop on a host that can be taken away could not publish its disk first, so it runs on\n- `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`: Nobody used it for as long as the installation allows: suspended with its processes, a start resumes them\n- `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`: It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them\n- `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`: A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it\n- `WORKSPACE_EVENT_TYPE_KEPT`: Somebody kept it awake until a time: no suspension before it\n- `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`: Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back", + "x-enum-descriptions": [ + "", + "Workspace was created", + "Workspace was started", + "Workspace was stopped; its disk is kept, and no snapshot is taken", + "Manual snapshot", + "Workspace was deleted", + "Workspace start failed", + "Its disk was put back to a snapshot", + "It went on from a snapshot's memory", + "Suspended, its memory could not be resumed, and its disk was booted", + "An administrator held it: stopped, and startable by nobody until released", + "The hold was released: back to stopped, where it was held from", + "A workspace that waited for a host was given one, and its disk there", + "Deleted into the trash: its disk kept, its owner able to undelete it", + "Taken back out of the trash", + "Suspended on its host and resumed on another, which had room for what it was granted", + "Its host was drained or went away: suspended there, it is resumed on another on its own", + "A stop on a host that can be taken away could not publish its disk first, so it runs on", + "Nobody used it for as long as the installation allows: suspended with its processes, a start resumes them", + "It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them", + "A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it", + "Somebody kept it awake until a time: no suspension before it", + "Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back" ] }, "spin.v1.WorkspaceFailure": { @@ -21857,7 +22036,22 @@ "WORKSPACE_FAILURE_NO_HOST", "WORKSPACE_FAILURE_MACHINE_CHANGED" ], - "description": "WorkspaceFailure is why a FAILED workspace failed: which part of its run, closed so what a\n person can do about it - and a failure rate split by the repair it needs - is decided by the\n kind rather than by the text of an error. The reason beside it is the detail.\n\n One enum for the client and the host's report (spin.agent.v1.ObservedWorkspace): the kind a\n person is shown is the one the host named, with no second list to keep in step." + "description": "WorkspaceFailure is why a FAILED workspace failed: which part of its run, closed so what a\n person can do about it - and a failure rate split by the repair it needs - is decided by the\n kind rather than by the text of an error. The reason beside it is the detail.\n\n One enum for the client and the host's report (spin.agent.v1.ObservedWorkspace): the kind a\n person is shown is the one the host named, with no second list to keep in step.\n\n- `WORKSPACE_FAILURE_UNSPECIFIED`: Not classified. A failure that lands here is a site missing its classification.\n- `WORKSPACE_FAILURE_VOLUME`: Its disk could not be served or made: the host is not serving its volume (its refusal says\n why), or what the disk was to be made from is gone.\n- `WORKSPACE_FAILURE_EXTENSION`: An extension could not be attached, or the releases it starts with could not be named.\n- `WORKSPACE_FAILURE_NETWORK`: The machine's network namespace or its tags could not be set up.\n- `WORKSPACE_FAILURE_RESOURCES`: The machine could not be given the cores or memory it was asked for.\n- `WORKSPACE_FAILURE_MACHINE`: QEMU could not be prepared or did not boot.\n- `WORKSPACE_FAILURE_GUEST`: The guest booted and did not take its identity or its own filesystem.\n- `WORKSPACE_FAILURE_RELEASE_GONE`: A resume needs an extension release that is no longer in the object store: the memory\n cannot be resumed anywhere, and the control plane boots the disk with the newest releases.\n- `WORKSPACE_FAILURE_EXITED`: The machine ended without being asked to: its guest powered off, or its QEMU crashed or was\n killed.\n- `WORKSPACE_FAILURE_STOP`: The machine could not be stopped or removed.\n- `WORKSPACE_FAILURE_TIMED_OUT`: Its host did not bring a start or a stop to an end before the deadline: unreachable, or its\n attempts outlasted it. The control plane's verdict (the stuck sweep), never a host's.\n- `WORKSPACE_FAILURE_NO_HOST`: No host could take it: none came with room while it waited, or its disk is only on a host\n that is not connected. The control plane's verdict, never a host's.\n- `WORKSPACE_FAILURE_MACHINE_CHANGED`: Its memory was taken on a machine no host of the installation runs now: the machine's\n contract moved (a release that changed it), or the processor did. The memory resumes nowhere;\n the workspace stays suspended, and booting it from its disk, which drops the memory, is its\n owner's to choose (StartWorkspaceRequest.from_disk).", + "x-enum-descriptions": [ + "Not classified. A failure that lands here is a site missing its classification.", + "Its disk could not be served or made: the host is not serving its volume (its refusal says\n why), or what the disk was to be made from is gone.", + "An extension could not be attached, or the releases it starts with could not be named.", + "The machine's network namespace or its tags could not be set up.", + "The machine could not be given the cores or memory it was asked for.", + "QEMU could not be prepared or did not boot.", + "The guest booted and did not take its identity or its own filesystem.", + "A resume needs an extension release that is no longer in the object store: the memory\n cannot be resumed anywhere, and the control plane boots the disk with the newest releases.", + "The machine ended without being asked to: its guest powered off, or its QEMU crashed or was\n killed.", + "The machine could not be stopped or removed.", + "Its host did not bring a start or a stop to an end before the deadline: unreachable, or its\n attempts outlasted it. The control plane's verdict (the stuck sweep), never a host's.", + "No host could take it: none came with room while it waited, or its disk is only on a host\n that is not connected. The control plane's verdict, never a host's.", + "Its memory was taken on a machine no host of the installation runs now: the machine's\n contract moved (a release that changed it), or the processor did. The memory resumes nowhere;\n the workspace stays suspended, and booting it from its disk, which drops the memory, is its\n owner's to choose (StartWorkspaceRequest.from_disk)." + ] }, "spin.v1.WorkspaceHostStatus": { "type": "object", @@ -21989,7 +22183,17 @@ "WORKSPACE_PHASE_GUEST", "WORKSPACE_PHASE_BACKUP" ], - "description": "WorkspacePhase is what a host is doing to bring a workspace up." + "description": "WorkspacePhase is what a host is doing to bring a workspace up.\n\n- `WORKSPACE_PHASE_DISK`: Waiting for its disk to be served on the host.\n- `WORKSPACE_PHASE_EXTENSIONS`: Holding the extension releases it runs with.\n- `WORKSPACE_PHASE_NETWORK`: Setting up its network.\n- `WORKSPACE_PHASE_MACHINE`: Booting its machine, or resuming it from a checkpoint.\n- `WORKSPACE_PHASE_FIRST_BOOT`: Its first boot of a disk another person's workspace was cloned from.\n- `WORKSPACE_PHASE_GUEST`: The machine is up and its workspace inside is starting.\n- `WORKSPACE_PHASE_BACKUP`: Stopping on a host that can be taken away: its disk is being published before the machine\n stops, the control plane's doing rather than the host's, and retried if it restarts.", + "x-enum-descriptions": [ + "", + "Waiting for its disk to be served on the host.", + "Holding the extension releases it runs with.", + "Setting up its network.", + "Booting its machine, or resuming it from a checkpoint.", + "Its first boot of a disk another person's workspace was cloned from.", + "The machine is up and its workspace inside is starting.", + "Stopping on a host that can be taken away: its disk is being published before the machine\n stops, the control plane's doing rather than the host's, and retried if it restarts." + ] }, "spin.v1.WorkspaceProgress": { "type": "object", @@ -22060,7 +22264,15 @@ "WORKSPACE_PROXY_STATUS_PORT_NOT_EXPOSED", "WORKSPACE_PROXY_STATUS_WAKING" ], - "description": "Proxy status for workspace access" + "description": "Proxy status for workspace access\n\n- `WORKSPACE_PROXY_STATUS_ACCESSIBLE`: Port exposed, workspace running\n- `WORKSPACE_PROXY_STATUS_NOT_RUNNING`: Return 503\n- `WORKSPACE_PROXY_STATUS_NOT_FOUND`: Return 404\n- `WORKSPACE_PROXY_STATUS_PORT_NOT_EXPOSED`: Return 403\n- `WORKSPACE_PROXY_STATUS_WAKING`: Not running, and woken for this caller (Workspace.wake_on_access): the proxy opens a session,\n which resumes it and waits a while, and shows a page that asks again while it is not up.", + "x-enum-descriptions": [ + "", + "Port exposed, workspace running", + "Return 503", + "Return 404", + "Return 403", + "Not running, and woken for this caller (Workspace.wake_on_access): the proxy opens a session,\n which resumes it and waits a while, and shows a page that asks again while it is not up." + ] }, "spin.v1.WorkspaceRuntime": { "type": "object", @@ -22113,7 +22325,19 @@ "WORKSPACE_STATE_WAITING", "WORKSPACE_STATE_QUARANTINED" ], - "description": "Workspace states" + "description": "WorkspaceState is where a workspace is in its life. Each value's comment is what the API's\n document says of it (buf.gen.openapi.yaml's with-enum-value-descriptions), and the website's\n table of states is generated from it: it is written for a person reading that table, in the\n site's words (a runner, the CLI's commands). Why a value is what it is goes in a comment\n apart, above the value's own, which the document does not carry.\n\n- `WORKSPACE_STATE_UNSPECIFIED`: Never a workspace's state: a client that reads it read a field nothing set.\n- `WORKSPACE_STATE_CREATING`: The workspace exists and has not run yet.\n- `WORKSPACE_STATE_STARTING`: A runner is preparing its disk and starting its machine.\n- `WORKSPACE_STATE_RUNNING`: Its machine is up.\n- `WORKSPACE_STATE_STOPPING`: Its machine is shutting down, and then what its disk wrote since its last commit is\n uploaded to the bucket. A stop stays here until the upload is done, and says why it is not;\n `spin workspace stop --force` does not wait for it.\n- `WORKSPACE_STATE_STOPPED`: Not running. Its disk is kept, and the next start boots from it.\n- `WORKSPACE_STATE_FAILED`: A start or a stop failed: `spin workspace status` says which part, and why. It stays so\n until it is started again.\n- `WORKSPACE_STATE_DELETED`: In the trash, with its disk, for the days the installation keeps it there\n (`workspace_trash_days`): `spin workspace undelete` brings it back, stopped. An installation\n that keeps no trash erases it at once.\n- `WORKSPACE_STATE_WAITING`: Wanted running, and no runner has room for it yet. On AWS, where runners scale to none, one\n is being started, and the workspace starts on it once it is up.\n- `WORKSPACE_STATE_QUARANTINED`: Held by an administrator with `spin workspace quarantine`: it cannot start until\n `spin workspace unquarantine` releases it, and its disk is kept as it was.", + "x-enum-descriptions": [ + "Never a workspace's state: a client that reads it read a field nothing set.", + "The workspace exists and has not run yet.", + "A runner is preparing its disk and starting its machine.", + "Its machine is up.", + "Its machine is shutting down, and then what its disk wrote since its last commit is\n uploaded to the bucket. A stop stays here until the upload is done, and says why it is not;\n `spin workspace stop --force` does not wait for it.", + "Not running. Its disk is kept, and the next start boots from it.", + "A start or a stop failed: `spin workspace status` says which part, and why. It stays so\n until it is started again.", + "In the trash, with its disk, for the days the installation keeps it there\n (`workspace_trash_days`): `spin workspace undelete` brings it back, stopped. An installation\n that keeps no trash erases it at once.", + "Wanted running, and no runner has room for it yet. On AWS, where runners scale to none, one\n is being started, and the workspace starts on it once it is up.", + "Held by an administrator with `spin workspace quarantine`: it cannot start until\n `spin workspace unquarantine` releases it, and its disk is kept as it was." + ] }, "spin.v1.WorkspaceSuspendFailure": { "type": "object", diff --git a/src/assets/shots/workspace.png b/src/assets/shots/workspace.png index a3f80da365cba55222352b594fb0c21445ee669a..f6c8782afd89a66f15ca8e1e66147c428e2c7229 100644 GIT binary patch literal 61490 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 literal 61236 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 z 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 KKizr!>c0RNswpD? diff --git a/src/assets/shots/workspaces.png b/src/assets/shots/workspaces.png index 120693001fdb07ecb570a2f1623d34a2692b1583..6c4c437082fd8ff290f0b6b76efcbfd4697947fb 100644 GIT binary patch delta 8221 zcmZ8`cT`j9)4wi@e0Nn?*98`7>nb23vQnf5)|Dc-kd5>fq)Q1=T7Zz;RllGTAS)K`%Kl{spM-aJ z7kCf-4x?_Z{DMgEZ*04_q=G%2*C*uByOu14 zpLiInQ%RzgW2SLWc4c06kCmoJElx79^>Mx1OC7iZ1);)7fqi9zKZiv6k4Vhm8-+w^ z1u2SjHV|N6wcv9VKK}VEGn3N1 z)jCp8Ic(k;-P@yOKr2f(eoF_oec98zNx8F$QNf1-Y>=Wv>d!CI27diUq$u@Rif1cx zRVaACDLd@T>BM;v-vkZit9tA=gSeH-z>RcONO<6GzCAtH5Z=1ruWaNPzq>OP(DV;_ zblaHDVeT;ju{aeR2?3d4@g=FQ`);--lMQ&Rrcq=!#fJYiLKRHf%Z50k;T?%FM^^lA zNtK3ylfd5-8`g;>M~>sLw=*kAfurzr`2_LiO1|JJ$hfp5#Hn0;V@#j%xG;$fsRCt8 zR0bAuetVv6Z*Zk>JFl`1j*cGXt7u#g#b^UYEO`fqVNEyf*g-HJt&@a4+*0wZ%r&`4 zLQ=8Rjk6kgMi0E#pJEb;NbmK}hqZ<GF{;vlMYHso z7S9!BLCubuK2;v821Pb=284Xy%td2AZi zN^gThhThrs$k)RPK_KBjD1su#cm@x*tR~#h1Ji=9s}YCb>)bURQ7*in^Sw z>_~gPO)CXbAn1spmi~Twf*HPXF(eb)R3i+u5AgzLypSxj&);%Ly^xiXsTx>sZ z;1Sf2U)gZbl$$M1r0(FU{K{*@t58VREqaApb)-cZw?RD5?cL`Oak6`6bp*fV3^8*4 zMU~OIkj%0S^>Skxs==#~WcyN&xt?VEY!5m!`OaK(647G|4lTC9sbwh06}+pvmo-of z7PiDrWWWKDOMd@NvOmO!8n>~vM77N}Z;amJa4DcE+Z?4oZ(8@zb?)E7KYT0-8t(yq zL>Q^G-PRY`NgQ>6#m{$?+W7AGc?XVY=xJ7mEI>9Mzlvt`Cl_2Syk)K)l$D1qjt#qM zd&9DHCq+JFDsuA&j9av!@1E;Pj2ds-s?s7$4UkE0*-nNAof9R6WB+|q_0Sj6wey4~ zq)K&4g2UKGYyV9k3x^If1*_#mDtc>w{dwC7RRlCr@LE2sg=qg|krRLLYpS`4Qo-Ac z)qj-vM~8WPQyxu7J3e!9%5lmvoaszq44wC_Ww?-fxo+BI zOF(vP5)|)^_E)$e2M(#cuf>C4gT5e zpUS4N+rw9h+c{!8>s0uUxBG+K^_DZK&{^cCx96MhxHoMqO5oLHFe=wge`As)qJ<~@ zRw9)R%8D-0-YQ`Npi%QpOBFR|TTB96qK}f*w}h@1aG$}qaK>cR?pC!1v~+zZik4nm57vz{o>6q^l07-5kk2w9l*o!OhWpkQP%@ zLn#*&)z+2Xu@YEd{_PgiKLp&raqhUNmMjHrexK@B_cL<95LuU=<$IuVR#>y3^(@cW zOA~+%*2)rX&5EoZqD_9B@|tKWCOQ6k#sZmS=@a;3@CtB8|H#oUPj;=(W_7;9A1-Uz z9URVdZ5{VI#De{1ZY4z-6u`-PSUUyxw6t@u%Gn9+LiQ>Hmn$t&ee6x}rsib^J8oq3 zot2(#$dL9UY^J+|Xd%_*iO};r-Ufd5NGv}295>rV^zt`g^iWLn{15Kq(f4n`>Ex1s zfIdP;ap@HE%O^Fb3MhMY3hwMUrW-VPvD~%?C7}yiFG?pN4kzUbYwr!19Ocl1|L8`G zcQORqd&xrd72K_h#E`nN(c$5iz>ldhycQvPlMQ&BQH0hO*mqL3QJxFUQ=-2jnYZf)CydIh_YPpi(^W2JjX<0n1YBd|IasRSF6!H~;MK z(ljVtot}l+ADxQ7r3S~P72wT$r=fgPzqEI@*tm^yV!o8KGwCkJR>hcXu=!z)=ylzw zav~i;jbLQM&Kzl%2o`yXKT&l7-HDO{N>?@Tlu+dBPKV4sK%=-v{(4hU;KouRl>g+< z^$%5-^DV-STVh8l8D91G{4IvB5%2vq@DZo{zU%^|CElC)__lM?kN(TK@sy_o(}^k$ z(nXb0xs~DC61mSYpMoZcS)!}0oWhe1GNezg2;&CU_u)0&pn|*GuX#|ps;wM+UKG%k zbb5-AoXS4|NJ~eBC?5F(AFABt?vNI>xGqn>6uZ+8soD65orE5K>S6XOZ3&cq@>%l? zH!4)wHJ@mEH!HGsM@P008S5!3V8)f7^#smDXuMrx3VW7J3TD$| z2=CU%AALs@9HcVEi#3$%V+U4Zc9Q*7hHeuCfN!N> zwX&EWb7>(2muhpEMQm`ZDRqkvR22tl-ucnJPK`kEr2LE;{j~6%8E+s2vhqwkUyB#M zGMZhIqBR}k7*r;RG%ke}2W5Gl#eOhZ{Yiwuw97Q@QJTdlhRJUVhzW2STF zYhi><4QhF_N@|n4OyTIsLmb@QWwBAy%?@uZXgq@Tp#@}r#X={*4!DTmeOIm>LBh&Y z3m?BdikpohcQ7LrsWQ{-S zbB%4-vL}?hj8K~;Ej6rvrng^!*p#`t5qW3N_Rvf`p+H4n|4~(WJE&tIf;5*-&yT~{ ze0Y#dj&zB<@3zE}H(g1|(zhisDNBVe0n{^XR;(~Zz@ofgUTtBZ>-{R%s>}+CT63TI2*Si;hdW}-7+uB)(aZ+dQ~Uwtvqy_FmBAs&Hq~t=xUKT(-1-ZcSIGU*W?~i6_O5`;$C(a?i|w4n*S!z zd%D-}#~%*c*IgeQE%#`qiwH*8i1t2TEL$mRm?&yb+WyUUSW6L+dkB^!7KtpXP-U9- z@5{0H-1IZ0I6x00nQs1T)m~Sj5W!3f#G&XTWJd?57Tk2!b7t|PsG@D`g1}llz>D{Z z=3C`*R2T2pD~kFPV+6g4)-nM?viTfhqHre_iH~2;O3{MFpJ<1{ST=1j7m5#3RFk!^JS$BYVE@V$6CA^qX%xo(O(Xl z>rD3_ALn;mnPE|Aih!mPi;=H{RzKSKqv4{DOxCXsNlX8~Q=5XD8L$VmWKJCj4mN~N zP-g4nbg>SPL$6p=ixHbBtPUBgSbeQ4>>Xpo`t+0*AO%gFuLx6Qq&DDJ2CQ}>D!S$P zrD^TA(F6K!_h+P5V1n07k*1I2B1`d9zmoc;B;_*T!Qw;Zoll(8vR>EGt)HkCPj2j9 zZL4V9=%@y7rOo71#WQKdxS)1UIb^Y^A@%|DRb}2Nx4r@;;TcO+hR#CB@R|HEEGN1( zi2r?}M-+Fko8t|*;}2T@hGW$QT>vgRxV09n$9gN${QIIp++2*G;M2*g3fz?(W67QR zq6&K78yXgUZ`K!bK`{>%Odeug?Te{iDM*S5U~jHK@{^A zjn~sOq&Rlzh>KDRs6)s8a<_=r5}Ps1`CTxVtE2Zlnn%;8?(f$vBcS`3ZhI}0>fHee zU4fV`IC$t?RF0$?%6AEIA~Fan=xqb;L1PYycEJ&my8w3(kr?SB{Q9A{Z^Q*W9qmdlB=9D0JUr1w@wOWG5!n6CP?_K2M8FwT7b2EO>(A{{Mv8b$OS z0lf6$EOmJq11KFSzxX>gyBw9D8K!OYJXoCPZ-KV>tSMHcB!4iqyA}u-4fWTXkt96=M zN;(|gWmpqK#EY_-%nzd ze1~B1{m~ud<-F@roJM7P(*Cof*8bqL!K%AMaNXGKcC~wcn;$UP|1Pw2LP?R(ZN`h) zlgdPS@08_862i8F}e(;z>De^1k@Q^TK$Q8t707KFzNyK!f%A`CzdGwf^^}G-o^&l zOEBY(d!~lagHwfdu5C`9=vK}C;Z5Xf>`gLi2waJMJ)q=O$J%SEIO1nkxX0)dowv2% zVF#EbGpgzOBju}HtEPLirba&in(oR+B~JI#{7Ho;C4`0ABVW8eBgp~e6r`nJo(7)B z4kk!xQg?!b`1nCN+VWfTl-wUgGIJjlxAM?Y#_M$TRzG)Y?cmkV00ymr3t7Z9K@ z_eIe-I&@~>@-CxN!I0#ba|t&c`{nFWn$lf;EoSA^Q6*s%ImIc|aF?o|+bHyVYhG?P zBz#oe2jogaqtnIum3!jQ~;6iU$9Ex z4f@cXJ)Mk{Svn<`Nxg3L*OU84TYEqDrb)FN>{agH_J=cX^Cd#!0AsVM+U6)@z<9NCA76$V%I*a z%VRpE)?Q|8p4qL;Q%q3;gd-HlVH#K2^LY0r{VpV4ZfzgdmoG9qj3l z&7M&@-TzO9ad>>^aLuSXHpD>n%7R$E-!MRnshlbomPx+j-&(Q*R;sUo=eP~-TsP8r7mX0Wi6H$gReV| zl~X5)5j!`71F%>3M}84l+M4KTs6gzcYc*Ggjckg0y2rV@_Jlm&fUPuN95~MjE@1tyCp=@q>VhgmUQ2Eo<0_Hl!+e zvChx6sJyJG1mIdb)CR0gzkH^Y;H3x({_94W4=UvxB8H`^8ybXdMD&wT9}pu5#J@%kG~HoqBlJf%TYXaQbYE@5YOwmbY(- zA?{HjOg0ek`Ockee_VLSYIIl1>;*2Y>A~QVA#BjNre{mPXb}nL-|C~|Wj&3T2VOud z5YwO~KFzu->~7+LMi0<@cYpHpdY}!Rx*LH!rD*&HxJjENJ(%4*EN;8nv!&S6{q!ZJ zCD3R2wZ@6-x;rRYWea1r;oI~ar=w7PEy|h}AK2MeY^8Xt#`3!6o*5sf-6MT>lY6zx4Aj5tfRY+`=5h1|7}u^3D(ljSH%NZ!~3DG z;TvxmGc6_SVu`~U(q0i$)2II}`*R<4G3Qj6JA+mj<=E(v4$^RH1Bzm_n9JMDP>%l{ zHp6<6H=x$Win@&nymCeTHZ-2ydLb!^RAWakbE}S7pTRgc?F2-Ic0RiC*pgK&v^bqw zhWBn8oO-8Ov2GYMtsgN2*he#xGPSau;&(rkRNU;eTgNvCQjhmHz}mOcD>aKJkf^G~ z%2)9Zye->gsdKrfaf%`%2$uCO-~X(E*F@j+1$K zYM#zLLM56@xVJ*wA@V)FTWNW?a~8#*M6XF-Hs!;DHMXO%AoD6`7Xw+5?Z12u^qW2i zYKmA`0*rgs$HHpNHU`yi8jWaOEt>faHP|%Sv{)*m7RFWgD6# zm5get*jC)?eod@_ZQN-h-8b zvxTrL=NcPrJ`=BGYwtEZn)i*1zH;sXI*z!x1S~;_N?XdVoNyRnW7Kg2YZ$xd3NpF~ zK=8+DWxVA_dhRD=uK%VjcLC@A*B$rY{5Asof#;Mq^oBV5BK z(%#sRO$kYQCUT>`lv|4mWAU-DTN!`nwqA&H25Hl(^a{whDieNLYr^S~6wXHPm#uWC zD!-Y!BJ_y$TH0iE!i<}h=+>UGb`pU2@OKI}@_Q*kRpwE)zh>a>G(;|pfAE+-=B;zTUN=j209>QBp zx*@zFsB2}5dzcBoPZ>_6NQ&%W^{4~nr>jzWfAc_nQ9_CWcW(@(A5;+m>B@;21E2D^ zCBM2qgYt5Kj)s}+a_W1P7OJ|>np~Eq{S@o+=8#5tMTybC+`QwjJ=x9b3=$Gdb z(=lfkrO~}k3!NyQTd4MlQ0;RWSSxMYouad!pH+t;mkQu6> zcqH>pge3&S%G0inlYAwz`*)8A$0#_%5L?f^hqEA>MBcyWGC_}ZKEF%o85q@VD_FBX zSoS9h!YSQ5F`X!h&xG;gb|YnPggFdk%x2#4KEk+ZCXn}Zoy{P>-h4i?wZy{UP+<`P zBRhG`C-{8pqA90doNLp&t=KV-X|+Z{m26dwQmLVA}lJJVO`Gs|AmSm5nP=>(CqLK*D3kzPWicT|HcA z=(ox)%kzW8WIjLZuYxnEj7$~ler)2mujiF$_=I`1p*t2nu( zsX8^*r>qma@L2^p_DRUtAU2l2W6 zQ^<2p_X1OvjHd~I!FuUadF-1zNh{i}Jk z2MM+VC-Y@`r*#%|0k!h3Ta#X71$h_5Z7k16)#G^lXO z*i5aenw3I&VeZ4|tT|B;0R)1vB3sOPd8B(bMq4~_=DRz{1Zb!J>^i*mJHzf_n~2T+ zui3`*P0OR+%k;SEBj==dE6KU9{@+N!qbwa#0#auSMXN&L_tHrvBB>Kcp&@qcYEMSY VkMEWK5`8&lZDD6#@yFdq{{us|OFaMp delta 8194 zcmY*;cU)81_OCPCk!yo%0hAI(5m4#~(%WzaQ5nF9fB^!dNH3v<03kV!j?x5_DlI6z zBOOACNN+)UC-l$~Y7)|4nBRM!_ugOG*=O&w*4}HM@AtdbF3#tR$>;m(P~^RZeat%M zUpnu{n(B#p>3d!L&KaY7SZ|wd4T#+1uV)_}J-YF*@K|c&`m-&o!j7{FZ5?#JzyAe0 z<~zT({1!X#^W`7^`F=6t^Ji~M^{WB?0)4deUmx@TeD6?Vh`6E~9EK-08|)5gvFayR z*z~aKi)A19s=t=p=Q|&|8qYX&>OZF*8W}!KSSsF?XufZu1Qq+~)TvW{mkw(+X5KhX z`8>hTRL$uE(wJGTiqG{7OX8;1*i-HrOf zcZ2ujRoudGvr!%^rtjr^!#?v~g{0Qa#!AHPZUYnN-c>QQ7948!FWxwDzS!?)W5bDT zH07MwOfCJ$R2er@2Vch_xc2_UhpAan`@6oL;PdXjz4yf>WcV5tPWIt3z|IDMoLHTdD}K|?(yfoyc>DqkJIlc8(&=x4#?0B za9HW86q)e$n%ZlqoJ1jZIqBW@GoK9;=cbR36PsKIGI4I3;pRews-4(P<$Ri$|D>J) zMmryX(K=K|h06(k-94ewrngsUh9?nuBWls!_GI|q~8lNB65;9xwfKGPtOY!d6 z*dzclS$o*)R4&>~BgH$Hkkje2tM?7jabh@wz+HS)U$K?v1dW`8+$&m!C6gkYspN@P z^*?f5M9$-tf@wJtc9?YfpZifUvpMg9pceis!a=dZ7FW5WYcS*Ciq_hO(b~(WjcH^q zwMoxOI-y(ffkY_%!-TRqNTWi#X-(eL26x4IT~M1F^?F7cq%)y_r7SF8NKzY*bZKnw ze&6qTt+T%Tlfmv^Z%Z_qrxl3rS%2{zU|l;-V)*O7F2Jyx`GugMuFC;gxAXzJD#Y8? zm9u0a5BSg41ncfI#FFB;yOKJXIrZ(__Xhfhtacomt-%zj;npVz=vzH%cWajf3;>i_ zsBN^cVw$@9F`0jSyMVn@pBKW%@qCu0n%<%t&@~D}(7&e)>6I|krMI;m0w-gLVbtR; z(%}IWDP|lwnROd|XYCNsGlyC4ha1Z;Y)~ncHWV_ws44_UAElb>nHzBOvLBuk3v-@2 zF2VPE+aL5K2ub({JaM$$JJiy_g${l#VT7sIGGbmnbf0a0ZuHn;j@8xcZSkJBPEG0< z?NZWf7Km`Xl|oLVy7?nJvrK1d^)?qAIlf!DV&)$3QK3y*wib)sy1ll+7NAXxAv*O{_oQ0U72NvE#4VXtla z@~*pz-_y9`y5cA^<%Lk_!_qpfo#NoyVs~pRT@UotQ8F{NGI8}vh?2ML$K1m zAvbHRyCpn2$lD1#8cU4bsQ>J?BM2OYCWd$boQQrr36t-~^W*ocTVk5R!pg|N1uoln z?89mhZPXmH$25TYkH;;biJ6mxLUHv5z@NC5a=u}$&Yd)i89Qtj@w>Uae@j|ARp^CT zwg1_(Rm35=k_R2OwQk9&^Ug<~Fy59_N&7gHZ}~2czuiI(98029CvIt9cbzJ1765AN zrMyS3SNMiGJb&8gymWNUQnG(jUsLC2ohzr zWXf%O`*ykj4%J-2_OHtz@-qFYJ#CPSJWu}+loq44Hw%SR6MGHs z+!fRA@9q0Xo;`Ky+nwzV1Nl|UO~sR8uj0Tc$;;<>tvw4_U*6BDw#%9){flQ3ew4=X zIPj@~nwpNJ-QHN=`1Z+3=VAEi3!=HTZdmTCcij>Q+mu*GJzA-ZnW)LhbjiOM<%`Gj zlF1g_UD@SGBmX836S$QXg?W1CefKV}56$fs8XmTSs)P(E7nGYe17f^cJWN9T(!C|3 zzDnH)W%pd~CE20%~B{>j`(gg6C#oxXY-9w0OFutne;ld9kEmA%qe!ci)15 zB-E(QO7SMWdUHZueAA7p=t*`Qx_Yla3-1+D*!{FT3$U|K&L2>kJuFD)9aNIoF3DGV$>iwC?l9lC-=-jIDDPy6wkz45V_#^I6wm z2{{9TeMxy|)KC5e6^_dBELpv>Unajkg#2@9>jF%@UrP#DeAP_8R{8%DAdmk59s&CN zL$6t0lD(EsGA}!+dwhJo07UQ=g)UNwRrl?ao*wU^SZftRyx>gz961t$7*X z4=6MmJTmhhxtoI;(r@vveo;$|f;aw#Ly>wwbdrBbXe4J{Q%+*)ypyNiA59YuMQt@U{|4cW9gRGiu z$M2TNfolD8EP0!9e3SX$=Weq}G?5oGQN5sp)qR4&k+Ha$s=1F?ney$5Ub9&d8*SXQm5~bs(pOX+Nh*wFjKq^{33=C;P&ck1V!V7h zB718qEx2?ZlXt^RdsQfQNdCQCy+Ve*)0UH#lezo<;TP!(JV*ZBZQ>vKXr=460hZk4 zni16ZTtX<%nKl%sn4yBi_l-pLjR>7{<+?53JEt*`i@Gk!R@<8{<3y{HExGXdTqP;#7io@1N_tls3bkKQbxefS8&f70Yk zG$ri5NNss1aBU(d1h}Gx3l1jmgEG`s7pe;3=1ZTW83?aSoujiEk3(rOm$NH#-qp;) znr5d_!ou^x(<3wO{6vI>%zI?D>;?0#XqVIqkvP#X=K8aB;<>Xpn-59x3Znm)6o!(6 z`lhA$UDeEDpuaUw4s2S6|1q7WYtyE|Sa;#6LY@X$Oekw3&xh}SP7uUWsMmN}geusI z@bhOTJI)b48@{i>d=%17+UR5 z!PXN(3Lv9nf&y;AbAALlg$DxBykV#GMR^$ii@p{wVL5fmcYyH#bJ94q=XWXLVo4@2 zc}x4zrO1x>f)wsBma-`AY9_HM({hj7di-{%`$gqHDUO@Y zS$WMM(hQuyuEtU}D77#F`Z#nHgI=FDQ--0d^JVCdd~OmJ?l^mJeJr3Sd0Rr7r?+>I59(Gv|OI$-`V0Ji@{zCuT7Q3C=+%%f`<)-`RirTO4s&#=47)& zwe`0L7Fsz_z|FTinZ zf))-mu@flAdQIlkLAAvNN z)3z~=wd;=sr|2U&DH#+R(qol-JOpbYu8{i4tz?lkSBD^n@D)LKmf>A_=VW zHBvo+gLjsS`;*kgi4S)STH9DQ4iHuMI$p~0+%3ApURbyWN7V(41CAOmLhr7oNQF9s z`i^rGyJ}5;TR^_k)3FQ01%A&<0DKMOq9;rwhM3g9?Mzs9kdWzW3+R4QL2Lz7ysA2o zoh^0o0x1dXb58Q*(H4J-@Mu53?%!qZE3SwN-?0{IT{y z#PY5WW?DBi#LnspN$;iW^g0Rba;R5gkOtK4@e2xZex0Fy9}ue$Ln101*PK~)WJp3m zD@{Fb787-{!xrz`TaEHOOel&5O?ujox&W@%2(?&Z_@W%QJe4AUn zR5sHTqtqO743BGmQjsTrvN|wg>aUghIOX7#n5d0gA?%p4Lrm~Ndv^;BBMQi(*c_Y; zvRxiH?mTi$<_>kB=cy#v^a|G4nIFUzjA;^RU6UoYaH7xQb&F7OXajWdN@1kN`nXKI zb=GdcI)0O{3GPWxbc+SVL@->_5mzJpkGCt0v*o*?gG?ufoOH1z~_vJ@@| z(C&XpanxIHBMgLafd%yzatJH7g3A`Z3Z_f7!MJ+O^3rV#-igLX&9yWcT@D*zOC{ls`-c#eo>>{H0}_Q{Oj^~9-qfM#D`-!|vh!fS>KV#E-6kTnZ z9cq4pbiQt}t9L5lB`cSbS}ere#f|s>!9S^hDS1s5RaF7MReYvSJ;^JXPBV!WCzKjr zu^{U%pE=>Kt-z_ja;&-{!?gpM@7C4^nGTFvRh1{%>sgxtn{;R$H-s*~>j(^fObzL| zeB#~M+E+f4Nu`1@b{mJb7)&ZcGP16c!Ztr<5pc!*g|b-ydV7XW!`P^86Gu~E+;4wp z>HMQ-3&T%0A$Ijk`Gh&-BA7$4d*G46C)%HJ zU_->p9;!S*7S4B)KNl9XqoW?ZIenpABBawe<$Xl#yE_D&3L}^_bv(Dzje*!X)JlB} z6Y-qE_J1>^&#S)R*S`VA?(EOz8&q#m>YrG6(K>(PyMHvm_-e8^p=-cyrBA=PPpo|} zFn&?|WNAAAH{&8n0S*=AP;*Ev<82{Yf3ne%u<*+;(CyZZHLl0YZEFSZeW02x%vZ0* z>bNEfv=&-0`R>N{#k&i_wthQ~8qQ2lQbKJ^gbOQ>f*ualyurvgSb`w|!Es%BukZ0} zyh2DkTy*>Kxove8?N7ED0=COChd*j_j=L;n*hi1=chxIg({Q(3`eZmi8n5?aA*MR} zqEjm{a$OF}T3k7t^q#+{*1tKu{r&aM(XHZV^{an{Cnq(xwrEfIEbjeCenY7gFr!ko~J~r5g#GwzTu^TJ2pm zre>a)OU9e?*qT(XJsf`HQS|s7|16R`2&3i=&`X3oqq<6!#q~608H+u~%+|2=cQjD^ zKl(I$>A}w?HAILU4$Gb}eFwcP@$u!2hZ8YFaQy?Op>^|KQ{$Re4y?yh$XgNOczJfz zFbX6m->`FV(H*=Q4_V1q?!7iza_?!A<_*gGXfn3cIc#NlHajDFw9mz2dgS?DA#ia% zND-s5viY)ZW2)9_pE0skUX%nM{BX(CVz#LvC;w${)u3$6_6Ok-rae>1-hBb}!&oFm zL@3Lz_d=ga&}rhAPELLJ=D+z&o-El6nWlzz=cU9I7lmwp70^A2LNwZs zoPxVDes3#Mwq8yd69$8X2LUAiL+ss{OBKy~b5Rs$v95}WvWt<$gGp*)b(F0SVF_u| zwNBn@5jcpDg?CbXVR3}*dOZx3H&)X(MLV?2hVI`2+Y--TW8$Ax`Y)`~)f!XQh`BNj zkkGFmnMFuEiw1=7-1_VgtLtlo^y#_-kO#iBo3u7OU%3wQ_YViCz1ZQk0IlJrht0d3 zE4LwzSM}79#{2Pk@*?xtKz0Q9Z7Mitz~}8sxi(vG67iIb=s7d^q}X%0(q*%0%_5)U;fd6YT81d8W*+Gdnm_bw`USZwkUXJ%6gX&Z{z-f-epKWP*O2DMg^I@dsI) z2(wpGK~r&&04mF}DaZjEywH)gz}mD<<(Etq-#gsrCW(hNz@?;XA)`jq#b&b!&R?+2 zrPk{4CWyIJtrvn27^ylMwfU-3yT$8D{*{r&~HDMU^TU(6hX z6>lY-6v@UzXgz{qbfc4+^w_-?Yu}ypY;aDrGGpQ`5nyk+Vo?4|+_K=Hwg0Uc>EQca z1?JjC_(`vs9K!`lsHr8PA&~8dQ*Ylyy%&9Q9cz;XgK(Zu1Kaqw`53&QD_iMtFbsevnTFhTYnD;1%YZv~y9np6#>$iUp zl>Cv<$SYsH@|E!X>kZ)iGe3`4@07IC7J08ZbzG3}u`~?OU;kDK-zTl$ki_DsH|Kdt zV_>^PfV#{L-jG-KMsF3T@QU;x<5Hmsa@9@FcMCh<=do0{E zDqs1QLl)}*dRjnHVP{IWvHHbeb}voIc7MxmIFfY0fBx!3HC1F>t19SSj4An3Rblq* zw_!rhL%?FXTHXQc`)JtPR9+i;*CQ;ew1p|)iC+bt@W8-HhOL!Hvr0H!Z=v-qr6K^Y zJtV+$jC-(E`&!C@V?W%Ut{vtyHHP%TXf~U8(O=WIJp@9H`d@GRp#L1(+#HtueXThA zc66V%;HN<1C%={)x+TaFoH_?l;g!#~R8IqD*h9uXpUNaY)Q!_+G%rOP{CZQaVU=OX zEfk9`xFY1;w*~iDH(37ud@wb`sXt&;_+i*MmtjUEfOmbK?d@1+Z z5K-{jbQyH%hv|rp>-a=69y+TF)U76M85MY!sAu>xBGAxT82~)gDpJZCXQ|mSMaJ$_ zA!o{oL=hXJpeS@N?(HQVb;V3O463syAYDI*u!GwTqx>MgmzFZ#cPde3imaEXg8dh{ z$J#`N2V;IgyjW=pk9q!L@@N}`QkfvAyUayY(#+7yjqwMF6xdAbEa?a-ei}M_N38zOw1A#@ElNc~8(275~uuBt?gMy<#Z* zNmTCQS6}a)U){UZ9Aavx6~y89;}#CgN~K`D0yhFC91bj5O+q9*XsT?wE#=QK zEmseyEAOLwQ~#;z}7XJ*xR)5bNTqZsv|jK#<>N zig`~psG+~zezAEi)y&c^NO@yguPi@X1x#ELT9Xzt?`ix@*yNR(GHrdy->7Qx6O;Jq z8Wcx}{i3?t!f}`*fA7E+^xN6onw_-t))0EM5IFnjtyLto0C8;MTr~aFx2vJs;~*Tp zHpU(?g#&Oi7Tb}b$6H~#dg5em!y2+(trKPf za@C@x<(99#T`5?VHh?w<+KleVz+?Y-U}o6{cf z5<_K{(fEv+v(ECYhJxK);@iS|%;fO;uZw)|l3VYeI`y;6$^B}0f$M7EgTw)c29JC6 ziTKWQ>oAWIJ>JED#CBA4@?Ei@{;#hOLX4wL1+BG4W+-0JN?-K;DA=49gtYxVYWGANw`%{WflmqmFntYDWqedHiSLC=h5JZLKz}0EL> zoI7w2QyoI<_d$nEbm&#s$x=KgiwIV6v9mTBL8a*${>Ke|(X_I+Jn?X%^<%-jWe(Q_ zENvK`%O7MoFEOHw#tO~IueJm1?njn^OCN5PM0eTO?J5CZ_;fTPsZG6Zr0;)sXAd~E z%UsZIC5IRU2PXzB{g}(Xty&)DYcrM&-EAXIF8onb^>XHD+?)SG@1O@rGNayOW+7mQU!oLUJ15)d3#HI8s4*5W=!K0?v@~1M?Oa@ktc2zhmqfbRWYc5-NG}D=@;`b ze#6ilbAweaLDrv>9pzgZo=+}CqF|$2#~6NXrtEU6+R32=dwfOG$Qv8QsHnczJmGY9 zR&s0nw(nEj|L^*usrMFd@D*MfZL;@Zcx>nSO4UCl^SEds-YvS`ZH@u&F_-Ih@1qN^ farz|se5Y;$F@ug5Sk1hiQxA>JjmrP~=j;CkK_y2~ diff --git a/src/content/docs/reference/api/types.md b/src/content/docs/reference/api/types.md index e81bfa9..6389790 100644 --- a/src/content/docs/reference/api/types.md +++ b/src/content/docs/reference/api/types.md @@ -45,7 +45,7 @@ Allowed email/domain entry ## AllowedEmailType -Allowed email type enum +Allowed email type enum - `ALLOWED_EMAIL_TYPE_EMAIL`: Exact email address match - `ALLOWED_EMAIL_TYPE_DOMAIN`: Domain suffix match (@domain.com) One of: `ALLOWED_EMAIL_TYPE_UNSPECIFIED`, `ALLOWED_EMAIL_TYPE_EMAIL`, `ALLOWED_EMAIL_TYPE_DOMAIN`. @@ -106,7 +106,7 @@ BrokeredRequest is one request the egress proxy read from the workspace's machin ## BurstMode -BurstMode is how a workspace of a preset may grow past what it starts with. +BurstMode is how a workspace of a preset may grow past what it starts with. - `BURST_MODE_FIXED`: FIXED starts at the preset's size and stays there. - `BURST_MODE_TO_PRESET`: TO_PRESET starts at the preset's burst floor and may grow to its size. - `BURST_MODE_TO_HOST`: TO_HOST starts at the preset's burst floor and may grow to everything its host has. One of: `BURST_MODE_UNSPECIFIED`, `BURST_MODE_FIXED`, `BURST_MODE_TO_PRESET`, `BURST_MODE_TO_HOST`. @@ -134,7 +134,7 @@ One thing the config file says differently from the installation. ## ConfigItemKind -What one item of the installation's config file is. +What one item of the installation's config file is. - `CONFIG_ITEM_KIND_SETTING`: A setting, by its key: registration_mode, default_network_tags, allowed_images... - `CONFIG_ITEM_KIND_EMAIL`: An address or domain registration admits, by itself. One of: `CONFIG_ITEM_KIND_UNSPECIFIED`, `CONFIG_ITEM_KIND_SETTING`, `CONFIG_ITEM_KIND_EMAIL`, `CONFIG_ITEM_KIND_PRESET`, `CONFIG_ITEM_KIND_POLICY`. @@ -151,6 +151,8 @@ DeletedWorkspace is a workspace in the trash. ## DeviceLoginStatus +- `DEVICE_LOGIN_STATUS_PENDING`: User hasn't completed login yet - `DEVICE_LOGIN_STATUS_COMPLETE`: Login complete, token available - `DEVICE_LOGIN_STATUS_EXPIRED`: Device code expired - `DEVICE_LOGIN_STATUS_DENIED`: User denied the request + One of: `DEVICE_LOGIN_STATUS_UNSPECIFIED`, `DEVICE_LOGIN_STATUS_PENDING`, `DEVICE_LOGIN_STATUS_COMPLETE`, `DEVICE_LOGIN_STATUS_EXPIRED`, `DEVICE_LOGIN_STATUS_DENIED`. ## DotfilesConfig @@ -218,6 +220,8 @@ FieldValue is one value a field has, and how many of a search's records have it. ## FileChangeKind +- `FILE_CHANGE_KIND_MODIFIED`: The same type on both sides, and a different content, mode, owner or symlink target. + One of: `FILE_CHANGE_KIND_UNSPECIFIED`, `FILE_CHANGE_KIND_ADDED`, `FILE_CHANGE_KIND_REMOVED`, `FILE_CHANGE_KIND_MODIFIED`, `FILE_CHANGE_KIND_TYPE_CHANGED`. ## FileState @@ -236,6 +240,8 @@ One of: `FILE_CHANGE_KIND_UNSPECIFIED`, `FILE_CHANGE_KIND_ADDED`, `FILE_CHANGE_K ## FileType +- `FILE_TYPE_OTHER`: A device, a FIFO or a socket. + One of: `FILE_TYPE_UNSPECIFIED`, `FILE_TYPE_REGULAR`, `FILE_TYPE_DIRECTORY`, `FILE_TYPE_SYMLINK`, `FILE_TYPE_OTHER`. ## FleetHostVersion @@ -565,7 +571,7 @@ ObservedDestination is one address the workspace was allowed to reach, with what ## OutsideShareState -OutsideShareState is how far a snapshot's share outside its team is. +OutsideShareState is how far a snapshot's share outside its team is. - `OUTSIDE_SHARE_STATE_UNSPECIFIED`: None: the snapshot was never shared outside its team, nor made public. - `OUTSIDE_SHARE_STATE_PREPARING`: A host is writing the keys a clone outside the team reads the snapshot with. - `OUTSIDE_SHARE_STATE_READY`: Somebody of another team can create a workspace from it. One of: `OUTSIDE_SHARE_STATE_UNSPECIFIED`, `OUTSIDE_SHARE_STATE_PREPARING`, `OUTSIDE_SHARE_STATE_READY`. @@ -618,15 +624,19 @@ PendingSignature is one document the caller is asked to sign. ## PlatformImageArtifact +- `PLATFORM_IMAGE_ARTIFACT_BASE`: The machine's base image, every workspace's disk's floor. - `PLATFORM_IMAGE_ARTIFACT_SUPERVISOR`: The supervisor extension every workspace is handed. + One of: `PLATFORM_IMAGE_ARTIFACT_UNSPECIFIED`, `PLATFORM_IMAGE_ARTIFACT_BASE`, `PLATFORM_IMAGE_ARTIFACT_SUPERVISOR`. ## PlatformImageState +- `PLATFORM_IMAGE_STATE_UNAVAILABLE`: This build carries nothing to publish. - `PLATFORM_IMAGE_STATE_FOREIGN`: The ref names an image somebody else published, which is left as it is. + One of: `PLATFORM_IMAGE_STATE_UNSPECIFIED`, `PLATFORM_IMAGE_STATE_PENDING`, `PLATFORM_IMAGE_STATE_PUBLISHED`, `PLATFORM_IMAGE_STATE_PUBLISHING`, `PLATFORM_IMAGE_STATE_FAILED`, `PLATFORM_IMAGE_STATE_UNAVAILABLE`, `PLATFORM_IMAGE_STATE_FOREIGN`. ## PortAccess -Who may reach a published port. Per port rather than per workspace: one workspace serves a demo anyone may see and an admin panel only its owner may, and a single setting for both makes the safe answer for one the wrong answer for the other. UNSPECIFIED is not a level and is never stored - the column's CHECK excludes it. A request that leaves it at proto3's zero is treated as PRIVATE, which is the direction to be wrong in: the cost of failing closed is a confusing error, and the cost of failing open is a port somebody published without meaning to. +Who may reach a published port. Per port rather than per workspace: one workspace serves a demo anyone may see and an admin panel only its owner may, and a single setting for both makes the safe answer for one the wrong answer for the other. UNSPECIFIED is not a level and is never stored - the column's CHECK excludes it. A request that leaves it at proto3's zero is treated as PRIVATE, which is the direction to be wrong in: the cost of failing closed is a confusing error, and the cost of failing open is a port somebody published without meaning to. - `PORT_ACCESS_PRIVATE`: Only the workspace's owner, who must be signed in. - `PORT_ACCESS_WHITELIST`: The owner, and the users the owner granted. See GrantPortAccess. - `PORT_ACCESS_PUBLIC`: Anyone, with no session at all. Nothing is asked and nobody is redirected to a login. Until the workspace stops or fails: then the port is PRIVATE again, and made public again when it is meant to be. One of: `PORT_ACCESS_UNSPECIFIED`, `PORT_ACCESS_PRIVATE`, `PORT_ACCESS_WHITELIST`, `PORT_ACCESS_PUBLIC`. @@ -664,6 +674,8 @@ A prebuild: one build of a project's ref at a commit, and the snapshot it left. ## PrebuildState +- `PREBUILD_STATE_RETIRED`: Superseded and given back: its snapshot is being deleted. + One of: `PREBUILD_STATE_UNSPECIFIED`, `PREBUILD_STATE_BUILDING`, `PREBUILD_STATE_READY`, `PREBUILD_STATE_FAILED`, `PREBUILD_STATE_RETIRED`. ## PreemptionSource @@ -727,7 +739,7 @@ RateLimitSettings configures API rate limiting ## RegistrationMode -Registration mode enum +Registration mode enum - `REGISTRATION_MODE_OPEN`: Anyone can register - `REGISTRATION_MODE_WHITELIST`: Only whitelisted emails/domains - `REGISTRATION_MODE_CLOSED`: No new registrations One of: `REGISTRATION_MODE_UNSPECIFIED`, `REGISTRATION_MODE_OPEN`, `REGISTRATION_MODE_WHITELIST`, `REGISTRATION_MODE_CLOSED`. @@ -749,7 +761,7 @@ One of: `REGISTRATION_MODE_UNSPECIFIED`, `REGISTRATION_MODE_OPEN`, `REGISTRATION ## RekeyState -RekeyState is how far a disk's re-key is. +RekeyState is how far a disk's re-key is. - `REKEY_STATE_PENDING`: Marked by a revoke: re-keyed once its workspace cannot run. - `REKEY_STATE_COPYING`: A host is copying the disk. - `REKEY_STATE_READY`: Copied: the workspace is pointed at the copy and the disk deleted on the next pass. One of: `REKEY_STATE_UNSPECIFIED`, `REKEY_STATE_PENDING`, `REKEY_STATE_COPYING`, `REKEY_STATE_READY`. @@ -871,6 +883,8 @@ ServiceHealth is one service over a window: the traces begun in it - what it was ## SignatureKind +- `SIGNATURE_KIND_KEYRING`: A user's keyring: the keys that may sign for them (roster.Keyring). Signed with a key of the keyring before it; the first, and one started anew, with a key it lists. - `SIGNATURE_KIND_ROSTER`: A team's roster: its members, its owners and each member's keyring (roster.Roster). Signed by an owner the roster before it lists; the first, by an owner it lists. + One of: `SIGNATURE_KIND_UNSPECIFIED`, `SIGNATURE_KIND_KEYRING`, `SIGNATURE_KIND_ROSTER`. ## SignedDocument @@ -901,7 +915,7 @@ A snapshot is a rotation of a workspace's volume, published as a commit. It has ## SnapshotAccessType -Access type for snapshots +Access type for snapshots - `SNAPSHOT_ACCESS_TYPE_OWNER`: Owner of the source workspace - `SNAPSHOT_ACCESS_TYPE_SHARED`: Explicitly shared with user - `SNAPSHOT_ACCESS_TYPE_PUBLIC`: Public snapshot One of: `SNAPSHOT_ACCESS_TYPE_UNSPECIFIED`, `SNAPSHOT_ACCESS_TYPE_OWNER`, `SNAPSHOT_ACCESS_TYPE_SHARED`, `SNAPSHOT_ACCESS_TYPE_PUBLIC`. @@ -921,7 +935,7 @@ A share record for a snapshot ## SnapshotState -How far along a snapshot is. A snapshot is taken by the host serving the volume, so it exists before it is usable: CREATING is the window between asking for one and the host reporting the commit it published. +How far along a snapshot is. A snapshot is taken by the host serving the volume, so it exists before it is usable: CREATING is the window between asking for one and the host reporting the commit it published. - `SNAPSHOT_STATE_CREATING`: Requested; the host has not published a commit yet - `SNAPSHOT_STATE_PUBLISHED`: Usable: a workspace can be created from it One of: `SNAPSHOT_STATE_UNSPECIFIED`, `SNAPSHOT_STATE_CREATING`, `SNAPSHOT_STATE_PUBLISHED`, `SNAPSHOT_STATE_FAILED`, `SNAPSHOT_STATE_DELETING`. @@ -952,6 +966,8 @@ Span is one operation of a trace, as OpenTelemetry names its parts. ## StatusDisagreementKind +- `STATUS_DISAGREEMENT_KIND_SUPERVISOR_STALE`: The control plane says the workspace runs and the supervisor has gone quiet for longer than several heartbeat intervals. - `STATUS_DISAGREEMENT_KIND_SUPERVISOR_ABSENT`: The control plane says the workspace runs and no supervisor ever reported. - `STATUS_DISAGREEMENT_KIND_HOST_UNREACHABLE`: The host holding this workspace is not ACTIVE, or has stopped heartbeating. - `STATUS_DISAGREEMENT_KIND_VOLUME_REFUSING`: The volume under the workspace is refusing to serve. - `STATUS_DISAGREEMENT_KIND_UNHEALTHY`: The supervisor reports a failing health check. + One of: `STATUS_DISAGREEMENT_KIND_UNSPECIFIED`, `STATUS_DISAGREEMENT_KIND_SUPERVISOR_STALE`, `STATUS_DISAGREEMENT_KIND_SUPERVISOR_ABSENT`, `STATUS_DISAGREEMENT_KIND_HOST_UNREACHABLE`, `STATUS_DISAGREEMENT_KIND_VOLUME_REFUSING`, `STATUS_DISAGREEMENT_KIND_UNHEALTHY`. ## StorageSettings @@ -996,6 +1012,8 @@ StoredVolume is one volume in the store: what is under volumes/<volume_id>/, ## StoredVolumeKind +- `STORED_VOLUME_KIND_WORKSPACE`: A workspace's disk, now or before. - `STORED_VOLUME_KIND_IMAGE`: An image a workspace's disk is cloned from. - `STORED_VOLUME_KIND_EXTENSION`: A release of an extension: the supervisor, the VS Code servers. - `STORED_VOLUME_KIND_UNCLAIMED`: A volume the database has and nothing names: a clone being made, or a delete not finished. - `STORED_VOLUME_KIND_ORPHAN`: Objects under a volume the database does not have. + One of: `STORED_VOLUME_KIND_UNSPECIFIED`, `STORED_VOLUME_KIND_WORKSPACE`, `STORED_VOLUME_KIND_IMAGE`, `STORED_VOLUME_KIND_EXTENSION`, `STORED_VOLUME_KIND_UNCLAIMED`, `STORED_VOLUME_KIND_ORPHAN`. ## SupervisorState @@ -1070,7 +1088,7 @@ What the supervisor inside the guest last reported. Absent (`connected` false wi ## TeamRole -Team member role enum +Team member role enum - `TEAM_ROLE_OWNER`: Full control, can delete team - `TEAM_ROLE_ADMIN`: Can manage members and settings - `TEAM_ROLE_MEMBER`: Can create workspaces, view team resources One of: `TEAM_ROLE_UNSPECIFIED`, `TEAM_ROLE_OWNER`, `TEAM_ROLE_ADMIN`, `TEAM_ROLE_MEMBER`. @@ -1131,6 +1149,8 @@ VSCodeServerPublish is this control plane's publish: the last one, or the one un ## VSCodeServerPublishState +- `VS_CODE_SERVER_PUBLISH_STATE_IDLE`: Nothing published since this control plane started. + One of: `VS_CODE_SERVER_PUBLISH_STATE_UNSPECIFIED`, `VS_CODE_SERVER_PUBLISH_STATE_IDLE`, `VS_CODE_SERVER_PUBLISH_STATE_WORKING`, `VS_CODE_SERVER_PUBLISH_STATE_PUBLISHED`, `VS_CODE_SERVER_PUBLISH_STATE_FAILED`. ## VolumeRekey @@ -1192,7 +1212,7 @@ VolumeRekey is a workspace's disk to re-key or being re-keyed. ## WorkspaceAction -WorkspaceAction is an act a person can ask of a workspace. +WorkspaceAction is an act a person can ask of a workspace. - `WORKSPACE_ACTION_FORCE_STOP`: Stop without waiting for the guest: also what ends a stop that does not finish. - `WORKSPACE_ACTION_SUSPEND`: Put down with its memory, to be resumed where it was. - `WORKSPACE_ACTION_START_FROM_DISK`: Boot a suspended workspace from its disk, dropping its memory (StartWorkspaceRequest.from_disk): offered when that memory's machine is run by no host (Workspace.memory_machine_gone). One of: `WORKSPACE_ACTION_UNSPECIFIED`, `WORKSPACE_ACTION_START`, `WORKSPACE_ACTION_STOP`, `WORKSPACE_ACTION_FORCE_STOP`, `WORKSPACE_ACTION_DELETE`, `WORKSPACE_ACTION_FORCE_DELETE`, `WORKSPACE_ACTION_SUSPEND`, `WORKSPACE_ACTION_START_FROM_DISK`. @@ -1240,11 +1260,13 @@ Timeline event for workspace state changes ## WorkspaceEventType +- `WORKSPACE_EVENT_TYPE_CREATED`: Workspace was created - `WORKSPACE_EVENT_TYPE_STARTED`: Workspace was started - `WORKSPACE_EVENT_TYPE_STOPPED`: Workspace was stopped; its disk is kept, and no snapshot is taken - `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`: Manual snapshot - `WORKSPACE_EVENT_TYPE_DELETED`: Workspace was deleted - `WORKSPACE_EVENT_TYPE_FAILED`: Workspace start failed - `WORKSPACE_EVENT_TYPE_RESTORED`: Its disk was put back to a snapshot - `WORKSPACE_EVENT_TYPE_RESUMED`: It went on from a snapshot's memory - `WORKSPACE_EVENT_TYPE_BOOTED`: Suspended, its memory could not be resumed, and its disk was booted - `WORKSPACE_EVENT_TYPE_QUARANTINED`: An administrator held it: stopped, and startable by nobody until released - `WORKSPACE_EVENT_TYPE_UNQUARANTINED`: The hold was released: back to stopped, where it was held from - `WORKSPACE_EVENT_TYPE_PLACED`: A workspace that waited for a host was given one, and its disk there - `WORKSPACE_EVENT_TYPE_TRASHED`: Deleted into the trash: its disk kept, its owner able to undelete it - `WORKSPACE_EVENT_TYPE_UNDELETED`: Taken back out of the trash - `WORKSPACE_EVENT_TYPE_MOVED`: Suspended on its host and resumed on another, which had room for what it was granted - `WORKSPACE_EVENT_TYPE_DISPLACED`: Its host was drained or went away: suspended there, it is resumed on another on its own - `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`: A stop on a host that can be taken away could not publish its disk first, so it runs on - `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`: Nobody used it for as long as the installation allows: suspended with its processes, a start resumes them - `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`: It ran at a stretch for as long as the installation allows: suspended with its processes, a start resumes them - `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`: A suspension is minutes away and the question was asked: its terminals, its page, the CLI; a keep answers it - `WORKSPACE_EVENT_TYPE_KEPT`: Somebody kept it awake until a time: no suspension before it - `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`: Its supervisor said nothing for longer than the control plane waits: stopped by force, and a start brings it back + One of: `WORKSPACE_EVENT_TYPE_UNSPECIFIED`, `WORKSPACE_EVENT_TYPE_CREATED`, `WORKSPACE_EVENT_TYPE_STARTED`, `WORKSPACE_EVENT_TYPE_STOPPED`, `WORKSPACE_EVENT_TYPE_SNAPSHOT_CREATED`, `WORKSPACE_EVENT_TYPE_DELETED`, `WORKSPACE_EVENT_TYPE_FAILED`, `WORKSPACE_EVENT_TYPE_RESTORED`, `WORKSPACE_EVENT_TYPE_RESUMED`, `WORKSPACE_EVENT_TYPE_BOOTED`, `WORKSPACE_EVENT_TYPE_QUARANTINED`, `WORKSPACE_EVENT_TYPE_UNQUARANTINED`, `WORKSPACE_EVENT_TYPE_PLACED`, `WORKSPACE_EVENT_TYPE_TRASHED`, `WORKSPACE_EVENT_TYPE_UNDELETED`, `WORKSPACE_EVENT_TYPE_MOVED`, `WORKSPACE_EVENT_TYPE_DISPLACED`, `WORKSPACE_EVENT_TYPE_STOP_BACKUP_FAILED`, `WORKSPACE_EVENT_TYPE_IDLE_SUSPENDED`, `WORKSPACE_EVENT_TYPE_RUNNING_CAP_SUSPENDED`, `WORKSPACE_EVENT_TYPE_SUSPENSION_DUE`, `WORKSPACE_EVENT_TYPE_KEPT`, `WORKSPACE_EVENT_TYPE_UNRESPONSIVE`. ## WorkspaceFailure -WorkspaceFailure is why a FAILED workspace failed: which part of its run, closed so what a person can do about it - and a failure rate split by the repair it needs - is decided by the kind rather than by the text of an error. The reason beside it is the detail. One enum for the client and the host's report (spin.agent.v1.ObservedWorkspace): the kind a person is shown is the one the host named, with no second list to keep in step. +WorkspaceFailure is why a FAILED workspace failed: which part of its run, closed so what a person can do about it - and a failure rate split by the repair it needs - is decided by the kind rather than by the text of an error. The reason beside it is the detail. One enum for the client and the host's report (spin.agent.v1.ObservedWorkspace): the kind a person is shown is the one the host named, with no second list to keep in step. - `WORKSPACE_FAILURE_UNSPECIFIED`: Not classified. A failure that lands here is a site missing its classification. - `WORKSPACE_FAILURE_VOLUME`: Its disk could not be served or made: the host is not serving its volume (its refusal says why), or what the disk was to be made from is gone. - `WORKSPACE_FAILURE_EXTENSION`: An extension could not be attached, or the releases it starts with could not be named. - `WORKSPACE_FAILURE_NETWORK`: The machine's network namespace or its tags could not be set up. - `WORKSPACE_FAILURE_RESOURCES`: The machine could not be given the cores or memory it was asked for. - `WORKSPACE_FAILURE_MACHINE`: QEMU could not be prepared or did not boot. - `WORKSPACE_FAILURE_GUEST`: The guest booted and did not take its identity or its own filesystem. - `WORKSPACE_FAILURE_RELEASE_GONE`: A resume needs an extension release that is no longer in the object store: the memory cannot be resumed anywhere, and the control plane boots the disk with the newest releases. - `WORKSPACE_FAILURE_EXITED`: The machine ended without being asked to: its guest powered off, or its QEMU crashed or was killed. - `WORKSPACE_FAILURE_STOP`: The machine could not be stopped or removed. - `WORKSPACE_FAILURE_TIMED_OUT`: Its host did not bring a start or a stop to an end before the deadline: unreachable, or its attempts outlasted it. The control plane's verdict (the stuck sweep), never a host's. - `WORKSPACE_FAILURE_NO_HOST`: No host could take it: none came with room while it waited, or its disk is only on a host that is not connected. The control plane's verdict, never a host's. - `WORKSPACE_FAILURE_MACHINE_CHANGED`: Its memory was taken on a machine no host of the installation runs now: the machine's contract moved (a release that changed it), or the processor did. The memory resumes nowhere; the workspace stays suspended, and booting it from its disk, which drops the memory, is its owner's to choose (StartWorkspaceRequest.from_disk). One of: `WORKSPACE_FAILURE_UNSPECIFIED`, `WORKSPACE_FAILURE_VOLUME`, `WORKSPACE_FAILURE_EXTENSION`, `WORKSPACE_FAILURE_NETWORK`, `WORKSPACE_FAILURE_RESOURCES`, `WORKSPACE_FAILURE_MACHINE`, `WORKSPACE_FAILURE_GUEST`, `WORKSPACE_FAILURE_RELEASE_GONE`, `WORKSPACE_FAILURE_EXITED`, `WORKSPACE_FAILURE_STOP`, `WORKSPACE_FAILURE_TIMED_OUT`, `WORKSPACE_FAILURE_NO_HOST`, `WORKSPACE_FAILURE_MACHINE_CHANGED`. @@ -1270,7 +1292,7 @@ WorkspaceLease is a process in the workspace keeping it awake while it lives. ## WorkspacePhase -WorkspacePhase is what a host is doing to bring a workspace up. +WorkspacePhase is what a host is doing to bring a workspace up. - `WORKSPACE_PHASE_DISK`: Waiting for its disk to be served on the host. - `WORKSPACE_PHASE_EXTENSIONS`: Holding the extension releases it runs with. - `WORKSPACE_PHASE_NETWORK`: Setting up its network. - `WORKSPACE_PHASE_MACHINE`: Booting its machine, or resuming it from a checkpoint. - `WORKSPACE_PHASE_FIRST_BOOT`: Its first boot of a disk another person's workspace was cloned from. - `WORKSPACE_PHASE_GUEST`: The machine is up and its workspace inside is starting. - `WORKSPACE_PHASE_BACKUP`: Stopping on a host that can be taken away: its disk is being published before the machine stops, the control plane's doing rather than the host's, and retried if it restarts. One of: `WORKSPACE_PHASE_UNSPECIFIED`, `WORKSPACE_PHASE_DISK`, `WORKSPACE_PHASE_EXTENSIONS`, `WORKSPACE_PHASE_NETWORK`, `WORKSPACE_PHASE_MACHINE`, `WORKSPACE_PHASE_FIRST_BOOT`, `WORKSPACE_PHASE_GUEST`, `WORKSPACE_PHASE_BACKUP`. @@ -1290,7 +1312,7 @@ WorkspaceProgress is a transition under way. ## WorkspaceProxyStatus -Proxy status for workspace access +Proxy status for workspace access - `WORKSPACE_PROXY_STATUS_ACCESSIBLE`: Port exposed, workspace running - `WORKSPACE_PROXY_STATUS_NOT_RUNNING`: Return 503 - `WORKSPACE_PROXY_STATUS_NOT_FOUND`: Return 404 - `WORKSPACE_PROXY_STATUS_PORT_NOT_EXPOSED`: Return 403 - `WORKSPACE_PROXY_STATUS_WAKING`: Not running, and woken for this caller (Workspace.wake_on_access): the proxy opens a session, which resumes it and waits a while, and shows a page that asks again while it is not up. One of: `WORKSPACE_PROXY_STATUS_UNSPECIFIED`, `WORKSPACE_PROXY_STATUS_ACCESSIBLE`, `WORKSPACE_PROXY_STATUS_NOT_RUNNING`, `WORKSPACE_PROXY_STATUS_NOT_FOUND`, `WORKSPACE_PROXY_STATUS_PORT_NOT_EXPOSED`, `WORKSPACE_PROXY_STATUS_WAKING`. @@ -1308,7 +1330,7 @@ WorkspaceRuntime is a running workspace's machine as its host measures it from o ## WorkspaceState -Workspace states +WorkspaceState is where a workspace is in its life. Each value's comment is what the API's document says of it (buf.gen.openapi.yaml's with-enum-value-descriptions), and the website's table of states is generated from it: it is written for a person reading that table, in the site's words (a runner, the CLI's commands). Why a value is what it is goes in a comment apart, above the value's own, which the document does not carry. - `WORKSPACE_STATE_UNSPECIFIED`: Never a workspace's state: a client that reads it read a field nothing set. - `WORKSPACE_STATE_CREATING`: The workspace exists and has not run yet. - `WORKSPACE_STATE_STARTING`: A runner is preparing its disk and starting its machine. - `WORKSPACE_STATE_RUNNING`: Its machine is up. - `WORKSPACE_STATE_STOPPING`: Its machine is shutting down, and then what its disk wrote since its last commit is uploaded to the bucket. A stop stays here until the upload is done, and says why it is not; `spin workspace stop --force` does not wait for it. - `WORKSPACE_STATE_STOPPED`: Not running. Its disk is kept, and the next start boots from it. - `WORKSPACE_STATE_FAILED`: A start or a stop failed: `spin workspace status` says which part, and why. It stays so until it is started again. - `WORKSPACE_STATE_DELETED`: In the trash, with its disk, for the days the installation keeps it there (`workspace_trash_days`): `spin workspace undelete` brings it back, stopped. An installation that keeps no trash erases it at once. - `WORKSPACE_STATE_WAITING`: Wanted running, and no runner has room for it yet. On AWS, where runners scale to none, one is being started, and the workspace starts on it once it is up. - `WORKSPACE_STATE_QUARANTINED`: Held by an administrator with `spin workspace quarantine`: it cannot start until `spin workspace unquarantine` releases it, and its disk is kept as it was. One of: `WORKSPACE_STATE_UNSPECIFIED`, `WORKSPACE_STATE_CREATING`, `WORKSPACE_STATE_STARTING`, `WORKSPACE_STATE_RUNNING`, `WORKSPACE_STATE_STOPPING`, `WORKSPACE_STATE_STOPPED`, `WORKSPACE_STATE_FAILED`, `WORKSPACE_STATE_DELETED`, `WORKSPACE_STATE_WAITING`, `WORKSPACE_STATE_QUARANTINED`. diff --git a/src/content/docs/reference/security/known-gaps.md b/src/content/docs/reference/security/known-gaps.md index 48d98c3..6ee538c 100644 --- a/src/content/docs/reference/security/known-gaps.md +++ b/src/content/docs/reference/security/known-gaps.md @@ -9,7 +9,7 @@ sidebar: -The open items of Spinbox's security model, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/docs/security/README.md) at `b3598142d`. The numbers are [its rules](/reference/security/rules/). +The open items of Spinbox's security model, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/docs/security/README.md) at `4534f6521`. The numbers are [its rules](/reference/security/rules/). What no line keeps yet. Each is a design change, not a patch, which is why it is here. diff --git a/src/content/docs/reference/security/rules.md b/src/content/docs/reference/security/rules.md index 2db656f..f1df9e6 100644 --- a/src/content/docs/reference/security/rules.md +++ b/src/content/docs/reference/security/rules.md @@ -9,7 +9,7 @@ sidebar: -The rules every entry point must keep, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/docs/security/README.md) at `b3598142d`. Code cites a rule's number at the line that keeps it. **Gate** is what fails a build when the rule is broken; *none* marks a rule kept only by each place remembering it. What is still open is on [Known gaps](/reference/security/known-gaps/). +The rules every entry point must keep, from spin's [`docs/security/README.md`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/docs/security/README.md) at `4534f6521`. Code cites a rule's number at the line that keeps it. **Gate** is what fails a build when the rule is broken; *none* marks a rule kept only by each place remembering it. What is still open is on [Known gaps](/reference/security/known-gaps/). | # | Rule | Gate | |---|---|---| diff --git a/src/content/docs/reference/status/index.md b/src/content/docs/reference/status/index.md index 045a2f6..235520d 100644 --- a/src/content/docs/reference/status/index.md +++ b/src/content/docs/reference/status/index.md @@ -9,7 +9,7 @@ sidebar: -Every row of this page is a line of `internal/features` in spin, and a test there resolves it against the tree. A row that says **built** names what shows the feature exists - a procedure the control plane serves, a command the CLI has, or a test - and, under **End to end**, the tests that drive a real runner and its guest and check what the feature did, or what no test checks yet. spin's build checks that each of those tests is there and not quarantined; whether it checks the whole feature is its review's. A row that says **not built** is an item of [`docs/ROADMAP.md`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/docs/ROADMAP.md). The page is written by `task reference` from `spin features` at spin `b3598142d`, and cannot say a feature the binary does not. +Every row of this page is a line of `internal/features` in spin, and a test there resolves it against the tree. A row that says **built** names what shows the feature exists - a procedure the control plane serves, a command the CLI has, or a test - and, under **End to end**, the tests that drive a real runner and its guest and check what the feature did, or what no test checks yet. spin's build checks that each of those tests is there and not quarantined; whether it checks the whole feature is its review's. A row that says **not built** is an item of [`docs/ROADMAP.md`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/docs/ROADMAP.md). The page is written by `task reference` from `spin features` at spin `4534f6521`, and cannot say a feature the binary does not. ## Built @@ -17,116 +17,116 @@ Every row of this page is a line of `internal/features` in spin, and a test ther | Feature | Exists | End to end | |---|---|---| -| A machine per workspace: KVM, its own kernel, root, a persistent disk, SSH | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vm_test.go#L167), a test of `internal/e2e` | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vm_test.go#L167) | -| Create, start, stop and delete | [`WorkspaceService/CreateWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_WorkspaceCRUD`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L397) | -| A trash: a deleted workspace stays whole, for its owner to undelete, until its days are up | [`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L379), a test of `internal/e2e` | [`TestATrashedWorkspaceIsWholeWhenItsOwnerUndeletesIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L411)
[`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L379) | -| Idle suspend, with a question before it that a keep answers | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L107), a test of `internal/e2e` | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L107) | -| A workspace that ran as long as the installation allows is suspended | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L69), a test of `internal/e2e` | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L69) | -| A process inside holds its workspace awake while it lives | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L190), a test of `internal/e2e` | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L190) | -| Suspend with the processes where they are; a start resumes them | [`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L35), a test of `internal/e2e` | [`TestE2E_ASuspendedWorkspaceResumesWhereItWas`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L160)
[`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L35) | -| Cores and memory lent while the host has them, and taken back | [`TestABusyWorkspaceIsLentCoresAndGivesThemBack`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L342), a test of `internal/e2e` | not yet: memory lent and taken back, and a loan refused while the host is full | -| A grant of cores and memory of its own, for a while | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L288), a test of `internal/e2e` | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/background_test.go#L288) | -| Move a running workspace to another host, its processes as they are | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/hosts_flows_test.go#L65), a test of `internal/e2e` | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/hosts_flows_test.go#L65) | -| Clone a workspace: its disk, team, project, size, policies and environment, in one | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/clone_test.go#L68), a test of `internal/e2e` | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/clone_test.go#L68) | -| Recover a workspace whose host is gone, at a cost its owner accepts | [`TestHostsAWorkspaceWhoseHostIsGoneIsRecoveredOnAnother`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/hosts_flows_test.go#L99), a test of `internal/e2e` | not yet: the cost asked of the owner before a recovery, and what was written after the snapshot gone | -| A workspace outlives its runner | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vm_test.go#L250), a test of `internal/e2e` | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vm_test.go#L250) | -| Quarantine, by an administrator | [`WorkspaceService/QuarantineWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L209) | -| Why a workspace is not behaving: status, console, history | [`spin workspace status`](/reference/cli/workspace/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L209)
[`TestE2E_AWorkspacesConsoleIsWhatItsMachinePrinted`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L243) | -| The owner's shell, environment, editor settings, Taskfile and dotfiles reach the guest | [`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/env_test.go#L23), a test of `internal/e2e` | [`TestTheOwnersSettingsArriveInTheGuest`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/env_test.go#L64)
[`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/env_test.go#L23) | -| Reset a disk to what it was created from | [`spin workspace reset`](/reference/cli/workspace/) | [`TestE2E_ResetPutsAWorkspaceBackToWhatItWasCreatedFrom`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L1182) | -| Claude Code and Codex on every workspace's PATH, at the versions the release pins, with their own defaults | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/agentclis_test.go#L20), a test of `internal/e2e` | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/agentclis_test.go#L20) | +| A machine per workspace: KVM, its own kernel, root, a persistent disk, SSH | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vm_test.go#L167), a test of `internal/e2e` | [`TestAWorkspaceBootsARealGuest`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vm_test.go#L167) | +| Create, start, stop and delete | [`WorkspaceService/CreateWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_WorkspaceCRUD`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L397) | +| A trash: a deleted workspace stays whole, for its owner to undelete, until its days are up | [`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L379), a test of `internal/e2e` | [`TestATrashedWorkspaceIsWholeWhenItsOwnerUndeletesIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L411)
[`TestAWorkspaceWhoseDaysInTheTrashAreUpIsErasedFromItsHost`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L379) | +| Idle suspend, with a question before it that a keep answers | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L107), a test of `internal/e2e` | [`TestAWorkspaceIsAskedBeforeItsSuspensionAndAKeepAnswersIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L107) | +| A workspace that ran as long as the installation allows is suspended | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L69), a test of `internal/e2e` | [`TestAWorkspaceThatRanForAsLongAsAllowedIsSuspended`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L69) | +| A process inside holds its workspace awake while it lives | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L190), a test of `internal/e2e` | [`TestAProcessHoldsItsWorkspaceAwakeWhileItLives`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L190) | +| Suspend with the processes where they are; a start resumes them | [`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L35), a test of `internal/e2e` | [`TestE2E_ASuspendedWorkspaceResumesWhereItWas`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L160)
[`TestAWorkspaceNobodyUsesIsSuspendedAndAStartResumesIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L35) | +| Cores and memory lent while the host has them, and taken back | [`TestABusyWorkspaceIsLentCoresAndGivesThemBack`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L342), a test of `internal/e2e` | not yet: memory lent and taken back, and a loan refused while the host is full | +| A grant of cores and memory of its own, for a while | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L288), a test of `internal/e2e` | [`TestAGrantWhoseTimeIsUpIsGivenBackToTheMachine`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/background_test.go#L288) | +| Move a running workspace to another host, its processes as they are | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/hosts_flows_test.go#L65), a test of `internal/e2e` | [`TestHostsAMoveTakesARunningWorkspaceToAnotherHost`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/hosts_flows_test.go#L65) | +| Clone a workspace: its disk, team, project, size, policies and environment, in one | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/clone_test.go#L68), a test of `internal/e2e` | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/clone_test.go#L68) | +| Recover a workspace whose host is gone, at a cost its owner accepts | [`TestHostsAWorkspaceWhoseHostIsGoneIsRecoveredOnAnother`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/hosts_flows_test.go#L99), a test of `internal/e2e` | not yet: the cost asked of the owner before a recovery, and what was written after the snapshot gone | +| A workspace outlives its runner | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vm_test.go#L250), a test of `internal/e2e` | [`TestAWorkspaceOutlivesItsRunner`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vm_test.go#L250) | +| Quarantine, by an administrator | [`WorkspaceService/QuarantineWorkspace`](/reference/api/workspaceservice/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L209) | +| Why a workspace is not behaving: status, console, history | [`spin workspace status`](/reference/cli/workspace/) | [`TestE2E_AQuarantinedWorkspaceIsHeldUntilReleased`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L209)
[`TestE2E_AWorkspacesConsoleIsWhatItsMachinePrinted`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L243) | +| The owner's shell, environment, editor settings, Taskfile and dotfiles reach the guest | [`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/env_test.go#L23), a test of `internal/e2e` | [`TestTheOwnersSettingsArriveInTheGuest`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/env_test.go#L64)
[`TestAWorkspacesOwnEnvironmentIsInItsOwnersLoginShell`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/env_test.go#L23) | +| Reset a disk to what it was created from | [`spin workspace reset`](/reference/cli/workspace/) | [`TestE2E_ResetPutsAWorkspaceBackToWhatItWasCreatedFrom`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L1182) | +| Claude Code and Codex on every workspace's PATH, at the versions the release pins, with their own defaults | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/agentclis_test.go#L20), a test of `internal/e2e` | [`TestTheAgentCLIsAreOnPathWithThePinnedVersions`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/agentclis_test.go#L20) | ### Teams and projects | Feature | Exists | End to end | |---|---|---| -| Open a repository, branch, commit or pull request from its URL, in the dashboard (/launch) and from the terminal
*From the terminal; the dashboard's /launch page makes the same create and has no test of its own against the stack.* | [`spin open --no-connect`](/reference/cli/open/) | [`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L97) | -| A workspace opened at a commit or a pull request, checked out as pr-<n> | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/project_test.go#L91), a test of `internal/e2e` | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/project_test.go#L91)
[`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L97) | -| Teams, with owner, admin and member | [`spin team member role`](/reference/cli/team/) | [`TestE2E_ATeamRoleIsWhatItsHolderMayDo`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L473) | -| A team's own identity providers | [`TeamService/CreateIdentityProvider`](/reference/api/teamservice/) | [`TestE2E_ATeamsIdentityProviderIsItsAdminsAndSignsNobodyIn`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L505) | +| Open a repository, branch, commit or pull request from its URL, in the dashboard (/launch) and from the terminal
*From the terminal; the dashboard's /launch page makes the same create and has no test of its own against the stack.* | [`spin open --no-connect`](/reference/cli/open/) | [`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L97) | +| A workspace opened at a commit or a pull request, checked out as pr-<n> | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/project_test.go#L91), a test of `internal/e2e` | [`TestAProjectsWorkspaceOpensAtTheCommitItWasAskedFor`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/project_test.go#L91)
[`TestE2E_AURLOpensTheWorkspaceItNames`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L97) | +| Teams, with owner, admin and member | [`spin team member role`](/reference/cli/team/) | [`TestE2E_ATeamRoleIsWhatItsHolderMayDo`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L473) | +| A team's own identity providers | [`TeamService/CreateIdentityProvider`](/reference/api/teamservice/) | [`TestE2E_ATeamsIdentityProviderIsItsAdminsAndSignsNobodyIn`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L505) | | A team's forge app: private repositories cloned and pushed with nothing on the disk | [`spin team forge set`](/reference/cli/team/) | not yet: a real GitHub App and a private repository for the lane to clone and push | -| A team's own network policies, where the installation allows them | [`spin team policy set`](/reference/cli/team/) | [`TestATeamsOwnPolicyIsWhatItsWorkspacesReach`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/team_policy_test.go#L24) | -| Projects: a repository and the shape of the workspace that opens it | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/project_test.go#L27), a test of `internal/e2e` | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/project_test.go#L27) | -| Prebuilds of a project's refs, as the floor of the workspaces that open them | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/prebuild_test.go#L29), a test of `internal/e2e` | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/prebuild_test.go#L29) | -| A team's workspaces run on the installation's hosts | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/team_test.go#L20), a test of `internal/e2e` | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/team_test.go#L20) | +| A team's own network policies, where the installation allows them | [`spin team policy set`](/reference/cli/team/) | [`TestATeamsOwnPolicyIsWhatItsWorkspacesReach`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/team_policy_test.go#L24) | +| Projects: a repository and the shape of the workspace that opens it | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/project_test.go#L27), a test of `internal/e2e` | [`TestAProjectsWorkspaceHasItsRepositoryCheckedOutAtTheRef`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/project_test.go#L27) | +| Prebuilds of a project's refs, as the floor of the workspaces that open them | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/prebuild_test.go#L29), a test of `internal/e2e` | [`TestAProjectOpensAsItsPrebuildMadeIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/prebuild_test.go#L29) | +| A team's workspaces run on the installation's hosts | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/team_test.go#L20), a test of `internal/e2e` | [`TestATeamsWorkspaceRunsOnTheInstallationsHost`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/team_test.go#L20) | ### Snapshots | Feature | Exists | End to end | |---|---|---| -| Snapshots of a running workspace's disk | [`WorkspaceService/CreateSnapshot`](/reference/api/workspaceservice/) | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/clone_test.go#L68)
[`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/compaction_test.go#L19) | -| Snapshots with memory, resumed with their processes | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/restore_test.go#L175), a test of `internal/e2e` | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/restore_test.go#L175) | -| Restore a workspace to a snapshot | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/restore_test.go#L29), a test of `internal/e2e` | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/restore_test.go#L29) | -| A diff of the files that changed between two snapshots | [`TestADiffOfTwoSnapshotsIsWhatChangedBetweenThem`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/diff_test.go#L28), a test of `internal/e2e` | [`TestADiffOfTwoSnapshotsNamesWhatWasAddedChangedAndRemoved`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/diff_test.go#L95) | -| Share a snapshot with a person or make it public, and create a workspace from it | [`TestACloneOfASnapshotRegistersAsItself`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/clone_test.go#L24), a test of `internal/e2e` | [`TestASharedSnapshotIsCreatedFromByThePersonItIsSharedWith`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/share_test.go#L22) | -| What looks like a credential is found before a share, and the share refused unless acknowledged | [`ShareService/ShareSnapshot`](/reference/api/shareservice/) | [`TestE2E_ASharedSnapshotIsScannedForCredentials`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L46) | -| A long chain is compacted while the workspace runs | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/compaction_test.go#L19), a test of `internal/e2e` | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/compaction_test.go#L19) | +| Snapshots of a running workspace's disk | [`WorkspaceService/CreateSnapshot`](/reference/api/workspaceservice/) | [`TestACloneHoldsWhatItsSourceWroteAndItsShape`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/clone_test.go#L68)
[`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/compaction_test.go#L19) | +| Snapshots with memory, resumed with their processes | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/restore_test.go#L175), a test of `internal/e2e` | [`TestARunningWorkspaceResumesFromASnapshotsMemory`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/restore_test.go#L175) | +| Restore a workspace to a snapshot | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/restore_test.go#L29), a test of `internal/e2e` | [`TestARestoredWorkspaceBootsOnTheSnapshotItWasRestoredTo`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/restore_test.go#L29) | +| A diff of the files that changed between two snapshots | [`TestADiffOfTwoSnapshotsIsWhatChangedBetweenThem`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/diff_test.go#L28), a test of `internal/e2e` | [`TestADiffOfTwoSnapshotsNamesWhatWasAddedChangedAndRemoved`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/diff_test.go#L95) | +| Share a snapshot with a person or make it public, and create a workspace from it | [`TestACloneOfASnapshotRegistersAsItself`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/clone_test.go#L24), a test of `internal/e2e` | [`TestASharedSnapshotIsCreatedFromByThePersonItIsSharedWith`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/share_test.go#L22) | +| What looks like a credential is found before a share, and the share refused unless acknowledged | [`ShareService/ShareSnapshot`](/reference/api/shareservice/) | [`TestE2E_ASharedSnapshotIsScannedForCredentials`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L46) | +| A long chain is compacted while the workspace runs | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/compaction_test.go#L19), a test of `internal/e2e` | [`TestADiskSnapshottedPastTheThresholdIsCompactedWhileItRuns`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/compaction_test.go#L19) | ### Network | Feature | Exists | End to end | |---|---|---| -| Egress is closed by default; policies, by tag, name what a workspace may reach | [`TestAnOwnerMayOnlyChooseAPolicyTheInstallationDeclares`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/retag_test.go#L163), a test of `internal/e2e` | [`TestAWorkspaceNamedNoPolicyReachesNothing`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/retag_test.go#L71)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/retag_test.go#L24) | -| A policy changed reaches the host that runs the workspace | [`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/retag_test.go#L24), a test of `internal/e2e` | [`TestAnEditedPolicyChangesWhatARunningGuestReaches`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/retag_test.go#L100)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/retag_test.go#L24) | +| Egress is closed by default; policies, by tag, name what a workspace may reach | [`TestAnOwnerMayOnlyChooseAPolicyTheInstallationDeclares`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/retag_test.go#L163), a test of `internal/e2e` | [`TestAWorkspaceNamedNoPolicyReachesNothing`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/retag_test.go#L71)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/retag_test.go#L24) | +| A policy changed reaches the host that runs the workspace | [`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/retag_test.go#L24), a test of `internal/e2e` | [`TestAnEditedPolicyChangesWhatARunningGuestReaches`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/retag_test.go#L100)
[`TestChangingAWorkspacesPoliciesReachesTheHostThatRunsIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/retag_test.go#L24) | | Brokered names: the host's proxy stands in and adds what the workspace never holds - a team secret, a forge token, its identity, a cloud role | [`spin team secret set`](/reference/cli/team/) | not yet: the forge, identity and cloud role injections, and the secret's value seen at the origin | -| A workspace trusts the egress root only by its owner's word | [`TestAGuestTrustsTheEgressRootOnlyByItsOwnersWord`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/egress_root_test.go#L20), a test of `internal/e2e` | [`TestAGuestTrustsTheEgressRootOnlyByItsOwnersWord`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/egress_root_test.go#L20) | -| What a workspace reached, what it looked up and what it was refused | [`spin workspace egress`](/reference/cli/workspace/) | [`TestE2E_EgressIsAnsweredByTheHostTheWorkspaceRunsOn`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L766) | -| Each request to a brokered name as the proxy read it, served or refused and why; and whether each injection's secret is the team's to give | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L28), a test of `internal/e2e` | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L28) | -| The egress proxy is a process of its own, holding no key of the host's, started again by the runner when it ends | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/egress_process_test.go#L21), a test of `internal/e2e` | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/egress_process_test.go#L21) | -| A brokered rule names whose it is, the agent's or the person's: one policy says what each may reach and with what | [`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L72), a test of `internal/e2e` | [`TestAPersonsRuleAndAnAgentsOnOneNameEachArriveWithTheirOwnInjection`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L100)
[`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L72) | -| A WebSocket to a brokered name: its handshake under the rule's headers and scope, then bytes each way
*The rule's header on the handshake is not read at the origin: the lane's WebSocket echo answers frames, not headers.* | [`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L168), a test of `internal/e2e` | [`TestAWebSocketToABrokeredNameCarriesTheGuestsBytesAndRefusesAPathOutOfScope`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L196)
[`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L168) | -| HTTP/2 to a brokered name, the proxy's ALPN the real host's: a rule's headers set stream by stream, gRPC's trailers both ways | [`TestHTTP2ToABrokeredNameIsTheRealHosts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L231), a test of `internal/e2e` | not yet: headers on several streams and gRPC's trailers, which need an h2 origin that echoes them | -| Watch where a workspace connects, into its logs | [`spin workspace watch`](/reference/cli/workspace/) | [`TestE2E_AWatchedWorkspacesConnectionsAreInItsLogs`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L264) | -| An agent the supervisor starts is marked, and reaches only brokered names | [`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/seal_test.go#L21), a test of `internal/e2e` | [`TestAnAgentReachesOnlyBrokeredNames`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/brokered_test.go#L138)
[`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/seal_test.go#L21) | -| Published ports at https://{port}-{workspace}.{domain}: private, whitelisted or public | [`spin port expose`](/reference/cli/port/) | [`TestAPublicPortIsReachedWithNoSessionAtAll`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/proxy/lane_test.go#L144)
[`workspace-sign-in.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/workspace-sign-in.spec.ts#L31): a visitor signed in to the dashboard reaches their private port | +| A workspace trusts the egress root only by its owner's word | [`TestAGuestTrustsTheEgressRootOnlyByItsOwnersWord`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/egress_root_test.go#L20), a test of `internal/e2e` | [`TestAGuestTrustsTheEgressRootOnlyByItsOwnersWord`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/egress_root_test.go#L20) | +| What a workspace reached, what it looked up and what it was refused | [`spin workspace egress`](/reference/cli/workspace/) | [`TestE2E_EgressIsAnsweredByTheHostTheWorkspaceRunsOn`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L766) | +| Each request to a brokered name as the proxy read it, served or refused and why; and whether each injection's secret is the team's to give | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L28), a test of `internal/e2e` | [`TestABrokeredRequestIsSeenAsTheProxyReadIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L28) | +| The egress proxy is a process of its own, holding no key of the host's, started again by the runner when it ends | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/egress_process_test.go#L21), a test of `internal/e2e` | [`TestTheEgressProxyIsAProcessOfItsOwnThatTheRunnerStartsAgain`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/egress_process_test.go#L21) | +| A brokered rule names whose it is, the agent's or the person's: one policy says what each may reach and with what | [`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L72), a test of `internal/e2e` | [`TestAPersonsRuleAndAnAgentsOnOneNameEachArriveWithTheirOwnInjection`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L100)
[`TestABrokeredNameForTheAgentIsTheAgentsAlone`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L72) | +| A WebSocket to a brokered name: its handshake under the rule's headers and scope, then bytes each way
*The rule's header on the handshake is not read at the origin: the lane's WebSocket echo answers frames, not headers.* | [`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L168), a test of `internal/e2e` | [`TestAWebSocketToABrokeredNameCarriesTheGuestsBytesAndRefusesAPathOutOfScope`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L196)
[`TestAWebSocketToABrokeredNameIsCarriedAfterItsHandshake`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L168) | +| HTTP/2 to a brokered name, the proxy's ALPN the real host's: a rule's headers set stream by stream, gRPC's trailers both ways | [`TestHTTP2ToABrokeredNameIsTheRealHosts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L231), a test of `internal/e2e` | not yet: headers on several streams and gRPC's trailers, which need an h2 origin that echoes them | +| Watch where a workspace connects, into its logs | [`spin workspace watch`](/reference/cli/workspace/) | [`TestE2E_AWatchedWorkspacesConnectionsAreInItsLogs`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L264) | +| An agent the supervisor starts is marked, and reaches only brokered names | [`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/seal_test.go#L21), a test of `internal/e2e` | [`TestAnAgentReachesOnlyBrokeredNames`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/brokered_test.go#L138)
[`TestARealWorkspaceMarksTheAgentItsSupervisorStarts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/seal_test.go#L21) | +| Published ports at https://{port}-{workspace}.{domain}: private, whitelisted or public | [`spin port expose`](/reference/cli/port/) | [`TestAPublicPortIsReachedWithNoSessionAtAll`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/proxy/lane_test.go#L144)
[`workspace-sign-in.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/workspace-sign-in.spec.ts#L31): a visitor signed in to the dashboard reaches their private port | ### Access | Feature | Exists | End to end | |---|---|---| | Sign in with GitHub or an OIDC provider | [`AuthService/StartLogin`](/reference/api/authservice/) | not yet: a GitHub provider: the sign-in through it and the verified email it gives | -| Device login for a terminal | [`AuthService/StartDeviceLogin`](/reference/api/authservice/) | [`TestE2E_Logout`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L1169)
[`auth.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/auth.spec.ts#L19): the CLI's device page stands alone and keeps its code through a sign-in | -| API keys for scripts and agents | [`spin api-key create`](/reference/cli/api-key/) | [`TestE2E_APIKeyCRUD`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L1124) | -| SSH keys, and plain ssh to spin.<workspace> | [`spin ssh-config`](/reference/cli/ssh-config/) | [`TestE2E_SSHConfigCarriesSSHToAWorkspace`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L637) | -| Who logs in to a workspace is what its owner signed | [`TestOnlyThePeopleTheAccessNamesLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/login_test.go#L259), a test of `internal/e2e` | [`TestOnlyThePeopleTheAccessNamesLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/login_test.go#L259) | -| Guests of a workspace, invited by its owner | [`spin workspace guests`](/reference/cli/workspace/) | [`TestOnlyThePeopleTheAccessNamesLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/login_test.go#L259) | -| A workspace's identity, signed by its host, for the audiences its owner allows | [`TestAWorkspacesIdentityIsTheHostsSignatureOfWhatItsOwnerSigned`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/identity_test.go#L60), a test of `internal/e2e` | [`TestAWorkspacesIdentityIsTheHostsSignatureOfWhatItsOwnerSigned`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/identity_test.go#L60) | -| VS Code over SSH, with the server the installation publishes and nothing downloaded
*spin code itself is run by its unit tests only: it opens VS Code desktop, which no lane has.* | [`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vscodehotplug_test.go#L23), a test of `internal/e2e` | [`TestTheCarriedVSCodeServerRunsOfflineAndAnswersOverTheSSHTunnel`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vscodeserver_test.go#L86)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vscodehotplug_test.go#L23) | -| Run a command in a workspace, copy files to and from it | [`spin exec`](/reference/cli/exec/) | [`TestE2E_ADetachedRunIsFollowedToItsEndAndFilesGoBothWays`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L178) | +| Device login for a terminal | [`AuthService/StartDeviceLogin`](/reference/api/authservice/) | [`TestE2E_Logout`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L1169)
[`auth.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/auth.spec.ts#L19): the CLI's device page stands alone and keeps its code through a sign-in | +| API keys for scripts and agents | [`spin api-key create`](/reference/cli/api-key/) | [`TestE2E_APIKeyCRUD`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L1124) | +| SSH keys, and plain ssh to spin.<workspace> | [`spin ssh-config`](/reference/cli/ssh-config/) | [`TestE2E_SSHConfigCarriesSSHToAWorkspace`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L637) | +| Who logs in to a workspace is what its owner signed | [`TestOnlyThePeopleTheAccessNamesLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/login_test.go#L259), a test of `internal/e2e` | [`TestOnlyThePeopleTheAccessNamesLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/login_test.go#L259) | +| Guests of a workspace, invited by its owner | [`spin workspace guests`](/reference/cli/workspace/) | [`TestOnlyThePeopleTheAccessNamesLogInToAWorkspace`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/login_test.go#L259) | +| A workspace's identity, signed by its host, for the audiences its owner allows | [`TestAWorkspacesIdentityIsTheHostsSignatureOfWhatItsOwnerSigned`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/identity_test.go#L60), a test of `internal/e2e` | [`TestAWorkspacesIdentityIsTheHostsSignatureOfWhatItsOwnerSigned`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/identity_test.go#L60) | +| VS Code over SSH, with the server the installation publishes and nothing downloaded
*spin code itself is run by its unit tests only: it opens VS Code desktop, which no lane has.* | [`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vscodehotplug_test.go#L23), a test of `internal/e2e` | [`TestTheCarriedVSCodeServerRunsOfflineAndAnswersOverTheSSHTunnel`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vscodeserver_test.go#L86)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vscodehotplug_test.go#L23) | +| Run a command in a workspace, copy files to and from it | [`spin exec`](/reference/cli/exec/) | [`TestE2E_ADetachedRunIsFollowedToItsEndAndFilesGoBothWays`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L178) | ### Administration | Feature | Exists | End to end | |---|---|---| | Installation settings seeded from a file; a change in the file is a proposal to apply or dismiss | [`AdminService/DecideConfigChange`](/reference/api/adminservice/) | not yet: the real file read, an apply and its effect, and a dismiss kept when the file is read again | -| Resource presets | [`AdminService/CreateResourcePreset`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/admin.spec.ts#L422): an admin's preset sizes a person's workspace, and is gone once deleted | -| Registration: open, by allowlist, or closed | [`AdminService/SetRegistrationMode`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/admin.spec.ts#L216): closed, open and a domain on the allowlist decide who registers
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/admin.spec.ts#L146): the allowlist lets in who it names, and nobody else | -| An audit log | [`AdminService/ListAuditLog`](/reference/api/adminservice/) | [`TestE2E_AnAdministratorsActionIsAuditedWithItsActorAndTarget`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L580)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/admin.spec.ts#L895): admin reads the log and can narrow it to one kind of event | -| The control plane's jobs, and running one now | [`spin admin jobs`](/reference/cli/admin/) | [`TestACarryResumesASuspendedWorkspaceAndStopsIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/carry_test.go#L21)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/admin.spec.ts#L705): admin runs a job by hand and sees how it ended | +| Resource presets | [`AdminService/CreateResourcePreset`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/admin.spec.ts#L422): an admin's preset sizes a person's workspace, and is gone once deleted | +| Registration: open, by allowlist, or closed | [`AdminService/SetRegistrationMode`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/admin.spec.ts#L216): closed, open and a domain on the allowlist decide who registers
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/admin.spec.ts#L146): the allowlist lets in who it names, and nobody else | +| An audit log | [`AdminService/ListAuditLog`](/reference/api/adminservice/) | [`TestE2E_AnAdministratorsActionIsAuditedWithItsActorAndTarget`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L580)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/admin.spec.ts#L895): admin reads the log and can narrow it to one kind of event | +| The control plane's jobs, and running one now | [`spin admin jobs`](/reference/cli/admin/) | [`TestACarryResumesASuspendedWorkspaceAndStopsIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/carry_test.go#L21)
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/admin.spec.ts#L705): admin runs a job by hand and sees how it ended | | The month's bill, its forecast, and what each workspace cost | [`spin admin costs`](/reference/cli/admin/) | not yet: the cloud's real bill read: no lane has an AWS account, so the bill a test gives the reader stands in for it | -| The store: every volume, whose it is, and taking out what nothing needs | [`spin admin storage list`](/reference/cli/admin/) | [`TestAVolumeNothingNeedsIsTakenOutOfTheStore`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/orphan_test.go#L26) | -| Re-key a workspace's disk | [`spin admin volume rekey`](/reference/cli/admin/) | [`TestARekeyedDiskBootsWithWhatItHeldUnderANewKey`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/rekey_test.go#L24) | +| The store: every volume, whose it is, and taking out what nothing needs | [`spin admin storage list`](/reference/cli/admin/) | [`TestAVolumeNothingNeedsIsTakenOutOfTheStore`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/orphan_test.go#L26) | +| Re-key a workspace's disk | [`spin admin volume rekey`](/reference/cli/admin/) | [`TestARekeyedDiskBootsWithWhatItHeldUnderANewKey`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/rekey_test.go#L24) | | Runners: registration tokens, drain, activate, revoke, and a policy per host | [`spin admin runner drain`](/reference/cli/admin/) | not yet: a runner registered with a token the API made, an expired or revoked token refused, and a revoke carried out | | Runners start when a workspace waits for one and stop when nothing runs | [`HostService/GetFleet`](/reference/api/hostservice/) | not yet: an autoscaling group to start and stop: the one group is AWS's, and no lane has an account | -| A host that reboots brings its workspaces back | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/restart_test.go#L38), a test of `internal/e2e` | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/restart_test.go#L38) | -| A cloud's reclaim warning empties the host before the machine goes | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/preemption_test.go#L26), a test of `internal/e2e` | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/preemption_test.go#L26) | -| A writeback bound per host, measured on that host before it is taken | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/writeback_test.go#L28), a test of `internal/e2e` | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/writeback_test.go#L28) | -| What is running where: the control plane, each runner and its machine | [`spin admin versions`](/reference/cli/admin/) | [`TestE2E_Admin`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L1026) | +| A host that reboots brings its workspaces back | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/restart_test.go#L38), a test of `internal/e2e` | [`TestAHostRebootBringsItsWorkspacesBack`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/restart_test.go#L38) | +| A cloud's reclaim warning empties the host before the machine goes | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/preemption_test.go#L26), a test of `internal/e2e` | [`TestACloudsReclaimWarningEmptiesTheHostBeforeAnySignal`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/preemption_test.go#L26) | +| A writeback bound per host, measured on that host before it is taken | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/writeback_test.go#L28), a test of `internal/e2e` | [`TestCustomWritebackValuesAreMeasuredOnTheRunner`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/writeback_test.go#L28) | +| What is running where: the control plane, each runner and its machine | [`spin admin versions`](/reference/cli/admin/) | [`TestE2E_Admin`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L1026) | ### Observability | Feature | Exists | End to end | |---|---|---| -| Platform logs, workspace logs and traces, searched in the product | [`LogService/SearchPlatformLogs`](/reference/api/logservice/) | [`TestAWorkspacesLinesAndTracesAreFoundBySearchingForIt`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/observe_test.go#L22)
[`TestE2E_TheInstallationsLogsAreSearchable`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L928) | -| Metrics, with Grafana on the control plane | [`AdminService/GetMonitoring`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/admin.spec.ts#L1149): a series of the lane's host is in the metric store, read through Grafana
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/dashboard/e2e/admin.spec.ts#L1126): admin reads the installation's dashboards without leaving the page | -| A workspace's journal and console are collected only with its owner's consent | [`spin workspace logs-consent`](/reference/cli/workspace/) | [`TestE2E_AWorkspacesConsoleIsKeptAndSearchable`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/e2e_test.go#L949) | +| Platform logs, workspace logs and traces, searched in the product | [`LogService/SearchPlatformLogs`](/reference/api/logservice/) | [`TestAWorkspacesLinesAndTracesAreFoundBySearchingForIt`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/observe_test.go#L22)
[`TestE2E_TheInstallationsLogsAreSearchable`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L928) | +| Metrics, with Grafana on the control plane | [`AdminService/GetMonitoring`](/reference/api/adminservice/) | [`admin.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/admin.spec.ts#L1149): a series of the lane's host is in the metric store, read through Grafana
[`admin.spec.ts`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/dashboard/e2e/admin.spec.ts#L1126): admin reads the installation's dashboards without leaving the page | +| A workspace's journal and console are collected only with its owner's consent | [`spin workspace logs-consent`](/reference/cli/workspace/) | [`TestE2E_AWorkspacesConsoleIsKeptAndSearchable`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/e2e_test.go#L949) | ### Platform | Feature | Exists | End to end | |---|---|---| -| A smoke test of what an installation's API promises, with a workspace of its own | [`spin smoke`](/reference/cli/smoke/) | [`TestE2E_SmokePassesAndLeavesNothingBehind`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/cmd/cli/journeys_e2e_test.go#L314) | -| A host serves only the releases it carries
*A resume whose recorded release was collected since has no test against the stack.* | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/suspend_test.go#L126), a test of `internal/e2e` | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/suspend_test.go#L126)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/internal/e2e/vscodehotplug_test.go#L23) | +| A smoke test of what an installation's API promises, with a workspace of its own | [`spin smoke`](/reference/cli/smoke/) | [`TestE2E_SmokePassesAndLeavesNothingBehind`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/cmd/cli/journeys_e2e_test.go#L314) | +| A host serves only the releases it carries
*A resume whose recorded release was collected since has no test against the stack.* | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/suspend_test.go#L126), a test of `internal/e2e` | [`TestAMachineAdoptedWithoutItsReleasesIsSuspendedWithItsDisk`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/suspend_test.go#L126)
[`TestAVSCodeServerOfAnotherCommitIsHandedToTheRunningMachine`](https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/internal/e2e/vscodehotplug_test.go#L23) | ## Partly there diff --git a/src/content/docs/use/dashboard.md b/src/content/docs/use/dashboard.md index bb25b14..733fdf1 100644 --- a/src/content/docs/use/dashboard.md +++ b/src/content/docs/use/dashboard.md @@ -7,7 +7,7 @@ editUrl: false -The dashboard is at `https://app.`. These screenshots are of spin v20261024.01, taken by spin's dashboard suite on its end-to-end stack - real workspaces on a real runner - each by a test that first checks the screen shows what its title says. Everything here is also in the [CLI](/reference/cli/) and the [API](/reference/api/). +The dashboard is at `https://app.`. These screenshots are of spin v20261025.01, taken by spin's dashboard suite on its end-to-end stack - real workspaces on a real runner - each by a test that first checks the screen shows what its title says. Everything here is also in the [CLI](/reference/cli/) and the [API](/reference/api/). ## A person's workspaces diff --git a/src/data/figures.json b/src/data/figures.json index df1cec1..0a318bf 100644 --- a/src/data/figures.json +++ b/src/data/figures.json @@ -1,6 +1,6 @@ { "datapath": { - "source": "https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/docs/network/datapath", + "source": "https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/docs/network/datapath", "width": 552, "words": [ "How a packet leaves a workspace", @@ -56,7 +56,7 @@ ] }, "egress-policy": { - "source": "https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/docs/network/egress-policy", + "source": "https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/docs/network/egress-policy", "width": 854, "words": [ "What the forward chain decides, in order", @@ -157,7 +157,7 @@ ] }, "isolation": { - "source": "https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/docs/network/isolation", + "source": "https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/docs/network/isolation", "width": 499, "words": [ "Same address, different segment", @@ -204,7 +204,7 @@ ] }, "traffic": { - "source": "https://github.com/spin-stack/spin/blob/b3598142dbcd6ef24135066332441a400dd35980/docs/security/traffic", + "source": "https://github.com/spin-stack/spin/blob/4534f652122fbb0bb2ba8e434f6e4cd73212fa18/docs/security/traffic", "width": 1889, "words": [ "Traffic: every arrow is a connection opened in its direction, and nothing else is let in", diff --git a/src/data/reference.json b/src/data/reference.json index 1858255..3543250 100644 --- a/src/data/reference.json +++ b/src/data/reference.json @@ -1,8 +1,8 @@ { "spin": { "installs": "v20261019.02", - "commit": "b3598142dbcd6ef24135066332441a400dd35980", - "tag": "v20261024.01", + "commit": "4534f652122fbb0bb2ba8e434f6e4cd73212fa18", + "tag": "v20261025.01", "machine": "v20261014.01" }, "terraform": { @@ -10,7 +10,7 @@ "release": "v20261024.01" }, "brand": { - "commit": "c882b6f0f3901787525ef16ef29058c9c1418cbe" + "commit": "31d07eb9b76596695a138ff96403d881f358e80d" }, "counts": { "built": 75, @@ -20,5 +20,5 @@ "endToEnd": 65, "gap": 10 }, - "openapiSha256": "f600ebac2a39e1b1e59bcb3b08ebfd80692432d8d98b29111b55991729f924d2" + "openapiSha256": "55f225492362049f6ed1501104de85e6345aa55a6163f0aa0bf96950aff45322" } diff --git a/src/data/shots.json b/src/data/shots.json index f2be707..ccd27ff 100644 --- a/src/data/shots.json +++ b/src/data/shots.json @@ -1,6 +1,6 @@ { - "release": "v20261024.01", - "commit": "b3598142dbcd6ef24135066332441a400dd35980", + "release": "v20261025.01", + "commit": "4534f652122fbb0bb2ba8e434f6e4cd73212fa18", "shots": [ { "name": "workspaces", diff --git a/versions.yaml b/versions.yaml index 39dcf2d..a7d6958 100644 --- a/versions.yaml +++ b/versions.yaml @@ -7,8 +7,8 @@ - name: spin kind: git source: https://github.com/spin-stack/spin - version: v20261024.01 - pin: b3598142dbcd6ef24135066332441a400dd35980 + version: v20261025.01 + pin: 4534f652122fbb0bb2ba8e434f6e4cd73212fa18 track: github-release note: >- The release the site documents (D2: the newest, exactly). The daily sync moves it to the next @@ -29,7 +29,7 @@ kind: git source: https://github.com/spin-stack/brand version: main - pin: c882b6f0f3901787525ef16ef29058c9c1418cbe + pin: 31d07eb9b76596695a138ff96403d881f358e80d track: branch note: >- The palette and the logos. brand cuts no releases, so its main is what it has to say. The