cnab

package
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2024 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ActionInstall   = cnabclaims.ActionInstall
	ActionUpgrade   = cnabclaims.ActionUpgrade
	ActionUninstall = cnabclaims.ActionUninstall
	ActionUnknown   = cnabclaims.ActionUnknown

	StatusSucceeded = cnabclaims.StatusSucceeded
	StatusCanceled  = cnabclaims.StatusCanceled
	StatusFailed    = cnabclaims.StatusFailed
	StatusRunning   = cnabclaims.StatusRunning
	StatusPending   = cnabclaims.StatusPending
	StatusUnknown   = cnabclaims.StatusUnknown

	OutputInvocationImageLogs = cnabclaims.OutputInvocationImageLogs
)
View Source
const (
	// DependenciesV1ExtensionShortHand is the short suffix of the DependenciesV1ExtensionKey
	DependenciesV1ExtensionShortHand = "dependencies"

	// DependenciesV1ExtensionKey represents the full key for the DependenciesV1Extension.
	DependenciesV1ExtensionKey = OfficialExtensionsPrefix + DependenciesV1ExtensionShortHand

	// DependenciesV1Schema represents the schema for the Dependencies Extension
	DependenciesV1Schema = "https://cnab.io/v1/dependencies.schema.json"
)
View Source
const (
	// DependenciesV2ExtensionShortHand is the short suffix of the DependenciesV2ExtensionKey
	DependenciesV2ExtensionShortHand = "dependencies@v2"

	// DependenciesV2ExtensionKey represents the full key for the DependenciesV2Extension.
	DependenciesV2ExtensionKey = "org.getporter." + DependenciesV2ExtensionShortHand

	// DependenciesV2Schema represents the schema for the DependenciesV2 Extension
	DependenciesV2Schema = "https://porter.sh/extensions/dependencies/v2/schema.json"
)
View Source
const (
	// DockerExtensionShortHand is the short suffix of the DockerExtensionKey.
	DockerExtensionShortHand = "docker"

	// DockerExtensionKey represents the full key for the Docker Extension
	DockerExtensionKey = OfficialExtensionsPrefix + DockerExtensionShortHand

	// DockerExtensionSchema represents the schema for the Docker Extension
	DockerExtensionSchema = "schema/io-cnab-docker.schema.json"
)
View Source
const (
	// PorterExtension is the key for all Porter configuration stored in the custom section of bundles.
	// Since it was defined before we had porter.sh, it uses our legacy domain.
	PorterExtension = "sh.porter"

	// OfficialExtensionsPrefix is the prefix applied to extensions defined in the CNAB spec.
	OfficialExtensionsPrefix = "io.cnab."

	// PorterInternal is the identifier that we put in the $comment of fields in bundle.json
	// to indicate that it's just for Porter and shouldn't be visible to the end users.
	PorterInternal = "porter-internal"
)
View Source
const (
	// FileParameterExtensionShortHand is the short suffix of the FileParameterExtensionKey.
	FileParameterExtensionShortHand = "file-parameters"

	// FileParameterExtensionKey represents the full key for the File Parameter extension.
	// This uses the legacy porter domain and cannot be changed to use our new domain.
	// Going forward extensions should use org.getporter instead.
	FileParameterExtensionKey = "sh.porter." + FileParameterExtensionShortHand
)
View Source
const (
	// ParameterSourcesExtensionShortHand is the short suffix of the ParameterSourcesExtensionKey.
	ParameterSourcesExtensionShortHand = "parameter-sources"

	// ParameterSourcesExtensionKey represents the full key for the Parameter Sources Extension.
	ParameterSourcesExtensionKey = OfficialExtensionsPrefix + ParameterSourcesExtensionShortHand

	// ParameterSourcesExtensionSchema represents the schema for the Docker Extension.
	ParameterSourcesSchema = "https://cnab.io/v1/parameter-sources.schema.json"
	// ParameterSourceTypeOutput defines a type of parameter source that is provided by a bundle output.
	ParameterSourceTypeOutput = "output"
	// ParameterSourceTypeDependencyOutput defines a type of parameter source that is provided by a bundle's dependency
	// output.
	ParameterSourceTypeDependencyOutput = "dependencies.output"
)
View Source
const SupportedVersion = "1.0.0 || 1.1.0 || 1.2.0"

