remotenodes

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package remotenodes owns the desktop's local node configuration and credential lifecycle.

Index

Constants

View Source
const (
	CurrentFormat     = 1
	MaxNodes          = 64
	MaxCredentialRefs = 1024
	MaxFileBytes      = 4 << 20
)
View Source
const ObservationLifetime = 45 * time.Second

Variables

View Source
var (
	ErrInvalid           = errors.New("invalid_remote_node_configuration")
	ErrUnsupported       = errors.New("remote_node_configuration_upgrade_required")
	ErrConflict          = errors.New("remote_node_revision_conflict")
	ErrNotFound          = errors.New("remote_node_not_found")
	ErrDuplicate         = errors.New("remote_installation_already_configured")
	ErrRePairRequired    = errors.New("remote_node_connection_identity_is_bound")
	ErrReferenced        = errors.New("remote_node_still_referenced")
	ErrUsageUnknown      = errors.New("remote_node_usage_unavailable")
	ErrCommitUnconfirmed = errors.New("remote_node_configuration_commit_unconfirmed")
	ErrCredential        = errors.New("remote_node_credential_unavailable")
	ErrBusy              = errors.New("remote_node_checks_busy")
)
View Source
var ErrUpgradeIdentity = errors.New("remote_upgrade_identity_conflict")

Functions

This section is empty.

Types

type ArtifactSource

type ArtifactSource interface {
	Open(context.Context, string, string) (*runnerartifacts.Artifact, error)
}

type Authentication

type Authentication struct {
	Kind          AuthenticationKind `json:"kind"`
	PasswordRef   string             `json:"password_ref"`
	PrivateKeyRef string             `json:"private_key_ref"`
	PassphraseRef string             `json:"passphrase_ref"`
}

type AuthenticationKind

type AuthenticationKind string
const (
	AuthenticationPassword   AuthenticationKind = "password"
	AuthenticationPrivateKey AuthenticationKind = "private_key"
)

type BindCommand

type BindCommand struct {
	ID               string
	ExpectedRevision uint64
	Identity         runnerinstall.Identity
	Token            *credentials.Lease
}

func (BindCommand) GoString

func (BindCommand) GoString() string

func (BindCommand) MarshalJSON

func (BindCommand) MarshalJSON() ([]byte, error)

func (BindCommand) String

func (BindCommand) String() string

type Binding

type Binding struct {
	Identity runnerinstall.Identity `json:"identity"`
	TokenRef string                 `json:"token_ref"`
}

type Configuration

type Configuration struct {
	Format         int       `json:"format"`
	Revision       uint64    `json:"revision"`
	Default        Selection `json:"default"`
	Nodes          []Node    `json:"nodes"`
	CredentialRefs []string  `json:"credential_refs"`
}

func (Configuration) Validate

func (config Configuration) Validate() error

type Connection

type Connection struct {
	Node           Node
	Authentication remotessh.Authentication
	// contains filtered or unexported fields
}

func (*Connection) Close

func (connection *Connection) Close() error

func (*Connection) GoString

func (*Connection) GoString() string

func (*Connection) MarshalJSON

func (*Connection) MarshalJSON() ([]byte, error)

func (*Connection) String

func (*Connection) String() string

type Dependencies

type Dependencies struct {
	Store       *FileStore
	Credentials credentials.Store
	Now         func() time.Time
	// Must consult accepted, uncertain and undownloaded local job ownership.
	// Absence fails closed; removing a node never uninstalls its server runner.
	CanRemove func(context.Context, Node) error
}

type FileStore

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

FileStore uses the same cross-process advisory lock and durable replacement primitives as authored catalogs. nodes.json belongs to the user config root.

func NewFileStore

func NewFileStore(path string) (*FileStore, error)

func (*FileStore) Read

func (store *FileStore) Read(ctx context.Context) (Configuration, error)

type HostKey

type HostKey struct {
	Type        string `json:"type"`
	Fingerprint string `json:"fingerprint"`
}

type HostKeyConfirmation

type HostKeyConfirmation struct {
	ID               string
	ExpectedRevision uint64
	Key              HostKey
}

type Installation

type Installation struct {
	Request            runnerinstall.Request `json:"request"`
	Release            string                `json:"release"`
	Arch               string                `json:"arch"`
	Stage              string                `json:"stage"`
	ErrorCode          string                `json:"error_code"`
	TemporaryDirectory string                `json:"temporary_directory"`
	CleanupPending     bool                  `json:"cleanup_pending"`
}

type InstallationCommand

type InstallationCommand struct {
	ID                  string
	ExpectedRevision    uint64
	ExpectedOperationID string
	Installation        Installation
}

type Manager

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

func NewManager

func NewManager(ctx context.Context, dependencies ManagerDependencies) (*Manager, error)

func (*Manager) Check

