engine

package
v0.0.0-...-453cd44 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2024 License: GPL-3.0 Imports: 15 Imported by: 54

Documentation

Overview

Package engine represents the implementation of the resource engine that runs the graph of resources in real-time. This package has the common imports that most consumers use directly.

Index

Constants

View Source
const (
	// ErrClosed means we couldn't complete a task because we had closed.
	ErrClosed = Error("closed")

	// ErrBackPoke means we're postponing due to a needed backpoke.
	ErrBackPoke = Error("backpoke")
)

Variables

View Source
var DefaultMetaParams = &MetaParams{
	Noop:  false,
	Retry: 0,
	Delay: 0,
	Poll:  0,
	Limit: rate.Inf,
	Burst: 0,
	Reset: false,

	Rewatch: false,
	Realize: false,
}

DefaultMetaParams are the defaults that are used for undefined metaparams. Don't modify this variable. Use .Copy() if you'd like some for yourself.

Functions

func AdaptCmp

func AdaptCmp(r1, r2 CompatibleRes) error

AdaptCmp compares two resources by checking multiple aspects. This is the main entry point for running all the compatible compare steps on two resources. This code is very similar to ResCmp.

func EdgeCmpFn

func EdgeCmpFn(e1, e2 pgraph.Edge) (bool, error)

EdgeCmpFn returns if two edges are equivalent. It errors if they can't be compared because one is not an edge. This returns true if equal. TODO: shouldn't the first argument be an `error` instead?

func GenerateRecvFunc

func GenerateRecvFunc(res Res) func() map[string]*Send

GenerateRecvFunc generates the Recv function using the resource of our choice for use in the resource internal state handle.

func GenerateSendFunc

func GenerateSendFunc(res Res) func(interface{}) error

GenerateSendFunc generates the Send function using the resource of our choice for use in the resource internal state handle.

func RegisterResource

func RegisterResource(kind string, fn func() Res)

RegisterResource registers a new resource by providing a constructor function that returns a resource object ready to be unmarshalled from YAML.

func RegisteredResourcesNames

func RegisteredResourcesNames() []string

RegisteredResourcesNames returns the kind of the registered resources.

func Repr

func Repr(kind, name string) string

Repr returns a representation of a resource from its kind and name. This is used as the definitive format so that it can be changed in one place.

func ResCmp

func ResCmp(r1, r2 Res) error

ResCmp compares two resources by checking multiple aspects. This is the main entry point for running all the compare steps on two resources. This code is very similar to AdaptCmp.

func ResGraphMapper

func ResGraphMapper(oldGraph, newGraph *pgraph.Graph) (map[RecvableRes]RecvableRes, error)

ResGraphMapper compares two graphs, and gives us a mapping from new to old based on the resource kind and name only. This allows us to know which previous resource might have data to pass on to the new version in the next generation. FIXME: Optimize this for performance since it runs a lot...

func Stringer

func Stringer(res Res) string

Stringer returns a consistent and unique string representation of a resource.

func Validate

func Validate(res Res) error

Validate validates a resource by checking multiple aspects. This is the main entry point for running all the validation steps on a resource.

func VertexCmpFn

func VertexCmpFn(v1, v2 pgraph.Vertex) (bool, error)

VertexCmpFn returns if two vertices are equivalent. It errors if they can't be compared because one is not a vertex. This returns true if equal. TODO: shouldn't the first argument be an `error` instead?

Types

type AutoEdge

type AutoEdge interface {
	Next() []ResUID   // call to get list of edges to add
	Test([]bool) bool // call until false
}

The AutoEdge interface is used to implement the autoedges feature.

type AutoEdgeMeta

type AutoEdgeMeta struct {
	// Disabled specifies that automatic edges should be disabled for this
	// resource.
	Disabled bool
}

AutoEdgeMeta provides some parameters specific to automatic edges. TODO: currently this only supports disabling the feature per-resource, but in the future you could conceivably have some small pattern to control it better

func (*AutoEdgeMeta) Cmp

func (obj *AutoEdgeMeta) Cmp(aem *AutoEdgeMeta) error

Cmp compares two AutoEdgeMeta structs and determines if they're equivalent.

