Documentation ¶
Overview ¶
Package plugin defines a set of interfaces that plugins must implement to enable wash functonality.
All resources must implement the Entry interface. To do so they should include the EntryBase type, and initialize it via NewEntry. For example
type myResource struct { plugin.EntryBase } ... rsc := myResource{plugin.NewEntry("a resource")}
EntryBase gives the resource a name - which is how it will be displayed in the filesystem or referenced via the API - and tools for controlling how its data is cached.
Implementing the Parent interface displays that resource as a directory on the filesystem. Anything that does not implement Parent will be displayed as a file.
The Readable interface allows reading data from an entry via the filesystem. The Writable interface allows sending data to the entry.
Wash distinguishes between two different patterns for things you can read and write. It considers a "file-like" entry to be one with a defined size (so the `size` attribute is set when listing the entry). Reading and writing a "file-like" entry edits the contents. Something that can be read and written but doesn't define size has different characteristics. Reading and writing are not symmetrical: if you write to it then read from it, you may not see what you just wrote. So these non-file-like entries error if you try to open them with a ReadWrite handle. If your plugin implements non-file-like write-semantics, remember to document how they work in the plugin schema's description.
All of the above, as well as other types - Execable, Stream - provide additional functionality via the HTTP API.
Index ¶
- Constants
- Variables
- func Actions() map[string]Action
- func CName(e Entry) string
- func CachedOp(ctx context.Context, opName string, entry Entry, ttl time.Duration, op opFunc) (interface{}, error)
- func ClearCacheFor(path string, clearAncestorList bool) []string
- func Delete(ctx context.Context, d Deletable) (deleted bool, err error)
- func DeleteWithAnalytics(ctx context.Context, d Deletable) (bool, error)
- func ID(e Entry) string
- func InitCache()
- func InitInteractive(init bool)
- func IsInteractive() bool
- func IsInvalidInputErr(err error) bool
- func IsPrefetched(e Entry) bool
- func Name(e Entry) string
- func Prompt(msg string) (string, error)
- func Read(ctx context.Context, e Entry, size int64, offset int64) (data []byte, err error)
- func ReadWithAnalytics(ctx context.Context, e Entry, size int64, offset int64) ([]byte, error)
- func SchemaGraph(e Entry) (*linkedhashmap.Map, error)
- func SetTestCache(c datastore.Cache) context.Context
- func Signal(ctx context.Context, s Signalable, signal string) error
- func SignalWithAnalytics(ctx context.Context, s Signalable, signal string) error
- func Size(ctx context.Context, e Entry) (uint64, error)
- func Stream(ctx context.Context, s Streamable) (io.ReadCloser, error)
- func StreamWithAnalytics(ctx context.Context, s Streamable) (io.ReadCloser, error)
- func SupportedActionsOf(entry Entry) []string
- func TrackTime(start time.Time, name string)
- func TypeID(e Entry) string
- func UnsetTestCache()
- func Write(ctx context.Context, a Writable, b []byte) error
- func WriteWithAnalytics(ctx context.Context, w Writable, b []byte) error
- type Action
- type BlockReadable
- type CleanupReader
- type Deletable
- type DuplicateCNameErr
- type Entry
- type EntryAttributes
- func (a *EntryAttributes) Atime() time.Time
- func (a *EntryAttributes) Crtime() time.Time
- func (a *EntryAttributes) Ctime() time.Time
- func (a *EntryAttributes) HasAtime() bool
- func (a *EntryAttributes) HasCrtime() bool
- func (a *EntryAttributes) HasCtime() bool
- func (a *EntryAttributes) HasMode() bool
- func (a *EntryAttributes) HasMtime() bool
- func (a *EntryAttributes) HasOS() bool
- func (a *EntryAttributes) HasSize() bool
- func (a EntryAttributes) MarshalJSON() ([]byte, error)
- func (a *EntryAttributes) Mode() os.FileMode
- func (a *EntryAttributes) Mtime() time.Time
- func (a *EntryAttributes) OS() OS
- func (a *EntryAttributes) SetAtime(atime time.Time) *EntryAttributes
- func (a *EntryAttributes) SetCrtime(crtime time.Time) *EntryAttributes
- func (a *EntryAttributes) SetCtime(ctime time.Time) *EntryAttributes
- func (a *EntryAttributes) SetMode(mode os.FileMode) *EntryAttributes
- func (a *EntryAttributes) SetMtime(mtime time.Time) *EntryAttributes
- func (a *EntryAttributes) SetOS(os OS) *EntryAttributes
- func (a *EntryAttributes) SetSize(size uint64) *EntryAttributes
- func (a *EntryAttributes) Size() uint64
- func (a *EntryAttributes) ToMap() map[string]interface{}
- func (a *EntryAttributes) UnmarshalJSON(data []byte) error
- type EntryBase
- func (e *EntryBase) Attributes() *EntryAttributes
- func (e *EntryBase) DisableCachingFor(op defaultOpCode) *EntryBase
- func (e *EntryBase) DisableDefaultCaching() *EntryBase
- func (e *EntryBase) ID() string
- func (e *EntryBase) IsInaccessible() bool
- func (e *EntryBase) MarkInaccessible(ctx context.Context, err error)
- func (e *EntryBase) Metadata(ctx context.Context) (JSONObject, error)
- func (e *EntryBase) Name() string
- func (e *EntryBase) Prefetched() *EntryBase
- func (e *EntryBase) SetAttributes(attr EntryAttributes) *EntryBase
- func (e *EntryBase) SetPartialMetadata(obj interface{}) *EntryBase
- func (e *EntryBase) SetSlashReplacer(char rune) *EntryBase
- func (e *EntryBase) SetTTLOf(op defaultOpCode, ttl time.Duration) *EntryBase
- func (e *EntryBase) SetTestID(id string)
- func (e *EntryBase) String() string
- func (e *EntryBase) TTLOf(op defaultOpCode) time.Duration
- type EntryMap
- type EntrySchema
- func (s *EntrySchema) AddSignal(name string, description string) *EntrySchema
- func (s *EntrySchema) AddSignalGroup(name string, regex string, description string) *EntrySchema
- func (s *EntrySchema) IsSingleton() *EntrySchema
- func (s EntrySchema) MarshalJSON() ([]byte, error)
- func (s *EntrySchema) SetDescription(description string) *EntrySchema
- func (s *EntrySchema) SetMetadataSchema(obj interface{}) *EntrySchema
- func (s *EntrySchema) SetPartialMetadataSchema(obj interface{}) *EntrySchema
- type ExecCommand
- type ExecCommandImpl
- func (cmd *ExecCommandImpl) CloseStreamsWithError(err error)
- func (cmd *ExecCommandImpl) ExitCode() (int, error)
- func (cmd *ExecCommandImpl) OutputCh() <-chan ExecOutputChunk
- func (cmd *ExecCommandImpl) SetExitCode(exitCode int)
- func (cmd *ExecCommandImpl) SetExitCodeErr(err error)
- func (cmd *ExecCommandImpl) SetStopFunc(stopFunc func())
- func (cmd *ExecCommandImpl) Stderr() *OutputStream
- func (cmd *ExecCommandImpl) Stdout() *OutputStream
- type ExecOptions
- type ExecOutputChunk
- type ExecPacketType
- type Execable
- type HasWrappedTypes
- type InvalidInputErr
- type JSONObject
- type JSONSchema
- type MetadataJSONFile
- type MethodSignature
- type OS
- type OutputStream
- type Parent
- type Readable
- type Registry
- type Root
- type SchemaMap
- type Shell
- type SignalSchema
- func (s *SignalSchema) Description() string
- func (s *SignalSchema) IsGroup() bool
- func (s SignalSchema) MarshalJSON() ([]byte, error)
- func (s *SignalSchema) Name() string
- func (s *SignalSchema) Regex() *regexp.Regexp
- func (s *SignalSchema) SetDescription(description string) *SignalSchema
- func (s *SignalSchema) SetName(name string) *SignalSchema
- func (s *SignalSchema) SetRegex(regex *regexp.Regexp) *SignalSchema
- func (s *SignalSchema) UnmarshalJSON(bytes []byte) error
- type Signalable
- type Streamable
- type Writable
Constants ¶
const ( // ListOp represents Parent#List ListOp defaultOpCode = iota // ReadOp represents Readable/BlockReadable#Read ReadOp // MetadataOp represents Entry#Metadata MetadataOp )
Variables ¶
var DefaultTimeout = 10 * time.Second
DefaultTimeout is the default timeout for prefetching
Functions ¶
func Actions ¶
Actions returns all of the available Wash actions as a map of <action_name> => <action_object>.
func CName ¶
CName returns the entry's canonical name, which is what Wash uses to construct the entry's path. The entry's cname is plugin.Name(e), but with all '/' characters replaced by a '#' character. CNames are necessary because it is possible for entry names to have '/'es in them, which is illegal in bourne shells and UNIX-y filesystems.
CNames are unique. CName uniqueness is checked in plugin.CachedList.
NOTE: The '#' character was chosen because it is unlikely to appear in a meaningful entry's name. If, however, there's a good chance that an entry's name can contain the '#' character, and that two entries can have the same cname (e.g. 'foo/bar', 'foo#bar'), then you can use e.SetSlashReplacer(<char>) to change the default slash replacer from a '#' to <char>.
func CachedOp ¶
func CachedOp(ctx context.Context, opName string, entry Entry, ttl time.Duration, op opFunc) (interface{}, error)
CachedOp caches the given op's result for the duration specified by the ttl. You should use it when you need more fine-grained caching than what the existing CachedList, CachedOpen, and CachedMetadata methods provide. For example, CachedOp could be useful to cache an API request whose response lets you implement Open() and Metadata() for the given entry.
A ttl of 0 uses the cache default of 1 minute. Negative ttls are not allowed.
CachedOp uses the supplied context to determine where to log activity.
func ClearCacheFor ¶
ClearCacheFor removes entries from the cache that match or are children of the provided path. If successful, returns an array of deleted keys. Optionally clear the list operation for the parent to remove any attributes related to the specified entry.
TODO: If path == "/", we could optimize this by calling cache.Flush(). Not important right now, but may be worth considering in the future.
func DeleteWithAnalytics ¶
DeleteWithAnalytics is a wrapper to plugin.Delete. Use it when you need to report a 'Delete' invocation to analytics. Otherwise, use plugin.Delete.
func ID ¶
ID returns the entry's ID, which is just its path rooted at Wash's mountpoint. An entry's ID is described as
/<plugin_name>/<parent1_cname>/<parent2_cname>/.../<entry_cname>
NOTE: <plugin_name> is really <plugin_cname>. However since <plugin_name> can never contain a '/', <plugin_cname> reduces to <plugin_name>.
func InitInteractive ¶
func InitInteractive(init bool)
InitInteractive is used by Wash commands to set option-specific overrides. Only sets interactivity to true if it already was and 'init' is also true.
func IsInteractive ¶
func IsInteractive() bool
IsInteractive returns true if Wash is running as an interactive session. If false, please don't prompt for input on stdin.
func IsInvalidInputErr ¶
IsInvalidInputErr returns true if err is an InvalidInputErr error object
func IsPrefetched ¶
IsPrefetched returns whether an entry has data that was added during creation that it would like to have updated.
func Name ¶
Name returns the entry's name as it was passed into plugin.NewEntry. It is meant to be called by other Wash packages. Plugin authors should use EntryBase#Name when writing their plugins.
func Read ¶
Read reads up to size bits of the entry's content starting at the given offset. It will panic if the entry does not support the read action. Callers can use len(data) to check the amount of data that was actually read.
If the offset is >= to the available content size, then data != nil, len(data) == 0, and err == io.EOF. Otherwise if len(data) < size, then err == io.EOF.
Note that Read is thread-safe.
func ReadWithAnalytics ¶
ReadWithAnalytics is a wrapper to plugin.Read. Use it when you need to report a 'Read' invocation to analytics. Otherwise, use plugin.Read.
func SchemaGraph ¶
func SchemaGraph(e Entry) (*linkedhashmap.Map, error)
SchemaGraph returns e's schema graph. This is effectively a map[string]plugin.EntrySchema object that preserves insertion order (where the string is each entry's type ID).
func SetTestCache ¶
SetTestCache sets the cache to the provided mock. It can only be called by the tests. Returns a context that includes a parent ID so later cache operations will succeed.
func Signal ¶
func Signal(ctx context.Context, s Signalable, signal string) error
Signal signals the entry with the specified signal
func SignalWithAnalytics ¶
func SignalWithAnalytics(ctx context.Context, s Signalable, signal string) error
SignalWithAnalytics is a wrapper to plugin.Signal. Use it when you need to report a 'Signal' invocation to analytics. Otherwise, use plugin.Signal.
func Stream ¶
func Stream(ctx context.Context, s Streamable) (io.ReadCloser, error)
Stream streams the entry's content for updates.
func StreamWithAnalytics ¶
func StreamWithAnalytics(ctx context.Context, s Streamable) (io.ReadCloser, error)
StreamWithAnalytics is a wrapper to s#Stream. Use it when you need to report a 'Stream' invocation to analytics. Otherwise, use s#Stream.
func SupportedActionsOf ¶
SupportedActionsOf returns all of the given entry's supported actions.
func TrackTime ¶
TrackTime helper is useful for timing functions. Use with `defer plugin.TrackTime(time.Now(), "funcname")`.
func TypeID ¶
TypeID returns the entry's type ID. It is needed by the API, so plugin authors should ignore this.
func UnsetTestCache ¶
func UnsetTestCache()
UnsetTestCache unsets the test cache. It can only be called by the tests
Types ¶
type Action ¶
type Action struct { Name string `json:"name"` Protocol string `json:"protocol"` // contains filtered or unexported fields }
Action represents a Wash action.
func (Action) IsSupportedOn ¶
IsSupportedOn returns true if the action's supported on the specified entry, false otherwise.
type BlockReadable ¶
type BlockReadable interface { Entry Read(ctx context.Context, size int64, offset int64) ([]byte, error) }
BlockReadable is an entry with data that can be read in blocks. A BlockReadable entry must set its Size attribute. If you don't set it, the file size will be reported as 0 and reads will return an empty file.
type CleanupReader ¶
type CleanupReader struct { io.ReadCloser Cleanup func() }
CleanupReader is a wrapper for an io.ReadCloser that performs cleanup when closed.
func (CleanupReader) Close ¶
func (c CleanupReader) Close() error
Close closes the reader it wraps, then calls the Cleanup function and returns any errors.
type Deletable ¶
Deletable is an entry that can be deleted. Entries that implement Delete should ensure that it and all its children are removed. If the entry has any dependencies that need to be deleted, then Delete should return an error.
If Delete returns true, then that means the entry was deleted. If Delete returns false, then that means the entry is marked for deletion by the plugin's API. You should return false if you anticipate delete taking a long time (> 30 seconds).
type DuplicateCNameErr ¶
type DuplicateCNameErr struct { ParentID string FirstChildName string FirstChildSlashReplacer rune SecondChildName string SecondChildSlashReplacer rune CName string }
DuplicateCNameErr represents a duplicate cname error, which occurs when at least two children have the same cname.
func (DuplicateCNameErr) Error ¶
func (c DuplicateCNameErr) Error() string
type Entry ¶
type Entry interface { Metadata(ctx context.Context) (JSONObject, error) Schema() *EntrySchema // contains filtered or unexported methods }
Entry is the interface for things that are representable by Wash's filesystem. This includes plugin roots; resources like containers and volumes; placeholders (e.g. the containers directory in the Docker plugin); read-only files like the metadata.json files for containers and EC2 instances; and more. It is a sealed interface, meaning you must use plugin.NewEntry when creating your plugin objects.
Metadata returns a complete description of the entry. See the EntryBase documentation for more details on when to override it.
Schema returns the entry's schema. See plugin.EntrySchema for more details.
type EntryAttributes ¶
type EntryAttributes struct {
// contains filtered or unexported fields
}
EntryAttributes represents an entry's attributes. We use a struct instead of a map for efficient memory allocation/deallocation, which is needed to make Parent#List fast.
Each of the setters supports the builder pattern, which enables you to do something like
attr := plugin.EntryAttributes{} attr. SetCrtime(crtime). SetMtime(mtime) entry.SetAttributes(attr)
func Attributes ¶
func Attributes(e Entry) EntryAttributes
Attributes returns the entry's attributes.
func (*EntryAttributes) Atime ¶
func (a *EntryAttributes) Atime() time.Time
Atime returns the entry's last access time
func (*EntryAttributes) Crtime ¶
func (a *EntryAttributes) Crtime() time.Time
Crtime returns the entry's creation time
func (*EntryAttributes) Ctime ¶
func (a *EntryAttributes) Ctime() time.Time
Ctime returns the entry's change time
func (*EntryAttributes) HasAtime ¶
func (a *EntryAttributes) HasAtime() bool
HasAtime returns true if the entry has a last access time
func (*EntryAttributes) HasCrtime ¶
func (a *EntryAttributes) HasCrtime() bool
HasCrtime returns true if the entry has a creation time
func (*EntryAttributes) HasCtime ¶
func (a *EntryAttributes) HasCtime() bool
HasCtime returns true if the entry has a change time
func (*EntryAttributes) HasMode ¶
func (a *EntryAttributes) HasMode() bool
HasMode returns true if the entry has a mode
func (*EntryAttributes) HasMtime ¶
func (a *EntryAttributes) HasMtime() bool
HasMtime returns true if the entry has a last modified time
func (*EntryAttributes) HasOS ¶
func (a *EntryAttributes) HasOS() bool
HasOS returns true if the entry has information about its OS
func (*EntryAttributes) HasSize ¶
func (a *EntryAttributes) HasSize() bool
HasSize returns true if the entry has a size
func (EntryAttributes) MarshalJSON ¶
func (a EntryAttributes) MarshalJSON() ([]byte, error)
MarshalJSON marshals the entry's attributes to JSON. It takes a value receiver so that the attributes are still marshaled when they're referenced as interface{} objects. See https://stackoverflow.com/a/21394657 for more details.
func (*EntryAttributes) Mode ¶
func (a *EntryAttributes) Mode() os.FileMode
Mode returns the entry's mode
func (*EntryAttributes) Mtime ¶
func (a *EntryAttributes) Mtime() time.Time
Mtime returns the entry's last modified time
func (*EntryAttributes) OS ¶
func (a *EntryAttributes) OS() OS
OS returns the entry's operating system information
func (*EntryAttributes) SetAtime ¶
func (a *EntryAttributes) SetAtime(atime time.Time) *EntryAttributes
SetAtime sets the entry's last access time
func (*EntryAttributes) SetCrtime ¶
func (a *EntryAttributes) SetCrtime(crtime time.Time) *EntryAttributes
SetCrtime sets the entry's creation time
func (*EntryAttributes) SetCtime ¶
func (a *EntryAttributes) SetCtime(ctime time.Time) *EntryAttributes
SetCtime sets the entry's change time
func (*EntryAttributes) SetMode ¶
func (a *EntryAttributes) SetMode(mode os.FileMode) *EntryAttributes
SetMode sets the entry's mode
func (*EntryAttributes) SetMtime ¶
func (a *EntryAttributes) SetMtime(mtime time.Time) *EntryAttributes
SetMtime sets the entry's last modified time
func (*EntryAttributes) SetOS ¶
func (a *EntryAttributes) SetOS(os OS) *EntryAttributes
SetOS sets the entry's operating system information
func (*EntryAttributes) SetSize ¶
func (a *EntryAttributes) SetSize(size uint64) *EntryAttributes
SetSize sets the entry's size
func (*EntryAttributes) Size ¶
func (a *EntryAttributes) Size() uint64
Size returns the entry's Size
func (*EntryAttributes) ToMap ¶
func (a *EntryAttributes) ToMap() map[string]interface{}
ToMap converts the entry's attributes to a map, which makes it easier to write generic code on them.
func (*EntryAttributes) UnmarshalJSON ¶
func (a *EntryAttributes) UnmarshalJSON(data []byte) error
UnmarshalJSON unmarshals the entry's attributes from JSON.
type EntryBase ¶
type EntryBase struct {
// contains filtered or unexported fields
}
EntryBase implements Entry, making it easy to create new entries. You should use plugin.NewEntry to create new EntryBase objects.
Each of the setters supports the builder pattern, which enables you to do something like
e := plugin.NewEntry("foo") e. DisableCachingFor(plugin.ListOp). Attributes(). SetCrtime(crtime). SetMtime(mtime). SetMeta(meta)
func (*EntryBase) Attributes ¶
func (e *EntryBase) Attributes() *EntryAttributes
Attributes returns a pointer to the entry's attributes. Use it to individually set the entry's attributes
func (*EntryBase) DisableCachingFor ¶
DisableCachingFor disables caching for the specified op
func (*EntryBase) DisableDefaultCaching ¶
DisableDefaultCaching disables the default caching for List, Open and Metadata.
func (*EntryBase) ID ¶
ID returns the entry's ID. It won't panic on an empty string. See ID() for more detail. This exists primarily to support the `external` package.
func (*EntryBase) IsInaccessible ¶
IsInaccessible returns whether the entry is inaccessible.
func (*EntryBase) MarkInaccessible ¶
MarkInaccessible sets the inaccessible attribute and logs a message about why the entry is inaccessible.
func (*EntryBase) Metadata ¶
func (e *EntryBase) Metadata(ctx context.Context) (JSONObject, error)
Metadata returns the entry's partial metadata. Override this if e has additional metadata properties that couldn't be included in the partial metadata because doing so would have slowed down parent#List.
func (*EntryBase) Name ¶
Name returns the entry's name as it was passed into plugin.NewEntry. You should use e.Name() when making the appropriate API calls within your plugin.
func (*EntryBase) Prefetched ¶
Prefetched marks the entry as a prefetched entry. A prefetched entry is an entry that was fetched as part of a batch operation that fetched multiple levels of hierarchy at once. Volume directories and files are good examples of prefetched entries (see the volume package for more details).
func (*EntryBase) SetAttributes ¶
func (e *EntryBase) SetAttributes(attr EntryAttributes) *EntryBase
SetAttributes sets the entry's attributes. Use it to set the entry's attributes in a single operation, which is useful when you've already pre-computed them.
func (*EntryBase) SetPartialMetadata ¶
SetPartialMetadata sets the entry's partial metadata. This is typically the raw object that's returned by the plugin API's List endpoint, or a wrapper that includes the raw object + some additional information. For example, if the entry represents a Docker container, then obj would be a Container struct. If the entry represents a Docker volume, then obj would be a Volume struct.
In general, the partial metadata is the subset of metadata that can be fetched "quickly" s.t. parent#List isn't slowed down.
SetPartialMetadata will panic if obj does not serialize to a JSON object.
func (*EntryBase) SetSlashReplacer ¶
SetSlashReplacer overrides the default '/' replacer '#' to char. The '/' replacer is used when determining the entry's cname. See plugin.CName for more details.
func (*EntryBase) SetTestID ¶
SetTestID sets the entry's cache ID for testing. It can only be called by the tests.
type EntryMap ¶
type EntryMap struct {
// contains filtered or unexported fields
}
EntryMap is a thread-safe map of <entry_cname> => <entry_object>. It's API is (mostly) symmetric with sync.Map.
func List ¶
List lists the parent's children. It returns an EntryMap to optimize querying a specific entry.
Note that List's results could be cached.
func ListWithAnalytics ¶
ListWithAnalytics is a wrapper to plugin.List. Use it when you need to report a 'List' invocation to analytics. Otherwise, use plugin.List
type EntrySchema ¶
type EntrySchema struct {
// contains filtered or unexported fields
}
EntrySchema represents an entry's schema. Use plugin.NewEntrySchema to create instances of these objects.
func NewEntrySchema ¶
func NewEntrySchema(e Entry, label string) *EntrySchema
NewEntrySchema returns a new EntrySchema object with the specified label.
func (*EntrySchema) AddSignal ¶
func (s *EntrySchema) AddSignal(name string, description string) *EntrySchema
AddSignal adds the given signal to s' supported signals. See https://puppetlabs.github.io/wash/docs#signal for a list of common signal names. You should try to re-use these names if you can.
func (*EntrySchema) AddSignalGroup ¶
func (s *EntrySchema) AddSignalGroup(name string, regex string, description string) *EntrySchema
AddSignalGroup adds the given signal group to s' supported signals
func (*EntrySchema) IsSingleton ¶
func (s *EntrySchema) IsSingleton() *EntrySchema
IsSingleton marks the entry as a singleton entry.
func (EntrySchema) MarshalJSON ¶
func (s EntrySchema) MarshalJSON() ([]byte, error)
MarshalJSON marshals the entry's schema to JSON. It takes a value receiver so that the entry schema's still marshalled when it's referenced as an interface{} object. See https://stackoverflow.com/a/21394657 for more details.
Note that UnmarshalJSON is not implemented since that is not how plugin.EntrySchema objects are meant to be used.
func (*EntrySchema) SetDescription ¶
func (s *EntrySchema) SetDescription(description string) *EntrySchema
SetDescription sets the entry's description.
func (*EntrySchema) SetMetadataSchema ¶
func (s *EntrySchema) SetMetadataSchema(obj interface{}) *EntrySchema
SetMetadataSchema sets Entry#Metadata's schema. obj is an empty struct that will be marshalled into a JSON schema. SetMetadataSchema will panic if obj is not a struct.
NOTE: Only use SetMetadataSchema if you're overriding Entry#Metadata. Otherwise, use SetPartialMetadataSchema.
func (*EntrySchema) SetPartialMetadataSchema ¶
func (s *EntrySchema) SetPartialMetadataSchema(obj interface{}) *EntrySchema
SetPartialMetadataSchema sets the partial metadata's schema. obj is an empty struct that will be marshalled into a JSON schema. SetPartialMetadataSchema will panic if obj is not a struct.
type ExecCommand ¶
type ExecCommand interface { OutputCh() <-chan ExecOutputChunk ExitCode() (int, error) }
ExecCommand represents a command that was invoked by a call to Exec. It is a sealed interface, meaning you must use plugin.NewExecCommand to create instances of these objects.
OutputCh returns a channel containing timestamped chunks of the command's stdout/stderr.
ExitCode returns the command's exit code. It will block until the command's exit code is set, or until the execution context is cancelled. ExitCode will return an error if it fails to fetch the command's exit code.
func Exec ¶
func Exec(ctx context.Context, e Execable, cmd string, args []string, opts ExecOptions) (ExecCommand, error)
Exec execs the command on the given entry.
func ExecWithAnalytics ¶
func ExecWithAnalytics(ctx context.Context, e Execable, cmd string, args []string, opts ExecOptions) (ExecCommand, error)
ExecWithAnalytics is a wrapper to e#Exec. Use it when you need to report an 'Exec' invocation to analytics. Otherwise, use e#Exec.
type ExecCommandImpl ¶
type ExecCommandImpl struct {
// contains filtered or unexported fields
}
ExecCommandImpl implements the plugin.ExecCommand interface. Use plugin.NewExecCommand to create instances of these objects.
ExecCommandImpl provides Stdout/Stderr streams that you can wire-up to your plugin's API. These streams ensure that your API's stdout/stderr ordering is preserved. For example, if your API sends over Stderr, Stdout, and Stderr packets (in that order), then ExecCommand's OutputCh will stream them as Stderr, Stdout, and Stderr packets to your clients.
Once the command's finished its execution, use SetExitCode to set the command's exit code. If your API fails to retrieve the command's exit code, then use SetExitCodeErr to set an appropriate error that ExitCode() can return.
ExecCommandImpl also includes helpers that handle context-cancellation related cleanup for you. plugin.NewExecCommand ensures that the OutputCh is closed upon context-cancellation so that clients streaming your command's output are not blocked. SetStopFunc ensures that the exec'ing command is stopped upon context-cancellation, which prevents orphaned processes.
See Container#Exec in the Docker plugin and ExecSSH in the transport package for examples of how ExecCommandImpl is used.
func NewExecCommand ¶
func NewExecCommand(ctx context.Context) *ExecCommandImpl
NewExecCommand creates a new ExecCommandImpl object whose lifetime is tied to the passed-in execution context. This ctx should match what's passed into Execable#Exec. Note that NewExecCommand ensures that the OutputCh is closed when ctx is cancelled.
func (*ExecCommandImpl) CloseStreamsWithError ¶
func (cmd *ExecCommandImpl) CloseStreamsWithError(err error)
CloseStreamsWithError closes the command's stdout/stderr streams with the given error.
func (*ExecCommandImpl) ExitCode ¶
func (cmd *ExecCommandImpl) ExitCode() (int, error)
ExitCode implements ExecCommand#ExitCode
func (*ExecCommandImpl) OutputCh ¶
func (cmd *ExecCommandImpl) OutputCh() <-chan ExecOutputChunk
OutputCh implements ExecCommand#OutputCh
func (*ExecCommandImpl) SetExitCode ¶
func (cmd *ExecCommandImpl) SetExitCode(exitCode int)
SetExitCode sets the command's exit code that will be returned by cmd.ExitCode().
func (*ExecCommandImpl) SetExitCodeErr ¶
func (cmd *ExecCommandImpl) SetExitCodeErr(err error)
SetExitCodeErr sets the error that will be returned by cmd.ExitCode(). Use it if your plugin API fails to get the command's exit code.
func (*ExecCommandImpl) SetStopFunc ¶
func (cmd *ExecCommandImpl) SetStopFunc(stopFunc func())
SetStopFunc sets the function that stops the running command. stopFunc is called when cmd.ctx is cancelled.
NOTE: SetStopFunc can be used to avoid orphaned processes.
func (*ExecCommandImpl) Stderr ¶
func (cmd *ExecCommandImpl) Stderr() *OutputStream
Stderr returns the command's stderr stream. Attach this to your plugin API's stderr stream.
func (*ExecCommandImpl) Stdout ¶
func (cmd *ExecCommandImpl) Stdout() *OutputStream
Stdout returns the command's stdout stream. Attach this to your plugin API's stdout stream.
type ExecOptions ¶
type ExecOptions struct { // Stdin can be used to pass a stream of input to write to stdin when executing the command. // It is not included in ExecOption's JSON serialization. Stdin io.Reader `json:"-"` // Tty instructs the executor to allocate a TTY (pseudo-terminal), which lets Wash communicate // with the running process via its Stdin. The TTY is used to send a process termination signal // (Ctrl+C) via Stdin when the passed-in Exec context is cancelled. // // NOTE TO PLUGIN AUTHORS: The Tty option is only relevant for executors that do not have an API // endpoint to stop a running command (e.g. Docker, Kubernetes). If your executor does have an // API endpoint to stop a running command, then ignore the Tty option. Note that the reason we // make Tty an option instead of having the relevant executors always attach a TTY is because // attaching a TTY can change the behavior of the command that's being executed. // // NOTE TO CALLERS: The Tty option is useful for executing your own stream-like commands (e.g. // tail -f), because it ensures that there are no orphaned processes after the request is // cancelled/finished. Tty bool `json:"tty"` // Elevate execution to run as a privileged user if not already running as a privileged user. Elevate bool `json:"elevate"` }
ExecOptions is a struct we can add new features to that must be serializable to JSON. Examples of potential features: user, privileged, map of environment variables, timeout.
type ExecOutputChunk ¶
type ExecOutputChunk struct { StreamID ExecPacketType Timestamp time.Time Data string Err error }
ExecOutputChunk is a struct containing a chunk of the Exec'ed cmd's output.
type ExecPacketType ¶
type ExecPacketType = string
ExecPacketType identifies the packet type.
const ( Stdout ExecPacketType = "stdout" Stderr ExecPacketType = "stderr" )
Enumerates packet types.
type Execable ¶
type Execable interface { Entry Exec(ctx context.Context, cmd string, args []string, opts ExecOptions) (ExecCommand, error) }
Execable is an entry that can have a command run on it.
type HasWrappedTypes ¶
HasWrappedTypes is an interface that's used by the EntrySchema#SetMeta*Schema methods to return the right metadata schema for wrapped types. Plugin roots should implement this interface if the plugin's SDK wraps primitive types like date, integer, number, string, boolean, etc. See kubernetes/root.go for an example of when WrappedTypes is used.
NOTE: Type aliases like "type Time = time.Time" do NOT count as wrapped types. Pointers also don't count. Only promoted types ("type Time time.Time") and wrapper structs ("struct Time { t time.Time }") count.
NOTE: Without WrappedTypes, the underlying JSON schema library will treat promoted types and wrapper structs as JSON objects, which would be incorrect. This, unfortunately, is a limitation of Go's reflect package.
type InvalidInputErr ¶
type InvalidInputErr struct {
// contains filtered or unexported fields
}
InvalidInputErr indicates that the method invocation received invalid input (e.g. plugin.Signal received an unsupported signal).
func (InvalidInputErr) Error ¶
func (e InvalidInputErr) Error() string
type JSONObject ¶
type JSONObject = map[string]interface{}
JSONObject is a typedef to a map[string]interface{} object.
func Metadata ¶
func Metadata(ctx context.Context, e Entry) (JSONObject, error)
Metadata returns the entry's metadata. Note that Metadata's results could be cached.
func PartialMetadata ¶
func PartialMetadata(e Entry) JSONObject
PartialMetadata returns the entry's partial metadata, a subset of the entry's metadata that is typically provided by the plugin API's List endpoint. If the entry didn't specify any partial metadata, then this returns Attributes(e).ToMap() to enforce the "attributes are a subset of the partial metadata" invariant.
func ToJSONObject ¶
func ToJSONObject(v interface{}) JSONObject
ToJSONObject serializes v to a JSON object. It will panic if the serialization fails.
type JSONSchema ¶
type JSONSchema = jsonschema.Schema
JSONSchema represents a JSON schema
func BooleanSchema ¶
func BooleanSchema() *JSONSchema
BooleanSchema represents a boolean's schema (bool)
func IntegerSchema ¶
func IntegerSchema() *JSONSchema
IntegerSchema represents an integer's schema (int)
func NumberSchema ¶
func NumberSchema() *JSONSchema
NumberSchema represents a number's schema (float64)
func StringSchema ¶
func StringSchema() *JSONSchema
StringSchema represents a string's schema (string)
func TimeSchema ¶
func TimeSchema() *JSONSchema
TimeSchema represents the schema of a time.Time object
type MetadataJSONFile ¶
type MetadataJSONFile struct { EntryBase // contains filtered or unexported fields }
MetadataJSONFile represents a metadata.json file that contains another entry's metadata.
func NewMetadataJSONFile ¶
func NewMetadataJSONFile(ctx context.Context, other Entry) (*MetadataJSONFile, error)
NewMetadataJSONFile creates a new MetadataJSONFile. If caching Metadata on the `other` entry is disabled, it will use that to compute the file size upfront.
func (*MetadataJSONFile) Read ¶
func (m *MetadataJSONFile) Read(ctx context.Context) ([]byte, error)
Read returns the metadata of the `other` entry as its content.
func (*MetadataJSONFile) Schema ¶
func (m *MetadataJSONFile) Schema() *EntrySchema
Schema defines the schema of a metadata.json file.
type MethodSignature ¶
type MethodSignature int
MethodSignature defines what method signature is supported for a method.
const ( UnsupportedSignature MethodSignature = iota DefaultSignature BlockReadableSignature )
Defines different method signatures.
type OS ¶
type OS struct { // LoginShell describes the type of shell execution occurs in. It can be used // by the caller to decide what type of commands to run. LoginShell Shell }
OS contains information about the operating system of a compute-like entry
type OutputStream ¶
type OutputStream struct {
// contains filtered or unexported fields
}
OutputStream represents stdout/stderr.
func (*OutputStream) CloseWithError ¶
func (s *OutputStream) CloseWithError(err error)
CloseWithError sends the given error before closing the OutputStream. It will noop if the OutputStream's already closed.
func (*OutputStream) WriteWithTimestamp ¶
func (s *OutputStream) WriteWithTimestamp(timestamp time.Time, data []byte) error
WriteWithTimestamp writes the given data with the specified timestamp
type Parent ¶
type Parent interface { Entry // TODO: "nil" schemas mean that the schema's unknown. This condition's necessary for // the plugin registry b/c external plugins may not have a schema. However, core plugins // should never return a "nil" schema -- their schema's always known. Since this specification // affects core plugin authors, it should be cleaned up once the metadata schema + external // plugin schema work is finished. ChildSchemas() []*EntrySchema List(context.Context) ([]Entry, error) }
Parent is an entry with children. It will be represented as a directory in the Wash filesystem. All parents must implement ChildSchemas, which is useful for documenting your plugin's hierarchy via the stree command, and for optimizing `wash find`'s traversal by eliminating non-satisfying paths. Your implementation of ChildSchemas should be something like
return []*plugin.EntrySchema{ (&childObj1{}).Schema(), (&childObj2{}).Schema(), ... (&childObjN{}).Schema(), }
For example,
return []*plugin.EntrySchema{ (&containerLogFile{}).Schema(), (&containerMetadata{}).Schema(), (&vol.FS{}).Schema(), }
is the implementation of ChildSchemas for a Docker container.
type Registry ¶
type Registry struct { EntryBase // contains filtered or unexported fields }
Registry represents the plugin registry. It is also Wash's root.
func (*Registry) ChildSchemas ¶
func (r *Registry) ChildSchemas() []*EntrySchema
ChildSchemas only makes sense for core plugin roots
func (*Registry) Plugins ¶
Plugins returns a map of the currently registered plugins. It should not be called while registering plugins.
func (*Registry) RegisterPlugin ¶
RegisterPlugin initializes the given plugin and adds it to the registry if initialization was successful.
func (*Registry) Schema ¶
func (r *Registry) Schema() *EntrySchema
Schema only makes sense for core plugin roots
type Root ¶
Root represents the plugin root. The Init function is passed a config map representing plugin-specific configuration.
type SchemaMap ¶
type SchemaMap = map[interface{}]*JSONSchema
SchemaMap represents a map of <type> => <JSON schema>.
type Shell ¶
type Shell int
Shell describes a command shell.
Defines specific Shell classes you can configure
type SignalSchema ¶
type SignalSchema struct {
// contains filtered or unexported fields
}
SignalSchema represents a given signal/signal group's schema
func (*SignalSchema) Description ¶
func (s *SignalSchema) Description() string
Description returns the signal/signal group's name
func (*SignalSchema) IsGroup ¶
func (s *SignalSchema) IsGroup() bool
IsGroup returns true if s is a signal group's schema. This is true if s.Regex() != nil
func (SignalSchema) MarshalJSON ¶
func (s SignalSchema) MarshalJSON() ([]byte, error)
MarshalJSON marshals the signal schema to JSON. It takes a value receiver so that the entry schema's still marshalled when it's referenced as an interface{} object. See https://stackoverflow.com/a/21394657 for more details.
func (*SignalSchema) Name ¶
func (s *SignalSchema) Name() string
Name returns the signal/signal group's name
func (*SignalSchema) Regex ¶
func (s *SignalSchema) Regex() *regexp.Regexp
Regex returns a regex describing an arbitrary signal in the signal group.
func (*SignalSchema) SetDescription ¶
func (s *SignalSchema) SetDescription(description string) *SignalSchema
SetDescription sets the signal/signal group's description. This should only be called by the tests.
func (*SignalSchema) SetName ¶
func (s *SignalSchema) SetName(name string) *SignalSchema
SetName sets the signal/signal group's name. This should only be called by the tests.
func (*SignalSchema) SetRegex ¶
func (s *SignalSchema) SetRegex(regex *regexp.Regexp) *SignalSchema
SetRegex sets the signal group's regex. This should only be called by the tests.
func (*SignalSchema) UnmarshalJSON ¶
func (s *SignalSchema) UnmarshalJSON(bytes []byte) error
UnmarshalJSON unmarshals the signal schema JSON.
type Signalable ¶
Signalable is an entry that can be signaled. Signal should return nil if the signal was successfully sent. Otherwise, it should return an error explaining why the signal was not sent.
NOTE: You can assume that the sent signal is downcased and valid.
type Streamable ¶
Streamable is an entry that returns a stream of updates.
type Writable ¶
Writable is an entry that we can write new data to. What that means can be implementation-specific; it could be overwriting a file, submitting a configuration change to an API, or writing data to a queue. It doesn't support a concept of a partial write.
Writable can be implemented with or without Readable/BlockReadable. If an entry is only Writable, then only full writes (starting from offset 0) are allowed, anything else initiated by the filesystem will result in an error.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package aws presents a filesystem hierarchy for AWS resources.
|
Package aws presents a filesystem hierarchy for AWS resources. |
Package docker presents a filesystem hierarchy for Docker resources.
|
Package docker presents a filesystem hierarchy for Docker resources. |
Package gcp presents a filesystem hierarchy for Google Cloud Platform resources.
|
Package gcp presents a filesystem hierarchy for Google Cloud Platform resources. |
Package kubernetes presents a filesystem hierarchy for Kubernetes resources.
|
Package kubernetes presents a filesystem hierarchy for Kubernetes resources. |