kotsstore

package
v1.91.3 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2022 License: Apache-2.0 Imports: 72 Imported by: 0

README

kotsstore

This backing store uses S3 for application archives and support bundles. In addition, this store uses rqlite for storage of all metadata and cache. There are some scenarios where this store uses the local Kubernetes cluster for storing some sensitive information (gitops, etc).

This is progressively migrating away from S3 and PG and into k8s native storage components.

Kubernetes Objects

To enable this store to function quickly, some data is stored in the cluster.

Design goals

This store must use a fixed number of configmaps and secrets per application stored, and the number will not scale with the number of versions of an app, time that an application has been running, or any other metric that's not controlled by the end user.

Activity on an application must not increase the number of objects stored in the cluster.

The store must be safe to operate with multiple replicas reading AND writing to the objects.

Sensitive data must be stored in secrets, while non sensitive data is stored in configmaps.

Use of ephemeral storage in the pod is limited and discouraged.

Documentation

Index

Constants

View Source
const (
	TaskStatusConfigMapName = `kotsadm-tasks`
	ConfgConfigMapName      = `kotsadm-confg`
)

Variables

View Source
var (
	ErrNotFound = errors.New("not found")
)
View Source
var (
	ErrTooManyAttempts = errors.New("too many attempts")
)

Functions

This section is empty.

Types

type KOTSStore

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

func StoreFromEnv

func StoreFromEnv() *KOTSStore

func (*KOTSStore) AddAppToAllDownstreams

func (s *KOTSStore) AddAppToAllDownstreams(appID string) error

func (*KOTSStore) AddDownstreamVersionDetails

func (s *KOTSStore) AddDownstreamVersionDetails(appID string, clusterID string, version *downstreamtypes.DownstreamVersion, checkIfDeployable bool) error

func (*KOTSStore) AddDownstreamVersionsDetails

func (s *KOTSStore) AddDownstreamVersionsDetails(appID string, clusterID string, versions []*downstreamtypes.DownstreamVersion, checkIfDeployable bool) error

func (*KOTSStore) ClearTaskStatus

func (s *KOTSStore) ClearTaskStatus(id string) error

func (*KOTSStore) CreateApp

func (s *KOTSStore) CreateApp(name string, upstreamURI string, licenseData string, isAirgapEnabled bool, skipImagePush bool, registryIsReadOnly bool) (*apptypes.App, error)

func (*KOTSStore) CreateAppVersion

func (s *KOTSStore) CreateAppVersion(appID string, baseSequence *int64, filesInDir string, source string, skipPreflights bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer) (int64, error)

func (*KOTSStore) CreateAppVersionArchive

func (s *KOTSStore) CreateAppVersionArchive(appID string, sequence int64, archivePath string) error

CreateAppVersion takes an unarchived app, makes an archive and then uploads it to s3 with the appID and sequence specified

func (*KOTSStore) CreateInProgressSupportBundle

func (s *KOTSStore) CreateInProgressSupportBundle(supportBundle *types.SupportBundle) error

func (*KOTSStore) CreateInitialBranding added in v1.86.2

func (s *KOTSStore) CreateInitialBranding(brandingArchive []byte) (string, error)

CreateInitialBranding creates a new initial branding archive

func (*KOTSStore) CreateNewCluster

func (s *KOTSStore) CreateNewCluster(userID string, isAllUsers bool, title string, token string) (string, error)

func (*KOTSStore) CreatePendingDownloadAppVersion

func (s *KOTSStore) CreatePendingDownloadAppVersion(appID string, update upstreamtypes.Update, kotsApplication *kotsv1beta1.Application, license *kotsv1beta1.License) (int64, error)

func (*KOTSStore) CreateScheduledInstanceSnapshot

func (s *KOTSStore) CreateScheduledInstanceSnapshot(id string, clusterID string, timestamp time.Time) error

func (*KOTSStore) CreateScheduledSnapshot

func (s *KOTSStore) CreateScheduledSnapshot(id string, appID string, timestamp time.Time) error

func (*KOTSStore) CreateSession

func (s *KOTSStore) CreateSession(forUser *usertypes.User, issuedAt time.Time, expiresAt time.Time, roles []string) (*sessiontypes.Session, error)

