std

package
v0.0.0-...-f1406b7 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: BSD-3-Clause Imports: 35 Imported by: 11

Documentation

Overview

Package std contains tensile.Node primitives to most common operations.

Index

Constants

View Source
const DefaultDirMode = 0o755 | os.ModeDir

DefaultDirMode is the mode applied to directories when none is set.

View Source
const DefaultServiceTimeout = 30 * time.Second

DefaultServiceTimeout bounds waiting for a service manager to report the desired service state when no timeout is set.

Variables

View Source
var WellKnownShellArgs = map[string][]string{
	"dash":       {"-c"},
	"sh":         {"-c"},
	"bash":       {"-c"},
	"zsh":        {"-c"},
	"python":     {"-c"},
	"python3":    {"-c"},
	"ruby":       {"-e"},
	"perl":       {"-e"},
	"pwsh":       {"-NoProfile", "-Command"},
	"powershell": {"-NoProfile", "-Command"},
	"cmd":        {"/C"},
}

WellKnownShellArgs maps shells to arguments so that Command.Command can be executed by the shell. It is used to fill Command.Args if it is empty based on Command.Shell.

Functions

func DescribeFileMode

func DescribeFileMode(mode os.FileMode) string

DescribeFileMode returns an approximate description the os.FileMode. e.g. "Directory" if it contains os.ModeDir.

func DirIdentity

func DirIdentity(path string) tensile.Identity

DirIdentity returns the identity of the node managing the directory at path.

func DownloadIdentity

func DownloadIdentity(downloadURL string, path string) tensile.Identity

DownloadIdentity returns the identity of the node downloading from downloadURL to path.

func DownloadQueueIdentity

func DownloadQueueIdentity(path string) tensile.Identity

DownloadQueueIdentity returns the identity of the named queue for a Download node.

func FactsIdentity

func FactsIdentity() tensile.Identity

FactsIdentity returns the identity of the facts node.

func FileIdentity

func FileIdentity(path string) tensile.Identity

FileIdentity returns the identity of the node managing the file at path.

func FileQueueIdentity

func FileQueueIdentity(path string) tensile.Identity

FileQueueIdentity returns the identity of the queue managing the file at path.

func FileSerializeKey

func FileSerializeKey(path string) string

FileSerializeKey returns the tensile.Serializer key of nodes modifying the content of the file at path.

func GroupIdentity

func GroupIdentity(name string) tensile.Identity

GroupIdentity returns the identity of the node managing the named group.

func GroupMembershipIdentity

func GroupMembershipIdentity(user, group string) tensile.Identity

GroupMembershipIdentity returns the identity of the supplementary membership of user in group.

func INIFieldIdentity

func INIFieldIdentity(path, section, key string) tensile.Identity

INIFieldIdentity returns the identity of the node managing key in section of the INI file at path.

func NoopIdentity

func NoopIdentity(name string) tensile.Identity

NoopIdentity returns the identity of the named noop node.

func PackageIdentity

func PackageIdentity(name string) tensile.Identity

PackageIdentity returns the identity of the node managing the named package.

func PackageManagerUpdateIdentity

func PackageManagerUpdateIdentity() tensile.Identity

PackageManagerUpdateIdentity returns the identity of the node updating package lists.

func ParentDirIdentities

func ParentDirIdentities(p string) []tensile.Identity

ParentDirIdentities returns Dir identities for all parents of p.

func PruneUnmanagedFilesIdentity

func PruneUnmanagedFilesIdentity(dir string) tensile.Identity

PruneUnmanagedFilesIdentity returns the identity of the node pruning unmanaged files in dir.

func PruneUnmanagedGroupMembershipsIdentity

func PruneUnmanagedGroupMembershipsIdentity(group string) tensile.Identity

PruneUnmanagedGroupMembershipsIdentity returns the identity of the node pruning unmanaged memberships of group. Empty group covers all groups.

func PruneUnmanagedGroupsIdentity

func PruneUnmanagedGroupsIdentity() tensile.Identity

PruneUnmanagedGroupsIdentity returns the identity of the node pruning unmanaged groups.

func PruneUnmanagedUsersIdentity

func PruneUnmanagedUsersIdentity() tensile.Identity