func (manager *Manager) Check(ctx context.Context, id string, expected uint64) error

Check waits for an application-owned check. Ending the observer's context stops only this wait; closing the manager stops its SSH activity, never jobs.

func (*Manager) Close

func (manager *Manager) Close() error

func (*Manager) ConfirmHostKey

func (manager *Manager) ConfirmHostKey(ctx context.Context, command HostKeyConfirmation) (Node, error)

ConfirmHostKey acknowledges the exact, fresh key shown by the last check. A changed previously confirmed key requires an explicit new node definition.

func (*Manager) GetUpgrade

func (manager *Manager) GetUpgrade(ctx context.Context, id string) (*Upgrade, error)

GetUpgrade reads only the local intent. It never authenticates, starts work, polls a remote node or turns an uncertain acknowledgment into confirmation.

func (*Manager) RecoverUpgrade

func (manager *Manager) RecoverUpgrade(ctx context.Context, action UpgradeAction) (*Upgrade, error)

func (*Manager) Refresh

func (manager *Manager) Refresh(ctx context.Context, id string, expected uint64) error

func (*Manager) Remove

func (manager *Manager) Remove(ctx context.Context, id string, expected uint64) error

func (*Manager) RetryInstallation

func (manager *Manager) RetryInstallation(ctx context.Context, id string, expected uint64) error

func (*Manager) RetryUpgrade

func (manager *Manager) RetryUpgrade(ctx context.Context, action UpgradeAction) (*Upgrade, error)

func (*Manager) Run

func (manager *Manager) Run() error

Run performs independent per-node checks every 15 seconds. A slow or offline node never blocks checks of another node. Call Close and join Run at shutdown.

func (*Manager) Save

func (manager *Manager) Save(ctx context.Context, command SaveCommand) (Node, error)

func (*Manager) SelectDefault

func (manager *Manager) SelectDefault(ctx context.Context, expected uint64, target jobcontract.ExecutionTarget) error

func (*Manager) SetTaskConcurrency

func (manager *Manager) SetTaskConcurrency(ctx context.Context, command TaskConcurrencyCommand) error

func (*Manager) Snapshot

func (manager *Manager) Snapshot(ctx context.Context) (Snapshot, error)

func (*Manager) StartUpgrade

func (manager *Manager) StartUpgrade(ctx context.Context, command UpgradeCommand) (*Upgrade, error)

type ManagerDependencies

type ManagerDependencies struct {
	Configuration *Service
	Artifacts     ArtifactSource
	Release       string
	Connect       Connector
}

type Node

type Node struct {
	domain.EntityMeta
	Name           string         `json:"name"`
	Region         string         `json:"region"`
	Host           string         `json:"host"`
	Port           uint16         `json:"port"`
	User           string         `json:"user"`
	Enabled        bool           `json:"enabled"`
	Authentication Authentication `json:"authentication"`
	HostKey        *HostKey       `json:"host_key"`
	Binding        *Binding       `json:"binding"`
	Installation   *Installation  `json:"installation"`
	Observation    *Observation   `json:"observation"`
}

func (Node) Endpoint

func (node Node) Endpoint() remotessh.Endpoint

func (Node) Validate

func (node Node) Validate() error

type NodeView

type NodeView struct {
	ID                 string             `json:"id"`
	Revision           uint64             `json:"revision"`
	Name               string             `json:"name"`
	Region             string             `json:"region"`
	Host               string             `json:"host"`
	Port               uint16             `json:"port"`
	User               string             `json:"user"`
	Enabled            bool               `json:"enabled"`
	AuthenticationKind AuthenticationKind `json:"authentication_kind"`
	HasAuthentication  bool               `json:"has_authentication"`
	HasPassphrase      bool               `json:"has_passphrase"`
	HostKey            *HostKey           `json:"host_key"`
	RunnerNodeID       string             `json:"runner_node_id"`
	InstallationID     string             `json:"installation_id"`
	Installation       *Installation      `json:"installation"`
	Upgrade            *Upgrade           `json:"upgrade"`
	Observation        *Observation       `json:"observation"`
	Status             string             `json:"status"`
	Eligible           bool               `json:"eligible"`
	Checking           bool               `json:"checking"`
}

type Observation

type Observation struct {
	CheckedAt       time.Time               `json:"checked_at"`
	Status          string                  `json:"status"`
	ProposedHostKey *HostKey                `json:"proposed_host_key"`
	System          *remotessh.SystemInfo   `json:"system"`
	Runner          *jobcontract.RunnerInfo `json:"runner"`
}

type Pairing

type Pairing struct {
	Identity runnerinstall.Identity
	Runner   jobcontract.RunnerInfo
	Token    *credentials.Lease
}

func (Pairing) GoString

func (Pairing) GoString() string

func (Pairing) MarshalJSON