func (*KOTSStore) CreateSupportBundle

func (s *KOTSStore) CreateSupportBundle(id string, appID string, archivePath string, marshalledTree []byte) (*types.SupportBundle, error)

func (*KOTSStore) DeleteDownstreamDeployStatus

func (s *KOTSStore) DeleteDownstreamDeployStatus(appID string, clusterID string, sequence int64) error

func (*KOTSStore) DeleteExpiredSessions

func (s *KOTSStore) DeleteExpiredSessions() error

func (*KOTSStore) DeletePendingScheduledInstanceSnapshots

func (s *KOTSStore) DeletePendingScheduledInstanceSnapshots(clusterID string) error

func (*KOTSStore) DeletePendingScheduledSnapshots

func (s *KOTSStore) DeletePendingScheduledSnapshots(appID string) error

func (*KOTSStore) DeleteSession

func (s *KOTSStore) DeleteSession(id string) error

func (*KOTSStore) FindDownstreamVersions

func (s *KOTSStore) FindDownstreamVersions(appID string, downloadedOnly bool) (*downstreamtypes.DownstreamVersions, error)

func (*KOTSStore) FlagInvalidPassword

func (s *KOTSStore) FlagInvalidPassword() error

func (*KOTSStore) FlagSuccessfulLogin

func (s *KOTSStore) FlagSuccessfulLogin() error

func (*KOTSStore) GetAirgapInstallStatus

func (s *KOTSStore) GetAirgapInstallStatus(appID string) (*airgaptypes.InstallStatus, error)

func (*KOTSStore) GetAllAppLicenses

func (s *KOTSStore) GetAllAppLicenses() ([]*kotsv1beta1.License, error)

func (*KOTSStore) GetApp

func (s *KOTSStore) GetApp(id string) (*apptypes.App, error)

func (*KOTSStore) GetAppFromSlug

func (s *KOTSStore) GetAppFromSlug(slug string) (*apptypes.App, error)

func (*KOTSStore) GetAppIDFromSlug

func (s *KOTSStore) GetAppIDFromSlug(slug string) (string, error)

func (*KOTSStore) GetAppIDsFromRegistry

func (s *KOTSStore) GetAppIDsFromRegistry(hostname string) ([]string, error)

func (*KOTSStore) GetAppStatus

func (s *KOTSStore) GetAppStatus(appID string) (*appstatetypes.AppStatus, error)

func (*KOTSStore) GetAppVersion

func (s *KOTSStore) GetAppVersion(appID string, sequence int64) (*versiontypes.AppVersion, error)

func (*KOTSStore) GetAppVersionArchive

func (s *KOTSStore) GetAppVersionArchive(appID string, sequence int64, dstPath string) error

GetAppVersionArchive will fetch the archive and extract it into the given dstPath directory name

func (*KOTSStore) GetAppVersionBaseArchive

func (s *KOTSStore) GetAppVersionBaseArchive(appID string, versionLabel string) (string, int64, error)

GetAppVersionBaseArchive returns the base archive directory for a given version label. if the "versionLabel" param is empty or is not a valid semver, the archive of the latest version will be returned. the base archive directory contains data such as config values. caller is responsible for cleaning up the created archive dir. returns the path to the archive and the base sequence.

func (*KOTSStore) GetAppVersionBaseSequence

func (s *KOTSStore) GetAppVersionBaseSequence(appID string, versionLabel string) (int64, error)

GetAppVersionBaseSequence returns the base sequence for a given version label. if the "versionLabel" param is empty or is not a valid semver, the sequence of the latest version will be returned.

func (*KOTSStore) GetClusterIDFromDeployToken

func (s *KOTSStore) GetClusterIDFromDeployToken(deployToken string) (string, error)

func (*KOTSStore) GetClusterIDFromSlug

func (s *KOTSStore) GetClusterIDFromSlug(slug string) (string, error)

func (*KOTSStore) GetCurrentDownstreamSequence

func (s *KOTSStore) GetCurrentDownstreamSequence(appID string, clusterID string) (int64, error)

func (*KOTSStore) GetCurrentDownstreamVersion

func (s *KOTSStore) GetCurrentDownstreamVersion(appID string, clusterID string) (*downstreamtypes.DownstreamVersion, error)