PruneUnmanagedUsersIdentity returns the identity of the node pruning unmanaged users.

func RegisterPackageManager

func RegisterPackageManager(name string, manager PackageManager)

RegisterPackageManager registers a package manager. Panics when name is already registered.

func RegisterServiceManager

func RegisterServiceManager(name string, manager ServiceManager)

RegisterServiceManager registers a service manager. Panics when name is already registered.

func ServiceIdentity

func ServiceIdentity(name string) tensile.Identity

ServiceIdentity returns the identity of the node managing the named service.

func ServiceRestartIdentity

func ServiceRestartIdentity(name string) tensile.Identity

ServiceRestartIdentity returns the identity of the node restarting the named service.

func UserIdentity

func UserIdentity(name string) tensile.Identity

UserIdentity returns the identity of the node managing the named user.

Types

type Apk

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

Apk manages packages through apk.

func (*Apk) Handles

func (a *Apk) Handles(ctx context.Context, name string) (bool, error)

Handles implements PackageManager.

func (*Apk) Install

func (a *Apk) Install(ctx context.Context, name string) error

Install implements PackageManager.

func (*Apk) Installed

func (a *Apk) Installed(ctx context.Context, name string) (bool, error)

Installed implements PackageManager.

func (*Apk) Remove

func (a *Apk) Remove(ctx context.Context, name string) error

Remove implements PackageManager.

func (*Apk) Update

func (a *Apk) Update(ctx context.Context) error

Update implements PackageManager.

type Chmod

type Chmod struct {
	Path     string
	FileMode os.FileMode
}

Chmod ensures a file has the specified permissions. FileMode is interpreted as unix permission bits.

Not implemented on windows.

func (Chmod) DependsOn

func (c Chmod) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (Chmod) Execute

func (c Chmod) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (Chmod) Identity

func (c Chmod) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (Chmod) NeedsExecution

func (c Chmod) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

type Chown

type Chown struct {
	Path  string
	Owner string
	Group string
}

Chown ensures a file has the specified owner and group.

func (Chown) DependsOn

func (c Chown) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (Chown) Execute

func (c Chown) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (Chown) Identity

func (c Chown) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (Chown) NeedsExecution

func (c Chown) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

type Command

type Command struct {
	// Shell is the interpreter binary, e.g. "bash", "pwsh", "python".
	// Defaults to "sh", regardless of OS.
	//
	// This is intentional - defining the shell to depend on the OS is
	// error prone as POSIXly correct shells have vastly different
	// syntax than powershell. So in an environment with both Windows
	// and Unixoid machines would have to define both Shell and Command
	// depending on the OS anyway, unless e.g. sh/bash is also available
	// on Windows, in which case the Shell would have to be set for all
	// hosts anyway.
	// So to summarize - setting the shell per OS is nonsense and only
	// makes sense for homogeneous environments where you might as well
	// set the shell static if it diverges from the default.
	Shell string
	// Args are passed between interpreter and command.
	// Defaults are looked up by interpreter name.
	// Unknown interpreters require Args.
	Args []string
	// Command is passed as the final argument to the interpreter.
	Command string
	// Env is appended to the process environment as KEY=VALUE.
	Env map[string]string
	// Dir is the working directory. Empty means inherited.
	Dir string

	// Creates skips execution when the path exists.
	Creates string
	// Removes skips execution when the path is missing.
	Removes string

	// Unless skips execution when the command exits 0.
	// Executed with the same Shell, Args, Env and Dir as Command.
	Unless string
	// OnlyIf skips execution unless the command exits 0.
	// Executed with the same Shell, Args, Env and Dir as Command.
	OnlyIf string
	// contains filtered or unexported fields
}

Command runs a command line through an interpreter.

func (*Command) Execute

func (c *Command) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Command) Identity

func (c *Command) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Command) NeedsExecution

func (c *Command) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*Command) Report

func (c *Command) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

func (*Command) Validate

func (c *Command) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type CommandOutput

type CommandOutput struct {
	// Output is the combined stdout and stderr of the executed
	// command, empty when the command was not executed.
	Output string
}

CommandOutput is the output reported by Command.

type Dir

type Dir struct {
	Chmod
	Chown

	Path string
}

Dir ensures a directory exists with specified ownership and permissions.

