conf

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2023 License: BSD-3-Clause Imports: 17 Imported by: 9

Documentation

Index

Constants

View Source
const (
	// SystemdLineMax mimics the maximum line length that systemd can use.
	// On typical systemd platforms (i.e. modern Linux), this will most
	// commonly be 2048, so let's use that as a sanity check.
	// Technically, we should probably pull this at runtime:
	//    SystemdLineMax = int(C.sysconf(C.__SC_LINE_MAX))
	// but this would introduce an (unfortunate) dependency on cgo
	SystemdLineMax = 2048

	// SystemdNewline defines characters that systemd considers indicators
	// for a newline.
	SystemdNewline = "\r\n"
)
View Source
const DropInExt = ".conf"

DropInExt is the file extension for drop-in files.

Variables

View Source
var (
	ErrOptionRequired          = errors.New("option is required")
	ErrOptionAllowedOnce       = errors.New("option is only allowed once")
	ErrOptionNotExists         = errors.New("option does not exist")
	ErrInvalidBoolean          = errors.New("invalid boolean value")
	ErrInvalidFloat            = errors.New("invalid floating point number)")
	ErrInvalidNumber           = errors.New("invalid number")
	ErrInvalidDuration         = errors.New("invalid duration")
	ErrNoSections              = errors.New("task does not contain any sections")
	ErrUnknownSection          = errors.New("unknown section")
	ErrDropInSectionNotExists  = errors.New("section defined in drop-in does not exist")
	ErrDropInSectionNotAllowed = errors.New("drop-ins not allowed for not-unique sections")
	ErrNoOptions               = errors.New("no options defined")
)

Commonly used validation and error messages.

View Source
var (
	// ErrOptionNotSet is returned when a given option is
	// not set.
	ErrOptionNotSet = errors.New("option not set")

	// ErrUnknownOptionType indicates that an option's type is
	// not known.
	ErrUnknownOptionType = errors.New("unknown option type")
)
View Source
var (
	StringType        = option("string    ", false)
	StringSliceType   = option("[]string  ", true)
	BoolType          = option("bool      ", false)
	IntType           = option("int       ", false)
	IntSliceType      = option("[]int     ", true)
	FloatType         = option("float     ", false)
	FloatSliceType    = option("[]float   ", true)
	DurationType      = option("duration", false)
	DurationSliceType = option("[]duration", true)
)

All supported option types.

View Source
var (
	// ErrLineTooLong gets returned when a line is too long for systemd to handle.
	ErrLineTooLong = fmt.Errorf("line too long (max %d bytes)", SystemdLineMax)
)

Functions

func ApplyDropIns

func ApplyDropIns(t *File, dropins []*DropIn, secReg SectionRegistry) error

ApplyDropIns applies all dropins on t. DropIns can only be applied to files with unique section names. That is, if a file specifies the same section multiple times (like multiple [Copy] sections), drop-ins cannot be applied to that file.

func ConvertBool

func ConvertBool(s string) (bool, error)

ConvertBool converts the string s into a boolean value if it matches one of the supported boolean identifiers.

func DecodeFile

func DecodeFile(file *File, target interface{}, spec SectionRegistry) error

Decode a file into target following the file specification.

func DecodeSections

func DecodeSections(sections []Section, registry OptionRegistry, receiver interface{}) error

DecodeSections decodes a slice of sections into receiver. Only options defined in registry are allowed and permitted.

func DecodeValues

func DecodeValues(data []string, specType OptionType, receiver interface{}) error

DecodeValues decodes data into receiver. If receiver is a pointer to a nil interface a new value of the correct type will be created and stored. If receiver already has a type that Decode tries to parse data into receiver. If specType does not match receiver an error is returned.

func DropInSearchPaths

func DropInSearchPaths(unitName string, rootDir string) []string

DropInSearchPaths returns the search paths that should be checked when searching for task specific drop-ins. Normally, drop-ins should be placed in <rootDir>/<unitName>.d/<file>.conf. If the task name contains dashes the name is split there and used as a search path as well. In other words, the search path for foo-bar.task will result in the following search path: <rootDir>/foo-.task.d/, <rootDir>/foo-bar.task.d/. If the unitName contains an extension (like .task), it is used for <rootDir>/task.d/ as well. The returned search path is already sorted by priority where the first search path has lowest and the last search path has highest priority.

func IsNotSet

func IsNotSet(err error) bool

IsNotSet returns true if err is ErrOptionNotSet

func IsSecret

func IsSecret(spec OptionSpec) bool

IsSecret returns true if spec is annotated as a secret.

func IsSymlink(file string) (bool, error)

IsSymlink returns true if file is a symlink.

