container

package
v17.12.0-ce-rc4+incomp... Latest Latest
Warning

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

Go to latest
Published: Mar 23, 2020 License: Apache-2.0 Imports: 56 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultStopTimeout is the timeout (in seconds) for the syscall signal used to stop a container.
	DefaultStopTimeout = 10
)

Variables

View Source
var (
	// ErrNameReserved is an error which is returned when a name is requested to be reserved that already is reserved
	ErrNameReserved = errors.New("name is reserved")
	// ErrNameNotReserved is an error which is returned when trying to find a name that is not reserved
	ErrNameNotReserved = errors.New("name is not reserved")
)

Functions

func GetSandboxPortMapInfo added in v1.11.2

func GetSandboxPortMapInfo(sb libnetwork.Sandbox) nat.PortMap

GetSandboxPortMapInfo retrieves the current port-mapping programmed for the given sandbox

func IsValidHealthString added in v1.13.0

func IsValidHealthString(s string) bool

IsValidHealthString checks if the provided string is a valid container health status or not.

func IsValidStateString

func IsValidStateString(s string) bool

IsValidStateString checks if the provided string is a valid container state or not.

func ReplaceOrAppendEnvValues

func ReplaceOrAppendEnvValues(defaults, overrides []string) []string

ReplaceOrAppendEnvValues returns the defaults with the overrides either replaced by env key or appended to the list

Types

type Container

type Container struct {
	StreamConfig *stream.Config
	// embed for Container to support states directly.
	*State          `json:"State"`          // Needed for Engine API version <= 1.11
	Root            string                  `json:"-"` // Path to the "home" of the container, including metadata.
	BaseFS          containerfs.ContainerFS `json:"-"` // interface containing graphdriver mount
	RWLayer         layer.RWLayer           `json:"-"`
	ID              string
	Created         time.Time
	Managed         bool
	Path            string
	Args            []string
	Config          *containertypes.Config
	ImageID         image.ID `json:"Image"`
	NetworkSettings *network.Settings
	LogPath         string
	Name            string
	Driver          string
	OS              string
	// MountLabel contains the options for the 'mount' command
	MountLabel             string
	ProcessLabel           string
	RestartCount           int
	HasBeenStartedBefore   bool
	HasBeenManuallyStopped bool // used for unless-stopped restart policy
	MountPoints            map[string]*volume.MountPoint
	HostConfig             *containertypes.HostConfig `json:"-"` // do not serialize the host config in the json, otherwise we'll make the container unportable
	ExecCommands           *exec.Store                `json:"-"`
	DependencyStore        agentexec.DependencyGetter `json:"-"`
	SecretReferences       []*swarmtypes.SecretReference
	ConfigReferences       []*swarmtypes.ConfigReference
	// logDriver for closing
	LogDriver logger.Logger  `json:"-"`
	LogCopier *logger.Copier `json:"-"`

	// Fields here are specific to Unix platforms
	AppArmorProfile string
	HostnamePath    string
	HostsPath       string
	ShmPath         string
	ResolvConfPath  string
	SeccompProfile  string
	NoNewPrivileges bool

	// Fields here are specific to Windows
	NetworkSharedContainerID string   `json:"-"`
	SharedEndpointList       []string `json:"-"`
	// contains filtered or unexported fields
}

Container holds the structure defining a container object.

func NewBaseContainer

func NewBaseContainer(id, root string) *Container

NewBaseContainer creates a new container with its basic configuration.

func (*Container) AddMountPointWithVolume

func (container *Container) AddMountPointWithVolume(destination string, vol volume.Volume, rw bool)

AddMountPointWithVolume adds a new mount point configured with a volume to the container.

func (*Container) BuildCreateEndpointOptions

func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epConfig *networktypes.EndpointSettings, sb libnetwork.Sandbox, daemonDNS []string) ([]libnetwork.EndpointOption, error)

BuildCreateEndpointOptions builds endpoint options from a given network.

func (*Container) BuildEndpointInfo

func (container *Container) BuildEndpointInfo(n libnetwork.Network, ep libnetwork.Endpoint) error

BuildEndpointInfo sets endpoint-related fields on container.NetworkSettings based on the provided network and endpoint.

func (*Container) BuildHostnameFile