Variables

View Source
var DefaultSchemaVersion = semver.MustParse(string(BundleSchemaVersion()))
View Source
var DependenciesV1Extension = RequiredExtension{
	Shorthand: DependenciesV1ExtensionShortHand,
	Key:       DependenciesV1ExtensionKey,
	Schema:    DependenciesV1Schema,
	Reader: func(b ExtendedBundle) (interface{}, error) {
		return b.DependencyV1Reader()
	},
}

DependenciesV1Extension represents the required extension to enable dependencies

View Source
var DependenciesV2Extension = RequiredExtension{
	Shorthand: DependenciesV2ExtensionShortHand,
	Key:       DependenciesV2ExtensionKey,
	Schema:    DependenciesV2Schema,
	Reader: func(b ExtendedBundle) (interface{}, error) {
		return b.DependencyV2Reader()
	},
}

DependenciesV2Extension represents the required extension to enable dependencies

View Source
var DockerExtension = RequiredExtension{
	Shorthand: DockerExtensionShortHand,
	Key:       DockerExtensionKey,
	Schema:    "schema/io-cnab-docker.schema.json",
	Reader:    DockerExtensionReader,
}

DockerExtension represents a required extension enabling access to the host Docker daemon

FileParameterExtension represents a required extension that indicates that the bundle requires support for parameters of type "file"

ParameterSourcesExtension represents a required extension that specifies how to default parameter values.

SupportedExtensions represent a listing of the current required extensions that Porter supports

Functions

func DockerExtensionReader added in v1.0.1

func DockerExtensionReader(bun ExtendedBundle) (interface{}, error)

DockerExtensionReader is a Reader for the DockerExtension, which reads from the applicable section in the provided bundle and returns the raw data in the form of an interface

func FileParameterReader added in v1.0.1

func FileParameterReader(b ExtendedBundle) (interface{}, error)

FileParameterReader is a Reader for the FileParameterExtension. The extension does not have any data, its presence indicates that parameters of type "file" should be supported by the tooling.

func ParameterSourcesReader added in v1.0.1

func ParameterSourcesReader(bun ExtendedBundle) (interface{}, error)

ParameterSourcesReader is a Reader for the ParameterSourcesExtension, which reads from the applicable section in the provided bundle and returns the raw data in the form of an interface

func WriteParameterToString added in v1.0.1

func WriteParameterToString(paramName string, value interface{}) (string, error)

WriteParameterToString changes a parameter's value from its type as defined by the bundle to its runtime string representation. The value should have already been converted to its bundle representation by calling ConvertParameterValue.

Types

type BundleReference added in v1.0.1

type BundleReference struct {
	Reference     OCIReference
	Digest        digest.Digest
	Definition    ExtendedBundle
	RelocationMap relocation.ImageRelocationMap
}

func (BundleReference) AddToTrace added in v1.0.1

func (r BundleReference) AddToTrace(cxt context.Context)

AddToTrace appends the bundle reference attributes to the current span.

func (BundleReference) String added in v1.0.1

func (r BundleReference) String() string

type Claim added in v1.0.1

type Claim = cnabclaims.Claim

type DependencyLock added in v1.0.1

type DependencyLock struct {
	Alias        string
	Reference    string
	SharingMode  bool
	SharingGroup string
}

type DependencyOutputParameterSource added in v1.0.1

type DependencyOutputParameterSource struct {
	Dependency string `json:"dependency" mapstructure:"dependency"`
	OutputName string `json:"name" mapstructure:"name"`
}

DependencyOutputParameterSource represents a parameter that is set using the value from a bundle's dependency output.

type Docker added in v1.0.1

type Docker struct {
	// Privileged represents whether or not the Docker container should run as --privileged
	Privileged bool `json:"privileged,omitempty"`
}

Docker describes the set of custom extension metadata associated with the Docker extension

type ExtendedBundle added in v1.0.1

type ExtendedBundle struct {
	bundle.Bundle
}

ExtendedBundle is a bundle that has typed access to extensions declared in the bundle, allowing quick type-safe access to custom extensions from the CNAB spec.

func LoadBundle

func LoadBundle(c *portercontext.Context, bundleFile string) (ExtendedBundle, error)

