cli: use Bazel container images

This commit is contained in:
Malte Poll 2023-04-03 18:09:03 +02:00 committed by Malte Poll
parent bd889bd6a7
commit 9dfad32e33
19 changed files with 376 additions and 26 deletions

View File

@ -319,6 +319,7 @@ go_library(
visibility = ["//cli:__subpackages__"], visibility = ["//cli:__subpackages__"],
deps = [ deps = [
"//cli/internal/clusterid", "//cli/internal/clusterid",
"//cli/internal/helm/imageversion",
"//internal/attestation/idkeydigest", "//internal/attestation/idkeydigest",
"//internal/cloud/cloudprovider", "//internal/cloud/cloudprovider",
"//internal/compatibility", "//internal/compatibility",

View File

@ -51,7 +51,7 @@ spec:
- --metrics-bind-address=127.0.0.1:8080 - --metrics-bind-address=127.0.0.1:8080
- --leader-elect - --leader-elect
command: command:
- /ko-app/v2 - /node-operator
env: env:
- name: KUBERNETES_CLUSTER_DOMAIN - name: KUBERNETES_CLUSTER_DOMAIN
value: {{ .Values.kubernetesClusterDomain }} value: {{ .Values.kubernetesClusterDomain }}

View File

@ -0,0 +1,41 @@
# gazelle:ignore
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/oci:containers.bzl", "helm_containers")
load("//bazel/oci:pin.bzl", "oci_go_source")
GENERATED_SRCS = [
":" + container["name"]
for container in helm_containers()
]
go_library(
name = "imageversion",
srcs = ["imageversion.go"] + GENERATED_SRCS, # keep
importpath = "github.com/edgelesssys/constellation/v2/cli/internal/helm/imageversion",
visibility = ["//cli:__subpackages__"],
deps = ["//internal/containerimage"],
)
[
oci_go_source(
name = container["name"],
identifier = container["identifier"],
image_name = container["image_name"],
oci = container["oci"],
package = "imageversion",
prefix = container["prefix"],
registry = container["registry"],
tag_file = container["tag_file"],
visibility = ["//cli:__subpackages__"],
)
for container in helm_containers()
]
# TODO(malt3): add missing third-party images
# - logstash
# - filebeat
# - konnectivity-agent
# - konnectivity-server
# - node-maintenance-operator
# - gcp-guest-agent

View File

@ -0,0 +1,67 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
// Package imageversion contains the pinned container images for the helm charts.
package imageversion
import "github.com/edgelesssys/constellation/v2/internal/containerimage"
// TODO(malt3): Migrate third-party images from versions.go.
// JoinService is the image of the join service.
// registry and prefix can be optionally set to use a different source.
func JoinService(registry, prefix string) string {
return containerimage.NewBuilder(defaultJoinService, registry, prefix).Build().String()
}
// KeyService is the image of the key service.
// registry and prefix can be optionally set to use a different source.
func KeyService(registry, prefix string) string {
return containerimage.NewBuilder(defaultKeyService, registry, prefix).Build().String()
}
// VerificationService is the image of the verification service.
// registry and prefix can be optionally set to use a different source.
func VerificationService(registry, prefix string) string {
return containerimage.NewBuilder(defaultVerificationService, registry, prefix).Build().String()
}
// ConstellationNodeOperator is the image of the constellation node operator.
// registry and prefix can be optionally set to use a different source.
func ConstellationNodeOperator(registry, prefix string) string {
return containerimage.NewBuilder(defaultNodeOperator, registry, prefix).Build().String()
}
var (
defaultJoinService = containerimage.Image{
Registry: joinServiceRegistry,
Prefix: joinServicePrefix,
Name: joinServiceName,
Tag: joinServiceTag,
Digest: joinServiceDigest,
}
defaultKeyService = containerimage.Image{
Registry: keyServiceRegistry,
Prefix: keyServicePrefix,
Name: keyServiceName,
Tag: keyServiceTag,
Digest: keyServiceDigest,
}
defaultVerificationService = containerimage.Image{
Registry: verificationServiceRegistry,
Prefix: verificationServicePrefix,
Name: verificationServiceName,
Tag: verificationServiceTag,
Digest: verificationServiceDigest,
}
defaultNodeOperator = containerimage.Image{
Registry: constellationNodeOperatorRegistry,
Prefix: constellationNodeOperatorPrefix,
Name: constellationNodeOperatorName,
Tag: constellationNodeOperatorTag,
Digest: constellationNodeOperatorDigest,
}
)

View File

@ -0,0 +1,36 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package imageversion
// This file is only used if `go build` is used instead of Bazel.
// It contains placeholder values for the container images so that everything
// still compiles.
const (
joinServiceRegistry = "placeholder"
joinServicePrefix = "placeholder"
joinServiceName = "placeholder"
joinServiceDigest = "placeholder"
joinServiceTag = "placeholder"
keyServiceRegistry = "placeholder"
keyServicePrefix = "placeholder"
keyServiceName = "placeholder"
keyServiceDigest = "placeholder"
keyServiceTag = "placeholder"
verificationServiceRegistry = "placeholder"
verificationServicePrefix = "placeholder"
verificationServiceName = "placeholder"
verificationServiceDigest = "placeholder"
verificationServiceTag = "placeholder"
constellationNodeOperatorRegistry = "placeholder"
constellationNodeOperatorPrefix = "placeholder"
constellationNodeOperatorName = "placeholder"
constellationNodeOperatorDigest = "placeholder"
constellationNodeOperatorTag = "placeholder"
)

View File

@ -17,6 +17,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/edgelesssys/constellation/v2/cli/internal/helm/imageversion"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider" "github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility" "github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config" "github.com/edgelesssys/constellation/v2/internal/config"
@ -81,17 +82,19 @@ func NewLoader(csp cloudprovider.Provider, k8sVersion versions.ValidK8sVersion)
ccmImage = versions.VersionConfigs[k8sVersion].CloudControllerManagerImageOpenStack ccmImage = versions.VersionConfigs[k8sVersion].CloudControllerManagerImageOpenStack
} }
// TODO(malt3): Allow overriding container image registry + prefix for all images
// (e.g. for air-gapped environments).
return &ChartLoader{ return &ChartLoader{
csp: csp, csp: csp,
joinServiceImage: versions.JoinImage, joinServiceImage: imageversion.JoinService("", ""),
keyServiceImage: versions.KeyServiceImage, keyServiceImage: imageversion.KeyService("", ""),
ccmImage: ccmImage, ccmImage: ccmImage,
cnmImage: cnmImage, cnmImage: cnmImage,
autoscalerImage: versions.VersionConfigs[k8sVersion].ClusterAutoscalerImage, autoscalerImage: versions.VersionConfigs[k8sVersion].ClusterAutoscalerImage,
verificationServiceImage: versions.VerificationImage, verificationServiceImage: imageversion.VerificationService("", ""),
gcpGuestAgentImage: versions.GcpGuestImage, gcpGuestAgentImage: versions.GcpGuestImage,
konnectivityImage: versions.KonnectivityAgentImage, konnectivityImage: versions.KonnectivityAgentImage,
constellationOperatorImage: versions.ConstellationOperatorImage, constellationOperatorImage: imageversion.ConstellationNodeOperator("", ""),
nodeMaintenanceOperatorImage: versions.NodeMaintenanceOperatorImage, nodeMaintenanceOperatorImage: versions.NodeMaintenanceOperatorImage,
} }
} }

