daemon

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: Apache-2.0 Imports: 46 Imported by: 0

Documentation

Overview

Package daemon provides the AgentPaaS control daemon — a Unix-socket-bound gRPC server that implements the ControlService API.

The daemon lifecycle has three phases:

  1. Starting – home directory is validated, socket is bound, but the daemon is not yet ready to serve requests. All RPCs return Unavailable.
  2. Ready – the caller signals readiness via Ready(). RPCs are served normally. Stub handlers return Unimplemented for methods that have not been wired up yet.
  3. Shutdown – SIGTERM/SIGINT triggers graceful shutdown: new RPCs are rejected and in-flight requests are drained with a configurable timeout.

Single-instance enforcement

The daemon uses POSIX flock(2) on a lock file inside the home directory. A second daemon trying to start will fail with EWOULDBLOCK.

Security

  • The daemon refuses to run as root unless --allow-root-for-test is set (checked at the cmd/agentpaasd level).
  • The Unix socket file is created with mode 0600.
  • The home directory and socket permissions are validated before serving.

Versioning

VersionInfo is embedded in gRPC response trailers and returned as a diagnostic check in the Doctor RPC so that the CLI can verify daemon compatibility before issuing commands.

Index

Constants

View Source
const (
	// ProtoVersion is the version of the ControlService protocol that this
	// daemon implements. It corresponds to the API package import path.
	ProtoVersion = "v1"
)

Current CLI and daemon version. This is the single source of truth for the agentpaasd binary and the agent CLI alike.

Variables

View Source
var CLIVersion = "0.1.0-dev"

CLIVersion is the current version of the agentpaas CLI. Set at build time via -ldflags "-X github.com/AgentPaaS-ai/agentpaas/internal/daemon.CLIVersion=<version>".

View Source
var DaemonVersion = "0.1.0-dev"

DaemonVersion is the current version of the agentpaas daemon. Set at build time via -ldflags "-X github.com/AgentPaaS-ai/agentpaas/internal/daemon.DaemonVersion=<version>".

View Source
var GitCommit = "unknown"

GitCommit is set at build time via -ldflags "-X github.com/AgentPaaS-ai/agentpaas/internal/daemon.GitCommit=<commit>". If not injected, it defaults to "unknown".

Functions

func CheckRoot

func CheckRoot(uid int, allowRoot bool) error

CheckRoot checks whether the daemon is running as root and returns an error if it is, unless allowRoot is true. This protects against accidental privilege escalation.

func NewDockerResourceManager

func NewDockerResourceManager(rt *runtime.DockerRuntime) *dockerResourceManager

NewDockerResourceManager creates a ResourceManager backed by the given Docker runtime. The runtime must already be initialized.

Types

type ConfirmationStore

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

ConfirmationStore tracks trust-boundary changes awaiting a human decision.

func NewConfirmationStore

func NewConfirmationStore() *ConfirmationStore

NewConfirmationStore creates an empty confirmation store.

func (*ConfirmationStore) Approve

func (s *ConfirmationStore) Approve(id string) error

Approve records explicit human approval without applying the change.

func (*ConfirmationStore) Create

func (s *ConfirmationStore) Create(change PendingConfirmation) (string, error)

Create stores a proposed change in the pending state.

func (*ConfirmationStore) Decline

func (s *ConfirmationStore) Decline(id string) error

Decline records explicit human rejection of the change.

func (*ConfirmationStore) Expire

func (s *ConfirmationStore) Expire() int

Expire removes confirmations whose expiry time has passed.

func (*ConfirmationStore) Get

Get retrieves a confirmation by id.

func (*ConfirmationStore) ListPending

func (s *ConfirmationStore) ListPending() []PendingConfirmation

ListPending returns snapshots of all confirmations still awaiting a decision.

type Daemon

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

Daemon is the AgentPaaS control daemon. It binds a gRPC server to a Unix domain socket and serves the ControlService API.

Use New() to create, Start() to begin serving, and Stop() or HandleSignal() for graceful shutdown.

func New

func New(paths *home.HomePaths, version VersionInfo, opts ...Option) (*Daemon, error)

New creates a new Daemon bound to the given home directory paths.

It acquires an exclusive flock on the lock file to prevent multiple daemon instances. If the lock cannot be acquired (EWOULDBLOCK), New returns an error indicating that another daemon is already running.

