diff --git a/options.go b/options.go index c9619a6..01abaf4 100644 --- a/options.go +++ b/options.go @@ -53,6 +53,7 @@ type options struct { FcCPUTemplate string `long:"cpu-template" description:"Firecracker CPU Template (C3 or T2)"` FcMemSz int64 `long:"memory" short:"m" description:"VM memory, in MiB" default:"512"` FcMetadata string `long:"metadata" description:"Firecracker Metadata for MMDS (json)"` + FcMetadataFile string `long:"metadata-file" description:"Firecracker Metadata for MMDS (json file). json file is ignored if metadata is set."` FcFifoLogFile string `long:"firecracker-log" short:"l" description:"pipes the fifo contents to the specified file"` FcSocketPath string `long:"socket-path" short:"s" description:"path to use for firecracker socket, defaults to a unique file in in the first existing directory from {$HOME, $TMPDIR, or /tmp}"` Debug bool `long:"debug" short:"d" description:"Enable debug output"` @@ -83,6 +84,15 @@ func (opts *options) getFirecrackerConfig() (firecracker.Config, error) { return firecracker.Config{}, fmt.Errorf("%s: %v", errInvalidMetadata.Error(), err) } } + if opts.FcMetadataFile != "" && opts.FcMetadata == "" { + file, err := os.ReadFile(opts.FcMetadataFile) + if err != nil { + return firecracker.Config{}, err + } + if err := json.Unmarshal(file, &opts.validMetadata); err != nil { + return firecracker.Config{}, fmt.Errorf("%s: %v", errInvalidMetadata.Error(), err) + } + } //setup NICs NICs, err := opts.getNetwork() if err != nil { diff --git a/options_test.go b/options_test.go index f632b84..17da474 100644 --- a/options_test.go +++ b/options_test.go @@ -149,6 +149,43 @@ func TestGetFirecrackerConfig(t *testing.T) { }, }, }, + { + name: "Valid metadata file config", + opts: &options{ + FcMetadataFile: "testdata/valid_metadata.json", + FcSocketPath: "valid/path", + }, + expectedErr: func(e error) (bool, error) { + return e == nil, nil + }, + outConfig: firecracker.Config{ + SocketPath: "valid/path", + Drives: []models.Drive{ + { + DriveID: firecracker.String("1"), + PathOnHost: firecracker.String(""), + IsRootDevice: firecracker.Bool(true), + IsReadOnly: firecracker.Bool(false), + }, + }, + MachineCfg: models.MachineConfiguration{ + VcpuCount: firecracker.Int64(0), + MemSizeMib: firecracker.Int64(0), + Smt: firecracker.Bool(true), + }, + }, + }, + { + name: "Invalid metadata file config", + opts: &options{ + FcMetadataFile: "testdata/invalid_metadata.json", + FcSocketPath: "valid/path", + }, + expectedErr: func(e error) (bool, error) { + return strings.HasPrefix(e.Error(), errInvalidMetadata.Error()), errInvalidMetadata + }, + outConfig: firecracker.Config{}, + }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { diff --git a/testdata/invalid_metadata.json b/testdata/invalid_metadata.json new file mode 100644 index 0000000..e689b70 --- /dev/null +++ b/testdata/invalid_metadata.json @@ -0,0 +1,2 @@ +{ + "valid": false, diff --git a/testdata/valid_metadata.json b/testdata/valid_metadata.json new file mode 100644 index 0000000..1ca9d57 --- /dev/null +++ b/testdata/valid_metadata.json @@ -0,0 +1,3 @@ +{ + "valid": true +} \ No newline at end of file