LoadBundle from the specified filepath.

func NewBundle added in v1.0.1

func NewBundle(bundle bundle.Bundle) ExtendedBundle

NewBundle creates an ExtendedBundle from a given bundle.

func ReadTestBundle

func ReadTestBundle(t *testing.T, path string) ExtendedBundle

func (*ExtendedBundle) BuildPrerequisiteInstallationName added in v1.0.16

func (b *ExtendedBundle) BuildPrerequisiteInstallationName(installation string, dependency string) string

BuildPrerequisiteInstallationName generates the name of a prerequisite dependency installation.

func (ExtendedBundle) ConvertParameterValue added in v1.0.1

func (b ExtendedBundle) ConvertParameterValue(key string, value interface{}) (interface{}, error)

ConvertParameterValue converts a parameter's value from an unknown type, it could be a string from stdin or another Go type, into the type of the parameter as defined in the bundle.

func (ExtendedBundle) DependencyV1Reader added in v1.0.1

func (b ExtendedBundle) DependencyV1Reader() (interface{}, error)

DependencyV1Reader is a Reader for the DependenciesV1Extension, which reads from the applicable section in the provided bundle and returns the raw data in the form of an interface

func (ExtendedBundle) DependencyV2Reader added in v1.0.12

func (b ExtendedBundle) DependencyV2Reader() (interface{}, error)

DependencyV2Reader is a Reader for the DependenciesV2Extension, which reads from the applicable section in the provided bundle and returns the raw data in the form of an interface

func (ExtendedBundle) DockerExtensionReader added in v1.0.1

func (b ExtendedBundle) DockerExtensionReader() (interface{}, error)

DockerExtensionReader is a Reader for the DockerExtension, which reads from the applicable section in the provided bundle and returns the raw data in the form of an interface

func (ExtendedBundle) FileParameterReader added in v1.0.1

func (b ExtendedBundle) FileParameterReader() (interface{}, error)

FileParameterReader is a Reader for the FileParameterExtension. The extension does not have any data, its presence indicates that parameters of type "file" should be supported by the tooling.

func (ExtendedBundle) GetParameterType added in v1.0.1

func (b ExtendedBundle) GetParameterType(def *definition.Schema) string

GetParameterType determines the type of parameter accounting for Porter-specific parameter types like file.

func (ExtendedBundle) GetReferencedRegistries added in v1.0.1

func (b ExtendedBundle) GetReferencedRegistries() ([]string, error)

GetReferencedRegistries identifies all OCI registries used by the bundle from both the bundle image and the referenced images.

func (ExtendedBundle) HasDependenciesV1 added in v1.0.1

func (b ExtendedBundle) HasDependenciesV1() bool

HasDependenciesV1 returns whether the bundle has parameter sources defined.

func (ExtendedBundle) HasDependenciesV2 added in v1.0.12

func (b ExtendedBundle) HasDependenciesV2() bool

HasDependenciesV2 returns whether the bundle has v2 dependencies defined.

func (ExtendedBundle) HasParameterSources added in v1.0.1

func (b ExtendedBundle) HasParameterSources() bool

HasParameterSources returns whether or not the bundle has parameter sources defined.

func (ExtendedBundle) IsFileType added in v1.0.1

func (b ExtendedBundle) IsFileType(def *definition.Schema) bool

IsFileType determines if the parameter/credential is of type "file".

func (ExtendedBundle) IsInternalOutput added in v1.0.1

func (b ExtendedBundle) IsInternalOutput(name string) bool

IsInternalOutput determines if the provided output is internal to Porter after analyzing the provided bundle.

func (ExtendedBundle) IsInternalParameter added in v1.0.1

func (b ExtendedBundle) IsInternalParameter(name string) bool

IsInternalParameter determines if the provided parameter is internal to Porter after analyzing the provided bundle.

func (ExtendedBundle) IsPorterBundle added in v1.0.1

func (b ExtendedBundle) IsPorterBundle() bool

IsPorterBundle determines if the bundle was created by Porter.

func (ExtendedBundle) IsSensitiveParameter added in v1.0.1

func (b ExtendedBundle) IsSensitiveParameter(param string) bool

IsSensitiveParameter determines if the parameter contains a sensitive value.

