Documentation
¶
Overview ¶
Package agent is the transport boundary between reconcile controllers and the node they run on. Local is the in-process form; GRPCTransport (grpc_transport.go) is the remote form.
Index ¶
- Constants
- Variables
- func CertFingerprint(der []byte) string
- func Execute(ctx context.Context, rt docker.Runtime, req *agentpb.AgentRequest, ...) *agentpb.AgentResponse
- func IsAuthRejection(err error) bool
- func LocalAgentInfo() *agentpb.AgentInfo
- func NewKeyAndCSR(commonName string) (keyPEM, csrDER []byte, err error)
- func NewServerCredentials(ca *CA, hosts []string, validFor time.Duration, opts ...CredentialOption) (credentials.TransportCredentials, error)
- func OnboardingIntervalFromEnv(lookup func(string) (string, bool)) time.Duration
- func RunSession(ctx context.Context, addr string, id *Identity, rt docker.Runtime, ...) error
- func WithFileRoot(ctx context.Context, dir string) context.Context
- type BuildDispatcher
- type BuildRelay
- type BuildRunner
- type CA
- func (ca *CA) CertPEM() []byte
- func (ca *CA) Fingerprint() string
- func (ca *CA) IssueServerCert(hosts []string, validFor time.Duration) (certPEM, keyPEM []byte, err error)
- func (ca *CA) KeyPEM() []byte
- func (ca *CA) SignClientCSR(commonName string, csrDER []byte, validFor time.Duration, now time.Time) (IssuedCert, error)
- type CredentialOption
- type EnrollOption
- type EnrollStore
- type ExecRelay
- func (r *ExecRelay) Cancel(execID string)
- func (r *ExecRelay) CloseAll()
- func (r *ExecRelay) Credit(c *agentpb.ExecCredit)
- func (r *ExecRelay) Input(in *agentpb.ExecInput)
- func (r *ExecRelay) Resize(rz *agentpb.ExecResize)
- func (r *ExecRelay) Start(ctx context.Context, execID string, req *agentpb.ExecRequest)
- type FileEntry
- type FileStore
- type GPUProbe
- type GPUSink
- type GRPCSink
- func (s *GRPCSink) ApplyMesh(ctx context.Context, nodeID string, cfg network.DeviceConfig) (network.NodeIdentity, error)
- func (s *GRPCSink) MeshStatus(ctx context.Context, nodeID string) (network.Status, error)
- func (s *GRPCSink) RotateKey(ctx context.Context, nodeID string) (network.RotationResult, error)
- type GRPCTransport
- func (t *GRPCTransport) ApplyMesh(ctx context.Context, cfg network.DeviceConfig) (network.NodeIdentity, error)
- func (t *GRPCTransport) BuildOnNode(ctx context.Context, req build.RemoteRequest, image io.Writer, ...) (*build.Result, error)
- func (t *GRPCTransport) CopyFromContainer(ctx context.Context, containerID, path string, maxBytes int64) (io.ReadCloser, docker.PathStat, error)
- func (t *GRPCTransport) CopyToContainer(ctx context.Context, containerID, dir string, content io.Reader, ...) error
- func (t *GRPCTransport) Create(ctx context.Context, spec docker.ContainerSpec) (string, error)
- func (t *GRPCTransport) DeleteFile(ctx context.Context, path string) error
- func (t *GRPCTransport) EnsureNetwork(ctx context.Context, name string) (string, error)
- func (t *GRPCTransport) EnsureVolume(ctx context.Context, name string) error
- func (t *GRPCTransport) Events(ctx context.Context) (<-chan docker.Event, <-chan error)
- func (t *GRPCTransport) Exec(ctx context.Context, containerID string, cmd []string) (io.ReadCloser, error)
- func (t *GRPCTransport) ExecTTY(ctx context.Context, containerID string, opts docker.ExecTTYOptions) (docker.ExecSession, error)
- func (t *GRPCTransport) ExecWithInput(ctx context.Context, containerID string, cmd []string, stdin io.Reader) (io.ReadCloser, error)
- func (t *GRPCTransport) GetFile(ctx context.Context, path string) (io.ReadCloser, error)
- func (t *GRPCTransport) InspectByName(ctx context.Context, name string) (*docker.ContainerState, error)
- func (t *GRPCTransport) InspectExitState(ctx context.Context, name string) (*docker.ExitState, error)
- func (t *GRPCTransport) ListByPrefix(ctx context.Context, prefix string) ([]docker.ContainerState, error)
- func (t *GRPCTransport) ListFiles(ctx context.Context, prefix string) ([]FileEntry, error)
- func (t *GRPCTransport) ListImages(ctx context.Context, repo string) ([]docker.ImageInfo, error)
- func (t *GRPCTransport) ListNetworksByPrefix(ctx context.Context, prefix string) ([]docker.NetworkInfo, error)
- func (t *GRPCTransport) Logs(ctx context.Context, containerID string, follow bool, since time.Time) (<-chan docker.LogLine, <-chan error)
- func (t *GRPCTransport) MeshStatus(ctx context.Context) (network.Status, error)
- func (t *GRPCTransport) NetworkConnect(ctx context.Context, network, containerID string) error
- func (t *GRPCTransport) NetworkDisconnect(ctx context.Context, network, containerID string, force bool) error
- func (t *GRPCTransport) PutFile(ctx context.Context, path string, content io.Reader, maxBytes int64) error
- func (t *GRPCTransport) Remove(ctx context.Context, id string, force bool) error
- func (t *GRPCTransport) RemoveNetwork(ctx context.Context, name string) error
- func (t *GRPCTransport) RemoveVolume(ctx context.Context, name string) error
- func (t *GRPCTransport) ReportsExitTimes() bool
- func (t *GRPCTransport) RotateMeshKey(ctx context.Context) (network.RotationResult, error)
- func (t *GRPCTransport) Start(ctx context.Context, id string) error
- func (t *GRPCTransport) Stats(ctx context.Context, containerID string) (docker.ContainerStats, error)
- func (t *GRPCTransport) Stop(ctx context.Context, id string, timeout time.Duration) error
- func (t *GRPCTransport) UpdateResources(ctx context.Context, id string, resources docker.Resources) error
- func (t *GRPCTransport) VolumeList(ctx context.Context, volume, dir string, limit int) ([]VolumeFileEntry, bool, error)
- func (t *GRPCTransport) VolumeRead(ctx context.Context, volume, path string) (io.ReadCloser, error)
- func (t *GRPCTransport) VolumeRemove(ctx context.Context, volume, path string) error
- func (t *GRPCTransport) VolumeWrite(ctx context.Context, volume, path string, content io.Reader, maxBytes int64) error
- type HostProbe
- type HostReport
- type HostReportSink
- type HostReportStore
- type Identity
- type IdentityChecker
- type IdentityFile
- func (f *IdentityFile) CheckWritable() error
- func (f *IdentityFile) Confirm() error
- func (f *IdentityFile) HasStaged() bool
- func (f *IdentityFile) Load() (*Identity, error)
- func (f *IdentityFile) LoadPrev() (*Identity, error)
- func (f *IdentityFile) PrevPath() string
- func (f *IdentityFile) ResolveStaged(ctx context.Context, check func(context.Context, *Identity) error) (*Identity, error)
- func (f *IdentityFile) Rollback() error
- func (f *IdentityFile) Save(id *Identity) error
- func (f *IdentityFile) Stage(next *Identity) error
- type IdentityHolder
- type IdentityPersister
- type IssuedCert
- type Local
- func (l Local) CopyFromContainer(ctx context.Context, containerID, path string, maxBytes int64) (io.ReadCloser, docker.PathStat, error)
- func (l Local) CopyToContainer(ctx context.Context, containerID, dir string, content io.Reader, ...) error
- func (l Local) ExecTTY(ctx context.Context, containerID string, opts docker.ExecTTYOptions) (docker.ExecSession, error)
- func (l Local) InspectExitState(ctx context.Context, name string) (*docker.ExitState, error)
- func (l Local) InspectImageID(ctx context.Context, ref string) (string, error)
- func (l Local) InspectImageLayers(ctx context.Context, ref string) ([]string, error)
- func (l Local) LoadImage(ctx context.Context, r io.Reader) error
- func (l Local) Logs(ctx context.Context, containerID string, follow bool, since time.Time) (<-chan docker.LogLine, <-chan error)
- func (l Local) RemoveVolume(ctx context.Context, name string) error
- func (l Local) RunToCompletion(ctx context.Context, spec docker.ContainerSpec, maxOutput int) (docker.RunOutcome, error)
- func (l Local) Stats(ctx context.Context, containerID string) (docker.ContainerStats, error)
- func (l Local) VolumeList(ctx context.Context, volume, dir string, limit int) ([]VolumeFileEntry, bool, error)
- func (l Local) VolumeRead(ctx context.Context, volume, path string) (io.ReadCloser, error)
- func (l Local) VolumeRemove(ctx context.Context, volume, path string) error
- func (l Local) VolumeWrite(ctx context.Context, volume, path string, content io.Reader, maxBytes int64) error
- type MeshApplier
- type MeshStatusReader
- type NodeFiles
- func (n *NodeFiles) Delete(ctx context.Context, nodeID, path string) error
- func (n *NodeFiles) Get(ctx context.Context, nodeID, path string) (io.ReadCloser, error)
- func (n *NodeFiles) List(ctx context.Context, nodeID, prefix string) ([]FileEntry, error)
- func (n *NodeFiles) Put(ctx context.Context, nodeID, path string, r io.Reader) error
- type OnboardingProbe
- type OnboardingReport
- type OnboardingSink
- type OnboardingStore
- type Option
- func WithCertValidity(d time.Duration) Option
- func WithClock(now func() time.Time) Option
- func WithGPUSink(sink GPUSink) Option
- func WithHostReportSink(sink HostReportSink) Option
- func WithOnboardingSink(sink OnboardingSink) Option
- func WithRenewGrace(d time.Duration) Option
- func WithSecurityLog(st SecurityStore, cfg SecurityConfig) Option
- func WithSessionObserver(f func(nodeID, remoteIP string)) Option
- type Registry
- type RejectedHandshake
- type RemoteBuilder
- type RenewConfig
- type RenewalStatus
- type Renewer
- func (r *Renewer) Holder() *IdentityHolder
- func (r *Renewer) RenewAt(id *Identity) (time.Time, error)
- func (r *Renewer) RenewNow()
- func (r *Renewer) RenewOnce(ctx context.Context, client agentpb.AgentServiceClient) error
- func (r *Renewer) Run(ctx context.Context, client agentpb.AgentServiceClient)
- func (r *Renewer) Status() RenewalStatus
- func (r *Renewer) Updates() <-chan struct{}
- type SecurityConfig
- type SecurityStore
- type Server
- func (s *Server) CheckIdentity(ctx context.Context, _ *agentpb.CheckIdentityRequest) (*agentpb.CheckIdentityResponse, error)
- func (s *Server) Disconnect(nodeID string)
- func (s *Server) Enroll(ctx context.Context, req *agentpb.EnrollRequest) (*agentpb.EnrollResponse, error)
- func (s *Server) NotifyShutdown()
- func (s *Server) ObserveRejected(r RejectedHandshake)
- func (s *Server) RecordSecurityEvent(ev store.NodeSecurityEvent)
- func (s *Server) Reenroll(ctx context.Context, req *agentpb.ReenrollRequest) (*agentpb.ReenrollResponse, error)
- func (s *Server) Renew(ctx context.Context, req *agentpb.RenewRequest) (*agentpb.RenewResponse, error)
- func (s *Server) RequestRenew(nodeID string) error
- func (s *Server) Session(stream agentpb.AgentService_SessionServer) error
- func (s *Server) SetSilenceSource(src SilenceSource)
- type SessionOption
- func WithBuildRunner(runner BuildRunner) SessionOption
- func WithFileStorage(dir string) SessionOption
- func WithGPUProbe(p GPUProbe) SessionOption
- func WithHeartbeatInterval(d time.Duration) SessionOption
- func WithHostProbe(p HostProbe) SessionOption
- func WithKeepalive(pingTime, timeout time.Duration) SessionOption
- func WithMesh(nodeID string, mesh MeshApplier) SessionOption
- func WithOnboardingProbe(p OnboardingProbe, interval time.Duration) SessionOption
- func WithRenewer(r *Renewer) SessionOption
- func WithSilenceWatcher(w *SilenceWatcher) SessionOption
- type SilenceConfig
- type SilenceSource
- type SilenceWatcher
- type StoredOnboarding
- type Transport
- type UnmanagedContainer
- type VolumeFileEntry
- type VolumeFileOps
Constants ¶
const ( DefaultSecurityCoalesceWindow = 10 * time.Minute DefaultSecurityPerNodeCap = 500 DefaultSecurityRetention = 30 * 24 * time.Hour )
Defaults for SecurityConfig.
const ( DefaultClientCertValidity = 90 * 24 * time.Hour DefaultCertRenewGrace = 24 * time.Hour )
Defaults for the env-tunable certificate settings (ADR 021).
const ( EnvSilenceGrace = "APP_AGENT_CP_SILENCE_GRACE" EnvSilenceInterval = "APP_AGENT_CP_SILENCE_INTERVAL" EnvSilenceMaxBackoff = "APP_AGENT_CP_SILENCE_MAX_BACKOFF" EnvSilenceCheck = "APP_AGENT_CP_SILENCE_CHECK" EnvSilenceTimeout = "APP_AGENT_CP_SILENCE_TIMEOUT" EnvSilenceJitterPct = "APP_AGENT_CP_SILENCE_JITTER_PCT" )
Env knobs for the control plane silence watcher, all durations except the jitter percent.
const CapContainerSpecFiles = "container_spec_files"
CapContainerSpecFiles means the agent writes the spec's inline files into the container before starting it.
const CapContainerSpecSecurity = "container_spec_security"
CapContainerSpecSecurity means the agent applies userns, security-opt, device, user and bind mount fields of a container spec.
const CapExitTimes = "exit_times"
CapExitTimes means the agent sends exit state start and finish times, so zero means never started.
const (
DefaultRenewFraction = 2.0 / 3.0
)
Defaults for RenewConfig. Renewing at two thirds of the lifetime leaves the last third to retry through outages (the step-ca and cert-manager default).
const EnvOnboardingInterval = "APP_AGENT_ONBOARDING_INTERVAL"
EnvOnboardingInterval is how often the agent re-sends its onboarding facts, so a fix applied on the node shows up without a restart.
const EnvSilencePushEvery = "APP_AGENT_CP_SILENCE_PUSH_EVERY"
EnvSilencePushEvery is how often a session re-checks the silence URL, so a dashboard edit reaches live agents.
Variables ¶
var ErrAgentLacksCapability = errors.New("agent: node agent too old for this container spec, upgrade the agent")
ErrAgentLacksCapability is returned when a spec needs a feature the node's agent did not advertise, so it would be silently dropped.
var ErrBuildWindowViolated = errors.New("agent: build peer exceeded its flow-control window")
ErrBuildWindowViolated ends a dispatched build whose peer sent more unacknowledged data frames than buildWindowFrames allows, for the same reason ErrExecWindowViolated ends an exec.
var ErrCAFingerprintMismatch = pinned.ErrMismatch
ErrCAFingerprintMismatch is returned by DialEnroll when the control plane's CA does not match the pinned fingerprint.
var ErrExecWindowViolated = errors.New("agent: exec peer exceeded its flow-control window")
ErrExecWindowViolated fails one exec whose peer exceeded its window; blocking recvLoop would stall the session.
var ErrExitStateUnsupported = errors.New("agent: this node's container runtime cannot inspect container exit state")
ErrExitStateUnsupported means the runtime cannot inspect exit state; callers wait out the full readiness budget.
var ErrFilePathEscapes = errors.New("agent: file path escapes the storage directory")
ErrFilePathEscapes is returned for any path that would resolve outside the storage root.
var ErrFileStoreDisabled = errors.New("agent: file storage is not enabled on this node (no storage directory configured)")
ErrFileStoreDisabled means the agent has no storage directory configured, so it refuses every file operation.
var ErrImageLoadUnsupported = errors.New("agent: this node's container runtime cannot load an image archive")
ErrImageLoadUnsupported is returned when the node runtime cannot load an image archive.
var ErrInvalidCSR = errors.New("agent: invalid certificate signing request")
ErrInvalidCSR is returned by SignClientCSR for a malformed request, a bad signature, or a key type this CA does not issue for.
var ErrLogsUnsupported = errors.New("agent: this node's runtime cannot read container logs")
ErrLogsUnsupported is what a Logs request gets when the node's runtime cannot read logs.
ErrMeshUnavailable is returned when no MeshApplier was wired in. The control plane treats it as a per-node failure, never a fleet-wide one.
var ErrNodeNotConnected = errors.New("agent: node is not connected")
ErrNodeNotConnected is returned by RequestRenew when the node has no live session to carry the request.
var ErrNodeNotMeshCapable = fmt.Errorf("network: node's transport does not support mesh operations")
ErrNodeNotMeshCapable is returned when a node's registered transport does not support mesh operations. Real agent connections never hit it.
var ErrNodeNotRegistered = errors.New("agent: node not registered in this transport registry")
ErrNodeNotRegistered is Registry.Get's failure mode for an unknown node ID.
var ErrSessionClosed = errors.New("agent: session closed")
ErrSessionClosed is returned by mux.Call once the underlying stream has ended, for any pending or future call.
var ErrStatsUnsupported = errors.New("agent: this node's container runtime cannot report container stats")
ErrStatsUnsupported is what a Stats request gets when this node's runtime cannot report container resource usage.
var ErrTTYUnsupported = errors.New("agent: this node's container runtime does not support interactive exec")
ErrTTYUnsupported is what an ExecRequest asking for a PTY gets when this agent's runtime has no interactive exec to offer.
var ErrVolumeFilesUnsupported = errors.New("agent: this runtime cannot resolve a volume's host directory")
ErrVolumeFilesUnsupported means the runtime cannot map a volume to a host directory.
var ErrVolumeRemoveUnsupported = errors.New("agent: this node's runtime cannot remove volumes")
ErrVolumeRemoveUnsupported is what a RemoveVolume request gets from a runtime that cannot delete volumes.
Functions ¶
func CertFingerprint ¶
CertFingerprint returns the hex SHA-256 of a DER-encoded certificate. Sessions compare against this rather than trusting CommonName, which another certificate could also claim.
func Execute ¶
func Execute(ctx context.Context, rt docker.Runtime, req *agentpb.AgentRequest, emitEvent func(*agentpb.ProxiedEvent)) *agentpb.AgentResponse
Execute returns exactly one AgentResponse per request, carrying req.RequestId, even on failure. Errors travel as plain strings because the gRPC boundary cannot carry %w wrapping.
func IsAuthRejection ¶ added in v0.2.0
IsAuthRejection is isAuthRejection for callers outside this package.
func LocalAgentInfo ¶ added in v0.2.0
LocalAgentInfo describes this agent binary and the machine it runs on.
func NewKeyAndCSR ¶ added in v0.2.0
NewKeyAndCSR generates a fresh ed25519 private key on this machine and a CSR for it. The key never leaves the caller; only the CSR is sent.
func NewServerCredentials ¶
func NewServerCredentials(ca *CA, hosts []string, validFor time.Duration, opts ...CredentialOption) (credentials.TransportCredentials, error)
NewServerCredentials returns mTLS credentials that verify a client certificate when presented but do not require one. Must go to grpc.Creds, not a raw tls.Listener: grpc only sees the peer TLS state when it performs the handshake.
func OnboardingIntervalFromEnv ¶
OnboardingIntervalFromEnv reads EnvOnboardingInterval, or the default.
Types ¶
type BuildDispatcher ¶ added in v0.2.0
type BuildDispatcher struct {
// contains filtered or unexported fields
}
BuildDispatcher resolves a node ID to that node's session and runs a build there. Satisfies internal/build.NodeBuilder, which is how build.Router reaches a node without knowing anything about transports.
func NewBuildDispatcher ¶ added in v0.2.0
func NewBuildDispatcher(registry *Registry) *BuildDispatcher
NewBuildDispatcher builds a dispatcher over registry.
func (*BuildDispatcher) BuildOnNode ¶ added in v0.2.0
func (d *BuildDispatcher) BuildOnNode(ctx context.Context, nodeID string, req build.RemoteRequest, image io.Writer, progress func(build.ProgressEvent)) (*build.Result, error)
BuildOnNode implements internal/build.NodeBuilder.
type BuildRelay ¶ added in v0.2.0
type BuildRelay struct {
// contains filtered or unexported fields
}
BuildRelay owns the agent side of every in-flight dispatched build on one Session, the same per-session state ExecRelay holds for exec.
func NewBuildRelay ¶ added in v0.2.0
func NewBuildRelay(runner BuildRunner, send func(*agentpb.AgentMessage)) *BuildRelay
NewBuildRelay returns a relay that runs builds through runner and writes frames through send; a nil runner rejects every build.
func (*BuildRelay) Cancel ¶ added in v0.2.0
func (r *BuildRelay) Cancel(buildID string)
Cancel stops a build the control plane no longer wants. No terminal frame follows: the caller that cancelled is not reading anymore.
func (*BuildRelay) CloseAll ¶ added in v0.2.0
func (r *BuildRelay) CloseAll()
CloseAll stops every in-flight build, for a session that is ending.
func (*BuildRelay) Credit ¶ added in v0.2.0
func (r *BuildRelay) Credit(c *agentpb.BuildCredit)
Credit records the control plane's refund of this build's output window.
func (*BuildRelay) Input ¶ added in v0.2.0
func (r *BuildRelay) Input(in *agentpb.BuildInput)
Input routes one build-context frame to its build.
func (*BuildRelay) Start ¶ added in v0.2.0
func (r *BuildRelay) Start(ctx context.Context, buildID string, req *agentpb.BuildRequest)
Start begins the build identified by buildID without blocking the session's receive loop.
type BuildRunner ¶ added in v0.2.0
type BuildRunner interface {
SolveRemote(ctx context.Context, req build.RemoteRequest, out io.Writer, progress func(build.ProgressEvent)) (*build.Result, error)
}
BuildRunner runs dispatched builds; *build.Client satisfies it.
type CA ¶
type CA struct {
// contains filtered or unexported fields
}
CA is the control plane's self-signed root, signing its server cert and every agent's client cert.
func GenerateCA ¶
GenerateCA creates a new self-signed CA using ed25519 keys.
func LoadCA ¶
LoadCA restores a CA persisted via CertPEM/KeyPEM; regenerating it would invalidate every enrolled agent.
func (*CA) CertPEM ¶
CertPEM returns the CA certificate, PEM-encoded, for agents to verify the control plane and for persistence.
func (*CA) Fingerprint ¶ added in v0.2.0
Fingerprint returns the hex SHA-256 of the CA certificate's DER, the value an agent pins at enrollment (APP_CA_FINGERPRINT).
func (*CA) IssueServerCert ¶
func (ca *CA) IssueServerCert(hosts []string, validFor time.Duration) (certPEM, keyPEM []byte, err error)
IssueServerCert issues the control plane's gRPC listener certificate, signed by ca.
func (*CA) KeyPEM ¶
KeyPEM returns the CA's own private key, PEM-encoded, PKCS#8: the other half LoadCA needs. Never sent over the wire to an agent, only ever persisted locally by the control plane's own startup code.
func (*CA) SignClientCSR ¶ added in v0.2.0
func (ca *CA) SignClientCSR(commonName string, csrDER []byte, validFor time.Duration, now time.Time) (IssuedCert, error)
SignClientCSR issues a client certificate for commonName over the CSR's public key. The CSR's own subject, SANs and extensions are ignored: the control plane alone decides what the certificate asserts.
type CredentialOption ¶
type CredentialOption func(*credentialConfig)
CredentialOption configures NewServerCredentials.
func WithCredentialClock ¶
func WithCredentialClock(now func() time.Time) CredentialOption
WithCredentialClock overrides the time source for certificate validity.
func WithRejectObserver ¶
func WithRejectObserver(f func(RejectedHandshake)) CredentialOption
WithRejectObserver calls f for every client certificate the handshake refuses. f runs on the handshake path and must not block.
type EnrollOption ¶ added in v0.2.0
type EnrollOption func(*enrollConfig)
EnrollOption configures DialEnroll.
func WithPinnedCAFingerprint ¶ added in v0.2.0
func WithPinnedCAFingerprint(fingerprint string) EnrollOption
WithPinnedCAFingerprint makes DialEnroll refuse any control plane whose CA certificate's SHA-256 (hex, colons optional) is not fingerprint.
func WithTrustedCA ¶ added in v0.2.0
func WithTrustedCA(caPEM []byte) EnrollOption
WithTrustedCA verifies the control plane against caPEM, the CA an already-enrolled node has on disk, instead of a fingerprint pin.
type EnrollStore ¶
type EnrollStore interface {
GetNodeJoinTokenByHash(ctx context.Context, hash string) (*store.NodeJoinToken, error)
MarkNodeJoinTokenUsed(ctx context.Context, id string) error
SaveNode(ctx context.Context, n store.Node) error
GetNode(ctx context.Context, id string) (*store.Node, error)
UpdateNodeStatus(ctx context.Context, id string, status store.NodeStatus) error
TouchNodeLastSeen(ctx context.Context, id string) error
RotateNodeCert(ctx context.Context, id, presentedFingerprint string, c store.NodeCert, grace time.Duration, now time.Time) error
ReenrollNodeCert(ctx context.Context, id string, c store.NodeCert, now time.Time) error
SyncNodeCertDetails(ctx context.Context, id, fingerprint, serial string, notAfter time.Time) error
UpdateNodeAgentInfo(ctx context.Context, id string, info store.NodeAgentInfo, now time.Time) error
}
EnrollStore is the store surface Server needs. *store.DB satisfies it.
type ExecRelay ¶ added in v0.2.0
type ExecRelay struct {
// contains filtered or unexported fields
}
ExecRelay owns the agent side of every in-flight remote exec on one Session.
func NewExecRelay ¶ added in v0.2.0
func NewExecRelay(rt docker.Runtime, send func(*agentpb.AgentMessage)) *ExecRelay
NewExecRelay builds a relay running commands against rt and writing its frames through send, which must serialize writes to the Session stream.
func (*ExecRelay) Cancel ¶ added in v0.2.0
Cancel stops an exec the control plane no longer wants. No terminal frame follows: the caller that cancelled is not reading anymore.
func (*ExecRelay) CloseAll ¶ added in v0.2.0
func (r *ExecRelay) CloseAll()
CloseAll stops every in-flight exec, for a session that is ending.
func (*ExecRelay) Credit ¶ added in v0.2.0
func (r *ExecRelay) Credit(c *agentpb.ExecCredit)
Credit records the control plane's refund of this exec's output window.
func (*ExecRelay) Resize ¶ added in v0.2.0
func (r *ExecRelay) Resize(rz *agentpb.ExecResize)
Resize records the newest terminal size for a PTY exec. A no-op for an exec that never asked for one, or that has already ended.
type FileStore ¶
type FileStore struct {
// contains filtered or unexported fields
}
FileStore performs object operations strictly inside root.
func NewFileStore ¶
NewFileStore returns a store rooted at dir, creating it when missing.
func (*FileStore) List ¶
func (s *FileStore) List(prefix string) (io.ReadCloser, error)
List returns "<size>\t<path>" lines for every file whose path starts with prefix.
type GRPCSink ¶ added in v0.2.0
type GRPCSink struct {
// contains filtered or unexported fields
}
GRPCSink dispatches mesh config to remote nodes over their own agent Session stream, resolved per call through registry.
func NewGRPCSink ¶ added in v0.2.0
NewGRPCSink builds a GRPCSink that resolves node transports through registry.
func (*GRPCSink) ApplyMesh ¶ added in v0.2.0
func (s *GRPCSink) ApplyMesh(ctx context.Context, nodeID string, cfg network.DeviceConfig) (network.NodeIdentity, error)
ApplyMesh forwards cfg to nodeID's live agent session, failing only that node's pass if it has no registered transport.
func (*GRPCSink) MeshStatus ¶ added in v0.2.0
MeshStatus returns nodeID's live WireGuard view over its agent session.
type GRPCTransport ¶
type GRPCTransport struct {
// contains filtered or unexported fields
}
GRPCTransport is the control-plane side of a reverse-dialed agent connection, built on the agent's session mux.
func (*GRPCTransport) ApplyMesh ¶ added in v0.2.0
func (t *GRPCTransport) ApplyMesh(ctx context.Context, cfg network.DeviceConfig) (network.NodeIdentity, error)
ApplyMesh lives on meshTransport, not Transport, so container-only callers never see mesh dispatch.
func (*GRPCTransport) BuildOnNode ¶ added in v0.2.0
func (t *GRPCTransport) BuildOnNode(ctx context.Context, req build.RemoteRequest, image io.Writer, progress func(build.ProgressEvent)) (*build.Result, error)
BuildOnNode dispatches a build to this transport's node and writes the image tar to image. The image is never loaded on the build node; the requesting control plane loads it.
func (*GRPCTransport) CopyFromContainer ¶
func (t *GRPCTransport) CopyFromContainer(ctx context.Context, containerID, path string, maxBytes int64) (io.ReadCloser, docker.PathStat, error)
CopyFromContainer implements docker.ArchiveRuntime over the exec frame stream: the same window, credit and cancel as any exec, no new RPC shape.
func (*GRPCTransport) CopyToContainer ¶
func (t *GRPCTransport) CopyToContainer(ctx context.Context, containerID, dir string, content io.Reader, maxBytes int64) error
CopyToContainer implements docker.ArchiveRuntime. It returns once the agent's archive API has consumed the whole stream, or with its error.
func (*GRPCTransport) Create ¶
func (t *GRPCTransport) Create(ctx context.Context, spec docker.ContainerSpec) (string, error)
Create implements Transport (docker.Runtime).
func (*GRPCTransport) DeleteFile ¶
func (t *GRPCTransport) DeleteFile(ctx context.Context, path string) error
DeleteFile removes path; a missing object is success.
func (*GRPCTransport) EnsureNetwork ¶
EnsureNetwork implements Transport (docker.Runtime).
func (*GRPCTransport) EnsureVolume ¶
func (t *GRPCTransport) EnsureVolume(ctx context.Context, name string) error
EnsureVolume implements Transport (docker.Runtime).
func (*GRPCTransport) Events ¶
Events relays WatchEvents over mux and drops events under backpressure rather than blocking the shared recv loop.
func (*GRPCTransport) Exec ¶
func (t *GRPCTransport) Exec(ctx context.Context, containerID string, cmd []string) (io.ReadCloser, error)
Exec runs its initial round trip synchronously, so a failed attach errors here rather than on a later Read.
func (*GRPCTransport) ExecTTY ¶ added in v0.2.0
func (t *GRPCTransport) ExecTTY(ctx context.Context, containerID string, opts docker.ExecTTYOptions) (docker.ExecSession, error)
ExecTTY runs over the usual exec stream; the PTY lives on the agent and this end only adds resize frames.
func (*GRPCTransport) ExecWithInput ¶
func (t *GRPCTransport) ExecWithInput(ctx context.Context, containerID string, cmd []string, stdin io.Reader) (io.ReadCloser, error)
ExecWithInput drains stdin concurrently with output, so a command that writes while reading does not deadlock.
func (*GRPCTransport) GetFile ¶
func (t *GRPCTransport) GetFile(ctx context.Context, path string) (io.ReadCloser, error)
GetFile streams the object at path; the caller closes it.
func (*GRPCTransport) InspectByName ¶
func (t *GRPCTransport) InspectByName(ctx context.Context, name string) (*docker.ContainerState, error)
InspectByName implements Transport (docker.Runtime).
func (*GRPCTransport) InspectExitState ¶ added in v0.2.0
func (t *GRPCTransport) InspectExitState(ctx context.Context, name string) (*docker.ExitState, error)
InspectExitState implements docker.ExitStateInspector over the wire; an agent too old to know it is treated as can't-tell.
func (*GRPCTransport) ListByPrefix ¶
func (t *GRPCTransport) ListByPrefix(ctx context.Context, prefix string) ([]docker.ContainerState, error)
ListByPrefix implements Transport (docker.Runtime).
func (*GRPCTransport) ListImages ¶
ListImages implements Transport (docker.Runtime).
func (*GRPCTransport) ListNetworksByPrefix ¶
func (t *GRPCTransport) ListNetworksByPrefix(ctx context.Context, prefix string) ([]docker.NetworkInfo, error)
ListNetworksByPrefix implements Transport (docker.Runtime).
func (*GRPCTransport) Logs ¶
func (t *GRPCTransport) Logs(ctx context.Context, containerID string, follow bool, since time.Time) (<-chan docker.LogLine, <-chan error)
Logs implements telemetry.LogSource over the wire. The agent answers bounded batches, so a follow stream is a poll with an advancing cursor; ctx ends it.
func (*GRPCTransport) MeshStatus ¶ added in v0.2.0
MeshStatus asks this transport's node for its live WireGuard view.
func (*GRPCTransport) NetworkConnect ¶ added in v0.2.0
func (t *GRPCTransport) NetworkConnect(ctx context.Context, network, containerID string) error
NetworkConnect implements Transport (docker.Runtime).
func (*GRPCTransport) NetworkDisconnect ¶ added in v0.2.0
func (t *GRPCTransport) NetworkDisconnect(ctx context.Context, network, containerID string, force bool) error
NetworkDisconnect implements Transport (docker.Runtime).
func (*GRPCTransport) PutFile ¶
func (t *GRPCTransport) PutFile(ctx context.Context, path string, content io.Reader, maxBytes int64) error
PutFile streams content to path inside the node's confined storage directory.
func (*GRPCTransport) RemoveNetwork ¶
func (t *GRPCTransport) RemoveNetwork(ctx context.Context, name string) error
RemoveNetwork implements Transport (docker.Runtime).
func (*GRPCTransport) RemoveVolume ¶
func (t *GRPCTransport) RemoveVolume(ctx context.Context, name string) error
RemoveVolume implements docker.VolumeRemover over the wire.
func (*GRPCTransport) ReportsExitTimes ¶
func (t *GRPCTransport) ReportsExitTimes() bool
ReportsExitTimes lets run-to-completion treat zero exit times as never started; older agents keep the old rule.
func (*GRPCTransport) RotateMeshKey ¶ added in v0.2.0
func (t *GRPCTransport) RotateMeshKey(ctx context.Context) (network.RotationResult, error)
RotateMeshKey asks this transport's own node to rotate its mesh key and returns the change. Part of meshTransport, same reasoning as ApplyMesh above.
func (*GRPCTransport) Start ¶
func (t *GRPCTransport) Start(ctx context.Context, id string) error
Start implements Transport (docker.Runtime).
func (*GRPCTransport) Stats ¶ added in v0.2.0
func (t *GRPCTransport) Stats(ctx context.Context, containerID string) (docker.ContainerStats, error)
Stats implements docker.StatsInspector over the wire; an agent too old for it makes the collector skip this target.
func (*GRPCTransport) Stop ¶
Stop sends timeout < 0 as TimeoutMs -1, so an indefinite wait is not silently clamped to zero.
func (*GRPCTransport) UpdateResources ¶
func (t *GRPCTransport) UpdateResources(ctx context.Context, id string, resources docker.Resources) error
UpdateResources implements Transport (docker.Runtime).
func (*GRPCTransport) VolumeList ¶
func (t *GRPCTransport) VolumeList(ctx context.Context, volume, dir string, limit int) ([]VolumeFileEntry, bool, error)
VolumeList implements VolumeFileOps over the exec frame stream.
func (*GRPCTransport) VolumeRead ¶
func (t *GRPCTransport) VolumeRead(ctx context.Context, volume, path string) (io.ReadCloser, error)
VolumeRead implements VolumeFileOps; the caller closes the stream.
func (*GRPCTransport) VolumeRemove ¶
func (t *GRPCTransport) VolumeRemove(ctx context.Context, volume, path string) error
VolumeRemove implements VolumeFileOps.
func (*GRPCTransport) VolumeWrite ¶
func (t *GRPCTransport) VolumeWrite(ctx context.Context, volume, path string, content io.Reader, maxBytes int64) error
VolumeWrite implements VolumeFileOps.
type HostProbe ¶ added in v0.2.2
type HostProbe func(ctx context.Context) HostReport
HostProbe reads the node's current host report.
type HostReport ¶ added in v0.2.2
type HostReport struct {
MemoryTotalBytes uint64
MemoryAvailableBytes uint64
AgentRSSBytes uint64
OtherContainersMemoryBytes uint64
OtherContainers []UnmanagedContainer
CPUCores uint32
DiskTotalBytes uint64
DiskFreeBytes uint64
DiskInodesTotal uint64
DiskInodesFree uint64
SwapTotalBytes uint64
SwapFreeBytes uint64
}
HostReport is one node's host memory split as the agent reads it. MemoryTotalBytes, DiskTotalBytes and DiskFreeBytes are zero when unreadable.
type HostReportSink ¶ added in v0.2.2
type HostReportSink interface {
SetNodeHostReport(nodeID string, r HostReport)
}
HostReportSink receives a node's host report on the control plane.
type HostReportStore ¶ added in v0.2.2
type HostReportStore struct {
// contains filtered or unexported fields
}
HostReportStore keeps each node's latest host report in memory only: it is a live gauge, and a restart simply waits for the next agent tick.
func NewHostReportStore ¶ added in v0.2.2
func NewHostReportStore() *HostReportStore
NewHostReportStore returns an empty store.
func (*HostReportStore) Get ¶ added in v0.2.2
func (s *HostReportStore) Get(nodeID string) (HostReport, bool)
Get returns nodeID's latest report, false when none arrived or it is stale.
func (*HostReportStore) SetNodeHostReport ¶ added in v0.2.2
func (s *HostReportStore) SetNodeHostReport(nodeID string, r HostReport)
SetNodeHostReport implements HostReportSink.
type Identity ¶
Identity is the PEM cert, key and CA that an enrolled node reconnects with; cmd/levelrail-agent persists them.
func DialEnroll ¶
func DialEnroll(ctx context.Context, addr, joinToken, nodeName string, opts ...EnrollOption) (*Identity, error)
DialEnroll exchanges joinToken for an Identity over addr; the private key never leaves the agent.
func DialReenroll ¶ added in v0.2.0
func DialReenroll(ctx context.Context, addr, token, nodeID string, opts ...EnrollOption) (*Identity, error)
DialReenroll exchanges a re-enrollment token for a new certificate for an existing node, keeping its identity. nodeID may be empty when the old identity file is gone; the token alone names the node.
type IdentityChecker ¶ added in v0.2.0
IdentityChecker proves an identity is accepted by the control plane without opening a Session.
func CheckIdentityAt ¶ added in v0.2.0
func CheckIdentityAt(addr string) IdentityChecker
CheckIdentityAt returns an IdentityChecker that dials addr presenting the identity and calls CheckIdentity, requiring it to be current.
type IdentityFile ¶ added in v0.2.0
type IdentityFile struct {
Path string
// contains filtered or unexported fields
}
IdentityFile is the on-disk agent identity; writes are atomic, so a crash never leaves a torn one. The previous identity is kept as <path>.prev until a renewed certificate is proven to work.
func NewIdentityFile ¶ added in v0.2.0
func NewIdentityFile(path string) *IdentityFile
NewIdentityFile returns an IdentityFile for path.
func (*IdentityFile) CheckWritable ¶ added in v0.2.0
func (f *IdentityFile) CheckWritable() error
CheckWritable proves the identity file's directory accepts new files by creating and removing a probe, so enrollment can fail before it spends the one-time join token on an identity that could never be saved.
func (*IdentityFile) Confirm ¶ added in v0.2.0
func (f *IdentityFile) Confirm() error
Confirm drops the pre-renewal backup once the new identity works.
func (*IdentityFile) HasStaged ¶ added in v0.2.0
func (f *IdentityFile) HasStaged() bool
HasStaged reports whether a renewal was staged but never confirmed or rolled back, meaning the agent stopped in between.
func (*IdentityFile) Load ¶ added in v0.2.0
func (f *IdentityFile) Load() (*Identity, error)
Load reads the identity and removes temp files a crashed write left behind. It returns an error wrapping os.ErrNotExist when none exists.
func (*IdentityFile) LoadPrev ¶ added in v0.2.0
func (f *IdentityFile) LoadPrev() (*Identity, error)
LoadPrev reads the pre-renewal identity kept at PrevPath.
func (*IdentityFile) PrevPath ¶ added in v0.2.0
func (f *IdentityFile) PrevPath() string
PrevPath is where the pre-renewal identity is kept.
func (*IdentityFile) ResolveStaged ¶ added in v0.2.0
func (f *IdentityFile) ResolveStaged(ctx context.Context, check func(context.Context, *Identity) error) (*Identity, error)
ResolveStaged settles a renewal the agent stopped in the middle of: the staged identity is kept if check accepts it, otherwise the backup is restored. It returns the identity to use.
func (*IdentityFile) Rollback ¶ added in v0.2.0
func (f *IdentityFile) Rollback() error
Rollback restores the pre-renewal identity over the current one.
func (*IdentityFile) Save ¶ added in v0.2.0
func (f *IdentityFile) Save(id *Identity) error
Save atomically replaces the identity on disk with id.
func (*IdentityFile) Stage ¶ added in v0.2.0
func (f *IdentityFile) Stage(next *Identity) error
Stage keeps the current identity file as PrevPath, then saves next. Confirm or Rollback completes it.
type IdentityHolder ¶ added in v0.2.0
type IdentityHolder struct {
// contains filtered or unexported fields
}
IdentityHolder is the agent's in-memory current identity, swapped after a renewal so the next connection presents the new certificate without a restart.
func NewIdentityHolder ¶ added in v0.2.0
func NewIdentityHolder(id *Identity) *IdentityHolder
NewIdentityHolder wraps id.
func (*IdentityHolder) Current ¶ added in v0.2.0
func (h *IdentityHolder) Current() *Identity
Current returns the identity in use.
func (*IdentityHolder) Set ¶ added in v0.2.0
func (h *IdentityHolder) Set(id *Identity)
Set replaces the identity in use.
type IdentityPersister ¶ added in v0.2.0
IdentityPersister stages a renewed identity durably and then confirms or rolls it back. *IdentityFile implements it.
type IssuedCert ¶ added in v0.2.0
type IssuedCert struct {
PEM []byte
Fingerprint string
Serial string
NotBefore time.Time
NotAfter time.Time
}
IssuedCert is a signed client certificate plus the fields the control plane records about it.
type Local ¶
Local adapts this process's own docker.Runtime into a Transport for the local node, with no network hop.
func (Local) CopyFromContainer ¶
func (l Local) CopyFromContainer(ctx context.Context, containerID, path string, maxBytes int64) (io.ReadCloser, docker.PathStat, error)
CopyFromContainer implements docker.ArchiveRuntime by forwarding to the wrapped runtime, which the embedded interface would otherwise hide.
func (Local) CopyToContainer ¶
func (l Local) CopyToContainer(ctx context.Context, containerID, dir string, content io.Reader, maxBytes int64) error
CopyToContainer implements docker.ArchiveRuntime by forwarding.
func (Local) ExecTTY ¶ added in v0.2.0
func (l Local) ExecTTY(ctx context.Context, containerID string, opts docker.ExecTTYOptions) (docker.ExecSession, error)
ExecTTY implements docker.TTYRuntime by forwarding to the wrapped runtime, which the embedded docker.Runtime interface would otherwise hide even when the concrete value behind it supports interactive exec.
func (Local) InspectExitState ¶ added in v0.2.0
InspectExitState forwards to the wrapped runtime, since embedding would hide the optional ExitStateInspector.
func (Local) InspectImageID ¶ added in v0.2.0
InspectImageID implements docker.ImageInspector by forwarding; an unsupporting runtime reports "" so digest verification is skipped.
func (Local) InspectImageLayers ¶ added in v0.2.0
InspectImageLayers implements docker.ImageLayerInspector by forwarding.
func (Local) LoadImage ¶ added in v0.2.0
LoadImage implements docker.ImageLoader by forwarding to the wrapped runtime.
func (Local) Logs ¶
func (l Local) Logs(ctx context.Context, containerID string, follow bool, since time.Time) (<-chan docker.LogLine, <-chan error)
Logs forwards to the wrapped runtime, which embedding would otherwise hide.
func (Local) RemoveVolume ¶
RemoveVolume forwards to the wrapped runtime.
func (Local) RunToCompletion ¶ added in v0.2.0
func (l Local) RunToCompletion(ctx context.Context, spec docker.ContainerSpec, maxOutput int) (docker.RunOutcome, error)
RunToCompletion implements docker.RunToCompletionRuntime by forwarding to the wrapped runtime, which the embedded docker.Runtime would hide.
func (Local) Stats ¶ added in v0.2.0
Stats implements docker.StatsInspector by forwarding to the wrapped runtime, the same forwarding InspectExitState above already does for a different optional capability.
func (Local) VolumeList ¶
func (l Local) VolumeList(ctx context.Context, volume, dir string, limit int) ([]VolumeFileEntry, bool, error)
VolumeList implements VolumeFileOps for the control plane's own node.
func (Local) VolumeRead ¶
VolumeRead implements VolumeFileOps for the control plane's own node.
func (Local) VolumeRemove ¶
VolumeRemove implements VolumeFileOps for the control plane's own node.
type MeshApplier ¶ added in v0.2.0
type MeshApplier interface {
ApplyMesh(ctx context.Context, nodeID string, cfg network.DeviceConfig) (network.NodeIdentity, error)
RotateKey(ctx context.Context, nodeID string) (network.RotationResult, error)
}
MeshApplier is satisfied by *network.LocalSink's ApplyMesh and RotateKey methods, with no adapter.
type MeshStatusReader ¶ added in v0.2.0
MeshStatusReader is the optional half of a MeshApplier that can report the node's live WireGuard view, for node-pair diagnostics.
type NodeFiles ¶
type NodeFiles struct {
// contains filtered or unexported fields
}
NodeFiles resolves a node ID to its session and runs file operations there.
func NewNodeFiles ¶
NewNodeFiles builds the control plane side of agent file destinations over registry.
type OnboardingProbe ¶
type OnboardingProbe func(ctx context.Context) OnboardingReport
OnboardingProbe gathers the node's current onboarding report.
func NewOnboardingProbe ¶
func NewOnboardingProbe(rt docker.Runtime, diskPath string, meshEnabled bool, cloud cloudmeta.Config) OnboardingProbe
NewOnboardingProbe measures this host. Cloud detection is retried on every report until it finds something, then cached for the process lifetime.
type OnboardingReport ¶
type OnboardingReport struct {
Cloud cloudmeta.Info
Facts nodepreflight.Facts
Disabled bool
}
OnboardingReport is one node's detected cloud placement and the raw facts the control plane judges into preflight checks.
type OnboardingSink ¶
type OnboardingSink interface {
SetNodeOnboarding(nodeID string, r OnboardingReport, receivedAt time.Time)
}
OnboardingSink receives a node's onboarding report on the control plane.
type OnboardingStore ¶
type OnboardingStore struct {
// contains filtered or unexported fields
}
OnboardingStore keeps each node's latest report in memory: it is a live gauge and a restart simply waits for the next agent tick.
func NewOnboardingStore ¶
func NewOnboardingStore() *OnboardingStore
NewOnboardingStore returns an empty store.
func (*OnboardingStore) Get ¶
func (s *OnboardingStore) Get(nodeID string) (StoredOnboarding, bool)
Get returns nodeID's latest report.
func (*OnboardingStore) SetNodeOnboarding ¶
func (s *OnboardingStore) SetNodeOnboarding(nodeID string, r OnboardingReport, receivedAt time.Time)
SetNodeOnboarding implements OnboardingSink.
func (*OnboardingStore) Snapshot ¶
func (s *OnboardingStore) Snapshot() map[string]StoredOnboarding
Snapshot returns a copy of every node's latest report.
type Option ¶
type Option func(*Server)
Option configures optional Server behavior.
func WithCertValidity ¶ added in v0.2.0
WithCertValidity sets how long issued agent certificates stay valid.
func WithGPUSink ¶ added in v0.2.0
WithGPUSink persists GPU reports agents send up their Session stream.
func WithHostReportSink ¶ added in v0.2.2
func WithHostReportSink(sink HostReportSink) Option
WithHostReportSink records the host reports agents send up their Session stream.
func WithOnboardingSink ¶
func WithOnboardingSink(sink OnboardingSink) Option
WithOnboardingSink records the onboarding reports agents send up their Session stream.
func WithRenewGrace ¶ added in v0.2.0
WithRenewGrace sets how long a renewed node's previous certificate stays accepted, so a renewal whose response was lost cannot lock the node out.
func WithSecurityLog ¶
func WithSecurityLog(st SecurityStore, cfg SecurityConfig) Option
WithSecurityLog turns on the per-node security event log, stored in st.
func WithSessionObserver ¶ added in v0.2.0
WithSessionObserver calls f with each authenticated node's remote IP as its session opens, so the mesh can record where to reach that node.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry resolves a node ID to the Transport that reaches it.
func (*Registry) Register ¶
Register associates nodeID with t, replacing any existing entry for that ID. Safe for concurrent use.
func (*Registry) Resolve ¶ added in v0.2.0
Resolve is Get plus the local node's own ID, for callers that just need a runtime for whichever node a resource is placed on.
func (*Registry) SetLocal ¶ added in v0.2.0
SetLocal makes Resolve answer localID with t, this process's own runtime. It is deliberately not in byID: Get callers (build dispatch, mesh sink) must keep treating the local node as "not a remote agent".
func (*Registry) Unregister ¶
Unregister removes nodeID's entry, if any. Not an error if nodeID was never registered, matching this codebase's established idempotent- delete convention (store.DeleteDesiredService, store.DeleteNode).
type RejectedHandshake ¶
type RejectedHandshake struct {
Subject, SourceIP, Reason, Fingerprint string
}
RejectedHandshake describes a client certificate refused during the TLS handshake. Subject is what the certificate claims, not a verified identity.
type RemoteBuilder ¶ added in v0.2.0
type RemoteBuilder interface {
BuildOnNode(ctx context.Context, req build.RemoteRequest, image io.Writer, progress func(build.ProgressEvent)) (*build.Result, error)
}
RemoteBuilder is implemented by transports that can run a build on their node.
type RenewConfig ¶ added in v0.2.0
type RenewConfig struct {
// Fraction of the certificate's lifetime after which renewal starts.
Fraction float64
// Jitter is the fraction of lifetime added at random so nodes enrolled
// together do not all renew at once.
Jitter float64
RetryMin, RetryMax time.Duration
}
RenewConfig tunes when and how often the agent renews its certificate.
type RenewalStatus ¶
type RenewalStatus struct {
NextRenewAt time.Time
LastError string
LastFailedAt time.Time
NextRetryAt time.Time
ConsecutiveFailures int
}
RenewalStatus is the renewer's schedule and last failure, reported to the control plane so the node page can show it.
type Renewer ¶ added in v0.2.0
type Renewer struct {
// contains filtered or unexported fields
}
Renewer keeps an agent's certificate fresh over its authenticated connection (ADR 021).
func NewRenewer ¶ added in v0.2.0
func NewRenewer(holder *IdentityHolder, persist IdentityPersister, check IdentityChecker, cfg RenewConfig, logger *slog.Logger) *Renewer
NewRenewer builds a Renewer. check defaults to CheckIdentityAt(addr) when nil.
func (*Renewer) Holder ¶ added in v0.2.0
func (r *Renewer) Holder() *IdentityHolder
Holder returns the identity holder the renewer updates.
func (*Renewer) RenewAt ¶ added in v0.2.0
RenewAt is when id should be renewed: Fraction of its lifetime plus up to Jitter more.
func (*Renewer) RenewNow ¶
func (r *Renewer) RenewNow()
RenewNow makes Run attempt a renewal immediately, skipping any wait.
func (*Renewer) RenewOnce ¶ added in v0.2.0
RenewOnce keeps the current certificate on failure, which the control plane still accepts during the overlap window.
func (*Renewer) Run ¶ added in v0.2.0
func (r *Renewer) Run(ctx context.Context, client agentpb.AgentServiceClient)
Run renews whenever the current certificate reaches its renewal time, retrying with capped backoff, until ctx is done. A RenewNow call skips the wait. The schedule comes from the certificate, so a restart resumes it.
func (*Renewer) Status ¶
func (r *Renewer) Status() RenewalStatus
Status returns the current schedule and failure state.
type SecurityConfig ¶
SecurityConfig bounds the log. Zero fields take the defaults.
type SecurityStore ¶
type SecurityStore interface {
AddNodeSecurityEvent(ctx context.Context, ev store.NodeSecurityEvent, p store.SecurityEventPolicy, now time.Time) error
PruneNodeSecurityEvents(ctx context.Context, cutoff time.Time) (int64, error)
SetNodeCAPin(ctx context.Context, nodeID, state string, now time.Time) error
SetNodeRenewalReport(ctx context.Context, s store.NodeTrustState, now time.Time) error
}
SecurityStore is the persistence the security event log needs. *store.DB satisfies it.
type Server ¶
type Server struct {
agentpb.UnimplementedAgentServiceServer
// contains filtered or unexported fields
}
Server implements agentpb.AgentServiceServer.
func NewServer ¶
func NewServer(ca *CA, st EnrollStore, registry *Registry, logger *slog.Logger, opts ...Option) *Server
NewServer builds a Server. logger defaults to slog.Default() if nil.
func (*Server) CheckIdentity ¶ added in v0.2.0
func (s *Server) CheckIdentity(ctx context.Context, _ *agentpb.CheckIdentityRequest) (*agentpb.CheckIdentityResponse, error)
CheckIdentity implements agentpb.AgentServiceServer.
func (*Server) Disconnect ¶ added in v0.2.0
Disconnect ends nodeID's live Session, if any, so a node whose certificate was just revoked stops acting on an already-open stream.
func (*Server) Enroll ¶
func (s *Server) Enroll(ctx context.Context, req *agentpb.EnrollRequest) (*agentpb.EnrollResponse, error)
Enroll implements agentpb.AgentServiceServer.
func (*Server) NotifyShutdown ¶ added in v0.2.0
func (s *Server) NotifyShutdown()
NotifyShutdown sends GoAway to every agent, best-effort; agents that miss it fall back to the GracefulStop timeout.
func (*Server) ObserveRejected ¶
func (s *Server) ObserveRejected(r RejectedHandshake)
ObserveRejected records a client certificate the TLS handshake refused.
func (*Server) RecordSecurityEvent ¶
func (s *Server) RecordSecurityEvent(ev store.NodeSecurityEvent)
RecordSecurityEvent appends an event without coalescing, for operator actions such as revoking a certificate.
func (*Server) Reenroll ¶ added in v0.2.0
func (s *Server) Reenroll(ctx context.Context, req *agentpb.ReenrollRequest) (*agentpb.ReenrollResponse, error)
Reenroll implements agentpb.AgentServiceServer: a token bound to an existing node buys that node a new certificate. Minting the token was the operator's authorization, so a revocation is cleared.
func (*Server) Renew ¶ added in v0.2.0
func (s *Server) Renew(ctx context.Context, req *agentpb.RenewRequest) (*agentpb.RenewResponse, error)
Renew implements agentpb.AgentServiceServer. The CSR is signed before the store is updated: if the update fails, the new certificate was never recorded and so is never trusted.
func (*Server) RequestRenew ¶
RequestRenew asks nodeID's agent, over its live session, to renew its certificate now.
func (*Server) Session ¶
func (s *Server) Session(stream agentpb.AgentService_SessionServer) error
Session implements agentpb.AgentServiceServer for an mTLS-authenticated agent stream.
func (*Server) SetSilenceSource ¶
func (s *Server) SetSilenceSource(src SilenceSource)
SetSilenceSource wires the URL provider; safe to call after the server starts.
type SessionOption ¶ added in v0.2.0
type SessionOption func(*sessionConfig)
SessionOption configures optional RunSession behavior.
func WithBuildRunner ¶ added in v0.2.0
func WithBuildRunner(runner BuildRunner) SessionOption
WithBuildRunner sets the build runner; without one, dispatched builds are rejected up front.
func WithFileStorage ¶
func WithFileStorage(dir string) SessionOption
WithFileStorage lets the control plane read and write objects under dir, and nowhere else, over this session.
func WithGPUProbe ¶ added in v0.2.0
func WithGPUProbe(p GPUProbe) SessionOption
WithGPUProbe makes RunSession report this node's GPUs to the control plane on connect and periodically after.
func WithHeartbeatInterval ¶
func WithHeartbeatInterval(d time.Duration) SessionOption
WithHeartbeatInterval overrides the Heartbeat cadence; the env var is read by cmd/levelrail-agent, not here.
func WithHostProbe ¶ added in v0.2.2
func WithHostProbe(p HostProbe) SessionOption
WithHostProbe makes RunSession report this node's host memory split to the control plane periodically.
func WithKeepalive ¶ added in v0.2.0
func WithKeepalive(pingTime, timeout time.Duration) SessionOption
WithKeepalive overrides the HTTP/2 PING keepalive timing; the caller supplies env-derived durations.
func WithMesh ¶ added in v0.2.0
func WithMesh(nodeID string, mesh MeshApplier) SessionOption
WithMesh enables ApplyMesh and RotateMeshKey on this stream; without it both answer ErrMeshUnavailable.
func WithOnboardingProbe ¶
func WithOnboardingProbe(p OnboardingProbe, interval time.Duration) SessionOption
WithOnboardingProbe makes RunSession report the node's onboarding facts every interval.
func WithRenewer ¶ added in v0.2.0
func WithRenewer(r *Renewer) SessionOption
WithRenewer keeps the session's certificate fresh with r while the session is open. The identity r holds replaces the one RunSession was given, so each reconnect presents the newest certificate.
func WithSilenceWatcher ¶
func WithSilenceWatcher(w *SilenceWatcher) SessionOption
WithSilenceWatcher feeds w the session state and the URL the control plane pushes.
type SilenceConfig ¶
type SilenceConfig struct {
Grace, Interval, MaxBackoff, Check, Timeout time.Duration
JitterPct int
AllowPrivate bool
}
SilenceConfig tunes the watcher; zero fields fall back to the defaults.
func SilenceConfigFromEnv ¶
func SilenceConfigFromEnv(lookup func(string) (string, bool)) (SilenceConfig, error)
SilenceConfigFromEnv reads the watcher env; a bad value is an error so a typo does not silently disable alerting.
type SilenceSource ¶
SilenceSource returns the off-host URL agents ping when they lose the control plane, or "" for none.
type SilenceWatcher ¶
type SilenceWatcher struct {
// contains filtered or unexported fields
}
SilenceWatcher pings an off-host URL while this agent has had no contact with the control plane for longer than the grace.
func NewSilenceWatcher ¶
func NewSilenceWatcher(cfg SilenceConfig, node string, logger *slog.Logger, rnd func(int64) int64) *SilenceWatcher
NewSilenceWatcher builds a watcher; contact is assumed fresh at start so a booting agent does not alert before it dials.
func (*SilenceWatcher) Run ¶
func (w *SilenceWatcher) Run(ctx context.Context)
Run checks every Check and pings with jittered interval while silent, backing off on failed pings, until ctx ends.
func (*SilenceWatcher) SetConnected ¶
func (w *SilenceWatcher) SetConnected(up bool)
SetConnected marks a session as up or down; the silence clock starts when it goes down.
func (*SilenceWatcher) SetURL ¶
func (w *SilenceWatcher) SetURL(raw string)
SetURL stores the configured URL; an empty or invalid one disables the watcher.
type StoredOnboarding ¶
type StoredOnboarding struct {
Report OnboardingReport
ReceivedAt time.Time
}
StoredOnboarding is a node's latest report with the control plane's receipt time.
type Transport ¶
Transport is what a reconcile controller needs from the node a resource is placed on. It embeds docker.Runtime so the two cannot drift; optional agent capabilities go in separate interfaces like RemoteBuilder.
type UnmanagedContainer ¶ added in v0.2.2
UnmanagedContainer is one running container on a node that Levelrail does not manage.
type VolumeFileEntry ¶
type VolumeFileEntry = volumefiles.Entry
VolumeFileEntry is one item of a volume directory listing.
type VolumeFileOps ¶
type VolumeFileOps interface {
VolumeList(ctx context.Context, volume, dir string, limit int) ([]VolumeFileEntry, bool, error)
VolumeRead(ctx context.Context, volume, path string) (io.ReadCloser, error)
VolumeWrite(ctx context.Context, volume, path string, content io.Reader, maxBytes int64) error
VolumeRemove(ctx context.Context, volume, path string) error
}
VolumeFileOps is the node-side surface the API uses for volume file browsing.
Source Files
¶
- archive_relay.go
- archive_transport.go
- build_dispatch.go
- build_relay.go
- build_wire.go
- client.go
- convert.go
- credentials.go
- exec_relay.go
- execute.go
- file_transport.go
- filestore.go
- gpu_report.go
- grpc_transport.go
- host_report.go
- identity.go
- identity_file.go
- logs_relay.go
- mesh_convert.go
- mesh_dispatch.go
- mesh_sink.go
- mesh_status.go
- mux.go
- onboarding.go
- pki.go
- pki_csr.go
- renew.go
- renew_session.go
- security_events.go
- server.go
- server_cert.go
- server_observer.go
- server_security.go
- silence.go
- silence_server.go
- transport.go
- transport_job.go
- volume_files.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package migrationmode is the read-only agent that runs on a source host being migrated away from.
|
Package migrationmode is the read-only agent that runs on a source host being migrated away from. |
|
Package pinned holds the small trust primitives shared by every reverse-dialed client: CA fingerprint pinning and key plus CSR generation.
|
Package pinned holds the small trust primitives shared by every reverse-dialed client: CA fingerprint pinning and key plus CSR generation. |