func (*Dir) Conflicts

func (d *Dir) Conflicts() ([]tensile.Identity, error)

Conflicts implements tensile.Conflictor.

func (*Dir) DependsOn

func (d *Dir) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*Dir) Execute

func (d *Dir) Execute(s tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Dir) Identity

func (d *Dir) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Dir) NeedsExecution

func (d *Dir) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*Dir) Validate

func (d *Dir) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type Download

type Download struct {
	Chown
	Chmod

	// State is the desired existence.
	// Defaults to [tensile.Present].
	State tensile.State

	// URL is the remote file location.
	// Required.
	URL string
	// Output is the local destination.
	// May be a file path or a directory (ending in /).
	// Required.
	Output string

	// Checksum is the expected hash of the file.
	// Mutually exclusive with ChecksumURL.
	Checksum string
	// ChecksumURL is a URL to a hashsum file containing the expected hash.
	// Mutually exclusive with Checksum.
	ChecksumURL string
}

Download ensures a remote file is downloaded and optionally verified.

func (*Download) Conflicts

func (d *Download) Conflicts() ([]tensile.Identity, error)

Conflicts implements tensile.Conflictor.

func (*Download) DependsOn

func (d *Download) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*Download) Execute

func (d *Download) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Download) Identity

func (d *Download) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Download) NeedsExecution

func (d *Download) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*Download) Queue

func (d *Download) Queue() *queue.NamedQueue

Queue implements queue.NamedQueuer.

func (*Download) Validate

func (d *Download) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type Facts

type Facts struct{}

Facts gathers system facts and reports them as FactsData. It changes nothing and reports on every run, including noop runs.

func (*Facts) Execute

func (f *Facts) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Facts) Identity

func (f *Facts) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Facts) NeedsExecution

func (f *Facts) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor. Facts never execute, gathering happens in Report.

func (*Facts) Report

func (f *Facts) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

type FactsData

type FactsData struct {
	// OS is the operating system, e.g. "linux", "darwin".
	OS string
	// Architecture is the CPU architecture, e.g. "amd64", "arm64".
	Architecture string
	Hostname     string
	// OSRelease is parsed from /etc/os-release, zero when unavailable.
	OSRelease OSRelease
	// UserID is the uid of the running process.
	UserID int
}

FactsData is the output reported by Facts.

type File

type File struct {
	Path string
	// State is the desired existence.
	// Defaults to [tensile.Present].
	// [tensile.Absent] ignores all fields but Path.
	// [tensile.ReadOnly] is not supported.
	State tensile.State

	// Content is the managed file content.
	// Empty means only existence is ensured, existing content is left alone.
	Content string

	// FileMode, Owner and Group are applied by the queue returned by [NewFile], not by the node itself.
	FileMode os.FileMode
	Owner    string
	Group    string
}

File ensures a file is present or absent.

func (*File) DependsOn

func (f *File) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*File) Execute

func (f *File) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*File) Identity

func (f *File) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*File) NeedsExecution

func (f *File) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*File) Queue

func (f *File) Queue() *queue.NamedQueue

Queue implements queue.NamedQueuer. The queue contains the File itself and, when the fields are set, Chmod, Chown and FileContent nodes.

func (*File) Validate

func (f *File) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type FileContent

type FileContent struct {
	Path    string
	Content string
}

FileContent ensures an existing file has the specified content. The file is not created if it does not exit.

func (*FileContent) DependsOn

func (f *FileContent) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*FileContent) Execute

func (f *FileContent) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*FileContent) Identity

func (f *FileContent) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*FileContent) NeedsExecution

func (f *FileContent) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*FileContent) Report

func (f *FileContent) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

type FileContentOutput

type FileContentOutput struct {
	Path string
	// SHA256 is the hex-encoded checksum of the content.
	SHA256 string
}

FileContentOutput is the output reported by FileContent.

type Group

type Group struct {
	Name string
	// GID nil is unmanaged, allocated on creation.
	GID *int
	// State defaults to [tensile.Present].
	State tensile.State
	// contains filtered or unexported fields
}

Group ensures a local group is present or absent.

func (*Group) Conflicts

func (g *Group) Conflicts() ([]tensile.Identity, error)

Conflicts implements tensile.Conflictor.

