forge

package
v0.0.0-...-2e8aeb9 Latest Latest
Warning

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

Go to latest
Published: Jul 26, 2023 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package forge groups the methods used to forge the Kubernetes object definitions required by the different controllers.

Package forge groups the methods used to forge the Kubernetes object definitions required by the different controllers.

Index

Constants

View Source
const (
	// WebsockifyName -> name of the websockify sidecar container.
	WebsockifyName = "websockify"
	// XVncName -> name of the x+vnc server sidecar container.
	XVncName = "xvnc"
	// PersistentVolumeName -> name of the persistent volume.
	PersistentVolumeName = "persistent"
	// ContentDownloaderName -> name of the downloader initcontainer.
	ContentDownloaderName = "content-downloader"
	// ContentUploaderName -> name of the uploader initcontainer.
	ContentUploaderName = "content-uploader"
	// PersistentDefaultMountPath -> default path for the container's pvc or persistent storage.
	PersistentDefaultMountPath = "/media/data"
	// HealthzEndpoint -> default endpoint for HTTP probes.
	HealthzEndpoint = "/healthz"
	// CrownLabsUserID -> used as UID and GID for containers security context.
	CrownLabsUserID = int64(1010)
	// SubmissionJobMaxRetries -> max number of retries for submission jobs.
	SubmissionJobMaxRetries = 10
	// SubmissionJobTTLSeconds -> seconds for submission jobs before deletion (either failure or success).
	SubmissionJobTTLSeconds = 300
	// AppCPULimitsEnvName -> name of the env variable containing AppContainer CPU limits.
	AppCPULimitsEnvName = "APP_CPU_LIMITS"
	// AppMEMLimitsEnvName -> name of the env variable containing AppContainer memory limits.
	AppMEMLimitsEnvName = "APP_MEM_LIMITS"
	// PodNameEnvName -> name of the env variable containing the Pod Name.
	PodNameEnvName = "POD_NAME"
	// MyDriveVolumeName -> Name of the NFS volume.
	MyDriveVolumeName = "mydrive"
	// MyDriveVolumeMountPath -> Mount path for the NFS personal volume.
	MyDriveVolumeMountPath = "/media/mydrive"
)
View Source
const (
	// IngressInstancePrefix -> the prefix prepended to the path of any ingresses targeting the instance or its subresources.
	IngressInstancePrefix = "/instance"

	// IngressGUINameSuffix -> the suffix added to the name of the ingress targeting the environment GUI.
	IngressGUINameSuffix = "gui"
	// IngressAppSuffix -> the suffix added to the path of the ingress targeting standalone and container environments.
	IngressAppSuffix = "app"

	// IngressDefaultCertificateName -> the name of the secret containing the crownlabs certificate.
	IngressDefaultCertificateName = "crownlabs-ingress-secret"

	// IngressVNCGUIPathSuffix -> the suffix appended to the path of the ingress targeting the environment GUI websocketed vnc endpoint.
	IngressVNCGUIPathSuffix = "vnc"

	// WebsockifyRewriteEndpoint -> endpoint of the websocketed vnc server.
	WebsockifyRewriteEndpoint = "/websockify"
	// StandaloneRewriteEndpoint -> endpoint of the standalone application.
	StandaloneRewriteEndpoint = "/$2"
)
View Source
const (

	// InstanceTerminationSelectorLabel -> label for Instances which have to be be checked for termination.
	InstanceTerminationSelectorLabel = "crownlabs.polito.it/watch-for-instance-termination"
	// InstanceSubmissionSelectorLabel -> label for Instances which have to be submitted.
	InstanceSubmissionSelectorLabel = "crownlabs.polito.it/instance-submission-requested"
	// InstanceSubmissionCompletedLabel -> label for Instances that have been submitted.
	InstanceSubmissionCompletedLabel = "crownlabs.polito.it/instance-submission-completed"
)
View Source
const (
	// InstancesCountKey -> The key for accessing at the total number of instances in the corev1.ResourceList map.
	InstancesCountKey = "count/instances.crownlabs.polito.it"

	// CapInstance -> The cap number of instances that can be requested by a Tenant.
	CapInstance = 10
)
View Source
const (
	// SSHPortNumber -> the port the SSH daemon is exposed to.
	SSHPortNumber = 22
	// GUIPortNumber -> the port the GUI service is exposed to.
	GUIPortNumber = 6080
	// MyDrivePortNumber -> the port the "MyDrive" service is exposed to.
	MyDrivePortNumber = 8080
	// XVncPortNumber -> the port in the container in which the X server is accessible through VNC.
	XVncPortNumber = 5900
	// MetricsPortNumber -> the port in the container in which the metrics server is accessible.
	MetricsPortNumber = 9090

	// SSHPortName -> the name of the port the SSH daemon is exposed to.
	SSHPortName = "ssh"
	// GUIPortName -> the name of the port the NoVNC service is exposed to.
	GUIPortName = "gui"
	// MyDrivePortName -> the name of the port the "MyDrive" service is exposed to.
	MyDrivePortName = "mydrive"
	// XVncPortName -> the name of the port through which the X server is accessible through VNC.
	XVncPortName = "xvnc"
	// MetricsPortName -> the name of the port through which the metrics are exposed.
	MetricsPortName = "metrics"
)
View Source
const (
	// StringSeparator -> the separator used to concatenate string.
	StringSeparator = "-"
)