func (ExtendedBundle) ParameterHasSource added in v1.0.1

func (b ExtendedBundle) ParameterHasSource(paramName string) bool

ParameterHasSource determines if the specified parameter has a parameter source defined.

func (ExtendedBundle) ParameterSourcesReader added in v1.0.1

func (b ExtendedBundle) ParameterSourcesReader() (interface{}, error)

ParameterSourcesReader is a Reader for the ParameterSourcesExtension, which reads from the applicable section in the provided bundle and returns the raw data in the form of an interface

func (ExtendedBundle) ProcessRequiredExtensions added in v1.0.1

func (b ExtendedBundle) ProcessRequiredExtensions() (ProcessedExtensions, error)

ProcessRequiredExtensions checks all required extensions in the provided bundle and makes sure Porter supports them.

If an unsupported required extension is found, an error is returned.

For each supported required extension, the configuration for that extension is read and returned in the form of a map of the extension name to the extension configuration

func (ExtendedBundle) ReadDependenciesV1 added in v1.0.1

func (b ExtendedBundle) ReadDependenciesV1() (depsv1ext.Dependencies, error)

ReadDependenciesV1 is a convenience method for returning a bonafide Dependencies reference after reading from the applicable section from the provided bundle

func (ExtendedBundle) ReadDependenciesV2 added in v1.0.12

func (b ExtendedBundle) ReadDependenciesV2() (v2.Dependencies, error)

ReadDependenciesV2 is a convenience method for returning a bonafide DependenciesV2 reference after reading from the applicable section from the provided bundle

func (ExtendedBundle) ReadParameterSources added in v1.0.1

func (b ExtendedBundle) ReadParameterSources() (ParameterSources, error)

ReadParameterSources is a convenience method for returning a bonafide ParameterSources reference after reading from the applicable section from the provided bundle

func (*ExtendedBundle) ResolveDependencies added in v1.0.16

func (b *ExtendedBundle) ResolveDependencies(bun ExtendedBundle) ([]DependencyLock, error)

func (*ExtendedBundle) ResolveSharedDeps added in v1.0.16

func (b *ExtendedBundle) ResolveSharedDeps(bun ExtendedBundle) ([]DependencyLock, error)

ResolveSharedDeps only works with depsv2

func (*ExtendedBundle) ResolveVersion added in v1.0.16

func (b *ExtendedBundle) ResolveVersion(name string, dep depsv1ext.Dependency) (OCIReference, error)

ResolveVersion returns the bundle name, its version and any error.

func (*ExtendedBundle) ResolveVersionv2 added in v1.0.16

func (b *ExtendedBundle) ResolveVersionv2(name string, dep v2.Dependency) (OCIReference, error)

ResolveVersion returns the bundle name, its version and any error.

func (ExtendedBundle) SupportsDependenciesV1 added in v1.0.1

func (b ExtendedBundle) SupportsDependenciesV1() bool

SupportsDependenciesV1 checks if the bundle supports dependencies

func (ExtendedBundle) SupportsDependenciesV2 added in v1.0.12

func (b ExtendedBundle) SupportsDependenciesV2() bool

SupportsDependenciesV2 checks if the bundle supports dependencies

func (ExtendedBundle) SupportsDocker added in v1.0.1

func (b ExtendedBundle) SupportsDocker() bool

SupportsDocker checks if the bundle supports docker.

func (ExtendedBundle) SupportsExtension added in v1.0.1

func (b ExtendedBundle) SupportsExtension(key string) bool

SupportsExtension checks if the bundle supports the specified CNAB extension.

func (ExtendedBundle) SupportsFileParameters added in v1.0.1

func (b ExtendedBundle) SupportsFileParameters() bool

SupportsFileParameters checks if the bundle supports file parameters.

func (ExtendedBundle) SupportsParameterSources added in v1.0.1

func (b ExtendedBundle) SupportsParameterSources() bool

SupportsParameterSources checks if the bundle supports parameter sources.

func (ExtendedBundle) Validate added in v1.0.1

func (b ExtendedBundle) Validate(cxt *portercontext.Context, strategy schema.CheckStrategy) error

func (ExtendedBundle) WriteParameterToString added in v1.0.1

func (b ExtendedBundle) WriteParameterToString(paramName string, value interface{}) (string, error)

