cli

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package cli is the rainier CLI's HTTP client and on-disk config — the pieces cmd/rainier composes into the actual command surface, and the pieces a smoke test can drive against a real controld without going through main().

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ProgressLine

func ProgressLine(verb string, done, total int64) string

ProgressLine renders one line of transfer progress. It is a function rather than a Printf at the call site so the formatting has a test and both directions read the same.

A total of zero means "unknown", which is a pull: nothing on the client side knows how big the archive is until it ends.

func Pull

func Pull(c *Client, sessionID, remotePath, localDir string, progress func(received, total int64)) error

Pull downloads remotePath from session id and extracts it into localDir, which is created if it does not exist.

progress, when non-nil, is called as bytes arrive; the total is 0 because nothing on this side knows it until the stream ends.

func Push

func Push(c *Client, sessionID, localDir, remotePath string, progress func(sent, total int64)) error

Push tars localDir and streams it to remotePath inside session id.

progress, when non-nil, is called after every acked chunk with the bytes sent so far and the archive's total size.

func RandHex

func RandHex(n int) string

RandHex returns n random bytes rendered as 2n lowercase hex characters — used for X-Request-Id (below) and by cmd/rainier for a fresh Idempotency-Key per `rainier new` invocation.

func Save

func Save(c Config) error

Save writes c to the config file, creating its directory (0700) if necessary. The file itself is 0600: it carries a bearer token.

Types

type APIError

type APIError struct {
	Code    string
	Message string
}

APIError is controld's stable non-2xx error envelope. Error preserves the CLI's existing "code: message" text while errors.As lets callers make decisions from Code instead of parsing prose.

func (*APIError) Error

func (e *APIError) Error() string

type Client

type Client struct {
	Base  string
	Token string
	HTTP  *http.Client
}

Client is the rainier CLI's HTTP client: a controld base URL, the bearer token to authenticate with, and (optionally) a caller-supplied *http.Client — nil means http.DefaultClient.

func (*Client) Do

func (c *Client) Do(method, path string, in, out any, opts ...Option) error

Do issues method against path (appended verbatim to c.Base — callers own their own query strings), marshaling in as the JSON body (skipped when in is nil) and decoding a 2xx response into out (skipped when out is nil). It always sets Authorization (when c.Token is set) and a fresh X-Request-Id; opts may add more headers (IdempotencyKey).

Errors are send's, below — including the error-envelope decoding every non-2xx response on this API gets.

func (*Client) DoContext

func (c *Client) DoContext(ctx context.Context, method, path string, in, out any, opts ...Option) error

DoContext is Do with the request bound to ctx. Use it for polling and other bounded operations so cancellation can interrupt a stalled transport.

func (*Client) Open

func (c *Client) Open(method, path string, opts ...Option) (io.ReadCloser, error)

Open is Do for a response that is NOT JSON: it returns the successful response's body for the caller to read and close. The one such response on this API is a pull's archive (GET /v0/sessions/{id}/files), which is streamed and may be hundreds of megabytes — decoding it into memory the way Do does would defeat the point of streaming it.

Failures are identical to Do's: a non-2xx is read as the error envelope and returned as an error, with the body already closed, so a caller only ever holds a body it is going to read.

type Config

type Config struct {
	ServerURL string `json:"server_url"`
	Token     string `json:"token"`
	OwnerID   string `json:"owner_id,omitempty"`
}

Config is what `rainier login` writes and every other command reads: the controld server to talk to, and the bearer token to talk to it with.

OwnerID is the caller's own user id, learned at login from the identity controld returns (the same one GET /v0/me answers with) and cached here so every later command has it without a round trip. It is the string a session row carries as owner_id, and it is used to break ties when a session name resolves to more than one session; see cmd/rainier's resolveSessionID. Empty only for a config written before logins carried it — one `rainier login` fills it in.

func Load

func Load() (Config, error)

Load reads the config file, returning a zero Config (not an error) if it doesn't exist yet — "not logged in" is an ordinary state every command has to handle, not a failure Load itself should report.

type Option

type Option func(*http.Request)

Option adjusts one Do call's request before it's sent — the "path-independent option" mechanism for headers that aren't part of every request, namely Idempotency-Key.

func IdempotencyKey

func IdempotencyKey(key string) Option

IdempotencyKey sets the Idempotency-Key header for one Do call. Callers that need one (POST /v0/sessions) generate a fresh key per invocation — Do itself never invents one, since only the caller knows which calls are retries of the same intent and which are new.

Jump to

Keyboard shortcuts

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