slicer

package module
v0.0.59 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2026 License: MIT Imports: 22 Imported by: 1

README

Golang SDK for Slicer

SDK for SlicerVM.com

Table of Contents

Installation

go get github.com/slicervm/sdk@latest

Features

  • VM Management: Create, list, delete, pause, and resume VMs.
  • Execute Commands in VMs: Run commands in VMs and stream command output (stdout/stderr).
  • File Management: Upload and download files to/from VMs with CpToVM and CpFromVM.
  • Secret Management: Securely manage secrets like API keys or other sensitive information for VMs.
  • Port Forwarding: Bidirectional port forwarding with support for TCP ports and UNIX sockets.
  • Pause/Resume: Pause VM CPU usage, then resume instantly when needed.

Connecting to UNIX Sockets

The SDK supports connecting directly to the Slicer API via a UNIX socket. Simply pass the socket path as the baseURL when creating a client:

// Connect via Unix socket
client := sdk.NewSlicerClient("/var/run/slicer/api.sock", token, userAgent, nil)

// Then use normally
ctx := context.Background()
hostGroups, err := client.GetHostGroups(ctx)

The client automatically detects UNIX socket paths (starting with / or ./) and configures the HTTP transport accordingly.

Port Forwarding

The github.com/slicervm/sdk/forward subpackage opens host → VM tunnels from Go. Each accepted local connection gets its own WebSocket to the daemon; the daemon dials the upstream target inside the guest. Same spec syntax as slicer vm forward -L.

import (
    slicer "github.com/slicervm/sdk"
    "github.com/slicervm/sdk/forward"
)

fwd, err := forward.Start(ctx, forward.Options{
    BaseURL: os.Getenv("SLICER_URL"),   // http(s)://… or /path/to/slicer.sock
    Token:   os.Getenv("SLICER_TOKEN"), // optional for unix sockets with no auth
    VMName:  node.Hostname,
    Specs: []string{
        "127.0.0.1:8080:127.0.0.1:80",            // TCP → TCP
        "2375:/var/run/docker.sock",              // TCP → Unix socket in guest
        "/tmp/docker.sock:/var/run/docker.sock",  // Unix → Unix
    },
})
if err != nil { log.Fatal(err) }
defer fwd.Close()

for _, ln := range fwd.Listeners() {
    log.Printf("forward: %s → %s", ln.Local, ln.Remote)
}

// Listeners are bound and serving; make host-side requests now.
resp, _ := http.Get("http://127.0.0.1:8080/")

Supported -L formats (mirrors the CLI):

Spec Listen Upstream
127.0.0.1:9000 127.0.0.1:9000 TCP 127.0.0.1:9000 TCP
9001:127.0.0.1:9000 0.0.0.0:9001 TCP 127.0.0.1:9000 TCP
0:127.0.0.1:9000 random TCP port 127.0.0.1:9000 TCP
0.0.0.0:9000:127.0.0.1:9000 0.0.0.0:9000 TCP 127.0.0.1:9000 TCP
127.0.0.1:9000:/var/run/docker.sock 127.0.0.1:9000 TCP unix:/var/run/docker.sock
9000:/var/run/docker.sock 0.0.0.0:9000 TCP unix:/var/run/docker.sock
/tmp/docker.sock:/var/run/docker.sock Unix socket unix:/var/run/docker.sock

Supported on: Linux, Darwin, and WSL.

See examples/nginx/main.go for a runnable end-to-end demo.

Pause and Resume VMs

Control VM CPU usage with instant pause/resume:

// Pause a VM
err := client.PauseVM(ctx, "vm-1")

// Resume a VM
err := client.ResumeVM(ctx, "vm-1")

SDK Methods Reference

Key concepts

User-facing documentation may refer to Sandboxes and Services. These are logical concepts, not API primitives.

Primitives:

  • Host Group - Host Groups define the template or specification for a Virtual Machine. A slicer daemon can have multiple host groups, but most use-cases should use only one. Host Groups are defined in YAML, and not via API at this time.
  • VM - A virtual machine - (sometimes called Node). Theses are either launched via an initial count value per Host Group, or on demand via API.

When you want a "Sandbox" (read: disposable VM launched via API), it's recommended that you have count: 0 in your host group. VMs launched via API are backed by a persistent disk or snapshot whilst running, which is removed when they terminate.

When you want to host a "Service" or run a server, such as a Kubernetes cluster, or a version of your application, it's best to write a succinct name for the host group such as "k3s" or "app" and then define how many VMs you'll need via count: 1, or count: 3, etc.

VM Operations
Method Description Parameters Returns
CreateVM(ctx, groupName, request) Create a new VM in a host group and return immediately after the API create response. ctx (context.Context), groupName (string), request (SlicerCreateNodeRequest) (*SlicerCreateNodeResponse, error)
CreateVMWithOptions(ctx, groupName, request, options) Create a new VM with typed query options. Set SlicerCreateNodeOptions.Wait to SlicerCreateNodeWaitAgent or SlicerCreateNodeWaitUserdata with an optional Timeout to block server-side until readiness. ctx (context.Context), groupName (string), request (SlicerCreateNodeRequest), options (SlicerCreateNodeOptions) (*SlicerCreateNodeResponse, error)
RelaunchVM(ctx, hostname) Relaunch a known stopped persistent VM (re-uses its disk image). ctx (context.Context), hostname (string) (*SlicerCreateNodeResponse, error)
DeleteVM(ctx, groupName, hostname) Delete a VM from a host group ctx (context.Context), groupName (string), hostname (string) (*SlicerDeleteResponse, error)
ListVMs(ctx, opts...) List all VMs across all host groups. Pass an optional ListOptions{Tag: "…"} or ListOptions{TagPrefix: "…"} to filter server-side. ctx (context.Context), opts (...ListOptions) ([]SlicerNode, error)
GetHostGroups(ctx) Fetch all host groups ctx (context.Context) ([]SlicerHostGroup, error)
GetHostGroupNodes(ctx, groupName, opts...) Fetch nodes for a specific host group. Optional ListOptions filter works the same as ListVMs. ctx (context.Context), groupName (string), opts (...ListOptions) ([]SlicerNode, error)
DeleteNode(groupName, nodeName) Delete a node from a host group groupName (string), nodeName (string) error
PauseVM(ctx, hostname) Pause a running VM to save CPU cost ctx (context.Context), hostname (string) error
ResumeVM(ctx, hostname) Resume a paused VM ctx (context.Context), hostname (string) error
SuspendVM(ctx, hostname) Suspend a running VM to disk via a Firecracker snapshot. Memory and disk state are saved; the VM is shut down. Slicer-for-Mac only, for now — the Linux daemon will return 501 Not Implemented. ctx (context.Context), hostname (string) error
RestoreVM(ctx, hostname) Restore a VM from its previously-taken Firecracker snapshot. Slicer-for-Mac only, for now. ctx (context.Context), hostname (string) error
Shutdown(ctx, hostname, request) Shutdown or reboot a VM ctx (context.Context), hostname (string), request (*SlicerShutdownRequest) error
GetVMStats(ctx, hostname) Get CPU, memory, and disk statistics for a VM or all VMs ctx (context.Context), hostname (string, empty for all) ([]SlicerNodeStat, error)
GetVMLogs(ctx, hostname, lines) Get recent logs from a VM ctx (context.Context), hostname (string), lines (int, -1 for all) (*SlicerLogsResponse, error)
GetInfo(ctx) Fetch server version and build information ctx (context.Context) (*SlicerInfo, error)
Guest Operations
Method Description Parameters Returns
Exec(ctx, hostname, request) Execute a command in a VM and stream output line-by-line as NDJSON frames. Typed frames (started, stdout, stderr, exit) let callers measure process-start latency separately from first-byte latency. ctx (context.Context), hostname (string), request (SlicerExecRequest) (chan SlicerExecWriteResult, error)
ExecBuffered(ctx, hostname, request) Execute a command and wait for completion — a single buffered JSON result instead of the NDJSON stream. Use this when you don't need live output. Hits POST /vm/{hostname}/exec?buffered=true. stdin is not supported; use ExecWithReader for that. ctx (context.Context), hostname (string), request (SlicerExecRequest) (ExecResult, error)
CpToVM(ctx, vmName, localPath, vmPath, uid, gid, permissions, mode) Upload a file/directory to a VM ctx (context.Context), vmName (string), localPath (string), vmPath (string), uid (uint32), gid (uint32), permissions (string), mode (string: "tar" or "binary") error
CpFromVM(ctx, vmName, vmPath, localPath, permissions, mode) Download a file/directory from a VM ctx (context.Context), vmName (string), vmPath (string), localPath (string), permissions (string), mode (string: "tar" or "binary") error

Exec requests made through the SDK default to stdio=base64 so stdout/stderr are binary-safe. The SDK decodes those frames before returning data or writing to RemoteCmd.Stdout / RemoteCmd.Stderr. Set SlicerExecRequest.Stdio to ExecStdioText only when you explicitly want raw readable NDJSON frames.

When mode is tar, localPath is treated as a directory destination and will be created automatically if it does not already exist. | GetAgentHealth(ctx, hostname, includeStats) | Check VM agent health and optionally get system stats | ctx (context.Context), hostname (string), includeStats (bool) | (*SlicerAgentHealthResponse, error) |

Filesystem Operations