type Installation added in v1.0.1

type Installation = cnabclaims.Installation

type OCIReference added in v1.0.1

type OCIReference struct {
	// Name is the wrapped reference that we are providing helper methods on top of
	Named reference.Named
}

OCIReference is a wrapper around a docker reference with convenience methods for decomposing and manipulating bundle references.

It is designed to be safe to call even when uninitialized, returning empty strings when parts are requested that do not exist, such as calling Digest() when no digest is set on the reference.

func CalculateTemporaryImageTag added in v1.0.1

func CalculateTemporaryImageTag(bunRef OCIReference) (OCIReference, error)

CalculateTemporaryImageTag returns the temporary tag applied to images that we use to push it and then retrieve the repository digest for an image.

func MustParseOCIReference added in v1.0.1

func MustParseOCIReference(value string) OCIReference

MustParseOCIReference parses the specified value as an OCIReference, panicking on any errors. Only use this for unit tests where you know the value is a reference.

func ParseOCIReference added in v1.0.1

func ParseOCIReference(value string) (OCIReference, error)

ParseOCIReference parses the specified value as an OCIReference. If the reference includes a digest, the digest is validated.

func (OCIReference) Digest added in v1.0.1

func (r OCIReference) Digest() digest.Digest

Digest portion of the reference. Example: ghcr.io/getporter/mybuns@sha256:abc123 returns sha256:abc123

func (OCIReference) HasDigest added in v1.0.1

func (r OCIReference) HasDigest() bool

HasDigest determines if the reference has a digest portion. Example: ghcr.io/getporter/mybuns@sha256:abc123 returns true

func (OCIReference) HasTag added in v1.0.1

func (r OCIReference) HasTag() bool

HasTag determines if the reference has a tag portion. Example: ghcr.io/getporter/mybuns:latest returns true

func (OCIReference) HasVersion added in v1.0.1

func (r OCIReference) HasVersion() bool

HasVersion detects if the reference tag is a bundle version (semver).

func (OCIReference) IsRepositoryOnly added in v1.0.1

func (r OCIReference) IsRepositoryOnly() bool

IsRepositoryOnly determines if the reference is fully qualified with a tag/digest or if it only contains a repository. Example: ghcr.io/getporter/mybuns returns true

func (OCIReference) MarshalJSON added in v1.0.1

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

func (OCIReference) ParseRepositoryInfo added in v1.0.1

func (r OCIReference) ParseRepositoryInfo() (*registry.RepositoryInfo, error)

ParseRepositoryInfo returns additional metadata about the repository portion of the reference.

func (OCIReference) Registry added in v1.0.1

func (r OCIReference) Registry() string

Registry portion of the reference. Example: ghcr.io/getporter/mybuns:v0.1.1 returns ghcr.io

func (OCIReference) Repository added in v1.0.1

func (r OCIReference) Repository() string

Repository portion of the reference. Example: docker.io/getporter/mybuns:v0.1.1 returns getporter/mybuns

func (OCIReference) String added in v1.0.1

func (r OCIReference) String() string

Always print the original name provided, not the one with docker.io prefixed.

func (OCIReference) Tag added in v1.0.1

func (r OCIReference) Tag() string

Tag portion of the reference. Example: ghcr.io/getporter/mybuns:latest returns latest

func (*OCIReference) UnmarshalJSON added in v1.0.1

func (r *OCIReference) UnmarshalJSON(bytes []byte) error

func (OCIReference) Version added in v1.0.1

func (r OCIReference) Version() string

Version parses the reference tag as a bundle version (semver).

func (OCIReference) WithDigest added in v1.0.1

func (r OCIReference) WithDigest(digest digest.Digest) (OCIReference, error)

WithDigest creates a new reference using the repository and the specified digest.

func (OCIReference) WithTag added in v1.0.1

func (r OCIReference) WithTag(tag string) (OCIReference, error)

WithTag creates a new reference using the repository and the specified tag.

func (OCIReference) WithVersion added in v1.0.1

func (r OCIReference) WithVersion(version string) (OCIReference, error)

WithVersion creates a new reference using the repository and the specified bundle version.

type Output added in v1.0.1

type Output = cnabclaims.Output

type OutputMetadata added in v1.0.1