func (*KOTSStore) GetCurrentParentSequence

func (s *KOTSStore) GetCurrentParentSequence(appID string, clusterID string) (int64, error)

func (*KOTSStore) GetCurrentUpdateCursor

func (s *KOTSStore) GetCurrentUpdateCursor(appID string, channelID string) (string, string, bool, error)

func (*KOTSStore) GetDownstream

func (s *KOTSStore) GetDownstream(clusterID string) (*downstreamtypes.Downstream, error)

func (*KOTSStore) GetDownstreamOutput

func (s *KOTSStore) GetDownstreamOutput(appID string, clusterID string, sequence int64) (*downstreamtypes.DownstreamOutput, error)

func (*KOTSStore) GetDownstreamVersionHistory

func (s *KOTSStore) GetDownstreamVersionHistory(appID string, clusterID string, currentPage int, pageSize int, pinLatest bool, pinLatestDeployable bool) (*downstreamtypes.DownstreamVersionHistory, error)

func (*KOTSStore) GetDownstreamVersionSource

func (s *KOTSStore) GetDownstreamVersionSource(appID string, sequence int64) (string, error)

GetDownstreamVersionSource gets the source for the downstream version with the given sequence and app id

func (*KOTSStore) GetDownstreamVersionStatus

func (s *KOTSStore) GetDownstreamVersionStatus(appID string, sequence int64) (types.DownstreamVersionStatus, error)

GetDownstreamVersionStatus gets the status for the downstream version with the given sequence and app id

func (*KOTSStore) GetDownstreamVersions

func (s *KOTSStore) GetDownstreamVersions(appID string, clusterID string, downloadedOnly bool) (*downstreamtypes.DownstreamVersions, error)

func (*KOTSStore) GetEmbeddedClusterAuthToken

func (s *KOTSStore) GetEmbeddedClusterAuthToken() (string, error)

func (*KOTSStore) GetIgnoreRBACErrors

func (s *KOTSStore) GetIgnoreRBACErrors(appID string, sequence int64) (bool, error)

func (*KOTSStore) GetInitialBranding added in v1.86.2

func (s *KOTSStore) GetInitialBranding() ([]byte, error)

GetInitialBranding returns the latest initial branding archive

func (*KOTSStore) GetLatestAppSequence

func (s *KOTSStore) GetLatestAppSequence(appID string, downloadedOnly bool) (int64, error)

GetLatestAppSequence returns the sequence of the latest app version. This function handles both semantic and non-semantic versions. If downloadedOnly param is set to true, the sequence of the latest downloaded app version will be returned.

func (*KOTSStore) GetLatestBranding added in v1.86.2

func (s *KOTSStore) GetLatestBranding() ([]byte, error)

GetLatestBranding returns the latest branding archive for any app

func (*KOTSStore) GetLatestBrandingForApp added in v1.86.2

func (s *KOTSStore) GetLatestBrandingForApp(appID string) ([]byte, error)

GetLatestBrandingForApp returns the latest branding archive for a specific app

func (*KOTSStore) GetLatestDeployableDownstreamVersion

func (s *KOTSStore) GetLatestDeployableDownstreamVersion(appID string, clusterID string) (latestDeployableVersion *downstreamtypes.DownstreamVersion, numOfSkippedVersions int, numOfRemainingVersions int, finalError error)

func (*KOTSStore) GetLatestLicenseForApp

func (s *KOTSStore) GetLatestLicenseForApp(appID string) (*kotsv1beta1.License, error)

func (*KOTSStore) GetLicenseForAppVersion

func (s *KOTSStore) GetLicenseForAppVersion(appID string, sequence int64) (*kotsv1beta1.License, error)

func (*KOTSStore) GetNextAppSequence

func (s *KOTSStore) GetNextAppSequence(appID string) (int64, error)

func (*KOTSStore) GetParentSequenceForSequence

func (s *KOTSStore) GetParentSequenceForSequence(appID string, clusterID string, sequence int64) (int64, error)

func (*KOTSStore) GetPasswordUpdatedAt

func (s *KOTSStore) GetPasswordUpdatedAt() (*time.Time, error)

GetPasswordUpdatedAt - returns the time the password was last updated

func (*KOTSStore) GetPendingAirgapUploadApp