These methods hit native /vm/{hostname}/fs/* endpoints — preferred over shelling out through Exec because they don't depend on guest-side ls/stat/mkdir/rm and don't have shell-quoting hazards.

Method Description Parameters Returns
ReadDir(ctx, vmName, path) List directory entries with typed metadata. ctx, vmName (string), path (string) ([]SlicerFSInfo, error)
Stat(ctx, vmName, path) Get a single file/directory entry; returns os.ErrNotExist on 404. ctx, vmName (string), path (string) (*SlicerFSInfo, error)
Exists(ctx, vmName, path) Convenience wrapper around Stat. ctx, vmName (string), path (string) (bool, error)
Mkdir(ctx, vmName, request) Create a directory (recursive + mode optional). ctx, vmName (string), request (SlicerFSMkdirRequest) error
Remove(ctx, vmName, path, recursive) Remove a file or directory. ctx, vmName (string), path (string), recursive (bool) error
ReadFile(ctx, vmName, vmPath) Download a single file's bytes plus its mode. ctx, vmName (string), vmPath (string) ([]byte, string, error)
WriteFile(ctx, vmName, vmPath, data, uid, gid, permissions) Upload a single file with a specific mode. ctx, vmName (string), vmPath (string), data ([]byte), uid/gid (uint32), permissions (string) error
WatchFS(ctx, vmName, request) Stream filesystem events (SSE) from GET /vm/{hostname}/fs/watch. Delivers decoded events on one channel and any terminal error on another. ctx, vmName (string), request (SlicerFSWatchRequest) (<-chan SlicerFSWatchEvent, <-chan error)
WatchFSIter(ctx, vmName, request) Range-over-func adapter for WatchFS using Go 1.23 iter.Seq2. ctx, vmName (string), request (SlicerFSWatchRequest) iter.Seq2[SlicerFSWatchEvent, error]
Secret Management
Method Description Parameters Returns
CreateSecret(ctx, request) Create a new secret for VMs to use. Returns ErrSecretExists if a secret with the same name already exists. ctx (context.Context), request (CreateSecretRequest) error
ListSecrets(ctx) List all secrets (metadata only, not values for security reasons) ctx (context.Context) ([]Secret, error)
PatchSecret(ctx, secretName, request) Update an existing secret with new data and/or metadata. Only provided fields are modified. ctx (context.Context), secretName (string), request (UpdateSecretRequest) error
DeleteSecret(ctx, secretName) Delete a secret ctx (context.Context), secretName (string) error
Slicer-Proxy Admin

Available since v0.0.49. Manages the slicer egress proxy: clients (holders of an HTTPS_PROXY access token), upstream-credential secrets, and per-client allow rules. The proxy injects a bound secret onto the inner request when an allow rule matches, so real upstream credentials never need to enter a guest VM.

Method Description Parameters Returns
CreateProxyClient(ctx, name, setToken) Mint a client and return its access token. The token is shown once and is the only way to authenticate against the data-plane CONNECT listener. Pass setToken="" for a server-minted spt_… token. ctx (context.Context), name (string), setToken (string) (*ProxyClientCreated, error)
ListProxyClients(ctx) List all proxy clients (no tokens). ctx (context.Context) ([]ProxyClient, error)
DeleteProxyClient(ctx, name) Revoke the token, drop every allow rule the client owned, remove the client. ctx (context.Context), name (string) error
CreateProxySecret(ctx, request) Register an upstream credential. Use Type: SecretTypeBearer (default) for raw tokens or Type: SecretTypeBasic with Value in user:pass form for HTTP Basic. ctx (context.Context), request (CreateProxySecretRequest) error
ListProxySecrets(ctx) List secrets (values never returned). ctx (context.Context) ([]ProxySecret, error)
DeleteProxySecret(ctx, name) Remove a secret. Allow rules referencing it stop matching until the secret is recreated. ctx (context.Context), name (string) error
AddProxyAllow(ctx, request) Grant a client access to a host, optionally injecting a named secret on every CONNECT to that host. Set request.Host="*" to match every CONNECT. ctx (context.Context), request (AddProxyAllowRequest) error
RemoveProxyAllow(ctx, client, host) Revoke one allow rule for a client. ctx (context.Context), client, host (string) error
ListProxyRules(ctx, client) Return the client's allow rules in declaration order. ctx (context.Context), client (string) ([]ProxyAllowRule, error)

End-to-end example — mint a client, register a credential, allow an upstream, exec a curl through the proxy from inside the guest, then revoke the grant:

import (
    "context"
    "log"
    "os"
    "strings"

    sdk "github.com/slicervm/sdk"
)

func main() {
    c := sdk.NewSlicerClient("./slicer.sock", "", "proxy-demo/1.0", nil)
    ctx := context.Background()

    created, err := c.CreateProxyClient(ctx, "build-1", "")
    if err != nil { log.Fatal(err) }
    defer c.DeleteProxyClient(ctx, "build-1")

    bearer, _ := os.ReadFile(os.ExpandEnv("$HOME/upstream-bearer.txt"))
    if err := c.CreateProxySecret(ctx, sdk.CreateProxySecretRequest{
        Name:  "llama",
        Host:  "llm.example.internal",
        Value: strings.TrimSpace(string(bearer)),
    }); err != nil { log.Fatal(err) }
    defer c.DeleteProxySecret(ctx, "llama")

    if err := c.AddProxyAllow(ctx, sdk.AddProxyAllowRequest{
        Client: "build-1",
        Host:   "llm.example.internal",
        Secret: "llama",
    }); err != nil { log.Fatal(err) }

    cmd := c.CommandContext(ctx, "demo-1", "curl", "-sS",
        "-X", "POST", "https://llm.example.internal/v1/chat/completions",
        "-H", "Content-Type: application/json",
        "-d", `{"model":"local","messages":[{"role":"user","content":"Reply OK"}],"max_tokens":4}`,
    )
    cmd.Env = []string{
        "HTTPS_PROXY=https://:" + created.Token + "@192.168.142.1:3128",
    }
    out, _ := cmd.CombinedOutput()
    log.Printf("upstream said: %s", out)

    // revoke the grant; subsequent CONNECTs land as DENY in the proxy log
    _ = c.RemoveProxyAllow(ctx, "build-1", "llm.example.internal")
}

The token never enters the guest filesystem in this example — only its HTTPS_PROXY env-var literal for that single exec. The upstream credential (llama bearer) never enters the guest at all; the proxy injects it on the inner request.

Documentation

Samples/Examples

Each example is its own module requiring github.com/slicervm/sdk v0.0.49 with replace github.com/slicervm/sdk => ../../, so run examples from their own directory.

E2E benchmark notes (unix socket + devmapper + --min)

Use this for local benchmark/e2e runs on a dedicated daemon:

SLICER_BIN=${SLICER_BIN:-./path/to/slicer/bin/slicer}

cd /tmp
mkdir -p /tmp/sdk-e2e
$SLICER_BIN new timetti \
  --min \
  --count=0 \
  --storage=devmapper \
  --net=isolated \
  --api-bind /tmp/slicer-e2e.sock \
  > /tmp/sdk-e2e/slicer.yaml
$SLICER_BIN up /tmp/sdk-e2e/slicer.yaml > /tmp/sdk-e2e/slicer.log 2>&1 &

Then run the example:

SLICER_URL=/tmp/slicer-e2e.sock \
SLICER_HOST_GROUP=timetti \
SLICER_CREATE_WAIT=agent \
SLICER_CREATE_TIMEOUT=120s \
go run ./examples/time_till_interactive

Cleanup:

sudo kill -INT $(pgrep -f "/bin/slicer up /tmp/sdk-e2e/slicer.yaml")

Quick start

Create a new slicer config with a count of 0.

Every VM launched by API will be ephemeral, so it'll be deleted after running sudo -E slicer vm shutdown NAME, or when it's deleted either by an API call, this slicer daemon shutting down, or when you delete the VM via REST API.

The first launch will take the name api-1, then api-2 and so forth. You can attach tags when you create the VM, if you want a stable name that can be looked up via the list endpoint.

slicer new api \
    --count=0 \
    --graceful-shutdown=false \
    --ram 4 \
    --cpu 2 > api.yaml

Start Slicer:

sudo -E slicer up ./api.yaml

Create a VM (node) in a host group with the default RAM/CPU settings as defined in the host group.

package main

import (
    "context"
    "fmt"
    "os"
    "time"
    
    sdk "github.com/slicervm/sdk"
)

func main() {
    // Typically you'd load these from environment variables
    baseURL := os.Getenv("SLICER_URL")      // API base URL
    token := os.Getenv("SLICER_TOKEN")      // Your API token
    userAgent := "my-microvm-client/1.0"
    hostGroup := "api"                       // Existing host group name

    client := sdk.NewSlicerClient(baseURL, token, userAgent, nil /* or &http.Client{} */)

    createReq := sdk.SlicerCreateNodeRequest{
        RamBytes:      4 * 1024 * 1024 * 1024, // 4GB RAM 
        CPUs:       2,
        Userdata: `#!/bin/bash
echo 'Bootstrapping...'
ping -c3 google.com

sudo reboot
`,
        SSHKeys: []string{"ssh-rsa AAAA..."}, // Optional: inject public SSH keys
        ImportUser: "alexellis", // Optional: Import GitHub keys for a specific user
    }

    ctx := context.Background()
    node, err := client.CreateVMWithOptions(ctx, hostGroup, createReq, sdk.SlicerCreateNodeOptions{
        Wait:    sdk.SlicerCreateNodeWaitUserdata,
        Timeout: 5 * time.Minute,
    })
    if err != nil {
        panic(fmt.Errorf("failed to create node: %w", err))
    }

    fmt.Printf("Created VM: hostname=%s ip=%s created_at=%s\n", node.Hostname, node.IP, node.CreatedAt)
    fmt.Printf("Parsed IP only: %s\n", node.IPAddress())
}

