Skip to content

Commit

Permalink
service: Document
Browse files Browse the repository at this point in the history
  • Loading branch information
livingsilver94 committed Nov 4, 2023
1 parent 1580c4a commit de8d830
Showing 1 changed file with 70 additions and 12 deletions.
82 changes: 70 additions & 12 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,54 @@ const (
)

var (
// DefaultPkgManager is the default package manager command to install OS packages.
DefaultPkgManager = []string{"pkcon", "install", "-y"}
)

// Service is a collection of resources to reinstall/restore on an operating system.
// All fields except Name are optional.
type Service struct {
Name string `yaml:"-"`
Depends *DepSet `yaml:"depends"`
Setup *string `yaml:"setup"`
PkgManager []string `yaml:"pkgmanager"`
Packages []string `yaml:"packages"`
Links map[string]FilePath `yaml:"links"`
Variables map[string]VarValue `yaml:"variables"`
Copies map[string]FilePath `yaml:"copies"`
Finalize *string `yaml:"finalize"`
// Name uniquely identifies a Service.
Name string `yaml:"-"`

// Depends is a set of Service names upon which this Service depends.
Depends *DepSet `yaml:"depends"`

// Setup is a script (UNIX Shell or Powershell, depending on the operating system)
// to run before reinstalling and/or restoring any resources.
Setup *string `yaml:"setup"`

// PkgManager is combination of command name
// and arguments to reinstall operating system packages.
// It must accept a list of package names appended to it.
PkgManager []string `yaml:"pkgmanager"`

// Packages is a list of operating system packages to reinstall.
// It will be appended as-is to PkgManager.
Packages []string `yaml:"packages"`

// Links is a collection of symlinks to restore. Their source path
// is relative to Service's linkdir.
Links map[string]FilePath `yaml:"links"`

// Variables is a collection of local variables associated to this Service.
// A template engine may use them to edit files in place before copying them,
// or to customize Setup and Finalize scripts.
// Variables will always contain at least VarDatadir of Datadir kind.
Variables map[string]VarValue `yaml:"variables"`

// Copies is a collection of files to copy. Their source path
// is relative to Service's datadir. A template engine may use Variables
// to customize the content.
Copies map[string]FilePath `yaml:"copies"`

// Setup is a script (UNIX Shell or Powershell, depending on the operating system)
// to run after reinstalling and/or restoring any resources.
Finalize *string `yaml:"finalize"`
}

// New creates a Service with a given name. Variables will contain VarDatadir
// and PkgManager will be DefaultPkgManager.
func New(name string) *Service {
return &Service{
Name: name,
Expand All @@ -50,11 +83,15 @@ func New(name string) *Service {
}
}

// NewFromYAML creates a Service with a given name whose fields are defined by
// a buffered YAML document.
func NewFromYAML(name string, yml []byte) (*Service, error) {
srv := New(name)
return srv, yaml.Unmarshal(yml, srv)
}

// NewFromYAML creates a Service with a given name whose fields are defined by
// a streaming YAML document.
func NewFromYAMLReader(name string, rd io.Reader) (*Service, error) {
srv := New(name)
err := yaml.NewDecoder(rd).Decode(srv)
Expand All @@ -64,26 +101,33 @@ func NewFromYAMLReader(name string, rd io.Reader) (*Service, error) {
return srv, err
}

// Hash returns a string that uniquely identifies this Service.
// It currently returns Name.
func (srv *Service) Hash() string {
return srv.Name
}

// DepSet is an unordered set of Service names.
type DepSet struct {
*set.Set[string]
}

// NewDepSet crates an empty DepSet with an initial capacity.
func NewDepSet(capacity int) DepSet {
return DepSet{set.New[string](capacity)}
}

// NewDepSetFrom creates a DepSet from a list of Service names.
func NewDepSetFrom(items []string) DepSet {
return DepSet{set.From(items)}
}

// Equal returns true if ds is equal to ds2.
func (ds DepSet) Equal(ds2 DepSet) bool {
return ds.Set.Equal(ds2.Set)
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (ds *DepSet) UnmarshalYAML(node *yaml.Node) error {
var deps []string
err := node.Decode(&deps)
Expand All @@ -94,11 +138,14 @@ func (ds *DepSet) UnmarshalYAML(node *yaml.Node) error {
return nil
}

// FilePath is a filesystem file path with its file mode.
type FilePath struct {
Path string `yaml:"path"`
Mode uint16 `yaml:"mode"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
// Mode defaults to 0644 if unspecified in the YAML node.
func (lp *FilePath) UnmarshalYAML(node *yaml.Node) error {
switch node.Kind {
case yaml.ScalarNode:
Expand All @@ -121,18 +168,29 @@ func (lp *FilePath) UnmarshalYAML(node *yaml.Node) error {
return nil
}

// VarKind is a kind of variable.
// Any non-ClearText kind will require a solver to extract the value.
type VarKind string

const (
// ClearText is the simplest VarKind. Any variable of type ClearText
// has its value immediately accessible.
ClearText VarKind = "cleartext"
Datadir VarKind = "datadir"

// Datadir is the path of a Service's data directory.
Datadir VarKind = "datadir"
)

// VarValue is a variable's value.
type VarValue struct {
Kind VarKind `yaml:"kind"`
Value string `yaml:"value"`
// Kind is the variable kind. Unless it's ClearText, a solver is required
// to get the real value.
Kind VarKind `yaml:"kind"`
// Value is either the final value, if Kind is ClearText, or an intermediate value.
Value string `yaml:"value"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (val *VarValue) UnmarshalYAML(node *yaml.Node) error {
switch node.Kind {
case yaml.ScalarNode:
Expand Down

0 comments on commit de8d830

Please sign in to comment.