Variables

View Source
var (
	// DefaultDivisor -> "0".
	DefaultDivisor = *resource.NewQuantity(0, "")
	// MilliDivisor -> "1m".
	MilliDivisor = *resource.NewMilliQuantity(1, resource.DecimalSI)
)
View Source
var (
	// CapCPU -> The cap amount of CPU cores that can be requested by a Tenant.
	CapCPU = *resource.NewQuantity(25, resource.DecimalSI)

	// CapMemory -> The cap amount of RAM memory that can be requested by a Tenant.
	CapMemory = *resource.NewScaledQuantity(50, resource.Giga)

	// SandboxCPUQuota -> The maximum amount of CPU cores that can be used by a sandbox namespace.
	SandboxCPUQuota = *resource.NewQuantity(4, resource.DecimalSI)

	// SandboxRequestCPUQuota -> The maximum amount of CPU cores that can be requested by a sandbox namespace.
	SandboxRequestCPUQuota = *resource.NewQuantity(2, resource.DecimalSI)

	// SandboxMemoryQuota -> The maximum amount of RAM memory that can be used by a sandbox namespace.
	SandboxMemoryQuota = *resource.NewScaledQuantity(8, resource.Giga)
)

Functions

func AddContainerArg

func AddContainerArg(c *corev1.Container, name, value string)

AddContainerArg appends an argument to the given container's args in the format of --name=value.

func AddContainerVolumeMount

func AddContainerVolumeMount(c *corev1.Container, name, path string)

AddContainerVolumeMount appends a VolumeMount to the given container's volumeMounts.

func AddEnvVariableFromFieldToContainer

func AddEnvVariableFromFieldToContainer(c *corev1.Container, name, value string)

AddEnvVariableFromFieldToContainer appends an environment variable to the given container's env with a generic field-referenced value.

func AddEnvVariableFromResourcesToContainer

func AddEnvVariableFromResourcesToContainer(c *corev1.Container, envVarName, srcContainerName string, resName corev1.ResourceName, divisor resource.Quantity)

AddEnvVariableFromResourcesToContainer appends an environment variable to the given container's env with a resource-referenced value from the source container.

func AddEnvVariableToContainer

func AddEnvVariableToContainer(c *corev1.Container, name, value string)

AddEnvVariableToContainer appends an environment variable to the given container's env with the specified value.

func AddTCPPortToContainer

func AddTCPPortToContainer(c *corev1.Container, name string, port int)

AddTCPPortToContainer appends a TCP port to the given container's ports.

func AppContainer

func AppContainer(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, volumeMountPath string) corev1.Container

AppContainer forges the main application container of the environment.

func CanonicalSandboxName

func CanonicalSandboxName(name string) string

CanonicalSandboxName returns a name given a tenant name.

func CapIntegerQuantity

func CapIntegerQuantity(quantity, capQuantity uint32) uint32