func SearchDropinFiles

func SearchDropinFiles(unitName string, searchPath []string) ([]string, error)

SearchDropinFiles searches for drop-in files in a set of search directories. `searchPath` is ordered by priority with lowest-priority first. That means that a drop-in file found in a latter directory will overwrite any drop-in file with the same name of a previous directory. For example, if the searchPath would equal "/var/lib/system-deploy", "/etc/system-deploy" then a /etc/system-deploy/<unit>/10-overwrite.conf would overwrite /var/lib/system-deploy/<unit>/10-overwrite.conf.

func TemplateInstanceName

func TemplateInstanceName(path string) (string, bool)

TemplateInstanceName parses path and returns the template instance name if path represents a systemd template unit name. For my-webserver@config-1.service TemplateInstanceName returns "config-1", true.

func ValidateFile

func ValidateFile(file *File, specs SectionRegistry, opts ...ValidationConfig) error

ValidateFile validates all sections in file and applies any default option values. If specs is nil then ValidateFile is a no-op.

func ValidateOption

func ValidateOption(values []string, spec OptionSpec) error

ValidateOption validates if values matches spec.

func ValidateOptions

func ValidateOptions(options Options, specs OptionRegistry, opts ...ValidationConfig) error

ValidateOptions validates if all unit options specified in sec conform to the specification options.

func ValidateValue

func ValidateValue(val string, optType OptionType) error

ValidateValue ensures that val is a valid value for optType.

func WriteSectionsTo

func WriteSectionsTo(sections Sections, w io.Writer) error

WriteSectionsTo writes all sections to w .

Types

type Annotation

type Annotation map[string]interface{}

func (Annotation) Get

func (an Annotation) Get(key string) interface{}

Get returns the value of an annoation by key or nil.

func (Annotation) Has

func (an Annotation) Has(key string) bool

Has returns true if an annotation identified by key exists.

func (*Annotation) With

func (an *Annotation) With(kvs ...KeyValue) Annotation

With adds one or more annotation key-value pairs.

type DropIn

type DropIn File

DropIn is a drop-in file for a given system-deploy task.

func LoadDropIns

func LoadDropIns(unitName string, searchPath []string) ([]*DropIn, error)

LoadDropIns loads all drop-in files for unitName. See SearchDropInFiles and DropInSearchPaths for more information on the searchPath.

type File

type File struct {
	// Path holds the path to the unit file.
	Path string

	// Sections are all sections defined in the file.
	Sections
}

File is a configuration file.

func ConvertToFile

func ConvertToFile(x interface{}, path string) (*File, error)

ConvertToFile converts x to a File. x is expected to be or point to a struct type.

func Deserialize

func Deserialize(path string, f io.Reader) (*File, error)

Deserialize parses a systemd unit file into a list of UnitOption objects. The path parameter is only copied to the returned File struct and may be left empty.

func LoadFile

func LoadFile(path string) (*File, error)

LoadFile loads the unit file at path.

func ParseFromEnv

func ParseFromEnv(prefix string, env []string, reg SectionRegistry) (*File, error)

func ReadDir

func ReadDir(directory, suffix string, spec SectionRegistry) ([]*File, error)

ReadDir parses all files in directory that end in suffix. The sections of each file are validated against the spec map using the lowercase section name as the map key. If spec is nil no validation is performed.

func ReplaceSpecifiers

func ReplaceSpecifiers(f *File, sm Specifiers) (*File, error)

ReplaceSpecifiers replaces all specifiers in all section options of f. If an unknown identifier is encountered an error is returned. The original File f remains untouched.

func (*File) Clone

func (f *File) Clone() *File

Clone creates a deep copy of f.

type FileSpec

type FileSpec map[string]OptionRegistry

FileSpec describes all sections and the allowed options for each section. It implements the SectionRegistry interface.

func (FileSpec) OptionsForSection

func (spec FileSpec) OptionsForSection(name string) (OptionRegistry, bool)

OptionsForSection searches the FileSpec for the section spec with the given name. It implements the SectionRegistry.

func (FileSpec) Parse

func (spec FileSpec) Parse(path string, r io.Reader, target interface{}) error

Parse parses a configuration file from r, validates it against the spec and unmarshals it into target. Users that want to utilize drop-in files should take care of deserializing, validating, applying drop-ins and decoding into target themself.

func (FileSpec) ParseFile

func (spec FileSpec) ParseFile(path string, target interface{}) error

ParseFile is like Parse but opens the file at path.

type KeyValue

type KeyValue struct {
	Key   string
	Value interface{}
}

func SecretValue

func SecretValue() KeyValue

SecretValue returns an annotation KeyValue that marks an option as secret.

