snap

package
v0.0.0-...-25a8614 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2021 License: GPL-3.0 Imports: 27 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrBadModes is returned by ValidateContainer when the container has files with the wrong file modes for their role
	ErrBadModes = errors.New("snap is unusable due to bad permissions")
	// ErrMissingPaths is returned by ValidateContainer when the container is missing required files or directories
	ErrMissingPaths = errors.New("snap is unusable due to missing files")
)
View Source
var ErrUnknownRestartCondition = errors.New("invalid restart condition")

ErrUnknownRestartCondition is returned when trying to unmarshal an unknown restart condition

View Source
var RestartMap = map[string]RestartCondition{
	"no":          RestartNever,
	"never":       RestartNever,
	"on-success":  RestartOnSuccess,
	"on-failure":  RestartOnFailure,
	"on-abnormal": RestartOnAbnormal,
	"on-abort":    RestartOnAbort,
	"on-watchdog": RestartOnWatchdog,
	"always":      RestartAlways,
}
View Source
var SanitizePlugsSlots = func(snapInfo *Info) {
	panic("SanitizePlugsSlots function not set")
}
View Source
var SupportedSystemUsernames = map[string]systemUsername{
	"snap_daemon": {Id: 584788},
	"snap_microk8s": {Id: 584789, AllowedSnapIds: []string{
		"EaXqgt1lyCaxKaQCU349mlodBkDCXRcg",
	}},
}

SupportedSystemUsernames for now contains the hardcoded list of system users (and implied system group of same name) that snaps may specify. This will eventually be moved out of here into the store.