func (*Group) Execute

func (g *Group) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Group) Identity

func (g *Group) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Group) NeedsExecution

func (g *Group) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*Group) Report

func (g *Group) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

func (*Group) SerializesOn

func (g *Group) SerializesOn() []string

SerializesOn implements tensile.Serializer.

func (*Group) Validate

func (g *Group) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type GroupData

type GroupData struct {
	shadow.Group

	Present bool
}

GroupData is the output reported by Group.

type GroupMembership

type GroupMembership struct {
	User  string
	Group string
	// State defaults to [tensile.Present].
	// [tensile.ReadOnly] is not supported.
	State tensile.State
	// contains filtered or unexported fields
}

GroupMembership ensures a user is or is not a supplementary member of a group.

func (*GroupMembership) DependsOn

func (m *GroupMembership) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*GroupMembership) Execute

func (m *GroupMembership) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*GroupMembership) Identity

func (m *GroupMembership) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*GroupMembership) NeedsExecution

func (m *GroupMembership) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*GroupMembership) SerializesOn

func (m *GroupMembership) SerializesOn() []string

SerializesOn implements tensile.Serializer.

func (*GroupMembership) Validate

func (m *GroupMembership) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type INIField

type INIField[T INIValue] struct {
	// State is the desired state.
	// Defaults to [tensile.Present].
	State tensile.State

	Path string
	// Section is the INI section, empty for the default section.
	Section string
	Key     string
	Value   T

	// LoadOptions configures parsing, empty uses the ini defaults.
	LoadOptions ini.LoadOptions
}

INIField ensures a key in an INI file is present or absent. A missing file is created on tensile.Present.

func (*INIField[T]) DependsOn

func (i *INIField[T]) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*INIField[T]) Execute

func (i *INIField[T]) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*INIField[T]) Identity

func (i *INIField[T]) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*INIField[T]) NeedsExecution

func (i *INIField[T]) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*INIField[T]) Report

func (i *INIField[T]) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

func (*INIField[T]) SerializesOn

func (i *INIField[T]) SerializesOn() []string

SerializesOn implements tensile.Serializer.

func (*INIField[T]) Validate

func (i *INIField[T]) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type INIFieldOutput

type INIFieldOutput struct {
	Path    string
	Section string
	Key     string
	Present bool
	// Value is the current value, empty when absent.
	Value string
}

INIFieldOutput is the output reported by INIField.

type INIValue

type INIValue interface {
	string | int | float64 | bool
}

INIValue are the value types storable in an INI key. INI stores only strings. int is rendered as '<int>'. float64 as '<float64>'. bool as 'true' or 'false'.

type JSONField

type JSONField struct {
	// State is the desired state.
	// Defaults to [tensile.Present].
	State tensile.State

	Path  string
	Key   string
	Value any
}

JSONField ensures a field in a JSON file is present or absent. The top level of the file must be a JSON object. Key is a dot-separated path into nested objects. A missing file is created on tensile.Present.

func (*JSONField) DependsOn

func (j *JSONField) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*JSONField) Execute

func (j *JSONField) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*JSONField) Identity

func (j *JSONField) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*JSONField) NeedsExecution

func (j *JSONField) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*JSONField) Report

func (j *JSONField) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

func (*JSONField) Validate

func (j *JSONField) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type JSONFieldOutput

type JSONFieldOutput struct {
	Path    string
	Key     string
	Present bool
	// Value is the current value, nil when absent.
	Value any
}

JSONFieldOutput is the output reported by JSONField.

type LineInFile

type LineInFile struct {
	Path string
	// Regexp locates the line to replace.
	// If multiple lines match the regex the last match is considered.
	// Empty matches Line verbatim.
	Regexp string
	Line   string
}

LineInFile ensures a file contains Line. The last line matching Regexp is replaced with Line, otherwise Line is appended. A missing file is created.

func (*LineInFile) DependsOn

func (l *LineInFile) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*LineInFile) Execute

func (l *LineInFile) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*LineInFile) Identity

func (l *LineInFile) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*LineInFile) NeedsExecution

func (l *LineInFile) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*LineInFile) Validate

func (l *LineInFile) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type Noop

type Noop struct {
	Name string
}

Noop does nothing.