type AutoGroupMeta

type AutoGroupMeta struct {
	// Disabled specifies that automatic grouping should be disabled for
	// this resource.
	Disabled bool
}

AutoGroupMeta provides some parameters specific to automatic grouping. TODO: currently this only supports disabling the feature per-resource, but in the future you could conceivably have some small pattern to control it better

func (*AutoGroupMeta) Cmp

func (obj *AutoGroupMeta) Cmp(agm *AutoGroupMeta) error

Cmp compares two AutoGroupMeta structs and determines if they're equivalent.

type AutoGrouper

type AutoGrouper interface {
	// listed in the order these are typically called in...
	Name() string                                                    // friendly identifier
	Init(*pgraph.Graph) error                                        // only call once
	VertexNext() (pgraph.Vertex, pgraph.Vertex, error)               // mostly algorithmic
	VertexCmp(pgraph.Vertex, pgraph.Vertex) error                    // can we merge these ?
	VertexMerge(pgraph.Vertex, pgraph.Vertex) (pgraph.Vertex, error) // vertex merge fn to use
	EdgeMerge(pgraph.Edge, pgraph.Edge) pgraph.Edge                  // edge merge fn to use
	VertexTest(bool) (bool, error)                                   // call until false
}

AutoGrouper is the required interface to implement an autogrouping algorithm.

type BaseUID

type BaseUID struct {
	Name string // name and kind are the values of where this is coming from
	Kind string

	Reversed *bool // piggyback edge information here
}

The BaseUID struct is used to provide a unique resource identifier.

func (*BaseUID) GetKind

func (obj *BaseUID) GetKind() string

GetKind returns the kind of the resource UID.

func (*BaseUID) GetName

func (obj *BaseUID) GetName() string

GetName returns the name of the resource UID.

func (*BaseUID) IFF

func (obj *BaseUID) IFF(uid ResUID) bool

IFF looks at two UID's and if and only if they are equivalent, returns true. If they are not equivalent, it returns false. Most resources will want to override this method, since it does the important work of actually discerning if two resources are identical in function.

func (*BaseUID) IsReversed

func (obj *BaseUID) IsReversed() bool

IsReversed is part of the ResUID interface, and true means this resource happens before the generator.

func (*BaseUID) String

func (obj *BaseUID) String() string

String returns the canonical string representation for a resource UID.

type CollectableRes

type CollectableRes interface {
	Res

	CollectPattern(string) // XXX: temporary until Res collection is more advanced
}

CollectableRes is an interface for resources that support collection. It is currently temporary until a proper API for all resources is invented.

type CompatibleRes

type CompatibleRes interface {
	//Res // causes "duplicate method" error
	CopyableRes // we'll need to use the Copy method in the Merge function!

	// Adapts compares itself to another resource and returns an error if
	// they are not compatibly equivalent. This is less strict than the
	// default `Cmp` method which should be used for most cases. Don't call
	// this directly, use engine.AdaptCmp instead.
	Adapts(CompatibleRes) error

	// Merge returns the combined resource to use when two are equivalent.
	// This might get called multiple times for N different resources that
	// need to get merged, and so it should produce a consistent result no
	// matter which order it is called in. Don't call this directly, use
	// engine.ResMerge instead.
	Merge(CompatibleRes) (CompatibleRes, error)
}

CompatibleRes is an interface that a resource can implement to express if a similar variant of itself is functionally equivalent. For example, two `pkg` resources that install `cowsay` could be equivalent if one requests a state of `installed` and the other requests `newest`, since they'll finish with a compatible result. This doesn't need to be behind a metaparam flag or trait, because it is never beneficial to turn it off, unless there is a bug to fix.

func ResMerge

func ResMerge(r ...CompatibleRes) (CompatibleRes, error)

ResMerge merges a set of resources that are compatible with each other. This is the main entry point for the merging. They must each successfully be able to run AdaptCmp without error.

type CopyableRes

type CopyableRes interface {
	Res

	// Copy returns a new resource which has a copy of the public data.
	// Don't call this directly, use engine.ResCopy instead.
	// TODO: should we copy any private state or not?
	Copy() CopyableRes
}

