managers

package
v0.0.0-...-443b9db Latest Latest
Warning

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

Go to latest
Published: May 7, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package managers defines the Manager interface and shared plan/apply/verify types used by each of the 13 linuxctl subsystem managers.

Index

Constants

View Source
const LimitsManagedPath = "/etc/security/limits.d/99-linuxctl.conf"

LimitsManagedPath is the single drop-in file limits manager owns.

View Source
const SysctlManagedPath = "/etc/sysctl.d/99-linuxctl.conf"

SysctlManagedPath is the single file sysctl manager owns. Every Apply rewrites it atomically; the rest of /etc/sysctl.d/ is left alone.

Variables

View Source
var ErrNotImplemented = errors.New("not implemented")

ErrNotImplemented is returned by scaffold manager methods.

View Source
var ErrSessionRequired = errors.New("session is required")

ErrSessionRequired is returned when an Apply/Verify path is invoked on a manager that was not bound to a session.

Functions

func All

func All() map[string]Manager

All returns a snapshot of every registered manager keyed by name.

func Register

func Register(m Manager)

Register adds m to the global registry. Safe for init-time use.

func RunAndCheck

func RunAndCheck(ctx context.Context, sess session.Session, cmd string) (string, error)

RunAndCheck runs cmd through sess and returns stdout. Non-zero exits are wrapped with the captured stderr preview for context.

func RunSudoAndCheck

func RunSudoAndCheck(ctx context.Context, sess session.Session, cmd string) (string, error)

RunSudoAndCheck is RunAndCheck under sudo.

Types

type ApplyResult

type ApplyResult struct {
	RunID    string
	Applied  []Change
	Skipped  []Change
	Failed   []ChangeErr
	Duration time.Duration
}

ApplyResult is returned from Manager.Apply.

type Change

type Change struct {
	ID          string
	Manager     string
	Target      string
	Action      string // create|update|delete|noop
	Before      any
	After       any
	RollbackCmd string
	Hazard      HazardLevel
}

Change describes a single planned mutation.

type ChangeErr

type ChangeErr struct {
	Change Change
	Err    error
}

ChangeErr pairs a failed change with its error.

type ChangeSet

type ChangeSet = []Change

ChangeSet is a convenience alias for an ordered slice of changes.

type ClusterSSHResult

type ClusterSSHResult struct {
	PerNode map[string]*NodeSSHResult
	Errors  []error
}

ClusterSSHResult summarises what SetupClusterSSH did per node, plus any errors that were captured without aborting the run.

func SetupClusterSSH

func SetupClusterSSH(ctx context.Context, sessions map[string]SessionRunner, users []string) (*ClusterSSHResult, error)

SetupClusterSSH generates Ed25519 keypairs for each (node, user) pair, cross-authorizes the collected public keys, and seeds per-user known_hosts via ssh-keyscan. Idempotent: re-running yields no drift.

Phase 1 (parallel per node): ensure ~user/.ssh/id_ed25519 exists, read pubkey. Phase 2 (serialised): merge collected pubkeys into each node's authorized_keys + seed known_hosts for every peer.

Per-node failures are accumulated in Result.Errors rather than aborting the whole run — the rest of the cluster may still get partial setup, which is more useful than a half-broken RAC bootstrap with no visibility.

type DirManager

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

DirManager reconciles a list of config.Directory entries. It is the simplest manager and proves the Manager contract end-to-end.

Safety: Plan/Apply only create or adjust ownership/mode. Delete is never planned — directories must be removed by a human. Rollback reverses only in-session creations.

func NewDirManager

func NewDirManager() *DirManager

NewDirManager returns a directory manager without a session. Use WithSession to bind one before Plan/Apply/Verify/Rollback.

func (*DirManager) Apply

func (m *DirManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*DirManager) DependsOn

func (*DirManager) DependsOn() []string

DependsOn implements Manager — directories are created after their mount parents exist.

func (*DirManager) Name

func (*DirManager) Name() string

Name implements Manager.

func (*DirManager) Plan

func (m *DirManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*DirManager) Rollback

