Documentation
¶
Index ¶
- Constants
- Variables
- func AgentHomeStateRoot(origin, contextName, workspaceID string) (string, error)
- func CanonicalStateRoot(origin, contextName, workspaceID string) (string, error)
- func DiagnosticsReaderIdentity() machinediagnostics.ReaderIdentity
- func EncodeDaemonConfig(cfg *DaemonConfig) (string, error)
- func FormatTimeout(d time.Duration) string
- func GetEncodedWorkspaceDaemonConfig(platformOptions devsy.PlatformOptions, workspaceConfig *provider2.Workspace, ...) (string, error)
- func InstallDaemon(opts InstallOptions) error
- func RefreshLifecycle(encoded string, lifecycle LifecycleOptions, shutdownAction string) (string, error)
- func RemoveDaemon() error
- func ResolveInactivityTimeout(in TimeoutInputs) (time.Duration, error)
- func RunProcessReaper(ctx context.Context)
- func StartActivityWriter(ctx context.Context, interval time.Duration) (context.Context, func(), error)
- func TouchActivity(path string, now time.Time) error
- type AckRecord
- type ActivityWriter
- type ControlRecord
- type DaemonConfig
- type Decision
- type InstallOptions
- type LifecycleClient
- type LifecycleConfig
- type LifecycleLoop
- type LifecycleMonitor
- func (m *LifecycleMonitor) Apply(rec ControlRecord, now time.Time) (bool, error)
- func (m *LifecycleMonitor) ArmNow(timeout time.Duration, now time.Time)
- func (m *LifecycleMonitor) CheckInterval() time.Duration
- func (m *LifecycleMonitor) Evaluate(now, modTime time.Time, statErr error) Decision
- func (m *LifecycleMonitor) Release(id string, now time.Time)
- type LifecycleOptions
- type LifecycleOwner
- type LifecycleState
- type OwnerRecord
- type ResolveStateLocationOptions
- type SshConfig
- type StateLayout
- type StateLocation
- type TimeoutInputs
Constants ¶
const ContainerDaemonConfigPath = "/var/run/secrets/" + config.BinaryName + "/daemon_config"
const (
DefaultActivityInterval = 10 * time.Second
)
const ( // LifecycleOwnerManagedDaemon marks a container whose main process is the // Devsy daemon and owns inactivity shutdown. LifecycleOwnerManagedDaemon = "managedDaemon" )
const (
LifecycleProtocolVersion = 3
)
Variables ¶
var ( ErrLifecycleOwnerMissing = errors.New( "container lifecycle owner unavailable; stop and start the workspace to replace its pod", ) ErrLifecycleNotAcknowledged = errors.New( "container lifecycle owner did not acknowledge the update", ) ErrLifecycleOwnerIncompatible = errors.New( "container lifecycle owner is incompatible; stop and start the workspace to replace its pod", ) )
var ErrInactivityExpired = errors.New("inactivity timeout reached")
ErrInactivityExpired is returned by the lifecycle loop when the idle timeout elapsed. It is the normal way a managed container asks to stop.
Functions ¶
func AgentHomeStateRoot ¶ added in v1.20.0
AgentHomeStateRoot derives the agent home from a workspace origin created by a container-side agent invocation.
func CanonicalStateRoot ¶ added in v1.20.0
CanonicalStateRoot derives the canonical data root from a persisted workspace origin while validating every structural component.
func DiagnosticsReaderIdentity ¶ added in v1.20.0
func DiagnosticsReaderIdentity() machinediagnostics.ReaderIdentity
DiagnosticsReaderIdentity captures the invoking user before systemd starts the daemon as root. SUDO_UID/GID identify the original user on sudo paths.
func EncodeDaemonConfig ¶
func EncodeDaemonConfig(cfg *DaemonConfig) (string, error)
EncodeDaemonConfig is the inverse of DecodeDaemonConfig.
func FormatTimeout ¶
FormatTimeout renders a timeout for DaemonConfig/ContainerWorkspaceInfo; zero is "".
func GetEncodedWorkspaceDaemonConfig ¶
func GetEncodedWorkspaceDaemonConfig( platformOptions devsy.PlatformOptions, workspaceConfig *provider2.Workspace, substitutionContext *config.SubstitutionContext, mergedConfig *config.MergedDevContainerConfig, lifecycle LifecycleOptions, ) (string, error)
func InstallDaemon ¶
func InstallDaemon( opts InstallOptions, ) error
func RefreshLifecycle ¶
func RefreshLifecycle( encoded string, lifecycle LifecycleOptions, shutdownAction string, ) (string, error)
RefreshLifecycle rewrites the generated lifecycle policy of a stored encoded daemon config, leaving platform and SSH settings untouched. An empty stored config yields a minimal timeout-only config.
func RemoveDaemon ¶
func RemoveDaemon() error
func ResolveInactivityTimeout ¶
func ResolveInactivityTimeout(in TimeoutInputs) (time.Duration, error)
ResolveInactivityTimeout returns the single effective inactivity timeout for a managed container. Zero means disabled.
func RunProcessReaper ¶
RunProcessReaper reaps zombie child processes until ctx is cancelled. This is needed when running as PID 1 (e.g. in a container).
func StartActivityWriter ¶
Types ¶
type ActivityWriter ¶
type ActivityWriter struct {
Path string
LifecycleDir string
RequireOwner bool
Interval time.Duration
Touch func(string, time.Time) error
Now func() time.Time
Tick func(time.Duration) (<-chan time.Time, func())
}
ActivityWriter retains file heartbeats for non-managed daemons. Managed work is protected by its acknowledged connection, including when all writes fail.
func (ActivityWriter) Run ¶
func (w ActivityWriter) Run(ctx context.Context)
Run records legacy file activity without claiming managed protection. Managed callers use Start so registration completes before their work begins.
type ControlRecord ¶
type ControlRecord struct {
Version int `json:"version"`
Generation string `json:"generation"`
ClientID string `json:"clientID"`
Sequence uint64 `json:"sequence"`
PID int `json:"pid"`
StartTicks string `json:"startTicks,omitempty"`
Timeout string `json:"timeout"`
ShutdownAction string `json:"shutdownAction"`
State LifecycleState `json:"state"`
}
ControlRecord belongs to one connection and operation. PID/start identity prevents inherited descriptors or PID reuse from orphaning setup protection.
type DaemonConfig ¶
type DaemonConfig struct {
Platform devsy.PlatformOptions `json:"platform"`
Ssh SshConfig `json:"ssh"`
Timeout string `json:"timeout"`
ShutdownAction string `json:"shutdownAction,omitempty"`
Lifecycle LifecycleConfig `json:"lifecycle,omitzero"`
}
func BuildWorkspaceDaemonConfig ¶
func BuildWorkspaceDaemonConfig( platformOptions devsy.PlatformOptions, workspaceConfig *provider2.Workspace, substitutionContext *config.SubstitutionContext, mergedConfig *config.MergedDevContainerConfig, lifecycle LifecycleOptions, ) (*DaemonConfig, error)
func DecodeDaemonConfig ¶
func DecodeDaemonConfig(encoded string) (*DaemonConfig, error)
DecodeDaemonConfig parses the base64 JSON produced by GetEncodedWorkspaceDaemonConfig.
func LoadContainerDaemonConfig ¶
func LoadContainerDaemonConfig() (*DaemonConfig, error)
type InstallOptions ¶ added in v1.20.0
type InstallOptions struct {
StateLocation StateLocation
Interval string
ShutdownAction string
DiagnosticsReader machinediagnostics.ReaderIdentity
}
type LifecycleClient ¶
type LifecycleClient struct {
// contains filtered or unexported fields
}
LifecycleClient never reconnects silently: losing protection cancels the work. A fresh operation must explicitly connect to the current owner instance.
func ConnectLifecycle ¶
func ConnectLifecycle(ctx context.Context, dir string) (*LifecycleClient, error)
func (*LifecycleClient) Close ¶
func (c *LifecycleClient) Close() error
func (*LifecycleClient) Done ¶
func (c *LifecycleClient) Done() <-chan struct{}
func (*LifecycleClient) ProtectedContext ¶
func (c *LifecycleClient) ProtectedContext( parent context.Context, ) (context.Context, context.CancelCauseFunc)
ProtectedContext aborts work on socket loss instead of leaving it untracked.
func (*LifecycleClient) Send ¶
func (c *LifecycleClient) Send( state LifecycleState, timeout, shutdownAction string, ) (sendErr error)
Send retries the same operation while the connection survives. The owner's cached result makes acknowledgement recovery independent of applying state.
type LifecycleConfig ¶
type LifecycleConfig struct {
// Owner is LifecycleOwnerManagedDaemon when the daemon is the container's main
// process and owns the timer.
Owner string `json:"owner,omitempty"`
// SetupArmsTimer means the daemon starts unarmed and container setup arms it.
SetupArmsTimer bool `json:"setupArmsTimer,omitempty"`
}
LifecycleConfig tells the daemon who owns inactivity shutdown.
func (LifecycleConfig) Managed ¶
func (l LifecycleConfig) Managed() bool
Managed reports whether the daemon owns the inactivity timer.
type LifecycleLoop ¶
type LifecycleLoop struct {
Owner *LifecycleOwner
Monitor *LifecycleMonitor
ActivityPath string
}
LifecycleLoop uses live registrations for managed containers and the legacy activity file only for daemons without a managed owner.
type LifecycleMonitor ¶
type LifecycleMonitor struct {
// contains filtered or unexported fields
}
LifecycleMonitor serializes protection changes with the decision to stop.
func (*LifecycleMonitor) Apply ¶
func (m *LifecycleMonitor) Apply(rec ControlRecord, now time.Time) (bool, error)
Apply changes one client's protection. Acknowledgements are sent only after this method returns; no filesystem write is needed to retain protection.
func (*LifecycleMonitor) ArmNow ¶
func (m *LifecycleMonitor) ArmNow(timeout time.Duration, now time.Time)
ArmNow arms daemons that have no managed setup handshake.
func (*LifecycleMonitor) CheckInterval ¶
func (m *LifecycleMonitor) CheckInterval() time.Duration
CheckInterval bounds the delay before observing idle time or process death.
type LifecycleOptions ¶
type LifecycleOptions struct {
// Managed marks the daemon as the container's main process and timer owner.
Managed bool
// Timeout is the effective inactivity timeout; zero disables it.
Timeout time.Duration
}
LifecycleOptions are the explicit lifecycle inputs for building a daemon config.
func ResolveManagedLifecycle ¶
func ResolveManagedLifecycle( timeout time.Duration, dockerless, imageEntrypoint bool, ) (LifecycleOptions, error)
ResolveManagedLifecycle selects ownership for a managed-capable driver's topology. Dockerless owns the pod process; its nested workspace cannot stop that pod.
type LifecycleOwner ¶
type LifecycleOwner struct {
// contains filtered or unexported fields
}
LifecycleOwner keeps live work and applied operations in memory. Discovery and policy files are never evidence that a registered writer is healthy.
func NewLifecycleOwner ¶
func NewLifecycleOwner(dir string) (*LifecycleOwner, error)
NewLifecycleOwner binds before publishing discovery. All subsequent safety decisions and acknowledgements use the connection, never writable files.
func (*LifecycleOwner) Close ¶
func (o *LifecycleOwner) Close() error
func (*LifecycleOwner) Generation ¶
func (o *LifecycleOwner) Generation() string
func (*LifecycleOwner) Serve ¶
func (o *LifecycleOwner) Serve(ctx context.Context, monitor *LifecycleMonitor) error
type LifecycleState ¶
type LifecycleState string
const ( LifecycleStateSetup LifecycleState = "setup" LifecycleStateReady LifecycleState = "ready" LifecycleStateFailed LifecycleState = "failed" LifecycleStateActivity LifecycleState = "activity" LifecycleStateRelease LifecycleState = "release" )
type OwnerRecord ¶
type OwnerRecord struct {
Version int `json:"version"`
Generation string `json:"generation"`
PID int `json:"pid"`
StartTicks string `json:"startTicks,omitempty"`
}
OwnerRecord identifies the daemon instance, not a lease on work.
type ResolveStateLocationOptions ¶ added in v1.20.0
type StateLayout ¶ added in v1.20.0
type StateLayout string
StateLayout describes how machine workspace state is stored beneath Root.
const ( StateLayoutCanonical StateLayout = "canonical" StateLayoutAgentHome StateLayout = "agent-home" )
type StateLocation ¶ added in v1.20.0
type StateLocation struct {
Root string
Layout StateLayout
}
StateLocation identifies the workspace state that an inactivity daemon owns.
func ResolveStateLocation ¶ added in v1.20.0
func ResolveStateLocation(opts ResolveStateLocationOptions) (StateLocation, error)
ResolveStateLocation captures the persisted state root at installation time, before the daemon is started by systemd under a potentially different user.
func (StateLocation) Validate ¶ added in v1.20.0
func (l StateLocation) Validate() error
func (StateLocation) WorkspaceConfigPattern ¶ added in v1.20.0
func (l StateLocation) WorkspaceConfigPattern() (string, error)
type TimeoutInputs ¶
type TimeoutInputs struct {
// Canonical is agent.containerInactivityTimeout.
Canonical string
// Legacy is agent.kubernetes.inactivityTimeout, used only when Canonical is empty.
Legacy string
ShutdownAction string
DisableDaemon bool
}
TimeoutInputs are the configured values that decide the effective timeout.