Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: Include Calico images in image list #903

Merged
merged 1 commit into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ before:
- make template-helm-repository
- |
sh -ec 'if [ {{ .IsSnapshot }} == false ] ; then
env CAREN_VERSION=v{{ trimprefix .Version "v" }} make list-images
make --no-print-directory CAREN_VERSION=v{{ trimprefix .Version "v" }} list-images >caren-images.txt
fi'

builds:
Expand Down
135 changes: 97 additions & 38 deletions hack/tools/fetch-images/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"fmt"
"io"
"os"
"path"
"path/filepath"
"slices"
"strings"
"text/template"
Expand All @@ -20,6 +20,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/yaml"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
)
Expand All @@ -30,10 +31,11 @@ const (
)

type ChartInfo struct {
repo string
name string
valuesFile string
stringValues []string
repo string
name string
valuesFile string
stringValues []string
extraImagesFiles []string
}

func main() {
Expand All @@ -47,9 +49,9 @@ func main() {
flagSet.StringVar(&chartDirectory, "chart-directory", "",
"path to chart directory for CAREN")
flagSet.StringVar(&helmChartConfigMap, "helm-chart-configmap", "",
"path to chart directory for CAREN")
"path to helm chart configmap for CAREN")
flagSet.StringVar(&carenVersion, "caren-version", "",
"caren version for images override")
"CAREN version for images override")
err := flagSet.Parse(args[1:])
if err != nil {
fmt.Println("failed to parse args", err.Error())
Expand All @@ -66,7 +68,7 @@ func main() {
os.Exit(1)
}
if chartDirectory == "" || helmChartConfigMap == "" {
fmt.Println("chart-directory helm-chart-configmap must be set")
fmt.Println("chart-directory and helm-chart-configmap must be set")
os.Exit(1)
}
i := &ChartInfo{
Expand Down Expand Up @@ -97,15 +99,10 @@ func main() {
}

func EnsureFullPath(filename string) (string, error) {
if path.IsAbs(filename) {
return filename, nil
}
wd, err := os.Getwd()
fullPath, err := filepath.Abs(filename)
if err != nil {
return "", fmt.Errorf("failed to get wd: %w", err)
return "", err
}
fullPath := path.Join(wd, filename)
fullPath = path.Clean(fullPath)
_, err = os.Stat(fullPath)
if err != nil {
return "", err
Expand All @@ -129,7 +126,7 @@ func getImagesForAddons(helmChartConfigMap, carenChartDirectory string) ([]strin
if err != nil {
return nil, fmt.Errorf("failed to unmarshal configmap to object %w", err)
}
images := []string{}
var images []string
for _, chartInfoRaw := range cm.Data {
var settings HelmChartFromConfigMap
err = yamlv2.Unmarshal([]byte(chartInfoRaw), &settings)
Expand All @@ -140,19 +137,24 @@ func getImagesForAddons(helmChartConfigMap, carenChartDirectory string) ([]strin
name: settings.ChartName,
repo: settings.Repository,
}
valuesFile := getValuesFileForChartIfNeeded(settings.ChartName, carenChartDirectory)
valuesFile, err := getValuesFileForChartIfNeeded(settings.ChartName, carenChartDirectory)
if err != nil {
return nil, fmt.Errorf("failed to get values file for %s: %w", settings.ChartName, err)
}
if valuesFile != "" {
info.valuesFile = valuesFile
}
if settings.ChartName == "aws-cloud-controller-manager" {

switch settings.ChartName {
case "aws-cloud-controller-manager":
values, err := getHelmValues(carenChartDirectory)
if err != nil {
return nil, err
}
awsImages, found, err := unstructured.NestedStringMap(values, "hooks", "ccm", "aws", "k8sMinorVersionToCCMVersion")
if !found {
return images, fmt.Errorf("failed to find k8sMinorVersionToCCMVersion from file %s",
path.Join(carenChartDirectory, "values.yaml"))
filepath.Join(carenChartDirectory, "values.yaml"))
}
if err != nil {
return images, fmt.Errorf("failed to get map k8sMinorVersionToCCMVersion with error %w",
Expand All @@ -168,9 +170,33 @@ func getImagesForAddons(helmChartConfigMap, carenChartDirectory string) ([]strin
}
images = append(images, chartImages...)
}
// skip the to next addon because we got what we needed
// skip to the next addon because we got what we needed
continue
case "tigera-operator":
extraImagesFile, err := os.CreateTemp("", "")
if err != nil {
return nil, fmt.Errorf("failed to create temp file for extra Calico images: %w", err)
}
defer os.Remove(extraImagesFile.Name()) //nolint:gocritic // Won't be leaked.
_, err = extraImagesFile.WriteString(`
{{default "docker.io/" .Values.installation.registry }}calico/cni:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/kube-controllers:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/node:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/apiserver:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/pod2daemon-flexvol:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/typha:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/csi:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/node-driver-registrar:{{ .Chart.Version }}
{{default "docker.io/" .Values.installation.registry }}calico/ctl:{{ .Chart.Version }}
`)
_ = extraImagesFile.Close()
if err != nil {
return nil, fmt.Errorf("failed to write to temp file for extra Calico images: %w", err)
}

info.extraImagesFiles = append(info.extraImagesFiles, extraImagesFile.Name())
}

chartImages, err := getImagesForChart(info)
if err != nil {
return nil, fmt.Errorf("failed to get images for %s with error %w", info.name, err)
Expand All @@ -181,7 +207,7 @@ func getImagesForAddons(helmChartConfigMap, carenChartDirectory string) ([]strin
}

func getHelmValues(carenChartDirectory string) (map[string]interface{}, error) {
values := path.Join(carenChartDirectory, "values.yaml")
values := filepath.Join(carenChartDirectory, "values.yaml")
valuesFile, err := os.Open(values)
if err != nil {
return nil, fmt.Errorf("failed to open file %s with %w", values, err)
Expand All @@ -195,21 +221,53 @@ func getHelmValues(carenChartDirectory string) (map[string]interface{}, error) {
return m, nil
}

func getValuesFileForChartIfNeeded(chartName, carenChartDirectory string) string {
func getValuesFileForChartIfNeeded(chartName, carenChartDirectory string) (string, error) {
switch chartName {
case "nutanix-csi-storage":
return path.Join(carenChartDirectory, "addons", "csi", "nutanix", defaultHelmAddonFilename)
return filepath.Join(carenChartDirectory, "addons", "csi", "nutanix", defaultHelmAddonFilename), nil
case "node-feature-discovery":
return path.Join(carenChartDirectory, "addons", "nfd", defaultHelmAddonFilename)
return filepath.Join(carenChartDirectory, "addons", "nfd", defaultHelmAddonFilename), nil
case "snapshot-controller":
return path.Join(carenChartDirectory, "addons", "csi", "snapshot-controller", defaultHelmAddonFilename)
return filepath.Join(carenChartDirectory, "addons", "csi", "snapshot-controller", defaultHelmAddonFilename), nil
case "cilium":
return path.Join(carenChartDirectory, "addons", "cni", "cilium", defaultHelmAddonFilename)
return filepath.Join(carenChartDirectory, "addons", "cni", "cilium", defaultHelmAddonFilename), nil
// Calico values differ slightly per provider, but that does not have a material imapct on the images required
// so we can use the default values file for AWS provider.
case "tigera-operator":
f := filepath.Join(carenChartDirectory, "addons", "cni", "calico", "aws", defaultHelmAddonFilename)
tempFile, err := os.CreateTemp("", "")
if err != nil {
return "", fmt.Errorf("failed to create temp file: %w", err)
}

// CAAPH uses unstructured internally, so we need to create an unstructured copy of a cluster
// to pass to the CAAPH values template.
c, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&clusterv1.Cluster{})
if err != nil {
return "", fmt.Errorf("failed to convert cluster to unstructured %w", err)
}

templateInput := struct {
Cluster map[string]interface{}
}{
Cluster: c,
}

err = template.Must(template.New(defaultHelmAddonFilename).ParseFiles(f)).Execute(tempFile, &templateInput)
if err != nil {
return "", fmt.Errorf("failed to execute helm values template %w", err)
}

return tempFile.Name(), nil
// this uses the values from kustomize because the file at addons/cluster-autoscaler/values-template.yaml
// is a file that is templated
case "cluster-autoscaler":
f := path.Join(carenChartDirectory, "addons", "cluster-autoscaler", defaultHelmAddonFilename)
tempFile, _ := os.CreateTemp("", "")
f := filepath.Join(carenChartDirectory, "addons", "cluster-autoscaler", defaultHelmAddonFilename)
tempFile, err := os.CreateTemp("", "")
if err != nil {
return "", fmt.Errorf("failed to create temp file: %w", err)
}

c := clusterv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Name: "tmplCluster",
Expand All @@ -227,25 +285,26 @@ func getValuesFileForChartIfNeeded(chartName, carenChartDirectory string) string
Cluster: &c,
}

template.Must(template.New(defaultHelmAddonFilename).ParseFiles(f)).Execute(tempFile, &templateInput)
return tempFile.Name()
err = template.Must(template.New(defaultHelmAddonFilename).ParseFiles(f)).Execute(tempFile, &templateInput)
if err != nil {
return "", fmt.Errorf("failed to execute helm values template %w", err)
}

return tempFile.Name(), nil
default:
return ""
return "", nil
}
}

func getImagesForChart(info *ChartInfo) ([]string, error) {
images := pkg.Images{}
images.SetChart(info.name)
if info.repo != "" {
images.RepoURL = info.repo
}
images.RepoURL = info.repo
if info.valuesFile != "" {
images.ValueFiles.Set(info.valuesFile)
}
if len(info.stringValues) > 0 {
images.StringValues = info.stringValues
_ = images.ValueFiles.Set(info.valuesFile)
}
images.StringValues = info.stringValues
images.ExtraImagesFiles = info.extraImagesFiles
// kubeVersion needs to be set for some addons
images.KubeVersion = "v1.29.0"
images.SetRelease("sample")
Expand Down
9 changes: 4 additions & 5 deletions make/addons.mk
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ template-helm-repository: generate-mindthegap-repofile ## this is used by goreal

.PHONY: list-images
list-images:
cd hack/tools/fetch-images && go build
./hack/tools/fetch-images/fetch-images \
-chart-directory=./charts/cluster-api-runtime-extensions-nutanix/ \
-helm-chart-configmap=./charts/cluster-api-runtime-extensions-nutanix/templates/helm-config.yaml \
-caren-version=$(CAREN_VERSION) >> caren-images.txt
cd hack/tools/fetch-images && go run . \
-chart-directory=$(PWD)/charts/cluster-api-runtime-extensions-nutanix/ \
-helm-chart-configmap=$(PWD)/charts/cluster-api-runtime-extensions-nutanix/templates/helm-config.yaml \
-caren-version=$(CAREN_VERSION)
Loading