When Noop is added as a notifier it always notifies.

func (*Noop) Execute

func (n *Noop) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Noop) Identity

func (n *Noop) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Noop) NeedsExecution

func (n *Noop) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor. A Noop always executes so notifications propagate.

type OSRelease

type OSRelease struct {
	// Name is NAME, e.g. "Arch Linux".
	Name string
	// PrettyName is PRETTY_NAME, e.g. "Arch Linux".
	PrettyName string
	// ID is ID, e.g. "arch".
	ID string
	// IDLike is the space separated ID_LIKE, e.g. ["rhel", "fedora"].
	IDLike []string
	// Version is VERSION, e.g. "9.4 (Blue Onyx)".
	Version string
	// VersionID is VERSION_ID, e.g. "9.4".
	VersionID string
	// BuildID is BUILD_ID, e.g. "rolling".
	BuildID string
}

OSRelease holds the identifying fields of os-release(5).

type Opkg

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

Opkg manages packages through opkg.

func (*Opkg) Handles

func (o *Opkg) Handles(ctx context.Context, name string) (bool, error)

Handles implements PackageManager. A package is handled when it is known to the package lists or installed locally.

func (*Opkg) Install

func (o *Opkg) Install(ctx context.Context, name string) error

Install implements PackageManager.

func (*Opkg) Installed

func (o *Opkg) Installed(ctx context.Context, name string) (bool, error)

Installed implements PackageManager.

func (*Opkg) Remove

func (o *Opkg) Remove(ctx context.Context, name string) error

Remove implements PackageManager.

func (*Opkg) Update

func (o *Opkg) Update(ctx context.Context) error

Update implements PackageManager.

type Package

type Package struct {
	Name string
	// State is the desired presence.
	// Empty means [tensile.Present].
	// [tensile.ReadOnly] is not supported.
	State tensile.State
	// Manager selects a registered [PackageManager] by name.
	// Empty means detection.
	Manager string
}

Package ensures a package is present or absent.

Package deliberately does not manage package versions. Version constraints should be handled either in the package manger configuration or in the repository the packages are sourced from (e.g. a Spacewalk, SUSE Manager, ...) should produce a prefiltered stream. Similarly updates should be installed through a controlled process, not in a provisioning tool.

func (*Package) DependsOn

func (p *Package) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender. Package lists are updated first when a PackageManagerUpdate node is enqueued.

func (*Package) Execute

func (p *Package) Execute(c tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Package) Identity

func (p *Package) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Package) NeedsExecution

func (p *Package) NeedsExecution(c tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor. If no registered PackageManager handles the package the package is considered not installed.

func (*Package) SerializesOn

func (p *Package) SerializesOn() []string

SerializesOn implements tensile.Serializer. If a manager is set explicitly the serialization key is per manager. If it is empty the key is shared for all package manager.

func (*Package) Validate

func (p *Package) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type PackageManager

type PackageManager interface {
	// Handles reports whether this manager handles the package.
	Handles(ctx context.Context, name string) (bool, error)
	// Update refreshes the package lists.
	// It does not upgrade packages.
	// A no-op when the manager is not available or has no way of updating package lists.
	Update(ctx context.Context) error
	// Installed returns whether the package is installed.
	Installed(ctx context.Context, name string) (bool, error)
	// Install installs the package.
	Install(ctx context.Context, name string) error
	// Remove removes the package.
	Remove(ctx context.Context, name string) error
}

PackageManager queries and changes installed packages.

func DetectPackageManager

func DetectPackageManager(ctx context.Context, name string) (PackageManager, error)

DetectPackageManager returns the last registered package manager that handles the named package.

func PackageManagerByName

func PackageManagerByName(name string) (PackageManager, error)

PackageManagerByName returns the package manager registered under name.

type PackageManagerUpdate

type PackageManagerUpdate struct{}

PackageManagerUpdate refreshes the package lists of all registered package managers. It does not upgrade packages.

func (*PackageManagerUpdate) Execute

Execute implements tensile.Executor.

func (*PackageManagerUpdate) Identity

func (p *PackageManagerUpdate) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*PackageManagerUpdate) NeedsExecution

func (p *PackageManagerUpdate) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor. List staleness is not observable, so it always executes.

type Pacman

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