func (container *Container) BuildHostnameFile() error

BuildHostnameFile writes the container's hostname file.

func (*Container) BuildJoinOptions

func (container *Container) BuildJoinOptions(n named) ([]libnetwork.EndpointOption, error)

BuildJoinOptions builds endpoint Join options from a given network.

func (*Container) CancelAttachContext added in v1.11.0

func (container *Container) CancelAttachContext()

CancelAttachContext cancels attach context. All attach calls should detach after this call.

func (*Container) CheckpointDir added in v1.13.0

func (container *Container) CheckpointDir() string

CheckpointDir returns the directory checkpoints are stored in

func (*Container) CheckpointTo

func (container *Container) CheckpointTo(store ViewDB) error

CheckpointTo makes the Container's current state visible to queries, and persists state. Callers must hold a Container lock.

func (*Container) CloseStreams added in v1.12.5

func (container *Container) CloseStreams() error

CloseStreams closes the container's stdio streams

func (*Container) ConfigFilePath

func (container *Container) ConfigFilePath(configRef swarmtypes.ConfigReference) string

ConfigFilePath returns the path to the on-disk location of a config.

func (*Container) ConfigMounts

func (container *Container) ConfigMounts() []Mount

ConfigMounts returns the mounts for configs.

func (*Container) ConfigPath

func (container *Container) ConfigPath() (string, error)

ConfigPath returns the path to the container's JSON config

func (*Container) ConfigsDirPath

func (container *Container) ConfigsDirPath() string

ConfigsDirPath returns the path to the directory where configs are stored on disk.

func (*Container) CopyImagePathContent

func (container *Container) CopyImagePathContent(v volume.Volume, destination string) error

CopyImagePathContent copies files in destination to the volume.

func (*Container) CreateDaemonEnvironment

func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string) []string

CreateDaemonEnvironment creates a new environment variable slice for this container.

func (*Container) DetachAndUnmount added in v1.13.0

func (container *Container) DetachAndUnmount(volumeEventLog func(name, action string, attributes map[string]string)) error

DetachAndUnmount uses a detached mount on all mount destinations, then unmounts each volume normally. This is used from daemon/archive for `docker cp`

func (*Container) EnableServiceDiscoveryOnDefaultNetwork added in v1.13.0

func (container *Container) EnableServiceDiscoveryOnDefaultNetwork() bool

EnableServiceDiscoveryOnDefaultNetwork Enable service discovery on default network

func (*Container) ExitOnNext

func (container *Container) ExitOnNext()

ExitOnNext signals to the monitor that it should not restart the container after we send the kill signal.

func (*Container) FromDisk

func (container *Container) FromDisk() error

FromDisk loads the container configuration stored in the host.

func (*Container) FullHostname added in v1.11.0

func (container *Container) FullHostname() string

FullHostname returns hostname and optional domain appended to it.

func (*Container) GetEndpointInNetwork

func (container *Container) GetEndpointInNetwork(n libnetwork.Network) (libnetwork.Endpoint, error)

GetEndpointInNetwork returns the container's endpoint to the provided network.

func (*Container) GetExecIDs

func (container *Container) GetExecIDs() []string

GetExecIDs returns the list of exec commands running on the container.

func (*Container) GetMountLabel

func (container *Container) GetMountLabel() string

GetMountLabel returns the mounting label for the container. This label is empty if the container is privileged.

func (*Container) GetMountPoints

func (container *Container) GetMountPoints() []types.MountPoint

GetMountPoints gives a platform specific transformation to types.MountPoint. Callers must hold a Container lock.

func (*Container) GetProcessLabel

func (container *Container) GetProcessLabel() string

GetProcessLabel returns the process label for the container.

func (*Container) GetResourcePath

func (container *Container) GetResourcePath(path string) (string, error)

GetResourcePath evaluates `path` in the scope of the container's BaseFS, with proper path sanitisation. Symlinks are all scoped to the BaseFS of the container, as though the container's BaseFS was `/`.

The BaseFS of a container is the host-facing path which is bind-mounted as `/` inside the container. This method is essentially used to access a particular path inside the container as though you were a process in that container.

NOTE: The returned path is *only* safely scoped inside the container's BaseFS