View File

@ -63,7 +63,7 @@ spec:
- --metrics-bind-address=127.0.0.1:8080 - --metrics-bind-address=127.0.0.1:8080
- --leader-elect - --leader-elect
command: command:
- /ko-app/v2 - /node-operator
env: env:
- name: KUBERNETES_CLUSTER_DOMAIN - name: KUBERNETES_CLUSTER_DOMAIN
value: cluster.local value: cluster.local

View File

@ -63,7 +63,7 @@ spec:
- --metrics-bind-address=127.0.0.1:8080 - --metrics-bind-address=127.0.0.1:8080
- --leader-elect - --leader-elect
command: command:
- /ko-app/v2 - /node-operator
env: env:
- name: KUBERNETES_CLUSTER_DOMAIN - name: KUBERNETES_CLUSTER_DOMAIN
value: cluster.local value: cluster.local

View File

@ -63,7 +63,7 @@ spec:
- --metrics-bind-address=127.0.0.1:8080 - --metrics-bind-address=127.0.0.1:8080
- --leader-elect - --leader-elect
command: command:
- /ko-app/v2 - /node-operator
env: env:
- name: KUBERNETES_CLUSTER_DOMAIN - name: KUBERNETES_CLUSTER_DOMAIN
value: cluster.local value: cluster.local