func (Pairing) MarshalJSON() ([]byte, error)

func (Pairing) String

func (Pairing) String() string

type SaveCommand

type SaveCommand struct {
	ID               string
	ExpectedRevision uint64
	Name             string
	Region           string
	Host             string
	Port             uint16
	User             string
	Enabled          bool
	Authentication   AuthenticationKind
	HostKey          *HostKey
	Secrets          SecretUpdate
}

func (SaveCommand) GoString

func (SaveCommand) GoString() string

func (SaveCommand) MarshalJSON

func (SaveCommand) MarshalJSON() ([]byte, error)

func (SaveCommand) String

func (SaveCommand) String() string

type SecretUpdate

type SecretUpdate struct {
	Password         *credentials.Lease
	PrivateKey       *credentials.Lease
	Passphrase       *credentials.Lease
	RemovePassphrase bool
}

func (SecretUpdate) GoString

func (SecretUpdate) GoString() string

func (SecretUpdate) MarshalJSON

func (SecretUpdate) MarshalJSON() ([]byte, error)

func (SecretUpdate) String

func (SecretUpdate) String() string

type Selection

type Selection struct {
	Revision uint64                 `json:"revision"`
	Kind     jobcontract.TargetKind `json:"kind"`
	NodeID   string                 `json:"node_id"`
}

Selection.NodeID is a local configuration ID. JobSpec.target.node_id instead uses the daemon's shared ID from Binding.Identity.NodeID.

type Service

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

func New

func New(dependencies Dependencies) (*Service, error)

func (*Service) AcquireSSH

func (service *Service) AcquireSSH(ctx context.Context, id string, expected uint64) (*Connection, error)

AcquireSSH freezes one node revision and copies its credentials under the config lock. Later edits or cleanup cannot alter the already issued leases.

func (*Service) AcquireToken

func (service *Service) AcquireToken(ctx context.Context, id string, expected uint64) (*credentials.Lease, error)

func (*Service) Bind

func (service *Service) Bind(ctx context.Context, command BindCommand) (Node, error)

func (*Service) Cleanup

func (service *Service) Cleanup(ctx context.Context) error

Cleanup holds the node mutation lock until unreferenced keyring entries have been deleted and their registry records removed. It first confirms that the entire reference set is durable, including after a prior ambiguous save.

func (*Service) RecordInstallation

func (service *Service) RecordInstallation(ctx context.Context, command InstallationCommand) error

func (*Service) RecordObservation

func (service *Service) RecordObservation(
	ctx context.Context,
	id string,
	expected uint64,
	observation Observation,
) error

func (*Service) Remove

func (service *Service) Remove(ctx context.Context, id string, expected uint64) error

func (*Service) Save

func (service *Service) Save(ctx context.Context, command SaveCommand) (Node, error)

Save writes a durable credential intent before touching the keyring, then commits the node reference. Garbage collection is a separate guarded action.

func (*Service) SelectDefault

func (service *Service) SelectDefault(ctx context.Context, expected uint64, target jobcontract.ExecutionTarget) error

func (*Service) Snapshot

func (service *Service) Snapshot(ctx context.Context) (Snapshot, error)

type Snapshot

type Snapshot struct {
	Revision                 uint64     `json:"revision"`
	Default                  Selection  `json:"default"`
	Nodes                    []NodeView `json:"nodes"`
	PendingCredentialCleanup int        `json:"pending_credential_cleanup"`
}

Snapshot exposes no credential references, token hashes, suffixes or key text. A persisted observation is advisory; submission still requires a fresh check.

type TaskConcurrencyCommand

type TaskConcurrencyCommand struct {
	ID                    string
	ExpectedRevision      uint64
	ExpectedMaxActiveJobs uint32
	MaxActiveJobs         uint32
}

type Upgrade

type Upgrade struct {
	Request            runnerinstall.UpgradeRequest    `json:"request"`
	Release            string                          `json:"release"`
	Arch               string                          `json:"arch"`
	TemporaryDirectory string                          `json:"temporary_directory"`
	Stage              string                          `json:"stage"`
	ErrorCode          string                          `json:"error_code"`
	Operation          *runnerinstall.UpgradeOperation `json:"operation"`
	ChangedAt          time.Time                       `json:"changed_at"`
}

Upgrade is a local, durable intent. Its optional Operation is exclusively a confirmed server journal, never an inferred receipt from a failed SSH call.

func (Upgrade) Validate

func (attempt Upgrade) Validate() error

type UpgradeAction

type UpgradeAction struct {
	ID               string
	ExpectedRevision uint64
	OperationID      string
}

type UpgradeCommand

type UpgradeCommand struct {
	ID               string
	ExpectedRevision uint64
	OperationID      string
	ExpectedBuildID  string
}

Jump to

Keyboard shortcuts

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