CopyableRes is an interface that a resource can implement if we want to be able to copy the resource to build another one.

func ResCopy

func ResCopy(r CopyableRes) (CopyableRes, error)

ResCopy copies a resource. This is the main entry point for copying a resource since it does all the common engine-level copying as well.

type Edge

type Edge struct {
	Name   string
	Notify bool // should we send a refresh notification along this edge?
	// contains filtered or unexported fields
}

Edge is a struct that represents a graph's edge.

func (*Edge) Cmp

func (obj *Edge) Cmp(edge *Edge) error

Cmp compares this edge to another. It returns nil if they are equivalent.

func (*Edge) Refresh

func (obj *Edge) Refresh() bool

Refresh returns the pending refresh status of this edge.

func (*Edge) SetRefresh

func (obj *Edge) SetRefresh(b bool)

SetRefresh sets the pending refresh status of this edge.

func (*Edge) String

func (obj *Edge) String() string

String is a required method of the Edge interface that we must fulfill.

type EdgeableRes

type EdgeableRes interface {
	Res // implement everything in Res but add the additional requirements

	// AutoEdgeMeta lets you get or set meta params for the automatic edges
	// trait.
	AutoEdgeMeta() *AutoEdgeMeta

	// SetAutoEdgeMeta lets you set all of the meta params for the automatic
	// edges trait in a single call.
	SetAutoEdgeMeta(*AutoEdgeMeta)

	// UIDs includes all params to make a unique identification of this
	// object.
	UIDs() []ResUID // most resources only return one

	// AutoEdges returns a struct that implements the AutoEdge interface.
	// This interface can be used to generate automatic edges to other
	// resources.
	AutoEdges() (AutoEdge, error)
}

EdgeableRes is the interface a resource must implement to support automatic edges. Both the vertices involved in an edge need to implement this for it to be able to work.

type Error

type Error string

Error is a constant error type that implements error.

func (Error) Error

func (e Error) Error() string

Error fulfills the error interface of this type.

type Fs

type Fs interface {

	// URI returns a unique string handle to access this filesystem.
	URI() string // returns the URI for this file system

	afero.Fs // TODO: why doesn't this interface exist in the os pkg?

	// ReadFile reads the named file and returns its contents. A successful
	// call returns a nil error, not io.EOF. (Because ReadFile reads the
	// whole file, the expected EOF from the final Read is not treated as an
	// error to be reported.)
	//
	// The caller is permitted to modify the returned byte slice. This
	// method should return a copy of the underlying data.
	//
	// This mimics the signature from io/fs.ReadFileFS and has the same
	// docs.
	ReadFile(name string) ([]byte, error) // io/fs.ReadFileFS

	ReadDir(dirname string) ([]os.FileInfo, error)
}

Fs is an interface that represents the file system API that we support. TODO: rename this to FS for consistency with the io/fs.FS naming scheme

type GraphQueryableOption

type GraphQueryableOption func(*GraphQueryableOptions)

GraphQueryableOption is an option that can be used to specify the authentication.

func GraphQueryableOptionKind

func GraphQueryableOptionKind(kind string) GraphQueryableOption

GraphQueryableOptionKind tells the GraphQueryAllowed function what the resource kind is.

func GraphQueryableOptionName

func GraphQueryableOptionName(name string) GraphQueryableOption

GraphQueryableOptionName tells the GraphQueryAllowed function what the resource name is.

type GraphQueryableOptions

type GraphQueryableOptions struct {
	// Kind is the kind of the resource making the access.
	Kind string
	// Name is the name of the resource making the access.
	Name string
}

GraphQueryableOptions represents the different possible configurable options.

func (*GraphQueryableOptions) Apply

func (obj *GraphQueryableOptions) Apply(opts ...GraphQueryableOption)

Apply is a helper function to apply a list of options to the struct. You should initialize it with defaults you want, and then apply any you've received like this.

type GraphQueryableRes

type GraphQueryableRes interface {
	Res // implement everything in Res but add the additional requirements

	// GraphQueryAllowed returns nil if you're allowed to query the graph.
	GraphQueryAllowed(...GraphQueryableOption) error
}

