Documentation
¶
Overview ¶
Package agentlink is the panel side of the agent connection (docs/agent-protocol.md): a WebSocket over mTLS on a dedicated listener, carrying JSON messages.
Index ¶
- Constants
- Variables
- type AllocationSpec
- type CertRenew
- type CertRenewed
- type ConfigFileSpec
- type ConsoleCommand
- type ConsoleLines
- type CronJob
- type FileChunk
- type FileDelete
- type FileEntry
- type FileList
- type FilePath
- type FileRead
- type FileRename
- type FileWrite
- type Hello
- type HelloOK
- type Hub
- func (h *Hub) Command(ctx context.Context, nodeID, serviceID, command string) error
- func (h *Hub) Disconnect(nodeID string, reason string)
- func (h *Hub) Handler() http.Handler
- func (h *Hub) Online(nodeID string) (bool, time.Time)
- func (h *Hub) Request(ctx context.Context, nodeID, typ string, data any) (Message, error)
- func (h *Hub) Unwatch(sub *Subscriber)
- func (h *Hub) Watch(ctx context.Context, nodeID, serviceID string) (*Subscriber, []string, error)
- type InstallSpec
- type Limits
- type Message
- type PowerRequest
- type SFTPAuth
- type SFTPLogin
- type ServiceRef
- type ServiceSpec
- type ServiceState
- type Stats
- type StopSpec
- type Subscriber
- type WebBackup
- type WebCapabilities
- type WebDatabase
- type WebDomain
- type WebLimits
- type WebsiteApp
- type WebsiteAppResult
- type WebsiteBackup
- type WebsiteBackupList
- type WebsiteDB
- type WebsiteDBList
- type WebsiteSpec
- type WebsiteStatus
Constants ¶
const ( TypeHello = "hello" // agent -> panel, first message TypeHelloOK = "hello.ok" // panel -> agent TypeError = "error" // either direction, connection-level error )
Message types.
const ( TypeOK = "ok" // reply: request accepted TypeServiceCreate = "service.create" // panel -> agent: ServiceSpec; agent installs, then reports state TypeServiceReinstall = "service.reinstall" // panel -> agent: ServiceSpec; wipe nothing, rerun install TypeServiceDelete = "service.delete" // panel -> agent: ServiceRef; stop, remove container and data TypeServicePower = "service.power" // panel -> agent: PowerRequest TypeServiceState = "service.state" // agent -> panel: ServiceState (event, no reply) )
Service message types (docs/agent-protocol.md).
const ( StatePending = "pending" // panel only: not delivered to the agent yet StateInstalling = "installing" StateInstallFailed = "install_failed" StateOffline = "offline" StateStarting = "starting" StateRunning = "running" StateStopping = "stopping" StateCrashed = "crashed" )
Service states reported by the agent.
const ( TypeConsoleBacklog = "console.backlog" // panel -> agent: ServiceRef; reply ConsoleLines TypeConsoleSubscribe = "console.subscribe" // panel -> agent: ServiceRef; stream lines and stats TypeConsoleUnsubscribe = "console.unsubscribe" // panel -> agent: ServiceRef TypeConsoleCommand = "console.command" // panel -> agent: ConsoleCommand TypeConsoleLine = "console.line" // agent -> panel event: ConsoleLines TypeStats = "stats" // agent -> panel event: Stats )
Console and statistics message types.
const ( TypeFilesList = "files.list" // FilePath -> FileList TypeFilesRead = "files.read" // FileRead -> FileChunk TypeFilesWrite = "files.write" // FileWrite TypeFilesMkdir = "files.mkdir" // FilePath TypeFilesRename = "files.rename" // FileRename TypeFilesDelete = "files.delete" // FileDelete )
File operations (panel -> agent); paths are relative to the service's data directory.
const ( TypeWebsiteApply = "website.apply" // panel -> agent: WebsiteSpec (create or update, idempotent) TypeWebsiteDelete = "website.delete" // panel -> agent: ServiceRef; removes the account, its files and databases TypeWebsiteStatus = "website.status" // panel -> agent: ServiceRef -> WebsiteStatus TypeWebsiteDB = "website.db" // panel -> agent: WebsiteDB -> WebsiteDBList TypeWebsiteBackup = "website.backup" // panel -> agent: WebsiteBackup -> WebsiteBackupList TypeWebsiteApp = "website.app" // panel -> agent: WebsiteApp (WordPress install, Git deploy) )
Web hosting (Phase 3). A website is one hosting account: a Linux user, its own PHP-FPM master (systemd unit with cgroup limits), Caddy site blocks, MariaDB databases and cron.
const ChunkSize = 512 << 10
ChunkSize is the largest piece of file data in one message.
const ConnectPath = "/api/agent/v1/connect"
ConnectPath is where agents open their WebSocket on the agent listener.
const Protocol = 1
Protocol is the protocol version this panel speaks.
const TypeCertRenew = "cert.renew"
TypeCertRenew is an agent -> panel request: CertRenew, answered with CertRenewed.
const TypeSFTPAuth = "sftp.auth"
TypeSFTPAuth is an agent -> panel request: SFTPAuth, answered with SFTPLogin.
Variables ¶
var ErrOffline = errors.New("node is offline")
ErrOffline is returned by Request when the node has no live connection.
Functions ¶
This section is empty.
Types ¶
type AllocationSpec ¶
AllocationSpec is the IP:port the service listens on (TCP and UDP).
type CertRenew ¶
type CertRenew struct {
CSR string `json:"csr"`
}
CertRenew carries a certificate request for a fresh node key.
type CertRenewed ¶
type CertRenewed struct {
Certificate string `json:"certificate"`
ExpiresAt time.Time `json:"expires_at"`
}
CertRenewed is the new client certificate (PEM).
type ConfigFileSpec ¶
type ConfigFileSpec struct {
Path string `json:"path"`
Parser string `json:"parser"`
Find json.RawMessage `json:"find"`
}
ConfigFileSpec is one egg config file rewrite (applied by the agent before each start).
type ConsoleCommand ¶
ConsoleCommand is a line typed into the server console.
type ConsoleLines ¶
ConsoleLines carries console output (newest last).
type FileDelete ¶
FileDelete removes files and directories.
type FileEntry ¶
type FileEntry struct {
Name string `json:"name"`
Size int64 `json:"size"`
Mode string `json:"mode"`
ModTime int64 `json:"mod_time"`
IsDir bool `json:"is_dir"`
Symlink bool `json:"symlink"`
}
FileEntry is one directory entry.
type FileRead ¶
type FileRead struct {
ID string `json:"id"`
Path string `json:"path"`
Offset int64 `json:"offset"`
Length int `json:"length"`
}
FileRead asks for up to Length bytes at Offset.
type FileRename ¶
type FileRename struct {
ID string `json:"id"`
From string `json:"from"`
To string `json:"to"`
Overwrite bool `json:"overwrite,omitempty"`
}
FileRename moves From to To; Overwrite may replace an existing regular file.
type FileWrite ¶
type FileWrite struct {
ID string `json:"id"`
Path string `json:"path"`
Content string `json:"content,omitempty"`
Data []byte `json:"data,omitempty"`
Append bool `json:"append,omitempty"`
}
FileWrite writes Content (text) or Data; Append adds to the end.
type Hello ¶
type Hello struct {
Protocol int `json:"protocol"`
AgentVersion string `json:"agent_version"`
Hostname string `json:"hostname"`
OS string `json:"os"`
Kernel string `json:"kernel"`
Arch string `json:"arch"`
CPUs int `json:"cpus"`
MemoryBytes uint64 `json:"memory_bytes"`
DiskBytes uint64 `json:"disk_bytes"`
DiskFreeBytes uint64 `json:"disk_free_bytes"`
DockerVersion string `json:"docker_version"`
SFTPPort int `json:"sftp_port"`
// Services the agent knows about and their current state.
Services []ServiceState `json:"services"`
// Web is the node's web hosting stack (nil = no web hosting).
Web *WebCapabilities `json:"web,omitempty"`
// Websites the agent knows.
Websites []string `json:"websites,omitempty"`
}
Hello is what the agent reports about itself and its machine when it connects.
type Hub ¶
type Hub struct {
// OnConnect runs (in its own goroutine) after each successful handshake, e.g. to
// deliver services created while the node was offline.
OnConnect func(nodeID string)
// OnRequest answers requests an agent sends to the panel (e.g. sftp.auth). It runs in its
// own goroutine; the returned value becomes the reply's data.
OnRequest func(ctx context.Context, nodeID string, msg Message) (any, error)
// contains filtered or unexported fields
}
Hub tracks connected agents.
func (*Hub) Disconnect ¶
Disconnect closes a node's connection, e.g. after the node was deleted.
func (*Hub) Handler ¶
Handler serves the agent WebSocket. It must run behind the mTLS listener (pki.CA.ServerTLS), which guarantees a client certificate signed by the panel CA.
func (*Hub) Request ¶
Request sends a message to a node's agent and waits for its reply. An agent error reply is returned as an error.
func (*Hub) Unwatch ¶
func (h *Hub) Unwatch(sub *Subscriber)
Unwatch removes a subscriber; the agent stops streaming when the last one leaves.
type InstallSpec ¶
type InstallSpec struct {
Container string `json:"container"`
Entrypoint string `json:"entrypoint"`
Script string `json:"script"`
}
InstallSpec is the egg's install script and the container it runs in.
type Limits ¶
type Limits struct {
MemoryMB int `json:"memory_mb"`
CPUPercent int `json:"cpu_percent"` // 100 = one core; 0 = unlimited
DiskMB int `json:"disk_mb"` // 0 = unlimited
PIDs int `json:"pids"`
}
Limits are the container's resource limits.
type Message ¶
type Message struct {
ID string `json:"id,omitempty"`
Type string `json:"type"`
ReplyTo string `json:"reply_to,omitempty"`
Error string `json:"error,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
}
Message is the envelope for every frame in both directions.
type PowerRequest ¶
type PowerRequest struct {
ID string `json:"id"`
Action string `json:"action"` // start | stop | restart | kill
}
PowerRequest asks the agent to start, stop, restart or kill a service.
type SFTPAuth ¶
type SFTPAuth struct {
Username string `json:"username"`
Password string `json:"password"`
IP string `json:"ip"`
}
SFTPAuth asks whether a username/password may open a service over SFTP. Usernames are "<email>.<last 8 characters of the service ID>".
type SFTPLogin ¶
type SFTPLogin struct {
ServiceID string `json:"service_id"`
}
SFTPLogin names the service the user may access.
type ServiceSpec ¶
type ServiceSpec struct {
ID string `json:"id"`
Image string `json:"image"`
Invocation string `json:"invocation"` // startup command with variables substituted
Env map[string]string `json:"env"`
Install InstallSpec `json:"install"`
Stop StopSpec `json:"stop"`
DoneMarkers []string `json:"done_markers"`
ConfigFiles []ConfigFileSpec `json:"config_files"`
Limits Limits `json:"limits"`
Allocation AllocationSpec `json:"allocation"`
// SkipInstall: the files already exist (a server migrated from Wings); a first create
// adopts them instead of running the install script.
SkipInstall bool `json:"skip_install,omitempty"`
}
ServiceSpec is a blueprint resolved for one service: everything the agent needs, nothing it must look up.
type ServiceState ¶
type ServiceState struct {
ID string `json:"id"`
State string `json:"state"`
Detail string `json:"detail,omitempty"`
}
ServiceState is the agent's report of a service's state.
type Stats ¶
type Stats struct {
ID string `json:"id"`
CPUPercent float64 `json:"cpu_percent"`
MemoryBytes uint64 `json:"memory_bytes"`
MemoryLimitBytes uint64 `json:"memory_limit_bytes"`
NetRxBytes uint64 `json:"net_rx_bytes"`
NetTxBytes uint64 `json:"net_tx_bytes"`
DiskBytes uint64 `json:"disk_bytes"`
}
Stats is a resource sample of a running service.
type StopSpec ¶
type StopSpec struct {
Command string `json:"command,omitempty"`
Signal string `json:"signal,omitempty"`
}
StopSpec is how to stop the server: a console command, or a signal.
type Subscriber ¶
type Subscriber struct {
C chan Message
// contains filtered or unexported fields
}
Subscriber receives a service's console lines, stats and state changes.
type WebBackup ¶
type WebBackup struct {
File string `json:"file"`
SizeBytes int64 `json:"size_bytes"`
CreatedAt time.Time `json:"created_at"`
}
WebBackup is one archive.
type WebCapabilities ¶
type WebCapabilities struct {
PHP []string `json:"php"`
Caddy bool `json:"caddy"`
MariaDB bool `json:"mariadb"`
}
WebCapabilities is what a node offers for web hosting (sent in hello).
type WebDatabase ¶
WebDatabase is one database.
type WebDomain ¶
type WebDomain struct {
Name string `json:"name"`
Aliases []string `json:"aliases,omitempty"`
Root string `json:"root"` // document root relative to ~/sites/<name> ("public", "." …)
TLS string `json:"tls"` // "auto" (ACME) or "internal" (Caddy's local CA, for testing)
}
WebDomain is a site of the account: files in ~/sites/<name>/, served from Root inside it.
type WebLimits ¶
type WebLimits struct {
DiskMB int `json:"disk_mb"`
MemoryMB int `json:"memory_mb"`
CPUPercent int `json:"cpu_percent"`
Processes int `json:"processes"`
}
WebLimits are the account's resources.
type WebsiteApp ¶
type WebsiteApp struct {
ID string `json:"id"`
App string `json:"app"` // wordpress | git
Domain string `json:"domain"` // one of the account's domains
// WordPress: an existing database of the account.
DBName string `json:"db_name,omitempty"`
DBPassword string `json:"db_password,omitempty"`
// Git: HTTPS repository; a first deploy clones into the domain directory, later ones pull.
Repo string `json:"repo,omitempty"`
Branch string `json:"branch,omitempty"`
}
WebsiteApp installs or deploys an application into a domain.
type WebsiteAppResult ¶
type WebsiteAppResult struct {
Message string `json:"message"`
}
WebsiteAppResult describes what happened.
type WebsiteBackup ¶
type WebsiteBackup struct {
ID string `json:"id"`
Action string `json:"action"`
File string `json:"file,omitempty"`
}
WebsiteBackup: action create, restore (File), delete (File) or list.
type WebsiteBackupList ¶
type WebsiteBackupList struct {
Backups []WebBackup `json:"backups"`
}
WebsiteBackupList lists backups in ~/backups.
type WebsiteDB ¶
type WebsiteDB struct {
ID string `json:"id"`
Action string `json:"action"`
Name string `json:"name,omitempty"`
Password string `json:"password,omitempty"`
}
WebsiteDB manages a database: action create (with password), password, delete, or list.
type WebsiteDBList ¶
type WebsiteDBList struct {
Databases []WebDatabase `json:"databases"`
}
WebsiteDBList lists the account's databases and their sizes.
type WebsiteSpec ¶
type WebsiteSpec struct {
ID string `json:"id"`
Username string `json:"username"` // Linux user, also the database name prefix
PHPVersion string `json:"php_version"`
Domains []WebDomain `json:"domains"`
Limits WebLimits `json:"limits"`
PHP map[string]string `json:"php,omitempty"` // php.ini overrides (allow-listed keys)
Cron []CronJob `json:"cron,omitempty"`
Suspended bool `json:"suspended"`
BackupsKeep int `json:"backups_keep,omitempty"`
}
WebsiteSpec describes a hosting account.