func (m *DirManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Only reverses creations (`rmdir` if empty); ownership / mode updates are not reversed because the manager cannot know the pre-apply values without a persisted run record.

func (*DirManager) Verify

func (m *DirManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*DirManager) WithSession

func (m *DirManager) WithSession(sess session.Session) *DirManager

WithSession returns a copy bound to sess.

type DiskManager

type DiskManager struct {
	Session session.Session

	// ReformatFilesystems opts in to destructive mkfs over an existing,
	// mismatched filesystem (e.g. ext4 found where manifest says xfs).
	// Default false → Plan errors with remediation. Wired from the global
	// `--reformat-filesystems` flag in internal/root. linuxctl#52.
	ReformatFilesystems bool
}

DiskManager handles LVM (pvcreate/vgcreate/lvcreate), mkfs, and fstab for root + additional disks. Discovery uses `pvs/vgs/lvs --reportformat=json` and `blkid`; mutation uses sudo-privileged LVM + mkfs commands.

Safety: DiskManager only creates. It never removes PVs/VGs/LVs or reshapes existing filesystems. Rollback reverses in-session creations only.

mkfs idempotency (linuxctl#52): Plan probes blkid on each desired LV. If the existing filesystem matches the manifest `fs:` value, mkfs is skipped. If a different filesystem is present, Plan returns an error with the remediation hint to set --reformat-filesystems (a.k.a. DiskManager.ReformatFilesystems = true). If no filesystem is present, mkfs proceeds as before.

func NewDiskManager

func NewDiskManager() *DiskManager

NewDiskManager returns a disk manager bound to sess. sess may be nil for tests that exercise pure parsing paths.

func (*DiskManager) Apply

func (m *DiskManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply executes the ordered changes via the session.

func (*DiskManager) DependsOn

func (*DiskManager) DependsOn() []string

DependsOn implements Manager.

func (*DiskManager) Name

func (*DiskManager) Name() string

Name implements Manager.

func (*DiskManager) Plan

func (m *DiskManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager. Accepts a *config.DiskLayout via desired.

func (*DiskManager) PlanLayout

func (m *DiskManager) PlanLayout(ctx context.Context, layout *config.DiskLayout) ([]Change, error)

PlanLayout plans changes for a typed DiskLayout. This is the ergonomic entrypoint used by the CLI and the orchestrator.

func (*DiskManager) Rollback

func (m *DiskManager) Rollback(ctx context.Context, changes []Change) error

Rollback reverses in-session changes in reverse order.

func (*DiskManager) Verify

func (m *DiskManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify re-plans and reports any remaining drift.

func (*DiskManager) WithReformatFilesystems

func (m *DiskManager) WithReformatFilesystems(b bool) *DiskManager

WithReformatFilesystems returns a copy of m with ReformatFilesystems overridden. Used by `linuxctl --reformat-filesystems …` callers (linuxctl#52).

func (*DiskManager) WithSession

func (m *DiskManager) WithSession(sess session.Session) *DiskManager

WithSession returns a copy of m bound to sess.

type FirewallBackend

type FirewallBackend string

FirewallBackend identifies which host firewall implementation is in use.

const (
	FirewallBackendFirewalld FirewallBackend = "firewalld"
	FirewallBackendUFW       FirewallBackend = "ufw"
	FirewallBackendNftables  FirewallBackend = "nftables"
	FirewallBackendUnknown   FirewallBackend = "unknown"
)

type FirewallManager

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

FirewallManager reconciles a config.Firewall spec across firewalld (EL/Fedora), ufw (Debian/Ubuntu), and nftables (fallback). Distro detection is based on /etc/os-release. Operations are idempotent: Plan diffs desired vs live and emits minimal Changes; Apply applies them under sudo.

Safety: FirewallManager never removes zones; it only adds/removes ports and sources within a zone, and toggles the master service. Rollback reverses port/source changes applied in-session.

func NewFirewallManager

func NewFirewallManager() *FirewallManager

NewFirewallManager returns a firewall manager without a session.

func (*FirewallManager) Apply

func (m *FirewallManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*FirewallManager) DependsOn

func (*FirewallManager) DependsOn() []string

DependsOn implements Manager — firewall layers on top of networking + packages.

func (*FirewallManager) Name

func (*FirewallManager) Name() string

Name implements Manager.

func (*FirewallManager) Plan

func (m *FirewallManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*FirewallManager) Rollback

func (m *FirewallManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager.

func (*FirewallManager) Verify

func (m *FirewallManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*FirewallManager) WithBackend

func (m *FirewallManager) WithBackend(b FirewallBackend) *FirewallManager

WithBackend forces a specific backend (test-only).

func (*FirewallManager) WithSession

func (m *FirewallManager) WithSession(sess session.Session) *FirewallManager

WithSession returns a copy bound to sess.

type GroupSpec

type GroupSpec struct {
	Name string `yaml:"name"`
	GID  int    `yaml:"gid,omitempty"`
}

GroupSpec is a single group entry.

type HazardLevel

type HazardLevel string

HazardLevel classifies the blast radius of a proposed change.

const (
	HazardNone        HazardLevel = "none"
	HazardWarn        HazardLevel = "warn"
	HazardDestructive HazardLevel = "destructive"
)

type HostsManager

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

HostsManager reconciles a config.HostEntry list with the managed block in /etc/hosts.

Safety: the manager only rewrites content between the BEGIN/END markers. Operator-managed entries outside the sandwich are preserved verbatim. A warning is surfaced (via Change.Hazard=warn) when a desired hostname would collide with a non-managed entry, but the apply still proceeds — the managed block is authoritative because the resolver reads /etc/hosts top-to-bottom.

func NewHostsManager

func NewHostsManager() *HostsManager

NewHostsManager returns a hosts manager without a session.

func (*HostsManager) Apply

func (m *HostsManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*HostsManager) DependsOn

func (*HostsManager) DependsOn() []string

DependsOn implements Manager.

func (*HostsManager) Name

func (*HostsManager) Name() string

Name implements Manager.

func (*HostsManager) Plan

func (m *HostsManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*HostsManager) Rollback

func (m *HostsManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Restores the Before block content for each recorded update.

func (*HostsManager) Verify

func (m *HostsManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*HostsManager) WithSession

func (m *HostsManager) WithSession(sess session.Session) *HostsManager

WithSession returns a copy bound to sess.

type LimitsManager

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

LimitsManager reconciles /etc/security/limits.d/99-linuxctl.conf.

func NewLimitsManager

func NewLimitsManager() *LimitsManager

NewLimitsManager returns a limits manager without a session.

func (*LimitsManager) Apply

func (m *LimitsManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*LimitsManager) DependsOn

func (*LimitsManager) DependsOn() []string

DependsOn implements Manager.

func (*LimitsManager) Name

func (*LimitsManager) Name() string

Name implements Manager.

func (*LimitsManager) Plan

func (m *LimitsManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*LimitsManager) Rollback

func (m *LimitsManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Restores the previous file body captured in Before, or removes the drop-in if no previous content existed.

func (*LimitsManager) Verify

func (m *LimitsManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*LimitsManager) WithSession

func (m *LimitsManager) WithSession(sess session.Session) *LimitsManager

WithSession returns a copy bound to sess.

type Manager

type Manager interface {
	Name() string
	DependsOn() []string

	Plan(ctx context.Context, desired Spec, current State) ([]Change, error)
	Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
	Verify(ctx context.Context, desired Spec) (VerifyResult, error)
	Rollback(ctx context.Context, changes []Change) error
}

Manager is the contract every subsystem (disk, user, package, …) must satisfy.

func Lookup

func Lookup(name string) Manager

Lookup returns the registered manager for name, or nil.

type MountManager

type MountManager struct {
	Session session.Session
	// Vault optionally resolves CIFS credentials from a Vault path declared
	// via `credentials_vault:` in the Mount manifest. The expected schema
	// at the resolved path is `{"username": "<u>", "password": "<p>"}`.
	// If nil, manifests with credentials_vault and no inline username/password
	// produce an apply-time error pointing the operator at this gap.
	Vault config.VaultReader
}

MountManager handles CIFS / NFS / bind mounts. For CIFS, credentials are written to /etc/cifs-utils/credentials/<tag> with mode 0600.

func NewMountManager

func NewMountManager() *MountManager

NewMountManager returns a mount manager.

func (*MountManager) Apply

func (m *MountManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply executes planned mount changes.

func (*MountManager) DependsOn

func (*MountManager) DependsOn() []string

DependsOn implements Manager.

func (*MountManager) Name

func (*MountManager) Name() string

Name implements Manager.

func (*MountManager) Plan

func (m *MountManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager. desired is a []config.Mount.

func (*MountManager) PlanMounts

func (m *MountManager) PlanMounts(ctx context.Context, mounts []config.Mount) ([]Change, error)

PlanMounts is the typed planning entrypoint.

func (*MountManager) Rollback

func (m *MountManager) Rollback(ctx context.Context, changes []Change) error

Rollback reverses in-session changes.

func (*MountManager) Verify

func (m *MountManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify replans and reports drift.

func (*MountManager) WithSession

func (m *MountManager) WithSession(sess session.Session) *MountManager

WithSession returns a copy bound to sess.

type NetworkBackend

type NetworkBackend string

NetworkBackend identifies the live network stack.

const (
	NetworkBackendNetworkManager NetworkBackend = "NetworkManager"
	NetworkBackendSystemd        NetworkBackend = "systemd-networkd"
	NetworkBackendUnknown        NetworkBackend = "unknown"
)

type NetworkManager

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

NetworkManager reconciles basic network settings (hostname + DNS). It is deliberately narrow for Phase 4 — see TODO above.

func NewNetworkManager

func NewNetworkManager() *NetworkManager

NewNetworkManager returns a network manager without a session.

func (*NetworkManager) Apply

func (m *NetworkManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*NetworkManager) DependsOn

func (*NetworkManager) DependsOn() []string

DependsOn implements Manager.

func (*NetworkManager) Name

func (*NetworkManager) Name() string

Name implements Manager.

func (*NetworkManager) Plan

func (m *NetworkManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager. Emits an "update" change for hostname drift and a second for /etc/resolv.conf drift.

func (*NetworkManager) Rollback

func (m *NetworkManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Restores the Before hostname / resolv.conf.

func (*NetworkManager) Verify

func (m *NetworkManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*NetworkManager) WithBackend

func (m *NetworkManager) WithBackend(b NetworkBackend) *NetworkManager

WithBackend forces a specific backend (test-only).

func (*NetworkManager) WithSession

func (m *NetworkManager) WithSession(sess session.Session) *NetworkManager

WithSession returns a copy bound to sess.

type NetworkSpec

type NetworkSpec struct {
	Hostname   string   // desired hostname (ex. metadata.name)
	DNSServers []string // /etc/resolv.conf nameserver entries
	Search     []string // /etc/resolv.conf search domains
}

NetworkSpec is the Phase 4 minimal network desired state.

For Phase 4 we only reconcile hostname + /etc/resolv.conf. Full NIC management (nmcli connection add/modify, VIP, SCAN interfaces for RAC) will land in Phase 4b / Phase 5.

TODO(Phase 4b): full nmcli/networkd NIC management — bond, vlan, team, static IPv4/IPv6, routes, SCAN VIPs for Oracle RAC.

type NodeSSHResult

type NodeSSHResult struct {
	Hostname       string
	GeneratedKeys  map[string]string // user → key fingerprint (may be empty on existing keys)
	AuthorizedKeys map[string]int    // user → count of keys installed
	KnownHosts     int               // count of scanned known_hosts entries
}

NodeSSHResult is a per-host summary. All maps are keyed by service-account username (e.g. "grid", "oracle").

type PackageManager

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

PackageManager is distro-aware and batches installs/removes for speed.

func NewPackageManager

func NewPackageManager() *PackageManager

NewPackageManager returns a package manager with no session attached.

func (*PackageManager) Apply

func (m *PackageManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager. Batches all install/remove ops into one command per direction for efficiency; per-package Change entries are still kept in ApplyResult so callers get fine-grained visibility.

func (*PackageManager) DependsOn

func (*PackageManager) DependsOn() []string

DependsOn implements Manager.

func (*PackageManager) Name

func (*PackageManager) Name() string

Name implements Manager.

func (*PackageManager) Plan

func (m *PackageManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*PackageManager) Rollback

func (m *PackageManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Reverses create→remove and delete→install. Best-effort: a removed package may no longer exist in the repo.

func (*PackageManager) Verify

func (m *PackageManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*PackageManager) WithSession

func (m *PackageManager) WithSession(s SessionRunner) *PackageManager

WithSession attaches a SessionRunner and returns the receiver for chaining.

type PackagesSpec

type PackagesSpec struct {
	Install []string `yaml:"install,omitempty"`
	Remove  []string `yaml:"remove,omitempty"`
}

PackagesSpec is the desired state for the package manager. Install and Remove are opaque package names (distro-specific). Services are owned by ServiceManager and intentionally not represented here.

type SELinuxManager

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

SELinuxManager handles the "selinux" subsystem: enforcing mode + boolean overrides. Persistent mode is written to /etc/selinux/config; runtime mode is toggled via setenforce. Booleans are persisted with `setsebool -P`.

func NewSELinuxManager

func NewSELinuxManager() *SELinuxManager

NewSELinuxManager returns a selinux manager.

func (*SELinuxManager) Apply

func (m *SELinuxManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*SELinuxManager) DependsOn

func (*SELinuxManager) DependsOn() []string

DependsOn implements Manager. selinux-policy-* is installed by the package manager; the service manager owns auditd which integrates with SELinux.

func (*SELinuxManager) Name

func (*SELinuxManager) Name() string

Name implements Manager.

func (*SELinuxManager) Plan

func (m *SELinuxManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*SELinuxManager) Rollback

func (m *SELinuxManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Restores Before state by re-issuing the same Apply path against a reversed change. Mode transitions involving "disabled" still require a reboot.

func (*SELinuxManager) Verify

func (m *SELinuxManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*SELinuxManager) WithSession

func (m *SELinuxManager) WithSession(s SessionRunner) *SELinuxManager

WithSession attaches a SessionRunner for Apply / Verify.

type SSHAuthManager

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

SSHAuthManager handles the "ssh" subsystem:

  • authorized_keys for users NOT owned by the user manager (e.g. pre-existing system accounts that still need key drift control)
  • sshd_config directives via a managed drop-in file

func NewSSHAuthManager

func NewSSHAuthManager() *SSHAuthManager

NewSSHAuthManager returns an ssh manager. Passing no session is valid for tests that only exercise Plan against a pre-populated mock.

func (*SSHAuthManager) Apply

func (m *SSHAuthManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*SSHAuthManager) DependsOn

func (*SSHAuthManager) DependsOn() []string

DependsOn implements Manager. Keys are written into home dirs which are owned by the user manager; sshd_config is inert until the service manager reloads sshd.

func (*SSHAuthManager) Name

func (*SSHAuthManager) Name() string

Name implements Manager.

func (*SSHAuthManager) Plan

func (m *SSHAuthManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*SSHAuthManager) Rollback

func (m *SSHAuthManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager.

func (*SSHAuthManager) Verify

func (m *SSHAuthManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*SSHAuthManager) WithSession

func (m *SSHAuthManager) WithSession(s SessionRunner) *SSHAuthManager

WithSession attaches a SessionRunner for Apply / Verify.

type ServiceManager

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

ServiceManager reconciles desired systemd unit state (enabled/active) against the live system via `systemctl`.

Safety: Plan never proposes masking or removing units. Rollback best-effort reverses the enable/active flip captured in Change.Before.

func NewServiceManager

func NewServiceManager() *ServiceManager

NewServiceManager returns a service manager without a session.

func (*ServiceManager) Apply

func (m *ServiceManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*ServiceManager) DependsOn

func (*ServiceManager) DependsOn() []string

DependsOn implements Manager. Services depend on packages being installed and on ssh hardening (which may restart sshd).

func (*ServiceManager) Name

func (*ServiceManager) Name() string

Name implements Manager.

func (*ServiceManager) Plan

func (m *ServiceManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*ServiceManager) Rollback

func (m *ServiceManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Reverses each enable/disable + start/stop by applying the inverse captured in Before.

func (*ServiceManager) Verify

func (m *ServiceManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*ServiceManager) WithSession

func (m *ServiceManager) WithSession(sess sudoRunner) *ServiceManager

WithSession returns a copy bound to sess.

type SessionRunner

type SessionRunner interface {
	Run(ctx context.Context, cmd string) (stdout, stderr string, err error)
}

SessionRunner is the minimal command-execution contract that the User and Package managers need. It is intentionally narrower than pkg/session.Session so tests can mock it easily and so the managers do not block on Agent A's final session contract.

type Spec

type Spec any

Spec is a manager-specific YAML-decoded desired-state struct.

type State

type State any

State is a manager-specific snapshot of observed runtime state.

type SysctlManager

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

SysctlManager reconciles kernel parameters using a single managed drop-in.

func NewSysctlManager

func NewSysctlManager() *SysctlManager

NewSysctlManager returns a sysctl manager without a session.

func (*SysctlManager) Apply

func (m *SysctlManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*SysctlManager) DependsOn

func (*SysctlManager) DependsOn() []string

DependsOn implements Manager.

func (*SysctlManager) Name

func (*SysctlManager) Name() string

Name implements Manager.

func (*SysctlManager) Plan

func (m *SysctlManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*SysctlManager) Rollback

func (m *SysctlManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Restores the previous file body captured in Before and re-runs `sysctl -p`.

func (*SysctlManager) Verify

func (m *SysctlManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*SysctlManager) WithSession

func (m *SysctlManager) WithSession(sess session.Session) *SysctlManager

WithSession returns a copy bound to sess.

type UserManager

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

UserManager handles groupadd/useradd/usermod/authorized_keys idempotently.

func NewUserManager

func NewUserManager() *UserManager

NewUserManager returns a user manager bound to sess. Passing nil is valid for tests that only exercise Plan against a pre-populated current state.

func (*UserManager) Apply

func (m *UserManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)

Apply implements Manager.

func (*UserManager) DependsOn

func (*UserManager) DependsOn() []string

DependsOn implements Manager. Users may reference packages (e.g. shell), so we order after the package manager.

func (*UserManager) Name

func (*UserManager) Name() string

Name implements Manager.

func (*UserManager) Plan

func (m *UserManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)

Plan implements Manager.

func (*UserManager) Rollback

func (m *UserManager) Rollback(ctx context.Context, changes []Change) error

Rollback implements Manager. Best-effort: we only reverse creates safely; update rollbacks require Before state and are applied with the same Apply path on a reversed change set.

func (*UserManager) Verify

func (m *UserManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)

Verify implements Manager.

func (*UserManager) WithSession

func (m *UserManager) WithSession(s SessionRunner) *UserManager

WithSession attaches a SessionRunner and returns the receiver for chaining.

type UserSpec

type UserSpec struct {
	Name     string   `yaml:"name"`
	UID      int      `yaml:"uid,omitempty"`
	GID      string   `yaml:"gid,omitempty"` // primary group name
	Groups   []string `yaml:"groups,omitempty"`
	Home     string   `yaml:"home,omitempty"`
	Shell    string   `yaml:"shell,omitempty"`
	SSHKeys  []string `yaml:"ssh_keys,omitempty"`
	Password string   `yaml:"password,omitempty"` // hash, or ${vault:...}
	Sudo     string   `yaml:"sudo,omitempty"`     // "" | "NOPASSWD" | "PASSWD"
}

UserSpec is a single user entry in the users_groups manifest. Kept here (not in pkg/config) until Agent A promotes the concrete schema. The fields line up with the contract given for pkg/config.User.

type UsersGroupsSpec

type UsersGroupsSpec struct {
	Groups []GroupSpec `yaml:"groups,omitempty"`
	Users  []UserSpec  `yaml:"users,omitempty"`
}

UsersGroupsSpec is the desired state for the user manager.

type VerifyResult

type VerifyResult struct {
	OK       bool
	Drift    []Change
	Messages []string
}

VerifyResult is returned from Manager.Verify.

Jump to

Keyboard shortcuts

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