From 26f500f62f664c2347bca5c55c93abfd53a04766 Mon Sep 17 00:00:00 2001 From: Drew Hudson-Viles Date: Thu, 19 Jan 2023 11:06:20 +0000 Subject: [PATCH] patch: added ability to insert metadata into the image being created Adds the ability to insert metadata into the image being created. Bumps the Trivy version. Removes some fluff from when I was playing with env vars as an option. --- cmd/build.go | 3 ++ cmd/root.go | 9 ++--- pkg/constants/constants.go | 1 + pkg/openstack/config.go | 70 ++++++++++++++++++++++++++++++++++++++ pkg/openstack/openstack.go | 3 +- 5 files changed, 78 insertions(+), 8 deletions(-) diff --git a/cmd/build.go b/cmd/build.go index 48dcd43..afd7924 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -53,6 +53,9 @@ To use baskio to build an image, an Openstack cluster is required.`, buildGitDir := build.CreateRepoDirectory() build.FetchBuildRepo(buildGitDir, imageRepoFlag, viper.GetBool("build.enable-nvidia-support")) + metadata := ostack.GenerateBuilderMetadata() + ostack.UpdatePackerBuildersJson(buildGitDir, metadata) + capiPath := filepath.Join(buildGitDir, "images", "capi") packerBuildConfig.GenerateVariablesFile(capiPath) diff --git a/cmd/root.go b/cmd/root.go index ffc59b3..941d866 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -35,8 +35,6 @@ This tool has been designed to automatically build images for the Openstack poti It could be extended out to provide images for a variety of other builders however for now it's main goal is to work with Openstack.`, } - buildCmd := NewBuildCommand() - scanCmd := NewScanCommand() rootCmd.PersistentFlags().StringVar(&cloudsPathFlag, "clouds-file", "~/.config/openstack/clouds.yaml", "The location of the openstack clouds.yaml file to use") rootCmd.PersistentFlags().StringVar(&cloudNameFlag, "cloud-name", "", "The name of the cloud profile to use from the clouds.yaml file") rootCmd.PersistentFlags().StringVar(&baskioConfigFlag, "baskio-config", "baskio.yaml", "The location of a baskio config file") @@ -50,8 +48,8 @@ It could be extended out to provide images for a variety of other builders howev commands := []*cobra.Command{ versionCmd(), - buildCmd, - scanCmd, + NewBuildCommand(), + NewScanCommand(), NewPublishCommand(), } rootCmd.AddCommand(commands...) @@ -60,7 +58,6 @@ It could be extended out to provide images for a variety of other builders howev // initConfig will initialise viper and the configuration file. func initConfig() { - viper.SetEnvPrefix("baskio") if baskioConfigFlag != "" { viper.SetConfigFile(baskioConfigFlag) } else { @@ -74,8 +71,6 @@ func initConfig() { } } - viper.AutomaticEnv() - if err := viper.ReadInConfig(); err == nil { fmt.Println("Using config file:", viper.ConfigFileUsed()) } diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 5331661..3e394c4 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -25,6 +25,7 @@ var ( "ubuntu-2004", "ubuntu-2204", } + TrivyVersion = "0.36.1" ) // Year is used in reports parsing. It is the top level and contains multiple Month(s). diff --git a/pkg/openstack/config.go b/pkg/openstack/config.go index 3885b14..e9fe338 100644 --- a/pkg/openstack/config.go +++ b/pkg/openstack/config.go @@ -18,11 +18,13 @@ package ostack import ( "encoding/json" "fmt" + "io" "log" "os" "path/filepath" "strconv" "strings" + "time" "github.com/google/uuid" "github.com/spf13/viper" @@ -161,6 +163,74 @@ func generateImageName(semVer string) string { return imageName + "-" + imageUUID.String()[:strings.Index(imageUUID.String(), "-")] } +// GenerateBuilderMetadata generates some glance metadata for the image. +func GenerateBuilderMetadata() map[string]string { + gpu := viper.GetString("build.nvidia-driver-version") + if len(gpu) == 0 { + gpu = "no_gpu" + } + return map[string]string{ + "os": viper.GetString("build.build-os"), + "k8s": viper.GetString("build.kubernetes_version"), + "gpu": gpu, + "date": time.RFC3339, + } +} + +// UpdatePackerBuildersJson pre-populates the metadata field in the packer.json file as objects cannot be passed as variables in packer. +func UpdatePackerBuildersJson(dir string, metadata map[string]string) { + file, err := os.OpenFile(filepath.Join(dir, "images", "capi", "packer", "openstack", "packer.json"), os.O_RDWR, 0644) + if err != nil { + log.Fatalln(err) + } + defer file.Close() + + data, err := io.ReadAll(file) + if err != nil { + log.Fatalln(err) + } + + res := addMetadataToBuilders(metadata, data) + + err = file.Truncate(0) + if err != nil { + log.Fatalln(err) + } + _, err = file.Seek(0, 0) + if err != nil { + log.Fatalln(err) + } + + _, err = file.Write(res) + if err != nil { + log.Fatalln(err) + } +} + +// addMetadataToBuilders inserts the metadata into the packer's builder section. +func addMetadataToBuilders(metadata map[string]string, data []byte) []byte { + jsonStruct := struct { + Builders []map[string]interface{} `json:"builders"` + PostProcessors []map[string]interface{} `json:"post-processors"` + Provisioners []map[string]interface{} `json:"provisioners"` + Variables map[string]interface{} `json:"variables"` + }{} + + err := json.Unmarshal(data, &jsonStruct) + if err != nil { + log.Fatalln(err) + } + + jsonStruct.Builders[0]["metadata"] = metadata + + res, err := json.Marshal(jsonStruct) + if err != nil { + log.Fatalln(err) + } + + return res +} + // GenerateVariablesFile converts the PackerBuildConfig into a build configuration file that packer can use. func (p *PackerBuildConfig) GenerateVariablesFile(buildGitDir string) { outputFileName := strings.Join([]string{"tmp", ".json"}, "") diff --git a/pkg/openstack/openstack.go b/pkg/openstack/openstack.go index 737bf31..cd58f9f 100644 --- a/pkg/openstack/openstack.go +++ b/pkg/openstack/openstack.go @@ -17,6 +17,7 @@ package ostack import ( "fmt" + "github.com/eschercloudai/baskio/pkg/constants" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" @@ -85,7 +86,7 @@ func (c *Client) CreateKeypair(KeyNamePrefix string) *keypairs.KeyPair { // CreateServer creates a compute instance in Openstack. func (c *Client) CreateServer(keypair *keypairs.KeyPair, imageID, flavorName, networkID string, enableConfigDrive bool) (*servers.Server, string) { - trivyVersion := "0.31.3" + trivyVersion := constants.TrivyVersion client := createComputeClient(c) serverFlavorID := c.GetFlavorIDByName(flavorName)