CapIntegerQuantity compares an unsigned integer value with a given cap and returns the lower.

func CapResourceQuantity

func CapResourceQuantity(quantity, capQuantity resource.Quantity) resource.Quantity

CapResourceQuantity compares a resource.Quantity value with a given cap and returns the lower.

func CloudInitUserData

func CloudInitUserData(nfsServerName, nfsPath string, publicKeys []string) ([]byte, error)

CloudInitUserData forges the yaml manifest representing the cloud-init userdata configuration.

func ContainerProbe

func ContainerProbe() *corev1.Probe

ContainerProbe forges a Probe with certain preset values and no handler.

func ContainerVolume

func ContainerVolume(volumeName, claimName string, environment *clv1alpha2.Environment) corev1.Volume

ContainerVolume forges a Volume containing a PVC source in case of persistent envs, an emptydir in case of non persistent envs.

func ContainerVolumes

func ContainerVolumes(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, nfsServerName, nfsPath string) []corev1.Volume

ContainerVolumes forges the list of volumes for the deployment spec, possibly returning an empty list in case the environment is not standard and not persistent.

func ContainersSpec

func ContainersSpec(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, opts *ContainerEnvOpts) []corev1.Container

ContainersSpec returns the Containers obj based on Environment Type.

func ContentDownloaderInitContainer

func ContentDownloaderInitContainer(contentOrigin string, ceOpts *ContainerEnvOpts) corev1.Container

ContentDownloaderInitContainer forges a Container to be used as initContainer for downloading and decompressing an archive file into the <MyDriveName> volume.

func ContentUploaderJobContainer

func ContentUploaderJobContainer(contentDestination, filename string, ceOpts *ContainerEnvOpts) corev1.Container

ContentUploaderJobContainer forges a Container to be used within a Job to compress and upload an archive file from the <MyDriveName> volume.

func DataVolumeSourceForge

func DataVolumeSourceForge(environment *clv1alpha2.Environment) *cdiv1beta1.DataVolumeSource

DataVolumeSourceForge forges the DataVolumeSource for DataVolumeTemplate.

func DataVolumeTemplate

func DataVolumeTemplate(name string, environment *clv1alpha2.Environment) virtv1.DataVolumeTemplateSpec

DataVolumeTemplate forges the DataVolume template associated with a given environment.

func DeploymentSpec

func DeploymentSpec(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, nfsServerName, nfsPath string, opts *ContainerEnvOpts) appsv1.DeploymentSpec

DeploymentSpec forges the complete DeploymentSpec (without replicas) containing the needed sidecars for X-VNC based container instances.

func GenericContainer

func GenericContainer(name, image string) corev1.Container

GenericContainer forges a Container specification with a restrictive security context.

func HostName

func HostName(baseHostName string, mode clv1alpha2.EnvironmentMode) string

HostName returns the hostname based on the given EnvironmentMode.

func IngressAuthenticationAnnotations

func IngressAuthenticationAnnotations(annotations map[string]string, instancesAuthURL string) map[string]string

IngressAuthenticationAnnotations receives in input a set of annotations and returns the updated set including the ones required to enable the authentication in front of an ingress resource. instancesAuthURL represents the URL of an exposed oauth2-proxy instance properly configured.

func IngressGUIAnnotations

func IngressGUIAnnotations(environment *clv1alpha2.Environment, annotations map[string]string) map[string]string

IngressGUIAnnotations receives in input a set of annotations and returns the updated set including the ones associated with the ingress targeting the environment GUI.

func IngressGUICleanPath

func IngressGUICleanPath(instance *clv1alpha2.Instance) string

IngressGUICleanPath returns the path of the ingress targeting the environment GUI vnc or Standalone, without the url-rewrite's regex.

func IngressGUIName

func IngressGUIName(environment *clv1alpha2.Environment) string

IngressGUIName returns the name of the ingress resource.

func IngressGUIPath

func IngressGUIPath(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment) string

IngressGUIPath returns the path of the ingress targeting the environment GUI vnc or Standalone.

func IngressGuiStatusURL