Since the snap is mounted read-only and to avoid problems associated with different systems using different uids and gids for the same user name and group name, snapd will create system-usernames where 'scope' is not 'external' (currently snapd only supports 'scope: shared') with the following characteristics:

  • uid and gid shall match for the specified system-username
  • a snapd-allocated [ug]id for a user/group name shall never change
  • snapd should avoid [ug]ids that are known to overlap with uid ranges of common use cases and user namespace container managers so that DAC and AppArmor owner match work as intended.
  • [ug]id shall be < 2^31 to avoid (at least) broken devpts kernel code
  • [ug]id shall be >= 524288 (0x00080000) to give plenty of room for large sites, default uid/gid ranges for docker (231072-296608), LXD installs that setup a default /etc/sub{uid,gid} (100000-165536) and podman whose tutorials reference setting up a specific default user and range (100000-165536)
  • [ug]id shall be < 1,000,000 and > 1,001,000,000 (ie, 1,000,000 subordinate uid with 1,000,000,000 range) to avoid overlapping with LXD's minimum and maximum id ranges. LXD allows for any id range >= 65536 and doesn't perform any [ug]id overlap detection with current users
  • [ug]ids assigned by snapd initially will fall within a 65536 (2^16) range (see below) where the first [ug]id in the range has the 16 lower bits all set to zero. This allows snapd to conveniently be bitwise aligned, follows sensible conventions (see https://systemd.io/UIDS-GIDS.html) but also potentially discoverable by systemd-nspawn (it assigns a different 65536 range to each container. Its allocation algorithm is not sequential and may choose anything within its range that isn't already allocated. It's detection algorithm includes (effectively) performing a getpwent() operation on CANDIDATE_UID & 0XFFFF0000 and selecting another range if it is assigned).

What [ug]id range(s) should snapd use?

While snapd does not employ user namespaces, it will operate on systems with container managers that do and will assign from a range of [ug]ids. It is desirable that snapd assigns [ug]ids that minimally conflict with the system and other software (potential conflicts with admin-assigned ranges in /etc/subuid and /etc/subgid cannot be avoided, but can be documented as well as detected/logged). Overlapping with container managers is non-fatal for snapd and the container, but introduces the possibility that a uid in the container matches a uid a snap is using, which is undesirable in terms of security (eg, DoS via ulimit, same ownership of files between container and snap (even if the other's files are otherwise inaccessible), etc).

snapd shall assign [ug]ids from range(s) of 65536 where the lowest value in the range has the 16 lower bits all set to zero (initially just one range, but snapd can add more as needed).

To avoid [ug]id overlaps, snapd shall only assign [ug]ids >= 524288 (0x00080000) and <= 983040 (0x000F0000, ie the first 65536 range under LXD's minimum where the lower 16 bits are all zeroes). While [ug]ids >= 1001062400 (0x3BAB0000, the first 65536 range above LXD's maximum where the lower 16 bits are all zeroes) would also avoid overlap, considering nested containers (eg, LXD snap runs a container that runs a container that runs snapd), choosing >= 1001062400 would mean that the admin would need to increase the LXD id range for these containers for snapd to be allowed to create its [ug]ids in the deeply nested containers. The requirements would both be an administrative burden and artificially limit the number of deeply nested containers the host could have.

Looking at the LSB and distribution defaults for login.defs, we can observe uids and gids in the system's initial 65536 range (ie, 0-65536):

  • 0-99 LSB-suggested statically assigned range (eg, root, daemon, etc)
  • 0 mandatory 'root' user
  • 100-499 LSB-suggested dynamically assigned range for system users (distributions often prefer a higher range, see below)
  • 500-999 typical distribution default for dynamically assigned range for system users (some distributions use a smaller SYS_[GU]ID_MIN)
  • 1000-60000 typical distribution default for dynamically assigned range for regular users
  • 65535 (-1) should not be assigned since '-1' might be evaluated as this with set[ug]id* and chown families of functions
  • 65534 (-2) nobody/nogroup user for NFS/etc [ug]id anonymous squashing
  • 65519-65533 systemd recommended reserved range for site-local anonymous additions, etc

To facilitate potential future use cases within the 65536 range snapd will assign from, snapd will only assign from the following subset of ranges relative to the range minimum (ie, its 'base' which has the lower 16 bits all set to zero):

- 60500-60999 'scope: shared' system-usernames - 61000-65519 'scope: private' system-usernames

Since the first [ug]id range must be >= 524288 and <= 983040 (see above) and following the above guide for system-usernames [ug]ids within this 65536 range, the lowest 'scope: shared' user in this range is 584788 (0x0008EC54).

Since this number is within systemd-nspawn's range of 524288-1879048191 (0x00080000-0x6FFFFFFF), the number's lower 16 bits are not all zeroes so systemd-nspawn won't detect this allocation and could potentially assign the 65536 range starting at 0x00080000 to a container. snapd will therefore also create the 'snapd-range-524288-root' user and group with [ug]id 524288 to work within systemd-nspawn's collision detection. This user/group will not be assigned to snaps at this time.

In short (phew!), use the following:

$ snappy-debug.id-range 524288 # 0x00080000 Host range: 524288-589823 (00080000-0008ffff; 0-65535) LSB static range: 524288-524387 (00080000-00080063; 0-99) Useradd system range: 524788-525287 (000801f4-000803e7; 500-999) Useradd regular range: 525288-584288 (000803e8-0008ea60; 1000-60000) Snapd system range: 584788-585287 (0008ec54-0008ee47; 60500-60999) Snapd private range: 585288-589807 (0008ee48-0008ffef; 61000-65519)

Snapd is of course free to add more ranges (eg, 589824 (0x00090000)) with new snapd-range-<base>-root users, or to allocate differently within its 65536 range in the future (sequentially assigned [ug]ids are not required), but for now start very regimented to avoid as many problems as possible.

References: https://forum.snapcraft.io/t/multiple-users-and-groups-in-snaps/ https://systemd.io/UIDS-GIDS.html https://docs.docker.com/engine/security/userns-remap/ https://github.com/lxc/lxd/blob/master/doc/userns-idmap.md

Functions

func AppSecurityTag

func AppSecurityTag(snapName, appName string) string

AppSecurityTag returns the application-specific security tag.

func BadInterfacesSummary

func BadInterfacesSummary(snapInfo *Info) string

BadInterfacesSummary returns a summary of the problems of bad plugs and slots in the snap.

func BaseDataDir

func BaseDataDir(name string) string

BaseDataDir returns the base directory for snap data locations.

func BaseDir

func BaseDir(name string) string

BaseDir returns the system level directory of given snap.

func CommonDataDir

func CommonDataDir(name string) string

CommonDataDir returns the common data directory for given snap name. The name can be either a snap name or snap instance name.

func DataDir

func DataDir(name string, revision Revision) string

DataDir returns the data directory for given snap name and revision. The name can be either a snap name or snap instance name.

func DefaultContentProviders

func DefaultContentProviders(plugs []*PlugInfo) (providerSnapsToContentTag map[string][]string)

DefaultContentProviders returns the set of default provider snaps requested by the given plugs, mapped to their content tags.

func GuessAppsForBroken

func GuessAppsForBroken(info *Info) map[string]*AppInfo

GuessAppsForBroken guesses what apps and services a broken snap has on the system by searching for matches based on the snap name in the snap binaries and service file directories. It returns a mapping from app names to partial AppInfo.

func HookSecurityTag

func HookSecurityTag(snapName, hookName string) string

HookSecurityTag returns the hook-specific security tag.

func HooksDir

func HooksDir(name string, revision Revision) string

HooksDir returns the directory containing the snap's hooks for given snap name. The name can be either a snap name or snap instance name.

func InstallDate

func InstallDate(name string) time.Time

InstallDate returns the "install date" of the snap.

If the snap is not active, it'll return a zero time; otherwise it'll return the modtime of the "current" symlink.

func InstanceName

func InstanceName(snapName, instanceKey string) string

InstanceName takes the snap name and the instance key and returns an instance name of the snap.

func InstanceSnap

func InstanceSnap(instanceName string) string

InstanceSnap splits the instance name and returns the name of the snap.

func IsHookSupported

func IsHookSupported(hookName string) bool

IsHookSupported returns true if the given hook name matches one of the supported hooks.

func IsSnapd

func IsSnapd(snapID string) bool

func JoinSnapApp

func JoinSnapApp(snap, app string) string

JoinSnapApp produces a full application wrapper name from the `snap` and the `app` part. It also deals with the special case of snapName == appName.

func MockAppendSupportedHookTypes

func MockAppendSupportedHookTypes(hookTypes []*HookType) (restore func())

func MockSanitizePlugsSlots

func MockSanitizePlugsSlots(f func(snapInfo *Info)) (restore func())

func MockSupportedHookTypes

func MockSupportedHookTypes(hookTypes []*HookType) (restore func())

func MountDir

func MountDir(name string, revision Revision) string

MountDir returns the base directory where it gets mounted of the snap with the given name and revision.

func MountFile

func MountFile(name string, revision Revision) string

MountFile returns the path where the snap file that is mounted is installed.

func NeededDefaultProviders

func NeededDefaultProviders(info *Info) (providerSnapsToContentTag map[string][]string)

NeededDefaultProviders returns a map keyed by the names of all default-providers for the content plugs that the given snap.Info needs. The map values are the corresponding content tags.

func NoneSecurityTag

func NoneSecurityTag(snapName, uniqueName string) string

NoneSecurityTag returns the security tag for interfaces that are not associated to an app or hook in the snap.

func ScopedSecurityTag

func ScopedSecurityTag(snapName, scopeName, suffix string) string

ScopedSecurityTag returns the snap-specific, scope specific, security tag.

func SecurityTag

func SecurityTag(snapName string) string

SecurityTag returns the snap-specific security tag.

func SplitInstanceName

func SplitInstanceName(instanceName string) (snapName, instanceKey string)

SplitInstanceName splits the instance name and returns the snap name and the instance key.

func SplitSnapApp

func SplitSnapApp(snapApp string) (snap, app string)

SplitSnapApp will split a string of the form `snap.app` into the `snap` and the `app` part. It also deals with the special case of snapName == appName.

Example
fmt.Println(snap.SplitSnapApp("hello-world.env"))
Output:

hello-world env
Example (Short)
fmt.Println(snap.SplitSnapApp("hello-world"))
Output:

hello-world hello-world

func UserCommonDataDir

func UserCommonDataDir(home string, name string) string

UserCommonDataDir returns the user-specific common data directory for given snap name. The name can be either a snap name or snap instance name.

func UserDataDir

func UserDataDir(home string, name string, revision Revision) string

UserDataDir returns the user-specific data directory for given snap name. The name can be either a snap name or snap instance name.

func UserSnapDir

func UserSnapDir(home string, name string) string

UserSnapDir returns the user-specific directory for given snap name. The name can be either a snap name or snap instance name.

func UserXdgRuntimeDir

func UserXdgRuntimeDir(euid sys.UserID, name string) string

UserXdgRuntimeDir returns the user-specific XDG_RUNTIME_DIR directory for given snap name. The name can be either a snap name or snap instance name.

func ValidAppName

func ValidAppName(n string) bool

ValidAppName tells whether a string is a valid application name.

func Validate

func Validate(info *Info) error

Validate verifies the content in the info.

func ValidateAlias

func ValidateAlias(alias string) error

ValidateAlias checks if a string can be used as an alias name.

func ValidateApp

func ValidateApp(app *AppInfo) error

ValidateApp verifies the content in the app info.

func ValidateBase

func ValidateBase(info *Info) error

ValidateBase validates the base field.

func ValidateBasesAndProviders

func ValidateBasesAndProviders(snapInfos []*Info) []error

ValidateBasesAndProviders checks that all bases/default-providers are part of the seed

func ValidateCommonIDs

func ValidateCommonIDs(info *Info) error

func ValidateContainer

func ValidateContainer(c Container, s *Info, logf func(format string, v ...interface{})) error

ValidateContainer does a minimal sanity check on the container.

func ValidateDesktopPrefix

func ValidateDesktopPrefix(prefix string) bool

ValidateDesktopPrefix checks if a string can be used as a desktop file prefix. A desktop prefix should be of the form 'snapname' or 'snapname+instance'.

func ValidateHook

func ValidateHook(hook *HookInfo) error

ValidateHook validates the content of the given HookInfo

func ValidateInstanceName

func ValidateInstanceName(instanceName string) error

ValidateInstanceName checks if a string can be used as a snap instance name.

func ValidateInterfaceName

func ValidateInterfaceName(name string) error

ValidateInterfaceName checks if a string can be used as an interface name.

func ValidateLayout

func ValidateLayout(layout *Layout, constraints []LayoutConstraint) error

ValidateLayout ensures that the given layout contains only valid subset of constructs.

func ValidateLayoutAll

func ValidateLayoutAll(info *Info) error

ValidateLayoutAll validates the consistency of all the layout elements in a snap.

func ValidateLicense

func ValidateLicense(license string) error

ValidateLicense checks if a string is a valid SPDX expression.

func ValidateLinks(links map[string][]string) error

ValidateLinks checks that links entries have valid keys and values that can be parsed as URLs or are email addresses possibly prefixed with mailto:.

func ValidateName

func ValidateName(name string) error

ValidateName checks if a string can be used as a snap name.

func ValidatePathVariables

func ValidatePathVariables(path string) error

ValidatePathVariables ensures that given path contains only $SNAP, $SNAP_DATA or $SNAP_COMMON.

func ValidatePlugName

func ValidatePlugName(name string) error

ValidatePlugName checks if a string can be used as a slot name.

Slot names and plug names within one snap must have unique names. This is not enforced by this function but is enforced by snap-level validation.

func ValidateSlotName

func ValidateSlotName(name string) error

ValidateSlotName checks if a string can be used as a slot name.

Slot names and plug names within one snap must have unique names. This is not enforced by this function but is enforced by snap-level validation.

func ValidateSystemUsernames

func ValidateSystemUsernames(info *Info) error

func ValidateVersion

func ValidateVersion(version string) error

ValidateVersion checks if a string is a valid snap version.

Types

type AlreadyInstalledError

type AlreadyInstalledError struct {
	Snap string
}

func (AlreadyInstalledError) Error

func (e AlreadyInstalledError) Error() string

type AppInfo

type AppInfo struct {
	Snap *Info

	Name          string
	LegacyAliases []string // FIXME: eventually drop this
	Command       string
	CommandChain  []string
	CommonID      string

	Daemon          string
	DaemonScope     DaemonScope
	StopTimeout     timeout.Timeout
	StartTimeout    timeout.Timeout
	WatchdogTimeout timeout.Timeout
	StopCommand     string
	ReloadCommand   string
	PostStopCommand string
	RestartCond     RestartCondition
	RestartDelay    timeout.Timeout
	Completer       string
	RefreshMode     string
	StopMode        StopModeType
	InstallMode     string

	// TODO: this should go away once we have more plumbing and can change
	// things vs refactor
	// https://github.com/snapcore/snapd/pull/794#discussion_r58688496
	BusName     string
	ActivatesOn []*SlotInfo

	Plugs   map[string]*PlugInfo
	Slots   map[string]*SlotInfo
	Sockets map[string]*SocketInfo

	Environment strutil.OrderedMap

	// list of other service names that this service will start after or
	// before
	After  []string
	Before []string

	Timer *TimerInfo

	Autostart string
}

AppInfo provides information about an app.

func SortServices

func SortServices(apps []*AppInfo) (sorted []*AppInfo, err error)

SortServices sorts the apps based on their Before and After specs, such that starting the services in the returned ordering will satisfy all specs.

func (*AppInfo) CompleterPath

func (app *AppInfo) CompleterPath() string

CompleterPath returns the path to the completer snippet for the app binary.

func (*AppInfo) DesktopFile

func (app *AppInfo) DesktopFile() string

DesktopFile returns the path to the installed optional desktop file for the application.

func (*AppInfo) EnvChain

func (app *AppInfo) EnvChain() []osutil.ExpandableEnv

EnvChain returns the chain of environment overrides, possibly with expandable $ vars, specific for the app.

func (*AppInfo) IsService

func (app *AppInfo) IsService() bool

IsService returns whether app represents a daemon/service.

func (*AppInfo) LauncherCommand

func (app *AppInfo) LauncherCommand() string

LauncherCommand returns the launcher command line to use when invoking the app binary.

func (*AppInfo) LauncherPostStopCommand

func (app *AppInfo) LauncherPostStopCommand() string

LauncherPostStopCommand returns the launcher command line to use when invoking the app post-stop command binary.

func (*AppInfo) LauncherReloadCommand

func (app *AppInfo) LauncherReloadCommand() string

LauncherReloadCommand returns the launcher command line to use when invoking the app stop command binary.

func (*AppInfo) LauncherStopCommand

func (app *AppInfo) LauncherStopCommand() string

LauncherStopCommand returns the launcher command line to use when invoking the app stop command binary.

func (*AppInfo) SecurityTag

func (app *AppInfo) SecurityTag() string

SecurityTag returns application-specific security tag.

Security tags are used by various security subsystems as "profile names" and sometimes also as a part of the file name.

func (*AppInfo) ServiceFile

func (app *AppInfo) ServiceFile() string

ServiceFile returns the systemd service file path for the daemon app.

func (*AppInfo) ServiceName

func (app *AppInfo) ServiceName() string

ServiceName returns the systemd service name for the daemon app.

func (*AppInfo) String

func (app *AppInfo) String() string

func (*AppInfo) WrapperPath

func (app *AppInfo) WrapperPath() string

WrapperPath returns the path to wrapper invoking the app binary.

type AppInfoBySnapApp

type AppInfoBySnapApp []*AppInfo

AppInfoBySnapApp supports sorting the given slice of app infos by (instance name, app name).

func (AppInfoBySnapApp) Len

func (a AppInfoBySnapApp) Len() int

func (AppInfoBySnapApp) Less

func (a AppInfoBySnapApp) Less(i, j int) bool

func (AppInfoBySnapApp) Swap

func (a AppInfoBySnapApp) Swap(i, j int)

type BrokenSnapError

type BrokenSnapError interface {
	error
	Broken() string
}

BrokenSnapError describes an error that refers to a snap that warrants the "broken" note.

type ByType

type ByType []*Info

ByType supports sorting the given slice of snap info by types. The most important types will come first.

func (ByType) Len

func (r ByType) Len() int

func (ByType) Less

func (r ByType) Less(i, j int) bool

func (ByType) Swap

func (r ByType) Swap(i, j int)

type ChannelSnapInfo

type ChannelSnapInfo struct {
	Revision    Revision        `json:"revision"`
	Confinement ConfinementType `json:"confinement"`
	Version     string          `json:"version"`
	Channel     string          `json:"channel"`
	Epoch       Epoch           `json:"epoch"`
	Size        int64           `json:"size"`
	ReleasedAt  time.Time       `json:"released-at"`
}

ChannelSnapInfo is the minimum information that can be used to clearly distinguish different revisions of the same snap.

type ConfinementType

type ConfinementType string

ConfinementType represents the kind of confinement supported by the snap (devmode only, or strict confinement)

const (
	DevModeConfinement ConfinementType = "devmode"
	ClassicConfinement ConfinementType = "classic"
	StrictConfinement  ConfinementType = "strict"
)

The various confinement types we support

func (*ConfinementType) UnmarshalJSON

func (confinementType *ConfinementType) UnmarshalJSON(data []byte) error

UnmarshalJSON sets *confinementType to a copy of data, assuming validation passes

func (*ConfinementType) UnmarshalYAML

func (confinementType *ConfinementType) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML so ConfinementType implements yaml's Unmarshaler interface

type Container

type Container interface {
	// Size returns the size of the snap in bytes.
	Size() (int64, error)

	// RandomAccessFile returns an implementation to read at any
	// given location for a single file inside the snap plus
	// information about the file size.
	RandomAccessFile(relative string) (interface {
		io.ReaderAt
		io.Closer
		Size() int64
	}, error)

	// ReadFile returns the content of a single file from the snap.
	ReadFile(relative string) ([]byte, error)

	// Walk is like filepath.Walk, without the ordering guarantee.
	Walk(relative string, walkFn filepath.WalkFunc) error

	// ListDir returns the content of a single directory inside the snap.
	ListDir(path string) ([]string, error)

	// Install copies the snap file to targetPath (and possibly unpacks it to mountDir).
	// The bool return value indicates if the backend had nothing to do on install.
	Install(targetPath, mountDir string, opts *InstallOptions) (bool, error)

	// Unpack unpacks the src parts to the dst directory
	Unpack(src, dst string) error
}

Container is the interface to interact with the low-level snap files.

type DaemonScope

type DaemonScope string

DaemonScope represents the scope of the daemon running under systemd

const (
	SystemDaemon DaemonScope = "system"
	UserDaemon   DaemonScope = "user"
)

func (*DaemonScope) UnmarshalJSON

func (daemonScope *DaemonScope) UnmarshalJSON(data []byte) error

UnmarshalJSON sets *daemonScope to a copy of data, assuming validation passes

func (*DaemonScope) UnmarshalYAML

func (daemonScope *DaemonScope) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML so DaemonScope implements yaml's Unmarshaler interface

type DeltaInfo

type DeltaInfo struct {
	FromRevision    int    `json:"from-revision,omitempty"`
	ToRevision      int    `json:"to-revision,omitempty"`
	Format          string `json:"format,omitempty"`
	AnonDownloadURL string `json:"anon-download-url,omitempty"`
	DownloadURL     string `json:"download-url,omitempty"`
	Size            int64  `json:"size,omitempty"`
	Sha3_384        string `json:"sha3-384,omitempty"`
}

DeltaInfo contains the information to download a delta from one revision to another.

type DownloadInfo

type DownloadInfo struct {
	AnonDownloadURL string `json:"anon-download-url,omitempty"`
	DownloadURL     string `json:"download-url,omitempty"`

	Size     int64  `json:"size,omitempty"`
	Sha3_384 string `json:"sha3-384,omitempty"`

	// The server can include information about available deltas for a given
	// snap at a specific revision during refresh. Currently during refresh the
	// server will provide single matching deltas only, from the clients
	// revision to the target revision when available, per requested format.
	Deltas []DeltaInfo `json:"deltas,omitempty"`
}

DownloadInfo contains the information to download a snap. It can be marshalled.

type Epoch

type Epoch struct {
	Read  []uint32 `yaml:"read"`
	Write []uint32 `yaml:"write"`
}

An Epoch represents the ability of the snap to read and write its data. Most developers need not worry about it, and snaps default to the 0th epoch, and users are only offered refreshes to epoch 0 snaps. Once an epoch bump is in order, there's a simplified expression they can use which should cover the majority of the cases:

epoch: N

means a snap can read/write exactly the Nth epoch's data, and

epoch: N*

means a snap can additionally read (N-1)th epoch's data, which means it's a snap that can migrate epochs (so a user on epoch 0 can get offered a refresh to a snap on epoch 1*).

If the above is not enough, a developer can explicitly describe what epochs a snap can read and write:

epoch:
  read: [1, 2, 3]
  write: [1, 3]

the read attribute defaults to the value of the write attribute, and the write attribute defaults to the last item in the read attribute. If both are unset, it's the same as not specifying an epoch at all (i.e. epoch: 0). The lists must not have more than 10 elements, they must be strictly increasing, and there must be a non-empty intersection between them.

Epoch numbers must be written in base 10, with no zero padding.

func E

func E(s string) Epoch

E returns the epoch represented by the expression s. It's meant for use in testing, as it panics at the first sign of trouble.

func (*Epoch) CanRead

func (e *Epoch) CanRead(other Epoch) bool

CanRead checks whether this epoch can read the data written by the other one.

func (*Epoch) Equal

func (e *Epoch) Equal(other *Epoch) bool

func (*Epoch) IsZero

func (e *Epoch) IsZero() bool

IsZero checks whether a snap's epoch is not set (or is set to the default value of "0"). Also zero are some epochs that would be normalized to "0", such as {"read": 0}, as well as some invalid ones like {"read": []}.

func (Epoch) MarshalJSON

func (e Epoch) MarshalJSON() ([]byte, error)

func (Epoch) MarshalYAML

func (Epoch) MarshalYAML() (interface{}, error)

func (Epoch) String

func (e Epoch) String() string

func (*Epoch) UnmarshalJSON

func (e *Epoch) UnmarshalJSON(bs []byte) error

func (*Epoch) UnmarshalYAML

func (e *Epoch) UnmarshalYAML(unmarshal func(interface{}) error) error

func (*Epoch) Validate

func (e *Epoch) Validate() error

Validate checks that the epoch makes sense.

type EpochError

type EpochError struct {
	Message string
}

EpochError tracks the details of a failed epoch parse or validation.

func (EpochError) Error

func (e EpochError) Error() string

type HookInfo

type HookInfo struct {
	Snap *Info

	Name  string
	Plugs map[string]*PlugInfo
	Slots map[string]*SlotInfo

	Environment  strutil.OrderedMap
	CommandChain []string

	Explicit bool
}

HookInfo provides information about a hook.

func (*HookInfo) EnvChain

func (hook *HookInfo) EnvChain() []osutil.ExpandableEnv

EnvChain returns the chain of environment overrides, possibly with expandable $ vars, specific for the hook.

func (*HookInfo) SecurityTag

func (hook *HookInfo) SecurityTag() string

SecurityTag returns the hook-specific security tag.

Security tags are used by various security subsystems as "profile names" and sometimes also as a part of the file name.

type HookType

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

HookType represents a pattern of supported hook names.

func NewHookType

func NewHookType(pattern *regexp.Regexp) *HookType

NewHookType returns a new HookType with the given pattern.

func (HookType) Match

func (hookType HookType) Match(hookName string) bool

Match returns true if the given hook name matches this hook type.

type HotplugKey

type HotplugKey string

HotplugKey is a string key of a hotplugged device

func (HotplugKey) ShortString

func (h HotplugKey) ShortString() string

ShortString returns a truncated string representation of the hotplug key

type Info

type Info struct {
	SuggestedName string
	InstanceKey   string
	Version       string
	SnapType      Type
	Architectures []string
	Assumes       []string

	OriginalTitle       string
	OriginalSummary     string
	OriginalDescription string

	Environment strutil.OrderedMap

	LicenseAgreement string
	LicenseVersion   string
	License          string
	Epoch            Epoch
	Base             string
	Confinement      ConfinementType
	Apps             map[string]*AppInfo
	LegacyAliases    map[string]*AppInfo // FIXME: eventually drop this
	Hooks            map[string]*HookInfo
	Plugs            map[string]*PlugInfo
	Slots            map[string]*SlotInfo

	// Plugs or slots with issues (they are not included in Plugs or Slots)
	BadInterfaces map[string]string // slot or plug => message

	// The information in all the remaining fields is not sourced from the snap
	// blob itself.
	SideInfo

	// Broken marks whether the snap is broken and the reason.
	Broken string

	// The information in these fields is ephemeral, available only from the
	// store.
	DownloadInfo

	Prices  map[string]float64
	MustBuy bool

	Publisher StoreAccount

	Media   MediaInfos
	Website string

	StoreURL string

	// The flattended channel map with $track/$risk
	Channels map[string]*ChannelSnapInfo

	// The ordered list of tracks that contain channels
	Tracks []string

	Layout map[string]*Layout

	// The list of common-ids from all apps of the snap
	CommonIDs []string

	// List of system users (usernames) this snap may use. The group of the same
	// name must also exist.
	SystemUsernames map[string]*SystemUsernameInfo

	// OriginalLinks is a map links keys to link lists
	OriginalLinks map[string][]string
}

Info provides information about snaps.

func InfoFromSnapYaml

func InfoFromSnapYaml(yamlData []byte) (*Info, error)

InfoFromSnapYaml creates a new info based on the given snap.yaml data

func ReadCurrentInfo

func ReadCurrentInfo(snapName string) (*Info, error)

ReadCurrentInfo reads the snap information from the installed snap in 'current' revision

func ReadInfo

func ReadInfo(name string, si *SideInfo) (*Info, error)

ReadInfo reads the snap information for the installed snap with the given name and given side-info.

func ReadInfoFromSnapFile

func ReadInfoFromSnapFile(snapf Container, si *SideInfo) (*Info, error)

ReadInfoFromSnapFile reads the snap information from the given Container and completes it with the given side-info if this is not nil.

func (*Info) CommonDataDir

func (s *Info) CommonDataDir() string

CommonDataDir returns the data directory common across revisions of the snap.

func (*Info) CommonDataHomeDir

func (s *Info) CommonDataHomeDir() string

CommonDataHomeDir returns the per user data directory common across revisions of the snap.

func (*Info) Contact

func (s *Info) Contact() string

Contact returns the blessed contact information for the snap.

func (*Info) DataDir

func (s *Info) DataDir() string

DataDir returns the data directory of the snap.

func (*Info) DataHomeDir

func (s *Info) DataHomeDir() string

DataHomeDir returns the per user data directory of the snap.

func (*Info) Description

func (s *Info) Description() string

Description returns the blessed description for the snap.

func (*Info) DesktopPrefix

func (s *Info) DesktopPrefix() string

DesktopPrefix returns the prefix string for the desktop files that belongs to the given snapInstance. We need to do something custom here because a) we need to be compatible with the world before we had parallel installs b) we can't just use the usual "_" parallel installs separator because that is already used as the separator between snap and desktop filename.

func (*Info) ExpandSnapVariables

func (s *Info) ExpandSnapVariables(path string) string

ExpandSnapVariables resolves $SNAP, $SNAP_DATA and $SNAP_COMMON inside the snap's mount namespace.

func (*Info) Filename

func (s *Info) Filename() string

Filename returns the name of the snap with the revision number, as used on the filesystem. This is the equivalent of filepath.Base(s.MountFile()).

func (*Info) HooksDir

func (s *Info) HooksDir() string

HooksDir returns the directory containing the snap's hooks.

func (*Info) ID

func (s *Info) ID() string

ID implements naming.SnapRef.

func (*Info) InstallDate

func (s *Info) InstallDate() time.Time

InstallDate returns the "install date" of the snap.

If the snap is not active, it'll return a zero time; otherwise it'll return the modtime of the "current" symlink. Sneaky.

func (*Info) InstanceName

func (s *Info) InstanceName() string

InstanceName returns the blessed name of the snap decorated with instance key, if any.

func (*Info) IsActive

func (s *Info) IsActive() bool

IsActive returns whether this snap revision is active.

func (s *Info) Links() map[string][]string

Links returns the blessed set of snap-related links.

func (*Info) MountDir

func (s *Info) MountDir() string

MountDir returns the base directory of the snap where it gets mounted.

func (*Info) MountFile

func (s *Info) MountFile() string

MountFile returns the path where the snap file that is mounted is installed.

func (*Info) NeedsClassic

func (s *Info) NeedsClassic() bool

NeedsClassic returns whether the snap needs classic confinement consent.

func (*Info) NeedsDevMode

func (s *Info) NeedsDevMode() bool

NeedsDevMode returns whether the snap needs devmode.

func (*Info) Services

func (s *Info) Services() []*AppInfo

Services returns a list of the apps that have "daemon" set.

func (*Info) SnapName

func (s *Info) SnapName() string

SnapName returns the global blessed name of the snap.

func (*Info) SnapRevision

func (s *Info) SnapRevision() Revision

SnapRevision returns the revision of the snap.

func (*Info) Summary

func (s *Info) Summary() string

Summary returns the blessed summary for the snap.

func (*Info) Title

func (s *Info) Title() string

Title returns the blessed title for the snap.

func (*Info) Type

func (s *Info) Type() Type

Type returns the type of the snap, including additional snap ID check for the legacy snapd snap definitions.

func (*Info) UserCommonDataDir

func (s *Info) UserCommonDataDir(home string) string

UserCommonDataDir returns the user-specific data directory common across revision of the snap.

func (*Info) UserDataDir

func (s *Info) UserDataDir(home string) string

UserDataDir returns the user-specific data directory of the snap.

func (*Info) UserXdgRuntimeDir

func (s *Info) UserXdgRuntimeDir(euid sys.UserID) string

UserXdgRuntimeDir returns the XDG_RUNTIME_DIR directory of the snap for a particular user.

func (*Info) XdgRuntimeDirs

func (s *Info) XdgRuntimeDirs() string

XdgRuntimeDirs returns the XDG_RUNTIME_DIR directories for all users of the snap.

type InstallOptions

type InstallOptions struct {
	// MustNotCrossDevices indicates that the snap file when installed to the
	// target must not cross devices. For example, installing a snap file from
	// the ubuntu-seed partition onto the ubuntu-data partition must result in
	// an installation on ubuntu-data that does not depend or reference
	// ubuntu-seed at all.
	MustNotCrossDevices bool
}

InstallOptions is for customizing the behavior of Install() from a higher level function, i.e. from overlord customizing how a snap file is installed on a system with tmpfs mounted as writable or with full disk encryption and graded secured on UC20.

type Layout

type Layout struct {
	Snap *Info

	Path     string      `json:"path"`
	Bind     string      `json:"bind,omitempty"`
	BindFile string      `json:"bind-file,omitempty"`
	Type     string      `json:"type,omitempty"`
	User     string      `json:"user,omitempty"`
	Group    string      `json:"group,omitempty"`
	Mode     os.FileMode `json:"mode,omitempty"`
	Symlink  string      `json:"symlink,omitempty"`
}

Layout describes a single element of the layout section.

func (*Layout) String

func (l *Layout) String() string

String returns a simple textual representation of a layout.

type LayoutConstraint

type LayoutConstraint interface {
	IsOffLimits(path string) bool
}

LayoutConstraint abstracts validation of conflicting layout elements.

type MediaInfo

type MediaInfo struct {
	Type   string `json:"type"`
	URL    string `json:"url"`
	Width  int64  `json:"width,omitempty"`
	Height int64  `json:"height,omitempty"`
}

type MediaInfos

type MediaInfos []MediaInfo

func (MediaInfos) IconURL

func (mis MediaInfos) IconURL() string

type NotFoundError

type NotFoundError struct {
	Snap     string
	Revision Revision
	// Path encodes the path that triggered the not-found error. It may refer to
	// a file inside the snap or to the snap file itself.
	Path string
}

func (NotFoundError) Broken

func (e NotFoundError) Broken() string

func (NotFoundError) Error

func (e NotFoundError) Error() string

type NotInstalledError

type NotInstalledError struct {
	Snap string
	Rev  Revision
}

func (NotInstalledError) Error

func (e NotInstalledError) Error() string

type NotSnapError

type NotSnapError struct {
	Path string
}

func (NotSnapError) Error

func (e NotSnapError) Error() string

type PlaceInfo

type PlaceInfo interface {
	// InstanceName returns the name of the snap decorated with instance
	// key, if any.
	InstanceName() string

	// SnapName returns the name of the snap.
	SnapName() string

	// SnapRevision returns the revision of the snap.
	SnapRevision() Revision

	// Filename returns the name of the snap with the revision
	// number, as used on the filesystem.
	Filename() string

	// MountDir returns the base directory of the snap.
	MountDir() string

	// MountFile returns the path where the snap file that is mounted is
	// installed.
	MountFile() string

	// HooksDir returns the directory containing the snap's hooks.
	HooksDir() string

	// DataDir returns the data directory of the snap.
	DataDir() string

	// UserDataDir returns the per user data directory of the snap.
	UserDataDir(home string) string

	// CommonDataDir returns the data directory common across revisions of the
	// snap.
	CommonDataDir() string

	// UserCommonDataDir returns the per user data directory common across
	// revisions of the snap.
	UserCommonDataDir(home string) string

	// UserXdgRuntimeDir returns the per user XDG_RUNTIME_DIR directory
	UserXdgRuntimeDir(userID sys.UserID) string

	// DataHomeDir returns the a glob that matches all per user data directories
	// of a snap.
	DataHomeDir() string

	// CommonDataHomeDir returns a glob that matches all per user data
	// directories common across revisions of the snap.
	CommonDataHomeDir() string

	// XdgRuntimeDirs returns a glob that matches all XDG_RUNTIME_DIR
	// directories for all users of the snap.
	XdgRuntimeDirs() string
}

PlaceInfo offers all the information about where a snap and its data are located and exposed in the filesystem.

func MinimalPlaceInfo

func MinimalPlaceInfo(name string, revision Revision) PlaceInfo

MinimalPlaceInfo returns a PlaceInfo with just the location information for a snap of the given name and revision.

func ParsePlaceInfoFromSnapFileName

func ParsePlaceInfoFromSnapFileName(sn string) (PlaceInfo, error)

ParsePlaceInfoFromSnapFileName returns a PlaceInfo with just the location information for a snap of file name, failing if the snap file name is invalid This explicitly does not support filenames with instance names in them

type PlugInfo

type PlugInfo struct {
	Snap *Info

	Name      string
	Interface string
	Attrs     map[string]interface{}
	Label     string
	Apps      map[string]*AppInfo
	Hooks     map[string]*HookInfo
}

PlugInfo provides information about a plug.

func (*PlugInfo) Attr

func (plug *PlugInfo) Attr(key string, val interface{}) error

func (*PlugInfo) Lookup

func (plug *PlugInfo) Lookup(key string) (interface{}, bool)

func (*PlugInfo) SecurityTags

func (plug *PlugInfo) SecurityTags() []string

SecurityTags returns security tags associated with a given plug.

func (*PlugInfo) String

func (plug *PlugInfo) String() string

String returns the representation of the plug as snap:plug string.

type RestartCondition

type RestartCondition string

RestartCondition encapsulates the different systemd 'restart' options

const (
	RestartNever      RestartCondition = "never"
	RestartOnSuccess  RestartCondition = "on-success"
	RestartOnFailure  RestartCondition = "on-failure"
	RestartOnAbnormal RestartCondition = "on-abnormal"
	RestartOnAbort    RestartCondition = "on-abort"
	RestartOnWatchdog RestartCondition = "on-watchdog"
	RestartAlways     RestartCondition = "always"
)

These are the supported restart conditions

func (RestartCondition) String

func (rc RestartCondition) String() string

func (*RestartCondition) UnmarshalYAML

func (rc *RestartCondition) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML so RestartCondition implements yaml's Unmarshaler interface

type Revision

type Revision struct {
	N int
}

func ParseRevision

func ParseRevision(s string) (Revision, error)

ParseRevisions returns the representation in r as a revision. See R for a function more suitable for hardcoded revisions.

func R

func R(r interface{}) Revision

R returns a Revision given an int or a string. Providing an invalid revision type or value causes a runtime panic. See ParseRevision for a polite function that does not panic.

func (Revision) Local

func (r Revision) Local() bool

func (Revision) MarshalJSON

func (r Revision) MarshalJSON() ([]byte, error)

func (Revision) MarshalYAML

func (r Revision) MarshalYAML() (interface{}, error)

func (Revision) Store

func (r Revision) Store() bool

func (Revision) String

func (r Revision) String() string

func (*Revision) UnmarshalJSON

func (r *Revision) UnmarshalJSON(data []byte) error

func (*Revision) UnmarshalYAML

func (r *Revision) UnmarshalYAML(unmarshal func(interface{}) error) error

func (Revision) Unset

func (r Revision) Unset() bool

type ScreenshotInfo

type ScreenshotInfo struct {
	URL    string `json:"url,omitempty"`
	Width  int64  `json:"width,omitempty"`
	Height int64  `json:"height,omitempty"`
	Note   string `json:"note,omitempty"`
}

ScreenshotInfo provides information about a screenshot.

type ServiceStopReason

type ServiceStopReason string
const (
	StopReasonRefresh ServiceStopReason = "refresh"
	StopReasonRemove  ServiceStopReason = "remove"
	StopReasonDisable ServiceStopReason = "disable"
	StopReasonOther   ServiceStopReason = ""
)

type SideInfo

type SideInfo struct {
	RealName          string              `yaml:"name,omitempty" json:"name,omitempty"`
	SnapID            string              `yaml:"snap-id" json:"snap-id"`
	Revision          Revision            `yaml:"revision" json:"revision"`
	Channel           string              `yaml:"channel,omitempty" json:"channel,omitempty"`
	EditedLinks       map[string][]string `yaml:"links,omitempty" json:"links,omitempty"`
	EditedContact     string              `yaml:"contact,omitempty" json:"contact,omitempty"`
	EditedTitle       string              `yaml:"title,omitempty" json:"title,omitempty"`
	EditedSummary     string              `yaml:"summary,omitempty" json:"summary,omitempty"`
	EditedDescription string              `yaml:"description,omitempty" json:"description,omitempty"`
	Private           bool                `yaml:"private,omitempty" json:"private,omitempty"`
	Paid              bool                `yaml:"paid,omitempty" json:"paid,omitempty"`
}

SideInfo holds snap metadata that is crucial for the tracking of snaps and for the working of the system offline and which is not included in snap.yaml or for which the store is the canonical source overriding snap.yaml content.

It can be marshalled and will be stored in the system state for each currently installed snap revision so it needs to be evolved carefully.

Information that can be taken directly from snap.yaml or that comes from the store but is not required for working offline should not end up in SideInfo.

type SlotInfo

type SlotInfo struct {
	Snap *Info

	Name      string
	Interface string
	Attrs     map[string]interface{}
	Label     string
	Apps      map[string]*AppInfo
	Hooks     map[string]*HookInfo

	// HotplugKey is a unique key built by the slot's interface
	// using properties of a hotplugged device so that the same
	// slot may be made available if the device is reinserted.
	// It's empty for regular slots.
	HotplugKey HotplugKey
}

SlotInfo provides information about a slot.

func (*SlotInfo) Attr

func (slot *SlotInfo) Attr(key string, val interface{}) error

func (*SlotInfo) Lookup

func (slot *SlotInfo) Lookup(key string) (interface{}, bool)

func (*SlotInfo) SecurityTags

func (slot *SlotInfo) SecurityTags() []string

SecurityTags returns security tags associated with a given slot.

func (*SlotInfo) String

func (slot *SlotInfo) String() string

String returns the representation of the slot as snap:slot string.

type SocketInfo

type SocketInfo struct {
	App *AppInfo

	Name         string
	ListenStream string
	SocketMode   os.FileMode
}

SocketInfo provides information on application sockets.

func (*SocketInfo) File

func (socket *SocketInfo) File() string

File returns the path to the *.socket file

type StopModeType

type StopModeType string

StopModeType is the type for the "stop-mode:" of a snap app

func (StopModeType) KillAll

func (st StopModeType) KillAll() bool

KillAll returns if the stop-mode means all processes should be killed when the service is stopped or just the main process.

func (StopModeType) KillSignal

func (st StopModeType) KillSignal() string

KillSignal returns the signal that should be used to kill the process (or an empty string if no signal is needed).

func (StopModeType) Validate

func (st StopModeType) Validate() error

Validate ensures that the StopModeType has an valid value.

type StoreAccount

type StoreAccount struct {
	ID          string `json:"id"`
	Username    string `json:"username"`
	DisplayName string `json:"display-name"`
	Validation  string `json:"validation,omitempty"`
}

StoreAccount holds information about a store account, for example of snap publisher.

type SystemUsernameInfo

type SystemUsernameInfo struct {
	Name  string
	Scope string
	Attrs map[string]interface{}
}

SystemUsernameInfo provides information about a system username (ie, a UNIX user and group with the same name). The scope defines visibility of the username wrt the snap and the system. Defined scopes:

  • shared static, snapd-managed user/group shared between host and all snaps
  • private static, snapd-managed user/group private to a particular snap (currently not implemented)
  • external dynamic user/group shared between host and all snaps (currently not implented)

type TimerInfo

type TimerInfo struct {
	App *AppInfo

	Timer string
}

TimerInfo provides information on application timer.

func (*TimerInfo) File

func (timer *TimerInfo) File() string

File returns the path to the *.timer file

type Type

type Type string

Type represents the kind of snap (app, core, gadget, os, kernel, snapd)

const (
	TypeApp    Type = "app"
	TypeGadget Type = "gadget"
	TypeKernel Type = "kernel"
	TypeBase   Type = "base"
	TypeSnapd  Type = "snapd"

	// FIXME: this really should be TypeCore
	TypeOS Type = "os"
)

The various types of snap parts we support

func (Type) SortsBefore

func (m Type) SortsBefore(other Type) bool

func (*Type) UnmarshalJSON

func (m *Type) UnmarshalJSON(data []byte) error

UnmarshalJSON sets *m to a copy of data.

func (*Type) UnmarshalYAML

func (m *Type) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML so Type implements yaml's Unmarshaler interface

Directories

Path Synopsis
Package naming implements naming constraints and concepts for snaps and their elements.
Package naming implements naming constraints and concepts for snaps and their elements.
Package quota defines state structures for resource quota groups for snaps.
Package quota defines state structures for resource quota groups for snaps.
Package snaptest contains helper functions for mocking snaps.
Package snaptest contains helper functions for mocking snaps.

Jump to

Keyboard shortcuts

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