if no component of the returned path changes (such as a component
symlinking to a different path) between using this method and using the
path. See symlink.FollowSymlinkInScope for more details.

func (*Container) GetRootResourcePath

func (container *Container) GetRootResourcePath(path string) (string, error)

GetRootResourcePath evaluates `path` in the scope of the container's root, with proper path sanitisation. Symlinks are all scoped to the root of the container, as though the container's root was `/`.

The root of a container is the host-facing configuration metadata directory. Only use this method to safely access the container's `container.json` or other metadata files. If in doubt, use container.GetResourcePath.

NOTE: The returned path is *only* safely scoped inside the container's root

if no component of the returned path changes (such as a component
symlinking to a different path) between using this method and using the
path. See symlink.FollowSymlinkInScope for more details.

func (*Container) HasMountFor

func (container *Container) HasMountFor(path string) bool

HasMountFor checks if path is a mountpoint

func (*Container) HostConfigPath

func (container *Container) HostConfigPath() (string, error)

HostConfigPath returns the path to the container's JSON hostconfig

func (*Container) InitAttachContext added in v1.11.0

func (container *Container) InitAttachContext() context.Context

InitAttachContext initializes or returns existing context for attach calls to track container liveness.

func (*Container) InitDNSHostConfig

func (container *Container) InitDNSHostConfig()

InitDNSHostConfig ensures that the dns fields are never nil. New containers don't ever have those fields nil, but pre created containers can still have those nil values. The non-recommended host configuration in the start api can make these fields nil again, this corrects that issue until we remove that behavior for good. See https://github.com/docker/docker/pull/17779 for a more detailed explanation on why we don't want that.

func (*Container) InitializeStdio added in v1.12.4

func (container *Container) InitializeStdio(iop *libcontainerd.IOPipe) (cio.IO, error)

InitializeStdio is called by libcontainerd to connect the stdio.

func (*Container) IpcMounts

func (container *Container) IpcMounts() []Mount

IpcMounts returns the list of IPC mounts

func (*Container) IsDestinationMounted

func (container *Container) IsDestinationMounted(destination string) bool

IsDestinationMounted checks whether a path is mounted on the container or not.

func (*Container) NetworkMounts

func (container *Container) NetworkMounts() []Mount

NetworkMounts returns the list of network mounts.

func (*Container) Reset added in v1.11.0

func (container *Container) Reset(lock bool)

Reset puts a container into a state where it can be restarted again.

func (*Container) ResetRestartManager added in v1.13.0

func (container *Container) ResetRestartManager(resetCount bool)

ResetRestartManager initializes new restartmanager based on container config

func (*Container) ResolvePath

func (container *Container) ResolvePath(path string) (resolvedPath, absPath string, err error)

ResolvePath resolves the given path in the container to a resource on the host. Returns a resolved path (absolute path to the resource on the host), the absolute path to the resource relative to the container's rootfs, and an error if the path points to outside the container's rootfs.

func (*Container) RestartManager added in v1.11.0

func (container *Container) RestartManager() restartmanager.RestartManager

RestartManager returns the current restartmanager instance connected to container.

func (*Container) SecretFilePath

func (container *Container) SecretFilePath(secretRef swarmtypes.SecretReference) string

SecretFilePath returns the path to the location of a secret on the host.

func (*Container) SecretMountPath added in v1.13.0

func (container *Container) SecretMountPath() string

SecretMountPath returns the path of the secret mount for the container

func (*Container) SecretMounts

func (container *Container) SecretMounts() []Mount

SecretMounts returns the mounts for the secret path.

func (*Container) SetupWorkingDirectory

func (container *Container) SetupWorkingDirectory(rootIDs idtools.IDPair) error

SetupWorkingDirectory sets up the container's working directory as set in container.Config.WorkingDir

func (*Container) ShmResourcePath

func (container *Container) ShmResourcePath() (string, error)

ShmResourcePath returns path to shm

func (*Container) ShouldRestart

func (container *Container) ShouldRestart() bool

ShouldRestart decides whether the daemon should restart the container or not. This is based on the container's restart policy.

func (*Container) StartLogger

func (container *Container) StartLogger() (logger.Logger, error)

StartLogger starts a new logger driver for the container.

func (*Container) StatPath