func IngressGuiStatusURL(host string, environment *clv1alpha2.Environment, instance *clv1alpha2.Instance) string

IngressGuiStatusURL returns the path of the ingress targeting the environment.

func IngressMyDriveAnnotations

func IngressMyDriveAnnotations(annotations map[string]string) map[string]string

IngressMyDriveAnnotations receives in input a set of annotations and returns the updated set including the ones associated with the ingress targeting the environment "MyDrive".

func IngressSpec

func IngressSpec(host, path, certificateName, serviceName, servicePort string) netv1.IngressSpec

IngressSpec forges the specification of a Kubernetes Ingress resource.

func InitContainers

func InitContainers(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, opts *ContainerEnvOpts) []corev1.Container

InitContainers forges the list of initcontainers for the container based environment.

func InstanceAutomationLabelsOnSubmission

func InstanceAutomationLabelsOnSubmission(labels map[string]string, submissionSucceded bool) map[string]string

InstanceAutomationLabelsOnSubmission returns a set of labels to be set on an instance when it is submitted.

func InstanceAutomationLabelsOnTermination

func InstanceAutomationLabelsOnTermination(labels map[string]string, submissionRequired bool) map[string]string

InstanceAutomationLabelsOnTermination returns a set of labels to be set on an instance when it is terminated.

func InstanceComponentLabels

func InstanceComponentLabels(instance *clv1alpha2.Instance, componentName string) map[string]string

InstanceComponentLabels returns a set of labels to be set on an instance component when it is created.

func InstanceHostname

func InstanceHostname(environment *clv1alpha2.Environment) string

InstanceHostname forges the hostname of the instance: empty for standard mode (will use pod name) or the lowercase mode otherwise.

func InstanceLabels

func InstanceLabels(labels map[string]string, template *clv1alpha2.Template, instCustomizationUrls *clv1alpha2.InstanceCustomizationUrls) (map[string]string, bool)

InstanceLabels receives in input a set of labels and returns the updated set depending on the specified template, along with a boolean value indicating whether an update should be performed.

func InstanceNameFromLabels

func InstanceNameFromLabels(labels map[string]string) (string, bool)

InstanceNameFromLabels receives in input a set of labels and returns the instance name, if any.

func InstanceObjectLabels

func InstanceObjectLabels(labels map[string]string, instance *clv1alpha2.Instance) map[string]string

InstanceObjectLabels receives in input a set of labels and returns the updated set depending on the specified instance.

func InstanceSelectorLabels

func InstanceSelectorLabels(instance *clv1alpha2.Instance) map[string]string

InstanceSelectorLabels returns a set of selector labels depending on the specified instance.

func MonitorableServiceLabels

func MonitorableServiceLabels(labels map[string]string) map[string]string

MonitorableServiceLabels returns adds a label for a service so that it is monitored by the Instance ServiceMonitor.

func MyDriveVolume

func MyDriveVolume(volumeName, nfsServerName, nfsPath string) corev1.Volume

MyDriveVolume returns the Personal volume of the tenant.

func NamespacedName

func NamespacedName(instance *clv1alpha2.Instance) types.NamespacedName

NamespacedName returns the namespace/name pair given an instance object.

func NamespacedNameToObjectMeta

func NamespacedNameToObjectMeta(namespacedName types.NamespacedName) metav1.ObjectMeta

NamespacedNameToObjectMeta returns the ObjectMeta corresponding to a NamespacedName.

func NamespacedNameWithSuffix

func NamespacedNameWithSuffix(instance *clv1alpha2.Instance, suffix string) types.NamespacedName

NamespacedNameWithSuffix returns the namespace/name pair given an instance object and a name suffix.

func NeedsInitContainer

func NeedsInitContainer(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment) (value bool, contentOrigin string)

NeedsInitContainer returns true if the environment requires an initcontainer in order to be prepopulated.

func ObjectMeta

func ObjectMeta(instance *clv1alpha2.Instance) metav1.ObjectMeta

ObjectMeta returns the namespace/name pair given an instance object.

func ObjectMetaWithSuffix

func ObjectMetaWithSuffix(instance *clv1alpha2.Instance, suffix string) metav1.ObjectMeta