Pacman manages packages through pacman.

func (*Pacman) Handles

func (p *Pacman) Handles(ctx context.Context, name string) (bool, error)

Handles implements PackageManager. A package is handled when it is known to the database or installed locally.

func (*Pacman) Install

func (p *Pacman) Install(ctx context.Context, name string) error

Install implements PackageManager.

func (*Pacman) Installed

func (p *Pacman) Installed(ctx context.Context, name string) (bool, error)

Installed implements PackageManager.

func (*Pacman) Remove

func (p *Pacman) Remove(ctx context.Context, name string) error

Remove implements PackageManager.

func (*Pacman) Update

func (p *Pacman) Update(ctx context.Context) error

Update implements PackageManager.

type Print

type Print struct {
	Message string
	Args    []any
}

Print prints a message when executed.

func (*Print) Execute

func (p *Print) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Print) Identity

func (p *Print) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Print) NeedsExecution

func (p *Print) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution returns true, indicating the node should always execute.

type Procd

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

Procd manages services through /etc/init.d scripts on OpenWrt.

func (*Procd) Apply

func (p *Procd) Apply(ctx context.Context, name string, desired ServiceStatus) error

Apply implements ServiceManager.

func (*Procd) Handles

func (p *Procd) Handles(_ context.Context, name string) (bool, error)

Handles implements ServiceManager.

func (*Procd) Restart

func (p *Procd) Restart(ctx context.Context, name string) error

Restart implements ServiceManager.

func (*Procd) Status

func (p *Procd) Status(ctx context.Context, name string) (ServiceStatus, error)

Status implements ServiceManager.

type PruneUnmanagedFiles

type PruneUnmanagedFiles struct {
	Dir string
}

PruneUnmanagedFiles removes direct entries of Dir whose FileIdentity is not claimed by any node. Entries are removed recursively, an unmanaged directory is removed with its contents.

func (*PruneUnmanagedFiles) DependsOn

func (p *PruneUnmanagedFiles) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*PruneUnmanagedFiles) Execute

func (p *PruneUnmanagedFiles) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*PruneUnmanagedFiles) Identity

func (p *PruneUnmanagedFiles) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*PruneUnmanagedFiles) NeedsExecution

func (p *PruneUnmanagedFiles) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*PruneUnmanagedFiles) Validate

func (p *PruneUnmanagedFiles) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type PruneUnmanagedGroupMemberships

type PruneUnmanagedGroupMemberships struct {
	// Group limits pruning to the named group.
	// Empty prunes all groups.
	Group string
	// IncludeSystem also prunes members of groups with a system GID.
	// If the group is a system group (e.g. wheel) this must be true.
	IncludeSystem bool
	// IDMin nil defaults to [shadow.DefaultIDMin].
	IDMin *int
	// IDMax nil defaults to [shadow.DefaultIDMax].
	IDMax *int
	// contains filtered or unexported fields
}

PruneUnmanagedGroupMemberships removes supplementary members whose GroupMembershipIdentity is not claimed by any node. Primary group membership is not affected.

func (*PruneUnmanagedGroupMemberships) DependsOn

DependsOn implements tensile.Depender.

func (*PruneUnmanagedGroupMemberships) Execute

Execute implements tensile.Executor.

func (*PruneUnmanagedGroupMemberships) Identity

Identity implements tensile.Identifier.

func (*PruneUnmanagedGroupMemberships) NeedsExecution

func (p *PruneUnmanagedGroupMemberships) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*PruneUnmanagedGroupMemberships) SerializesOn

func (p *PruneUnmanagedGroupMemberships) SerializesOn() []string

SerializesOn implements tensile.Serializer.

func (*PruneUnmanagedGroupMemberships) Validate

Validate implements tensile.Validator.

type PruneUnmanagedGroups

type PruneUnmanagedGroups struct {
	// IncludeSystem also prunes groups with a system GID.
	IncludeSystem bool
	// IDMin nil defaults to [shadow.DefaultIDMin].
	IDMin *int
	// IDMax nil defaults to [shadow.DefaultIDMax].
	IDMax *int
	// contains filtered or unexported fields
}

PruneUnmanagedGroups deletes groups whose GroupIdentity is not claimed by any node. Gid 0 and primary groups of existing users are never deleted.