Run the program i.e. after running go build -o client main.go:

SLICER_URL=http://127.0.0.1:8080 SLICER_TOKEN="$(sudo cat /var/lib/slicer/auth/token)" ./client

You'll find the logs for the microVM at /var/log/slicer/HOSTNAME.txt, showing the userdata executing.

Notes:

  • The argument order for NewSlicerClient is (baseURL, token, userAgent, httpClient).
  • If RamBytes or CPUs are not the values configured on the host group are used; Userdata, SSHKeys and ImportUser are optional.
  • Userdata runs on first boot; keep it idempotent.
  • Use a persistent http.Client (e.g. with timeout) in production instead of nil.

See a more minimal example at: examples/create/main.go

Documentation

Index

Constants

View Source
const (
	ExecStdioText   = "text"
	ExecStdioBase64 = "base64"
)
View Source
const (
	SecretTypeBearer             = "bearer"
	SecretTypeBasic              = "basic"
	SecretTypeOAuthCodex         = "oauth-codex"
	SecretTypeOAuthClaude        = "oauth-claude"
	SecretTypeOAuthGitHubCopilot = "oauth-github-copilot"
	SecretTypeOAuthXAI           = "oauth-xai"
	SecretTypeGitHubAppUser      = "github-app-user"
	SecretTypeGitHubApp          = "github-app"
)

Secret types. Empty value is treated as bearer for backwards compat with state files / API callers that predate the field.

View Source
const NonRootUser = uint32(math.MaxUint32)

Variables

View Source
var (
	// ErrSecretExists is an error returned when a secret with given name already exists.
	ErrSecretExists = errors.New("secret already exists")
)

Functions

func ExtractTarStream added in v0.0.10

func ExtractTarStream(ctx context.Context, r io.Reader, extractDir string, uid, gid uint32, excludePatterns ...string) error

ExtractTarStream extracts a tar stream from r into extractDir. Only handles regular files and directories. Preserves mtime and executable bit. Normalizes permissions (strips setuid/setgid/sticky bits). Skips all other entry types. If uid or gid are non-zero, files will be chowned to that uid/gid after creation. Note: Permissions are set when opening files (efficient), chown is only applied if uid/gid are non-zero.

func ExtractTarToPath added in v0.0.10

func ExtractTarToPath(ctx context.Context, r io.Reader, dest string, uid, gid uint32, excludePatterns ...string) error

ExtractTarToPath extracts a tar stream to a local path with cp-like renaming. If dest exists and is a directory, extracts into it. Otherwise extracts and renames. No temporary directories are used - extraction happens directly. If uid or gid are non-zero, files will be chowned to that uid/gid after creation.

func GiB added in v0.0.17

func GiB(gb int64) int64

GB converts gigabytes to bytes

func MiB added in v0.0.17

func MiB(mb int64) int64

MB converts megabytes to bytes

func ParseFSWatchTimestamp added in v0.0.44

func ParseFSWatchTimestamp(v string) (time.Time, error)

ParseFSWatchTimestamp parses the wire timestamp from a watch event. The timestamp is RFC3339Nano when present; an empty value returns the zero time without error.

func StreamTarArchive added in v0.0.10

func StreamTarArchive(ctx context.Context, w io.Writer, parentDir, baseName string, excludePatterns ...string) error

StreamTarArchive streams a tar archive of regular files and directories to w. Only handles regular files and directories. Preserves mtime and executable bit. Skips symlinks, devices, and other special files.

func ValidRelPath added in v0.0.10

func ValidRelPath(p string) bool

ValidRelPath validates that a path is a valid relative path and doesn't contain directory traversal attempts. Note: Backslashes are allowed in filenames (e.g., systemd unit files with escaped characters). Since tar paths use forward slashes as separators (via filepath.ToSlash()), any backslashes in the path are part of the filename, not path separators.

Types

type AddProxyAllowRequest added in v0.0.49

type AddProxyAllowRequest struct {
	Client      string   `json:"client"`
	Host        string   `json:"host"`
	Secret      string   `json:"secret,omitempty"`
	Methods     []string `json:"methods,omitempty"`
	Paths       []string `json:"paths,omitempty"`
	Ports       []int    `json:"ports,omitempty"`
	TTLSeconds  int      `json:"ttl_seconds,omitempty"`
	Passthrough bool     `json:"passthrough,omitempty"`
}

AddProxyAllowRequest is the input to AddProxyAllow.

type CreateProxySecretRequest added in v0.0.49

type CreateProxySecretRequest struct {
	Name  string `json:"name"`
	Host  string `json:"host"`
	Type  string `json:"type,omitempty"`
	Value string `json:"value"`
	Force bool   `json:"force,omitempty"`
}

CreateProxySecretRequest is the input to CreateProxySecret. Type defaults to SecretTypeBearer when empty. For SecretTypeBasic the Value must be in user:pass form (the proxy base64-encodes it). For SecretTypeOAuthCodex the Value must be a Codex auth.json or minimal OAuth JSON containing access_token, refresh_token, and account_id; the proxy adopts it and refreshes it from host-side state. For SecretTypeOAuthClaude the Value must be Claude Code's .credentials.json or minimal OAuth JSON containing accessToken and refreshToken; the proxy adopts it and refreshes it from host-side state. For SecretTypeOAuthGitHubCopilot the Value must be opencode auth.json or minimal OAuth JSON containing a GitHub Copilot gho_* or ghu_* token; gho_* tokens are sent directly to api.githubcopilot.com, while legacy ghu_* tokens are exchanged for short-lived Copilot session tokens. For SecretTypeOAuthXAI the Value must be JSON emitted by `slicer proxy oauth xai`, or equivalent top-level JSON containing access_token and refresh_token; the proxy injects the current bearer for api.x.ai and refreshes it host-side. For SecretTypeGitHubAppUser the Value must be JSON emitted by `slicer proxy oauth github-app-user`, or equivalent top-level JSON containing access_token. Optional refresh material is stored and refreshed host-side; requests receive Authorization: Bearer <access-token>. For SecretTypeGitHubApp the Value must be JSON or YAML containing app_id and either private_key_file or private_key. With private_key_file, the proxy keeps the PEM file on the host; with private_key, the PEM is stored in proxy state. The proxy mints GitHub App installation tokens in memory and injects Git HTTPS Basic auth for github.com clone/fetch requests.

type CreateSecretRequest added in v0.0.6

type CreateSecretRequest struct {
	// Name is the unique name of the secret
	Name string `json:"name"`
	// Data is the secret content
	Data string `json:"data"`
	// Permissions specifies the file permissions (defaults to system default)
	Permissions string `json:"permissions,omitempty"`

	// GID is the user ID that should own the secret file. If not set, the default for
	// a uint32 will be used i.e root.
	UID uint32 `json:"uid,omitempty"`

	// GID is the group ID that should own the secret file. If not set, the default for
	// a uint32 will be used i.e root.
	GID uint32 `json:"gid,omitempty"`
}

CreateSecretRequest is the payload for creating a new secret via the REST API.

type ExecBackgroundDeleteResponse added in v0.0.46

type ExecBackgroundDeleteResponse struct {
	ExecID string `json:"exec_id"`
	Reaped bool   `json:"reaped"`
}

ExecBackgroundDeleteResponse is returned by ExecDelete.

type ExecBackgroundInfo added in v0.0.46

type ExecBackgroundInfo struct {
	ExecID       string     `json:"exec_id"`
	PID          int        `json:"pid"`
	Command      string     `json:"command"`
	Args         []string   `json:"args,omitempty"`
	Cwd          string     `json:"cwd,omitempty"`
	UID          uint32     `json:"uid,omitempty"`
	StartedAt    time.Time  `json:"started_at"`
	Running      bool       `json:"running"`
	ExitCode     *int       `json:"exit_code,omitempty"`
	Signal       string     `json:"signal,omitempty"`
	EndedAt      *time.Time `json:"ended_at,omitempty"`
	BytesWritten int64      `json:"bytes_written"`
	BytesDropped int64      `json:"bytes_dropped"`
	NextID       uint64     `json:"next_id"`
	RingBytes    int64      `json:"ring_bytes"`
}

ExecBackgroundInfo mirrors the server's info shape for a background exec.

type ExecBackgroundKillResponse added in v0.0.46

type ExecBackgroundKillResponse struct {
	ExecID     string `json:"exec_id"`
	PID        int    `json:"pid"`
	Running    bool   `json:"running"`
	SignalSent string `json:"signal_sent"`
}

ExecBackgroundKillResponse is returned by ExecKill.

type ExecBackgroundRequest added in v0.0.46

type ExecBackgroundRequest struct {
	Command string   `json:"command,omitempty"`
	Args    []string `json:"args,omitempty"`
	Env     []string `json:"env,omitempty"`
	UID     uint32   `json:"uid,omitempty"`
	GID     uint32   `json:"gid,omitempty"`
	Shell   string   `json:"shell,omitempty"`
	Cwd     string   `json:"cwd,omitempty"`

	// RingBytes sets the per-process ring buffer cap. Zero means server
	// default (1 MiB). Negative values are rejected.
	RingBytes int64 `json:"ring_bytes,omitempty"`
}