ObjectMetaWithSuffix returns the namespace/name pair given an instance object and a name suffix.

func PVCSpec

PVCSpec forges a ReadWriteOnce PersistentVolumeClaimSpec with requests set as in environment.Resources.Disk.

func PVCStorageClassName

func PVCStorageClassName(environment *clv1alpha2.Environment) *string

PVCStorageClassName returns the storage class configured as option, or nil if empty.

func PersistentMountPath

func PersistentMountPath(environment *clv1alpha2.Environment) string

PersistentMountPath returns the path on which mounting the persistent volume.

func PodSecurityContext

func PodSecurityContext() *corev1.PodSecurityContext

PodSecurityContext forges a PodSecurityContext with 1010 UID and GID and RunAsNonRoot set.

func PodSpec

func PodSpec(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, nfsServerName, nfsPath string, opts *ContainerEnvOpts) corev1.PodSpec

PodSpec forges the pod specification for X-VNC based container instance.

func RandomInstancePrettyName

func RandomInstancePrettyName() string

RandomInstancePrettyName generates a random name of 2 capitalized words.

func ReplicasCount

func ReplicasCount(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, isNew bool) *int32

ReplicasCount returns an int32 pointer to 1 if the instance is not persistent or, if persistent, in case environment spec is set as running; 0 otherwise.

func RestrictiveSecurityContext

func RestrictiveSecurityContext() *corev1.SecurityContext

RestrictiveSecurityContext forges an unprivileged SecurityContext to ensure insulation.

func SandboxLimitRangeSpec

func SandboxLimitRangeSpec() corev1.LimitRangeSpec

SandboxLimitRangeSpec forges the Limit Range spec for sandbox namespaces.

func SandboxObjectLabels

func SandboxObjectLabels(labels map[string]string, name string) map[string]string

SandboxObjectLabels receives in input a set of labels and the tenant name, returns the updated set.

func SandboxResourceQuotaSpec

func SandboxResourceQuotaSpec() corev1.ResourceList

SandboxResourceQuotaSpec forges the Resource Quota spec for sandbox namespaces.

func ServiceSpec

func ServiceSpec(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment) corev1.ServiceSpec

ServiceSpec forges the specification of a Kubernetes Service resource providing access to a CrownLabs environment.

func SetContainerReadinessHTTPProbe

func SetContainerReadinessHTTPProbe(c *corev1.Container, portName, path string)

SetContainerReadinessHTTPProbe sets the given container's ReadinessProbe with a HTTPGet handler.

func SetContainerReadinessTCPProbe

func SetContainerReadinessTCPProbe(c *corev1.Container, portName string)

SetContainerReadinessTCPProbe sets the given container's ReadinessProbe with a TCPSocket handler.

func SetContainerResources

func SetContainerResources(c *corev1.Container, cpuRequests, cpuLimits float32, memRequestsMi, memLimitsMi int)

SetContainerResources sets the given container's Resources with the given values: cpu values are converted to millis: 1.2 -> 1200m; ram sizes are in MiB.

func SetContainerResourcesFromEnvironment

func SetContainerResourcesFromEnvironment(c *corev1.Container, env *clv1alpha2.Environment)

SetContainerResourcesFromEnvironment sets the given container's Resources starting from the Resources specified inside the environment.

func StandaloneContainer

func StandaloneContainer(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, volumeMountPath string) corev1.Container

StandaloneContainer forges the Standalone application container of the environment.

func SubmissionJobSpec

func SubmissionJobSpec(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment, opts *ContainerEnvOpts) batchv1.JobSpec

SubmissionJobSpec returns the job spec for the submission job.

func TenantResourceList

func TenantResourceList(workspaces []clv1alpha1.Workspace, override *clv1alpha2.TenantResourceQuota) clv1alpha2.TenantResourceQuota

TenantResourceList forges the Tenant Resource Quota as the value defined in TenantSpec, if any, otherwise it keeps the sum of all quota for each workspace.

func TenantResourceQuotaSpec

func TenantResourceQuotaSpec(quota *clv1alpha2.TenantResourceQuota) corev1.ResourceList

TenantResourceQuotaSpec forges the Resource Quota spec as the value defined in TenantStatus.

func VirtualMachineCPULimits

func VirtualMachineCPULimits(environment *clv1alpha2.Environment) resource.Quantity

VirtualMachineCPULimits computes the CPU limits based on a given environment.

func VirtualMachineCPURequests

func VirtualMachineCPURequests(environment *clv1alpha2.Environment) resource.Quantity

VirtualMachineCPURequests computes the CPU requests based on a given environment.

func VirtualMachineDomain

func VirtualMachineDomain(environment *clv1alpha2.Environment) virtv1.DomainSpec

VirtualMachineDomain forges the specification of the domain of a Kubevirt VirtualMachineInstance object representing the definition of the VM corresponding to a given CrownLabs Environment.

func VirtualMachineInstanceSpec

func VirtualMachineInstanceSpec(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment) virtv1.VirtualMachineInstanceSpec

VirtualMachineInstanceSpec forges the specification of a Kubevirt VirtualMachineInstance object representing the definition of the VMI corresponding to a non-persistent CrownLabs Environment.

func VirtualMachineMemoryRequirements

func VirtualMachineMemoryRequirements(environment *clv1alpha2.Environment) resource.Quantity

VirtualMachineMemoryRequirements computes the memory requirements based on a given environment.

func VirtualMachineReadinessProbe

func VirtualMachineReadinessProbe(environment *clv1alpha2.Environment) *virtv1.Probe

VirtualMachineReadinessProbe forges the readiness probe for a given VM environment.

func VirtualMachineResources

func VirtualMachineResources(environment *clv1alpha2.Environment) virtv1.ResourceRequirements

VirtualMachineResources forges the resource requirements for a given VM environment.

func VirtualMachineSpec

func VirtualMachineSpec(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment) virtv1.VirtualMachineSpec

VirtualMachineSpec forges the specification of a Kubevirt VirtualMachine object representing the definition of the VM corresponding to a persistent CrownLabs environment.

func VolumeCloudInit

func VolumeCloudInit(secretName string) virtv1.Volume

VolumeCloudInit forges the specification of a volume mapping to a secret containing the cloud-init configuration.

func VolumeContainerDisk

func VolumeContainerDisk(image string) virtv1.Volume

VolumeContainerDisk forges the specification of a volume mapping an ephemeral container containing the root image.

func VolumeDiskTarget

func VolumeDiskTarget(name string) virtv1.Disk

VolumeDiskTarget forges the specification of a KVM disk attached to volume.

func VolumeDiskTargets

func VolumeDiskTargets(environment *clv1alpha2.Environment) []virtv1.Disk

VolumeDiskTargets forges the array of disks to be attached to the VM Domain.

func VolumePersistentDisk

func VolumePersistentDisk(dataVolumeName string) virtv1.Volume

VolumePersistentDisk forges the specification of a volume mapping a DataVolume containing the root image.

func VolumeRootDisk

func VolumeRootDisk(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment) virtv1.Volume

VolumeRootDisk forges the specification of the root volume, either ephemeral or persistent based on the environment characteristics.

func Volumes

func Volumes(instance *clv1alpha2.Instance, environment *clv1alpha2.Environment) []virtv1.Volume

Volumes forges the array of volumes to be mounted onto the VMI specification.

func WebsockifyContainer

func WebsockifyContainer(opts *ContainerEnvOpts, environment *clv1alpha2.Environment, instance *clv1alpha2.Instance) corev1.Container

WebsockifyContainer forges the sidecar container to proxy requests from websocket to the VNC server.

func XVncContainer

func XVncContainer(opts *ContainerEnvOpts) corev1.Container

XVncContainer forges the sidecar container which holds the desktop environment through a X+VNC server.

Types

type ContainerEnvOpts

type ContainerEnvOpts struct {
	ImagesTag            string
	XVncImg              string
	WebsockifyImg        string
	ContentDownloaderImg string
	ContentUploaderImg   string
	InstMetricsEndpoint  string
}

ContainerEnvOpts contains images name and tag for container environment.

Jump to

Keyboard shortcuts

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