func (s *KOTSStore) GetPendingAirgapUploadApp() (*airgaptypes.PendingApp, error)

func (*KOTSStore) GetPendingInstallationStatus

func (s *KOTSStore) GetPendingInstallationStatus() (*installationtypes.InstallStatus, error)

func (*KOTSStore) GetPreflightProgress

func (s *KOTSStore) GetPreflightProgress(appID string, sequence int64) (string, error)

func (*KOTSStore) GetPreflightResults

func (s *KOTSStore) GetPreflightResults(appID string, sequence int64) (*preflighttypes.PreflightResult, error)

func (*KOTSStore) GetPreviouslyDeployedSequence

func (s *KOTSStore) GetPreviouslyDeployedSequence(appID string, clusterID string) (int64, error)

func (*KOTSStore) GetPrometheusAddress

func (s *KOTSStore) GetPrometheusAddress() (string, error)

func (*KOTSStore) GetRedactions

func (s *KOTSStore) GetRedactions(id string) (troubleshootredact.RedactionList, error)

func (*KOTSStore) GetRegistryDetailsForApp

func (s *KOTSStore) GetRegistryDetailsForApp(appID string) (registrytypes.RegistrySettings, error)

func (*KOTSStore) GetSession

func (s *KOTSStore) GetSession(id string) (*sessiontypes.Session, error)

func (*KOTSStore) GetSharedPasswordBcrypt

func (s *KOTSStore) GetSharedPasswordBcrypt() ([]byte, error)

GetSharedPasswordBcrypt will return the hash of the current password that can be used to validate an auth request. This is in the store pkg, but the data may be in the cluster or the database, depending on the configuration.

func (*KOTSStore) GetStatusForVersion

func (s *KOTSStore) GetStatusForVersion(appID string, clusterID string, sequence int64) (types.DownstreamVersionStatus, error)

func (*KOTSStore) GetSupportBundle

func (s *KOTSStore) GetSupportBundle(id string) (*types.SupportBundle, error)

func (*KOTSStore) GetSupportBundleAnalysis

func (s *KOTSStore) GetSupportBundleAnalysis(id string) (*types.SupportBundleAnalysis, error)

func (*KOTSStore) GetSupportBundleArchive

func (s *KOTSStore) GetSupportBundleArchive(bundleID string) (string, error)

GetSupportBundle will fetch the bundle archive and return a path to where it is stored. The caller is responsible for deleting.

func (*KOTSStore) GetTargetKotsVersionForVersion

func (s *KOTSStore) GetTargetKotsVersionForVersion(appID string, sequence int64) (string, error)

func (*KOTSStore) GetTaskStatus

func (s *KOTSStore) GetTaskStatus(id string) (string, string, error)

func (*KOTSStore) HasStrictPreflights

func (s *KOTSStore) HasStrictPreflights(appID string, sequence int64) (bool, error)

func (*KOTSStore) Init

func (s *KOTSStore) Init() error

func (*KOTSStore) IsAppVersionDeployable

func (s *KOTSStore) IsAppVersionDeployable(appID string, sequence int64) (bool, string, error)

func (*KOTSStore) IsDownstreamDeploySuccessful

func (s *KOTSStore) IsDownstreamDeploySuccessful(appID string, clusterID string, sequence int64) (bool, error)

func (*KOTSStore) IsGitOpsEnabledForApp

func (s *KOTSStore) IsGitOpsEnabledForApp(appID string) (bool, error)

func (*KOTSStore) IsIdentityServiceSupportedForVersion

func (s *KOTSStore) IsIdentityServiceSupportedForVersion(appID string, sequence int64) (bool, error)

func (*KOTSStore) IsKotsadmIDGenerated

func (s *KOTSStore) IsKotsadmIDGenerated() (bool, error)

IsKotsadmIDGenerated retrieves the id of kotsadm if the pod is already

func (*KOTSStore) IsNotFound

func (s *KOTSStore) IsNotFound(err error) bool

func (*KOTSStore) IsRollbackSupportedForVersion

func (s *KOTSStore) IsRollbackSupportedForVersion(appID string, sequence int64) (bool, error)

func (*KOTSStore) IsSnapshotsSupportedForVersion