type Option

type Option struct {
	// Name is the name of the option.
	Name string

	// Value holds the raw string value of the option.
	Value string
}

Option is a key-value pair that is specified in a unit file section.

type OptionRegistry

type OptionRegistry interface {
	// hasOptoin returns true if the option with name is defined
	// in the option registry. optName is always lowercase.
	HasOption(optName string) bool

	// GetOption returns the definition of the option defined by optName.
	// optName is always lowercase.
	GetOption(optName string) (OptionSpec, bool)

	// All returns all options defined in the option registry (if supported).
	All() []OptionSpec
}

OptionRegistry is used to validate all options in a section. It's default implementation is SectionSpec.

type OptionSpec

type OptionSpec struct {
	// Name is the name of the option.
	Name string `json:"name"`

	// Aliases is a set of aliases supported by this
	// option spec. If set, there should be a "Interal"
	// option for each alias name. Otherwise system-deploy
	// will throw an error if an alias is used in the
	// configuration. Use with care!
	Aliases []string `json:"aliases,omitempty"`

	// Description is a human readable description of
	// the option.
	Description string `json:"description,omitempty"`

	// Type defines the type of the option.
	Type OptionType `json:"type,omitempty" option:"-"`

	// Required may be set to true if deploy tasks must
	// specify this option.
	Required bool `json:"required,omitempty"`

	// Default may hold the default value for this option.
	// This value is only for help purposes and is NOT SET
	// as the default for that option.
	Default string `json:"default,omitempty"`

	// Internal may be set to true to omit the option from
	// the help page.
	Internal bool `json:"internal,omitempty"`

	// Annotations can be used to add arbitrary metadata to
	// option definitions. For example, such annotations can
	// be later used in help or documentation generators.
	// Note that it is recommended to ensure annotation values
	// are JSON or Gob serializable.
	Annotations Annotation `json:"annotation,omitempty"`
}

OptionSpec describes an option

func (*OptionSpec) HasAnnotation

func (spec *OptionSpec) HasAnnotation(name string) bool

HasAnnotation returns true if spec has an annotation with the given name.

func (*OptionSpec) UnmarshalJSON

func (spec *OptionSpec) UnmarshalJSON(blob []byte) error

UnmarshalJSON unmarshals blob into spec.

func (*OptionSpec) UnmarshalSection

func (spec *OptionSpec) UnmarshalSection(sec Section, sectionSpec OptionRegistry) error

UnmarshalSection implements SectionUnmarshaller.

type OptionType

type OptionType interface {
	IsSliceType() bool

	fmt.Stringer
	json.Marshaler
	// contains filtered or unexported methods
}

OptionType describes the type of an option. It cannot be implemented outside the deploy package.

func TypeFromString

func TypeFromString(str string) *OptionType

TypeFromString returns the option type described by str.

type Options

type Options []Option

Options is a convenience type for working with a slice of deploy options.

func ApplyDefaults

func ApplyDefaults(options Options, specs OptionRegistry) Options

ApplyDefaults will add the default value for each option that is not specified but has an default set in it's spec.

func EncodeToOptions

func EncodeToOptions(name string, x interface{}) (Options, error)

EncodeToOptions encodes the value from x into one or more options with the given name.

func (Options) GetAs

func (opts Options) GetAs(name string, specType OptionType) interface{}

GetAs returns the value of name interpreted as specType. If no options with name exist nil is returned. GetAs panics if multiple options exist but specType is not a slice type.

func (Options) GetBool

func (opts Options) GetBool(name string) (bool, error)

GetBool returns the bool set for name or an error if it's not set.

func (Options) GetBoolDefault

func (opts Options) GetBoolDefault(name string, def bool) bool

GetBoolDefault returns the boolean value for name or a default if name is not set or cannot be parsed as a bool.

func (Options) GetFloat

func (opts Options) GetFloat(name string) (float64, error)

GetFloat returns the float set for name. If name is not set or cannot be parsed an error is returned.

func (Options) GetFloatDefault

func (opts Options) GetFloatDefault(name string, def float64) float64

GetFloatDefault is like GetFloat but returns a default value if name is not set or cannot be parsed.

func (Options) GetFloatSlice

func (opts Options) GetFloatSlice(name string) ([]float64, error)

GetFloatSlice returns a slice of float values set for name. If a value cannot be parsed an error is returned.

func (Options) GetInt

func (opts Options) GetInt(name string) (int64, error)

GetInt returns the integer value set for name. If name is not set or cannot be parsed an error is returned.

func (Options) GetIntDefault

func (opts Options) GetIntDefault(name string, def int64) int64

GetIntDefault is like GetInt but returns a default value if name is not set or cannot be parsed