func (container *Container) StatPath(resolvedPath, absPath string) (stat *types.ContainerPathStat, err error)

StatPath is the unexported version of StatPath. Locks and mounts should be acquired before calling this method and the given path should be fully resolved to a path on the host corresponding to the given absolute path inside the container.

func (*Container) StderrPipe added in v1.12.5

func (container *Container) StderrPipe() io.ReadCloser

StderrPipe gets the stderr stream of the container

func (*Container) StdinPipe added in v1.12.5

func (container *Container) StdinPipe() io.WriteCloser

StdinPipe gets the stdin stream of the container

func (*Container) StdoutPipe added in v1.12.5

func (container *Container) StdoutPipe() io.ReadCloser

StdoutPipe gets the stdout stream of the container

func (*Container) StopSignal

func (container *Container) StopSignal() int

StopSignal returns the signal used to stop the container.

func (*Container) StopTimeout added in v1.13.0

func (container *Container) StopTimeout() int

StopTimeout returns the timeout (in seconds) used to stop the container.

func (*Container) TmpfsMounts

func (container *Container) TmpfsMounts() ([]Mount, error)

TmpfsMounts returns the list of tmpfs mounts

func (*Container) TrySetNetworkMount

func (container *Container) TrySetNetworkMount(destination string, path string) bool

TrySetNetworkMount attempts to set the network mounts given a provided destination and the path to use for it; return true if the given destination was a network mount file

func (*Container) UnmountIpcMount

func (container *Container) UnmountIpcMount(unmount func(pth string) error) error

UnmountIpcMount uses the provided unmount function to unmount shm if it was mounted

func (*Container) UnmountSecrets added in v1.13.0

func (container *Container) UnmountSecrets() error

UnmountSecrets unmounts the local tmpfs for secrets

func (*Container) UnmountVolumes

func (container *Container) UnmountVolumes(volumeEventLog func(name, action string, attributes map[string]string)) error

UnmountVolumes unmounts all volumes

func (*Container) UpdateContainer

func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error

UpdateContainer updates configuration of a container. Callers must hold a Lock on the Container.

func (*Container) UpdateJoinInfo

func (container *Container) UpdateJoinInfo(n named, ep libnetwork.Endpoint) error

UpdateJoinInfo updates network settings when container joins network n with endpoint ep.

func (*Container) UpdateMonitor added in v1.11.0

func (container *Container) UpdateMonitor(restartPolicy containertypes.RestartPolicy)

UpdateMonitor updates monitor configure for running container

func (*Container) UpdateSandboxNetworkSettings

func (container *Container) UpdateSandboxNetworkSettings(sb libnetwork.Sandbox) error

UpdateSandboxNetworkSettings updates the sandbox ID and Key.

func (*Container) WriteHostConfig

func (container *Container) WriteHostConfig() (*containertypes.HostConfig, error)

WriteHostConfig saves the host configuration on disk for the container, and returns a deep copy of the saved object. Callers must hold a Container lock.

type ExitStatus added in v1.11.0

type ExitStatus struct {
	// The exit code with which the container exited.
	ExitCode int

	// Whether the container encountered an OOM.
	OOMKilled bool

	// Time at which the container died
	ExitedAt time.Time
}

ExitStatus provides exit reasons for a container.

type Health added in v1.12.0

type Health struct {
	types.Health
	// contains filtered or unexported fields
}

Health holds the current container health-check state

func (*Health) CloseMonitorChannel added in v1.12.0

func (s *Health) CloseMonitorChannel()

CloseMonitorChannel closes any existing monitor channel.

func (*Health) OpenMonitorChannel added in v1.12.0

func (s *Health) OpenMonitorChannel() chan struct{}

OpenMonitorChannel creates and returns a new monitor channel. If there already is one, it returns nil.

func (*Health) SetStatus

func (s *Health) SetStatus(new string)

SetStatus writes the current status to the underlying health structure, obeying the locking semantics.

Status may be set directly if another lock is used.

func (*Health) Status

func (s *Health) Status() string

Status returns the current health status.

Note that this takes a lock and the value may change after being read.

func (*Health) String added in v1.12.0

func (s *Health) String() string

String returns a human-readable description of the health-check state

type History