GraphQueryableRes is the interface that must be implemented if you want your resource to be allowed to be queried from another resource in the graph. This is done as a form of explicit authorization tracking so that we can consider security aspects more easily. Ultimately, all resource code should be trusted, but it's still a good idea to know if a particular resource is even able to access information about another one, and if your resource doesn't add the trait supporting this, then it won't be allowed.

type GroupableRes

type GroupableRes interface {
	Res // implement everything in Res but add the additional requirements

	// AutoGroupMeta lets you get or set meta params for the automatic
	// grouping trait.
	AutoGroupMeta() *AutoGroupMeta

	// SetAutoGroupMeta lets you set all of the meta params for the
	// automatic grouping trait in a single call.
	SetAutoGroupMeta(*AutoGroupMeta)

	// GroupCmp compares two resources and decides if they're suitable for
	// grouping. This usually needs to be unique to your resource.
	GroupCmp(res GroupableRes) error

	// GroupRes groups resource argument (res) into self. Callers of this
	// method should probably also run SetParent.
	GroupRes(res GroupableRes) error

	// IsGrouped determines if we are grouped.
	IsGrouped() bool // am I grouped?

	// SetGrouped sets a flag to tell if we are grouped.
	SetGrouped(bool)

	// GetGroup returns everyone grouped inside me.
	GetGroup() []GroupableRes // return everyone grouped inside me

	// SetGroup sets the grouped resources into me. Callers of this method
	// should probably also run SetParent.
	SetGroup([]GroupableRes)

	// Parent returns the parent groupable resource that I am inside of.
	Parent() GroupableRes

	// SetParent tells a particular grouped resource who their parent is.
	SetParent(res GroupableRes)
}

GroupableRes is the interface a resource must implement to support automatic grouping. Default implementations for most of the methods declared in this interface can be obtained for your resource by anonymously adding the traits.Groupable struct to your resource implementation.

type Init

type Init struct {
	// Program is the name of the program.
	Program string

	// Version is the version of the program.
	Version string

	// Hostname is the uuid for the host.
	Hostname string

	// Running must be called after your watches are all started and ready.
	Running func()

	// Event sends an event notifying the engine of a possible state change.
	Event func()

	// Refresh returns whether the resource received a notification. This
	// flag can be used to tell a svc to reload, or to perform some state
	// change that wouldn't otherwise be noticed by inspection alone. You
	// must implement the Refreshable trait for this to work.
	Refresh func() bool

	// Send exposes some variables you wish to send via the Send/Recv
	// mechanism. You must implement the Sendable trait for this to work.
	Send func(interface{}) error

	// Recv provides a map of variables which were sent to this resource via
	// the Send/Recv mechanism. You must implement the Recvable trait for
	// this to work.
	Recv func() map[string]*Send

	// FilteredGraph is a function that returns a filtered variant of the
	// current graph. Only resource that have allowed themselves to be added
	// into this graph will appear. If they did not consent, then those
	// vertices and any associated edges, will not be present.
	FilteredGraph func() (*pgraph.Graph, error)

	// Local has a bunch of methods and properties which are useful for
	// operations on the local machine and for communication between
	// functions and resources.
	Local *local.API

	// World provides a connection to the outside world. This is most often
	// used for communicating with the distributed database.
	World World

	// VarDir is a facility for local storage. It is used to return a path
	// to a directory which may be used for temporary storage. It should be
	// cleaned up on resource Close if the resource would like to delete the
	// contents. The resource should not assume that the initial directory
	// is empty, and it should be cleaned on Init if that is a requirement.
	VarDir func(string) (string, error)

	// Debug signals whether we are running in debugging mode. In this case,
	// we might want to log additional messages.
	Debug bool

	// Logf is a logging facility which will correctly namespace any
	// messages which you wish to pass on. You should use this instead of
	// the log package directly for production quality resources.
	Logf func(format string, v ...interface{})
}

Init is the structure of values and references which is passed into all resources on initialization. None of these are available in Validate, or before Init runs.

type InterruptableRes