func (Options) GetIntSlice

func (opts Options) GetIntSlice(name string) ([]int64, error)

GetIntSlice returns a slice of integer values set for name.

func (Options) GetRequiredFloatSlice

func (opts Options) GetRequiredFloatSlice(name string) ([]float64, error)

GetRequiredFloatSlice is like GetFloatSlice but returns an error if name is not specified at least once.

func (Options) GetRequiredIntSlice

func (opts Options) GetRequiredIntSlice(name string) ([]int64, error)

GetRequiredIntSlice is like GetIntSlice but returns an error if name is not set at least once.

func (Options) GetRequiredStringSlice

func (opts Options) GetRequiredStringSlice(name string) ([]string, error)

GetRequiredStringSlice is like GetStringSlice but returns an error if name is not specified at least once. GetRequiredStringSlice only ever returns ErrOptionNotSet, never some other error.

func (Options) GetString

func (opts Options) GetString(name string) (string, error)

GetString returns the value of the option name. It ensures that name is only set once. If name can be specified multiple time use GetStringSlice

func (Options) GetStringSlice

func (opts Options) GetStringSlice(name string) []string

GetStringSlice returns a slice of values specified for name. If name must be specified at least once, use GetRequiredStringSlice.

type Section

type Section struct {
	Name string

	Options
}

Section describes a single section in a unit file. It contains the section name and a slice of options defined below it.

func Prepare

func Prepare(sec Section, specs OptionRegistry, opts ...ValidationConfig) (Section, error)

Prepare prepares the sec by applying default values and validating options against a set of option specs.

type SectionDecoder

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

SectionDecoder supports decoding a single section matching the decoders option specifications.

func NewSectionDecoder

func NewSectionDecoder(specs []OptionSpec) *SectionDecoder

NewSectionDecoder returns a new decoder.

func (*SectionDecoder) AsMap

func (dec *SectionDecoder) AsMap(sec Section) map[string]interface{}

AsMap returns a map representation of the section.

func (*SectionDecoder) Get

func (dec *SectionDecoder) Get(sec Section, name string) interface{}

Get returns the value of the option name in sec. If name is not set or does not exist nil is returned.

type SectionRegistry

type SectionRegistry interface {
	// OptionsForSection returns the option registry that defines all options
	// allowed in the section name. It returns a boolean value to
	// indicate if a section with name was found. If false is returned
	// the section is treated as unknown and an error is returned.
	// The section name is always in lowercase.
	OptionsForSection(name string) (OptionRegistry, bool)
}

SectionRegistry is used to validate sections when parsing files. It's default implementation is FileSpec.

type SectionSpec

type SectionSpec []OptionSpec

SectionSpec describes all options that can be used in a given section.

func (SectionSpec) All

func (specs SectionSpec) All() []OptionSpec

All returns all options defined for the section.

func (SectionSpec) GetOption

func (specs SectionSpec) GetOption(optName string) (OptionSpec, bool)

GetOption searches for the OptionSpec with name optName.

func (SectionSpec) HasOption

func (specs SectionSpec) HasOption(optName string) bool

HasOption returns true if the section spec defines an option with name optName.

type SectionUnmarshaler

type SectionUnmarshaler interface {
	UnmarshalSection(sec Section, spec OptionRegistry) error
}

SectionUnmarshaler describes the interface that can be implemented to provide custom decoding of sections when using FileSpec.Decode. See OptionSpec for an example of how to use and implement UnmarshalSection.

type Sections

type Sections []Section

Sections is a convenience type for working with a slice of sections.

func (Sections) Get

func (ss Sections) Get(name string) *Section

Get returns the first section identified by name. Section names are compared using equal fold. If no section matches name nil is returned.

func (Sections) GetAll

func (ss Sections) GetAll(name string) []Section

GetAll returns all sections with name. Section names are compared using equal fold.

func (Sections) Has

func (ss Sections) Has(name string) bool

Has checks if a section with name is available. Section names are compared using equal fold.

type Specifiers

type Specifiers map[rune]string

Specifiers maps a alpha-numerical rune to a value.

func (Specifiers) Get

func (sm Specifiers) Get(val rune) (string, error)

Get returns the value fro val.

func (Specifiers) Replace

func (sm Specifiers) Replace(str string) (string, error)

Replace replaces all specifiers from sm in str and returns the result. If an specifier is unknown an error is returned.

type ValidationConfig

type ValidationConfig struct {
	IgnoreUnknownSections bool
	IgnoreUnknownOptions  bool
}

ValidationConfig can be passed to ValidateFile and ValidateOptions to allow for unknown sections or configuration options.

Jump to

Keyboard shortcuts

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