ExecBackgroundRequest carries parameters to launch a long-running process inside a VM via POST /vm/{hostname}/exec?background=true.

type ExecBackgroundResponse added in v0.0.46

type ExecBackgroundResponse struct {
	ExecID    string    `json:"exec_id"`
	PID       int       `json:"pid"`
	StartedAt time.Time `json:"started_at"`
	RingBytes int64     `json:"ring_bytes"`
}

ExecBackgroundResponse is returned by ExecBackground on success.

type ExecBackgroundWaitExitResponse added in v0.0.46

type ExecBackgroundWaitExitResponse struct {
	ExecID   string     `json:"exec_id"`
	Running  bool       `json:"running"`
	ExitCode *int       `json:"exit_code,omitempty"`
	Signal   string     `json:"signal,omitempty"`
	EndedAt  *time.Time `json:"ended_at,omitempty"`
	TimedOut bool       `json:"timed_out"`
}

ExecBackgroundWaitExitResponse is returned by ExecWaitExit.

type ExecResult added in v0.0.38

type ExecResult struct {
	Stdout    string    `json:"stdout,omitempty"`
	Stderr    string    `json:"stderr,omitempty"`
	Encoding  string    `json:"encoding,omitempty"`
	Pid       int       `json:"pid,omitempty"`
	StartedAt time.Time `json:"started_at,omitempty,omitzero"`
	EndedAt   time.Time `json:"ended_at,omitempty,omitzero"`
	Signal    string    `json:"signal,omitempty"`
	ExitCode  int       `json:"exit_code"`
	Error     string    `json:"error,omitempty"`
}

func (ExecResult) StderrBytes added in v0.0.41

func (r ExecResult) StderrBytes() ([]byte, error)

func (ExecResult) StdoutBytes added in v0.0.41

func (r ExecResult) StdoutBytes() ([]byte, error)

type ExitError added in v0.0.23

type ExitError struct {
	*RemoteProcessState

	// Stderr holds stderr output if it was collected.
	Stderr []byte
}

ExitError is returned by RemoteCmd methods when a command exits with a non-zero status. It mirrors exec.ExitError but for remote executions.

func (*ExitError) Error added in v0.0.23

func (e *ExitError) Error() string

Error returns a string representation of the exit error.

func (*ExitError) Unwrap added in v0.0.23

func (e *ExitError) Unwrap() error

Unwrap returns the underlying process state for errors.Is/As compatibility.

type KillOptions added in v0.0.46

type KillOptions struct {
	Signal  string `json:"signal,omitempty"`
	GraceMs int    `json:"grace_ms,omitempty"`
}

KillOptions tunes POST /vm/{hostname}/exec/{exec_id}/kill.

type ListOptions added in v0.0.40

type ListOptions struct {
	// Tag matches nodes whose tags contain exactly this value.
	Tag string
	// TagPrefix matches nodes whose tags start with this value.
	TagPrefix string
}

ListOptions filters applied to node listing endpoints. Both `Tag` (exact match) and `TagPrefix` are mutually exclusive — callers should set at most one. An empty ListOptions (the zero value) applies no filter.

type LogOptions added in v0.0.46

type LogOptions struct {
	// Follow=true keeps the connection open and streams live frames after
	// replaying the ring contents. Follow=false replays and closes.
	Follow bool
	// FromID starts the replay cursor at frame N if present in the ring.
	// If FromID is beyond the live cursor, the server waits for that frame
	// when Follow=true. If the frame has been evicted a gap frame is emitted.
	FromID uint64
}

LogOptions tunes GET /vm/{hostname}/exec/{exec_id}/logs.

type ProxyAllowRule added in v0.0.49

type ProxyAllowRule struct {
	Host        string    `json:"host"`
	Secret      string    `json:"secret,omitempty"`
	Methods     []string  `json:"methods,omitempty"`
	Paths       []string  `json:"paths,omitempty"`
	Ports       []int     `json:"ports,omitempty"`
	Expires     time.Time `json:"expires,omitempty"`
	Passthrough bool      `json:"passthrough,omitempty"`
}

ProxyAllowRule grants a ProxyClient access to one host (exact, *.suffix wildcard, or "*" for any). When Secret is set, the proxy strips the client-supplied Authorization on the inner request and substitutes the rule-bound credential.

Methods and Paths are optional filters. When set, the request must match at least one entry in each non-empty list. Empty list = any. Path supports exact match, "*" (any path), or "<prefix>/*" suffix glob (anything strictly under the prefix).

Ports is optional. Empty means the default web ports 80 and 443 for backwards compatibility with older host-only rules. When set, the request must target one of the listed upstream ports.

When Passthrough is true the proxy splices TCP both ways at CONNECT without terminating TLS — no MITM, no inner-request inspection. The guest does not need to trust the proxy CA on a passthrough host, so cert-pinned clients work. Passthrough is mutually exclusive with Secret, Methods, and Paths; the admin API rejects rules that combine them.

type ProxyClient added in v0.0.49

type ProxyClient struct {
	Name      string    `json:"name"`
	CreatedAt time.Time `json:"created_at"`
}

ProxyClient holds an opaque token used to authenticate against the slicer-proxy data plane via HTTPS_PROXY=https://:<token>@host:port.

type ProxyClientCreated added in v0.0.49

type ProxyClientCreated struct {
	Name      string    `json:"name"`
	Token     string    `json:"token"`
	CreatedAt time.Time `json:"created_at"`
}

ProxyClientCreated is the response shape from CreateProxyClient. The minted Token is shown once at create time and never returned by any other endpoint.

type ProxySecret added in v0.0.49

type ProxySecret struct {
	Name        string    `json:"name"`
	Host        string    `json:"host"`
	Type        string    `json:"type,omitempty"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"`
	AdoptedAt   time.Time `json:"adopted_at,omitempty"`
	RefreshedAt time.Time `json:"refreshed_at,omitempty"`
}

ProxySecret is an upstream credential the proxy injects into matching CONNECT requests. List/get endpoints never return Value.

type RemoteCmd added in v0.0.23

type RemoteCmd struct {
	// Path is the command to run. This is the only field that must be set.
	// If Path contains no path separators, it will be resolved using the
	// remote system's PATH.
	Path string

	// Args holds command line arguments, including the command as Args[0].
	// If Args is empty or nil, Run uses {Path}.
	Args []string

	// Env specifies the environment of the process.
	// Each entry is of the form "key=value".
	// If Env is nil, the remote process inherits the default environment.
	// Note: Environment variable support depends on the remote agent's capabilities.
	Env []string

	// Dir specifies the working directory of the command.
	// If Dir is empty, the command runs in the remote agent's default directory.
	Dir string

	// Stdin specifies the process's standard input.
	// If Stdin is nil, the process reads from an empty reader.
	// If Stdin is an *os.File, it is connected directly.
	// Otherwise, a goroutine reads from Stdin and delivers to the remote.
	Stdin io.Reader

	// Stdout specifies the process's standard output.
	// If Stdout is nil, output is discarded.
	// If Stdout is an *os.File, output is written directly.
	// Otherwise, a goroutine copies output to Stdout.
	Stdout io.Writer

	// Stderr specifies the process's standard error.
	// If Stderr is nil, error output is discarded.
	// If Stderr is the same as Stdout, both are combined.
	// Otherwise, a goroutine copies error output to Stderr.
	Stderr io.Writer

	// ProcessState contains information about an exited process.
	// It is available after a call to Wait or Run.
	ProcessState *RemoteProcessState

	// UID specifies the user ID to run the command as (Linux only).
	// If zero, uses the remote system's default (usually root).
	UID uint32

	// GID specifies the group ID to run the command as (Linux only).
	// If zero, uses the remote system's default (usually root).
	GID uint32

	// Shell specifies the shell interpreter to use.
	// If empty, defaults to "/bin/bash" on the remote.
	// Set to an empty string explicitly to disable shell interpretation.
	Shell string
	// contains filtered or unexported fields
}

RemoteCmd represents a remote command to be executed on a VM. It mirrors the os/exec.Cmd API but executes commands on remote VMs.

A RemoteCmd cannot be reused after calling Run, Output, or CombinedOutput.

func (*RemoteCmd) CombinedOutput added in v0.0.23

func (c *RemoteCmd) CombinedOutput() ([]byte, error)

CombinedOutput runs the command and returns its combined stdout and stderr.

func (*RemoteCmd) Environ added in v0.0.23

func (c *RemoteCmd) Environ() []string

Environ returns a copy of the environment in which the command would be run.

func (*RemoteCmd) Output added in v0.0.23

func (c *RemoteCmd) Output() ([]byte, error)

Output runs the command and returns its standard output.

If the command fails, the error is of type *ExitError. If stderr was not otherwise collected, the ExitError.Stderr field will contain any captured stderr output.

func (*RemoteCmd) Run added in v0.0.23

func (c *RemoteCmd) Run() error

Run starts the specified command and waits for it to complete.

If the command runs successfully and copies all output, the error is nil. If the command fails to start or doesn't complete successfully, the error is of type *ExitError. Other error types may be returned for other situations.

func (*RemoteCmd) Start added in v0.0.23

func (c *RemoteCmd) Start() error

Start starts the specified command but does not wait for it to complete.

If Start returns successfully, the c.ProcessState field will be set after a successful call to Wait.

After a successful call to Start, the Wait method must be called to release associated system resources.

func (*RemoteCmd) StderrPipe added in v0.0.23

