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
- Variables
- func All() map[string]Manager
- func Register(m Manager)
- func RunAndCheck(ctx context.Context, sess session.Session, cmd string) (string, error)
- func RunSudoAndCheck(ctx context.Context, sess session.Session, cmd string) (string, error)
- type ApplyResult
- type Change
- type ChangeErr
- type ChangeSet
- type ClusterSSHResult
- type DirManager
- func (m *DirManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*DirManager) DependsOn() []string
- func (*DirManager) Name() string
- func (m *DirManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *DirManager) Rollback(ctx context.Context, changes []Change) error
- func (m *DirManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *DirManager) WithSession(sess session.Session) *DirManager
- type DiskManager
- func (m *DiskManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*DiskManager) DependsOn() []string
- func (*DiskManager) Name() string
- func (m *DiskManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *DiskManager) PlanLayout(ctx context.Context, layout *config.DiskLayout) ([]Change, error)
- func (m *DiskManager) Rollback(ctx context.Context, changes []Change) error
- func (m *DiskManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *DiskManager) WithReformatFilesystems(b bool) *DiskManager
- func (m *DiskManager) WithSession(sess session.Session) *DiskManager
- type FirewallBackend
- type FirewallManager
- func (m *FirewallManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*FirewallManager) DependsOn() []string
- func (*FirewallManager) Name() string
- func (m *FirewallManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *FirewallManager) Rollback(ctx context.Context, changes []Change) error
- func (m *FirewallManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *FirewallManager) WithBackend(b FirewallBackend) *FirewallManager
- func (m *FirewallManager) WithSession(sess session.Session) *FirewallManager
- type GroupSpec
- type HazardLevel
- type HostsManager
- func (m *HostsManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*HostsManager) DependsOn() []string
- func (*HostsManager) Name() string
- func (m *HostsManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *HostsManager) Rollback(ctx context.Context, changes []Change) error
- func (m *HostsManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *HostsManager) WithSession(sess session.Session) *HostsManager
- type LimitsManager
- func (m *LimitsManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*LimitsManager) DependsOn() []string
- func (*LimitsManager) Name() string
- func (m *LimitsManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *LimitsManager) Rollback(ctx context.Context, changes []Change) error
- func (m *LimitsManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *LimitsManager) WithSession(sess session.Session) *LimitsManager
- type Manager
- type MountManager
- func (m *MountManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*MountManager) DependsOn() []string
- func (*MountManager) Name() string
- func (m *MountManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *MountManager) PlanMounts(ctx context.Context, mounts []config.Mount) ([]Change, error)
- func (m *MountManager) Rollback(ctx context.Context, changes []Change) error
- func (m *MountManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *MountManager) WithSession(sess session.Session) *MountManager
- type NetworkBackend
- type NetworkManager
- func (m *NetworkManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*NetworkManager) DependsOn() []string
- func (*NetworkManager) Name() string
- func (m *NetworkManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *NetworkManager) Rollback(ctx context.Context, changes []Change) error
- func (m *NetworkManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *NetworkManager) WithBackend(b NetworkBackend) *NetworkManager
- func (m *NetworkManager) WithSession(sess session.Session) *NetworkManager
- type NetworkSpec
- type NodeSSHResult
- type PackageManager
- func (m *PackageManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*PackageManager) DependsOn() []string
- func (*PackageManager) Name() string
- func (m *PackageManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *PackageManager) Rollback(ctx context.Context, changes []Change) error
- func (m *PackageManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *PackageManager) WithSession(s SessionRunner) *PackageManager
- type PackagesSpec
- type SELinuxManager
- func (m *SELinuxManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*SELinuxManager) DependsOn() []string
- func (*SELinuxManager) Name() string
- func (m *SELinuxManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *SELinuxManager) Rollback(ctx context.Context, changes []Change) error
- func (m *SELinuxManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *SELinuxManager) WithSession(s SessionRunner) *SELinuxManager
- type SSHAuthManager
- func (m *SSHAuthManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*SSHAuthManager) DependsOn() []string
- func (*SSHAuthManager) Name() string
- func (m *SSHAuthManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *SSHAuthManager) Rollback(ctx context.Context, changes []Change) error
- func (m *SSHAuthManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *SSHAuthManager) WithSession(s SessionRunner) *SSHAuthManager
- type ServiceManager
- func (m *ServiceManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*ServiceManager) DependsOn() []string
- func (*ServiceManager) Name() string
- func (m *ServiceManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *ServiceManager) Rollback(ctx context.Context, changes []Change) error
- func (m *ServiceManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *ServiceManager) WithSession(sess sudoRunner) *ServiceManager
- type SessionRunner
- type Spec
- type State
- type SysctlManager
- func (m *SysctlManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*SysctlManager) DependsOn() []string
- func (*SysctlManager) Name() string
- func (m *SysctlManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *SysctlManager) Rollback(ctx context.Context, changes []Change) error
- func (m *SysctlManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *SysctlManager) WithSession(sess session.Session) *SysctlManager
- type UserManager
- func (m *UserManager) Apply(ctx context.Context, changes []Change, dryRun bool) (ApplyResult, error)
- func (*UserManager) DependsOn() []string
- func (*UserManager) Name() string
- func (m *UserManager) Plan(ctx context.Context, desired Spec, _ State) ([]Change, error)
- func (m *UserManager) Rollback(ctx context.Context, changes []Change) error
- func (m *UserManager) Verify(ctx context.Context, desired Spec) (VerifyResult, error)
- func (m *UserManager) WithSession(s SessionRunner) *UserManager
- type UserSpec
- type UsersGroupsSpec
- type VerifyResult
Constants ¶
const LimitsManagedPath = "/etc/security/limits.d/99-linuxctl.conf"
LimitsManagedPath is the single drop-in file limits manager owns.
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 ¶
var ErrNotImplemented = errors.New("not implemented")
ErrNotImplemented is returned by scaffold manager methods.
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 Register ¶
func Register(m Manager)
Register adds m to the global registry. Safe for init-time use.
func RunAndCheck ¶
RunAndCheck runs cmd through sess and returns stdout. Non-zero exits are wrapped with the captured stderr preview for context.
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 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) 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) 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) 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 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) 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) 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.
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) PlanMounts ¶
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) Plan ¶
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) 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) 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) 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) 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 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) 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) 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 ¶
VerifyResult is returned from Manager.Verify.