type InterruptableRes interface {
	Res

	// Ask the resource to shutdown quickly. This can be called at any point
	// in the resource lifecycle after Init. Close will still be called. It
	// will only get called after an exit or pause request has been made. It
	// is designed to unblock any long running operation that is occurring
	// in the CheckApply portion of the life cycle. If the resource has
	// already exited, running this method should not block. (That is to say
	// that you should not expect CheckApply or Watch to be alive and be
	// able to read from a channel to satisfy your request.) It is best to
	// probably have this close a channel to multicast that signal around to
	// anyone who can detect it in a select. If you are in a situation which
	// cannot interrupt, then you can return an error.
	// FIXME: implement, and check the above description is what we expect!
	Interrupt() error
}

InterruptableRes is an interface that adds interrupt functionality to resources. If the resource implements this interface, the engine will call the Interrupt method to shutdown the resource quickly. Running this method may leave the resource in a partial state, however this may be desired if you want a faster exit or if you'd prefer a partial state over letting the resource complete in a situation where you made an error and you wish to exit quickly to avoid data loss. It is usually triggered after multiple ^C signals.

type KindedRes

type KindedRes interface {
	// Kind returns a string representing the kind of resource this is.
	Kind() string

	// SetKind sets the resource kind and should only be called by the
	// engine.
	SetKind(string)
}

KindedRes is an interface that is required for a resource to have a kind.

type MetaParams

type MetaParams struct {
	// Noop specifies that no changes should be made by the resource. It
	// relies on the individual resource implementation, and can't protect
	// you from a poorly or maliciously implemented resource.
	Noop bool `yaml:"noop"`

	// Retry is the number of times to retry on error. Use -1 for infinite.
	// This value is used for both Watch and CheckApply.
	Retry int16 `yaml:"retry"`

	// RetryReset resets the retry count for CheckApply if it succeeds. This
	// value is currently different from the count used for Watch.
	// TODO: Consider resetting retry count for watch if it sends an event?
	RetryReset bool `yaml:"retryreset"`

	// Delay is the number of milliseconds to wait between retries. This
	// value is used for both Watch and CheckApply.
	Delay uint64 `yaml:"delay"`

	// Poll is the number of seconds between poll intervals. Use 0 to Watch.
	Poll uint32 `yaml:"poll"`

	// Limit is the number of events per second to allow through.
	Limit rate.Limit `yaml:"limit"`

	// Burst is the number of events to allow in a burst.
	Burst int `yaml:"burst"`

	// Reset causes the meta param state to reset when the resource changes.
	// What this means is if you have a resource of a specific kind and name
	// and in the subsequent graph it changes because one of its params
	// changed, normally the Retry, and other params will remember their
	// state, and you'll not reset the retry counter, however if this is
	// true, then it will get reset. Note that any normal reset mechanisms
	// built into retry are not affected by this.
	Reset bool `yaml:"reset"`

	// Sema is a list of semaphore ids in the form `id` or `id:count`. If
	// you don't specify a count, then 1 is assumed. The sema of `foo` which
	// has a count equal to 1, is different from a sema named `foo:1` which
	// also has a count equal to 1, but is a different semaphore.
	Sema []string `yaml:"sema"`

	// Rewatch specifies whether we re-run the Watch worker during a swap
	// if it has errored. When doing a GraphCmp to swap the graphs, if this
	// is true, and this particular worker has errored, then we'll remove it
	// and add it back as a new vertex, thus causing it to run again. This
	// is different from the Retry metaparam which applies during the normal
	// execution. It is only when this is exhausted that we're in permanent
	// worker failure, and only then can we rely on this metaparam. This is
	// false by default, as the frequency of graph changes makes it unlikely
	// that you wanted this enabled on most resources.
	Rewatch bool `yaml:"rewatch"`

	// Realize ensures that the resource is guaranteed to converge at least
	// once before a potential graph swap removes or changes it. This
	// guarantee is useful for fast changing graphs, to ensure that the
	// brief creation of a resource is seen. This guarantee does not prevent
	// against the engine quitting normally, and it can't guarantee it if
	// the resource is blocked because of a failed pre-requisite resource.
	// XXX: Not implemented!
	Realize bool `yaml:"realize"`
}