func (c *RemoteCmd) StderrPipe() (io.ReadCloser, error)

StderrPipe returns a pipe that will be connected to the command's standard error when the command starts.

Wait will close the pipe after seeing the command exit, so most callers need not close the pipe themselves. It is thus incorrect to call Wait before all reads from the pipe have completed.

For the same reason, it is incorrect to call Run when using StderrPipe.

func (*RemoteCmd) StdinPipe added in v0.0.23

func (c *RemoteCmd) StdinPipe() (io.WriteCloser, error)

StdinPipe returns a pipe that will be connected to the command's standard input when the command starts.

The pipe will be closed automatically after Wait sees the command exit. The caller only needs to call Close to force the pipe to close sooner. For example, if the command being run won't exit until standard input is closed, the caller must close the pipe.

func (*RemoteCmd) StdoutPipe added in v0.0.23

func (c *RemoteCmd) StdoutPipe() (io.ReadCloser, error)

StdoutPipe returns a pipe that will be connected to the command's standard output when the command starts.

Wait will close the pipe after seeing the command exit, so most callers need not close the pipe themselves. It is thus incorrect to call Wait before all reads from the pipe have completed.

For the same reason, it is incorrect to call Run when using StdoutPipe.

func (*RemoteCmd) String added in v0.0.23

func (c *RemoteCmd) String() string

String returns a human-readable description of the command. It is intended only for debugging, not for execution.

func (*RemoteCmd) Wait added in v0.0.23

func (c *RemoteCmd) Wait() error

Wait waits for the command to exit and waits for any copying to complete.

The command must have been started by Start.

If the command runs successfully, the error is nil. If the command fails, the error is of type *ExitError.

Wait releases any resources associated with the Cmd.

type RemoteProcessState added in v0.0.23

type RemoteProcessState struct {
	// contains filtered or unexported fields
}

RemoteProcessState stores information about an exited remote process. It mirrors os.ProcessState but for remote executions.

func (*RemoteProcessState) ExitCode added in v0.0.23

func (p *RemoteProcessState) ExitCode() int

ExitCode returns the exit code of the exited process. Returns -1 if the process hasn't exited or was terminated abnormally.

func (*RemoteProcessState) Exited added in v0.0.23

func (p *RemoteProcessState) Exited() bool

Exited reports whether the program has exited.

func (*RemoteProcessState) Pid added in v0.0.23

func (p *RemoteProcessState) Pid() int

Pid returns the process id of the exited process. Returns -1 if the PID is not available (remote execution).

func (*RemoteProcessState) String added in v0.0.23

func (p *RemoteProcessState) String() string

String returns a human-readable description of the process state.

func (*RemoteProcessState) Success added in v0.0.23

func (p *RemoteProcessState) Success() bool

Success reports whether the program exited successfully (exit status 0).

type RemoveProxyAllowByTupleRequest added in v0.0.53

type RemoveProxyAllowByTupleRequest struct {
	Client      string   `json:"client"`
	Host        string   `json:"host"`
	Secret      string   `json:"secret,omitempty"`
	Methods     []string `json:"methods,omitempty"`
	Paths       []string `json:"paths,omitempty"`
	Ports       []int    `json:"ports,omitempty"`
	Passthrough bool     `json:"passthrough,omitempty"`
}

RemoveProxyAllowByTupleRequest mirrors the create payload (minus TTLSeconds, which is not part of identity). The proxy matches the rule by (host, methods, paths, ports, passthrough) and removes it from the client's allow list. Useful when the caller owns the tuple — e.g. a declarative config — and wants surgical removal of one rule among siblings on the same host.

type Secret added in v0.0.6

type Secret struct {
	// Name is the unique name of the secret
	Name string `json:"name"`
	// Size is the size of the secret data in bytes
	Size int64 `json:"size"`
	// Permissions specifies the file permissions for the secret (e.g., "0600")
	Permissions string `json:"permissions"`

	// GID is the user ID that should own the secret file. If not set, the default for
	// a uint32 will be used i.e root.
	UID uint32 `json:"uid,omitempty"`

	// GID is the group ID that should own the secret file. If not set, the default for
	// a uint32 will be used i.e root.
	GID uint32 `json:"gid,omitempty"`

	// ModifiedAt is the time the secret was last modified
	ModifiedAt *time.Time `json:"modified_at,omitempty"`
}

Secret represents a secret stored in the slicer system. Secrets can be used to store sensitive configuration data, keys, or other private information that can be mounted into nodes or used by services.

type SlicerAgentHealthResponse added in v0.0.13

type SlicerAgentHealthResponse struct {
	// Hostname is the hostname of the agent
	Hostname string `json:"hostname,omitempty"`

	// Uptime is the uptime of the agent
	AgentUptime time.Duration `json:"agent_uptime,omitempty"`

	// AgentVersion is the version of the agent
	AgentVersion string `json:"agent_version,omitempty"`

	// SystemUptime is the uptime of the system
	SystemUptime time.Duration `json:"system_uptime,omitempty"`

	// UserdataRan indicates whether the user data script has completed executing
	UserdataRan bool `json:"userdata_ran,omitempty"`

	// IP is the guest's primary IPv4 address, as reported by the agent.
	IP string `json:"ip,omitempty"`
}

type SlicerClient

type SlicerClient struct {
	// contains filtered or unexported fields
}

SlicerClient handles all HTTP communication with the Slicer API

func NewClientFromEnv added in v0.0.30

func NewClientFromEnv(baseURL, userAgent string, httpClient *http.Client) (*SlicerClient, error)

NewClientFromEnv creates a client using environment credentials.

The token is loaded from env as: - SLICER_TOKEN (preferred), or - SLICER_TOKEN_FILE.

Parameters: - baseURL: if empty, loaded from SLICER_URL - userAgent: if empty, loaded from SLICER_USER_AGENT or "slicer-sdk-go/1.0" - httpClient: optional custom HTTP client passed to NewSlicerClient

func NewSlicerClient

func NewSlicerClient(baseURL, token string, userAgent string, httpClient *http.Client) *SlicerClient

NewSlicerClient creates a new Slicer API client If baseURL is a Unix socket path (starts with "/" or "./"), it will create a custom HTTP client that uses Unix socket transport.

func NewSlicerClientFromEnv added in v0.0.30

func NewSlicerClientFromEnv() (*SlicerClient, error)

NewSlicerClientFromEnv creates a client from env using default userAgent and default http client. This keeps compatibility with the earlier env-only constructor shape.

func (*SlicerClient) AddProxyAllow added in v0.0.49

func (c *SlicerClient) AddProxyAllow(ctx context.Context, req AddProxyAllowRequest) error

AddProxyAllow grants a client access to a host, optionally injecting a named secret on every CONNECT to that host.

func (*SlicerClient) Command added in v0.0.23

func (c *SlicerClient) Command(ctx context.Context, vmName string, name string, arg ...string) *RemoteCmd

Command returns a RemoteCmd to execute the named program on the specified VM. The returned Cmd's Args field is set to the command name followed by any arguments.

The provided context is used for the lifetime of the command execution. If the context is canceled, the command will be terminated.

func (*SlicerClient) CommandContext added in v0.0.23

func (c *SlicerClient) CommandContext(ctx context.Context, vmName string, name string, arg ...string) *RemoteCmd

CommandContext is an alias for Command that makes the API more familiar to users of os/exec.CommandContext.

func (*SlicerClient) CpFromVM added in v0.0.10

func (c *SlicerClient) CpFromVM(ctx context.Context, vmName, vmPath, localPath string, permissions, mode string, excludePatterns ...string) error

CpFromVM copies files from a VM path to a local path. The tar stream is received from the VM and extracted to localPath with proper renaming logic (supports renaming files/directories). If uid or gid are 0, the current user's UID/GID will be used. On Windows, chown operations are skipped (uid/gid are ignored).

func (*SlicerClient) CpToVM added in v0.0.10

func (c *SlicerClient) CpToVM(ctx context.Context, vmName, localPath, vmPath string, uid, gid uint32, permissions, mode string, excludePatterns ...string) error

CpToVM copies files from a local path to a VM path. The localPath can be a file or directory. The tar stream is created internally and sent to the VM. uid and gid specify the ownership for extracted files (0 means use default).

func (*SlicerClient) CreateProxyClient added in v0.0.49

func (c *SlicerClient) CreateProxyClient(ctx context.Context, name, setToken string) (*ProxyClientCreated, error)

CreateProxyClient mints a new proxy access token. setToken lets the caller bring their own value (handy for demos / reproducible tests); pass "" for a server-minted token (recommended). The returned Token is shown once and is not retrievable later.

func (*SlicerClient) CreateProxySecret added in v0.0.49

func (c *SlicerClient) CreateProxySecret(ctx context.Context, req CreateProxySecretRequest) error

CreateProxySecret registers an upstream credential the proxy can inject when an allow rule references it.

func (*SlicerClient) CreateSecret added in v0.0.6

func (c *SlicerClient) CreateSecret(ctx context.Context, request CreateSecretRequest) error

CreateSecret creates a new secret. Returns ErrSecretExists if a secret with the same name already exists. An error is returned if creation fails.

func (*SlicerClient) CreateVM added in v0.0.10

func (c *SlicerClient) CreateVM(ctx context.Context, groupName string, request SlicerCreateNodeRequest) (*SlicerCreateNodeResponse, error)

CreateVM creates a new VM in the specified host group