View File

@ -63,7 +63,7 @@ spec:
- --metrics-bind-address=127.0.0.1:8080 - --metrics-bind-address=127.0.0.1:8080
- --leader-elect - --leader-elect
command: command:
- /ko-app/v2 - /node-operator
env: env:
- name: KUBERNETES_CLUSTER_DOMAIN - name: KUBERNETES_CLUSTER_DOMAIN
value: cluster.local value: cluster.local

View File

@ -63,7 +63,7 @@ spec:
- --metrics-bind-address=127.0.0.1:8080 - --metrics-bind-address=127.0.0.1:8080
- --leader-elect - --leader-elect
command: command:
- /ko-app/v2 - /node-operator
env: env:
- name: KUBERNETES_CLUSTER_DOMAIN - name: KUBERNETES_CLUSTER_DOMAIN
value: cluster.local value: cluster.local

View File

@ -20,6 +20,7 @@ go_library(
"//internal/attestation/measurements", "//internal/attestation/measurements",
"//internal/cloud/cloudprovider", "//internal/cloud/cloudprovider",
"//internal/compatibility", "//internal/compatibility",
"//internal/config/imageversion",
"//internal/config/instancetypes", "//internal/config/instancetypes",
"//internal/constants", "//internal/constants",
"//internal/file", "//internal/file",

View File

@ -35,6 +35,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements" "github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider" "github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/compatibility" "github.com/edgelesssys/constellation/v2/internal/compatibility"
"github.com/edgelesssys/constellation/v2/internal/config/imageversion"
"github.com/edgelesssys/constellation/v2/internal/constants" "github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file" "github.com/edgelesssys/constellation/v2/internal/file"
"github.com/edgelesssys/constellation/v2/internal/variant" "github.com/edgelesssys/constellation/v2/internal/variant"
@ -338,9 +339,9 @@ func Default() *Config {
ImageFormat: "raw", ImageFormat: "raw",
VCPUs: 2, VCPUs: 2,
Memory: 2048, Memory: 2048,
MetadataAPIImage: versions.QEMUMetadataImage, MetadataAPIImage: imageversion.QEMUMetadata(),
LibvirtURI: "", LibvirtURI: "",
LibvirtContainerImage: versions.LibvirtImage, LibvirtContainerImage: imageversion.Libvirt(),
NVRAM: "production", NVRAM: "production",
Measurements: measurements.DefaultsFor(cloudprovider.QEMU), Measurements: measurements.DefaultsFor(cloudprovider.QEMU),
}, },

View File

@ -0,0 +1,33 @@
# gazelle:ignore
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//bazel/oci:containers.bzl", "config_containers")
load("//bazel/oci:pin.bzl", "oci_go_source")
GENERATED_SRCS = [
":" + container["name"]
for container in config_containers()
]
go_library(
name = "imageversion",
srcs = ["imageversion.go"] + GENERATED_SRCS, # keep
importpath = "github.com/edgelesssys/constellation/v2/internal/config/imageversion",
visibility = ["//:__subpackages__"],
deps = ["//internal/containerimage"],
)
[
oci_go_source(
name = container["name"],
identifier = container["identifier"],
image_name = container["image_name"],
oci = container["oci"],
package = "imageversion",
prefix = container["prefix"],
registry = container["registry"],
tag_file = container["tag_file"],
visibility = ["//:__subpackages__"],
)
for container in config_containers()
]

View File

@ -0,0 +1,37 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
// Package imageversion contains the pinned container images for the config.
package imageversion
import "github.com/edgelesssys/constellation/v2/internal/containerimage"
// QEMUMetadata is the image of the QEMU metadata api service.
func QEMUMetadata() string {
return defaultQEMUMetadata.String()
}
// Libvirt is the image of the libvirt container.
func Libvirt() string {
return defaultLibvirt.String()
}
var (
defaultQEMUMetadata = containerimage.Image{
Registry: qemuMetadataRegistry,
Prefix: qemuMetadataPrefix,
Name: qemuMetadataName,
Tag: qemuMetadataTag,
Digest: qemuMetadataDigest,
}
defaultLibvirt = containerimage.Image{
Registry: libvirtRegistry,
Prefix: libvirtPrefix,
Name: libvirtName,
Tag: libvirtTag,
Digest: libvirtDigest,
}
)

View File