MetaParams provides some meta parameters that apply to every resource.

func (*MetaParams) Cmp

func (obj *MetaParams) Cmp(meta *MetaParams) error

Cmp compares two AutoGroupMeta structs and determines if they're equivalent.

func (*MetaParams) Copy

func (obj *MetaParams) Copy() *MetaParams

Copy copies this struct and returns a new one.

func (*MetaParams) UnmarshalYAML

func (obj *MetaParams) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML is the custom unmarshal handler for the MetaParams struct. It is primarily useful for setting the defaults. TODO: this is untested

func (*MetaParams) Validate

func (obj *MetaParams) Validate() error

Validate runs some validation on the meta params.

type MetaRes

type MetaRes interface {
	// MetaParams lets you get or set meta params for the resource.
	MetaParams() *MetaParams

	// SetMetaParams lets you set all of the meta params for the resource in
	// a single call.
	SetMetaParams(*MetaParams)
}

MetaRes is the interface a resource must implement to support meta params. All resources must implement this.

type MetaState

type MetaState struct {

	// CheckApplyRetry is the current retry count for CheckApply.
	CheckApplyRetry int16
}

MetaState is some local meta param state that is saved between resources of the same kind+name unique ID. Even though the vertex/resource pointer might change during a graph switch (because the params changed) we might be logically referring to the same resource, and we might want to preserve some data across that switch. The common example is the resource retry count. If a resource failed three times, and we had a limit of five before it would be a permanent failure, then we don't want to reset this counter just because we changed a parameter (field) of the resource. This doesn't mean we don't want to ever reset these counts. For that, flip on the reset meta param.

type NamedRes

type NamedRes interface {
	Name() string
	SetName(string)
}

NamedRes is an interface that is used so a resource can have a unique name.

type RecvableRes

type RecvableRes interface {
	Res

	// SetRecv stores the map of sendable data which should arrive here. It
	// is called by the GAPI when building the resource.
	SetRecv(recv map[string]*Send)

	// Recv is used by the resource to get information on changes. This data
	// can be used to invalidate caches, restart watches, or it can be
	// ignored entirely. You should use the GenerateRecvFunc helper function
	// to build this function for use in the resource internal state handle.
	Recv() map[string]*Send
}

RecvableRes is the interface a resource must implement to support receiving on public parameters. The resource only has to include the correct trait for this interface to be fulfilled, as no additional methods need to be added. To get information about received changes, you can use the Recv method from the input API that comes in via Init.

type RefreshableRes

type RefreshableRes interface {
	Res // implement everything in Res but add the additional requirements

	// Refresh returns the refresh notification state.
	Refresh() bool

	// SetRefresh sets the refresh notification state.
	SetRefresh(bool)
}

RefreshableRes is the interface a resource must implement to support refresh notifications. Default implementations for all of the methods declared in this interface can be obtained for your resource by anonymously adding the traits.Refreshable struct to your resource implementation.

type Res

type Res interface {
	fmt.Stringer // String() string

	KindedRes
	NamedRes // TODO: consider making this optional in the future
	MetaRes  // All resources must have meta params.

	// Default returns a struct with sane defaults for this resource.
	Default() Res

	// Validate determines if the struct has been defined in a valid state.
	Validate() error

	// Init initializes the resource and passes in some external information
	// and data from the engine.
	Init(*Init) error

	// Cleanup is run by the engine to clean up after the resource is done.
	Cleanup() error

	// Watch is run by the engine to monitor for state changes. If it
	// detects any, it notifies the engine which will usually run CheckApply
	// in response. If the input context cancels, we must shutdown.
	Watch(context.Context) error

	// CheckApply determines if the state of the resource is correct and if
	// asked to with the `apply` variable, applies the requested state. If
	// the input context cancels, we must return as quickly as possible. We
	// should never exit immediately if this would cause permanent
	// corruption of some sort. However it doesn't mean that a resource was
	// taken to the desired state.
	CheckApply(ctx context.Context, apply bool) (checkOK bool, err error)

	// Cmp compares itself to another resource and returns an error if they
	// are not equivalent. This is more strict than the Adapts method of the
	// CompatibleRes interface which allows for equivalent differences if
	// the have a compatible result in CheckApply.
	Cmp(Res) error
}