func (*SlicerClient) CreateVMWithOptions added in v0.0.41

func (c *SlicerClient) CreateVMWithOptions(ctx context.Context, groupName string, request SlicerCreateNodeRequest, options SlicerCreateNodeOptions) (*SlicerCreateNodeResponse, error)

CreateVMWithOptions creates a new VM in the specified host group with optional wait/query behavior.

groupName may be an empty string, in which case the SDK resolves it client-side by listing configured host groups and picking the only one. If zero or more than one host group is configured the call returns an error without touching the server further. Callers that already know the group name should always pass it in to avoid the extra list round-trip.

func (*SlicerClient) DeleteNode

func (c *SlicerClient) DeleteNode(groupName, nodeName string) error

DeleteNode deletes a node from the specified host group

func (*SlicerClient) DeleteProxyClient added in v0.0.49

func (c *SlicerClient) DeleteProxyClient(ctx context.Context, name string) error

DeleteProxyClient revokes the token, drops every allow rule the client owned, and removes the client.

func (*SlicerClient) DeleteProxySecret added in v0.0.49

func (c *SlicerClient) DeleteProxySecret(ctx context.Context, name string) error

DeleteProxySecret removes a secret. Allow rules that reference it stop matching until the secret is recreated or the rule is rewritten.

func (*SlicerClient) DeleteSecret added in v0.0.6

func (c *SlicerClient) DeleteSecret(ctx context.Context, secretName string) error

DeleteSecret removes a secret. Returns an error if the secret doesn't exist or if the deletion fails.

func (*SlicerClient) DeleteVM added in v0.0.10

func (c *SlicerClient) DeleteVM(ctx context.Context, groupName, hostname string) (*SlicerDeleteResponse, error)

DeleteVM deletes a VM from a host group

func (*SlicerClient) Exec added in v0.0.9

func (c *SlicerClient) Exec(ctx context.Context, nodeName string, execReq SlicerExecRequest) (chan SlicerExecWriteResult, error)

Exec executes a command on the specified node and streams the output. The channel is unbuffered so the caller should read from it promptly to avoid blocking.

func (*SlicerClient) ExecBackground added in v0.0.46

func (c *SlicerClient) ExecBackground(ctx context.Context, vmName string, req ExecBackgroundRequest) (*ExecBackgroundResponse, error)

ExecBackground launches a long-running process inside the named VM and returns the server-chosen exec_id plus process metadata. The child survives client disconnect — use ExecLogs, ExecInfo, ExecWaitExit, ExecKill and ExecDelete on the returned ExecID to interact with it.

func (*SlicerClient) ExecBuffered added in v0.0.38

func (c *SlicerClient) ExecBuffered(ctx context.Context, nodeName string, execReq SlicerExecRequest) (ExecResult, error)

ExecBuffered executes a command and returns a single buffered result. Unlike Exec, this method waits for process completion and returns a single structured result suitable for non-streaming callers.

func (*SlicerClient) ExecDelete added in v0.0.46

func (c *SlicerClient) ExecDelete(ctx context.Context, vmName, execID string) (*ExecBackgroundDeleteResponse, error)

ExecDelete reaps an exec's ring buffer and registry entry. Does not kill a running process — pair with ExecKill for "stop and clean up".

func (*SlicerClient) ExecInfo added in v0.0.46

func (c *SlicerClient) ExecInfo(ctx context.Context, vmName, execID string) (*ExecBackgroundInfo, error)

ExecInfo fetches the latest status for a single background exec.

func (*SlicerClient) ExecKill added in v0.0.46

func (c *SlicerClient) ExecKill(ctx context.Context, vmName, execID string, opts KillOptions) (*ExecBackgroundKillResponse, error)

ExecKill signals a running background exec. Default: SIGTERM with a 5 s grace period before the server escalates to SIGKILL. Calling ExecKill on an already-exited exec is a no-op (running=false is returned).

func (*SlicerClient) ExecList added in v0.0.46

func (c *SlicerClient) ExecList(ctx context.Context, vmName string) ([]ExecBackgroundInfo, error)

ExecList returns all background execs tracked by the VM's agent.

func (*SlicerClient) ExecLogs added in v0.0.46

func (c *SlicerClient) ExecLogs(ctx context.Context, vmName, execID string, opts LogOptions) (<-chan SlicerExecWriteResult, error)

ExecLogs opens the NDJSON log stream for a background exec.

The returned channel is closed when the stream ends (follow=false: after all ring contents are drained; follow=true: when the child exits or the context is cancelled).

func (*SlicerClient) ExecWaitExit added in v0.0.46

func (c *SlicerClient) ExecWaitExit(ctx context.Context, vmName, execID string, timeout time.Duration) (*ExecBackgroundWaitExitResponse, error)

ExecWaitExit long-polls until the child exits or the timeout elapses. If timeout is zero the server default (30s) is used.

func (*SlicerClient) ExecWithReader added in v0.0.23

func (c *SlicerClient) ExecWithReader(ctx context.Context, nodeName string, execReq SlicerExecRequest, stdin io.Reader) (chan SlicerExecWriteResult, error)

ExecWithReader is like Exec but accepts a custom io.Reader for stdin instead of using os.Stdin.

func (*SlicerClient) Exists added in v0.0.38

func (c *SlicerClient) Exists(ctx context.Context, vmName, path string) (bool, error)

Exists checks if a path exists in a VM.

func (*SlicerClient) GetAgentHealth added in v0.0.13

func (c *SlicerClient) GetAgentHealth(ctx context.Context, hostname string, includeStats bool) (*SlicerAgentHealthResponse, error)

GetAgentHealth fetches the health of the agent If includeStats is true, the response will include statistics about the system and agent.

func (*SlicerClient) GetHostGroupNodes

func (c *SlicerClient) GetHostGroupNodes(ctx context.Context, groupName string, opts ...ListOptions) ([]SlicerNode, error)

GetHostGroupNodes fetches nodes for a specific host group. Optional filters (tag / tag_prefix) may be supplied; only the first opts entry is honored.

func (*SlicerClient) GetHostGroups

func (c *SlicerClient) GetHostGroups(ctx context.Context) ([]SlicerHostGroup, error)

GetHostGroups fetches all host groups from the API

func (*SlicerClient) GetInfo added in v0.0.21

func (c *SlicerClient) GetInfo(ctx context.Context) (*SlicerInfo, error)

GetInfo fetches server version information from the /info endpoint

func (*SlicerClient) GetVMLogs added in v0.0.10

func (c *SlicerClient) GetVMLogs(ctx context.Context, hostname string, lines int) (*SlicerLogsResponse, error)

GetVMLogs fetches logs for a specific VM

func (*SlicerClient) GetVMStats added in v0.0.10

func (c *SlicerClient) GetVMStats(ctx context.Context, hostname string) ([]SlicerNodeStat, error)

GetVMStats fetches stats for all VMs or a specific VM if hostname is provided. If hostname is empty, returns stats for all VMs.

func (*SlicerClient) ListProxyClients added in v0.0.49

func (c *SlicerClient) ListProxyClients(ctx context.Context) ([]ProxyClient, error)

ListProxyClients returns all registered proxy clients (no tokens).

func (*SlicerClient) ListProxyRules added in v0.0.49

func (c *SlicerClient) ListProxyRules(ctx context.Context, client string) ([]ProxyAllowRule, error)

ListProxyRules returns the client's allow rules in declaration order.

func (*SlicerClient) ListProxySecrets added in v0.0.49

func (c *SlicerClient) ListProxySecrets(ctx context.Context) ([]ProxySecret, error)

ListProxySecrets returns all registered secrets (Value field is never returned by the server).

func (*SlicerClient) ListSecrets added in v0.0.6

func (c *SlicerClient) ListSecrets(ctx context.Context) ([]Secret, error)

ListSecrets retrieves all secrets. Note: The actual secret data is not returned for security reasons.

func (*SlicerClient) ListVMs added in v0.0.10

func (c *SlicerClient) ListVMs(ctx context.Context, opts ...ListOptions) ([]SlicerNode, error)

ListVMs fetches all VMs (nodes). Optional filters (tag / tag_prefix) may be supplied; only the first opts entry is honored.

func (*SlicerClient) Mkdir added in v0.0.38

func (c *SlicerClient) Mkdir(ctx context.Context, vmName string, request SlicerFSMkdirRequest) error

Mkdir creates a directory in a VM.

func (*SlicerClient) PatchSecret added in v0.0.6

func (c *SlicerClient) PatchSecret(ctx context.Context, secretName string, request UpdateSecretRequest) error

PatchSecret updates an existing secret with new data and/or metadata. Only the fields provided in the UpdateSecretRequest will be modified. Returns an error if the secret doesn't exist or if the update fails.

func (*SlicerClient) PauseVM added in v0.0.20

func (c *SlicerClient) PauseVM(ctx context.Context, hostname string) error

PauseVM pauses a running VM

func (*SlicerClient) ReadDir added in v0.0.38

func (c *SlicerClient) ReadDir(ctx context.Context, vmName, path string) ([]SlicerFSInfo, error)

ReadDir lists entries in a VM path.

func (*SlicerClient) ReadFile added in v0.0.38

func (c *SlicerClient) ReadFile(ctx context.Context, vmName, vmPath string) ([]byte, string, error)

ReadFile downloads a file from the VM and returns its contents and optional mode.

func (*SlicerClient) RelaunchVM added in v0.0.35