func (*PruneUnmanagedGroups) DependsOn

func (p *PruneUnmanagedGroups) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender. Pruned users release their primary groups first.

func (*PruneUnmanagedGroups) Execute

func (p *PruneUnmanagedGroups) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*PruneUnmanagedGroups) Identity

func (p *PruneUnmanagedGroups) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*PruneUnmanagedGroups) NeedsExecution

func (p *PruneUnmanagedGroups) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*PruneUnmanagedGroups) SerializesOn

func (p *PruneUnmanagedGroups) SerializesOn() []string

SerializesOn implements tensile.Serializer.

func (*PruneUnmanagedGroups) Validate

func (p *PruneUnmanagedGroups) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type PruneUnmanagedUsers

type PruneUnmanagedUsers struct {
	// IncludeSystem also prunes users with a system UID.
	IncludeSystem bool
	// IDMin nil defaults to [shadow.DefaultIDMin].
	IDMin *int
	// IDMax nil defaults to [shadow.DefaultIDMax].
	IDMax *int
	// contains filtered or unexported fields
}

PruneUnmanagedUsers deletes users whose UserIdentity is not claimed by any node, including their home directory as far as the tools do. Root (uid 0) is never deleted.

func (*PruneUnmanagedUsers) Execute

func (p *PruneUnmanagedUsers) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*PruneUnmanagedUsers) Identity

func (p *PruneUnmanagedUsers) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*PruneUnmanagedUsers) NeedsExecution

func (p *PruneUnmanagedUsers) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*PruneUnmanagedUsers) SerializesOn

func (p *PruneUnmanagedUsers) SerializesOn() []string

SerializesOn implements tensile.Serializer.

func (*PruneUnmanagedUsers) Validate

func (p *PruneUnmanagedUsers) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type Service

type Service struct {
	Name    string
	Enabled *bool
	Running *bool
	// Manager selects a registered [ServiceManager] by name.
	// Empty means detection.
	Manager string
	// Timeout in seconds to wait for the [ServiceManager] to report the
	// desired running state after applying it.
	// Defaults to [DefaultServiceTimeout].
	Timeout time.Duration
}

Service ensures a service is in the desired state. Nil means the state is unmanaged.

func (*Service) Execute

func (s *Service) Execute(c tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Service) Identity

func (s *Service) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Service) NeedsExecution

func (s *Service) NeedsExecution(c tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*Service) Validate

func (s *Service) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type ServiceManager

type ServiceManager interface {
	// Handles reports whether this manager handles the service.
	Handles(ctx context.Context, name string) (bool, error)
	// Status returns the current state of the service.
	Status(ctx context.Context, name string) (ServiceStatus, error)
	// Apply transitions the service to the desired state.
	Apply(ctx context.Context, name string, desired ServiceStatus) error
	// Restart restarts the service.
	Restart(ctx context.Context, name string) error
}

ServiceManager queries and changes service state.

func DetectServiceManager

func DetectServiceManager(ctx context.Context, name string) (ServiceManager, error)

DetectServiceManager returns the last registered service manager that handles the named service.

func ServiceManagerByName

func ServiceManagerByName(name string) (ServiceManager, error)

ServiceManagerByName returns the service manager registered under name.

type ServiceRestart

type ServiceRestart struct {
	Name string
	// Manager selects a registered [ServiceManager] by name.
	// Empty means detection.
	Manager string
	// Timeout in seconds to wait for the [ServiceManager] to report the
	// desired running state after applying it.
	// Defaults to [DefaultServiceTimeout].
	Timeout time.Duration
}

ServiceRestart restarts a service.

This node should only be used as a tensile.Handler to trigger a service restart after a configuration for this service was changed and the service does not reload dynamically.

If enqueued as a node it _will_ restart the service on every run.

func (*ServiceRestart) Execute

func (s *ServiceRestart) Execute(c tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*ServiceRestart) Identity

func (s *ServiceRestart) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*ServiceRestart) NeedsExecution

func (s *ServiceRestart) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*ServiceRestart) Validate

func (s *ServiceRestart) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type ServiceStatus

type ServiceStatus struct {
	Enabled bool
	Active  bool
}

ServiceStatus is the observable state of a service.

