diff --git a/cmd/osbuild-pipeline/main.go b/cmd/osbuild-pipeline/main.go index 370c41eb8..457d0ab42 100644 --- a/cmd/osbuild-pipeline/main.go +++ b/cmd/osbuild-pipeline/main.go @@ -3,6 +3,8 @@ package main import ( "encoding/json" "flag" + "fmt" + "github.com/osbuild/osbuild-composer/internal/common" "io/ioutil" "os" @@ -12,16 +14,42 @@ import ( ) func main() { - var format string + var imageType string var blueprintArg string var archArg string var distroArg string - flag.StringVar(&format, "output-format", "", "output format") - flag.StringVar(&blueprintArg, "blueprint", "", "blueprint to translate") - flag.StringVar(&archArg, "arch", "", "architecture to create image for") - flag.StringVar(&distroArg, "distro", "", "distribution to create") + flag.StringVar(&imageType, "image-type", "", "image type, e.g. qcow2 or ami") + flag.StringVar(&blueprintArg, "blueprint", "", "path to a JSON file containing a blueprint to translate") + flag.StringVar(&archArg, "arch", "", "architecture to create image for, e.g. x86_64") + flag.StringVar(&distroArg, "distro", "", "distribution to create, e.g. fedora-30") flag.Parse() + // Print help usage if one of the required arguments wasn't provided + if imageType == "" || blueprintArg == "" || archArg == "" || distroArg == "" { + flag.Usage() + return + } + + // Validate architecture + if !common.ArchitectureExists(archArg) { + _, _ = fmt.Fprintf(os.Stderr, "The provided architecture (%s) is not supported. Use one of these:\n", archArg) + for _, arch := range common.ListArchitectures() { + _, _ = fmt.Fprintln(os.Stderr, " *", arch) + } + return + } + + // Validate distribution + if !common.DistributionExists(distroArg) { + _, _ = fmt.Fprintf(os.Stderr, "The provided distribution (%s) is not supported. Use one of these:\n", distroArg) + for _, distro := range common.ListDistributions() { + _, _ = fmt.Fprintln(os.Stderr, " *", distro) + } + return + } + + // Validate image type + blueprint := &blueprint.Blueprint{} if blueprintArg != "" { file, err := ioutil.ReadFile(blueprintArg) @@ -58,7 +86,7 @@ func main() { panic(err.Error()) } - pipeline, err := d.Pipeline(blueprint, nil, checksums, archArg, format, 0) + pipeline, err := d.Pipeline(blueprint, nil, checksums, archArg, imageType, 0) if err != nil { panic(err.Error()) } diff --git a/internal/common/types.go b/internal/common/types.go index 8b2286c8f..38c8846bc 100644 --- a/internal/common/types.go +++ b/internal/common/types.go @@ -37,6 +37,23 @@ func marshalHelper(input int, mapping map[string]int, errorMessage string) ([]by return nil, &CustomJsonConversionError{fmt.Sprintf("%d %s", input, errorMessage)} } +func listHelper(mapping map[string]int) []string { + ret := make([]string, 0) + for k,_ := range mapping { + ret = append(ret, k) + } + return ret +} + +func existsHelper(mapping map[string]int, testedValue string) bool { + for k, _ := range mapping { + if k == testedValue { + return true + } + } + return false +} + // Architecture represents one of the supported CPU architectures available for images // produced by osbuild-composer. It is represented as an integer because if it // was a string it would unmarshal from JSON just fine even in case that the architecture @@ -72,6 +89,14 @@ func getArchMapping() map[string]int { return mapping } +func ListArchitectures() []string { + return listHelper(getArchMapping()) +} + +func ArchitectureExists(testedArch string) bool { + return existsHelper(getArchMapping(), testedArch) +} + // UnmarshalJSON is a custom unmarshaling function to limit the set of allowed values // in case the input is JSON. func (arch Architecture) UnmarshalJSON(data []byte) error { @@ -153,6 +178,15 @@ func getDistributionMapping() map[string]int { return mapping } + +func ListDistributions() []string { + return listHelper(getDistributionMapping()) +} + +func DistributionExists(testedDistro string) bool { + return existsHelper(getDistributionMapping(), testedDistro) +} + func (distro Distribution) UnmarshalJSON(data []byte) error { value, err := unmarshalHelper(data, " is not a valid JSON value", " is not a valid distribution", getDistributionMapping()) if err != nil {