func (c *SlicerClient) RelaunchVM(ctx context.Context, hostname string) (*SlicerCreateNodeResponse, error)

RelaunchVM relaunches a known stopped persistent VM.

func (*SlicerClient) Remove added in v0.0.38

func (c *SlicerClient) Remove(ctx context.Context, vmName, path string, recursive bool) error

Remove deletes a file or directory in a VM.

func (*SlicerClient) RemoveProxyAllow added in v0.0.49

func (c *SlicerClient) RemoveProxyAllow(ctx context.Context, client, host string) error

RemoveProxyAllow removes every allow rule for a client whose host matches. This is the host-bulk verb. For surgical removal of a single rule (when several share a host but differ on paths / methods / passthrough) use RemoveProxyAllowByTuple.

func (*SlicerClient) RemoveProxyAllowByTuple added in v0.0.53

func (c *SlicerClient) RemoveProxyAllowByTuple(ctx context.Context, req RemoveProxyAllowByTupleRequest) error

RemoveProxyAllowByTuple removes the single allow rule whose (host, methods, paths, passthrough) tuple matches the request. Callers pass the same fields they used to create the rule; TTL is not part of identity and is omitted from the request type.

func (*SlicerClient) RestoreVM added in v0.0.25

func (c *SlicerClient) RestoreVM(ctx context.Context, hostname string) error

RestoreVM restores a VM from a Firecracker snapshot with no readiness wait. Returns once the daemon has scheduled the launch goroutine; the agent may not yet be reachable. Pass options via RestoreVMWithOptions to have the daemon block on agent readiness.

func (*SlicerClient) RestoreVMWithOptions added in v0.0.48

func (c *SlicerClient) RestoreVMWithOptions(ctx context.Context, hostname string, opts SlicerRestoreVMOptions) error

RestoreVMWithOptions restores a VM and optionally waits server-side for the guest agent's /v1/health endpoint to answer 200. The daemon polls the vsock-backed health endpoint at ~1 ms intervals, so the call returns shortly after firecracker resumes the snapshot. timeout=0 falls back to the daemon default.

func (*SlicerClient) ResumeVM added in v0.0.20

func (c *SlicerClient) ResumeVM(ctx context.Context, hostname string) error

ResumeVM resumes a paused VM

func (*SlicerClient) Shutdown added in v0.0.19

func (c *SlicerClient) Shutdown(ctx context.Context, hostname string, request *SlicerShutdownRequest) error

Shutdown shuts down or reboots a VM. If request is nil, it defaults to shutdown action. The request Action field can be "shutdown" (halt) or "reboot" (restart).

func (*SlicerClient) Stat added in v0.0.38

func (c *SlicerClient) Stat(ctx context.Context, vmName, path string) (*SlicerFSInfo, error)

Stat fetches metadata for a single path inside a VM.

func (*SlicerClient) SuspendVM added in v0.0.25

func (c *SlicerClient) SuspendVM(ctx context.Context, hostname string) error

SuspendVM suspends a running VM to disk (Firecracker snapshot)

func (*SlicerClient) WatchFS added in v0.0.44

func (c *SlicerClient) WatchFS(ctx context.Context, vmName string, req SlicerFSWatchRequest) (<-chan SlicerFSWatchEvent, <-chan error)

WatchFS opens a filesystem watch stream at /vm/{vmName}/fs/watch and returns a channel of decoded events and a channel carrying any terminal error. Both channels are closed when the stream ends.

Heartbeat SSE comments and `event:` lines are silently discarded; each delivered event includes its `id:` in SlicerFSWatchEvent.ID.

func (*SlicerClient) WatchFSIter added in v0.0.44

WatchFSIter is a range-over-func adapter over WatchFS.

Usage:

for evt, err := range client.WatchFSIter(ctx, vm, req) {
	if err != nil {
		// stream error or cancellation
		break
	}
	// consume evt
}

func (*SlicerClient) WriteFile added in v0.0.38

func (c *SlicerClient) WriteFile(ctx context.Context, vmName, vmPath string, data []byte, uid, gid uint32, permissions string) error

WriteFile uploads a binary file to the VM.

type SlicerCpRequest added in v0.0.10

type SlicerCpRequest struct {
	VM   string // VM name
	Path string // Path on the VM
}

SlicerCpRequest contains parameters for copying files to/from a VM

type SlicerCreateNodeNetworkPolicy added in v0.0.52

type SlicerCreateNodeNetworkPolicy struct {
	Allow []string `json:"allow,omitempty"`
	Drop  []string `json:"drop,omitempty"`
}

SlicerCreateNodeNetworkPolicy optionally overrides the host group's isolated-network allow/drop firewall lists for this VM launch.

type SlicerCreateNodeOptions added in v0.0.41

type SlicerCreateNodeOptions struct {
	// Wait controls server-side readiness waiting (agent/userdata). Empty means no wait.
	Wait SlicerCreateNodeWaitFor `json:"-"`
	// Timeout is optional wait timeout when Wait is set. Parsed as Go duration.
	Timeout time.Duration `json:"-"`
}

SlicerCreateNodeOptions allows typed create query params.

type SlicerCreateNodeRequest

type SlicerCreateNodeRequest struct {
	RamBytes   int64                          `json:"ram_bytes,omitempty"` // RAM size in bytes (must not exceed host group limit)
	CPUs       int                            `json:"cpus,omitempty"`      // Number of CPUs (must not exceed host group limit)
	GPUCount   int                            `json:"gpu_count,omitempty"`
	Persistent bool                           `json:"persistent,omitempty"`
	DiskImage  string                         `json:"disk_image,omitempty"`
	ImportUser string                         `json:"import_user,omitempty"`
	SSHKeys    []string                       `json:"ssh_keys,omitempty"`
	Userdata   string                         `json:"userdata,omitempty"`
	IP         string                         `json:"ip,omitempty"`
	Tags       []string                       `json:"tags,omitempty"`
	Secrets    []string                       `json:"secrets,omitempty"`
	Network    *SlicerCreateNodeNetworkPolicy `json:"network,omitempty"`
}

SlicerCreateNodeRequest contains parameters for creating a node

type SlicerCreateNodeResponse

type SlicerCreateNodeResponse struct {
	Hostname  string    `json:"hostname"`
	HostGroup string    `json:"hostgroup,omitempty"`
	IP        string    `json:"ip"`
	CreatedAt time.Time `json:"created_at"`
	Arch      string    `json:"arch,omitempty"`
}

SlicerCreateNodeResponse is the response from the REST API when creating a node.

func (*SlicerCreateNodeResponse) IPAddress

func (n *SlicerCreateNodeResponse) IPAddress() net.IP

type SlicerCreateNodeWaitFor added in v0.0.41

type SlicerCreateNodeWaitFor string

SlicerCreateNodeWaitFor controls how far the server should wait before returning.

const (
	// SlicerCreateNodeWaitAgent returns once the guest agent is reachable.
	SlicerCreateNodeWaitAgent SlicerCreateNodeWaitFor = "agent"
	// SlicerCreateNodeWaitUserdata returns once agent readiness and userdata completion are observed.
	SlicerCreateNodeWaitUserdata SlicerCreateNodeWaitFor = "userdata"
)

type SlicerDeleteResponse added in v0.0.10

type SlicerDeleteResponse struct {
	Message     string `json:"message"`
	DiskRemoved string `json:"disk_removed"`
	Error       string `json:"error"`
}

SlicerDeleteResponse represents the response from the delete endpoint

type SlicerExecRequest added in v0.0.9

type SlicerExecRequest struct {
	Command     string   `json:"command,omitempty"`
	Args        []string `json:"args,omitempty"`
	Env         []string `json:"env,omitempty"`
	UID         uint32   `json:"uid,omitempty"`
	GID         uint32   `json:"gid,omitempty"`
	Stdin       bool     `json:"stdin,omitempty"`
	Stdout      bool     `json:"stdout,omitempty"`
	Stderr      bool     `json:"stderr,omitempty"`
	Stdio       string   `json:"stdio,omitempty"`
	Shell       string   `json:"shell,omitempty"`
	Cwd         string   `json:"cwd,omitempty"`
	Permissions string   `json:"permissions,omitempty"`
}

SlicerExecRequest contains parameters for invoking a command within a VM.

type SlicerExecWriteResult added in v0.0.9

type SlicerExecWriteResult struct {
	Timestamp time.Time `json:"timestamp,omitempty,omitzero"`
	Type      string    `json:"type,omitempty"`
	Pid       int       `json:"pid,omitempty"`
	Encoding  string    `json:"encoding,omitempty"`
	Data      string    `json:"data,omitempty"`
	StartedAt time.Time `json:"started_at,omitempty,omitzero"`
	EndedAt   time.Time `json:"ended_at,omitempty,omitzero"`
	Signal    string    `json:"signal,omitempty"`
	Stdout    string    `json:"stdout,omitempty"`
	Stderr    string    `json:"stderr,omitempty"`
	ExitCode  int       `json:"exit_code"`
	Error     string    `json:"error,omitempty"`

	// Background-exec extensions. The foreground /exec streaming API never sets
	// these; they are emitted by the background-exec log stream.
	ID            uint64 `json:"id,omitempty"`
	DroppedBytes  int64  `json:"dropped_bytes,omitempty"`
	DroppedFrames int    `json:"dropped_frames,omitempty"`
	Message       string `json:"message,omitempty"`
}

ExecWriteResult represents output from commands executing within a microVM.

func (SlicerExecWriteResult) DataBytes added in v0.0.41