Callers must call Start() to begin serving, and Stop() (or HandleSignal) to shut down gracefully.

func (*Daemon) HandleSignal

func (d *Daemon) HandleSignal(sig os.Signal, sigCh chan os.Signal) error

HandleSignal registers a signal handler that triggers graceful shutdown when the given signal is received. The signal is sent to sigCh by the caller (or by os/signal).

This is a test-friendly wrapper: instead of using signal.Notify directly, it accepts a channel that the test or main goroutine feeds signals into.

func (*Daemon) IsReady

func (d *Daemon) IsReady() bool

IsReady returns whether the daemon is in the ready state.

func (*Daemon) Ready

func (d *Daemon) Ready()

Ready transitions the daemon to the ready state. After this call, RPCs are processed normally instead of returning Unavailable.

The daemon is intentionally NOT ready immediately after Start() so that the caller can perform post-boot initialization before accepting RPCs.

func (*Daemon) Start

func (d *Daemon) Start(ctx context.Context) error

Start binds the Unix socket, starts the gRPC server, and begins serving.

Before binding, it:

  1. Calls home.Ensure() to set up the home directory layout.
  2. Calls home.ValidatePermissions() to check security invariants.
  3. Calls home.CleanStale() to remove stale socket/lock/pid files.
  4. Checks that the daemon is not running as root (unless WithAllowRoot).
  5. Writes the PID file.
  6. Binds the Unix socket with mode 0600.
  7. Registers the ControlService gRPC server.

After Start() returns, the daemon is listening but not yet ready to serve requests. Call Ready() to transition to the ready state.

func (*Daemon) Stop

func (d *Daemon) Stop(ctx context.Context) error

Stop gracefully shuts down the daemon. It:

  1. Stops accepting new RPCs (GracefulStop).
  2. Waits up to the default shutdown timeout for in-flight RPCs to drain.
  3. Force-stops if the timeout expires.
  4. Removes the PID file.
  5. Releases the lock file.

Stop is idempotent and safe to call multiple times.

type Option

type Option func(*Daemon)

Option configures the Daemon.

func WithAllowRoot

func WithAllowRoot() Option

WithAllowRoot allows the daemon to run as root. This is intended for integration tests and containerized environments where running as root is expected.

func WithDashboard

func WithDashboard(addr string) Option

WithDashboard sets the dashboard listen address. Pass an empty string to disable the dashboard server.

type PendingConfirmation

type PendingConfirmation struct {
	ID            string                 `json:"id"`
	CreatedAt     time.Time              `json:"created_at"`
	ExpiresAt     time.Time              `json:"expires_at"`
	ChangeType    string                 `json:"change_type"`
	RiskLevel     string                 `json:"risk_level"`
	Rationale     string                 `json:"rationale"`
	AffectedDests []string               `json:"affected_destinations,omitempty"`
	CredentialIDs []string               `json:"credential_ids,omitempty"`
	EvidenceRefs  []operator.EvidenceRef `json:"evidence_refs,omitempty"`
	ProposedPatch string                 `json:"proposed_patch,omitempty"`
	Status        string                 `json:"status"`
}

PendingConfirmation describes one proposed trust-boundary change.

type VersionInfo

type VersionInfo struct {
	// CLIVersion is the version of the CLI that was compiled with this daemon.
	CLIVersion string

	// DaemonVersion is the version of the running daemon binary.
	DaemonVersion string

	// ProtoVersion is the protocol version string (e.g. "v1").
	ProtoVersion string

	// GitCommit is the full git SHA from which this binary was built.
	GitCommit string

	// GoVersion is the Go runtime version (e.g. "go1.26.4").
	GoVersion string

	// OsArch is the operating system and architecture (e.g. "linux/amd64").
	OsArch string

	// DockerContext is the name of the active Docker context (stub for now).
	DockerContext string

	// DockerAPIVersion is the Docker API version (stub for now).
	DockerAPIVersion string
}

VersionInfo holds detailed version and compatibility information that the daemon reports to clients via the Doctor RPC and gRPC response trailers.

func CurrentVersion

func CurrentVersion() VersionInfo

CurrentVersion returns a VersionInfo populated with build-time constants and runtime values. This is the canonical version snapshot for the daemon.

func (VersionInfo) String

func (v VersionInfo) String() string

String returns a human-readable summary of the version info.

Jump to

Keyboard shortcuts

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