Res is the minimum interface you need to implement to define a new resource.

func NewNamedResource

func NewNamedResource(kind, name string) (Res, error)

NewNamedResource returns an empty resource object from a registered kind. It also sets the name. It is a wrapper around NewResource. It also errors if the name is empty.

func NewResource

func NewResource(kind string) (Res, error)

NewResource returns an empty resource object from a registered kind. It errors if the resource kind doesn't exist.

func Sort

func Sort(rs []Res) []Res

Sort the list of resources and return a copy without modifying the input.

type ResPtrUID

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

ResPtrUID is a unique identifier that is consistent for the kind and name of the resource only. This was formerly a string, but a struct is more precise. The result is suitable as a unique map key.

func PtrUID

func PtrUID(res Res) ResPtrUID

PtrUID generates a ResPtrUID from a resource. The result is suitable as a unique map key.

type ResUID

type ResUID interface {
	fmt.Stringer // String() string

	GetName() string
	GetKind() string

	IFF(ResUID) bool

	IsReversed() bool // true means this resource happens before the generator
}

ResUID is a unique identifier for a resource, namely it's name, and the kind ("type").

type ResourceSlice

type ResourceSlice []Res

ResourceSlice is a linear list of resources. It can be sorted.

func (ResourceSlice) Len

func (rs ResourceSlice) Len() int

func (ResourceSlice) Less

func (rs ResourceSlice) Less(i, j int) bool

func (ResourceSlice) Swap

func (rs ResourceSlice) Swap(i, j int)

type ReversibleMeta

type ReversibleMeta struct {
	// Disabled specifies that reversing should be disabled for this
	// resource.
	Disabled bool

	// Reversal specifies that the resource was built from a reversal. This
	// must be set if the resource was built by a reversal.
	Reversal bool

	// Overwrite specifies that we should overwrite any existing stored
	// reversible resource if one that is pending already exists. If this is
	// false, and a resource with the same name and kind exists, then this
	// will cause an error.
	Overwrite bool
}

ReversibleMeta provides some parameters specific to reversible resources.

func (*ReversibleMeta) Cmp

func (obj *ReversibleMeta) Cmp(rm *ReversibleMeta) error

Cmp compares two ReversibleMeta structs and determines if they're equivalent.

type ReversibleRes

type ReversibleRes interface {
	Res

	// ReversibleMeta lets you get or set meta params for the reversible
	// trait.
	ReversibleMeta() *ReversibleMeta

	// SetReversibleMeta lets you set all of the meta params for the
	// reversible trait in a single call.
	SetReversibleMeta(*ReversibleMeta)

	// Reversed returns the "reverse" or "reciprocal" resource. This is used
	// to "clean" up after a previously defined resource has been removed.
	// Interestingly, this could return the core Res interface instead of a
	// ReversibleRes, because there is no requirement that the reverse of a
	// Res be the same kind of Res, and the reverse might not be reversible!
	// However, in practice, it's nice to use some of the Reversible meta
	// params in the built value, so keep things simple and have this be a
	// reversible res. The Res itself doesn't have to implement Reversed()
	// in a meaningful way, it can just return nil and it will get ignored.
	Reversed() (ReversibleRes, error)
}

ReversibleRes is an interface that a resource can implement if it wants to have some resource run when it disappears. A disappearance happens when a resource is defined in one instance of the graph, and is gone in the subsequent one. This is helpful for building robust programs with the engine. Default implementations for most of the methods declared in this interface can be obtained for your resource by anonymously adding the traits.Reversible struct to your resource implementation.

type Send

type Send struct {
	Res SendableRes // a handle to the resource which is sending a value
	Key string      // the key in the resource that we're sending

	Changed bool // set to true if this key was updated, read only!
}

Send points to a value that a resource will send.

type SendableRes

type SendableRes interface {
	Res // implement everything in Res but add the additional requirements

	// Sends returns a struct containing the defaults of the type we send.
	Sends() interface{}

	// Send is used in CheckApply to send the desired data. It returns an
	// error if the data is malformed or doesn't type check. You should use
	// the GenerateSendFunc helper function to build this function for use
	// in the resource internal state handle.
	Send(st interface{}) error

	// Sent returns the most recently sent data. This is used by the engine.
	Sent() interface{}
}