type OutputMetadata = cnabclaims.OutputMetadata

type OutputParameterSource added in v1.0.1

type OutputParameterSource struct {
	OutputName string `json:"name" mapstructure:"name"`
}

OutputParameterSource represents a parameter that is set using the value from a bundle output.

type Outputs added in v1.0.1

type Outputs = cnabclaims.Outputs

type ParameterSource added in v1.0.1

type ParameterSource struct {
	// Priority is an array of source types in the priority order that they should be used to
	// populated the parameter.
	Priority []string `json:"priority" mapstructure:"priority"`

	// Sources is a map of key/value pairs of a source type and definition for
	// the parameter value.
	Sources ParameterSourceMap `json:"sources" mapstructure:"sources"`
}

func (ParameterSource) ListSourcesByPriority added in v1.0.1

func (s ParameterSource) ListSourcesByPriority() []ParameterSourceDefinition

ListSourcesByPriority returns the parameter sources by the requested priority, if none is specified, they are unsorted.

type ParameterSourceDefinition added in v1.0.1

type ParameterSourceDefinition interface {
}

type ParameterSourceMap added in v1.0.1

type ParameterSourceMap map[string]ParameterSourceDefinition

func (*ParameterSourceMap) UnmarshalJSON added in v1.0.1

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

type ParameterSources added in v1.0.1

type ParameterSources map[string]ParameterSource

ParameterSources describes the set of custom extension metadata associated with the Parameter Sources extension

func (*ParameterSources) SetParameterFromDependencyOutput added in v1.0.1

func (ps *ParameterSources) SetParameterFromDependencyOutput(parameter string, dep string, output string)

SetParameterFromDependencyOutput creates an entry in the parameter sources section setting the parameter's value using the specified dependency's output value.

func (*ParameterSources) SetParameterFromOutput added in v1.0.1

func (ps *ParameterSources) SetParameterFromOutput(parameter string, output string)

SetParameterFromOutput creates an entry in the parameter sources section setting the parameter's value using the specified output's value.

type ProcessedExtensions added in v1.0.1

type ProcessedExtensions map[string]interface{}

ProcessedExtensions represents a map of the extension name to the processed extension configuration

func (ProcessedExtensions) FileParameterSupport added in v1.0.1

func (e ProcessedExtensions) FileParameterSupport() bool

FileParameterSupport checks if the file parameter extension is present.

func (ProcessedExtensions) GetDocker added in v1.0.1

func (e ProcessedExtensions) GetDocker() (dockerExt Docker, dockerRequired bool, err error)

GetDocker checks if the docker extension is present and returns its extension configuration.

func (ProcessedExtensions) GetParameterSources added in v1.0.1

func (e ProcessedExtensions) GetParameterSources() (ParameterSources, bool, error)

GetParameterSources checks if the parameter sources extension is present and returns its extension configuration.

type RequiredExtension added in v1.0.1

type RequiredExtension struct {
	Shorthand string
	Key       string
	Schema    string
	Reader    func(b ExtendedBundle) (interface{}, error)
}

RequiredExtension represents a required extension that is known and supported by Porter

func GetSupportedExtension added in v1.0.1

func GetSupportedExtension(e string) (*RequiredExtension, error)

GetSupportedExtension returns a supported extension according to the provided name, or an error

type Result added in v1.0.1

type Result = cnabclaims.Result

type SchemaVersion added in v1.0.8

type SchemaVersion = schema.Version

func BundleSchemaVersion added in v1.0.1

func BundleSchemaVersion() SchemaVersion

BundleSchemaVersion is the schemaVersion value for CNAB bundle documents.

func ClaimSchemaVersion added in v1.0.1

func ClaimSchemaVersion() SchemaVersion

ClaimSchemaVersion is the schemaVersion value for CNAB claim documents.

Directories

Path Synopsis
Package configadapter converts a Porter manifest (porter.yaml) to a CNAB bundle.json
Package configadapter converts a Porter manifest (porter.yaml) to a CNAB bundle.json
extensions
dependencies/v2
Package v2 defines the v2 Porter Dependency specification, org.getporter.dependencies@v2.
Package v2 defines the v2 Porter Dependency specification, org.getporter.dependencies@v2.

Jump to

Keyboard shortcuts

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