func (r SlicerExecWriteResult) DataBytes() ([]byte, error)

func (SlicerExecWriteResult) StderrBytes added in v0.0.41

func (r SlicerExecWriteResult) StderrBytes() ([]byte, error)

func (SlicerExecWriteResult) StdoutBytes added in v0.0.41

func (r SlicerExecWriteResult) StdoutBytes() ([]byte, error)

type SlicerFSInfo added in v0.0.38

type SlicerFSInfo struct {
	Name  string    `json:"name"`
	Type  string    `json:"type"`
	Size  int64     `json:"size"`
	Mtime time.Time `json:"mtime"`
	Mode  string    `json:"mode"`
}

SlicerFSInfo represents file system entry metadata returned by VM fs endpoints.

type SlicerFSMkdirRequest added in v0.0.38

type SlicerFSMkdirRequest struct {
	Path      string `json:"path"`
	Recursive bool   `json:"recursive,omitempty"`
	Mode      string `json:"mode,omitempty"`
}

SlicerFSMkdirRequest contains parameters for mkdir on a VM.

type SlicerFSWatchEvent added in v0.0.44

type SlicerFSWatchEvent struct {
	ID        uint64 `json:"id"`
	Type      string `json:"type"`
	Path      string `json:"path"`
	Timestamp string `json:"timestamp"`
	Size      int64  `json:"size"`
	IsDir     bool   `json:"isDir"`
	Message   string `json:"message,omitempty"`
}

SlicerFSWatchEvent is one filesystem event delivered over the watch stream. ID is the monotonic per-stream id from the SSE `id:` line. Timestamp is left as a string to isolate the SDK from any future wire-format drift; use ParseFSWatchTimestamp to decode it.

type SlicerFSWatchRequest added in v0.0.44

type SlicerFSWatchRequest struct {
	Paths       []string `json:"paths,omitempty"`
	Patterns    []string `json:"patterns,omitempty"`
	Events      []string `json:"events,omitempty"`
	UID         uint32   `json:"uid,omitempty"`
	Recursive   bool     `json:"recursive,omitempty"`
	OneShot     bool     `json:"one_shot,omitempty"`
	Debounce    string   `json:"debounce,omitempty"`
	Timeout     string   `json:"timeout,omitempty"`
	MaxEvents   int      `json:"max_events,omitempty"`
	LastEventID string   `json:"last_event_id,omitempty"`
}

SlicerFSWatchRequest configures a filesystem watch stream.

Paths, Patterns and Events are repeated query parameters. Empty Events delivers all types (create, write, remove, rename, chmod).

LastEventID is sent as the SSE `Last-Event-ID` HTTP header. The server validates it as a uint64; cross-connection replay is not yet implemented — the field is accepted for forward compatibility.

type SlicerHostGroup

type SlicerHostGroup struct {
	Name     string `json:"name,omitempty"`
	Count    int    `json:"count,omitempty"`
	RamBytes int64  `json:"ram_bytes,omitempty"` // RAM size in bytes
	CPUs     int    `json:"cpus,omitempty"`
	Arch     string `json:"arch,omitempty"`
	GPUCount int    `json:"gpu_count,omitempty"`
}

SlicerHostGroup represents a host group from the /hostgroup endpoint.

type SlicerInfo added in v0.0.21

type SlicerInfo struct {
	// Version is the version of the slicer server
	Version string `json:"version,omitempty"`

	// GitCommit is the git commit hash of the slicer server
	GitCommit string `json:"git_commit,omitempty"`

	// Platform indicates the server operating system (runtime.GOOS).
	Platform string `json:"platform,omitempty"`

	// Arch is the server architecture (runtime.GOARCH).
	Arch string `json:"arch,omitempty"`
}

SlicerInfo represents version and server information from the /info endpoint

type SlicerLogsResponse added in v0.0.10

type SlicerLogsResponse struct {
	Hostname string `json:"hostname"`
	Lines    int    `json:"lines"`
	Content  string `json:"content"`
}

SlicerLogsResponse represents the response from the logs endpoint

type SlicerNode

type SlicerNode struct {
	Hostname   string    `json:"hostname"`
	HostGroup  string    `json:"hostgroup,omitempty"`
	IP         string    `json:"ip"`
	RamBytes   int64     `json:"ram_bytes,omitempty"` // RAM size in bytes
	CPUs       int       `json:"cpus,omitempty"`
	CreatedAt  time.Time `json:"created_at"`
	Arch       string    `json:"arch,omitempty"`
	Tags       []string  `json:"tags,omitempty"`
	Status     string    `json:"status,omitempty"` // "Running", "Paused", or "Stopped"
	Persistent bool      `json:"persistent,omitempty"`
}

SlicerNode represents a node managed by the slicer REST API.

type SlicerNodeStat added in v0.0.10

type SlicerNodeStat struct {
	Hostname  string          `json:"hostname"`
	IP        string          `json:"ip"`
	CreatedAt time.Time       `json:"created_at"`
	Snapshot  *SlicerSnapshot `json:"snapshot"`
	Error     string          `json:"error"`
}

SlicerNodeStat represents stats for a VM node

type SlicerRestoreVMOptions added in v0.0.48

type SlicerRestoreVMOptions struct {
	// Wait controls server-side readiness waiting. Empty means no wait.
	Wait SlicerRestoreVMWaitFor `json:"-"`
	// Timeout is optional wait timeout when Wait is set.
	Timeout time.Duration `json:"-"`
}

SlicerRestoreVMOptions mirrors SlicerCreateNodeOptions for the /vm/{h}/restore endpoint.

type SlicerRestoreVMWaitFor added in v0.0.48

type SlicerRestoreVMWaitFor string

SlicerRestoreVMWaitFor controls server-side readiness waiting for restore. Userdata is intentionally not exposed here: snapshot resume returns to a guest that has already booted, so the userdata-ran sentinel is irrelevant.

const (
	SlicerRestoreVMWaitNone  SlicerRestoreVMWaitFor = ""
	SlicerRestoreVMWaitAgent SlicerRestoreVMWaitFor = "agent"
)

type SlicerShutdownRequest added in v0.0.19

type SlicerShutdownRequest struct {
	// Action specifies the shutdown action: "shutdown" (halt) or "reboot" (restart).
	// If empty, defaults to "shutdown".
	Action string `json:"action,omitempty"`
}

SlicerShutdownRequest contains parameters for shutting down or rebooting a VM. Action can be "shutdown" (default) to halt the VM or "reboot" to restart it.

type SlicerSnapshot added in v0.0.10

type SlicerSnapshot struct {
	Hostname             string    `json:"hostname"`
	Arch                 string    `json:"arch"`
	Timestamp            time.Time `json:"timestamp"`
	Uptime               string    `json:"uptime"`
	TotalCPUS            int       `json:"totalCpus"`
	TotalMemory          uint64    `json:"totalMemory"`
	MemoryUsed           uint64    `json:"memoryUsed"`
	MemoryAvailable      uint64    `json:"memoryAvailable"`
	MemoryUsedPercent    float64   `json:"memoryUsedPercent"`
	LoadAvg1             float64   `json:"loadAvg1"`
	LoadAvg5             float64   `json:"loadAvg5"`
	LoadAvg15            float64   `json:"loadAvg15"`
	DiskReadTotal        float64   `json:"diskReadTotal"`
	DiskWriteTotal       float64   `json:"diskWriteTotal"`
	NetworkReadTotal     float64   `json:"networkReadTotal"`
	NetworkWriteTotal    float64   `json:"networkWriteTotal"`
	DiskIOInflight       int64     `json:"diskIOInflight"`
	OpenConnections      int64     `json:"openConnections"`
	OpenFiles            int64     `json:"openFiles"`
	Entropy              int64     `json:"entropy"`
	DiskSpaceTotal       uint64    `json:"diskSpaceTotal"`
	DiskSpaceUsed        uint64    `json:"diskSpaceUsed"`
	DiskSpaceFree        uint64    `json:"diskSpaceFree"`
	DiskSpaceUsedPercent float64   `json:"diskSpaceUsedPercent"`
}

SlicerSnapshot represents a snapshot of VM metrics

type UpdateSecretRequest added in v0.0.6

type UpdateSecretRequest struct {
	// Data is the updated secret content
	Data string `json:"data"`
	// Permissions specifies the file permissions
	Permissions string `json:"permissions,omitempty"`

	// GID is the user ID that should own the secret file. If not set, the default for
	// a uint32 will be used i.e root.
	UID uint32 `json:"uid,omitempty"`

	// GID is the group ID that should own the secret file. If not set, the default for
	// a uint32 will be used i.e root.
	GID uint32 `json:"gid,omitempty"`
}

UpdateSecretRequest is the payload for updating an existing secret via the REST API. All fields are optional - only provided fields will be updated.

Directories

Path Synopsis
examples
shell-test command
shell-test serves a minimal React + xterm.js UI that connects to a Slicer VM shell via the SDK's shell.ProxyHandler.
shell-test serves a minimal React + xterm.js UI that connects to a Slicer VM shell via the SDK's shell.ProxyHandler.
Package forward implements host-to-VM port forwarding for Slicer.
Package forward implements host-to-VM port forwarding for Slicer.
Package shell provides an HTTP handler that proxies browser WebSocket connections to a Slicer VM's interactive shell endpoint.
Package shell provides an HTTP handler that proxies browser WebSocket connections to a Slicer VM's interactive shell endpoint.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL