environs

package
v0.0.0-...-4308112 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2024 License: AGPL-3.0 Imports: 39 Imported by: 558

Documentation

Index

Constants

View Source
const (
	// ErrAvailabilityZoneIndependent is an error that represents if the error
	// is independent of any particular availability zone. Juju uses this to
	// decide whether or not to attempt the failed operation in another
	// availability zone. Errors that conform to
	// Is(err, ErrAvailabilityZoneIndependent) will not be reattempted.
	ErrAvailabilityZoneIndependent = errors.ConstError("availability zone independent")

	// ErrNotBootstrapped reports that the given model is not bootstrapped.
	ErrNotBootstrapped = errors.ConstError("model is not bootstrapped")

	// ErrPartialInstances reports that the only some of the expected instance
	// were found.
	ErrPartialInstances = errors.ConstError("only some instances were found")
)
View Source
const AdminUser = "admin"

AdminUser is the initial admin user created for all controllers.

View Source
const (
	// InstanceProfileAutoCreate defines the const value used for the constraint
	// when instance profile creation should be done on behalf of the user.
	InstanceProfileAutoCreate = "auto"
)

Variables

View Source
var AddressesRefreshAttempt = utils.AttemptStrategy{
	Total: 3 * time.Minute,
	Delay: 1 * time.Second,
}

AddressesRefreshAttempt is the attempt strategy used when refreshing instance addresses.

View Source
var DefaultSpaceInfo *network.SpaceInfo

DefaultSpaceInfo should be passed into Networking.ProviderSpaceInfo to get information about the default space.

View Source
var (
	// ErrNotInstances represents and error for describing that no instances
	// were found.
	// NOTE: 2022-04-01 tlm This error carries some technical debt. Ideally it
	// would be nice to make this a ConstError but it's very unclear if this
	// error needs to also be represented as a NotFound error. In 2.9 we are
	// going to leave it as is but break it for 3.0.
	ErrNoInstances = fmt.Errorf("instances %w", errors.NotFound)
)
View Source
var SupportsNetworking = supportsNetworking

SupportsNetworking is a convenience helper to check if an environment supports networking. It returns an interface containing Environ and Networking in this case.

Functions

func APIInfo

func APIInfo(
	ctx envcontext.ProviderCallContext, controllerUUID, modelUUID, caCert string, apiPort int, env Environ,
) (*api.Info, error)

APIInfo returns an api.Info for the environment. The result is populated with addresses and CA certificate, but no tag or password.

func CheckProviderAPI

func CheckProviderAPI(envOrBroker BootstrapEnviron, ctx envcontext.ProviderCallContext) error

CheckProviderAPI returns an error if a simple API call to check a basic response from the specified environ fails.

func Destroy

func Destroy(
	controllerName string,
	env ControllerDestroyer,
	ctx envcontext.ProviderCallContext,
	store jujuclient.ControllerStore,
) error

Destroy destroys the controller and, if successful, its associated configuration data from the given store.

func ImageMetadataSources

func ImageMetadataSources(env BootstrapEnviron, dataSourceFactory simplestreams.DataSourceFactory) ([]simplestreams.DataSource, error)

ImageMetadataSources returns the sources to use when looking for simplestreams image id metadata for the given stream.

func RegisterImageDataSourceFunc

func RegisterImageDataSourceFunc(id string, f ImageDataSourceFunc)

RegisterImageDataSourceFunc registers an ImageDataSourceFunc with the specified id, overwriting any function previously registered with the same id.

func RegisterProvider

func RegisterProvider(name string, p CloudEnvironProvider, alias ...string) (unregister func())

RegisterProvider registers a new environment provider. Name gives the name of the provider, and p the interface to that provider.

RegisterProvider will panic if the provider name or any of the aliases are registered more than once. The return function can be used to unregister the provider and is used by tests.

func RegisterUserImageDataSourceFunc

func RegisterUserImageDataSourceFunc(id string, f ImageDataSourceFunc)

RegisterUserImageDataSourceFunc registers an ImageDataSourceFunc with the specified id at the start of the search path, overwriting any function previously registered with the same id.

func RegisteredProviders

func RegisteredProviders() []string

RegisteredProviders enumerate all the environ providers which have been registered.

func SupportsContainerAddresses

func SupportsContainerAddresses(ctx envcontext.ProviderCallContext, env BootstrapEnviron) bool

SupportsContainerAddresses checks if the environment will let us allocate addresses for containers from the host ranges.

func SupportsSpaces

func SupportsSpaces(env NetworkingEnviron) bool

SupportsSpaces checks if the environment supports spaces.

func UnregisterImageDataSourceFunc

func UnregisterImageDataSourceFunc(id string)

UnregisterImageDataSourceFunc unregisters an ImageDataSourceFunc with the specified id.

func ZoneIndependentError

func ZoneIndependentError(err error) error

ZoneIndependentError wraps err so that it satisfy Is(err, ErrAvailabilityZoneIndependent) and the errors.Locationer interface. If a nil error is provider then a nil error is returned.

Types

type BootstrapContext

type BootstrapContext interface {
	BootstrapLogger
	context.Context

	// InterruptNotify starts watching for interrupt signals
	// on behalf of the caller, sending them to the supplied
	// channel.
	InterruptNotify(sig chan<- os.Signal)

	// StopInterruptNotify undoes the effects of a previous
	// call to InterruptNotify with the same channel. After
	// StopInterruptNotify returns, no more signals will be
	// delivered to the channel.
	StopInterruptNotify(chan<- os.Signal)

	// ShouldVerifyCredentials indicates whether the caller's cloud
	// credentials should be verified.
	ShouldVerifyCredentials() bool
}

BootstrapContext is an interface that is passed to Environ.Bootstrap, providing a means of obtaining information about and manipulating the context in which it is being invoked.

type BootstrapCredentialsFinaliser

type BootstrapCredentialsFinaliser interface {
	// FinalizeBootstrapCredential finalizes credential as the last step of a
	// bootstrap process.
	FinaliseBootstrapCredential(BootstrapContext, BootstrapParams, *cloud.Credential) (*cloud.Credential, error)
}

BootstrapCredentialsFinaliser is an interface for environs to provide a method for finalizing bootstrap credentials before being passed to a newly bootstrapped controller.

type BootstrapDialOpts

type BootstrapDialOpts struct {
	// Timeout is the amount of time to wait contacting a state
	// server.
	Timeout time.Duration

	// RetryDelay is the amount of time between attempts to connect to
	// an address.
	RetryDelay time.Duration

	// AddressesDelay is the amount of time between refreshing the
	// addresses.
	AddressesDelay time.Duration
}

BootstrapDialOpts contains the options for the synchronous part of the bootstrap procedure, where the CLI connects to the bootstrap machine to complete the process.

type BootstrapEnviron

type BootstrapEnviron interface {
	Configer
	Bootstrapper
	ConstraintsChecker

	CloudDestroyer
	ControllerDestroyer

	// ProviderRegistry is implemented in order to acquire
	// environ-scoped storage providers supported by the Environ.
	// StorageProviders returned from Environ.StorageProvider will
	// be scoped specifically to that Environ.
	storage.ProviderRegistry

	// Create creates the environment for a new hosted model.
	//
	// This will be called before any workers begin operating on the
	// Environ, to give an Environ a chance to perform operations that
	// are required for further use.
	//
	// Create is not called for the initial controller model; it is
	// the Bootstrap method's job to create the controller model.
	Create(envcontext.ProviderCallContext, CreateParams) error
}

BootstrapEnviron is an interface that an EnvironProvider implements in order to bootstrap a controller.

type BootstrapLogger

type BootstrapLogger interface {
	GetStdin() io.Reader
	GetStdout() io.Writer
	GetStderr() io.Writer

	Infof(format string, params ...interface{})
	Verbosef(format string, params ...interface{})
}

BootstrapLogger defines the logger used during a bootstrap.

type BootstrapParams

type BootstrapParams struct {
	// AuthorizedKeys is the set of authorized keys to be allowed to ssh to the
	// bootstrap instance during bootstrap. This may not be the same set of keys
	// that are allowed after the controller takes over management of the
	// instance.
	AuthorizedKeys []string

	// Cloud contains the name of the cloud that Juju will be
	// bootstrapped in. Used for printing feedback during bootstrap.
	CloudName string

	// CloudRegion is the name of the cloud region that Juju will be
	// bootstrapped in. Used for printing feedback during bootstrap.
	CloudRegion string

	// ControllerConfig contains the configuration attributes for the
	// bootstrapped controller.
	ControllerConfig controller.Config

	// ModelConstraints are merged with the bootstrap constraints
	// to choose the initial instance, and will be stored in the new
	// environment's state.
	ModelConstraints constraints.Value

	// BootstrapConstraints, in conjunction with ModelConstraints,
	// are used to choose the initial instance. BootstrapConstraints
	// will not be stored in state for the environment.
	BootstrapConstraints constraints.Value

	// StoragePools is one or more named storage pools to create
	// in the controller model.
	StoragePools map[string]storage.Attrs

	// BootstrapBase, if specified, is the base to use for the
	// initial bootstrap machine.
	BootstrapBase corebase.Base

	// SupportedBootstrapBases is a list of supported bases to use for
	// validating against the bootstrap base.
	SupportedBootstrapBases []corebase.Base

	// Placement, if non-empty, holds an environment-specific placement
	// directive used to choose the initial instance.
	Placement string

	// AvailableTools is a collection of tools which the Bootstrap method
	// may use to decide which architecture/base to instantiate.
	AvailableTools tools.List

	// ImageMetadata contains simplestreams image metadata for providers
	// that rely on it for selecting images. This will be empty for
	// providers that do not implements simplestreams.HasRegion.
	ImageMetadata []*imagemetadata.ImageMetadata

	// ExtraAgentValuesForTesting are testing only values written to the agent config file.
	ExtraAgentValuesForTesting map[string]string

	// Force is used to allow a bootstrap to be run on unsupported base.
	Force bool
}

BootstrapParams holds the parameters for bootstrapping an environment.

type BootstrapResult

type BootstrapResult struct {
	// Arch is the instance's architecture.
	Arch string

	// Base is the instance's base.
	Base corebase.Base

	// CloudBootstrapFinalizer is a function that must be called finalize the
	// bootstrap process by transferring the tools and installing the
	// initial Juju controller.
	CloudBootstrapFinalizer

	// CaasBootstrapFinalizer is the finalizer for caas.
	CaasBootstrapFinalizer
}

BootstrapResult holds the data returned by calls to Environ.Bootstrap.

type Bootstrapper

type Bootstrapper interface {
	// PrepareForBootstrap will be called very early in the bootstrap
	// procedure to give an Environ a chance to perform interactive
	// operations that are required for bootstrapping.
	PrepareForBootstrap(ctx BootstrapContext, controllerName string) error

	// Bootstrap creates a new environment, and an instance to host the
	// controller for that environment. The instance will have the
	// series and architecture of the Environ's choice, constrained to
	// those of the available tools. Bootstrap will return the instance's
	// architecture, series, and a function that must be called to finalize
	// the bootstrap process by transferring the tools and installing the
	// initial Juju controller.
	//
	// It is possible to direct Bootstrap to use a specific architecture
	// (or fail if it cannot start an instance of that architecture) by
	// using an architecture constraint; this will have the effect of
	// limiting the available tools to just those matching the specified
	// architecture.
	Bootstrap(ctx BootstrapContext, callCtx envcontext.ProviderCallContext, params BootstrapParams) (*BootstrapResult, error)
}

Bootstrapper provides the way for bootstrapping controller.

type CaasBootstrapFinalizer

type CaasBootstrapFinalizer func(BootstrapContext, *podcfg.ControllerPodConfig, BootstrapDialOpts) error

CaasBootstrapFinalizer is a function returned from Environ.Bootstrap. The caller must pass a ControllerPodConfig with the Tools field set.

type CheckProvider

type CheckProvider interface {
	// AllInstances returns all instances currently known to the broker.
	AllInstances(ctx envcontext.ProviderCallContext) ([]instances.Instance, error)
}

CheckProvider defines the old and/or public cloud style of cloud endpoint validation. This check is a heavy weight method to verify the current cloud connectivity. Typically used with public clouds which have not implemented the CloudEndpointChecker.

type CloudBootstrapFinalizer

type CloudBootstrapFinalizer func(BootstrapContext, *instancecfg.InstanceConfig, BootstrapDialOpts) error

CloudBootstrapFinalizer is a function returned from Environ.Bootstrap. The caller must pass a InstanceConfig with the Tools field set.

type CloudDestroyer

type CloudDestroyer interface {
	// Destroy shuts down all known machines and destroys the
	// rest of the environment. Note that on some providers,
	// very recently started instances may not be destroyed
	// because they are not yet visible.
	//
	// When Destroy has been called, any Environ referring to the
	// same remote environment may become invalid.
	Destroy(ctx envcontext.ProviderCallContext) error
}

CloudDestroyer provides the API to cleanup cloud resources.

type CloudDetector

type CloudDetector interface {
	// DetectCloud attempts to detect a cloud with the given name
	// from the environment. This may involve, for example,
	// inspecting environment variables, or returning special
	// hard-coded regions (e.g. "localhost" for lxd).
	//
	// If no cloud can be detected, DetectCloud should return
	// an error satisfying errors.IsNotFound.
	//
	// DetectCloud should be used in preference to DetectClouds
	// when a specific cloud is identified, as this may be more
	// efficient.
	DetectCloud(name string) (cloud.Cloud, error)

	// DetectClouds detects clouds from the environment. This may
	// involve, for example, inspecting environment variables, or
	// returning special hard-coded regions (e.g. "localhost" for lxd).
	DetectClouds() ([]cloud.Cloud, error)
}

CloudDetector is an interface that an EnvironProvider implements in order to automatically detect clouds from the environment.

type CloudEndpointChecker

type CloudEndpointChecker interface {
	// ValidateCloudEndpoint validates connectivity with the cloud's
	// endpoint and returns nil if no problems.
	ValidateCloudEndpoint(ctx envcontext.ProviderCallContext) error
}

CloudEndpointChecker defines a method for cloud endpoint validation.

TODO: hml 09-Feb-22 Implement this interface for all providers, including the public clouds.

type CloudEnvironProvider

type CloudEnvironProvider interface {
	EnvironProvider
	// Open opens the environment and returns it. The configuration must
	// have passed through PrepareConfig at some point in its lifecycle.
	//
	// Open should not perform any expensive operations, such as querying
	// the cloud API, as it will be called frequently.
	Open(stdcontext.Context, OpenParams) (Environ, error)
}

A CloudEnvironProvider represents a computing and storage provider for a traditional cloud like AWS or Openstack.

type CloudFinalizer

type CloudFinalizer interface {
	// FinalizeCloud finalizes a cloud definition, updating any attributes
	// as necessary. This is always done client-side, before bootstrapping.
	FinalizeCloud(FinalizeCloudContext, cloud.Cloud) (cloud.Cloud, error)
}

CloudFinalizer is an interface that an EnvironProvider implements in order to finalize a cloud.Cloud definition before bootstrapping.

type CloudRegionDetector

type CloudRegionDetector interface {
	// DetectRegions automatically detects one or more regions
	// from the environment. This may involve, for example, inspecting
	// environment variables, or returning special hard-coded regions
	// (e.g. "localhost" for lxd). The first item in the list will be
	// considered the default region for bootstrapping if the user
	// does not specify one.
	//
	// If no regions can be detected, DetectRegions should return
	// an error satisfying errors.IsNotFound.
	DetectRegions() ([]cloud.Region, error)
}

CloudRegionDetector is an interface that an EnvironProvider implements in order to automatically detect cloud regions from the environment.

type CloudService

type CloudService interface {
	Cloud(ctx context.Context, name string) (*cloud.Cloud, error)
}

CloudService provides access to clouds.

type CloudSpecSetter

type CloudSpecSetter interface {
	// SetCloudSpec updates the Environ's configuration.
	SetCloudSpec(ctx stdcontext.Context, spec environscloudspec.CloudSpec) error
}

CloudSpecSetter implements access to an environment's cloud spec.

type ConfigGetter

type ConfigGetter interface {
	// Config returns the configuration data with which the Environ was created.
	// Note that this is not necessarily current; the canonical location
	// for the configuration data is stored in the state.
	Config() *config.Config
}

ConfigGetter implements access to an environment's configuration.

type ConfigSetter

type ConfigSetter interface {
	// SetConfig updates the Environ's configuration.
	//
	// Calls to SetConfig do not affect the configuration of
	// values previously obtained from Storage.
	SetConfig(ctx context.Context, cfg *config.Config) error
}

ConfigSetter implements access to an environment's configuration.

type Configer

type Configer interface {
	ConfigGetter
	ConfigSetter
}

Configer implements access to an environment's configuration.

type ConnectorInfo

type ConnectorInfo interface {
	ConnectionProxyInfo(ctx stdcontext.Context) (proxy.Proxier, error)
}

type ConstraintsChecker

type ConstraintsChecker interface {
	// ConstraintsValidator returns a Validator instance which
	// is used to validate and merge constraints.
	ConstraintsValidator(ctx envcontext.ProviderCallContext) (constraints.Validator, error)
}

ConstraintsChecker provides a means to check that constraints are valid.

type ControllerDestroyer

type ControllerDestroyer interface {
	DestroyController(ctx envcontext.ProviderCallContext, controllerUUID string) error
}

ControllerDestroyer is similar to Destroy() in that it destroys the model, which in this case will be the controller model.

In addition, this method also destroys any resources relating to hosted models on the controller on which it is invoked. This ensures that "kill-controller" can clean up hosted models when the Juju controller process is unavailable.

type CreateParams

type CreateParams struct {
	// ControllerUUID is the UUID of the controller to be that is creating
	// the Environ.
	ControllerUUID string
}

CreateParams contains the parameters for Environ.Create.

type DefaultConstraintsChecker

type DefaultConstraintsChecker interface {
	// ShouldApplyControllerConstraints returns if bootstrapping logic should
	// use default constraints
	ShouldApplyControllerConstraints(constraints.Value) bool
}

DefaultConstraintsChecker defines an interface for checking if the default constraints should be applied for the Environ provider when bootstrapping the provider.

type Environ

type Environ interface {
	BootstrapEnviron

	// ResourceAdopter defines methods for adopting resources.
	ResourceAdopter

	// InstanceBroker defines methods for starting and stopping
	// instances.
	InstanceBroker

	InstanceLister

	// ControllerInstances returns the IDs of instances corresponding
	// to Juju controller, having the specified controller UUID.
	// If there are no controller instances, ErrNoInstances is returned.
	// If it can be determined that the environment has not been bootstrapped,
	// then ErrNotBootstrapped should be returned instead.
	ControllerInstances(ctx envcontext.ProviderCallContext, controllerUUID string) ([]instance.Id, error)

	// Provider returns the EnvironProvider that created this Environ.
	Provider() EnvironProvider

	InstancePrechecker

	// InstanceTypesFetcher represents an environment that can return
	// information about the available instance types.
	InstanceTypesFetcher
}

An Environ represents a Juju environment.

Due to the limitations of some providers (for example ec2), the results of the Environ methods may not be fully sequentially consistent. In particular, while a provider may retry when it gets an error for an operation, it will not retry when an operation succeeds, even if that success is not consistent with a previous operation.

Even though Juju takes care not to share an Environ between concurrent workers, it does allow concurrent method calls into the provider implementation. The typical provider implementation needs locking to avoid undefined behaviour when the configuration changes.

func GetEnviron

func GetEnviron(ctx context.Context, st EnvironConfigGetter, newEnviron NewEnvironFunc) (Environ, error)

GetEnviron returns the environs.Environ ("provider") associated with the model.

func GetEnvironAndCloud

func GetEnvironAndCloud(ctx context.Context, getter EnvironConfigGetter, newEnviron NewEnvironFunc) (Environ, *environscloudspec.CloudSpec, error)

GetEnvironAndCloud returns the environs.Environ ("provider") and cloud associated with the model.

func New

func New(ctx stdcontext.Context, args OpenParams) (Environ, error)

New returns a new environment based on the provided configuration.

func Open

Open creates an Environ instance and errors if the provider is not for a cloud.

type EnvironConfigGetter

type EnvironConfigGetter interface {
	ModelConfig(context.Context) (*config.Config, error)
	CloudSpec(context.Context) (environscloudspec.CloudSpec, error)
}

EnvironConfigGetter exposes a model configuration to its clients.

type EnvironProvider

type EnvironProvider interface {
	config.Validator
	ProviderCredentials

	// Version returns the version of the provider. This is recorded as the
	// environ version for each model, and used to identify which upgrade
	// operations to run when upgrading a model's environ. Providers should
	// start out at version 0.
	Version() int

	// CloudSchema returns the schema used to validate input for add-cloud.  If
	// a provider does not support custom clouds, CloudSchema should return
	// nil.
	CloudSchema() *jsonschema.Schema

	// Ping tests the connection to the cloud, to verify the endpoint is valid.
	Ping(ctx envcontext.ProviderCallContext, endpoint string) error

	// PrepareConfig prepares the configuration for a new model, based on
	// the provided arguments. PrepareConfig is expected to produce a
	// deterministic output. Any unique values should be based on the
	// "uuid" attribute of the base configuration. This is called for the
	// controller model during bootstrap, and also for new hosted models.
	PrepareConfig(context.Context, PrepareConfigParams) (*config.Config, error)
}

A EnvironProvider represents a computing and storage provider for either a traditional cloud or a container substrate like k8s.

func Provider

func Provider(providerType string) (EnvironProvider, error)

Provider returns the previously registered provider with the given type.

type FinalizeCloudContext

type FinalizeCloudContext interface {
	stdcontext.Context

	// Verbosef will write the formatted string to Stderr if the
	// verbose flag is true, and to the logger if not.
	Verbosef(string, ...interface{})
}

FinalizeCloudContext is an interface passed into FinalizeCloud to provide a means of interacting with the user when finalizing a cloud definition.

type FinalizeCredentialContext

type FinalizeCredentialContext interface {
	GetStderr() io.Writer

	// Verbosef will write the formatted string to Stderr if the
	// verbose flag is true, and to the logger if not.
	Verbosef(string, ...interface{})
}

FinalizeCredentialContext is an interface passed into FinalizeCredential to provide a means of interacting with the user when finalizing credentials.

type FinalizeCredentialParams

type FinalizeCredentialParams struct {
	// Credential is the credential that the provider should finalize.
	Credential cloud.Credential

	// CloudName is the name of the cloud that the credentials are for.
	CloudName string

	// CloudEndpoint is the endpoint for the cloud that the credentials are
	// for. This may be used by the provider to communicate with the cloud
	// to finalize the credentials.
	CloudEndpoint string

	// CloudStorageEndpoint is the storage endpoint for the cloud that the
	// credentials are for. This may be used by the provider to communicate
	// with the cloud to finalize the credentials.
	CloudStorageEndpoint string

	// CloudIdentityEndpoint is the identity endpoint for the cloud that the
	// credentials are for. This may be used by the provider to communicate
	// with the cloud to finalize the credentials.
	CloudIdentityEndpoint string
}

FinalizeCredentialParams contains the parameters for ProviderCredentials.FinalizeCredential.

type FirewallFeatureQuerier

type FirewallFeatureQuerier interface {
	// SupportsRulesWithIPV6CIDRs returns true if the environment supports
	// ingress rules containing IPV6 CIDRs.
	SupportsRulesWithIPV6CIDRs(ctx envcontext.ProviderCallContext) (bool, error)
}

FirewallFeatureQuerier exposes methods for detecting what features the environment firewall supports.

type Firewaller

type Firewaller interface {
	// OpenPorts opens the given port ranges for the whole environment.
	// Must only be used if the environment was setup with the
	// FwGlobal firewall mode.
	OpenPorts(ctx envcontext.ProviderCallContext, rules firewall.IngressRules) error

	// ClosePorts closes the given port ranges for the whole environment.
	// Must only be used if the environment was setup with the
	// FwGlobal firewall mode.
	ClosePorts(ctx envcontext.ProviderCallContext, rules firewall.IngressRules) error

	// IngressRules returns the ingress rules applied to the whole environment.
	// Must only be used if the environment was setup with the
	// FwGlobal firewall mode.
	// It is expected that there be only one ingress rule result for a given
	// port range - the rule's SourceCIDRs will contain all applicable source
	// address rules for that port range.
	IngressRules(ctx envcontext.ProviderCallContext) (firewall.IngressRules, error)
}

Firewaller exposes methods for managing network ports.

type HardwareCharacteristicsDetector

type HardwareCharacteristicsDetector interface {
	// DetectBase returns the base for the controller instance.
	DetectBase() (corebase.Base, error)
	// DetectHardware returns the hardware characteristics for the
	// controller instance.
	DetectHardware() (*instance.HardwareCharacteristics, error)
	// UpdateModelConstraints returns true if the model constraints should
	// be updated based on the returns of DetectBase() and
	// DetectHardware().
	UpdateModelConstraints() bool
}

HardwareCharacteristicsDetector is implemented by environments that can provide advance information about the series and hardware for controller instances that have not been provisioned yet.

type ImageDataSourceFunc

type ImageDataSourceFunc func(Environ) (simplestreams.DataSource, error)

ImageDataSourceFunc is a function type that takes an environment and returns a simplestreams datasource.

ImageDataSourceFunc will be used in ImageMetadataSources. Any error satisfying errors.IsNotSupported will be ignored; any other error will be cause ImageMetadataSources to fail.

type InstanceBroker

type InstanceBroker interface {
	// StartInstance asks for a new instance to be created, associated with
	// the provided config in machineConfig. The given config describes the
	// juju state for the new instance to connect to. The config
	// MachineNonce, which must be unique within an environment, is used by
	// juju to protect against the consequences of multiple instances being
	// started with the same machine id.
	//
	// Callers may attempt to distribute instances across a set of
	// availability zones. If one zone fails, then the caller is expected
	// to attempt in another zone. If the provider can determine that
	// the StartInstanceParams can never be fulfilled in any zone, then
	// it may return an error satisfying Is(err, ErrAvailabilityZoneIndependent).
	StartInstance(ctx envcontext.ProviderCallContext, args StartInstanceParams) (*StartInstanceResult, error)

	// StopInstances shuts down the instances with the specified IDs.
	// Unknown instance IDs are ignored, to enable idempotency.
	StopInstances(envcontext.ProviderCallContext, ...instance.Id) error

	// AllInstances returns all instances currently known to the broker.
	AllInstances(ctx envcontext.ProviderCallContext) ([]instances.Instance, error)

	// AllRunningInstances returns all running, available instances currently known to the broker.
	AllRunningInstances(ctx envcontext.ProviderCallContext) ([]instances.Instance, error)
}

InstanceBroker defines methods for managing vm or container instances. TODO(wallyworld) - we want this in the environs/instance package but import loops stop that from being possible right now.

type InstanceLister

type InstanceLister interface {
	// Instances returns a slice of instances corresponding to the
	// given instance ids.  If no instances were found, but there
	// was no other error, it will return ErrNoInstances.  If
	// some but not all the instances were found, the returned slice
	// will have some nil slots, and an ErrPartialInstances error
	// will be returned.
	Instances(ctx envcontext.ProviderCallContext, ids []instance.Id) ([]instances.Instance, error)
}

InstanceLister provider api to list instances for specified instance ids.

type InstancePrechecker

type InstancePrechecker interface {
	// PrecheckInstance performs a preflight check on the specified
	// series and constraints, ensuring that they are possibly valid for
	// creating an instance in this model.
	//
	// PrecheckInstance is best effort, and not guaranteed to eliminate
	// all invalid parameters. If PrecheckInstance returns nil, it is not
	// guaranteed that the constraints are valid; if a non-nil error is
	// returned, then the constraints are definitely invalid.
	PrecheckInstance(envcontext.ProviderCallContext, PrecheckInstanceParams) error
}

InstancePrechecker provides a means of "prechecking" instance arguments before recording them in state.

type InstanceRole

type InstanceRole interface {
	// CreateAutoInstanceRole is responsible for setting up an instance role on
	// behalf of the user.
	CreateAutoInstanceRole(envcontext.ProviderCallContext, BootstrapParams) (string, error)

	// SupportsInstanceRoles indicates if Instance Roles are supported by this
	// environ.
	SupportsInstanceRoles(envcontext.ProviderCallContext) bool
}

InstanceRole defines the interface for environ providers to implement when they offer InstanceRole support for their respective cloud.

type InstanceTagger

type InstanceTagger interface {
	// TagInstance tags the given instance with the specified tags.
	//
	// The specified tags will replace any existing ones with the
	// same names, but other existing tags will be left alone.
	TagInstance(ctx envcontext.ProviderCallContext, id instance.Id, tags map[string]string) error
}

InstanceTagger is an interface that can be used for tagging instances.

type InstanceTypesFetcher

type InstanceTypesFetcher interface {
	InstanceTypes(envcontext.ProviderCallContext, constraints.Value) (instances.InstanceTypesWithCostMetadata, error)
}

InstanceTypesFetcher is an interface that allows for instance information from a provider to be obtained.

type JujuUpgradePrechecker

type JujuUpgradePrechecker interface {
	// PreparePrechecker is called to to give an Environ a chance to
	// perform interactive operations that are required for prechecking
	// an upgrade.
	PreparePrechecker() error

	// PrecheckUpgradeOperations returns a list of
	// PrecheckJujuUpgradeOperations for checking if juju can be upgrade.
	PrecheckUpgradeOperations() []PrecheckJujuUpgradeOperation
}

JujuUpgradePrechecker is an interface that can be used to precheck the Environs before upgrading juju. If an Environ implements this interface, its PrecheckUpgradeOperations method will be invoked to identify operations that should be run to check if an juju upgrade is possible.

type LXDProfiler

type LXDProfiler interface {
	// AssignLXDProfiles assigns the given profile names to the lxd instance
	// provided.  The slice of ProfilePosts provides details for adding to
	// and removing profiles from the lxd server.
	AssignLXDProfiles(instID string, profilesNames []string, profilePosts []lxdprofile.ProfilePost) ([]string, error)

	// MaybeWriteLXDProfile writes the given LXDProfile to if not already there.
	MaybeWriteLXDProfile(pName string, put lxdprofile.Profile) error

	// LXDProfileNames returns all the profiles associated to a container name
	LXDProfileNames(containerName string) ([]string, error)
}

LXDProfiler defines an interface for dealing with lxd profiles used to deploy juju machines and containers.

type ModelConfigProvider

type ModelConfigProvider interface {
	// ConfigDefaults returns the default values for the
	// provider specific config attributes.
	ConfigDefaults() schema.Defaults

	// ConfigSchema returns extra config attributes specific
	// to this provider only.
	ConfigSchema() schema.Fields

	// ModelConfigDefaults provides a set of default model config attributes
	// that should be set on a models config if they have not been specified by
	// the user.
	ModelConfigDefaults(context.Context) (map[string]any, error)
}

ModelConfigProvider represents an interface that a EnvironProvider can implement to provide opinions and defaults into a model's config.

type Networking

type Networking interface {
	// Subnets returns basic information about subnets known
	// by the provider for the environment.
	Subnets(
		ctx envcontext.ProviderCallContext, inst instance.Id, subnetIds []network.Id,
	) ([]network.SubnetInfo, error)

	// NetworkInterfaces returns a slice with the network interfaces that
	// correspond to the given instance IDs. If no instances where found,
	// but there was no other error, it will return ErrNoInstances. If some
	// but not all of the instances were found, the returned slice will
	// have some nil slots, and an ErrPartialInstances error will be
	// returned.
	NetworkInterfaces(ctx envcontext.ProviderCallContext, ids []instance.Id) ([]network.InterfaceInfos, error)

	// SupportsSpaces returns whether the current environment supports
	// spaces. The returned error satisfies errors.IsNotSupported(),
	// unless a general API failure occurs.
	SupportsSpaces() (bool, error)

	// SupportsSpaceDiscovery returns whether the current environment
	// supports discovering spaces from the provider. The returned error
	// satisfies errors.IsNotSupported(), unless a general API failure occurs.
	SupportsSpaceDiscovery() (bool, error)

	// Spaces returns a slice of network.SpaceInfo with info, including
	// details of all associated subnets, about all spaces known to the
	// provider that have subnets available.
	Spaces(ctx envcontext.ProviderCallContext) (network.SpaceInfos, error)

	// ProviderSpaceInfo returns the details of the space requested as
	// a ProviderSpaceInfo. This will contain everything needed to
	// decide whether an Environ of the same type in another
	// controller could route to the space. Details for the default
	// space can be retrieved by passing DefaultSpaceInfo (which is nil).
	//
	// This method accepts a SpaceInfo with details of the space that
	// we need provider details for - this is the Juju model's view of
	// what subnets are in the space. If the provider supports spaces
	// and space discovery then it is the authority on what subnets
	// are actually in the space, and it's free to collect the full
	// space and subnet info using the space's ProviderId (discarding
	// the subnet details passed in which might be out-of date).
	//
	// If the provider doesn't support space discovery then the Juju
	// model's opinion of what subnets are in the space is
	// authoritative. In that case the provider should collect up any
	// other information needed to determine routability and include
	// the passed-in space info in the ProviderSpaceInfo returned.
	ProviderSpaceInfo(ctx envcontext.ProviderCallContext, space *network.SpaceInfo) (*ProviderSpaceInfo, error)

	// SupportsContainerAddresses returns true if the current environment is
	// able to allocate addresses for containers. If returning false, we also
	// return an IsNotSupported error.
	SupportsContainerAddresses(ctx envcontext.ProviderCallContext) (bool, error)

	// AllocateContainerAddresses allocates a static address for each of the
	// container NICs in preparedInfo, hosted by the hostInstanceID. Returns the
	// network config including all allocated addresses on success.
	AllocateContainerAddresses(ctx envcontext.ProviderCallContext, hostInstanceID instance.Id, containerTag names.MachineTag, preparedInfo network.InterfaceInfos) (network.InterfaceInfos, error)

	// ReleaseContainerAddresses releases the previously allocated
	// addresses matching the interface details passed in.
	ReleaseContainerAddresses(ctx envcontext.ProviderCallContext, interfaces []network.ProviderInterfaceInfo) error
}

Networking interface defines methods that environments with networking capabilities must implement.

type NetworkingEnviron

type NetworkingEnviron interface {
	// Environ represents a juju environment.
	Environ

	// Networking defines the methods of networking capable environments.
	Networking
}

NetworkingEnviron combines the standard Environ interface with the functionality for networking.

type NewEnvironFunc

type NewEnvironFunc func(context.Context, OpenParams) (Environ, error)

NewEnvironFunc is the type of a function that, given a model config, returns an Environ. This will typically be environs.New.

type NoSpaceDiscoveryEnviron

type NoSpaceDiscoveryEnviron struct{}

NoSpaceDiscoveryEnviron implements methods from Networking that represent an environ without native space support (all but MAAS at the time of writing). None of the method receiver references are used, so it can be embedded as nil without fear of panics.

func (*NoSpaceDiscoveryEnviron) ProviderSpaceInfo

ProviderSpaceInfo (Networking) indicates that this provider does not support returning provider info for the input space.

func (*NoSpaceDiscoveryEnviron) Spaces

Spaces (Networking) indicates that this provider does not support returning spaces.

func (*NoSpaceDiscoveryEnviron) SupportsSpaceDiscovery

func (*NoSpaceDiscoveryEnviron) SupportsSpaceDiscovery() (bool, error)

SupportsSpaceDiscovery (Networking) indicates that this environ does not support space discovery.

type NominatedStorageNotFound

type NominatedStorageNotFound struct {
	StorageName string
}

NominatedStorageNotFound is an error that indicates the storage the user nominated to use for a specific operation was not found and needs to be checked for existence or typo's.

func (*NominatedStorageNotFound) Error

func (n *NominatedStorageNotFound) Error() string

Error implements the error interface

type OpenParams

type OpenParams struct {
	// ControllerUUID is the controller UUID.
	ControllerUUID string

	// Cloud is the cloud specification to use to connect to the cloud.
	Cloud environscloudspec.CloudSpec

	// Config is the base configuration for the provider.
	Config *config.Config
}

OpenParams contains the parameters for EnvironProvider.Open.

type PrecheckInstanceParams

type PrecheckInstanceParams struct {
	// Base contains the base of the machine.
	Base corebase.Base

	// Constraints contains the machine constraints.
	Constraints constraints.Value

	// Placement contains the machine placement directive, if any.
	Placement string

	// VolumeAttachments contains the parameters for attaching existing
	// volumes to the instance. The PrecheckInstance method should not
	// expect the attachment's Machine field to be set, as PrecheckInstance
	// may be called before a machine ID is allocated.
	VolumeAttachments []storage.VolumeAttachmentParams
}

PrecheckInstanceParams contains the parameters for InstancePrechecker.PrecheckInstance.

type PrecheckJujuUpgradeOperation

type PrecheckJujuUpgradeOperation struct {
	// TargetVersion is the target juju version.
	TargetVersion version.Number

	// Steps contains the sequence of upgrade steps to apply when
	// upgrading to the accompanying target version number.
	Steps []PrecheckJujuUpgradeStep
}

PrecheckJujuUpgradeOperation contains a target agent version and sequence of upgrade precheck steps to apply to get to that version.

type PrecheckJujuUpgradeStep

type PrecheckJujuUpgradeStep interface {
	// Description is a human readable description of what the
	// precheck upgrade step does.
	Description() string

	// Run executes the precheck upgrade business logic.
	Run() error
}

PrecheckJujuUpgradeStep defines an idempotent operation that is run a specific precheck upgrade step on an Environ.

type PreferredStorageNotFound

type PreferredStorageNotFound struct {
	Message string
}

PreferredStorageNotFound is an error that indicates to the caller the environ was unable to completes it's operation because it could not find the storage it prefers for the operation. i.e aws block storage or Kubernetes cluster storage.

func (*PreferredStorageNotFound) Error

func (p *PreferredStorageNotFound) Error() string

Error implements the error interface

type PrepareConfigParams

type PrepareConfigParams struct {
	// Cloud is the cloud specification to use to connect to the cloud.
	Cloud environscloudspec.CloudSpec

	// Config is the base configuration for the provider. This should
	// be updated with the region, endpoint and credentials.
	Config *config.Config
}

PrepareConfigParams contains the parameters for EnvironProvider.PrepareConfig.

type ProviderCredentials

type ProviderCredentials interface {
	// CredentialSchemas returns credential schemas, keyed on
	// authentication type. These may be used to validate existing
	// credentials, or to generate new ones (e.g. to create an
	// interactive form.)
	CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema

	// DetectCredentials automatically detects one or more credentials
	// from the environment. This may involve, for example, inspecting
	// environment variables, or reading configuration files in
	// well-defined locations.
	//
	// If no credentials can be detected, DetectCredentials should
	// return an error satisfying errors.IsNotFound.
	//
	// If cloud name is not passed (empty-string), all credentials are
	// returned, otherwise only the credential for that cloud.
	DetectCredentials(cloudName string) (*cloud.CloudCredential, error)

	// FinalizeCredential finalizes a credential, updating any attributes
	// as necessary. This is always done client-side, when adding the
	// credential to credentials.yaml and before uploading credentials to
	// the controller. The provider may completely alter a credential, even
	// going as far as changing the auth-type, but the output must be a
	// fully formed credential.
	FinalizeCredential(
		FinalizeCredentialContext,
		FinalizeCredentialParams,
	) (*cloud.Credential, error)
}

ProviderCredentials is an interface that an EnvironProvider implements in order to validate and automatically detect credentials for clouds supported by the provider.

TODO(axw) replace CredentialSchemas with an updated environschema. The Dashboard also needs to be able to handle multiple credential types, and dependencies in config attributes.

type ProviderCredentialsRegister

type ProviderCredentialsRegister interface {

	// RegisterCredentials will return any credentials that need to be
	// registered for the provider.
	//
	// If no credentials can be found, RegisterCredentials should return
	// an error satisfying errors.IsNotFound.
	RegisterCredentials(cloud.Cloud) (map[string]*cloud.CloudCredential, error)
}

ProviderCredentialsRegister is an interface that an EnvironProvider implements in order to validate and automatically register credentials for clouds supported by the provider.

type ProviderRegistry

type ProviderRegistry interface {
	// RegisterProvider registers a new environment provider with the given
	// name, and zero or more aliases. If a provider already exists with the
	// given name or alias, an error will be returned.
	RegisterProvider(p EnvironProvider, providerType string, providerTypeAliases ...string) error

	// UnregisterProvider unregisters the environment provider with the given name.
	UnregisterProvider(providerType string)

	// RegisteredProviders returns the names of the registered environment
	// providers.
	RegisteredProviders() []string

	// Provider returns the environment provider with the specified name. If no
	// provider has been registered with the supplied name then an error
	// satisfying errors.NotFound is returned.
	Provider(providerType string) (EnvironProvider, error)
}

ProviderRegistry is an interface that provides methods for registering and obtaining environment providers by provider name.

func GlobalProviderRegistry

func GlobalProviderRegistry() ProviderRegistry

GlobalProviderRegistry returns the global provider registry.

type ProviderSchema

type ProviderSchema interface {
	// Schema returns the schema for the provider. It should
	// include all fields defined in environs/config, conventionally
	// by calling config.Schema.
	Schema() environschema.Fields
}

ProviderSchema can be implemented by a provider to provide access to its configuration schema. Once all providers implement this, it will be included in the EnvironProvider type and the information made available over the API.

type ProviderSpaceInfo

type ProviderSpaceInfo struct {
	network.SpaceInfo

	// Cloud type governs what attributes will exist in the
	// provider-specific map.
	CloudType string

	// Any provider-specific information to needed to identify the
	// network within the cloud, e.g. VPC ID for EC2.
	ProviderAttributes map[string]interface{}
}

ProviderSpaceInfo contains all the information about a space needed by another environ to decide whether it can be routed to.

type RequestFinalizeCredential

type RequestFinalizeCredential interface {

	// ShouldFinalizeCredential asks if a EnvironProvider wants to strictly
	// finalize a credential. The provider just returns true if they want to
	// call FinalizeCredential from ProviderCredentials when asked.
	ShouldFinalizeCredential(cloud.Credential) bool
}

RequestFinalizeCredential is an interface that an EnvironProvider implements in order to call ProviderCredentials.FinalizeCredential strictly rather than lazily to gather fully formed credentials.

type ResourceAdopter

type ResourceAdopter interface {
	// AdoptResources is called when the model is moved from one
	// controller to another using model migration. Some providers tag
	// instances, disks, and cloud storage with the controller UUID to
	// aid in clean destruction. This method will be called on the
	// environ for the target controller so it can update the
	// controller tags for all of those things. For providers that do
	// not track the controller UUID, a simple method returning nil
	// will suffice. The version number of the source controller is
	// provided for backwards compatibility - if the technique used to
	// tag items changes, the version number can be used to decide how
	// to remove the old tags correctly.
	AdoptResources(ctx envcontext.ProviderCallContext, controllerUUID string, fromVersion version.Number) error
}

type StartInstanceParams

type StartInstanceParams struct {
	// ControllerUUID is the uuid of the controller.
	ControllerUUID string

	// Constraints is a set of constraints on
	// the kind of instance to create.
	Constraints constraints.Value

	// Tools is a list of tools that may be used
	// to start a Juju agent on the machine.
	Tools tools.List

	// InstanceConfig describes the machine's configuration.
	InstanceConfig *instancecfg.InstanceConfig

	// Placement, if non-empty, contains an environment-specific
	// placement directive that may be used to decide how the
	// instance should be started.
	Placement string

	// AvailabilityZone, provides the name of the availability
	// zone required to start the instance.
	AvailabilityZone string

	// RootDisk is a set of parameters for creating the root disk volume.
	RootDisk *storage.VolumeParams

	// Volumes is a set of parameters for volumes that should be created.
	//
	// StartInstance need not check the value of the Attachment field,
	// as it is guaranteed that any volumes in this list are designated
	// for attachment to the instance being started.
	Volumes []storage.VolumeParams

	// VolumeAttachments is a set of parameters for existing volumes that
	// should be attached. If the StartInstance method does not attach the
	// volumes, they will be attached by the storage provisioner once the
	// machine has been created. The attachments are presented here to
	// give the provider an opportunity for the volume attachments to
	// influence the instance creation, e.g. by restricting the machine
	// to specific availability zones.
	VolumeAttachments []storage.VolumeAttachmentParams

	// NetworkInfo is an optional list of network interface details,
	// necessary to configure on the instance.
	NetworkInfo corenetwork.InterfaceInfos

	// SubnetsToZones is an optional collection of maps of provider-specific
	// subnet IDs to a list of availability zone names each subnet is available
	// in.
	// It is populated when valid positive spaces constraints are present,
	// or when the instance to be started will host an application with bound
	// endpoints.
	// The subnets present are derived from the union of
	// constrained/bound spaces.
	// Negative space constraints will have already been validated when
	// retrieving `ProvisioningInfo`.
	SubnetsToZones []map[corenetwork.Id][]string

	// EndpointBindings holds the mapping between application endpoint names to
	// provider-specific space IDs. It is populated when provisioning a machine
	// to host a unit of an application with endpoint bindings.
	EndpointBindings map[string]corenetwork.Id

	// ImageMetadata is a collection of image metadata
	// that may be used to start this instance.
	ImageMetadata []*imagemetadata.ImageMetadata

	// CleanupCallback is a callback to be used to clean up any residual
	// status-reporting output from StatusCallback.
	CleanupCallback func() error

	// StatusCallback is a callback to be used by the instance to report
	// changes in status. Its signature is consistent with other
	// status-related functions to allow them to be used as callbacks.
	StatusCallback StatusCallbackFunc

	// Abort is a channel that will be closed to indicate that the command
	// should be aborted.
	Abort <-chan struct{}

	// CharmLXDProfiles is a slice of names of lxd profiles to be used creating
	// the LXD container, if specified and an LXD container.  The profiles
	// come from charms deployed on the machine.
	CharmLXDProfiles []string
}

StartInstanceParams holds parameters for the InstanceBroker.StartInstance method.

type StartInstanceResult

type StartInstanceResult struct {
	// DisplayName is an optional human-readable string that's used
	// for display purposes only.
	DisplayName string

	// Instance is an interface representing a cloud instance.
	Instance instances.Instance

	// Config holds the environment config to be used for any further
	// operations, if the instance is for a controller.
	Config *config.Config

	// HardwareCharacteristics represents the hardware characteristics
	// of the newly created instance.
	Hardware *instance.HardwareCharacteristics

	// NetworkInfo contains information about how to configure network
	// interfaces on the instance. Depending on the provider, this
	// might be the same StartInstanceParams.NetworkInfo or may be
	// modified as needed.
	NetworkInfo corenetwork.InterfaceInfos

	// Volumes contains a list of volumes created, each one having the
	// same Name as one of the VolumeParams in StartInstanceParams.Volumes.
	// VolumeAttachment information is reported separately.
	Volumes []storage.Volume

	// VolumeAttachments contains a attachment-specific information about
	// volumes that were attached to the started instance.
	VolumeAttachments []storage.VolumeAttachment
}

StartInstanceResult holds the result of an InstanceBroker.StartInstance method call.

type StatusCallbackFunc

type StatusCallbackFunc func(ctx context.Context, settableStatus status.Status, info string, data map[string]interface{}) error

StatusCallbackFunc represents a function that can be called to report a status.

type SupportedFeatureEnumerator

type SupportedFeatureEnumerator interface {
	SupportedFeatures() (assumes.FeatureSet, error)
}

SupportedFeatureEnumerator is implemented by environments that can report the set of features that are available to charms deployed to them.

type UpgradeOperation

type UpgradeOperation struct {
	// TargetVersion is the target environ provider version number to
	// which the upgrade steps pertain. When a model is upgraded, all
	// upgrade operations will be run for versions greater than the
	// recorded environ version. This version number is independent of
	// the agent and controller versions.
	TargetVersion int

	// Steps contains the sequence of upgrade steps to apply when
	// upgrading to the accompanying target version number.
	Steps []UpgradeStep
}

UpgradeOperation contains a target agent version and sequence of upgrade steps to apply to get to that version.

type UpgradeOperationsParams

type UpgradeOperationsParams struct {
	// ControllerUUID is the UUID of the controller that manages
	// the Environ being upgraded.
	ControllerUUID string
}

UpgradeOperationsParams contains the parameters for Upgrader.UpgradeOperations.

type UpgradeStep

type UpgradeStep interface {
	// Description is a human readable description of what the upgrade
	// step does.
	Description() string

	// Run executes the upgrade business logic.
	Run(ctx envcontext.ProviderCallContext) error
}

UpgradeStep defines an idempotent operation that is run to perform a specific upgrade step on an Environ.

type Upgrader

type Upgrader interface {
	// UpgradeOperations returns a list of UpgradeOperations for upgrading
	// an Environ.
	UpgradeOperations(envcontext.ProviderCallContext, UpgradeOperationsParams) []UpgradeOperation
}

Upgrader is an interface that can be used for upgrading Environs. If an Environ implements this interface, its UpgradeOperations method will be invoked to identify operations that should be run on upgrade.

Directories

Path Synopsis
Package imagedownloads implements image-downloads metadata from simplestreams.
Package imagedownloads implements image-downloads metadata from simplestreams.
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
Package simplestreams supports locating, parsing, and filtering metadata in simplestreams format.
Package simplestreams supports locating, parsing, and filtering metadata in simplestreams format.
Code generated by MockGen.
Code generated by MockGen.

Jump to

Keyboard shortcuts

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