/* Copyright (c) Edgeless Systems GmbH SPDX-License-Identifier: AGPL-3.0-only */ package cmd import ( "encoding/json" "fmt" "os" "github.com/edgelesssys/constellation/v2/internal/attestation/measurements" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/spf13/cobra" ) // newMeasurementsMergeCmd creates a new merge command. func newMeasurementsMergeCmd() *cobra.Command { cmd := &cobra.Command{ Use: "merge [flags] ...", Short: "Merge OS image measurements", Long: "Merge OS image measurements.", Args: cobra.MinimumNArgs(1), RunE: runMergeMeasurements, } cmd.SetOut(os.Stdout) cmd.Flags().String("out", "", "Optional path to write the merge result to. If not set, the result is written to stdout.") cmd.Flags().Bool("verbose", false, "Enable verbose output") return cmd } func runMergeMeasurements(cmd *cobra.Command, args []string) error { workdir := os.Getenv("BUILD_WORKING_DIRECTORY") if len(workdir) > 0 { must(os.Chdir(workdir)) } flags, err := parseMergeMeasurementsFlags(cmd) if err != nil { return err } log := logger.NewTextLogger(flags.logLevel) log.Debug(fmt.Sprintf("Parsed flags: %+v", flags)) mergedMeasurements, err := readMeasurementsArgs(args) if err != nil { return fmt.Errorf("merging measurements: reading input files: %w", err) } out := cmd.OutOrStdout() if len(flags.out) > 0 { outF, err := os.Create(flags.out) if err != nil { return fmt.Errorf("merging measurements: opening output file: %w", err) } defer outF.Close() out = outF } if err := json.NewEncoder(out).Encode(mergedMeasurements); err != nil { return fmt.Errorf("merging measurements: writing output file: %w", err) } log.Info("Merged image measurements") return nil } func readMeasurementsArgs(paths []string) (measurements.ImageMeasurementsV2, error) { measuremnts := make([]measurements.ImageMeasurementsV2, len(paths)) for i, path := range paths { f, err := os.Open(path) if err != nil { return measurements.ImageMeasurementsV2{}, err } defer f.Close() if err := json.NewDecoder(f).Decode(&measuremnts[i]); err != nil { return measurements.ImageMeasurementsV2{}, err } } return measurements.MergeImageMeasurementsV2(measuremnts...) }