@ -0,0 +1,24 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package imageversion
// This file is only used if `go build` is used instead of Bazel.
// It contains placeholder values for the container images so that everything
// still compiles.
const (
qemuMetadataRegistry = "placeholder"
qemuMetadataPrefix = "placeholder"
qemuMetadataName = "placeholder"
qemuMetadataDigest = "placeholder"
qemuMetadataTag = "placeholder"
libvirtRegistry = "placeholder"
libvirtPrefix = "placeholder"
libvirtName = "placeholder"
libvirtDigest = "placeholder"
libvirtTag = "placeholder"
)

View File

@ -0,0 +1,8 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "containerimage",
srcs = ["containerimage.go"],
importpath = "github.com/edgelesssys/constellation/v2/internal/containerimage",
visibility = ["//:__subpackages__"],
)

View File

@ -0,0 +1,112 @@
/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
/*
This package provides container image names, registry info and digests.
It should only be used by the CLI and never be imported by any package that
ends up in a container image to avoid circular dependencies.
*/
package containerimage
import (
"errors"
"path"
"regexp"
)
// Image is a container image reference.
// It has the following format:
// <registry>/<prefix>/<name>:<tag>@<digest>
// where <registry> is the registry where the image is located,
// <prefix> is the (optional) prefix of the image name,
// <name> is the name of the image,
// <tag> is the (optional) tag of the image,
// <digest> is the digest of the image.
type Image struct {
// Registry is the registry where the image is located.
Registry string
// Prefix is the prefix of the image name.
Prefix string
// Name is the name of the image.
Name string
// Tag is the tag of the image.
Tag string
// Digest is the digest of the image.
Digest string
}
// Validate validates the image.
func (i Image) Validate() error {
if i.Registry == "" {
return errors.New("image registry is empty")
}
if i.Name == "" {
return errors.New("image name is empty")
}
if i.Digest == "" {
return errors.New("image digest is empty")
}
if matched := digestRegexp.MatchString(i.Digest); !matched {
return errors.New("image digest is not valid")
}
return nil
}
// String returns the image as a string.
// The format is <registry>/<prefix>/<name>:<tag>@<digest>
// or a shorter version if prefix or tag are empty.
func (i Image) String() string {
var base string
if i.Prefix == "" {
base = path.Join(i.Registry, i.Name)
} else {
base = path.Join(i.Registry, i.Prefix, i.Name)
}
var tag string
if i.Tag != "" {
tag = ":" + i.Tag
}
return base + tag + "@" + i.Digest
}
// Builder is a builder for container images.
type Builder struct {
Default Image
Registry string
Prefix string
}
// NewBuilder creates a new builder for container images.
func NewBuilder(def Image, registry, prefix string) *Builder {
return &Builder{
Default: def,
Registry: registry,
Prefix: prefix,
}
}
// Build builds a container image.
func (b *Builder) Build() Image {
img := Image{}
if b.Registry == "" {
img.Registry = b.Default.Registry
} else {
img.Registry = b.Registry
}
if b.Prefix == "" {
img.Prefix = b.Default.Prefix
} else {
img.Prefix = b.Prefix
}
img.Name = b.Default.Name
img.Tag = b.Default.Tag
img.Digest = b.Default.Digest
return img
}
var digestRegexp = regexp.MustCompile(`^sha256:[a-f0-9]{64}$`)

View File

@ -72,25 +72,11 @@ const (
KonnectivityAgentImage = "registry.k8s.io/kas-network-proxy/proxy-agent:v0.1.2@sha256:cd3046d253d26ffb5907c625e0d0c2be05c5693c90e12116980851739fc0ead8" // renovate:container KonnectivityAgentImage = "registry.k8s.io/kas-network-proxy/proxy-agent:v0.1.2@sha256:cd3046d253d26ffb5907c625e0d0c2be05c5693c90e12116980851739fc0ead8" // renovate:container
// KonnectivityServerImage server image for konnectivity service. // KonnectivityServerImage server image for konnectivity service.
KonnectivityServerImage = "registry.k8s.io/kas-network-proxy/proxy-server:v0.1.2@sha256:79933c3779bc30e33bb7509dff913e70f6ba78ad441f4827f0f3e840ce5f3ddb" // renovate:container KonnectivityServerImage = "registry.k8s.io/kas-network-proxy/proxy-server:v0.1.2@sha256:79933c3779bc30e33bb7509dff913e70f6ba78ad441f4827f0f3e840ce5f3ddb" // renovate:container
// JoinImage image of Constellation join service.
JoinImage = "ghcr.io/edgelesssys/constellation/join-service:v2.7.0-pre.0.20230330151913-6a2c9792e0ce@sha256:2610bae2e832f505bf83dcb382697a6f1dc34740df89f633750513afad26307d" // renovate:container
// KeyServiceImage image of Constellation KMS server.
KeyServiceImage = "ghcr.io/edgelesssys/constellation/key-service:v2.7.0-pre.0.20230330151913-6a2c9792e0ce@sha256:6095b3e1adcfd50d807d9c02263d04f26c6ecec1662ead65eb55b24718dd3b6d" // renovate:container
// VerificationImage image of Constellation verification service.
VerificationImage = "ghcr.io/edgelesssys/constellation/verification-service:v2.7.0-pre.0.20230330151913-6a2c9792e0ce@sha256:23dddc2244e80e84c40d7113fd47a779923ddc44ea80d827a1e0b37910daaafa" // renovate:container
// GcpGuestImage image for GCP guest agent. // GcpGuestImage image for GCP guest agent.
// Check for new versions at https://github.com/GoogleCloudPlatform/guest-agent/releases and update in /.github/workflows/build-gcp-guest-agent.yml. // Check for new versions at https://github.com/GoogleCloudPlatform/guest-agent/releases and update in /.github/workflows/build-gcp-guest-agent.yml.
GcpGuestImage = "ghcr.io/edgelesssys/gcp-guest-agent:20230221.0@sha256:8be328a5d8d601170b82481d413cf326b20c5219c016633f1651e35d95f1d6f1" // renovate:container GcpGuestImage = "ghcr.io/edgelesssys/gcp-guest-agent:20230221.0@sha256:8be328a5d8d601170b82481d413cf326b20c5219c016633f1651e35d95f1d6f1" // renovate:container
// ConstellationOperatorImage is the image for the constellation node operator.
ConstellationOperatorImage = "ghcr.io/edgelesssys/constellation/node-operator:v2.7.0-pre.0.20230329165140-d3e2f30f7b4c@sha256:3eca7e017f0e282e5c6581f42ed04b3e9395f62ef36c9c8344bbd8dab6933479" // renovate:container
// NodeMaintenanceOperatorImage is the image for the node maintenance operator. // NodeMaintenanceOperatorImage is the image for the node maintenance operator.
NodeMaintenanceOperatorImage = "quay.io/medik8s/node-maintenance-operator:v0.14.0@sha256:2dffb6ffdbbe997d317799fc709baf030d678bde0be0264931ff6b3e94fd89ab" // renovate:container NodeMaintenanceOperatorImage = "quay.io/medik8s/node-maintenance-operator:v0.14.0@sha256:2dffb6ffdbbe997d317799fc709baf030d678bde0be0264931ff6b3e94fd89ab" // renovate:container
// QEMUMetadataImage image of QEMU metadata api service.
QEMUMetadataImage = "ghcr.io/edgelesssys/constellation/qemu-metadata-api:v2.7.0-pre.0.20230330151913-6a2c9792e0ce@sha256:8283f9606366beaf05142aeef09a905085bc7cde071f43b43290a7f087994264" // renovate:container
// LibvirtImage image that provides libvirt.
LibvirtImage = "ghcr.io/edgelesssys/constellation/libvirt:v2.7.0-pre.0.20230330151913-6a2c9792e0ce@sha256:56d218cc501d471d25f6a6da940db48a008a040bc26dea1fe8a61edf9ca7ce73" // renovate:container
// LogstashImage is the container image of logstash, used for log collection by debugd. // LogstashImage is the container image of logstash, used for log collection by debugd.
LogstashImage = "ghcr.io/edgelesssys/constellation/logstash-debugd:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:544928006827a07183a7f0d8329ed9031103ab43e03842cae8b6062edf9d49dd" // renovate:container LogstashImage = "ghcr.io/edgelesssys/constellation/logstash-debugd:v2.7.0-pre.0.20230322165747-0a190c2bf672@sha256:544928006827a07183a7f0d8329ed9031103ab43e03842cae8b6062edf9d49dd" // renovate:container
// FilebeatImage is the container image of filebeat, used for log collection by debugd. // FilebeatImage is the container image of filebeat, used for log collection by debugd.