type History []*Container

History is a convenience type for storing a list of containers, sorted by creation date in descendant order.

func (*History) Len

func (history *History) Len() int

Len returns the number of containers in the history.

func (*History) Less

func (history *History) Less(i, j int) bool

Less compares two containers and returns true if the second one was created before the first one.

func (*History) Swap

func (history *History) Swap(i, j int)

Swap switches containers i and j positions in the history.

type Mount added in v1.11.0

type Mount struct {
	Source      string `json:"source"`
	Destination string `json:"destination"`
	Writable    bool   `json:"writable"`
	Data        string `json:"data"`
	Propagation string `json:"mountpropagation"`
}

Mount contains information for a mount operation.

type NoSuchContainerError

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

NoSuchContainerError indicates that the container wasn't found in the database.

func (NoSuchContainerError) Error

func (e NoSuchContainerError) Error() string

Error satisfies the error interface.

type Snapshot

type Snapshot struct {
	types.Container

	// additional info queries need to filter on
	// preserve nanosec resolution for queries
	CreatedAt    time.Time
	StartedAt    time.Time
	Name         string
	Pid          int
	ExitCode     int
	Running      bool
	Paused       bool
	Managed      bool
	ExposedPorts nat.PortSet
	PortBindings nat.PortSet
	Health       string
	HostConfig   struct {
		Isolation string
	}
}

Snapshot is a read only view for Containers. It holds all information necessary to serve container queries in a versioned ACID in-memory store.

type State

type State struct {
	sync.Mutex
	// Note that `Running` and `Paused` are not mutually exclusive:
	// When pausing a container (on Linux), the cgroups freezer is used to suspend
	// all processes in the container. Freezing the process requires the process to
	// be running. As a result, paused containers are both `Running` _and_ `Paused`.
	Running           bool
	Paused            bool
	Restarting        bool
	OOMKilled         bool
	RemovalInProgress bool // Not need for this to be persistent on disk.
	Dead              bool
	Pid               int
	ExitCodeValue     int    `json:"ExitCode"`
	ErrorMsg          string `json:"Error"` // contains last known error during container start or remove
	StartedAt         time.Time
	FinishedAt        time.Time
	Health            *Health
	// contains filtered or unexported fields
}

State holds the current container state, and has methods to get and set the state. Container has an embed, which allows all of the functions defined against State to run against Container.

func NewState

func NewState() *State

NewState creates a default state object with a fresh channel for state changes.

func (*State) Err

func (s *State) Err() error

Err returns an error if there is one.

func (*State) ExitCode

func (s *State) ExitCode() int

ExitCode returns current exitcode for the state. Take lock before if state may be shared.

func (*State) GetPID

func (s *State) GetPID() int

GetPID holds the process id of a container.

func (*State) HealthString added in v1.13.0

func (s *State) HealthString() string

HealthString returns a single string to describe health status.

func (*State) IsDead

func (s *State) IsDead() bool

IsDead returns whether the Dead flag is set. Used by Container to check whether a container is dead.

func (*State) IsPaused

func (s *State) IsPaused() bool

IsPaused returns whether the container is paused or not.

func (*State) IsRemovalInProgress

func (s *State) IsRemovalInProgress() bool

IsRemovalInProgress returns whether the RemovalInProgress flag is set. Used by Container to check whether a container is being removed.

func (*State) IsRestarting

func (s *State) IsRestarting() bool

IsRestarting returns whether the container is restarting or not.

func (*State) IsRunning

func (s *State) IsRunning() bool

IsRunning returns whether the running flag is set. Used by Container to check whether a container is running.

func (*State) ResetRemovalInProgress

func (s *State) ResetRemovalInProgress()

ResetRemovalInProgress makes the RemovalInProgress state to false.

func (*State) SetDead

func (s *State) SetDead()

SetDead sets the container state to "dead"

func (*State) SetError

func (s *State) SetError(err error)

SetError sets the container's error state. This is useful when we want to know the error that occurred when container transits to another state when inspecting it

func (*State) SetExitCode added in v1.12.0

func (s *State) SetExitCode(ec int)

SetExitCode sets current exitcode for the state. Take lock before if state may be shared.

func (*State) SetRemovalError

func (s *State) SetRemovalError(err error)