type Symlink struct {
	Path   string
	Target string
}

Symlink ensures a symbolic link at Path points to Target.

func (*Symlink) Conflicts

func (s *Symlink) Conflicts() ([]tensile.Identity, error)

Conflicts implements tensile.Conflictor.

func (*Symlink) DependsOn

func (s *Symlink) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*Symlink) Execute

func (s *Symlink) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*Symlink) Identity

func (s *Symlink) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*Symlink) NeedsExecution

func (s *Symlink) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

type Systemd

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

Systemd manages services through systemctl.

func (*Systemd) Apply

func (systemd *Systemd) Apply(ctx context.Context, name string, desired ServiceStatus) error

Apply implements ServiceManager.

func (*Systemd) Handles

func (systemd *Systemd) Handles(ctx context.Context, name string) (bool, error)

Handles implements ServiceManager.

func (*Systemd) Restart

func (systemd *Systemd) Restart(ctx context.Context, name string) error

Restart implements ServiceManager.

func (*Systemd) Status

func (systemd *Systemd) Status(ctx context.Context, name string) (ServiceStatus, error)

Status implements ServiceManager.

type User

type User struct {
	Name string
	// UID nil is unmanaged, allocated on creation.
	UID *int
	// Group is the primary group.
	// Empty applies the tool default on creation and is unmanaged afterwards.
	Group string
	// Groups are the supplementary groups.
	// Nil is unmanaged.
	// Memberships claimed by other nodes, e.g. [GroupMembership], are kept.
	Groups []string
	// Home empty applies the tool default on creation and is unmanaged afterwards.
	Home string
	// Shell empty applies the tool default on creation and is unmanaged afterwards.
	Shell string
	// State defaults to [tensile.Present].
	State tensile.State
	// contains filtered or unexported fields
}

User ensures a local user is present or absent. Absent also removes the home directory as far as the tools do.

func (*User) Conflicts

func (u *User) Conflicts() ([]tensile.Identity, error)

Conflicts implements tensile.Conflictor.

func (*User) DependsOn

func (u *User) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*User) Execute

func (u *User) Execute(wire tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*User) Identity

func (u *User) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*User) NeedsExecution

func (u *User) NeedsExecution(wire tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*User) Report

func (u *User) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

func (*User) RequiredBy

func (u *User) RequiredBy() ([]tensile.Identity, error)

RequiredBy implements tensile.Requisite. Nodes managing the home run after the user exists.

func (*User) SerializesOn

func (u *User) SerializesOn() []string

SerializesOn implements tensile.Serializer.

func (*User) Validate

func (u *User) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type UserData

type UserData struct {
	shadow.User

	Present bool
}

UserData is the output reported by User.

type YAMLField

type YAMLField struct {
	// State is the desired state.
	// Defaults to [tensile.Present].
	State tensile.State

	Path  string
	Key   string
	Value any
}

YAMLField ensures a field in a YAML file is present or absent. The top level of the file must be a YAML mapping. Key is a dot-separated path into nested mappings. A missing file is created on tensile.Present.

func (*YAMLField) DependsOn

func (y *YAMLField) DependsOn() ([]tensile.Identity, error)

DependsOn implements tensile.Depender.

func (*YAMLField) Execute

func (y *YAMLField) Execute(_ tensile.Wire) (tensile.Diff, error)

Execute implements tensile.Executor.

func (*YAMLField) Identity

func (y *YAMLField) Identity() tensile.Identity

Identity implements tensile.Identifier.

func (*YAMLField) NeedsExecution

func (y *YAMLField) NeedsExecution(_ tensile.Wire) (bool, tensile.Diff, error)

NeedsExecution implements tensile.Executor.

func (*YAMLField) Report

func (y *YAMLField) Report(_ tensile.Wire) (any, error)

Report implements tensile.Reporter.

func (*YAMLField) Validate

func (y *YAMLField) Validate(_ tensile.Wire) error

Validate implements tensile.Validator.

type YAMLFieldOutput

type YAMLFieldOutput struct {
	Path    string
	Key     string
	Present bool
	// Value is the current value, nil when absent.
	Value any
}

YAMLFieldOutput is the output reported by YAMLField.

Jump to

Keyboard shortcuts

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