SendableRes is the interface a resource must implement to support sending named parameters. You must specify to the engine what kind of values (and with their types) you will be sending. This is used for static type checking. Formerly, you had to make sure not to overwrite omitted parameters, otherwise it will be as if you've now declared a fixed state for that param. For that example, if a parameter `Foo string` had the zero value to mean that it was undefined, and you learned that the value is actually `up`, then sending on that param would cause that state to be managed, when it was previously not. This new interface actually provides a different namespace for sending keys.

type World

type World interface {
	ResWatch(context.Context) (chan error, error)
	ResExport(context.Context, []Res) error
	// FIXME: should this method take a "filter" data struct instead of many args?
	ResCollect(ctx context.Context, hostnameFilter, kindFilter []string) ([]Res, error)

	IdealClusterSizeWatch(context.Context) (chan error, error)
	IdealClusterSizeGet(context.Context) (uint16, error)
	IdealClusterSizeSet(context.Context, uint16) (bool, error)

	StrWatch(ctx context.Context, namespace string) (chan error, error)
	StrIsNotExist(error) bool
	StrGet(ctx context.Context, namespace string) (string, error)
	StrSet(ctx context.Context, namespace, value string) error
	StrDel(ctx context.Context, namespace string) error

	// XXX: add the exchange primitives in here directly?
	StrMapWatch(ctx context.Context, namespace string) (chan error, error)
	StrMapGet(ctx context.Context, namespace string) (map[string]string, error)
	StrMapSet(ctx context.Context, namespace, value string) error
	StrMapDel(ctx context.Context, namespace string) error

	Scheduler(namespace string, opts ...scheduler.Option) (*scheduler.Result, error)

	// Fs takes a URI and returns the filesystem that corresponds to that.
	// This is a way to turn a unique string handle into an appropriate
	// filesystem object that we can interact with.
	Fs(uri string) (Fs, error)

	// WatchMembers returns a channel of changing members in the cluster.
	WatchMembers(context.Context) (<-chan *interfaces.MembersResult, error)
}

World is an interface to the rest of the different graph state. It allows the GAPI to store state and exchange information throughout the cluster. It is the interface each machine uses to communicate with the rest of the world.

type WriteableFS

type WriteableFS interface {
	Fs

	// WriteFile writes data to the named file, creating it if necessary. If
	// the file does not exist, WriteFile creates it with permissions perm
	// (before umask); otherwise WriteFile truncates it before writing,
	// without changing permissions. Since Writefile requires multiple
	// system calls to complete, a failure mid-operation can leave the file
	// in a partially written state.
	//
	// This mimics the internal os.WriteFile function and has the same docs.
	WriteFile(name string, data []byte, perm os.FileMode) error
}

WriteableFS is our internal filesystem interface for filesystems we write to. It can wrap whatever implementations we want.

type YAMLRes

type YAMLRes interface {
	Res

	yaml.Unmarshaler // UnmarshalYAML(unmarshal func(interface{}) error) error
}

YAMLRes is a resource that supports creation by unmarshalling.

Directories

Path Synopsis
Package graph contains the actual implementation of the resource graph engine that runs the graph of resources in real-time.
Package graph contains the actual implementation of the resource graph engine that runs the graph of resources in real-time.
Package local contains functions and interfaces that are shared between functions and resources.
Package local contains functions and interfaces that are shared between functions and resources.
Package resources contains the implementations of all the core resources.
Package resources contains the implementations of all the core resources.
packagekit
Package packagekit provides an interface to interact with packagekit.
Package packagekit provides an interface to interact with packagekit.
Package traits contains all the definitions and implementations of the core resource traits that are imported by all the resource implementations.
Package traits contains all the definitions and implementations of the core resource traits that are imported by all the resource implementations.
Package util contains utility functions that are specific to the resource engine.
Package util contains utility functions that are specific to the resource engine.

Jump to

Keyboard shortcuts

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