SetRemovalError is to be called in case a container remove failed. It sets an error and closes the internal waitRemove channel to unblock callers waiting for the container to be removed.

func (*State) SetRemovalInProgress

func (s *State) SetRemovalInProgress() bool

SetRemovalInProgress sets the container state as being removed. It returns true if the container was already in that state.

func (*State) SetRemoved

func (s *State) SetRemoved()

SetRemoved assumes this container is already in the "dead" state and closes the internal waitRemove channel to unblock callers waiting for a container to be removed.

func (*State) SetRestarting

func (s *State) SetRestarting(exitStatus *ExitStatus)

SetRestarting sets the container state to "restarting" without locking. It also sets the container PID to 0.

func (*State) SetRunning

func (s *State) SetRunning(pid int, initial bool)

SetRunning sets the state of the container to "running".

func (*State) SetStopped

func (s *State) SetStopped(exitStatus *ExitStatus)

SetStopped sets the container state to "stopped" without locking.

func (*State) StateString

func (s *State) StateString() string

StateString returns a single string to describe state

func (*State) String

func (s *State) String() string

String returns a human-readable description of the state

func (*State) Wait

func (s *State) Wait(ctx context.Context, condition WaitCondition) <-chan StateStatus

Wait waits until the container is in a certain state indicated by the given condition. A context must be used for cancelling the request, controlling timeouts, and avoiding goroutine leaks. Wait must be called without holding the state lock. Returns a channel from which the caller will receive the result. If the container exited on its own, the result's Err() method will be nil and its ExitCode() method will return the container's exit code, otherwise, the results Err() method will return an error indicating why the wait operation failed.

type StateStatus added in v1.13.0

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

StateStatus is used to return container wait results. Implements exec.ExitCode interface. This type is needed as State include a sync.Mutex field which make copying it unsafe.

func (StateStatus) Err

func (s StateStatus) Err() error

Err returns current error for the state. Returns nil if the container had exited on its own.

func (StateStatus) ExitCode added in v1.13.0

func (s StateStatus) ExitCode() int

ExitCode returns current exitcode for the state.

type Store

type Store interface {
	// Add appends a new container to the store.
	Add(string, *Container)
	// Get returns a container from the store by the identifier it was stored with.
	Get(string) *Container
	// Delete removes a container from the store by the identifier it was stored with.
	Delete(string)
	// List returns a list of containers from the store.
	List() []*Container
	// Size returns the number of containers in the store.
	Size() int
	// First returns the first container found in the store by a given filter.
	First(StoreFilter) *Container
	// ApplyAll calls the reducer function with every container in the store.
	ApplyAll(StoreReducer)
}

Store defines an interface that any container store must implement.

func NewMemoryStore

func NewMemoryStore() Store

NewMemoryStore initializes a new memory store.

type StoreFilter

type StoreFilter func(*Container) bool

StoreFilter defines a function to filter container in the store.

type StoreReducer

type StoreReducer func(*Container)

StoreReducer defines a function to manipulate containers in the store

type View

type View interface {
	All() ([]Snapshot, error)
	Get(id string) (*Snapshot, error)

	GetID(name string) (string, error)
	GetAllNames() map[string][]string
}

View can be used by readers to avoid locking

type ViewDB

type ViewDB interface {
	Snapshot() View
	Save(*Container) error
	Delete(*Container) error

	ReserveName(name, containerID string) error
	ReleaseName(name string) error
}

ViewDB provides an in-memory transactional (ACID) container Store

func NewViewDB

func NewViewDB() (ViewDB, error)

NewViewDB provides the default implementation, with the default schema

type WaitCondition

type WaitCondition int

WaitCondition is an enum type for different states to wait for.

const (
	WaitConditionNotRunning WaitCondition = iota
	WaitConditionNextExit
	WaitConditionRemoved
)

Possible WaitCondition Values.

WaitConditionNotRunning (default) is used to wait for any of the non-running states: "created", "exited", "dead", "removing", or "removed".

WaitConditionNextExit is used to wait for the next time the state changes to a non-running state. If the state is currently "created" or "exited", this would cause Wait() to block until either the container runs and exits or is removed.

WaitConditionRemoved is used to wait for the container to be removed.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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