func (s *KOTSStore) IsSnapshotsSupportedForVersion(a *apptypes.App, sequence int64, renderer rendertypes.Renderer) (bool, error)

func (*KOTSStore) ListAppsForDownstream

func (s *KOTSStore) ListAppsForDownstream(clusterID string) ([]*apptypes.App, error)

func (*KOTSStore) ListClusters

func (s *KOTSStore) ListClusters() ([]*downstreamtypes.Downstream, error)

func (*KOTSStore) ListDownstreamsForApp

func (s *KOTSStore) ListDownstreamsForApp(appID string) ([]downstreamtypes.Downstream, error)

func (*KOTSStore) ListFailedApps

func (s *KOTSStore) ListFailedApps() ([]*apptypes.App, error)

func (*KOTSStore) ListInstalledAppSlugs

func (s *KOTSStore) ListInstalledAppSlugs() ([]string, error)

func (*KOTSStore) ListInstalledApps

func (s *KOTSStore) ListInstalledApps() ([]*apptypes.App, error)

func (*KOTSStore) ListPendingScheduledInstanceSnapshots

func (s *KOTSStore) ListPendingScheduledInstanceSnapshots(clusterID string) ([]snapshottypes.ScheduledInstanceSnapshot, error)

func (*KOTSStore) ListPendingScheduledSnapshots

func (s *KOTSStore) ListPendingScheduledSnapshots(appID string) ([]snapshottypes.ScheduledSnapshot, error)

func (*KOTSStore) ListSupportBundles

func (s *KOTSStore) ListSupportBundles(appID string) ([]*types.SupportBundle, error)

func (*KOTSStore) MarkAsCurrentDownstreamVersion

func (s *KOTSStore) MarkAsCurrentDownstreamVersion(appID string, sequence int64) error

func (*KOTSStore) RemoveApp

func (s *KOTSStore) RemoveApp(appID string) error

func (*KOTSStore) ResetAirgapInstallInProgress

func (s *KOTSStore) ResetAirgapInstallInProgress(appID string) error

func (*KOTSStore) ResetPreflightResults

func (s *KOTSStore) ResetPreflightResults(appID string, sequence int64) error

func (*KOTSStore) RunMigrations

func (s *KOTSStore) RunMigrations()

func (*KOTSStore) SetAppChannelChanged

func (s *KOTSStore) SetAppChannelChanged(appID string, channelChanged bool) error

func (*KOTSStore) SetAppInstallState

func (s *KOTSStore) SetAppInstallState(appID string, state string) error

func (*KOTSStore) SetAppIsAirgap

func (s *KOTSStore) SetAppIsAirgap(appID string, isAirgap bool) error

func (*KOTSStore) SetAppStatus

func (s *KOTSStore) SetAppStatus(appID string, resourceStates appstatetypes.ResourceStates, updatedAt time.Time, sequence int64) error

func (*KOTSStore) SetAutoDeploy

func (s *KOTSStore) SetAutoDeploy(appID string, autoDeploy apptypes.AutoDeploy) error

func (*KOTSStore) SetDownstreamVersionStatus

func (s *KOTSStore) SetDownstreamVersionStatus(appID string, sequence int64, status types.DownstreamVersionStatus, statusInfo string) error

SetDownstreamVersionStatus updates the status and status info for the downstream version with the given sequence and app id

func (*KOTSStore) SetEmbeddedClusterAuthToken

func (s *KOTSStore) SetEmbeddedClusterAuthToken(token string) error

func (*KOTSStore) SetIgnorePreflightPermissionErrors

func (s *KOTSStore) SetIgnorePreflightPermissionErrors(appID string, sequence int64) error

func (*KOTSStore) SetInstanceSnapshotSchedule

func (s *KOTSStore) SetInstanceSnapshotSchedule(clusterID string, snapshotSchedule string) error

func (*KOTSStore) SetInstanceSnapshotTTL

func (s *KOTSStore) SetInstanceSnapshotTTL(clusterID string, snapshotTTL string) error

func (*KOTSStore) SetIsKotsadmIDGenerated

func (s *KOTSStore) SetIsKotsadmIDGenerated() error

SetIsKotsadmIDGenerated sets the status to true if the pod is starting for the first time

func (*KOTSStore) SetPreflightProgress

func (s *KOTSStore) SetPreflightProgress(appID string, sequence int64, progress string) error

func (*KOTSStore) SetPreflightResults

func (s *KOTSStore) SetPreflightResults(appID string, sequence int64, results []byte) error

func (*KOTSStore) SetPrometheusAddress

func (s *KOTSStore) SetPrometheusAddress(address string) error

func (*KOTSStore) SetRedactions

func (s *KOTSStore) SetRedactions(id string, redacts troubleshootredact.RedactionList) error

func (*KOTSStore) SetSnapshotSchedule

func (s *KOTSStore) SetSnapshotSchedule(appID string, snapshotSchedule string) error

func (*KOTSStore) SetSnapshotTTL

func (s *KOTSStore) SetSnapshotTTL(appID string, snapshotTTL string) error

func (*KOTSStore) SetSupportBundleAnalysis

func (s *KOTSStore) SetSupportBundleAnalysis(id string, results []byte) error

func (*KOTSStore) SetTaskStatus

func (s *KOTSStore) SetTaskStatus(id string, message string, status string) error

func (*KOTSStore) SetUpdateCheckerSpec

func (s *KOTSStore) SetUpdateCheckerSpec(appID string, updateCheckerSpec string) error

func (*KOTSStore) UpdateAppLicense

func (s *KOTSStore) UpdateAppLicense(appID string, baseSequence int64, archiveDir string, newLicense *kotsv1beta1.License, originalLicenseData string, channelChanged bool, failOnVersionCreate bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer) (int64, error)

func (*KOTSStore) UpdateAppLicenseSyncNow

func (s *KOTSStore) UpdateAppLicenseSyncNow(appID string) error

func (*KOTSStore) UpdateAppVersion

func (s *KOTSStore) UpdateAppVersion(appID string, sequence int64, baseSequence *int64, filesInDir string, source string, skipPreflights bool, gitops gitopstypes.DownstreamGitOps, renderer rendertypes.Renderer) error

func (*KOTSStore) UpdateAppVersionInstallationSpec

func (s *KOTSStore) UpdateAppVersionInstallationSpec(appID string, sequence int64, installation kotsv1beta1.Installation) error

func (*KOTSStore) UpdateDownstreamDeployStatus

func (s *KOTSStore) UpdateDownstreamDeployStatus(appID string, clusterID string, sequence int64, isError bool, output downstreamtypes.DownstreamOutput) error

func (*KOTSStore) UpdateNextAppVersionDiffSummary

func (s *KOTSStore) UpdateNextAppVersionDiffSummary(appID string, baseSequence int64) error

func (*KOTSStore) UpdateRegistry

func (s *KOTSStore) UpdateRegistry(appID string, hostname string, username string, password string, namespace string, isReadOnly bool) error

func (*KOTSStore) UpdateScheduledInstanceSnapshot

func (s *KOTSStore) UpdateScheduledInstanceSnapshot(snapshotID string, backupName string) error

func (*KOTSStore) UpdateScheduledSnapshot

func (s *KOTSStore) UpdateScheduledSnapshot(snapshotID string, backupName string) error

func (*KOTSStore) UpdateSessionExpiresAt

func (s *KOTSStore) UpdateSessionExpiresAt(id string, expiresAt time.Time) error

func (*KOTSStore) UpdateSupportBundle

func (s *KOTSStore) UpdateSupportBundle(bundle *types.SupportBundle) error

UpdateSupportBundle updates the support bundle definition in the secret

func (*KOTSStore) UpdateTaskStatusTimestamp

func (s *KOTSStore) UpdateTaskStatusTimestamp(id string) error

func (*KOTSStore) UploadSupportBundle

func (s *KOTSStore) UploadSupportBundle(id string, archivePath string, marshalledTree []byte) error

UploadSupportBundle pushes the metadata file and support bundle archive to the file store

func (*KOTSStore) WaitForReady

func (s *KOTSStore) WaitForReady(ctx context.Context) error

type SessionMetadata

type SessionMetadata struct {
	Roles []string
}

type TaskStatus

type TaskStatus struct {
	Message   string    `json:"message"`
	Status    string    `json:"status"`
	UpdatedAt time.Time `json:"updatedAt"`
}

Jump to

Keyboard shortcuts

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