From 4a506acb2cdb8d29dbcc0f5fc05ad1b4f8347a46 Mon Sep 17 00:00:00 2001 From: Stephanie Date: Tue, 15 Feb 2022 12:41:18 -0500 Subject: [PATCH 1/9] update schema struct and generator library file Signed-off-by: Stephanie --- index/generator/library/library.go | 624 ++++++++++++++++++++++++++--- index/generator/schema/schema.go | 30 +- 2 files changed, 591 insertions(+), 63 deletions(-) diff --git a/index/generator/library/library.go b/index/generator/library/library.go index dfaa8ce8d..2ad96d105 100644 --- a/index/generator/library/library.go +++ b/index/generator/library/library.go @@ -3,13 +3,19 @@ package library import ( "encoding/json" "fmt" + "github.com/devfile/library/pkg/testingutil/filesystem" + "io" "io/ioutil" "os" + "os/signal" "path" "path/filepath" + "syscall" devfileParser "github.com/devfile/library/pkg/devfile" "github.com/devfile/library/pkg/devfile/parser" + gitpkg "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "github.com/devfile/registry-support/index/generator/schema" "gopkg.in/yaml.v2" ) @@ -18,6 +24,7 @@ const ( devfile = "devfile.yaml" devfileHidden = ".devfile.yaml" extraDevfileEntries = "extraDevfileEntries.yaml" + stackYaml = "stack.yaml" ) // MissingArchError is an error if the architecture list is empty @@ -125,94 +132,271 @@ func fileExists(filepath string) bool { return true } +func dirExists(dirpath string) error { + dir, err := os.Stat(dirpath) + if os.IsNotExist(err){ + return fmt.Errorf("path: %s does not exist: %w",dirpath, err) + } + if !dir.IsDir() { + return fmt.Errorf("%s is not a directory", dirpath) + } + return nil +} + func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, error) { + var index []schema.Schema stackDirPath := path.Join(registryDirPath, "stacks") stackDir, err := ioutil.ReadDir(stackDirPath) if err != nil { return nil, fmt.Errorf("failed to read stack directory %s: %v", stackDirPath, err) } - for _, devfileDir := range stackDir { - if !devfileDir.IsDir() { + for _, stackFolderDir := range stackDir { + if !stackFolderDir.IsDir() { continue } - - // Allow devfile.yaml or .devfile.yaml - devfilePath := filepath.Join(stackDirPath, devfileDir.Name(), devfile) - devfileHiddenPath := filepath.Join(stackDirPath, devfileDir.Name(), devfileHidden) - if fileExists(devfilePath) && fileExists(devfileHiddenPath) { - return nil, fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) - } - if fileExists(devfileHiddenPath) { - devfilePath = devfileHiddenPath - } - - if !force { - // Devfile validation - devfileObj, err := devfileParser.ParseAndValidate(devfilePath) + stackFolderPath := filepath.Join(stackDirPath, stackFolderDir.Name()) + stackYamlPath := filepath.Join(stackFolderPath, stackYaml) + // if stack.yaml exist, parse stack.yaml + var indexComponent schema.Schema + if fileExists(stackYamlPath) { + indexComponent, err = parseStackInfo(stackYamlPath) if err != nil { - return nil, fmt.Errorf("%s devfile is not valid: %v", devfileDir.Name(), err) + return nil, err + } + if !force { + stackYamlErrors := validateStackInfo(indexComponent, stackFolderPath) + if stackYamlErrors != nil { + return nil, fmt.Errorf("%s stack.yaml is not valid: %v", stackFolderDir.Name(), stackYamlErrors) + } } - metadataErrors := checkForRequiredMetadata(devfileObj) - if metadataErrors != nil { - return nil, fmt.Errorf("%s devfile is not valid: %v", devfileDir.Name(), metadataErrors) + for i, versionComponent:= range indexComponent.Versions { + if versionComponent.Git == nil { + stackVersonDirPath := filepath.Join(stackFolderPath, versionComponent.Version) + + err := parseStackDevfile(stackVersonDirPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) + if err != nil { + return nil, err + } + indexComponent.Versions[i] = versionComponent + } } + } else { // if stack.yaml not exist, old stack repo struct, directly lookfor & parse devfile.yaml + versionComponent := schema.Version{} + err := parseStackDevfile(stackFolderPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) + if err != nil { + return nil, err + } + versionComponent.Default = true + indexComponent.Versions = append(indexComponent.Versions, versionComponent) } + indexComponent.Type = schema.StackDevfileType - bytes, err := ioutil.ReadFile(devfilePath) - if err != nil { - return nil, fmt.Errorf("failed to read %s: %v", devfilePath, err) - } - var devfile schema.Devfile - err = yaml.Unmarshal(bytes, &devfile) + //// Allow devfile.yaml or .devfile.yaml + //devfilePath := filepath.Join(stackDirPath, stackFolderDir.Name(), devfile) + //devfileHiddenPath := filepath.Join(stackDirPath, stackFolderDir.Name(), devfileHidden) + //if fileExists(devfilePath) && fileExists(devfileHiddenPath) { + // return nil, fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) + //} + //if fileExists(devfileHiddenPath) { + // devfilePath = devfileHiddenPath + //} + // + //if !force { + // // Devfile validation + // devfileObj,_, err := devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) + // if err != nil { + // return nil, fmt.Errorf("%s devfile is not valid: %v", stackFolderDir.Name(), err) + // } + // + // metadataErrors := checkForRequiredMetadata(devfileObj) + // if metadataErrors != nil { + // return nil, fmt.Errorf("%s devfile is not valid: %v", stackFolderDir.Name(), metadataErrors) + // } + //} + // + //bytes, err := ioutil.ReadFile(devfilePath) + //if err != nil { + // return nil, fmt.Errorf("failed to read %s: %v", devfilePath, err) + //} + //var devfile schema.Devfile + //err = yaml.Unmarshal(bytes, &devfile) + //if err != nil { + // return nil, fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + //} + //indexComponent := devfile.Meta + //if indexComponent.Links == nil { + // indexComponent.Links = make(map[string]string) + //} + //indexComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", indexComponent.Name, "latest") + //indexComponent.Type = schema.StackDevfileType + // + //for _, starterProject := range devfile.StarterProjects { + // indexComponent.StarterProjects = append(indexComponent.StarterProjects, starterProject.Name) + //} + // + //// Get the files in the stack folder + //stackFolder := filepath.Join(stackDirPath, stackFolderDir.Name()) + //stackFiles, err := ioutil.ReadDir(stackFolder) + //if err != nil { + // return index, err + //} + //for _, stackFile := range stackFiles { + // // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file + // // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. + // if !stackFile.IsDir() { + // indexComponent.Resources = append(indexComponent.Resources, stackFile.Name()) + // } + //} + // + //if !force { + // // Index component validation + // err := validateIndexComponent(indexComponent, schema.StackDevfileType) + // switch err.(type) { + // case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: + // // log to the console as FYI if the devfile has no architectures/provider/supportUrl + // fmt.Printf("%s", err.Error()) + // default: + // // only return error if we dont want to print + // if err != nil { + // return nil, fmt.Errorf("%s index component is not valid: %v", stackFolderDir.Name(), err) + // } + // } + //} + + index = append(index, indexComponent) + } + + return index, nil +} + +func parseStackDevfile(devfileDirPath string, stackName string, force bool, versionComponent *schema.Version, indexComponent *schema.Schema) error { + // Allow devfile.yaml or .devfile.yaml + devfilePath := filepath.Join(devfileDirPath, devfile) + devfileHiddenPath := filepath.Join(devfileDirPath, devfileHidden) + if fileExists(devfilePath) && fileExists(devfileHiddenPath) { + return fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) + } + if fileExists(devfileHiddenPath) { + devfilePath = devfileHiddenPath + } + + if !force { + // Devfile validation + devfileObj,_, err := devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) if err != nil { - return nil, fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + return fmt.Errorf("%s devfile is not valid: %v", devfileDirPath, err) } - indexComponent := devfile.Meta - if indexComponent.Links == nil { - indexComponent.Links = make(map[string]string) - } - indexComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", indexComponent.Name, "latest") - indexComponent.Type = schema.StackDevfileType - for _, starterProject := range devfile.StarterProjects { - indexComponent.StarterProjects = append(indexComponent.StarterProjects, starterProject.Name) + metadataErrors := checkForRequiredMetadata(devfileObj) + if metadataErrors != nil { + return fmt.Errorf("%s devfile is not valid: %v", devfileDirPath, metadataErrors) } + } - // Get the files in the stack folder - stackFolder := filepath.Join(stackDirPath, devfileDir.Name()) - stackFiles, err := ioutil.ReadDir(stackFolder) - if err != nil { - return index, err - } - for _, stackFile := range stackFiles { - // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file - // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. - if !stackFile.IsDir() { - indexComponent.Resources = append(indexComponent.Resources, stackFile.Name()) - } + bytes, err := ioutil.ReadFile(devfilePath) + if err != nil { + return fmt.Errorf("failed to read %s: %v", devfilePath, err) + } + + + var devfile schema.Devfile + err = yaml.Unmarshal(bytes, &devfile) + if err != nil { + return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + } + metaBytes, err := yaml.Marshal(devfile.Meta) + if err != nil { + return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + } + var versionProp schema.Version + err = yaml.Unmarshal(metaBytes, &versionProp) + if err != nil { + return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + } + + // set common properties if not set + if indexComponent.ProjectType == "" { + indexComponent.ProjectType = devfile.Meta.ProjectType + } + if indexComponent.Language == "" { + indexComponent.Language = devfile.Meta.Language + } + if indexComponent.Provider == "" { + indexComponent.Provider = devfile.Meta.Provider + } + if indexComponent.SupportUrl == "" { + indexComponent.SupportUrl = devfile.Meta.SupportUrl + } + + // for single version stack with only devfile.yaml, without stack.yaml + // set the top-level properties for this stack + if indexComponent.Name == "" { + indexComponent.Name = devfile.Meta.Name + } + if indexComponent.DisplayName == "" { + indexComponent.DisplayName = devfile.Meta.DisplayName + } + if indexComponent.Description == "" { + indexComponent.Description = devfile.Meta.Description + } + if indexComponent.Icon == "" { + indexComponent.Icon = devfile.Meta.Icon + } + + versionProp.Default = versionComponent.Default + *versionComponent = versionProp + if versionComponent.Links == nil { + versionComponent.Links = make(map[string]string) + } + versionComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", stackName, versionComponent.Version) + versionComponent.SchemaVersion = devfile.SchemaVersion + + for _, starterProject := range devfile.StarterProjects { + versionComponent.StarterProjects = append(versionComponent.StarterProjects, starterProject.Name) + } + + for _, tag := range versionComponent.Tags { + if !inArray(indexComponent.Tags, tag) { + indexComponent.Tags = append(indexComponent.Tags, tag) } + } - if !force { - // Index component validation - err := validateIndexComponent(indexComponent, schema.StackDevfileType) - switch err.(type) { - case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: - // log to the console as FYI if the devfile has no architectures/provider/supportUrl - fmt.Printf("%s", err.Error()) - default: - // only return error if we dont want to print - if err != nil { - return nil, fmt.Errorf("%s index component is not valid: %v", devfileDir.Name(), err) - } - } + for _, arch := range versionComponent.Architectures { + if !inArray(indexComponent.Architectures, arch) { + indexComponent.Architectures = append(indexComponent.Architectures, arch) } + } - index = append(index, indexComponent) + // Get the files in the stack folder + stackFiles, err := ioutil.ReadDir(devfileDirPath) + if err != nil { + return err + } + for _, stackFile := range stackFiles { + // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file + // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. + if !stackFile.IsDir() { + versionComponent.Resources = append(versionComponent.Resources, stackFile.Name()) + } } - return index, nil + //if !force { + // // Index component validation + // err := validateIndexComponent(versionComponent, schema.StackDevfileType) + // switch err.(type) { + // case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: + // // log to the console as FYI if the devfile has no architectures/provider/supportUrl + // fmt.Printf("%s", err.Error()) + // default: + // // only return error if we dont want to print + // if err != nil { + // return schema.Version{}, fmt.Errorf("%s index component is not valid: %v", stackFolder, err) + // } + // } + //} + return nil } func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Schema, error) { @@ -285,6 +469,19 @@ func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Sche return index, nil } +func parseStackInfo(stackYamlPath string) (schema.Schema, error) { + var index schema.Schema + bytes, err := ioutil.ReadFile(stackYamlPath) + if err != nil { + return schema.Schema{}, fmt.Errorf("failed to read %s: %v", stackYamlPath, err) + } + err = yaml.Unmarshal(bytes, &index) + if err != nil { + return schema.Schema{}, fmt.Errorf("failed to unmarshal %s data: %v", stackYamlPath, err) + } + return index, nil +} + // checkForRequiredMetadata validates that a given devfile has the necessary metadata fields func checkForRequiredMetadata(devfileObj parser.DevfileObj) []error { devfileMetadata := devfileObj.Data.GetMetadata() @@ -305,3 +502,306 @@ func checkForRequiredMetadata(devfileObj parser.DevfileObj) []error { return metadataErrors } + +func validateStackInfo (stackInfo schema.Schema, stackfolderDir string) []error { + var errors []error + + if stackInfo.Name == "" { + errors = append(errors, fmt.Errorf("name is not set in stack.yaml")) + } + if stackInfo.DisplayName == "" { + errors = append(errors, fmt.Errorf("displayName is not set stack.yaml")) + } + if stackInfo.Icon == "" { + errors = append(errors, fmt.Errorf("icon is not set stack.yaml")) + } + if stackInfo.Versions == nil || len(stackInfo.Versions) == 0 { + errors = append(errors, fmt.Errorf("versions list is not set stack.yaml, or is empty")) + } + hasDefault := false + for _, version := range stackInfo.Versions { + if version.Default { + if !hasDefault { + hasDefault = true + } else { + errors = append(errors, fmt.Errorf("stack.yaml has multiple default versions")) + } + } + + if version.Git == nil { + versionFolder := path.Join(stackfolderDir, version.Version) + err := dirExists(versionFolder) + if err != nil { + errors = append(errors, fmt.Errorf("cannot find resorce folder for version %s defined in stack.yaml: %v", version.Version, err)) + } + } + } + if !hasDefault { + errors = append(errors, fmt.Errorf("stack.yaml does not contain a default version")) + } + + return errors +} + + +// In checks if the value is in the array +func inArray(arr []string, value string) bool { + for _, item := range arr { + if item == value { + return true + } + } + return false +} + +// downloadRemoteStack downloads the stack version outside of the registry repo +func downloadRemoteStack(git *schema.Git, path string, verbose bool) (err error) { + + // convert revision to referenceName type, ref name could be a branch or tag + // if revision is not specified it would be the default branch of the project + revision := git.Revision + refName := plumbing.ReferenceName(git.Revision) + + if plumbing.IsHash(revision) { + // Specifying commit in the reference name is not supported by the go-git library + // while doing git.PlainClone() + fmt.Printf("Specifying commit in 'revision' is not yet supported.") + // overriding revision to empty as we do not support this + revision = "" + } + + if revision != "" { + // lets consider revision to be a branch name first + refName = plumbing.NewBranchReferenceName(revision) + } + + + cloneOptions := &gitpkg.CloneOptions{ + URL: git.Url, + RemoteName: git.RemoteName, + ReferenceName: refName, + SingleBranch: true, + // we don't need history for starter projects + Depth: 1, + } + + originalPath := "" + if git.SubDir != "" { + originalPath = path + path, err = ioutil.TempDir("", "") + if err != nil { + return err + } + } + + _, err = gitpkg.PlainClone(path, false, cloneOptions) + + if err != nil { + + // it returns the following error if no matching ref found + // if we get this error, we are trying again considering revision as tag, only if revision is specified. + if _, ok := err.(gitpkg.NoMatchingRefSpecError); !ok || revision == "" { + return err + } + + // try again to consider revision as tag name + cloneOptions.ReferenceName = plumbing.NewTagReferenceName(revision) + // remove if any .git folder downloaded in above try + _ = os.RemoveAll(filepath.Join(path, ".git")) + _, err = gitpkg.PlainClone(path, false, cloneOptions) + if err != nil { + return err + } + } + + // we don't want to download project be a git repo + err = os.RemoveAll(filepath.Join(path, ".git")) + if err != nil { + // we don't need to return (fail) if this happens + fmt.Printf("Unable to delete .git from cloned devfile repository") + } + + if git.SubDir != "" { + err = GitSubDir(path, originalPath, + git.SubDir) + if err != nil { + return err + } + } + + return nil + +} + +// GitSubDir handles subDir for git components using the default filesystem +func GitSubDir(srcPath, destinationPath, subDir string) error { + return gitSubDir(srcPath, destinationPath, subDir, filesystem.DefaultFs{}) +} + +// gitSubDir handles subDir for git components +func gitSubDir(srcPath, destinationPath, subDir string, fs filesystem.Filesystem) error { + go StartSignalWatcher([]os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, os.Interrupt}, func(_ os.Signal) { + err := cleanDir(destinationPath, map[string]bool{ + "devfile.yaml": true, + }, fs) + if err != nil { + fmt.Printf("error %v occurred while calling handleInterruptedSubDir", err) + } + err = fs.RemoveAll(srcPath) + if err != nil { + fmt.Printf("error %v occurred during temp folder clean up", err) + } + }) + + err := func() error { + // Open the directory. + outputDirRead, err := fs.Open(filepath.Join(srcPath, subDir)) + if err != nil { + return err + } + defer func() { + if err1 := outputDirRead.Close(); err1 != nil { + fmt.Printf("err occurred while closing temp dir: %v", err1) + + } + }() + // Call Readdir to get all files. + outputDirFiles, err := outputDirRead.Readdir(0) + if err != nil { + return err + } + + // Loop over files. + for outputIndex := range outputDirFiles { + outputFileHere := outputDirFiles[outputIndex] + + // Get name of file. + fileName := outputFileHere.Name() + + oldPath := filepath.Join(srcPath, subDir, fileName) + + if outputFileHere.IsDir() { + err = copyDirWithFS(oldPath, filepath.Join(destinationPath, fileName), fs) + } else { + err = copyFileWithFs(oldPath, filepath.Join(destinationPath, fileName), fs) + } + + if err != nil { + return err + } + } + return nil + }() + if err != nil { + return err + } + return fs.RemoveAll(srcPath) +} + +// copyFileWithFs copies a single file from src to dst +func copyFileWithFs(src, dst string, fs filesystem.Filesystem) error { + var err error + var srcinfo os.FileInfo + + srcfd, err := fs.Open(src) + if err != nil { + return err + } + defer func() { + if e := srcfd.Close(); e != nil { + fmt.Printf("err occurred while closing file: %v", e) + } + }() + + dstfd, err := fs.Create(dst) + if err != nil { + return err + } + defer func() { + if e := dstfd.Close(); e != nil { + fmt.Printf("err occurred while closing file: %v", e) + } + }() + + if _, err = io.Copy(dstfd, srcfd); err != nil { + return err + } + if srcinfo, err = fs.Stat(src); err != nil { + return err + } + return fs.Chmod(dst, srcinfo.Mode()) +} + +// copyDirWithFS copies a whole directory recursively +func copyDirWithFS(src string, dst string, fs filesystem.Filesystem) error { + var err error + var fds []os.FileInfo + var srcinfo os.FileInfo + + if srcinfo, err = fs.Stat(src); err != nil { + return err + } + + if err = fs.MkdirAll(dst, srcinfo.Mode()); err != nil { + return err + } + + if fds, err = fs.ReadDir(src); err != nil { + return err + } + for _, fd := range fds { + srcfp := path.Join(src, fd.Name()) + dstfp := path.Join(dst, fd.Name()) + + if fd.IsDir() { + if err = copyDirWithFS(srcfp, dstfp, fs); err != nil { + return err + } + } else { + if err = copyFileWithFs(srcfp, dstfp, fs); err != nil { + return err + } + } + } + return nil +} + +// StartSignalWatcher watches for signals and handles the situation before exiting the program +func StartSignalWatcher(watchSignals []os.Signal, handle func(receivedSignal os.Signal)) { + signals := make(chan os.Signal, 1) + signal.Notify(signals, watchSignals...) + defer signal.Stop(signals) + + receivedSignal := <-signals + handle(receivedSignal) + // exit here to stop spinners from rotating + os.Exit(1) +} + +// cleanDir cleans the original folder during events like interrupted copy etc +// it leaves the given files behind for later use +func cleanDir(originalPath string, leaveBehindFiles map[string]bool, fs filesystem.Filesystem) error { + // Open the directory. + outputDirRead, err := fs.Open(originalPath) + if err != nil { + return err + } + + // Call Readdir to get all files. + outputDirFiles, err := outputDirRead.Readdir(0) + if err != nil { + return err + } + + // Loop over files. + for _, file := range outputDirFiles { + if value, ok := leaveBehindFiles[file.Name()]; ok && value { + continue + } + err = fs.RemoveAll(filepath.Join(originalPath, file.Name())) + if err != nil { + return err + } + } + return err +} \ No newline at end of file diff --git a/index/generator/schema/schema.go b/index/generator/schema/schema.go index adeb72a72..d8b50aa52 100644 --- a/index/generator/schema/schema.go +++ b/index/generator/schema/schema.go @@ -90,6 +90,7 @@ type Schema struct { Git *Git `yaml:"git,omitempty" json:"git,omitempty"` Provider string `yaml:"provider,omitempty" json:"provider,omitempty"` SupportUrl string `yaml:"supportUrl,omitempty" json:"supportUrl,omitempty"` + Versions []Version `yaml:"versions,omitempty" json:"versions,omitempty"` } // DevfileType describes the type of devfile @@ -112,11 +113,16 @@ type StarterProject struct { type Devfile struct { Meta Schema `yaml:"metadata,omitempty" json:"metadata,omitempty"` StarterProjects []StarterProject `yaml:"starterProjects,omitempty" json:"starterProjects,omitempty"` + SchemaVersion string `yaml:"schemaversion,omitempty" json:"schemaversion,omitempty"` } // Git stores the information of remote repositories type Git struct { - Remotes map[string]string `yaml:"remotes,omitempty" json:"remotes,omitempty"` + Remotes map[string]string `yaml:"remotes,omitempty" json:"remotes,omitempty"` + Url string `yaml:"url,omitempty" json:"url,omitempty"` + RemoteName string `yaml:"remoteName,omitempty" json:"remoteName,omitempty"` + SubDir string `yaml:"subDir,omitempty" json:"subDir,omitempty"` + Revision string `yaml:"revision,omitempty" json:"revision,omitempty"` } // ExtraDevfileEntries is the extraDevfileEntries structure that is used by index component @@ -124,3 +130,25 @@ type ExtraDevfileEntries struct { Samples []Schema `yaml:"samples,omitempty" json:"samples,omitempty"` Stacks []Schema `yaml:"stacks,omitempty" json:"stacks,omitempty"` } + +type StackInfo struct { + Name string `yaml:"name,omitempty" json:"name,omitempty"` + DisplayName string `yaml:"displayName,omitempty" json:"displayName,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` + Versions []Version `yaml:"versions,omitempty" json:"versions,omitempty"` +} + +type Version struct { + Version string `yaml:"version,omitempty" json:"version,omitempty"` + SchemaVersion string `yaml:"schemaVersion,omitempty" json:"schemaVersion,omitempty"` + Default bool `yaml:"default,omitempty" json:"default,omitempty"` + Git *Git `yaml:"git,omitempty" json:"git,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"` + Architectures []string `yaml:"architectures,omitempty" json:"architectures,omitempty"` + Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` + Links map[string]string `yaml:"links,omitempty" json:"links,omitempty"` + Resources []string `yaml:"resources,omitempty" json:"resources,omitempty"` + StarterProjects []string `yaml:"starterProjects,omitempty" json:"starterProjects,omitempty"` +} \ No newline at end of file From eaf9ae2a43516ed5d5880c5c87a77c9c1815fc2f Mon Sep 17 00:00:00 2001 From: Stephanie Date: Tue, 15 Feb 2022 15:48:23 -0500 Subject: [PATCH 2/9] remove git clone code Signed-off-by: Stephanie --- index/generator/library/library.go | 261 +---------------------------- 1 file changed, 3 insertions(+), 258 deletions(-) diff --git a/index/generator/library/library.go b/index/generator/library/library.go index 2ad96d105..040f62e7b 100644 --- a/index/generator/library/library.go +++ b/index/generator/library/library.go @@ -3,19 +3,13 @@ package library import ( "encoding/json" "fmt" - "github.com/devfile/library/pkg/testingutil/filesystem" - "io" "io/ioutil" "os" - "os/signal" "path" "path/filepath" - "syscall" devfileParser "github.com/devfile/library/pkg/devfile" "github.com/devfile/library/pkg/devfile/parser" - gitpkg "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" "github.com/devfile/registry-support/index/generator/schema" "gopkg.in/yaml.v2" ) @@ -172,6 +166,9 @@ func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, } for i, versionComponent:= range indexComponent.Versions { + if versionComponent.Git != nil { + + } if versionComponent.Git == nil { stackVersonDirPath := filepath.Join(stackFolderPath, versionComponent.Version) @@ -552,256 +549,4 @@ func inArray(arr []string, value string) bool { } } return false -} - -// downloadRemoteStack downloads the stack version outside of the registry repo -func downloadRemoteStack(git *schema.Git, path string, verbose bool) (err error) { - - // convert revision to referenceName type, ref name could be a branch or tag - // if revision is not specified it would be the default branch of the project - revision := git.Revision - refName := plumbing.ReferenceName(git.Revision) - - if plumbing.IsHash(revision) { - // Specifying commit in the reference name is not supported by the go-git library - // while doing git.PlainClone() - fmt.Printf("Specifying commit in 'revision' is not yet supported.") - // overriding revision to empty as we do not support this - revision = "" - } - - if revision != "" { - // lets consider revision to be a branch name first - refName = plumbing.NewBranchReferenceName(revision) - } - - - cloneOptions := &gitpkg.CloneOptions{ - URL: git.Url, - RemoteName: git.RemoteName, - ReferenceName: refName, - SingleBranch: true, - // we don't need history for starter projects - Depth: 1, - } - - originalPath := "" - if git.SubDir != "" { - originalPath = path - path, err = ioutil.TempDir("", "") - if err != nil { - return err - } - } - - _, err = gitpkg.PlainClone(path, false, cloneOptions) - - if err != nil { - - // it returns the following error if no matching ref found - // if we get this error, we are trying again considering revision as tag, only if revision is specified. - if _, ok := err.(gitpkg.NoMatchingRefSpecError); !ok || revision == "" { - return err - } - - // try again to consider revision as tag name - cloneOptions.ReferenceName = plumbing.NewTagReferenceName(revision) - // remove if any .git folder downloaded in above try - _ = os.RemoveAll(filepath.Join(path, ".git")) - _, err = gitpkg.PlainClone(path, false, cloneOptions) - if err != nil { - return err - } - } - - // we don't want to download project be a git repo - err = os.RemoveAll(filepath.Join(path, ".git")) - if err != nil { - // we don't need to return (fail) if this happens - fmt.Printf("Unable to delete .git from cloned devfile repository") - } - - if git.SubDir != "" { - err = GitSubDir(path, originalPath, - git.SubDir) - if err != nil { - return err - } - } - - return nil - -} - -// GitSubDir handles subDir for git components using the default filesystem -func GitSubDir(srcPath, destinationPath, subDir string) error { - return gitSubDir(srcPath, destinationPath, subDir, filesystem.DefaultFs{}) -} - -// gitSubDir handles subDir for git components -func gitSubDir(srcPath, destinationPath, subDir string, fs filesystem.Filesystem) error { - go StartSignalWatcher([]os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, os.Interrupt}, func(_ os.Signal) { - err := cleanDir(destinationPath, map[string]bool{ - "devfile.yaml": true, - }, fs) - if err != nil { - fmt.Printf("error %v occurred while calling handleInterruptedSubDir", err) - } - err = fs.RemoveAll(srcPath) - if err != nil { - fmt.Printf("error %v occurred during temp folder clean up", err) - } - }) - - err := func() error { - // Open the directory. - outputDirRead, err := fs.Open(filepath.Join(srcPath, subDir)) - if err != nil { - return err - } - defer func() { - if err1 := outputDirRead.Close(); err1 != nil { - fmt.Printf("err occurred while closing temp dir: %v", err1) - - } - }() - // Call Readdir to get all files. - outputDirFiles, err := outputDirRead.Readdir(0) - if err != nil { - return err - } - - // Loop over files. - for outputIndex := range outputDirFiles { - outputFileHere := outputDirFiles[outputIndex] - - // Get name of file. - fileName := outputFileHere.Name() - - oldPath := filepath.Join(srcPath, subDir, fileName) - - if outputFileHere.IsDir() { - err = copyDirWithFS(oldPath, filepath.Join(destinationPath, fileName), fs) - } else { - err = copyFileWithFs(oldPath, filepath.Join(destinationPath, fileName), fs) - } - - if err != nil { - return err - } - } - return nil - }() - if err != nil { - return err - } - return fs.RemoveAll(srcPath) -} - -// copyFileWithFs copies a single file from src to dst -func copyFileWithFs(src, dst string, fs filesystem.Filesystem) error { - var err error - var srcinfo os.FileInfo - - srcfd, err := fs.Open(src) - if err != nil { - return err - } - defer func() { - if e := srcfd.Close(); e != nil { - fmt.Printf("err occurred while closing file: %v", e) - } - }() - - dstfd, err := fs.Create(dst) - if err != nil { - return err - } - defer func() { - if e := dstfd.Close(); e != nil { - fmt.Printf("err occurred while closing file: %v", e) - } - }() - - if _, err = io.Copy(dstfd, srcfd); err != nil { - return err - } - if srcinfo, err = fs.Stat(src); err != nil { - return err - } - return fs.Chmod(dst, srcinfo.Mode()) -} - -// copyDirWithFS copies a whole directory recursively -func copyDirWithFS(src string, dst string, fs filesystem.Filesystem) error { - var err error - var fds []os.FileInfo - var srcinfo os.FileInfo - - if srcinfo, err = fs.Stat(src); err != nil { - return err - } - - if err = fs.MkdirAll(dst, srcinfo.Mode()); err != nil { - return err - } - - if fds, err = fs.ReadDir(src); err != nil { - return err - } - for _, fd := range fds { - srcfp := path.Join(src, fd.Name()) - dstfp := path.Join(dst, fd.Name()) - - if fd.IsDir() { - if err = copyDirWithFS(srcfp, dstfp, fs); err != nil { - return err - } - } else { - if err = copyFileWithFs(srcfp, dstfp, fs); err != nil { - return err - } - } - } - return nil -} - -// StartSignalWatcher watches for signals and handles the situation before exiting the program -func StartSignalWatcher(watchSignals []os.Signal, handle func(receivedSignal os.Signal)) { - signals := make(chan os.Signal, 1) - signal.Notify(signals, watchSignals...) - defer signal.Stop(signals) - - receivedSignal := <-signals - handle(receivedSignal) - // exit here to stop spinners from rotating - os.Exit(1) -} - -// cleanDir cleans the original folder during events like interrupted copy etc -// it leaves the given files behind for later use -func cleanDir(originalPath string, leaveBehindFiles map[string]bool, fs filesystem.Filesystem) error { - // Open the directory. - outputDirRead, err := fs.Open(originalPath) - if err != nil { - return err - } - - // Call Readdir to get all files. - outputDirFiles, err := outputDirRead.Readdir(0) - if err != nil { - return err - } - - // Loop over files. - for _, file := range outputDirFiles { - if value, ok := leaveBehindFiles[file.Name()]; ok && value { - continue - } - err = fs.RemoveAll(filepath.Join(originalPath, file.Name())) - if err != nil { - return err - } - } - return err } \ No newline at end of file From 21b194d6ee5b1aac853b5240fc2d2976d2303d7b Mon Sep 17 00:00:00 2001 From: Stephanie Date: Wed, 16 Feb 2022 18:43:24 -0500 Subject: [PATCH 3/9] modify registry build script and update unit tests Signed-off-by: Stephanie --- index/generator/library/library.go | 231 +++--- index/generator/library/library_test.go | 328 +++++++- index/generator/schema/schema.go | 2 +- .../tests/registry/extraDevfileEntries.yaml | 28 +- .../generator/tests/registry/index_extra.json | 98 ++- .../generator/tests/registry/index_main.json | 784 +++++++++++------- .../tests/registry/index_registry.json | 690 +++++++++------ .../{ => 1.1.0}/devfile.yaml | 0 .../nodejs-basic/{ => 1.0.0}/devfile.yaml | 0 .../samples/nodejs-basic/1.0.1/devfile.yaml | 43 + .../registry/stacks/go/1.1.0/devfile.yaml | 47 ++ .../registry/stacks/go/1.2.0/devfile.yaml | 47 ++ .../tests/registry/stacks/go/stack.yaml | 8 + 13 files changed, 1567 insertions(+), 739 deletions(-) rename index/generator/tests/registry/samples/code-with-quarkus/{ => 1.1.0}/devfile.yaml (100%) rename index/generator/tests/registry/samples/nodejs-basic/{ => 1.0.0}/devfile.yaml (100%) create mode 100644 index/generator/tests/registry/samples/nodejs-basic/1.0.1/devfile.yaml create mode 100644 index/generator/tests/registry/stacks/go/1.1.0/devfile.yaml create mode 100644 index/generator/tests/registry/stacks/go/1.2.0/devfile.yaml create mode 100644 index/generator/tests/registry/stacks/go/stack.yaml diff --git a/index/generator/library/library.go b/index/generator/library/library.go index 040f62e7b..4f7a8b8d8 100644 --- a/index/generator/library/library.go +++ b/index/generator/library/library.go @@ -89,18 +89,66 @@ func validateIndexComponent(indexComponent schema.Schema, componentType schema.D if indexComponent.Name == "" { return fmt.Errorf("index component name is not initialized") } - if indexComponent.Links == nil { - return fmt.Errorf("index component links are empty") - } - if indexComponent.Resources == nil { - return fmt.Errorf("index component resources are empty") + if indexComponent.Versions == nil || len(indexComponent.Versions) == 0 { + return fmt.Errorf("index component versions list is empty") + } else { + defaultFound := false + for _, version := range indexComponent.Versions { + if version.Version == "" { + return fmt.Errorf("index component versions list contains an entry with no version specified") + } + if version.SchemaVersion == "" { + return fmt.Errorf("index component version %s: schema version is empty", version.Version) + } + if version.Links == nil || len(version.Links) == 0 { + return fmt.Errorf("index component version %s: links are empty", version.Version) + } + if version.Resources == nil || len(version.Resources) == 0 { + return fmt.Errorf("index component version %s: resources are empty", version.Version) + } + if version.Default { + if !defaultFound { + defaultFound = true + } else { + return fmt.Errorf("index component has multiple default versions") + } + } + } + if !defaultFound { + return fmt.Errorf("index component has no default version defined") + } } } else if componentType == schema.SampleDevfileType { - if indexComponent.Git == nil { - return fmt.Errorf("index component git is empty") - } - if len(indexComponent.Git.Remotes) > 1 { - return fmt.Errorf("index component has multiple remotes") + if indexComponent.Versions != nil && len(indexComponent.Versions) > 0 { + defaultFound := false + for _, version := range indexComponent.Versions { + if version.Version == "" { + return fmt.Errorf("index component versions list contains an entry with no version specified") + } + if version.SchemaVersion == "" { + return fmt.Errorf("index component version %s: schema version is empty", version.Version) + } + if version.Git == nil { + return fmt.Errorf("index component version %s: git is empty", version.Version) + } + if version.Default { + if !defaultFound { + defaultFound = true + } else { + return fmt.Errorf("index component has multiple default versions") + } + } + } + if !defaultFound { + return fmt.Errorf("index component has no default version defined") + } + } else { + if indexComponent.Git == nil { + return fmt.Errorf("index component git is empty") + } + if len(indexComponent.Git.Remotes) > 1 { + return fmt.Errorf("index component has multiple remotes") + } } } @@ -165,19 +213,23 @@ func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, } } - for i, versionComponent:= range indexComponent.Versions { + i:= 0 + for i < len(indexComponent.Versions) { + versionComponent := indexComponent.Versions[i] if versionComponent.Git != nil { - + // Todo: implement Git reference support, get stack content from remote repository and store in OCI registry + fmt.Printf("stack: %v, version:%v, Git reference is currently not supported", stackFolderDir.Name(), versionComponent.Version) + indexComponent.Versions = append(indexComponent.Versions[:i], indexComponent.Versions[i+1:]...) + continue } - if versionComponent.Git == nil { - stackVersonDirPath := filepath.Join(stackFolderPath, versionComponent.Version) + stackVersonDirPath := filepath.Join(stackFolderPath, versionComponent.Version) - err := parseStackDevfile(stackVersonDirPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) - if err != nil { - return nil, err - } - indexComponent.Versions[i] = versionComponent + err := parseStackDevfile(stackVersonDirPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) + if err != nil { + return nil, err } + indexComponent.Versions[i] = versionComponent + i++ } } else { // if stack.yaml not exist, old stack repo struct, directly lookfor & parse devfile.yaml versionComponent := schema.Version{} @@ -190,77 +242,20 @@ func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, } indexComponent.Type = schema.StackDevfileType - //// Allow devfile.yaml or .devfile.yaml - //devfilePath := filepath.Join(stackDirPath, stackFolderDir.Name(), devfile) - //devfileHiddenPath := filepath.Join(stackDirPath, stackFolderDir.Name(), devfileHidden) - //if fileExists(devfilePath) && fileExists(devfileHiddenPath) { - // return nil, fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) - //} - //if fileExists(devfileHiddenPath) { - // devfilePath = devfileHiddenPath - //} - // - //if !force { - // // Devfile validation - // devfileObj,_, err := devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) - // if err != nil { - // return nil, fmt.Errorf("%s devfile is not valid: %v", stackFolderDir.Name(), err) - // } - // - // metadataErrors := checkForRequiredMetadata(devfileObj) - // if metadataErrors != nil { - // return nil, fmt.Errorf("%s devfile is not valid: %v", stackFolderDir.Name(), metadataErrors) - // } - //} - // - //bytes, err := ioutil.ReadFile(devfilePath) - //if err != nil { - // return nil, fmt.Errorf("failed to read %s: %v", devfilePath, err) - //} - //var devfile schema.Devfile - //err = yaml.Unmarshal(bytes, &devfile) - //if err != nil { - // return nil, fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) - //} - //indexComponent := devfile.Meta - //if indexComponent.Links == nil { - // indexComponent.Links = make(map[string]string) - //} - //indexComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", indexComponent.Name, "latest") - //indexComponent.Type = schema.StackDevfileType - // - //for _, starterProject := range devfile.StarterProjects { - // indexComponent.StarterProjects = append(indexComponent.StarterProjects, starterProject.Name) - //} - // - //// Get the files in the stack folder - //stackFolder := filepath.Join(stackDirPath, stackFolderDir.Name()) - //stackFiles, err := ioutil.ReadDir(stackFolder) - //if err != nil { - // return index, err - //} - //for _, stackFile := range stackFiles { - // // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file - // // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. - // if !stackFile.IsDir() { - // indexComponent.Resources = append(indexComponent.Resources, stackFile.Name()) - // } - //} - // - //if !force { - // // Index component validation - // err := validateIndexComponent(indexComponent, schema.StackDevfileType) - // switch err.(type) { - // case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: - // // log to the console as FYI if the devfile has no architectures/provider/supportUrl - // fmt.Printf("%s", err.Error()) - // default: - // // only return error if we dont want to print - // if err != nil { - // return nil, fmt.Errorf("%s index component is not valid: %v", stackFolderDir.Name(), err) - // } - // } - //} + if !force { + // Index component validation + err := validateIndexComponent(indexComponent, schema.StackDevfileType) + switch err.(type) { + case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: + // log to the console as FYI if the devfile has no architectures/provider/supportUrl + fmt.Printf("%s", err.Error()) + default: + // only return error if we dont want to print + if err != nil { + return nil, fmt.Errorf("%s index component is not valid: %v", stackFolderDir.Name(), err) + } + } + } index = append(index, indexComponent) } @@ -378,21 +373,6 @@ func parseStackDevfile(devfileDirPath string, stackName string, force bool, vers versionComponent.Resources = append(versionComponent.Resources, stackFile.Name()) } } - - //if !force { - // // Index component validation - // err := validateIndexComponent(versionComponent, schema.StackDevfileType) - // switch err.(type) { - // case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: - // // log to the console as FYI if the devfile has no architectures/provider/supportUrl - // fmt.Printf("%s", err.Error()) - // default: - // // only return error if we dont want to print - // if err != nil { - // return schema.Version{}, fmt.Errorf("%s index component is not valid: %v", stackFolder, err) - // } - // } - //} return nil } @@ -428,21 +408,38 @@ func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Sche indexComponent := devfileEntry indexComponent.Type = devfileType if !force { - // If sample, validate devfile associated with sample as well // Can't handle during registry build since we don't have access to devfile library/parser if indexComponent.Type == schema.SampleDevfileType && validateSamples { - devfilePath := filepath.Join(samplesDir, devfileEntry.Name, "devfile.yaml") - _, err := os.Stat(filepath.Join(devfilePath)) - if err != nil { - // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless - return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) - } - - // Validate the sample devfile - _, err = devfileParser.ParseAndValidate(devfilePath) - if err != nil { - return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) + if indexComponent.Versions != nil && len(indexComponent.Versions) > 0 { + for _, version := range indexComponent.Versions{ + sampleVersonDirPath := filepath.Join(samplesDir, devfileEntry.Name, version.Version) + devfilePath := filepath.Join(sampleVersonDirPath, "devfile.yaml") + _, err := os.Stat(filepath.Join(devfilePath)) + if err != nil { + // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless + return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) + } + + // Validate the sample devfile + _, _, err = devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) + if err != nil { + return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) + } + } + } else { + devfilePath := filepath.Join(samplesDir, devfileEntry.Name, "devfile.yaml") + _, err := os.Stat(filepath.Join(devfilePath)) + if err != nil { + // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless + return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) + } + + // Validate the sample devfile + _, _, err = devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) + if err != nil { + return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) + } } } diff --git a/index/generator/library/library_test.go b/index/generator/library/library_test.go index 3d600e85c..ff6423aa1 100644 --- a/index/generator/library/library_test.go +++ b/index/generator/library/library_test.go @@ -25,6 +25,11 @@ func TestValidateIndexComponent(t *testing.T) { noArchErr := ".*has no architecture.*" noProviderErr := ".*has no provider.*" noSupportUrlErr := ".*has no supportUrl.*" + versionsEmptyErr := ".*versions list is empty.*" + noDefaultVersionErr := ".*has no default version.*" + noVersionErr := ".*no version specified.*" + schemaVersionEmptyErr := ".*schema version is empty.*" + multipleVersionErr := ".*has multiple default versions.*" tests := []struct { name string @@ -49,8 +54,14 @@ func TestValidateIndexComponent(t *testing.T) { "Case 2: test index component links are empty for stack component", schema.Schema{ Name: "nodejs", - Resources: []string{ - "devfile.yaml", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Resources: []string{ + "devfile.yaml", + }, + }, }, }, schema.StackDevfileType, @@ -60,8 +71,14 @@ func TestValidateIndexComponent(t *testing.T) { "Case 3: test index component resources are empty for stack component", schema.Schema{ Name: "nodejs", - Links: map[string]string{ - "self": "devfile-catalog/java-maven:latest", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Links: map[string]string{ + "self": "devfile-catalog/java-maven:latest", + }, + }, }, }, schema.StackDevfileType, @@ -79,23 +96,40 @@ func TestValidateIndexComponent(t *testing.T) { "Case 5: test happy path for for stack component", schema.Schema{ Name: "nodejs", - Links: map[string]string{ - "self": "devfile-catalog/java-maven:latest", - }, - Resources: []string{ - "devfile.yaml", - }, Architectures: []string{ "amd64", }, Provider: "Red Hat", SupportUrl: "http://testurl/support.md", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Default: true, + Links: map[string]string{ + "self": "devfile-catalog/java-maven:1.0.0", + }, + Resources: []string{ + "devfile.yaml", + }, + }, + { + Version: "1.1.0", + SchemaVersion: "2.1.0", + Links: map[string]string{ + "self": "devfile-catalog/java-maven:2.1.0", + }, + Resources: []string{ + "devfile.yaml", + }, + }, + }, }, schema.StackDevfileType, nil, }, { - "Case 6: test happy path for for sample component", + "Case 6: test happy path for for sample component with old struct", schema.Schema{ Name: "nodejs", Git: &schema.Git{ @@ -145,11 +179,18 @@ func TestValidateIndexComponent(t *testing.T) { "Case 9: check for missing provider", schema.Schema{ Name: "nodejs", - Links: map[string]string{ - "self": "devfile-catalog/java-maven:latest", - }, - Resources: []string{ - "devfile.yaml", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Default: true, + Links: map[string]string{ + "self": "devfile-catalog/java-maven:latest", + }, + Resources: []string{ + "devfile.yaml", + }, + }, }, Architectures: []string{ "amd64", @@ -163,11 +204,18 @@ func TestValidateIndexComponent(t *testing.T) { "Case 10: check for missing supportUrl", schema.Schema{ Name: "nodejs", - Links: map[string]string{ - "self": "devfile-catalog/java-maven:latest", - }, - Resources: []string{ - "devfile.yaml", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Default: true, + Links: map[string]string{ + "self": "devfile-catalog/java-maven:latest", + }, + Resources: []string{ + "devfile.yaml", + }, + }, }, Architectures: []string{ "amd64", @@ -177,6 +225,244 @@ func TestValidateIndexComponent(t *testing.T) { schema.StackDevfileType, &noSupportUrlErr, }, + { + "Case 11: empty version list", + schema.Schema{ + Name: "nodejs", + Versions: []schema.Version{}, + }, + schema.StackDevfileType, + &versionsEmptyErr, + }, + { + "Case 12: test stack component missing default version", + schema.Schema{ + Name: "nodejs", + Architectures: []string{ + "amd64", + }, + Provider: "Red Hat", + SupportUrl: "http://testurl/support.md", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Links: map[string]string{ + "self": "devfile-catalog/java-maven:latest", + }, + Resources: []string{ + "devfile.yaml", + }, + }, + }, + }, + schema.StackDevfileType, + &noDefaultVersionErr, + }, + { + "Case 13: test stack component missing version", + schema.Schema{ + Name: "nodejs", + Versions: []schema.Version{ + { + SchemaVersion: "2.0.0", + Links: map[string]string{ + "self": "devfile-catalog/java-maven:latest", + }, + Resources: []string{ + "devfile.yaml", + }, + }, + }, + }, + schema.StackDevfileType, + &noVersionErr, + }, + { + "Case 14: test stack component missing schema version", + schema.Schema{ + Name: "nodejs", + Versions: []schema.Version{ + { + Version: "1.0.0", + Links: map[string]string{ + "self": "devfile-catalog/java-maven:latest", + }, + Resources: []string{ + "devfile.yaml", + }, + }, + }, + }, + schema.StackDevfileType, + &schemaVersionEmptyErr, + }, + { + "Case 15: test stack component multiple default version", + schema.Schema{ + Name: "nodejs", + Architectures: []string{ + "amd64", + }, + Provider: "Red Hat", + SupportUrl: "http://testurl/support.md", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Default: true, + Links: map[string]string{ + "self": "devfile-catalog/java-maven:1.0.0", + }, + Resources: []string{ + "devfile.yaml", + }, + }, + { + Version: "1.1.0", + SchemaVersion: "2.1.0", + Default: true, + Links: map[string]string{ + "self": "devfile-catalog/java-maven:1.1.0", + }, + Resources: []string{ + "devfile.yaml", + }, + }, + }, + }, + schema.StackDevfileType, + &multipleVersionErr, + }, + { + "Case 16: test happy path for for sample component with new struct", + schema.Schema{ + Name: "nodejs", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Default: true, + Git: &schema.Git{ + Remotes: map[string]string{ + "origin": "/~https://github.com/redhat-developer/devfile-sample/nodejs", + }, + }, + }, + { + Version: "1.1.0", + SchemaVersion: "2.1.0", + Git: &schema.Git{ + Remotes: map[string]string{ + "origin": "/~https://github.com/redhat-developer/devfile-sample/nodejs-2.1.0", + }, + }, + }, + }, + SupportUrl: "http://testurl/support.md", + Provider: "Red Hat", + Architectures: []string{ + "amd64", + }, + }, + schema.SampleDevfileType, + nil, + }, + { + "Case 17: test sample component missing default version", + schema.Schema{ + Name: "nodejs", + Architectures: []string{ + "amd64", + }, + Provider: "Red Hat", + SupportUrl: "http://testurl/support.md", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Git: &schema.Git{ + Remotes: map[string]string{ + "origin": "/~https://github.com/redhat-developer/devfile-sample/nodejs", + }, + }, + }, + }, + }, + schema.SampleDevfileType, + &noDefaultVersionErr, + }, + { + "Case 18: test sample component missing version", + schema.Schema{ + Name: "nodejs", + Versions: []schema.Version{ + { + SchemaVersion: "2.0.0", + Git: &schema.Git{ + Remotes: map[string]string{ + "origin": "/~https://github.com/redhat-developer/devfile-sample/nodejs", + }, + }, + }, + }, + }, + schema.SampleDevfileType, + &noVersionErr, + }, + { + "Case 19: test sample component missing schema version", + schema.Schema{ + Name: "nodejs", + Versions: []schema.Version{ + { + Version: "1.0.0", + Git: &schema.Git{ + Remotes: map[string]string{ + "origin": "/~https://github.com/redhat-developer/devfile-sample/nodejs", + }, + }, + }, + }, + }, + schema.SampleDevfileType, + &schemaVersionEmptyErr, + }, + { + "Case 20: test sample component multiple default version", + schema.Schema{ + Name: "nodejs", + Architectures: []string{ + "amd64", + }, + Provider: "Red Hat", + SupportUrl: "http://testurl/support.md", + Versions: []schema.Version{ + { + Version: "1.0.0", + SchemaVersion: "2.0.0", + Default: true, + Git: &schema.Git{ + Remotes: map[string]string{ + "origin": "/~https://github.com/redhat-developer/devfile-sample/nodejs", + }, + }, + }, + { + Version: "1.1.0", + SchemaVersion: "2.1.0", + Default: true, + Git: &schema.Git{ + Remotes: map[string]string{ + "origin": "/~https://github.com/redhat-developer/devfile-sample/nodejs-2.1.0", + }, + }, + }, + }, + }, + schema.SampleDevfileType, + &multipleVersionErr, + }, } for _, tt := range tests { diff --git a/index/generator/schema/schema.go b/index/generator/schema/schema.go index d8b50aa52..99a56d5d6 100644 --- a/index/generator/schema/schema.go +++ b/index/generator/schema/schema.go @@ -113,7 +113,7 @@ type StarterProject struct { type Devfile struct { Meta Schema `yaml:"metadata,omitempty" json:"metadata,omitempty"` StarterProjects []StarterProject `yaml:"starterProjects,omitempty" json:"starterProjects,omitempty"` - SchemaVersion string `yaml:"schemaversion,omitempty" json:"schemaversion,omitempty"` + SchemaVersion string `yaml:"schemaVersion,omitempty" json:"schemaVersion,omitempty"` } // Git stores the information of remote repositories diff --git a/index/generator/tests/registry/extraDevfileEntries.yaml b/index/generator/tests/registry/extraDevfileEntries.yaml index 9257f984f..a11a5cb84 100644 --- a/index/generator/tests/registry/extraDevfileEntries.yaml +++ b/index/generator/tests/registry/extraDevfileEntries.yaml @@ -7,9 +7,20 @@ samples: tags: ["NodeJS", "Express"] projectType: nodejs language: nodejs - git: - remotes: - origin: /~https://github.com/redhat-developer/devfile-sample + versions: + - version: 1.0.0 + schemaVersion: 2.0.0 + description: nodejs with devfile v2.0.0 + git: + remotes: + origin: /~https://github.com/redhat-developer/devfile-sample + - version: 1.0.1 + schemaVersion: 2.2.0 + default: true + description: nodejs with devfile v2.2.0 + git: + remotes: + origin: /~https://github.com/nodeshift-starters/devfile-sample - name: code-with-quarkus displayName: Basic Quarkus description: A simple Hello World Java application using Quarkus @@ -18,6 +29,11 @@ samples: projectType: quarkus language: java provider: Red Hat - git: - remotes: - origin: /~https://github.com/elsony/devfile-sample-code-with-quarkus.git \ No newline at end of file + versions: + - version: 1.1.0 + schemaVersion: 2.0.0 + default: true + description: java quarkus with devfile v2.0.0 + git: + remotes: + origin: /~https://github.com/elsony/devfile-sample-code-with-quarkus.git \ No newline at end of file diff --git a/index/generator/tests/registry/index_extra.json b/index/generator/tests/registry/index_extra.json index c3d0ad94e..a605f4c9b 100644 --- a/index/generator/tests/registry/index_extra.json +++ b/index/generator/tests/registry/index_extra.json @@ -1,39 +1,65 @@ [ - { - "name": "nodejs-basic", - "displayName": "Basic NodeJS", - "description": "A simple Hello World application", - "type": "sample", - "tags": [ - "NodeJS", - "Express" - ], - "icon": "nodejsIcon.svg", - "projectType": "nodejs", - "language": "nodejs", - "git": { - "remotes": { - "origin": "/~https://github.com/redhat-developer/devfile-sample" - } + { + "name": "nodejs-basic", + "displayName": "Basic NodeJS", + "description": "A simple Hello World application", + "type": "sample", + "tags": [ + "NodeJS", + "Express" + ], + "icon": "nodejsIcon.svg", + "projectType": "nodejs", + "language": "nodejs", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.0.0", + "git": { + "remotes": { + "origin": "/~https://github.com/redhat-developer/devfile-sample" + } + }, + "description": "nodejs with devfile v2.0.0" + }, + { + "version": "1.0.1", + "schemaVersion": "2.2.0", + "default": true, + "git": { + "remotes": { + "origin": "/~https://github.com/nodeshift-starters/devfile-sample" + } + }, + "description": "nodejs with devfile v2.2.0" } - }, - { - "name": "code-with-quarkus", - "displayName": "Basic Quarkus", - "description": "A simple Hello World Java application using Quarkus", - "type": "sample", - "tags": [ - "Java", - "Quarkus" - ], - "icon": "https://raw.githubusercontent.com/elsony/devfile-sample-code-with-quarkus/main/.devfile/icon/quarkus.png", - "projectType": "quarkus", - "language": "java", - "provider": "Red Hat", - "git": { - "remotes": { - "origin": "/~https://github.com/elsony/devfile-sample-code-with-quarkus.git" - } + ] + }, + { + "name": "code-with-quarkus", + "displayName": "Basic Quarkus", + "description": "A simple Hello World Java application using Quarkus", + "type": "sample", + "tags": [ + "Java", + "Quarkus" + ], + "icon": "https://raw.githubusercontent.com/elsony/devfile-sample-code-with-quarkus/main/.devfile/icon/quarkus.png", + "projectType": "quarkus", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "git": { + "remotes": { + "origin": "/~https://github.com/elsony/devfile-sample-code-with-quarkus.git" + } + }, + "description": "java quarkus with devfile v2.0.0" } - } - ] \ No newline at end of file + ] + } +] \ No newline at end of file diff --git a/index/generator/tests/registry/index_main.json b/index/generator/tests/registry/index_main.json index 86b0beea4..64363af21 100644 --- a/index/generator/tests/registry/index_main.json +++ b/index/generator/tests/registry/index_main.json @@ -1,301 +1,493 @@ [ - { - "name": "java-maven", - "version": "1.1.0", - "displayName": "Maven Java", - "description": "Upstream Maven and OpenJDK 11", - "type": "stack", - "tags": [ - "Java", - "Maven" - ], - "projectType": "maven", - "language": "java", - "provider": "Red Hat", - "links": { - "self": "devfile-catalog/java-maven:latest" + { + "name": "go", + "displayName": "Go Runtime", + "description": "Stack with the latest Go version", + "type": "stack", + "tags": [ + "Go", + "testtag" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "projectType": "go", + "language": "go", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "description": "Stack with the latest Go version with devfile v2.0.0 schema verison", + "tags": [ + "Go" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "links": { + "self": "devfile-catalog/go:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ] }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "springbootproject" - ] - }, - { - "name": "java-openliberty", - "version": "0.5.0", - "displayName": "Open Liberty", - "description": "Java application stack using Open Liberty runtime", - "type": "stack", - "projectType": "docker", - "language": "java", - "provider": "Red Hat", - "links": { - "self": "devfile-catalog/java-openliberty:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "user-app" - ] - }, - { - "name": "java-quarkus", - "version": "1.1.0", - "displayName": "Quarkus Java", - "description": "Upstream Quarkus with Java+GraalVM", - "type": "stack", - "tags": [ - "Java", - "Quarkus" - ], - "projectType": "quarkus", - "language": "java", - "provider": "Red Hat", - "links": { - "self": "devfile-catalog/java-quarkus:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "community", - "redhat-product" - ] - }, - { - "name": "java-springboot", - "version": "1.1.0", - "displayName": "Spring Boot®", - "description": "Spring Boot® using Java", - "type": "stack", - "tags": [ - "Java", - "Spring" - ], - "icon": "https://www.eclipse.org/che/images/logo-eclipseche.svg", - "globalMemoryLimit": "2674Mi", - "projectType": "spring", - "language": "java", - "links": { - "self": "devfile-catalog/java-springboot:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "springbootproject" - ] - }, - { - "name": "java-vertx", - "version": "1.1.0", - "displayName": "Vert.x Java", - "description": "Upstream Vert.x using Java", - "type": "stack", - "tags": [ - "Java", - "Vert.x" - ], - "projectType": "vertx", - "language": "java", - "links": { - "self": "devfile-catalog/java-vertx:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "vertx-http-example", - "vertx-istio-circuit-breaker-booster", - "vertx-istio-routing-booster", - "vertx-secured-http-example-redhat", - "vertx-crud-example-redhat", - "vertx-istio-security-booster", - "vertx-crud-example", - "vertx-circuit-breaker-example", - "vertx-configmap-example", - "vertx-circuit-breaker-example-redhat", - "vertx-cache-example-redhat", - "vertx-cache-example", - "vertx-secured-http-example", - "vertx-health-checks-example-redhat", - "vertx-http-example-redhat", - "vertx-health-checks-example", - "vertx-configmap-example-redhat", - "vertx-messaging-work-queue-booster", - "vertx-istio-distributed-tracing-booster" - ] - }, - { - "name": "java-wildfly", - "version": "1.0.0", - "displayName": "WildFly Java", - "description": "Upstream WildFly", - "type": "stack", - "tags": [ - "Java", - "WildFly" - ], - "projectType": "wildfly", - "language": "java", - "links": { - "self": "devfile-catalog/java-wildfly:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "microprofile-config", - "microprofile-fault-tolerance", - "microprofile-health", - "microprofile-jwt", - "microprofile-metrics", - "microprofile-openapi", - "microprofile-opentracing", - "microprofile-rest-client" - ] - }, - { - "name": "java-wildfly-bootable-jar", - "version": "1.0.0", - "displayName": "WildFly Bootable Jar", - "description": "Java stack with WildFly in bootable Jar mode, OpenJDK 11 and Maven 3.5", - "type": "stack", - "tags": [ - "RHEL8", - "Java", - "OpenJDK", - "Maven", - "WildFly", - "Microprofile", - "WildFly Bootable" - ], - "projectType": "WildFly", - "language": "java", - "links": { - "self": "devfile-catalog/java-wildfly-bootable-jar:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "microprofile-config", - "microprofile-fault-tolerance", - "microprofile-health", - "microprofile-jwt", - "microprofile-metrics", - "microprofile-openapi", - "microprofile-opentracing", - "microprofile-rest-client" - ] - }, - { - "name": "nodejs", - "version": "1.0.0", - "displayName": "NodeJS Runtime", - "description": "Stack with NodeJS 12", - "type": "stack", - "tags": [ - "NodeJS", - "Express", - "ubi8" - ], - "projectType": "nodejs", - "language": "nodejs", - "links": { - "self": "devfile-catalog/nodejs:latest" - }, - "resources": [ - "archive.tar", - "devfile.yaml" - ], - "starterProjects": [ - "nodejs-starter" - ] - }, - { - "name": "python", - "version": "1.0.0", - "displayName": "Python", - "description": "Python Stack with Python 3.7", - "type": "stack", - "tags": [ - "Python", - "pip" - ], - "projectType": "python", - "language": "python", - "links": { - "self": "devfile-catalog/python:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "python-example" - ] - }, - { - "name": "python-django", - "version": "1.0.0", - "displayName": "Django", - "description": "Python3.7 with Django", - "type": "stack", - "tags": [ - "Python", - "pip", - "Django" - ], - "projectType": "django", - "language": "python", - "links": { - "self": "devfile-catalog/python-django:latest" + { + "version": "1.2.0", + "schemaVersion": "2.1.0", + "description": "Stack with the latest Go version with devfile v2.1.0 schema verison", + "tags": [ + "testtag" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "links": { + "self": "devfile-catalog/go:1.2.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ] + } + ] + }, + { + "name": "java-maven", + "displayName": "Maven Java", + "description": "Upstream Maven and OpenJDK 11", + "type": "stack", + "tags": [ + "Java", + "Maven" + ], + "projectType": "maven", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream Maven and OpenJDK 11", + "tags": [ + "Java", + "Maven" + ], + "links": { + "self": "devfile-catalog/java-maven:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + } + ] + }, + { + "name": "java-openliberty", + "displayName": "Open Liberty", + "description": "Java application stack using Open Liberty runtime", + "type": "stack", + "projectType": "docker", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "0.5.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Java application stack using Open Liberty runtime", + "links": { + "self": "devfile-catalog/java-openliberty:0.5.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "user-app" + ] + } + ] + }, + { + "name": "java-quarkus", + "displayName": "Quarkus Java", + "description": "Upstream Quarkus with Java+GraalVM", + "type": "stack", + "tags": [ + "Java", + "Quarkus" + ], + "projectType": "quarkus", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream Quarkus with Java+GraalVM", + "tags": [ + "Java", + "Quarkus" + ], + "links": { + "self": "devfile-catalog/java-quarkus:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "community", + "redhat-product" + ] + } + ] + }, + { + "name": "java-springboot", + "displayName": "Spring Boot®", + "description": "Spring Boot® using Java", + "type": "stack", + "tags": [ + "Java", + "Spring" + ], + "icon": "https://www.eclipse.org/che/images/logo-eclipseche.svg", + "projectType": "spring", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Spring Boot® using Java", + "tags": [ + "Java", + "Spring" + ], + "icon": "https://www.eclipse.org/che/images/logo-eclipseche.svg", + "links": { + "self": "devfile-catalog/java-springboot:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + } + ] + }, + { + "name": "java-vertx", + "displayName": "Vert.x Java", + "description": "Upstream Vert.x using Java", + "type": "stack", + "tags": [ + "Java", + "Vert.x" + ], + "projectType": "vertx", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream Vert.x using Java", + "tags": [ + "Java", + "Vert.x" + ], + "links": { + "self": "devfile-catalog/java-vertx:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "vertx-http-example", + "vertx-istio-circuit-breaker-booster", + "vertx-istio-routing-booster", + "vertx-secured-http-example-redhat", + "vertx-crud-example-redhat", + "vertx-istio-security-booster", + "vertx-crud-example", + "vertx-circuit-breaker-example", + "vertx-configmap-example", + "vertx-circuit-breaker-example-redhat", + "vertx-cache-example-redhat", + "vertx-cache-example", + "vertx-secured-http-example", + "vertx-health-checks-example-redhat", + "vertx-http-example-redhat", + "vertx-health-checks-example", + "vertx-configmap-example-redhat", + "vertx-messaging-work-queue-booster", + "vertx-istio-distributed-tracing-booster" + ] + } + ] + }, + { + "name": "java-wildfly", + "displayName": "WildFly Java", + "description": "Upstream WildFly", + "type": "stack", + "tags": [ + "Java", + "WildFly" + ], + "projectType": "wildfly", + "language": "java", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream WildFly", + "tags": [ + "Java", + "WildFly" + ], + "links": { + "self": "devfile-catalog/java-wildfly:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "microprofile-config", + "microprofile-fault-tolerance", + "microprofile-health", + "microprofile-jwt", + "microprofile-metrics", + "microprofile-openapi", + "microprofile-opentracing", + "microprofile-rest-client" + ] + } + ] + }, + { + "name": "java-wildfly-bootable-jar", + "displayName": "WildFly Bootable Jar", + "description": "Java stack with WildFly in bootable Jar mode, OpenJDK 11 and Maven 3.5", + "type": "stack", + "tags": [ + "RHEL8", + "Java", + "OpenJDK", + "Maven", + "WildFly", + "Microprofile", + "WildFly Bootable" + ], + "projectType": "WildFly", + "language": "java", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Java stack with WildFly in bootable Jar mode, OpenJDK 11 and Maven 3.5", + "tags": [ + "RHEL8", + "Java", + "OpenJDK", + "Maven", + "WildFly", + "Microprofile", + "WildFly Bootable" + ], + "links": { + "self": "devfile-catalog/java-wildfly-bootable-jar:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "microprofile-config", + "microprofile-fault-tolerance", + "microprofile-health", + "microprofile-jwt", + "microprofile-metrics", + "microprofile-openapi", + "microprofile-opentracing", + "microprofile-rest-client" + ] + } + ] + }, + { + "name": "nodejs", + "displayName": "NodeJS Runtime", + "description": "Stack with NodeJS 12", + "type": "stack", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "projectType": "nodejs", + "language": "nodejs", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Stack with NodeJS 12", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "links": { + "self": "devfile-catalog/nodejs:1.0.0" + }, + "resources": [ + "archive.tar", + "devfile.yaml" + ], + "starterProjects": [ + "nodejs-starter" + ] + } + ] + }, + { + "name": "python", + "displayName": "Python", + "description": "Python Stack with Python 3.7", + "type": "stack", + "tags": [ + "Python", + "pip" + ], + "projectType": "python", + "language": "python", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Python Stack with Python 3.7", + "tags": [ + "Python", + "pip" + ], + "links": { + "self": "devfile-catalog/python:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "python-example" + ] + } + ] + }, + { + "name": "python-django", + "displayName": "Django", + "description": "Python3.7 with Django", + "type": "stack", + "tags": [ + "Python", + "pip", + "Django" + ], + "projectType": "django", + "language": "python", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Python3.7 with Django", + "tags": [ + "Python", + "pip", + "Django" + ], + "links": { + "self": "devfile-catalog/python-django:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "django-example" + ] + } + ] + }, + { + "name": "nodejs-basic", + "displayName": "Basic NodeJS", + "description": "A simple Hello World application", + "type": "sample", + "tags": [ + "NodeJS", + "Express" + ], + "icon": "nodejsIcon.svg", + "projectType": "nodejs", + "language": "nodejs", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.0.0", + "git": { + "remotes": { + "origin": "/~https://github.com/redhat-developer/devfile-sample" + } + }, + "description": "nodejs with devfile v2.0.0" }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "django-example" - ] - }, - { - "name": "nodejs-basic", - "displayName": "Basic NodeJS", - "description": "A simple Hello World application", - "type": "sample", - "tags": [ - "NodeJS", - "Express" - ], - "icon": "nodejsIcon.svg", - "projectType": "nodejs", - "language": "nodejs", - "git": { - "remotes": { - "origin": "/~https://github.com/redhat-developer/devfile-sample" - } + { + "version": "1.0.1", + "schemaVersion": "2.2.0", + "default": true, + "git": { + "remotes": { + "origin": "/~https://github.com/nodeshift-starters/devfile-sample" + } + }, + "description": "nodejs with devfile v2.2.0" } - }, - { - "name": "code-with-quarkus", - "displayName": "Basic Quarkus", - "description": "A simple Hello World Java application using Quarkus", - "type": "sample", - "tags": [ - "Java", - "Quarkus" - ], - "icon": "https://raw.githubusercontent.com/elsony/devfile-sample-code-with-quarkus/main/.devfile/icon/quarkus.png", - "projectType": "quarkus", - "language": "java", - "provider": "Red Hat", - "git": { - "remotes": { - "origin": "/~https://github.com/elsony/devfile-sample-code-with-quarkus.git" - } + ] + }, + { + "name": "code-with-quarkus", + "displayName": "Basic Quarkus", + "description": "A simple Hello World Java application using Quarkus", + "type": "sample", + "tags": [ + "Java", + "Quarkus" + ], + "icon": "https://raw.githubusercontent.com/elsony/devfile-sample-code-with-quarkus/main/.devfile/icon/quarkus.png", + "projectType": "quarkus", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "git": { + "remotes": { + "origin": "/~https://github.com/elsony/devfile-sample-code-with-quarkus.git" + } + }, + "description": "java quarkus with devfile v2.0.0" } - } - ] \ No newline at end of file + ] + } +] \ No newline at end of file diff --git a/index/generator/tests/registry/index_registry.json b/index/generator/tests/registry/index_registry.json index 349275ae7..f0050be0b 100644 --- a/index/generator/tests/registry/index_registry.json +++ b/index/generator/tests/registry/index_registry.json @@ -1,264 +1,430 @@ [ - { - "name": "java-maven", - "version": "1.1.0", - "displayName": "Maven Java", - "description": "Upstream Maven and OpenJDK 11", - "type": "stack", - "tags": [ - "Java", - "Maven" - ], - "projectType": "maven", - "language": "java", - "provider": "Red Hat", - "links": { - "self": "devfile-catalog/java-maven:latest" + { + "name": "go", + "displayName": "Go Runtime", + "description": "Stack with the latest Go version", + "type": "stack", + "tags": [ + "Go", + "testtag" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "projectType": "go", + "language": "go", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "description": "Stack with the latest Go version with devfile v2.0.0 schema verison", + "tags": [ + "Go" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "links": { + "self": "devfile-catalog/go:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ] }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "springbootproject" - ] - }, - { - "name": "java-openliberty", - "version": "0.5.0", - "displayName": "Open Liberty", - "description": "Java application stack using Open Liberty runtime", - "type": "stack", - "projectType": "docker", - "language": "java", - "provider": "Red Hat", - "links": { - "self": "devfile-catalog/java-openliberty:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "user-app" - ] - }, - { - "name": "java-quarkus", - "version": "1.1.0", - "displayName": "Quarkus Java", - "description": "Upstream Quarkus with Java+GraalVM", - "type": "stack", - "tags": [ - "Java", - "Quarkus" - ], - "projectType": "quarkus", - "language": "java", - "provider": "Red Hat", - "links": { - "self": "devfile-catalog/java-quarkus:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "community", - "redhat-product" - ] - }, - { - "name": "java-springboot", - "version": "1.1.0", - "displayName": "Spring Boot®", - "description": "Spring Boot® using Java", - "type": "stack", - "tags": [ - "Java", - "Spring" - ], - "icon": "https://www.eclipse.org/che/images/logo-eclipseche.svg", - "globalMemoryLimit": "2674Mi", - "projectType": "spring", - "language": "java", - "links": { - "self": "devfile-catalog/java-springboot:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "springbootproject" - ] - }, - { - "name": "java-vertx", - "version": "1.1.0", - "displayName": "Vert.x Java", - "description": "Upstream Vert.x using Java", - "type": "stack", - "tags": [ - "Java", - "Vert.x" - ], - "projectType": "vertx", - "language": "java", - "links": { - "self": "devfile-catalog/java-vertx:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "vertx-http-example", - "vertx-istio-circuit-breaker-booster", - "vertx-istio-routing-booster", - "vertx-secured-http-example-redhat", - "vertx-crud-example-redhat", - "vertx-istio-security-booster", - "vertx-crud-example", - "vertx-circuit-breaker-example", - "vertx-configmap-example", - "vertx-circuit-breaker-example-redhat", - "vertx-cache-example-redhat", - "vertx-cache-example", - "vertx-secured-http-example", - "vertx-health-checks-example-redhat", - "vertx-http-example-redhat", - "vertx-health-checks-example", - "vertx-configmap-example-redhat", - "vertx-messaging-work-queue-booster", - "vertx-istio-distributed-tracing-booster" - ] - }, - { - "name": "java-wildfly", - "version": "1.0.0", - "displayName": "WildFly Java", - "description": "Upstream WildFly", - "type": "stack", - "tags": [ - "Java", - "WildFly" - ], - "projectType": "wildfly", - "language": "java", - "links": { - "self": "devfile-catalog/java-wildfly:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "microprofile-config", - "microprofile-fault-tolerance", - "microprofile-health", - "microprofile-jwt", - "microprofile-metrics", - "microprofile-openapi", - "microprofile-opentracing", - "microprofile-rest-client" - ] - }, - { - "name": "java-wildfly-bootable-jar", - "version": "1.0.0", - "displayName": "WildFly Bootable Jar", - "description": "Java stack with WildFly in bootable Jar mode, OpenJDK 11 and Maven 3.5", - "type": "stack", - "tags": [ - "RHEL8", - "Java", - "OpenJDK", - "Maven", - "WildFly", - "Microprofile", - "WildFly Bootable" - ], - "projectType": "WildFly", - "language": "java", - "links": { - "self": "devfile-catalog/java-wildfly-bootable-jar:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "microprofile-config", - "microprofile-fault-tolerance", - "microprofile-health", - "microprofile-jwt", - "microprofile-metrics", - "microprofile-openapi", - "microprofile-opentracing", - "microprofile-rest-client" - ] - }, - { - "name": "nodejs", - "version": "1.0.0", - "displayName": "NodeJS Runtime", - "description": "Stack with NodeJS 12", - "type": "stack", - "tags": [ - "NodeJS", - "Express", - "ubi8" - ], - "projectType": "nodejs", - "language": "nodejs", - "links": { - "self": "devfile-catalog/nodejs:latest" - }, - "resources": [ - "archive.tar", - "devfile.yaml" - ], - "starterProjects": [ - "nodejs-starter" - ] - }, - { - "name": "python", - "version": "1.0.0", - "displayName": "Python", - "description": "Python Stack with Python 3.7", - "type": "stack", - "tags": [ - "Python", - "pip" - ], - "projectType": "python", - "language": "python", - "links": { - "self": "devfile-catalog/python:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "python-example" - ] - }, - { - "name": "python-django", - "version": "1.0.0", - "displayName": "Django", - "description": "Python3.7 with Django", - "type": "stack", - "tags": [ - "Python", - "pip", - "Django" - ], - "projectType": "django", - "language": "python", - "links": { - "self": "devfile-catalog/python-django:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "django-example" - ] - } - ] \ No newline at end of file + { + "version": "1.2.0", + "schemaVersion": "2.1.0", + "description": "Stack with the latest Go version with devfile v2.1.0 schema verison", + "tags": [ + "testtag" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "links": { + "self": "devfile-catalog/go:1.2.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ] + } + ] + }, + { + "name": "java-maven", + "displayName": "Maven Java", + "description": "Upstream Maven and OpenJDK 11", + "type": "stack", + "tags": [ + "Java", + "Maven" + ], + "projectType": "maven", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream Maven and OpenJDK 11", + "tags": [ + "Java", + "Maven" + ], + "links": { + "self": "devfile-catalog/java-maven:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + } + ] + }, + { + "name": "java-openliberty", + "displayName": "Open Liberty", + "description": "Java application stack using Open Liberty runtime", + "type": "stack", + "projectType": "docker", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "0.5.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Java application stack using Open Liberty runtime", + "links": { + "self": "devfile-catalog/java-openliberty:0.5.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "user-app" + ] + } + ] + }, + { + "name": "java-quarkus", + "displayName": "Quarkus Java", + "description": "Upstream Quarkus with Java+GraalVM", + "type": "stack", + "tags": [ + "Java", + "Quarkus" + ], + "projectType": "quarkus", + "language": "java", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream Quarkus with Java+GraalVM", + "tags": [ + "Java", + "Quarkus" + ], + "links": { + "self": "devfile-catalog/java-quarkus:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "community", + "redhat-product" + ] + } + ] + }, + { + "name": "java-springboot", + "displayName": "Spring Boot®", + "description": "Spring Boot® using Java", + "type": "stack", + "tags": [ + "Java", + "Spring" + ], + "icon": "https://www.eclipse.org/che/images/logo-eclipseche.svg", + "projectType": "spring", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Spring Boot® using Java", + "tags": [ + "Java", + "Spring" + ], + "icon": "https://www.eclipse.org/che/images/logo-eclipseche.svg", + "links": { + "self": "devfile-catalog/java-springboot:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + } + ] + }, + { + "name": "java-vertx", + "displayName": "Vert.x Java", + "description": "Upstream Vert.x using Java", + "type": "stack", + "tags": [ + "Java", + "Vert.x" + ], + "projectType": "vertx", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream Vert.x using Java", + "tags": [ + "Java", + "Vert.x" + ], + "links": { + "self": "devfile-catalog/java-vertx:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "vertx-http-example", + "vertx-istio-circuit-breaker-booster", + "vertx-istio-routing-booster", + "vertx-secured-http-example-redhat", + "vertx-crud-example-redhat", + "vertx-istio-security-booster", + "vertx-crud-example", + "vertx-circuit-breaker-example", + "vertx-configmap-example", + "vertx-circuit-breaker-example-redhat", + "vertx-cache-example-redhat", + "vertx-cache-example", + "vertx-secured-http-example", + "vertx-health-checks-example-redhat", + "vertx-http-example-redhat", + "vertx-health-checks-example", + "vertx-configmap-example-redhat", + "vertx-messaging-work-queue-booster", + "vertx-istio-distributed-tracing-booster" + ] + } + ] + }, + { + "name": "java-wildfly", + "displayName": "WildFly Java", + "description": "Upstream WildFly", + "type": "stack", + "tags": [ + "Java", + "WildFly" + ], + "projectType": "wildfly", + "language": "java", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Upstream WildFly", + "tags": [ + "Java", + "WildFly" + ], + "links": { + "self": "devfile-catalog/java-wildfly:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "microprofile-config", + "microprofile-fault-tolerance", + "microprofile-health", + "microprofile-jwt", + "microprofile-metrics", + "microprofile-openapi", + "microprofile-opentracing", + "microprofile-rest-client" + ] + } + ] + }, + { + "name": "java-wildfly-bootable-jar", + "displayName": "WildFly Bootable Jar", + "description": "Java stack with WildFly in bootable Jar mode, OpenJDK 11 and Maven 3.5", + "type": "stack", + "tags": [ + "RHEL8", + "Java", + "OpenJDK", + "Maven", + "WildFly", + "Microprofile", + "WildFly Bootable" + ], + "projectType": "WildFly", + "language": "java", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Java stack with WildFly in bootable Jar mode, OpenJDK 11 and Maven 3.5", + "tags": [ + "RHEL8", + "Java", + "OpenJDK", + "Maven", + "WildFly", + "Microprofile", + "WildFly Bootable" + ], + "links": { + "self": "devfile-catalog/java-wildfly-bootable-jar:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "microprofile-config", + "microprofile-fault-tolerance", + "microprofile-health", + "microprofile-jwt", + "microprofile-metrics", + "microprofile-openapi", + "microprofile-opentracing", + "microprofile-rest-client" + ] + } + ] + }, + { + "name": "nodejs", + "displayName": "NodeJS Runtime", + "description": "Stack with NodeJS 12", + "type": "stack", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "projectType": "nodejs", + "language": "nodejs", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Stack with NodeJS 12", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "links": { + "self": "devfile-catalog/nodejs:1.0.0" + }, + "resources": [ + "archive.tar", + "devfile.yaml" + ], + "starterProjects": [ + "nodejs-starter" + ] + } + ] + }, + { + "name": "python", + "displayName": "Python", + "description": "Python Stack with Python 3.7", + "type": "stack", + "tags": [ + "Python", + "pip" + ], + "projectType": "python", + "language": "python", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Python Stack with Python 3.7", + "tags": [ + "Python", + "pip" + ], + "links": { + "self": "devfile-catalog/python:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "python-example" + ] + } + ] + }, + { + "name": "python-django", + "displayName": "Django", + "description": "Python3.7 with Django", + "type": "stack", + "tags": [ + "Python", + "pip", + "Django" + ], + "projectType": "django", + "language": "python", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.2.0", + "default": true, + "description": "Python3.7 with Django", + "tags": [ + "Python", + "pip", + "Django" + ], + "links": { + "self": "devfile-catalog/python-django:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "django-example" + ] + } + ] + } +] \ No newline at end of file diff --git a/index/generator/tests/registry/samples/code-with-quarkus/devfile.yaml b/index/generator/tests/registry/samples/code-with-quarkus/1.1.0/devfile.yaml similarity index 100% rename from index/generator/tests/registry/samples/code-with-quarkus/devfile.yaml rename to index/generator/tests/registry/samples/code-with-quarkus/1.1.0/devfile.yaml diff --git a/index/generator/tests/registry/samples/nodejs-basic/devfile.yaml b/index/generator/tests/registry/samples/nodejs-basic/1.0.0/devfile.yaml similarity index 100% rename from index/generator/tests/registry/samples/nodejs-basic/devfile.yaml rename to index/generator/tests/registry/samples/nodejs-basic/1.0.0/devfile.yaml diff --git a/index/generator/tests/registry/samples/nodejs-basic/1.0.1/devfile.yaml b/index/generator/tests/registry/samples/nodejs-basic/1.0.1/devfile.yaml new file mode 100644 index 000000000..77164e36f --- /dev/null +++ b/index/generator/tests/registry/samples/nodejs-basic/1.0.1/devfile.yaml @@ -0,0 +1,43 @@ +schemaVersion: 2.2.0 +metadata: + name: nodejs + version: 1.0.1 + displayName: Node.js Runtime + description: Stack with Node.js 14 + tags: ["NodeJS", "Express", "ubi8"] + projectType: "nodejs" + language: "nodejs" + attributes: + alpha.dockerimage-port: 3001 + provider: Red Hat + supportUrl: /~https://github.com/devfile-samples/devfile-support#support-information +parent: + id: nodejs + registryUrl: "https://registry.devfile.io" +components: + - name: outerloop-build + image: + imageName: nodejs-image:latest + dockerfile: + uri: Dockerfile + buildContext: . + rootRequired: false + - name: outerloop-deploy + kubernetes: + uri: outerloop-deploy.yaml +commands: + - id: build-image + apply: + component: outerloop-build + - id: deployk8s + apply: + component: outerloop-deploy + - id: deploy + composite: + commands: + - build-image + - deployk8s + group: + kind: deploy + isDefault: true + diff --git a/index/generator/tests/registry/stacks/go/1.1.0/devfile.yaml b/index/generator/tests/registry/stacks/go/1.1.0/devfile.yaml new file mode 100644 index 000000000..001d47077 --- /dev/null +++ b/index/generator/tests/registry/stacks/go/1.1.0/devfile.yaml @@ -0,0 +1,47 @@ +schemaVersion: 2.0.0 +metadata: + description: Stack with the latest Go version with devfile v2.0.0 schema verison + displayName: Go Runtime + icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg + language: go + name: go + provider: Red Hat + projectType: go + tags: + - Go + version: 1.1.0 +starterProjects: + - name: go-starter + git: + checkoutFrom: + revision: main + remotes: + origin: /~https://github.com/devfile-samples/devfile-stack-go.git +components: + - container: + endpoints: + - name: http + targetPort: 8080 + image: golang:latest + memoryLimit: 1024Mi + mountSources: true + sourceMapping: /project + name: runtime +commands: + - exec: + commandLine: GOCACHE=/project/.cache go build main.go + component: runtime + group: + isDefault: true + kind: build + workingDir: /project + id: build + - exec: + commandLine: ./main + component: runtime + group: + isDefault: true + kind: run + workingDir: /project + id: run + diff --git a/index/generator/tests/registry/stacks/go/1.2.0/devfile.yaml b/index/generator/tests/registry/stacks/go/1.2.0/devfile.yaml new file mode 100644 index 000000000..a879fa8fd --- /dev/null +++ b/index/generator/tests/registry/stacks/go/1.2.0/devfile.yaml @@ -0,0 +1,47 @@ +schemaVersion: 2.1.0 +metadata: + description: Stack with the latest Go version with devfile v2.1.0 schema verison + displayName: Go Runtime + icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg + language: go + name: go + provider: Red Hat + projectType: go + tags: + - testtag + version: 1.2.0 +starterProjects: + - name: go-starter + git: + checkoutFrom: + revision: main + remotes: + origin: /~https://github.com/devfile-samples/devfile-stack-go.git +components: + - container: + endpoints: + - name: http + targetPort: 8080 + image: golang:latest + memoryLimit: 1024Mi + mountSources: true + sourceMapping: /project + name: runtime +commands: + - exec: + commandLine: GOCACHE=/project/.cache go build main.go + component: runtime + group: + isDefault: true + kind: build + workingDir: /project + id: build + - exec: + commandLine: ./main + component: runtime + group: + isDefault: true + kind: run + workingDir: /project + id: run + diff --git a/index/generator/tests/registry/stacks/go/stack.yaml b/index/generator/tests/registry/stacks/go/stack.yaml new file mode 100644 index 000000000..4ac2bf82a --- /dev/null +++ b/index/generator/tests/registry/stacks/go/stack.yaml @@ -0,0 +1,8 @@ +name: go +description: Stack with the latest Go version +displayName: Go Runtime +icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg +versions: + - version: 1.1.0 + default: true #should have one and only one default version + - version: 1.2.0 From d70e41e91aee235b968d34bf1297ec7576caf5a9 Mon Sep 17 00:00:00 2001 From: Stephanie Date: Thu, 17 Feb 2022 10:58:01 -0500 Subject: [PATCH 4/9] update build scripts Signed-off-by: Stephanie --- build-tools/build.sh | 44 ++++++++++++++++++++++++------------ build-tools/cache_samples.sh | 43 +++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/build-tools/build.sh b/build-tools/build.sh index dcc71eb7c..43c164098 100755 --- a/build-tools/build.sh +++ b/build-tools/build.sh @@ -13,6 +13,7 @@ shopt -s extglob buildToolsFolder="$(dirname "$0")" +buildToolsDir="$PWD" generatorFolder=$buildToolsFolder/../index/generator display_usage() { @@ -25,6 +26,22 @@ cleanup_and_exit() { exit $1 } +tar_files_and_cleanup() { + # Find the files to add to the tar archive + tarFiles=$(find . \( -not -name 'devfile.yaml' \ + -a -not -name "meta.yaml" \ + -a -not -name "*.vsx" \ + -a -not -name "." \ + -a -not -name "logo.svg" \ + -a -not -name "logo.png" \) -maxdepth 1) + + # There are files that need to be pulled into a tar archive + if [[ ! -z $tarFiles ]]; then + tar -czvf archive.tar $tarFiles > /dev/null + rm -rf $tarFiles + fi +} + # build_registry # Runs the steps to build the registry. Mainly: # 1. Copying over registry repository to build folder @@ -44,7 +61,7 @@ build_registry() { echo "Failed to build index-generator tool" return 1 fi - echo "Successfully built the index-generator tool\n" + echo "Successfully built the index-generator tool" cd "$OLDPWD" @@ -52,21 +69,18 @@ build_registry() { for stackDir in $outputFolder/stacks/*/ do cd $stackDir - # Find the files to add to the tar archive - tarFiles=$(find . \( -not -name 'devfile.yaml' \ - -a -not -name "meta.yaml" \ - -a -not -name "*.vsx" \ - -a -not -name "." \ - -a -not -name "logo.svg" \ - -a -not -name "logo.png" \) -maxdepth 1) - - # There are files that need to be pulled into a tar archive - if [[ ! -z $tarFiles ]]; then - tar -czvf archive.tar $tarFiles > /dev/null - rm -rf $tarFiles + if [[ -f "stack.yaml" ]]; then + for versionDir in $stackDir/*/ + do + cd $versionDir + tar_files_and_cleanup + done + else + tar_files_and_cleanup fi cd "$OLDPWD" done + cd "$buildToolsDir" # Cache any devfile samples if needed if [ -f $registryRepository/extraDevfileEntries.yaml ]; then @@ -85,7 +99,7 @@ build_registry() { echo "Failed to build the devfile registry index" return 1 fi - echo "Successfully built the devfile registry index\n" + echo "Successfully built the devfile registry index" } # check_params validates that the arguments passed into the script are valid @@ -127,5 +141,5 @@ check_params build_registry if [ $? -ne 0 ]; then echo "Error building the devfile registry" - cleanup_and_exit 1 + #cleanup_and_exit 1 fi \ No newline at end of file diff --git a/build-tools/cache_samples.sh b/build-tools/cache_samples.sh index 8a1878777..47c132c2f 100755 --- a/build-tools/cache_samples.sh +++ b/build-tools/cache_samples.sh @@ -14,10 +14,21 @@ function cache_sample() { local sampleName="$1" local outputDir="$2" tempDir=$(mktemp -d) + sampleDir=$tempDir/$sampleName # Git clone the sample project - local gitRepository="$(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.git.remotes.origin)' -)" - git clone "$gitRepository" "$tempDir/$sampleName" + gitRepository="$(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.git.remotes.origin)' -)" + if [[ $gitRepository == "null" ]]; then + for version in $(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.versions[].version)'); do + gitRepository="$(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.versions[] | select(.version == "'${version}'")' | yq e '.git.remotes.origin' )" + git clone "$gitRepository" "$sampleDir/$version" + mkdir $outputDir/$version + cache_devfile $sampleDir/$version $outputDir/$version $sampleName + done + else + git clone "$gitRepository" "$sampleDir" + cache_devfile $sampleDir $outputDir/ $sampleName + fi # Cache the icon for the sample local iconPath="$(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.icon)' -)" @@ -30,26 +41,30 @@ function cache_sample() { echo "The specified icon does not exist for sample $sampleName" exit 1 fi - cp $tempDir/$sampleName/$iconPath $outputDir/ + cp $sampleDir/$iconPath $outputDir/ fi fi + # Archive the sample project + (cd $tempDir && zip -r sampleName.zip $sampleName/) + cp $tempDir/sampleName.zip $outputDir/ + +} + +function cache_devfile() { + local srcDir="$1" + local outputDir="$2" + local sampleName="$3" # Cache the devfile for the sample - if [[ -f "$tempDir/$sampleName/devfile.yaml" ]]; then - cp $tempDir/$sampleName/devfile.yaml $outputDir/ - elif [[ -f "$tempDir/$sampleName/.devfile/devfile.yaml" ]]; then - cp $tempDir/$sampleName/.devfile/devfile.yaml $outputDir/ + if [[ -f "$srcDir/devfile.yaml" ]]; then + cp $srcDir/devfile.yaml $outputDir/ + elif [[ -f "$srcDir/.devfile/devfile.yaml" ]]; then + cp $srcDir/.devfile/devfile.yaml $outputDir/ else - echo "A devfile for sample $sampleName could not be found." + echo "A devfile for sample $sampleName, version $(basename $srcDir) could not be found." echo "Please ensure a devfile exists in the root of the repository or under .devfile/" exit 1 fi - - - # Archive the sample project - (cd $tempDir && zip -r sampleName.zip $sampleName/) - cp $tempDir/sampleName.zip $outputDir/ - } devfileEntriesFile=$1 From f6982808ccc72fbed0f8cca2bf74006793151c0b Mon Sep 17 00:00:00 2001 From: Stephanie Date: Thu, 17 Feb 2022 16:15:45 -0500 Subject: [PATCH 5/9] server works Signed-off-by: Stephanie --- index/server/go.mod | 4 +- index/server/go.sum | 6 + index/server/pkg/server/endpoint.go | 86 +- index/server/pkg/server/index.go | 12 +- index/server/pkg/server/registry.go | 23 +- index/server/pkg/util/index.json | 307 +++++ index/server/pkg/util/util.go | 30 + index/server/pkg/util/util_test.go | 29 + .../vendor/github.com/devfile/api/v2/LICENSE | 478 +++---- .../pkg/apis/workspaces/v1alpha2/commands.go | 23 +- .../v1alpha2/component_container.go | 16 +- .../workspaces/v1alpha2/component_image.go | 38 + .../v1alpha2/component_image_dockerfile.go | 83 ++ .../workspaces/v1alpha2/component_volume.go | 4 +- .../apis/workspaces/v1alpha2/components.go | 7 +- .../pkg/apis/workspaces/v1alpha2/endpoint.go | 8 +- .../pkg/apis/workspaces/v1alpha2/projects.go | 2 +- .../v1alpha2/zz_generated.deepcopy.go | 1182 +++++++++++++++-- .../v1alpha2/zz_generated.getters.go | 43 + .../v1alpha2/zz_generated.parent_overrides.go | 304 ++++- .../v1alpha2/zz_generated.plugin_overrides.go | 167 ++- .../zz_generated.union_definitions.go | 172 +++ .../devfile/api/v2/pkg/validation/commands.go | 18 +- .../api/v2/pkg/validation/components.go | 9 + .../devfile/api/v2/pkg/validation/errors.go | 28 +- .../devfile/api/v2/pkg/validation/projects.go | 42 +- .../api/v2/pkg/validation/validation-rule.md | 12 +- .../validation/variables/variables_command.go | 68 +- .../variables/variables_component.go | 233 +++- .../validation/variables/variables_project.go | 92 +- .../pkg/devfile/parser/context/apiVersion.go | 5 +- .../data/v2/2.2.0/devfileJsonSchema220.go | 263 +++- .../pkg/devfile/parser/data/v2/commands.go | 10 +- .../parser/data/v2/common/component_helper.go | 2 + .../pkg/devfile/parser/data/v2/components.go | 10 +- .../pkg/devfile/parser/data/versions.go | 2 +- .../library/pkg/devfile/parser/devfileobj.go | 1 - .../library/pkg/devfile/parser/parse.go | 110 +- .../registry-support/index/generator/LICENSE | 478 +++---- .../index/generator/library/library.go | 447 +++++-- .../index/generator/schema/schema.go | 30 +- index/server/vendor/modules.txt | 7 +- 42 files changed, 3839 insertions(+), 1052 deletions(-) create mode 100644 index/server/pkg/util/index.json create mode 100644 index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image.go create mode 100644 index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image_dockerfile.go create mode 100644 index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.getters.go diff --git a/index/server/go.mod b/index/server/go.mod index 7701b98cc..47dcd501a 100644 --- a/index/server/go.mod +++ b/index/server/go.mod @@ -5,7 +5,7 @@ go 1.14 require ( github.com/containerd/containerd v1.4.1 github.com/deislabs/oras v0.8.1 - github.com/devfile/api/v2 v2.0.0-20210910153124-da620cd1a7a1 + github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0 github.com/gin-gonic/gin v1.6.3 github.com/gorilla/mux v1.7.3 // indirect @@ -18,3 +18,5 @@ require ( gopkg.in/segmentio/analytics-go.v3 v3.1.0 k8s.io/apimachinery v0.21.3 ) + +replace github.com/devfile/registry-support/index/generator => github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee diff --git a/index/server/go.sum b/index/server/go.sum index ffe262c08..d8fc4e581 100644 --- a/index/server/go.sum +++ b/index/server/go.sum @@ -130,8 +130,12 @@ github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/devfile/api/v2 v2.0.0-20210910153124-da620cd1a7a1 h1:k25KKenebyxOUnGmGTZE0F/wHDQ+fh+HoxVfjsKXNv0= github.com/devfile/api/v2 v2.0.0-20210910153124-da620cd1a7a1/go.mod h1:kLX/nW93gigOHXK3NLeJL2fSS/sgEe+OHu8bo3aoOi4= +github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed h1:OXF9l+MlJrirXAqKN6EZUVaHB0FKm7nh0EjpktwnBig= +github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q= github.com/devfile/library v1.1.1-0.20210910214722-7c5ff63711ec h1:UtJiFJfnC7fhup2MbGOzt6DCKMFKJTw47aHHETLfcZA= github.com/devfile/library v1.1.1-0.20210910214722-7c5ff63711ec/go.mod h1:svPWwWb+BP15SXCHl0dyOeE4Sohrjl5a2BaOzc/riLc= +github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f h1:kKsBWkFiD7tSIpzwfmz7TH89U1U3yRxSJ9UPOo2OH1s= +github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f/go.mod h1:uFZZdTuRqA68FVe/JoJHP92CgINyQkyWnM2Qyiim+50= github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0 h1:F2OkuW0ASrSz5d06tJxWfweUNYTnsOCyiGTEORisokE= github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0/go.mod h1:bLGagbW2SFn7jo5+kUPlCMehIGqWkRtLKc5O0OyJMJM= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -570,6 +574,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g= github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= +github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee h1:+v/r+jE4pCYAMYF56cZO7NyFmbCEVBNXWw6UcZpfdjU= +github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee/go.mod h1:iRPBxs+ZjfLEduVXpCCIOzdD2588Zv9OCs/CcXMcCCY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= diff --git a/index/server/pkg/server/endpoint.go b/index/server/pkg/server/endpoint.go index 0cd259199..350bfa546 100644 --- a/index/server/pkg/server/endpoint.go +++ b/index/server/pkg/server/endpoint.go @@ -87,23 +87,38 @@ func serveDevfile(c *gin.Context) { } for _, devfileIndex := range index { if devfileIndex.Name == name { + var sampleDevfilePath string var bytes []byte - if devfileIndex.Type == indexSchema.StackDevfileType { - bytes, err = pullStackFromRegistry(devfileIndex) + if devfileIndex.Type == indexSchema.SampleDevfileType { + if devfileIndex.Versions == nil || len(devfileIndex.Versions) == 0 { + sampleDevfilePath = path.Join(samplesPath, devfileIndex.Name, devfileName) + } } else { - // Retrieve the sample devfile stored under /registry/samples/ - sampleDevfilePath := path.Join(samplesPath, devfileIndex.Name, devfileName) + for _, version := range devfileIndex.Versions { + if !version.Default { + continue + } + if devfileIndex.Type == indexSchema.StackDevfileType { + bytes, err = pullStackFromRegistry(version) + } else { + // Retrieve the sample devfile stored under /registry/samples/ + sampleDevfilePath = path.Join(samplesPath, devfileIndex.Name, version.Version, devfileName) + } + break + } + } + if sampleDevfilePath != "" { if _, err = os.Stat(sampleDevfilePath); err == nil { bytes, err = ioutil.ReadFile(sampleDevfilePath) } - } - if err != nil { - log.Print(err.Error()) - c.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), - "status": fmt.Sprintf("failed to pull the devfile of %s", name), - }) - return + if err != nil { + log.Print(err.Error()) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + "status": fmt.Sprintf("failed to pull the devfile of %s", name), + }) + return + } } // Track event for telemetry. Ignore events from the registry-viewer and DevConsole since those are tracked on the client side @@ -166,7 +181,7 @@ func buildIndexAPIResponse(c *gin.Context) { var bytes []byte var responseIndexPath, responseBase64IndexPath string - isFiltered := false + // isFiltered := false // Sets Access-Control-Allow-Origin response header to allow cross origin requests c.Header("Access-Control-Allow-Origin", "*") @@ -210,34 +225,33 @@ func buildIndexAPIResponse(c *gin.Context) { return } } - + index, err := util.ReadIndexPath(responseIndexPath) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "status": fmt.Sprintf("failed to read the devfile index: %v", err), + }) + return + } + index = util.ConvertToOldIndexFormat(index) // Filter the index if archs has been requested if len(archs) > 0 { - isFiltered = true - index, err := util.ReadIndexPath(responseIndexPath) - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "status": fmt.Sprintf("failed to read the devfile index: %v", err), - }) - return - } + // isFiltered = true index = util.FilterDevfileArchitectures(index, archs) - - bytes, err = json.MarshalIndent(&index, "", " ") - if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "status": fmt.Sprintf("failed to serialize index data: %v", err), - }) - return - } } - - // serve either the filtered index or the unfiltered index - if isFiltered { - c.Data(http.StatusOK, http.DetectContentType(bytes), bytes) - } else { - c.File(responseIndexPath) + bytes, err = json.MarshalIndent(&index, "", " ") + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "status": fmt.Sprintf("failed to serialize index data: %v", err), + }) + return } + c.Data(http.StatusOK, http.DetectContentType(bytes), bytes) + // serve either the filtered index or the unfiltered index + //if isFiltered { + // c.Data(http.StatusOK, http.DetectContentType(bytes), bytes) + //} else { + // c.File(responseIndexPath) + //} // Track event for telemetry. Ignore events from the registry-viewer and DevConsole since those are tracked on the client side if enableTelemetry && !util.IsWebClient(c) { diff --git a/index/server/pkg/server/index.go b/index/server/pkg/server/index.go index d78c2ce3c..0c9d6e51c 100644 --- a/index/server/pkg/server/index.go +++ b/index/server/pkg/server/index.go @@ -97,10 +97,14 @@ func ServeRegistry() { stackIndex = append(stackIndex, devfileIndex) } - if len(devfileIndex.Resources) != 0 { - err := pushStackToRegistry(devfileIndex) - if err != nil { - log.Fatal(err.Error()) + if devfileIndex.Versions != nil && len(devfileIndex.Versions) != 0{ + for _, versionComponent := range devfileIndex.Versions { + if len(versionComponent.Resources) != 0 { + err := pushStackToRegistry(versionComponent, devfileIndex.Name) + if err != nil { + log.Fatal(err.Error()) + } + } } } } diff --git a/index/server/pkg/server/registry.go b/index/server/pkg/server/registry.go index fd256b27d..ffbfe7dbb 100644 --- a/index/server/pkg/server/registry.go +++ b/index/server/pkg/server/registry.go @@ -6,6 +6,7 @@ import ( "fmt" "io/ioutil" "log" + "os" "path" "path/filepath" @@ -18,11 +19,11 @@ import ( ) // pushStackToRegistry pushes the given devfile stack to the OCI registry -func pushStackToRegistry(devfileIndex indexSchema.Schema) error { +func pushStackToRegistry(versionComponent indexSchema.Version, stackName string) error { // Load the devfile into memory and set up the pushing resource (file name, file content, media type, ref) memoryStore := content.NewMemoryStore() pushContents := []ocispec.Descriptor{} - for _, resource := range devfileIndex.Resources { + for _, resource := range versionComponent.Resources { if resource == "meta.yaml" { // Some registries may still have the meta.yaml in it, but we don't need it, so skip pushing it up continue @@ -47,8 +48,12 @@ func pushStackToRegistry(devfileIndex indexSchema.Schema) error { } } + resourcePath := filepath.Join(stacksPath, stackName, versionComponent.Version, resource) // Load the resource into memory and add to the push contents - resourceContent, err := ioutil.ReadFile(filepath.Join(stacksPath, devfileIndex.Name, resource)) + if _, err := os.Stat(resourcePath); os.IsNotExist(err) { + resourcePath = filepath.Join(stacksPath, stackName, resource) + } + resourceContent, err := ioutil.ReadFile(resourcePath) if err != nil { return err } @@ -58,23 +63,23 @@ func pushStackToRegistry(devfileIndex indexSchema.Schema) error { } - ref := path.Join(registryService, "/", devfileIndex.Links["self"]) + ref := path.Join(registryService, "/", versionComponent.Links["self"]) ctx := context.Background() resolver := docker.NewResolver(docker.ResolverOptions{PlainHTTP: true}) - log.Printf("Pushing %s to %s...\n", devfileIndex.Name, ref) + log.Printf("Pushing %s version %s to %s...\n", stackName, versionComponent.Version, ref) desc, err := oras.Push(ctx, resolver, ref, memoryStore, pushContents, oras.WithConfigMediaType(devfileConfigMediaType)) if err != nil { - return fmt.Errorf("failed to push %s to %s: %v", devfileIndex.Name, ref, err) + return fmt.Errorf("failed to push %s version %s to %s: %v", stackName, versionComponent.Version, ref, err) } log.Printf("Pushed to %s with digest %s\n", ref, desc.Digest) return nil } // pullStackFromRegistry pulls the given devfile stack from the OCI registry -func pullStackFromRegistry(devfileIndex indexSchema.Schema) ([]byte, error) { +func pullStackFromRegistry(versionComponent indexSchema.Version) ([]byte, error) { // Pull the devfile from registry and save to disk - ref := path.Join(registryService, "/", devfileIndex.Links["self"]) + ref := path.Join(registryService, "/", versionComponent.Links["self"]) ctx := context.Background() resolver := docker.NewResolver(docker.ResolverOptions{PlainHTTP: true}) @@ -84,7 +89,7 @@ func pullStackFromRegistry(devfileIndex indexSchema.Schema) ([]byte, error) { allowedMediaTypes := []string{devfileMediaType} var devfile string - for _, resource := range devfileIndex.Resources { + for _, resource := range versionComponent.Resources { if resource == devfileName { devfile = devfileName break diff --git a/index/server/pkg/util/index.json b/index/server/pkg/util/index.json new file mode 100644 index 000000000..93429ce8c --- /dev/null +++ b/index/server/pkg/util/index.json @@ -0,0 +1,307 @@ +[ + { + "name": "go", + "version": "1.1.0", + "displayName": "Go Runtime", + "description": "Stack with the latest Go version", + "type": "stack", + "tags": [ + "Go" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "projectType": "go", + "language": "go", + "links": { + "self": "devfile-catalog/go:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ], + "provider": "Red Hat" + }, + { + "name": "java-maven", + "version": "1.1.0", + "displayName": "Maven Java", + "description": "Upstream Maven and OpenJDK 11", + "type": "stack", + "tags": [ + "Java", + "Maven" + ], + "projectType": "maven", + "language": "java", + "links": { + "self": "devfile-catalog/java-maven:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ], + "provider": "Red Hat" + }, + { + "name": "java-openliberty", + "version": "0.5.0", + "displayName": "Open Liberty", + "description": "Java application stack using Open Liberty runtime", + "type": "stack", + "projectType": "docker", + "language": "java", + "links": { + "self": "devfile-catalog/java-openliberty:0.5.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "user-app" + ], + "provider": "Red Hat" + }, + { + "name": "java-quarkus", + "version": "1.1.0", + "displayName": "Quarkus Java", + "description": "Upstream Quarkus with Java+GraalVM", + "type": "stack", + "tags": [ + "Java", + "Quarkus" + ], + "projectType": "quarkus", + "language": "java", + "links": { + "self": "devfile-catalog/java-quarkus:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "community", + "redhat-product" + ], + "provider": "Red Hat" + }, + { + "name": "java-springboot", + "version": "1.1.0", + "displayName": "Spring Boot®", + "description": "Spring Boot® using Java", + "type": "stack", + "tags": [ + "Java", + "Spring" + ], + "icon": "https://www.eclipse.org/che/images/logo-eclipseche.svg", + "projectType": "spring", + "language": "java", + "links": { + "self": "devfile-catalog/java-springboot:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + }, + { + "name": "java-vertx", + "version": "1.1.0", + "displayName": "Vert.x Java", + "description": "Upstream Vert.x using Java", + "type": "stack", + "tags": [ + "Java", + "Vert.x" + ], + "projectType": "vertx", + "language": "java", + "links": { + "self": "devfile-catalog/java-vertx:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "vertx-http-example", + "vertx-istio-circuit-breaker-booster", + "vertx-istio-routing-booster", + "vertx-secured-http-example-redhat", + "vertx-crud-example-redhat", + "vertx-istio-security-booster", + "vertx-crud-example", + "vertx-circuit-breaker-example", + "vertx-configmap-example", + "vertx-circuit-breaker-example-redhat", + "vertx-cache-example-redhat", + "vertx-cache-example", + "vertx-secured-http-example", + "vertx-health-checks-example-redhat", + "vertx-http-example-redhat", + "vertx-health-checks-example", + "vertx-configmap-example-redhat", + "vertx-messaging-work-queue-booster", + "vertx-istio-distributed-tracing-booster" + ] + }, + { + "name": "java-wildfly", + "version": "1.0.0", + "displayName": "WildFly Java", + "description": "Upstream WildFly", + "type": "stack", + "tags": [ + "Java", + "WildFly" + ], + "projectType": "wildfly", + "language": "java", + "links": { + "self": "devfile-catalog/java-wildfly:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "microprofile-config", + "microprofile-fault-tolerance", + "microprofile-health", + "microprofile-jwt", + "microprofile-metrics", + "microprofile-openapi", + "microprofile-opentracing", + "microprofile-rest-client" + ] + }, + { + "name": "java-wildfly-bootable-jar", + "version": "1.0.0", + "displayName": "WildFly Bootable Jar", + "description": "Java stack with WildFly in bootable Jar mode, OpenJDK 11 and Maven 3.5", + "type": "stack", + "tags": [ + "RHEL8", + "Java", + "OpenJDK", + "Maven", + "WildFly", + "Microprofile", + "WildFly Bootable" + ], + "projectType": "WildFly", + "language": "java", + "links": { + "self": "devfile-catalog/java-wildfly-bootable-jar:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "microprofile-config", + "microprofile-fault-tolerance", + "microprofile-health", + "microprofile-jwt", + "microprofile-metrics", + "microprofile-openapi", + "microprofile-opentracing", + "microprofile-rest-client" + ] + }, + { + "name": "nodejs", + "version": "1.0.0", + "displayName": "NodeJS Runtime", + "description": "Stack with NodeJS 12", + "type": "stack", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "projectType": "nodejs", + "language": "nodejs", + "links": { + "self": "devfile-catalog/nodejs:1.0.0" + }, + "resources": [ + "archive.tar", + "devfile.yaml" + ], + "starterProjects": [ + "nodejs-starter" + ] + }, + { + "name": "python", + "version": "1.0.0", + "displayName": "Python", + "description": "Python Stack with Python 3.7", + "type": "stack", + "tags": [ + "Python", + "pip" + ], + "projectType": "python", + "language": "python", + "links": { + "self": "devfile-catalog/python:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "python-example" + ] + }, + { + "name": "python-django", + "version": "1.0.0", + "displayName": "Django", + "description": "Python3.7 with Django", + "type": "stack", + "tags": [ + "Python", + "pip", + "Django" + ], + "projectType": "django", + "language": "python", + "links": { + "self": "devfile-catalog/python-django:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "django-example" + ] + }, + { + "name": "nodejs-basic", + "version": "1.0.1", + "displayName": "Basic NodeJS", + "description": "A simple Hello World application", + "type": "sample", + "icon": "nodejsIcon.svg", + "projectType": "nodejs", + "language": "nodejs" + }, + { + "name": "code-with-quarkus", + "version": "1.1.0", + "displayName": "Basic Quarkus", + "description": "A simple Hello World Java application using Quarkus", + "type": "sample", + "icon": "https://raw.githubusercontent.com/elsony/devfile-sample-code-with-quarkus/main/.devfile/icon/quarkus.png", + "projectType": "quarkus", + "language": "java", + "provider": "Red Hat" + } +] \ No newline at end of file diff --git a/index/server/pkg/util/util.go b/index/server/pkg/util/util.go index 4b1c7f91e..480438fce 100644 --- a/index/server/pkg/util/util.go +++ b/index/server/pkg/util/util.go @@ -141,3 +141,33 @@ func GetOptionalEnv(key string, defaultValue interface{}) interface{} { } return defaultValue } + +func ConvertToOldIndexFormat(schemaList []indexSchema.Schema) []indexSchema.Schema { + var oldSchemaList []indexSchema.Schema + for _, schema := range schemaList { + oldSchema := schema + oldSchema.Versions = nil + if (schema.Versions == nil || len(schema.Versions) == 0) && schema.Type == indexSchema.SampleDevfileType { + oldSchemaList = append(oldSchemaList, oldSchema) + continue + } + for _, versionComponent := range schema.Versions { + if !versionComponent.Default { + continue + } + oldSchema.Tags = versionComponent.Tags + oldSchema.Architectures = versionComponent.Architectures + if schema.Type == indexSchema.SampleDevfileType { + oldSchema.Git = versionComponent.Git + } else { + oldSchema.Links = versionComponent.Links + oldSchema.Resources = versionComponent.Resources + oldSchema.StarterProjects = versionComponent.StarterProjects + oldSchema.Version = versionComponent.Version + } + oldSchemaList = append(oldSchemaList, oldSchema) + break + } + } + return oldSchemaList +} diff --git a/index/server/pkg/util/util_test.go b/index/server/pkg/util/util_test.go index 40d74cc7a..54c239084 100644 --- a/index/server/pkg/util/util_test.go +++ b/index/server/pkg/util/util_test.go @@ -1,6 +1,10 @@ package util import ( + "encoding/json" + indexLibrary "github.com/devfile/registry-support/index/generator/library" + "github.com/devfile/registry-support/index/generator/schema" + "io/ioutil" "os" "testing" ) @@ -190,3 +194,28 @@ func TestGetOptionalEnv(t *testing.T) { }) } } + + +func TestConvertToOldIndexFormat(t *testing.T) { + inputIndexFilePath := "../../../generator/index.json" + // wantIndexFilePath := "../tests/registry/index_main.json" + bytes,err := ioutil.ReadFile(inputIndexFilePath) + // bytes, err := ioutil.ReadFile(wantIndexFilePath) + if err != nil { + t.Errorf("Failed to read index.json: %v", err) + } + var inputIndex []schema.Schema + err = json.Unmarshal(bytes, &inputIndex) + if err != nil { + t.Errorf("Failed to unmarshal inputIndex.json") + } + + t.Run("Test generate index", func(t *testing.T) { + gotIndex:= ConvertToOldIndexFormat(inputIndex) + + //if !reflect.DeepEqual(wantIndex, gotIndex) { + // t.Errorf("Want index %v, got index %v", wantIndex, gotIndex) + //} + indexLibrary.CreateIndexFile(gotIndex, "./index.json") + }) +} \ No newline at end of file diff --git a/index/server/vendor/github.com/devfile/api/v2/LICENSE b/index/server/vendor/github.com/devfile/api/v2/LICENSE index d3087e4c5..261eeb9e9 100644 --- a/index/server/vendor/github.com/devfile/api/v2/LICENSE +++ b/index/server/vendor/github.com/devfile/api/v2/LICENSE @@ -1,277 +1,201 @@ -Eclipse Public License - v 2.0 - - THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE - PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION - OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - - a) in the case of the initial Contributor, the initial content - Distributed under this Agreement, and - - b) in the case of each subsequent Contributor: - i) changes to the Program, and - ii) additions to the Program; - where such changes and/or additions to the Program originate from - and are Distributed by that particular Contributor. A Contribution - "originates" from a Contributor if it was added to the Program by - such Contributor itself or anyone acting on such Contributor's behalf. - Contributions do not include changes or additions to the Program that - are not Modified Works. - -"Contributor" means any person or entity that Distributes the Program. - -"Licensed Patents" mean patent claims licensable by a Contributor which -are necessarily infringed by the use or sale of its Contribution alone -or when combined with the Program. - -"Program" means the Contributions Distributed in accordance with this -Agreement. - -"Recipient" means anyone who receives the Program under this Agreement -or any Secondary License (as applicable), including Contributors. - -"Derivative Works" shall mean any work, whether in Source Code or other -form, that is based on (or derived from) the Program and for which the -editorial revisions, annotations, elaborations, or other modifications -represent, as a whole, an original work of authorship. - -"Modified Works" shall mean any work in Source Code or other form that -results from an addition to, deletion from, or modification of the -contents of the Program, including, for purposes of clarity any new file -in Source Code form that contains any contents of the Program. Modified -Works shall not include works that contain only declarations, -interfaces, types, classes, structures, or files of the Program solely -in each case in order to link to, bind by name, or subclass the Program -or Modified Works thereof. - -"Distribute" means the acts of a) distributing or b) making available -in any manner that enables the transfer of a copy. - -"Source Code" means the form of a Program preferred for making -modifications, including but not limited to software source code, -documentation source, and configuration files. - -"Secondary License" means either the GNU General Public License, -Version 2.0, or any later versions of that license, including any -exceptions or additional permissions as identified by the initial -Contributor. - -2. GRANT OF RIGHTS - - a) Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free copyright - license to reproduce, prepare Derivative Works of, publicly display, - publicly perform, Distribute and sublicense the Contribution of such - Contributor, if any, and such Derivative Works. - - b) Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free patent - license under Licensed Patents to make, use, sell, offer to sell, - import and otherwise transfer the Contribution of such Contributor, - if any, in Source Code or other form. This patent license shall - apply to the combination of the Contribution and the Program if, at - the time the Contribution is added by the Contributor, such addition - of the Contribution causes such combination to be covered by the - Licensed Patents. The patent license shall not apply to any other - combinations which include the Contribution. No hardware per se is - licensed hereunder. - - c) Recipient understands that although each Contributor grants the - licenses to its Contributions set forth herein, no assurances are - provided by any Contributor that the Program does not infringe the - patent or other intellectual property rights of any other entity. - Each Contributor disclaims any liability to Recipient for claims - brought by any other entity based on infringement of intellectual - property rights or otherwise. As a condition to exercising the - rights and licenses granted hereunder, each Recipient hereby - assumes sole responsibility to secure any other intellectual - property rights needed, if any. For example, if a third party - patent license is required to allow Recipient to Distribute the - Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - - d) Each Contributor represents that to its knowledge it has - sufficient copyright rights in its Contribution, if any, to grant - the copyright license set forth in this Agreement. - - e) Notwithstanding the terms of any Secondary License, no - Contributor makes additional grants to any Recipient (other than - those set forth in this Agreement) as a result of such Recipient's - receipt of the Program under the terms of a Secondary License - (if permitted under the terms of Section 3). - -3. REQUIREMENTS - -3.1 If a Contributor Distributes the Program in any form, then: - - a) the Program must also be made available as Source Code, in - accordance with section 3.2, and the Contributor must accompany - the Program with a statement that the Source Code for the Program - is available under this Agreement, and informs Recipients how to - obtain it in a reasonable manner on or through a medium customarily - used for software exchange; and - - b) the Contributor may Distribute the Program under a license - different than this Agreement, provided that such license: - i) effectively disclaims on behalf of all other Contributors all - warranties and conditions, express and implied, including - warranties or conditions of title and non-infringement, and - implied warranties or conditions of merchantability and fitness - for a particular purpose; - - ii) effectively excludes on behalf of all other Contributors all - liability for damages, including direct, indirect, special, - incidental and consequential damages, such as lost profits; - - iii) does not attempt to limit or alter the recipients' rights - in the Source Code under section 3.2; and - - iv) requires any subsequent distribution of the Program by any - party to be under a license that satisfies the requirements - of this section 3. - -3.2 When the Program is Distributed as Source Code: - - a) it must be made available under this Agreement, or if the - Program (i) is combined with other material in a separate file or - files made available under a Secondary License, and (ii) the initial - Contributor attached to the Source Code the notice described in - Exhibit A of this Agreement, then the Program may be made available - under the terms of such Secondary Licenses, and - - b) a copy of this Agreement must be included with each copy of - the Program. - -3.3 Contributors may not remove or alter any copyright, patent, -trademark, attribution notices, disclaimers of warranty, or limitations -of liability ("notices") contained within the Program from any copy of -the Program which they Distribute, provided that Contributors may add -their own appropriate notices. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain responsibilities -with respect to end users, business partners and the like. While this -license is intended to facilitate the commercial use of the Program, -the Contributor who includes the Program in a commercial product -offering should do so in a manner which does not create potential -liability for other Contributors. Therefore, if a Contributor includes -the Program in a commercial product offering, such Contributor -("Commercial Contributor") hereby agrees to defend and indemnify every -other Contributor ("Indemnified Contributor") against any losses, -damages and costs (collectively "Losses") arising from claims, lawsuits -and other legal actions brought by a third party against the Indemnified -Contributor to the extent caused by the acts or omissions of such -Commercial Contributor in connection with its distribution of the Program -in a commercial product offering. The obligations in this section do not -apply to any claims or Losses relating to any actual or alleged -intellectual property infringement. In order to qualify, an Indemnified -Contributor must: a) promptly notify the Commercial Contributor in -writing of such claim, and b) allow the Commercial Contributor to control, -and cooperate with the Commercial Contributor in, the defense and any -related settlement negotiations. The Indemnified Contributor may -participate in any such claim at its own expense. - -For example, a Contributor might include the Program in a commercial -product offering, Product X. That Contributor is then a Commercial -Contributor. If that Commercial Contributor then makes performance -claims, or offers warranties related to Product X, those performance -claims and warranties are such Commercial Contributor's responsibility -alone. Under this section, the Commercial Contributor would have to -defend claims against the other Contributors related to those performance -claims and warranties, and if a court requires any other Contributor to -pay any damages as a result, the Commercial Contributor must pay -those damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" -BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR -IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF -TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR -PURPOSE. Each Recipient is solely responsible for determining the -appropriateness of using and distributing the Program and assumes all -risks associated with its exercise of rights under this Agreement, -including but not limited to the risks and costs of program errors, -compliance with applicable laws, damage to or loss of data, programs -or equipment, and unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS -SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST -PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE -EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -7. GENERAL - -If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of -the remainder of the terms of this Agreement, and without further -action by the parties hereto, such provision shall be reformed to the -minimum extent necessary to make such provision valid and enforceable. - -If Recipient institutes patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the -Program itself (excluding combinations of the Program with other software -or hardware) infringes such Recipient's patent(s), then such Recipient's -rights granted under Section 2(b) shall terminate as of the date such -litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it -fails to comply with any of the material terms or conditions of this -Agreement and does not cure such failure in a reasonable period of -time after becoming aware of such noncompliance. If all Recipient's -rights under this Agreement terminate, Recipient agrees to cease use -and distribution of the Program as soon as reasonably practicable. -However, Recipient's obligations under this Agreement and any licenses -granted by Recipient relating to the Program shall continue and survive. - -Everyone is permitted to copy and distribute copies of this Agreement, -but in order to avoid inconsistency the Agreement is copyrighted and -may only be modified in the following manner. The Agreement Steward -reserves the right to publish new versions (including revisions) of -this Agreement from time to time. No one other than the Agreement -Steward has the right to modify this Agreement. The Eclipse Foundation -is the initial Agreement Steward. The Eclipse Foundation may assign the -responsibility to serve as the Agreement Steward to a suitable separate -entity. Each new version of the Agreement will be given a distinguishing -version number. The Program (including Contributions) may always be -Distributed subject to the version of the Agreement under which it was -received. In addition, after a new version of the Agreement is published, -Contributor may elect to Distribute the Program (including its -Contributions) under the new version. - -Except as expressly stated in Sections 2(a) and 2(b) above, Recipient -receives no rights or licenses to the intellectual property of any -Contributor under this Agreement, whether expressly, by implication, -estoppel or otherwise. All rights in the Program not expressly granted -under this Agreement are reserved. Nothing in this Agreement is intended -to be enforceable by any entity that is not a Contributor or Recipient. -No third-party beneficiary rights are created under this Agreement. - -Exhibit A - Form of Secondary Licenses Notice - -"This Source Code may also be made available under the following -Secondary Licenses when the conditions for such availability set forth -in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), -version(s), and exceptions or additional permissions here}." - - Simply including a copy of this Agreement, including this Exhibit A - is not sufficient to license the Source Code under Secondary Licenses. - - If it is not possible or desirable to put the notice in a particular - file, then You may include the notice in a location (such as a LICENSE - file in a relevant directory) where a recipient would be likely to - look for such a notice. - - You may add additional accurate notices of copyright ownership. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/commands.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/commands.go index c4c14d343..e99a2dfa9 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/commands.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/commands.go @@ -18,23 +18,26 @@ const ( ) // CommandGroupKind describes the kind of command group. -// +kubebuilder:validation:Enum=build;run;test;debug +// +kubebuilder:validation:Enum=build;run;test;debug;deploy type CommandGroupKind string const ( - BuildCommandGroupKind CommandGroupKind = "build" - RunCommandGroupKind CommandGroupKind = "run" - TestCommandGroupKind CommandGroupKind = "test" - DebugCommandGroupKind CommandGroupKind = "debug" + BuildCommandGroupKind CommandGroupKind = "build" + RunCommandGroupKind CommandGroupKind = "run" + TestCommandGroupKind CommandGroupKind = "test" + DebugCommandGroupKind CommandGroupKind = "debug" + DeployCommandGroupKind CommandGroupKind = "deploy" ) +// +devfile:getter:generate type CommandGroup struct { // Kind of group the command is part of Kind CommandGroupKind `json:"kind"` // +optional // Identifies the default command for a given group kind - IsDefault bool `json:"isDefault,omitempty"` + // +devfile:default:value=false + IsDefault *bool `json:"isDefault,omitempty"` } type BaseCommand struct { @@ -106,6 +109,7 @@ type CommandUnion struct { Custom *CustomCommand `json:"custom,omitempty"` } +// +devfile:getter:generate type ExecCommand struct { LabeledCommand `json:",inline"` @@ -144,7 +148,8 @@ type ExecCommand struct { // If set to `true` the command won't be restarted and it is expected to handle file changes on its own. // // Default value is `false` - HotReloadCapable bool `json:"hotReloadCapable,omitempty"` + // +devfile:default:value=false + HotReloadCapable *bool `json:"hotReloadCapable,omitempty"` } type ApplyCommand struct { @@ -155,6 +160,7 @@ type ApplyCommand struct { Component string `json:"component"` } +// +devfile:getter:generate type CompositeCommand struct { LabeledCommand `json:",inline"` @@ -163,7 +169,8 @@ type CompositeCommand struct { // Indicates if the sub-commands should be executed concurrently // +optional - Parallel bool `json:"parallel,omitempty"` + // +devfile:default:value=false + Parallel *bool `json:"parallel,omitempty"` } type CustomCommand struct { diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go index bec6b34e7..08ded6bb2 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go @@ -7,6 +7,7 @@ type ContainerComponent struct { Endpoints []Endpoint `json:"endpoints,omitempty" patchStrategy:"merge" patchMergeKey:"name"` } +// +devfile:getter:generate type Container struct { Image string `json:"image"` @@ -69,7 +70,20 @@ type Container struct { // // Default value is `false` // +optional - DedicatedPod bool `json:"dedicatedPod,omitempty"` + // +devfile:default:value=false + DedicatedPod *bool `json:"dedicatedPod,omitempty"` +} + +//GetMountSources returns the value of the boolean property. If it's unset, the default value is true for all component types except plugins and components that set `dedicatedPod` to true. +func (in *Container) GetMountSources() bool { + if in.MountSources != nil { + return *in.MountSources + } else { + if in.GetDedicatedPod() { + return false + } + return true + } } type EnvVar struct { diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image.go new file mode 100644 index 000000000..c6e7e6b77 --- /dev/null +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image.go @@ -0,0 +1,38 @@ +package v1alpha2 + +// ImageType describes the type of image. +// Only one of the following image type may be specified. +// +kubebuilder:validation:Enum=Dockerfile +type ImageType string + +const ( + DockerfileImageType ImageType = "Dockerfile" +) + +type BaseImage struct { +} + +// Component that allows the developer to build a runtime image for outerloop +type ImageComponent struct { + BaseComponent `json:",inline"` + Image `json:",inline"` +} + +type Image struct { + // Name of the image for the resulting outerloop build + ImageName string `json:"imageName"` + ImageUnion `json:",inline"` +} + +// +union +type ImageUnion struct { + // Type of image + // + // +unionDiscriminator + // +optional + ImageType ImageType `json:"imageType,omitempty"` + + // Allows specifying dockerfile type build + // +optional + Dockerfile *DockerfileImage `json:"dockerfile,omitempty"` +} diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image_dockerfile.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image_dockerfile.go new file mode 100644 index 000000000..a200ba137 --- /dev/null +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_image_dockerfile.go @@ -0,0 +1,83 @@ +package v1alpha2 + +// DockerfileSrcType describes the type of +// the src for the Dockerfile outerloop build. +// Only one of the following location type may be specified. +// +kubebuilder:validation:Enum=Uri;DevfileRegistry;Git +type DockerfileSrcType string + +const ( + UriLikeDockerfileSrcType DockerfileSrcType = "Uri" + DevfileRegistryLikeDockerfileSrcType DockerfileSrcType = "DevfileRegistry" + GitLikeDockerfileSrcType DockerfileSrcType = "Git" +) + +// Dockerfile Image type to specify the outerloop build using a Dockerfile +type DockerfileImage struct { + BaseImage `json:",inline"` + DockerfileSrc `json:",inline"` + Dockerfile `json:",inline"` +} + +// +union +type DockerfileSrc struct { + // Type of Dockerfile src + // + + // +unionDiscriminator + // +optional + SrcType DockerfileSrcType `json:"srcType,omitempty"` + + // URI Reference of a Dockerfile. + // It can be a full URL or a relative URI from the current devfile as the base URI. + // +optional + Uri string `json:"uri,omitempty"` + + // Dockerfile's Devfile Registry source + // +optional + DevfileRegistry *DockerfileDevfileRegistrySource `json:"devfileRegistry,omitempty"` + + // Dockerfile's Git source + // +optional + Git *DockerfileGitProjectSource `json:"git,omitempty"` +} + +// +devfile:getter:generate +type Dockerfile struct { + // Path of source directory to establish build context. Defaults to ${PROJECT_ROOT} in the container + // +optional + BuildContext string `json:"buildContext,omitempty"` + + // The arguments to supply to the dockerfile build. + // +optional + Args []string `json:"args,omitempty" patchStrategy:"replace"` + + // Specify if a privileged builder pod is required. + // + // Default value is `false` + // +optional + // +devfile:default:value=false + RootRequired *bool `json:"rootRequired,omitempty"` +} + +type DockerfileDevfileRegistrySource struct { + // Id in a devfile registry that contains a Dockerfile. The src in the OCI registry + // required for the Dockerfile build will be downloaded for building the image. + Id string `json:"id"` + + // Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. + // To ensure the Dockerfile gets resolved consistently in different environments, + // it is recommended to always specify the `devfileRegistryUrl` when `Id` is used. + // +optional + RegistryUrl string `json:"registryUrl,omitempty"` +} + +type DockerfileGitProjectSource struct { + // Git src for the Dockerfile build. The src required for the Dockerfile build will need to be + // cloned for building the image. + GitProjectSource `json:",inline"` + + // Location of the Dockerfile in the Git repository when using git as Dockerfile src. + // Defaults to Dockerfile. + // +optional + FileLocation string `json:"fileLocation,omitempty"` +} diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_volume.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_volume.go index 54d3ecbbb..c3bd69280 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_volume.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_volume.go @@ -7,6 +7,7 @@ type VolumeComponent struct { } // Volume that should be mounted to a component container +// +devfile:getter:generate type Volume struct { // +optional // Size of the volume @@ -15,5 +16,6 @@ type Volume struct { // +optional // Ephemeral volumes are not stored persistently across restarts. Defaults // to false - Ephemeral bool `json:"ephemeral,omitempty"` + // +devfile:default:value=false + Ephemeral *bool `json:"ephemeral,omitempty"` } diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go index 208499234..9356aa655 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go @@ -7,7 +7,7 @@ import ( // ComponentType describes the type of component. // Only one of the following component type may be specified. -// +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume;Plugin;Custom +// +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume;Image;Plugin;Custom type ComponentType string const ( @@ -16,6 +16,7 @@ const ( OpenshiftComponentType ComponentType = "Openshift" PluginComponentType ComponentType = "Plugin" VolumeComponentType ComponentType = "Volume" + ImageComponentType ComponentType = "Image" CustomComponentType ComponentType = "Custom" ) @@ -72,6 +73,10 @@ type ComponentUnion struct { // +optional Volume *VolumeComponent `json:"volume,omitempty"` + // Allows specifying the definition of an image for outer loop builds + // +optional + Image *ImageComponent `json:"image,omitempty"` + // Allows importing a plugin. // // Plugins are mainly imported devfiles that contribute components, commands diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/endpoint.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/endpoint.go index c12e1262a..3cf10d8ea 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/endpoint.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/endpoint.go @@ -1,8 +1,6 @@ package v1alpha2 -import ( - attributes "github.com/devfile/api/v2/pkg/attributes" -) +import "github.com/devfile/api/v2/pkg/attributes" // EndpointProtocol defines the application and transport protocols of the traffic that will go through this endpoint. // Only one of the following protocols may be specified: http, ws, tcp, udp. @@ -46,6 +44,7 @@ const ( NoneEndpointExposure EndpointExposure = "none" ) +// +devfile:getter:generate type Endpoint struct { // +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ // +kubebuilder:validation:MaxLength=63 @@ -94,7 +93,8 @@ type Endpoint struct { // Describes whether the endpoint should be secured and protected by some // authentication process. This requires a protocol of `https` or `wss`. // +optional - Secure bool `json:"secure,omitempty"` + // +devfile:default:value=false + Secure *bool `json:"secure,omitempty"` // Path of the endpoint URL // +optional diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/projects.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/projects.go index eafa40ae0..9348d4d68 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/projects.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/projects.go @@ -110,7 +110,7 @@ type GitLikeProjectSource struct { CheckoutFrom *CheckoutFrom `json:"checkoutFrom,omitempty"` // The remotes map which should be initialized in the git project. - // Projects must have at least one remote configured while StarterProjects can only have at most one remote configured. + // Projects must have at least one remote configured while StarterProjects & Image Component's Git source can only have at most one remote configured. Remotes map[string]string `json:"remotes"` } diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.deepcopy.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.deepcopy.go index 80d4e331c..ee9afdfbb 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.deepcopy.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.deepcopy.go @@ -79,7 +79,7 @@ func (in *BaseCommand) DeepCopyInto(out *BaseCommand) { if in.Group != nil { in, out := &in.Group, &out.Group *out = new(CommandGroup) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -99,7 +99,7 @@ func (in *BaseCommandParentOverride) DeepCopyInto(out *BaseCommandParentOverride if in.Group != nil { in, out := &in.Group, &out.Group *out = new(CommandGroupParentOverride) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -119,7 +119,7 @@ func (in *BaseCommandPluginOverride) DeepCopyInto(out *BaseCommandPluginOverride if in.Group != nil { in, out := &in.Group, &out.Group *out = new(CommandGroupPluginOverride) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -139,7 +139,7 @@ func (in *BaseCommandPluginOverrideParentOverride) DeepCopyInto(out *BaseCommand if in.Group != nil { in, out := &in.Group, &out.Group *out = new(CommandGroupPluginOverrideParentOverride) - **out = **in + (*in).DeepCopyInto(*out) } } @@ -213,6 +213,66 @@ func (in *BaseComponentPluginOverrideParentOverride) DeepCopy() *BaseComponentPl return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BaseImage) DeepCopyInto(out *BaseImage) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BaseImage. +func (in *BaseImage) DeepCopy() *BaseImage { + if in == nil { + return nil + } + out := new(BaseImage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BaseImageParentOverride) DeepCopyInto(out *BaseImageParentOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BaseImageParentOverride. +func (in *BaseImageParentOverride) DeepCopy() *BaseImageParentOverride { + if in == nil { + return nil + } + out := new(BaseImageParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BaseImagePluginOverride) DeepCopyInto(out *BaseImagePluginOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BaseImagePluginOverride. +func (in *BaseImagePluginOverride) DeepCopy() *BaseImagePluginOverride { + if in == nil { + return nil + } + out := new(BaseImagePluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BaseImagePluginOverrideParentOverride) DeepCopyInto(out *BaseImagePluginOverrideParentOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BaseImagePluginOverrideParentOverride. +func (in *BaseImagePluginOverrideParentOverride) DeepCopy() *BaseImagePluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(BaseImagePluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheckoutFrom) DeepCopyInto(out *CheckoutFrom) { *out = *in @@ -243,6 +303,36 @@ func (in *CheckoutFromParentOverride) DeepCopy() *CheckoutFromParentOverride { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CheckoutFromPluginOverride) DeepCopyInto(out *CheckoutFromPluginOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckoutFromPluginOverride. +func (in *CheckoutFromPluginOverride) DeepCopy() *CheckoutFromPluginOverride { + if in == nil { + return nil + } + out := new(CheckoutFromPluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CheckoutFromPluginOverrideParentOverride) DeepCopyInto(out *CheckoutFromPluginOverrideParentOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckoutFromPluginOverrideParentOverride. +func (in *CheckoutFromPluginOverrideParentOverride) DeepCopy() *CheckoutFromPluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(CheckoutFromPluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Command) DeepCopyInto(out *Command) { *out = *in @@ -269,6 +359,11 @@ func (in *Command) DeepCopy() *Command { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CommandGroup) DeepCopyInto(out *CommandGroup) { *out = *in + if in.IsDefault != nil { + in, out := &in.IsDefault, &out.IsDefault + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommandGroup. @@ -284,6 +379,11 @@ func (in *CommandGroup) DeepCopy() *CommandGroup { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CommandGroupParentOverride) DeepCopyInto(out *CommandGroupParentOverride) { *out = *in + if in.IsDefault != nil { + in, out := &in.IsDefault, &out.IsDefault + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommandGroupParentOverride. @@ -299,6 +399,11 @@ func (in *CommandGroupParentOverride) DeepCopy() *CommandGroupParentOverride { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CommandGroupPluginOverride) DeepCopyInto(out *CommandGroupPluginOverride) { *out = *in + if in.IsDefault != nil { + in, out := &in.IsDefault, &out.IsDefault + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommandGroupPluginOverride. @@ -314,6 +419,11 @@ func (in *CommandGroupPluginOverride) DeepCopy() *CommandGroupPluginOverride { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CommandGroupPluginOverrideParentOverride) DeepCopyInto(out *CommandGroupPluginOverrideParentOverride) { *out = *in + if in.IsDefault != nil { + in, out := &in.IsDefault, &out.IsDefault + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommandGroupPluginOverrideParentOverride. @@ -550,6 +660,36 @@ func (in *CommonProjectSourceParentOverride) DeepCopy() *CommonProjectSourcePare return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CommonProjectSourcePluginOverride) DeepCopyInto(out *CommonProjectSourcePluginOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonProjectSourcePluginOverride. +func (in *CommonProjectSourcePluginOverride) DeepCopy() *CommonProjectSourcePluginOverride { + if in == nil { + return nil + } + out := new(CommonProjectSourcePluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CommonProjectSourcePluginOverrideParentOverride) DeepCopyInto(out *CommonProjectSourcePluginOverrideParentOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonProjectSourcePluginOverrideParentOverride. +func (in *CommonProjectSourcePluginOverrideParentOverride) DeepCopy() *CommonProjectSourcePluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(CommonProjectSourcePluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Component) DeepCopyInto(out *Component) { *out = *in @@ -663,7 +803,12 @@ func (in *ComponentUnion) DeepCopyInto(out *ComponentUnion) { if in.Volume != nil { in, out := &in.Volume, &out.Volume *out = new(VolumeComponent) - **out = **in + (*in).DeepCopyInto(*out) + } + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(ImageComponent) + (*in).DeepCopyInto(*out) } if in.Plugin != nil { in, out := &in.Plugin, &out.Plugin @@ -708,7 +853,12 @@ func (in *ComponentUnionParentOverride) DeepCopyInto(out *ComponentUnionParentOv if in.Volume != nil { in, out := &in.Volume, &out.Volume *out = new(VolumeComponentParentOverride) - **out = **in + (*in).DeepCopyInto(*out) + } + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(ImageComponentParentOverride) + (*in).DeepCopyInto(*out) } if in.Plugin != nil { in, out := &in.Plugin, &out.Plugin @@ -748,7 +898,12 @@ func (in *ComponentUnionPluginOverride) DeepCopyInto(out *ComponentUnionPluginOv if in.Volume != nil { in, out := &in.Volume, &out.Volume *out = new(VolumeComponentPluginOverride) - **out = **in + (*in).DeepCopyInto(*out) + } + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(ImageComponentPluginOverride) + (*in).DeepCopyInto(*out) } } @@ -783,7 +938,12 @@ func (in *ComponentUnionPluginOverrideParentOverride) DeepCopyInto(out *Componen if in.Volume != nil { in, out := &in.Volume, &out.Volume *out = new(VolumeComponentPluginOverrideParentOverride) - **out = **in + (*in).DeepCopyInto(*out) + } + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(ImageComponentPluginOverrideParentOverride) + (*in).DeepCopyInto(*out) } } @@ -806,6 +966,11 @@ func (in *CompositeCommand) DeepCopyInto(out *CompositeCommand) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Parallel != nil { + in, out := &in.Parallel, &out.Parallel + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompositeCommand. @@ -827,6 +992,11 @@ func (in *CompositeCommandParentOverride) DeepCopyInto(out *CompositeCommandPare *out = make([]string, len(*in)) copy(*out, *in) } + if in.Parallel != nil { + in, out := &in.Parallel, &out.Parallel + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompositeCommandParentOverride. @@ -848,6 +1018,11 @@ func (in *CompositeCommandPluginOverride) DeepCopyInto(out *CompositeCommandPlug *out = make([]string, len(*in)) copy(*out, *in) } + if in.Parallel != nil { + in, out := &in.Parallel, &out.Parallel + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompositeCommandPluginOverride. @@ -869,6 +1044,11 @@ func (in *CompositeCommandPluginOverrideParentOverride) DeepCopyInto(out *Compos *out = make([]string, len(*in)) copy(*out, *in) } + if in.Parallel != nil { + in, out := &in.Parallel, &out.Parallel + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompositeCommandPluginOverrideParentOverride. @@ -909,6 +1089,11 @@ func (in *Container) DeepCopyInto(out *Container) { *out = new(bool) **out = **in } + if in.DedicatedPod != nil { + in, out := &in.DedicatedPod, &out.DedicatedPod + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Container. @@ -1045,6 +1230,11 @@ func (in *ContainerParentOverride) DeepCopyInto(out *ContainerParentOverride) { *out = new(bool) **out = **in } + if in.DedicatedPod != nil { + in, out := &in.DedicatedPod, &out.DedicatedPod + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerParentOverride. @@ -1085,6 +1275,11 @@ func (in *ContainerPluginOverride) DeepCopyInto(out *ContainerPluginOverride) { *out = new(bool) **out = **in } + if in.DedicatedPod != nil { + in, out := &in.DedicatedPod, &out.DedicatedPod + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerPluginOverride. @@ -1125,6 +1320,11 @@ func (in *ContainerPluginOverrideParentOverride) DeepCopyInto(out *ContainerPlug *out = new(bool) **out = **in } + if in.DedicatedPod != nil { + in, out := &in.DedicatedPod, &out.DedicatedPod + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerPluginOverrideParentOverride. @@ -1476,241 +1676,677 @@ func (in *DevWorkspaceTemplateSpecContent) DeepCopy() *DevWorkspaceTemplateSpecC } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Endpoint) DeepCopyInto(out *Endpoint) { +func (in *Dockerfile) DeepCopyInto(out *Dockerfile) { *out = *in - if in.Attributes != nil { - in, out := &in.Attributes, &out.Attributes - *out = make(attributes.Attributes, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RootRequired != nil { + in, out := &in.RootRequired, &out.RootRequired + *out = new(bool) + **out = **in } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. -func (in *Endpoint) DeepCopy() *Endpoint { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Dockerfile. +func (in *Dockerfile) DeepCopy() *Dockerfile { if in == nil { return nil } - out := new(Endpoint) + out := new(Dockerfile) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EndpointParentOverride) DeepCopyInto(out *EndpointParentOverride) { +func (in *DockerfileDevfileRegistrySource) DeepCopyInto(out *DockerfileDevfileRegistrySource) { *out = *in - if in.Attributes != nil { - in, out := &in.Attributes, &out.Attributes - *out = make(attributes.Attributes, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointParentOverride. -func (in *EndpointParentOverride) DeepCopy() *EndpointParentOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileDevfileRegistrySource. +func (in *DockerfileDevfileRegistrySource) DeepCopy() *DockerfileDevfileRegistrySource { if in == nil { return nil } - out := new(EndpointParentOverride) + out := new(DockerfileDevfileRegistrySource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EndpointPluginOverride) DeepCopyInto(out *EndpointPluginOverride) { +func (in *DockerfileDevfileRegistrySourceParentOverride) DeepCopyInto(out *DockerfileDevfileRegistrySourceParentOverride) { *out = *in - if in.Attributes != nil { - in, out := &in.Attributes, &out.Attributes - *out = make(attributes.Attributes, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointPluginOverride. -func (in *EndpointPluginOverride) DeepCopy() *EndpointPluginOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileDevfileRegistrySourceParentOverride. +func (in *DockerfileDevfileRegistrySourceParentOverride) DeepCopy() *DockerfileDevfileRegistrySourceParentOverride { if in == nil { return nil } - out := new(EndpointPluginOverride) + out := new(DockerfileDevfileRegistrySourceParentOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EndpointPluginOverrideParentOverride) DeepCopyInto(out *EndpointPluginOverrideParentOverride) { +func (in *DockerfileDevfileRegistrySourcePluginOverride) DeepCopyInto(out *DockerfileDevfileRegistrySourcePluginOverride) { *out = *in - if in.Attributes != nil { - in, out := &in.Attributes, &out.Attributes - *out = make(attributes.Attributes, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointPluginOverrideParentOverride. -func (in *EndpointPluginOverrideParentOverride) DeepCopy() *EndpointPluginOverrideParentOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileDevfileRegistrySourcePluginOverride. +func (in *DockerfileDevfileRegistrySourcePluginOverride) DeepCopy() *DockerfileDevfileRegistrySourcePluginOverride { if in == nil { return nil } - out := new(EndpointPluginOverrideParentOverride) + out := new(DockerfileDevfileRegistrySourcePluginOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvVar) DeepCopyInto(out *EnvVar) { +func (in *DockerfileDevfileRegistrySourcePluginOverrideParentOverride) DeepCopyInto(out *DockerfileDevfileRegistrySourcePluginOverrideParentOverride) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVar. -func (in *EnvVar) DeepCopy() *EnvVar { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileDevfileRegistrySourcePluginOverrideParentOverride. +func (in *DockerfileDevfileRegistrySourcePluginOverrideParentOverride) DeepCopy() *DockerfileDevfileRegistrySourcePluginOverrideParentOverride { if in == nil { return nil } - out := new(EnvVar) + out := new(DockerfileDevfileRegistrySourcePluginOverrideParentOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvVarParentOverride) DeepCopyInto(out *EnvVarParentOverride) { +func (in *DockerfileGitProjectSource) DeepCopyInto(out *DockerfileGitProjectSource) { *out = *in + in.GitProjectSource.DeepCopyInto(&out.GitProjectSource) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVarParentOverride. -func (in *EnvVarParentOverride) DeepCopy() *EnvVarParentOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileGitProjectSource. +func (in *DockerfileGitProjectSource) DeepCopy() *DockerfileGitProjectSource { if in == nil { return nil } - out := new(EnvVarParentOverride) + out := new(DockerfileGitProjectSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvVarPluginOverride) DeepCopyInto(out *EnvVarPluginOverride) { +func (in *DockerfileGitProjectSourceParentOverride) DeepCopyInto(out *DockerfileGitProjectSourceParentOverride) { *out = *in + in.GitProjectSourceParentOverride.DeepCopyInto(&out.GitProjectSourceParentOverride) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVarPluginOverride. -func (in *EnvVarPluginOverride) DeepCopy() *EnvVarPluginOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileGitProjectSourceParentOverride. +func (in *DockerfileGitProjectSourceParentOverride) DeepCopy() *DockerfileGitProjectSourceParentOverride { if in == nil { return nil } - out := new(EnvVarPluginOverride) + out := new(DockerfileGitProjectSourceParentOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvVarPluginOverrideParentOverride) DeepCopyInto(out *EnvVarPluginOverrideParentOverride) { +func (in *DockerfileGitProjectSourcePluginOverride) DeepCopyInto(out *DockerfileGitProjectSourcePluginOverride) { *out = *in + in.GitProjectSourcePluginOverride.DeepCopyInto(&out.GitProjectSourcePluginOverride) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVarPluginOverrideParentOverride. -func (in *EnvVarPluginOverrideParentOverride) DeepCopy() *EnvVarPluginOverrideParentOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileGitProjectSourcePluginOverride. +func (in *DockerfileGitProjectSourcePluginOverride) DeepCopy() *DockerfileGitProjectSourcePluginOverride { if in == nil { return nil } - out := new(EnvVarPluginOverrideParentOverride) + out := new(DockerfileGitProjectSourcePluginOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Events) DeepCopyInto(out *Events) { +func (in *DockerfileGitProjectSourcePluginOverrideParentOverride) DeepCopyInto(out *DockerfileGitProjectSourcePluginOverrideParentOverride) { *out = *in - in.DevWorkspaceEvents.DeepCopyInto(&out.DevWorkspaceEvents) + in.GitProjectSourcePluginOverrideParentOverride.DeepCopyInto(&out.GitProjectSourcePluginOverrideParentOverride) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Events. -func (in *Events) DeepCopy() *Events { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileGitProjectSourcePluginOverrideParentOverride. +func (in *DockerfileGitProjectSourcePluginOverrideParentOverride) DeepCopy() *DockerfileGitProjectSourcePluginOverrideParentOverride { if in == nil { return nil } - out := new(Events) + out := new(DockerfileGitProjectSourcePluginOverrideParentOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExecCommand) DeepCopyInto(out *ExecCommand) { +func (in *DockerfileImage) DeepCopyInto(out *DockerfileImage) { *out = *in - in.LabeledCommand.DeepCopyInto(&out.LabeledCommand) - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make([]EnvVar, len(*in)) - copy(*out, *in) - } + out.BaseImage = in.BaseImage + in.DockerfileSrc.DeepCopyInto(&out.DockerfileSrc) + in.Dockerfile.DeepCopyInto(&out.Dockerfile) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCommand. -func (in *ExecCommand) DeepCopy() *ExecCommand { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileImage. +func (in *DockerfileImage) DeepCopy() *DockerfileImage { if in == nil { return nil } - out := new(ExecCommand) + out := new(DockerfileImage) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExecCommandParentOverride) DeepCopyInto(out *ExecCommandParentOverride) { +func (in *DockerfileImageParentOverride) DeepCopyInto(out *DockerfileImageParentOverride) { *out = *in - in.LabeledCommandParentOverride.DeepCopyInto(&out.LabeledCommandParentOverride) - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make([]EnvVarParentOverride, len(*in)) - copy(*out, *in) - } + out.BaseImageParentOverride = in.BaseImageParentOverride + in.DockerfileSrcParentOverride.DeepCopyInto(&out.DockerfileSrcParentOverride) + in.DockerfileParentOverride.DeepCopyInto(&out.DockerfileParentOverride) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCommandParentOverride. -func (in *ExecCommandParentOverride) DeepCopy() *ExecCommandParentOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileImageParentOverride. +func (in *DockerfileImageParentOverride) DeepCopy() *DockerfileImageParentOverride { if in == nil { return nil } - out := new(ExecCommandParentOverride) + out := new(DockerfileImageParentOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExecCommandPluginOverride) DeepCopyInto(out *ExecCommandPluginOverride) { +func (in *DockerfileImagePluginOverride) DeepCopyInto(out *DockerfileImagePluginOverride) { *out = *in - in.LabeledCommandPluginOverride.DeepCopyInto(&out.LabeledCommandPluginOverride) - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make([]EnvVarPluginOverride, len(*in)) - copy(*out, *in) - } + out.BaseImagePluginOverride = in.BaseImagePluginOverride + in.DockerfileSrcPluginOverride.DeepCopyInto(&out.DockerfileSrcPluginOverride) + in.DockerfilePluginOverride.DeepCopyInto(&out.DockerfilePluginOverride) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCommandPluginOverride. -func (in *ExecCommandPluginOverride) DeepCopy() *ExecCommandPluginOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileImagePluginOverride. +func (in *DockerfileImagePluginOverride) DeepCopy() *DockerfileImagePluginOverride { if in == nil { return nil } - out := new(ExecCommandPluginOverride) + out := new(DockerfileImagePluginOverride) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExecCommandPluginOverrideParentOverride) DeepCopyInto(out *ExecCommandPluginOverrideParentOverride) { +func (in *DockerfileImagePluginOverrideParentOverride) DeepCopyInto(out *DockerfileImagePluginOverrideParentOverride) { *out = *in - in.LabeledCommandPluginOverrideParentOverride.DeepCopyInto(&out.LabeledCommandPluginOverrideParentOverride) - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make([]EnvVarPluginOverrideParentOverride, len(*in)) - copy(*out, *in) - } + out.BaseImagePluginOverrideParentOverride = in.BaseImagePluginOverrideParentOverride + in.DockerfileSrcPluginOverrideParentOverride.DeepCopyInto(&out.DockerfileSrcPluginOverrideParentOverride) + in.DockerfilePluginOverrideParentOverride.DeepCopyInto(&out.DockerfilePluginOverrideParentOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileImagePluginOverrideParentOverride. +func (in *DockerfileImagePluginOverrideParentOverride) DeepCopy() *DockerfileImagePluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(DockerfileImagePluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerfileParentOverride) DeepCopyInto(out *DockerfileParentOverride) { + *out = *in + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RootRequired != nil { + in, out := &in.RootRequired, &out.RootRequired + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileParentOverride. +func (in *DockerfileParentOverride) DeepCopy() *DockerfileParentOverride { + if in == nil { + return nil + } + out := new(DockerfileParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerfilePluginOverride) DeepCopyInto(out *DockerfilePluginOverride) { + *out = *in + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RootRequired != nil { + in, out := &in.RootRequired, &out.RootRequired + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfilePluginOverride. +func (in *DockerfilePluginOverride) DeepCopy() *DockerfilePluginOverride { + if in == nil { + return nil + } + out := new(DockerfilePluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerfilePluginOverrideParentOverride) DeepCopyInto(out *DockerfilePluginOverrideParentOverride) { + *out = *in + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RootRequired != nil { + in, out := &in.RootRequired, &out.RootRequired + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfilePluginOverrideParentOverride. +func (in *DockerfilePluginOverrideParentOverride) DeepCopy() *DockerfilePluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(DockerfilePluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerfileSrc) DeepCopyInto(out *DockerfileSrc) { + *out = *in + if in.DevfileRegistry != nil { + in, out := &in.DevfileRegistry, &out.DevfileRegistry + *out = new(DockerfileDevfileRegistrySource) + **out = **in + } + if in.Git != nil { + in, out := &in.Git, &out.Git + *out = new(DockerfileGitProjectSource) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileSrc. +func (in *DockerfileSrc) DeepCopy() *DockerfileSrc { + if in == nil { + return nil + } + out := new(DockerfileSrc) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerfileSrcParentOverride) DeepCopyInto(out *DockerfileSrcParentOverride) { + *out = *in + if in.DevfileRegistry != nil { + in, out := &in.DevfileRegistry, &out.DevfileRegistry + *out = new(DockerfileDevfileRegistrySourceParentOverride) + **out = **in + } + if in.Git != nil { + in, out := &in.Git, &out.Git + *out = new(DockerfileGitProjectSourceParentOverride) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileSrcParentOverride. +func (in *DockerfileSrcParentOverride) DeepCopy() *DockerfileSrcParentOverride { + if in == nil { + return nil + } + out := new(DockerfileSrcParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerfileSrcPluginOverride) DeepCopyInto(out *DockerfileSrcPluginOverride) { + *out = *in + if in.DevfileRegistry != nil { + in, out := &in.DevfileRegistry, &out.DevfileRegistry + *out = new(DockerfileDevfileRegistrySourcePluginOverride) + **out = **in + } + if in.Git != nil { + in, out := &in.Git, &out.Git + *out = new(DockerfileGitProjectSourcePluginOverride) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileSrcPluginOverride. +func (in *DockerfileSrcPluginOverride) DeepCopy() *DockerfileSrcPluginOverride { + if in == nil { + return nil + } + out := new(DockerfileSrcPluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerfileSrcPluginOverrideParentOverride) DeepCopyInto(out *DockerfileSrcPluginOverrideParentOverride) { + *out = *in + if in.DevfileRegistry != nil { + in, out := &in.DevfileRegistry, &out.DevfileRegistry + *out = new(DockerfileDevfileRegistrySourcePluginOverrideParentOverride) + **out = **in + } + if in.Git != nil { + in, out := &in.Git, &out.Git + *out = new(DockerfileGitProjectSourcePluginOverrideParentOverride) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerfileSrcPluginOverrideParentOverride. +func (in *DockerfileSrcPluginOverrideParentOverride) DeepCopy() *DockerfileSrcPluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(DockerfileSrcPluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Endpoint) DeepCopyInto(out *Endpoint) { + *out = *in + if in.Secure != nil { + in, out := &in.Secure, &out.Secure + *out = new(bool) + **out = **in + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(attributes.Attributes, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. +func (in *Endpoint) DeepCopy() *Endpoint { + if in == nil { + return nil + } + out := new(Endpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointParentOverride) DeepCopyInto(out *EndpointParentOverride) { + *out = *in + if in.Secure != nil { + in, out := &in.Secure, &out.Secure + *out = new(bool) + **out = **in + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(attributes.Attributes, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointParentOverride. +func (in *EndpointParentOverride) DeepCopy() *EndpointParentOverride { + if in == nil { + return nil + } + out := new(EndpointParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointPluginOverride) DeepCopyInto(out *EndpointPluginOverride) { + *out = *in + if in.Secure != nil { + in, out := &in.Secure, &out.Secure + *out = new(bool) + **out = **in + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(attributes.Attributes, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointPluginOverride. +func (in *EndpointPluginOverride) DeepCopy() *EndpointPluginOverride { + if in == nil { + return nil + } + out := new(EndpointPluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointPluginOverrideParentOverride) DeepCopyInto(out *EndpointPluginOverrideParentOverride) { + *out = *in + if in.Secure != nil { + in, out := &in.Secure, &out.Secure + *out = new(bool) + **out = **in + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(attributes.Attributes, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointPluginOverrideParentOverride. +func (in *EndpointPluginOverrideParentOverride) DeepCopy() *EndpointPluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(EndpointPluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvVar) DeepCopyInto(out *EnvVar) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVar. +func (in *EnvVar) DeepCopy() *EnvVar { + if in == nil { + return nil + } + out := new(EnvVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvVarParentOverride) DeepCopyInto(out *EnvVarParentOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVarParentOverride. +func (in *EnvVarParentOverride) DeepCopy() *EnvVarParentOverride { + if in == nil { + return nil + } + out := new(EnvVarParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvVarPluginOverride) DeepCopyInto(out *EnvVarPluginOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVarPluginOverride. +func (in *EnvVarPluginOverride) DeepCopy() *EnvVarPluginOverride { + if in == nil { + return nil + } + out := new(EnvVarPluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvVarPluginOverrideParentOverride) DeepCopyInto(out *EnvVarPluginOverrideParentOverride) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVarPluginOverrideParentOverride. +func (in *EnvVarPluginOverrideParentOverride) DeepCopy() *EnvVarPluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(EnvVarPluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Events) DeepCopyInto(out *Events) { + *out = *in + in.DevWorkspaceEvents.DeepCopyInto(&out.DevWorkspaceEvents) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Events. +func (in *Events) DeepCopy() *Events { + if in == nil { + return nil + } + out := new(Events) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExecCommand) DeepCopyInto(out *ExecCommand) { + *out = *in + in.LabeledCommand.DeepCopyInto(&out.LabeledCommand) + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]EnvVar, len(*in)) + copy(*out, *in) + } + if in.HotReloadCapable != nil { + in, out := &in.HotReloadCapable, &out.HotReloadCapable + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCommand. +func (in *ExecCommand) DeepCopy() *ExecCommand { + if in == nil { + return nil + } + out := new(ExecCommand) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExecCommandParentOverride) DeepCopyInto(out *ExecCommandParentOverride) { + *out = *in + in.LabeledCommandParentOverride.DeepCopyInto(&out.LabeledCommandParentOverride) + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]EnvVarParentOverride, len(*in)) + copy(*out, *in) + } + if in.HotReloadCapable != nil { + in, out := &in.HotReloadCapable, &out.HotReloadCapable + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCommandParentOverride. +func (in *ExecCommandParentOverride) DeepCopy() *ExecCommandParentOverride { + if in == nil { + return nil + } + out := new(ExecCommandParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExecCommandPluginOverride) DeepCopyInto(out *ExecCommandPluginOverride) { + *out = *in + in.LabeledCommandPluginOverride.DeepCopyInto(&out.LabeledCommandPluginOverride) + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]EnvVarPluginOverride, len(*in)) + copy(*out, *in) + } + if in.HotReloadCapable != nil { + in, out := &in.HotReloadCapable, &out.HotReloadCapable + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCommandPluginOverride. +func (in *ExecCommandPluginOverride) DeepCopy() *ExecCommandPluginOverride { + if in == nil { + return nil + } + out := new(ExecCommandPluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExecCommandPluginOverrideParentOverride) DeepCopyInto(out *ExecCommandPluginOverrideParentOverride) { + *out = *in + in.LabeledCommandPluginOverrideParentOverride.DeepCopyInto(&out.LabeledCommandPluginOverrideParentOverride) + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]EnvVarPluginOverrideParentOverride, len(*in)) + copy(*out, *in) + } + if in.HotReloadCapable != nil { + in, out := &in.HotReloadCapable, &out.HotReloadCapable + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCommandPluginOverrideParentOverride. @@ -1779,6 +2415,62 @@ func (in *GitLikeProjectSourceParentOverride) DeepCopy() *GitLikeProjectSourcePa return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitLikeProjectSourcePluginOverride) DeepCopyInto(out *GitLikeProjectSourcePluginOverride) { + *out = *in + out.CommonProjectSourcePluginOverride = in.CommonProjectSourcePluginOverride + if in.CheckoutFrom != nil { + in, out := &in.CheckoutFrom, &out.CheckoutFrom + *out = new(CheckoutFromPluginOverride) + **out = **in + } + if in.Remotes != nil { + in, out := &in.Remotes, &out.Remotes + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitLikeProjectSourcePluginOverride. +func (in *GitLikeProjectSourcePluginOverride) DeepCopy() *GitLikeProjectSourcePluginOverride { + if in == nil { + return nil + } + out := new(GitLikeProjectSourcePluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitLikeProjectSourcePluginOverrideParentOverride) DeepCopyInto(out *GitLikeProjectSourcePluginOverrideParentOverride) { + *out = *in + out.CommonProjectSourcePluginOverrideParentOverride = in.CommonProjectSourcePluginOverrideParentOverride + if in.CheckoutFrom != nil { + in, out := &in.CheckoutFrom, &out.CheckoutFrom + *out = new(CheckoutFromPluginOverrideParentOverride) + **out = **in + } + if in.Remotes != nil { + in, out := &in.Remotes, &out.Remotes + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitLikeProjectSourcePluginOverrideParentOverride. +func (in *GitLikeProjectSourcePluginOverrideParentOverride) DeepCopy() *GitLikeProjectSourcePluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(GitLikeProjectSourcePluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GitProjectSource) DeepCopyInto(out *GitProjectSource) { *out = *in @@ -1811,6 +2503,250 @@ func (in *GitProjectSourceParentOverride) DeepCopy() *GitProjectSourceParentOver return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitProjectSourcePluginOverride) DeepCopyInto(out *GitProjectSourcePluginOverride) { + *out = *in + in.GitLikeProjectSourcePluginOverride.DeepCopyInto(&out.GitLikeProjectSourcePluginOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitProjectSourcePluginOverride. +func (in *GitProjectSourcePluginOverride) DeepCopy() *GitProjectSourcePluginOverride { + if in == nil { + return nil + } + out := new(GitProjectSourcePluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitProjectSourcePluginOverrideParentOverride) DeepCopyInto(out *GitProjectSourcePluginOverrideParentOverride) { + *out = *in + in.GitLikeProjectSourcePluginOverrideParentOverride.DeepCopyInto(&out.GitLikeProjectSourcePluginOverrideParentOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitProjectSourcePluginOverrideParentOverride. +func (in *GitProjectSourcePluginOverrideParentOverride) DeepCopy() *GitProjectSourcePluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(GitProjectSourcePluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Image) DeepCopyInto(out *Image) { + *out = *in + in.ImageUnion.DeepCopyInto(&out.ImageUnion) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image. +func (in *Image) DeepCopy() *Image { + if in == nil { + return nil + } + out := new(Image) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageComponent) DeepCopyInto(out *ImageComponent) { + *out = *in + out.BaseComponent = in.BaseComponent + in.Image.DeepCopyInto(&out.Image) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageComponent. +func (in *ImageComponent) DeepCopy() *ImageComponent { + if in == nil { + return nil + } + out := new(ImageComponent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageComponentParentOverride) DeepCopyInto(out *ImageComponentParentOverride) { + *out = *in + out.BaseComponentParentOverride = in.BaseComponentParentOverride + in.ImageParentOverride.DeepCopyInto(&out.ImageParentOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageComponentParentOverride. +func (in *ImageComponentParentOverride) DeepCopy() *ImageComponentParentOverride { + if in == nil { + return nil + } + out := new(ImageComponentParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageComponentPluginOverride) DeepCopyInto(out *ImageComponentPluginOverride) { + *out = *in + out.BaseComponentPluginOverride = in.BaseComponentPluginOverride + in.ImagePluginOverride.DeepCopyInto(&out.ImagePluginOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageComponentPluginOverride. +func (in *ImageComponentPluginOverride) DeepCopy() *ImageComponentPluginOverride { + if in == nil { + return nil + } + out := new(ImageComponentPluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageComponentPluginOverrideParentOverride) DeepCopyInto(out *ImageComponentPluginOverrideParentOverride) { + *out = *in + out.BaseComponentPluginOverrideParentOverride = in.BaseComponentPluginOverrideParentOverride + in.ImagePluginOverrideParentOverride.DeepCopyInto(&out.ImagePluginOverrideParentOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageComponentPluginOverrideParentOverride. +func (in *ImageComponentPluginOverrideParentOverride) DeepCopy() *ImageComponentPluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(ImageComponentPluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageParentOverride) DeepCopyInto(out *ImageParentOverride) { + *out = *in + in.ImageUnionParentOverride.DeepCopyInto(&out.ImageUnionParentOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageParentOverride. +func (in *ImageParentOverride) DeepCopy() *ImageParentOverride { + if in == nil { + return nil + } + out := new(ImageParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImagePluginOverride) DeepCopyInto(out *ImagePluginOverride) { + *out = *in + in.ImageUnionPluginOverride.DeepCopyInto(&out.ImageUnionPluginOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePluginOverride. +func (in *ImagePluginOverride) DeepCopy() *ImagePluginOverride { + if in == nil { + return nil + } + out := new(ImagePluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImagePluginOverrideParentOverride) DeepCopyInto(out *ImagePluginOverrideParentOverride) { + *out = *in + in.ImageUnionPluginOverrideParentOverride.DeepCopyInto(&out.ImageUnionPluginOverrideParentOverride) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePluginOverrideParentOverride. +func (in *ImagePluginOverrideParentOverride) DeepCopy() *ImagePluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(ImagePluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageUnion) DeepCopyInto(out *ImageUnion) { + *out = *in + if in.Dockerfile != nil { + in, out := &in.Dockerfile, &out.Dockerfile + *out = new(DockerfileImage) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageUnion. +func (in *ImageUnion) DeepCopy() *ImageUnion { + if in == nil { + return nil + } + out := new(ImageUnion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageUnionParentOverride) DeepCopyInto(out *ImageUnionParentOverride) { + *out = *in + if in.Dockerfile != nil { + in, out := &in.Dockerfile, &out.Dockerfile + *out = new(DockerfileImageParentOverride) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageUnionParentOverride. +func (in *ImageUnionParentOverride) DeepCopy() *ImageUnionParentOverride { + if in == nil { + return nil + } + out := new(ImageUnionParentOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageUnionPluginOverride) DeepCopyInto(out *ImageUnionPluginOverride) { + *out = *in + if in.Dockerfile != nil { + in, out := &in.Dockerfile, &out.Dockerfile + *out = new(DockerfileImagePluginOverride) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageUnionPluginOverride. +func (in *ImageUnionPluginOverride) DeepCopy() *ImageUnionPluginOverride { + if in == nil { + return nil + } + out := new(ImageUnionPluginOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageUnionPluginOverrideParentOverride) DeepCopyInto(out *ImageUnionPluginOverrideParentOverride) { + *out = *in + if in.Dockerfile != nil { + in, out := &in.Dockerfile, &out.Dockerfile + *out = new(DockerfileImagePluginOverrideParentOverride) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageUnionPluginOverrideParentOverride. +func (in *ImageUnionPluginOverrideParentOverride) DeepCopy() *ImageUnionPluginOverrideParentOverride { + if in == nil { + return nil + } + out := new(ImageUnionPluginOverrideParentOverride) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImportReference) DeepCopyInto(out *ImportReference) { *out = *in @@ -2637,6 +3573,11 @@ func (in *StarterProjectParentOverride) DeepCopy() *StarterProjectParentOverride // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Volume) DeepCopyInto(out *Volume) { *out = *in + if in.Ephemeral != nil { + in, out := &in.Ephemeral, &out.Ephemeral + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Volume. @@ -2653,7 +3594,7 @@ func (in *Volume) DeepCopy() *Volume { func (in *VolumeComponent) DeepCopyInto(out *VolumeComponent) { *out = *in out.BaseComponent = in.BaseComponent - out.Volume = in.Volume + in.Volume.DeepCopyInto(&out.Volume) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeComponent. @@ -2670,7 +3611,7 @@ func (in *VolumeComponent) DeepCopy() *VolumeComponent { func (in *VolumeComponentParentOverride) DeepCopyInto(out *VolumeComponentParentOverride) { *out = *in out.BaseComponentParentOverride = in.BaseComponentParentOverride - out.VolumeParentOverride = in.VolumeParentOverride + in.VolumeParentOverride.DeepCopyInto(&out.VolumeParentOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeComponentParentOverride. @@ -2687,7 +3628,7 @@ func (in *VolumeComponentParentOverride) DeepCopy() *VolumeComponentParentOverri func (in *VolumeComponentPluginOverride) DeepCopyInto(out *VolumeComponentPluginOverride) { *out = *in out.BaseComponentPluginOverride = in.BaseComponentPluginOverride - out.VolumePluginOverride = in.VolumePluginOverride + in.VolumePluginOverride.DeepCopyInto(&out.VolumePluginOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeComponentPluginOverride. @@ -2704,7 +3645,7 @@ func (in *VolumeComponentPluginOverride) DeepCopy() *VolumeComponentPluginOverri func (in *VolumeComponentPluginOverrideParentOverride) DeepCopyInto(out *VolumeComponentPluginOverrideParentOverride) { *out = *in out.BaseComponentPluginOverrideParentOverride = in.BaseComponentPluginOverrideParentOverride - out.VolumePluginOverrideParentOverride = in.VolumePluginOverrideParentOverride + in.VolumePluginOverrideParentOverride.DeepCopyInto(&out.VolumePluginOverrideParentOverride) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeComponentPluginOverrideParentOverride. @@ -2780,6 +3721,11 @@ func (in *VolumeMountPluginOverrideParentOverride) DeepCopy() *VolumeMountPlugin // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumeParentOverride) DeepCopyInto(out *VolumeParentOverride) { *out = *in + if in.Ephemeral != nil { + in, out := &in.Ephemeral, &out.Ephemeral + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeParentOverride. @@ -2795,6 +3741,11 @@ func (in *VolumeParentOverride) DeepCopy() *VolumeParentOverride { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumePluginOverride) DeepCopyInto(out *VolumePluginOverride) { *out = *in + if in.Ephemeral != nil { + in, out := &in.Ephemeral, &out.Ephemeral + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumePluginOverride. @@ -2810,6 +3761,11 @@ func (in *VolumePluginOverride) DeepCopy() *VolumePluginOverride { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumePluginOverrideParentOverride) DeepCopyInto(out *VolumePluginOverrideParentOverride) { *out = *in + if in.Ephemeral != nil { + in, out := &in.Ephemeral, &out.Ephemeral + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumePluginOverrideParentOverride. diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.getters.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.getters.go new file mode 100644 index 000000000..4c7c36a30 --- /dev/null +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.getters.go @@ -0,0 +1,43 @@ +package v1alpha2 + +// GetIsDefault returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker +func (in *CommandGroup) GetIsDefault() bool { + return getBoolOrDefault(in.IsDefault, false) +} + +// GetHotReloadCapable returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker +func (in *ExecCommand) GetHotReloadCapable() bool { + return getBoolOrDefault(in.HotReloadCapable, false) +} + +// GetParallel returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker +func (in *CompositeCommand) GetParallel() bool { + return getBoolOrDefault(in.Parallel, false) +} + +// GetDedicatedPod returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker +func (in *Container) GetDedicatedPod() bool { + return getBoolOrDefault(in.DedicatedPod, false) +} + +// GetRootRequired returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker +func (in *Dockerfile) GetRootRequired() bool { + return getBoolOrDefault(in.RootRequired, false) +} + +// GetEphemeral returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker +func (in *Volume) GetEphemeral() bool { + return getBoolOrDefault(in.Ephemeral, false) +} + +// GetSecure returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker +func (in *Endpoint) GetSecure() bool { + return getBoolOrDefault(in.Secure, false) +} + +func getBoolOrDefault(input *bool, defaultVal bool) bool { + if input != nil { + return *input + } + return defaultVal +} diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.parent_overrides.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.parent_overrides.go index d8579ac53..4886db49e 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.parent_overrides.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.parent_overrides.go @@ -142,7 +142,7 @@ type CommandParentOverride struct { // +union type ComponentUnionParentOverride struct { - // +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume;Plugin + // +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume;Image;Plugin // Type of component // // +unionDiscriminator @@ -172,6 +172,10 @@ type ComponentUnionParentOverride struct { // +optional Volume *VolumeComponentParentOverride `json:"volume,omitempty"` + // Allows specifying the definition of an image for outer loop builds + // +optional + Image *ImageComponentParentOverride `json:"image,omitempty"` + // Allows importing a plugin. // // Plugins are mainly imported devfiles that contribute components, commands @@ -262,6 +266,12 @@ type VolumeComponentParentOverride struct { VolumeParentOverride `json:",inline"` } +// Component that allows the developer to build a runtime image for outerloop +type ImageComponentParentOverride struct { + BaseComponentParentOverride `json:",inline"` + ImageParentOverride `json:",inline"` +} + type PluginComponentParentOverride struct { BaseComponentParentOverride `json:",inline"` ImportReferenceParentOverride `json:",inline"` @@ -330,7 +340,7 @@ type ExecCommandParentOverride struct { // If set to `true` the command won't be restarted and it is expected to handle file changes on its own. // // Default value is `false` - HotReloadCapable bool `json:"hotReloadCapable,omitempty"` + HotReloadCapable *bool `json:"hotReloadCapable,omitempty"` } type ApplyCommandParentOverride struct { @@ -350,7 +360,7 @@ type CompositeCommandParentOverride struct { // Indicates if the sub-commands should be executed concurrently // +optional - Parallel bool `json:"parallel,omitempty"` + Parallel *bool `json:"parallel,omitempty"` } // DevWorkspace component: Anything that will bring additional features / tooling / behaviour / context @@ -420,7 +430,7 @@ type ContainerParentOverride struct { // // Default value is `false` // +optional - DedicatedPod bool `json:"dedicatedPod,omitempty"` + DedicatedPod *bool `json:"dedicatedPod,omitempty"` } type EndpointParentOverride struct { @@ -471,7 +481,7 @@ type EndpointParentOverride struct { // Describes whether the endpoint should be secured and protected by some // authentication process. This requires a protocol of `https` or `wss`. // +optional - Secure bool `json:"secure,omitempty"` + Secure *bool `json:"secure,omitempty"` // Path of the endpoint URL // +optional @@ -507,7 +517,15 @@ type VolumeParentOverride struct { // +optional // Ephemeral volumes are not stored persistently across restarts. Defaults // to false - Ephemeral bool `json:"ephemeral,omitempty"` + Ephemeral *bool `json:"ephemeral,omitempty"` +} + +type ImageParentOverride struct { + + // +optional + // Name of the image for the resulting outerloop build + ImageName string `json:"imageName,omitempty"` + ImageUnionParentOverride `json:",inline"` } type ImportReferenceParentOverride struct { @@ -549,7 +567,7 @@ type GitLikeProjectSourceParentOverride struct { // +optional // The remotes map which should be initialized in the git project. - // Projects must have at least one remote configured while StarterProjects can only have at most one remote configured. + // Projects must have at least one remote configured while StarterProjects & Image Component's Git source can only have at most one remote configured. Remotes map[string]string `json:"remotes,omitempty"` } @@ -616,6 +634,21 @@ type K8sLikeComponentLocationParentOverride struct { Inlined string `json:"inlined,omitempty"` } +// +union +type ImageUnionParentOverride struct { + + // +kubebuilder:validation:Enum=Dockerfile + // Type of image + // + // +unionDiscriminator + // +optional + ImageType ImageTypeParentOverride `json:"imageType,omitempty"` + + // Allows specifying dockerfile type build + // +optional + Dockerfile *DockerfileImageParentOverride `json:"dockerfile,omitempty"` +} + // Location from where the an import reference is retrieved // +union type ImportReferenceUnionParentOverride struct { @@ -706,6 +739,17 @@ type BaseCommandParentOverride struct { // Only one of the following component type may be specified. type K8sLikeComponentLocationTypeParentOverride string +// ImageType describes the type of image. +// Only one of the following image type may be specified. +type ImageTypeParentOverride string + +// Dockerfile Image type to specify the outerloop build using a Dockerfile +type DockerfileImageParentOverride struct { + BaseImageParentOverride `json:",inline"` + DockerfileSrcParentOverride `json:",inline"` + DockerfileParentOverride `json:",inline"` +} + // ImportReferenceType describes the type of location // from where the referenced template structure should be retrieved. // Only one of the following parent locations may be specified. @@ -722,7 +766,7 @@ type KubernetesCustomResourceImportReferenceParentOverride struct { // +union type ComponentUnionPluginOverrideParentOverride struct { - // +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume + // +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume;Image // Type of component // // +unionDiscriminator @@ -751,6 +795,10 @@ type ComponentUnionPluginOverrideParentOverride struct { // shared by several other components // +optional Volume *VolumeComponentPluginOverrideParentOverride `json:"volume,omitempty"` + + // Allows specifying the definition of an image for outer loop builds + // +optional + Image *ImageComponentPluginOverrideParentOverride `json:"image,omitempty"` } // +union @@ -794,7 +842,51 @@ type CommandGroupParentOverride struct { // +optional // Identifies the default command for a given group kind - IsDefault bool `json:"isDefault,omitempty"` + IsDefault *bool `json:"isDefault,omitempty"` +} + +type BaseImageParentOverride struct { +} + +// +union +type DockerfileSrcParentOverride struct { + + // +kubebuilder:validation:Enum=Uri;DevfileRegistry;Git + // Type of Dockerfile src + // + + // +unionDiscriminator + // +optional + SrcType DockerfileSrcTypeParentOverride `json:"srcType,omitempty"` + + // URI Reference of a Dockerfile. + // It can be a full URL or a relative URI from the current devfile as the base URI. + // +optional + Uri string `json:"uri,omitempty"` + + // Dockerfile's Devfile Registry source + // +optional + DevfileRegistry *DockerfileDevfileRegistrySourceParentOverride `json:"devfileRegistry,omitempty"` + + // Dockerfile's Git source + // +optional + Git *DockerfileGitProjectSourceParentOverride `json:"git,omitempty"` +} + +type DockerfileParentOverride struct { + + // Path of source directory to establish build context. Defaults to ${PROJECT_ROOT} in the container + // +optional + BuildContext string `json:"buildContext,omitempty"` + + // The arguments to supply to the dockerfile build. + // +optional + Args []string `json:"args,omitempty" patchStrategy:"replace"` + + // Specify if a privileged builder pod is required. + // + // Default value is `false` + // +optional + RootRequired *bool `json:"rootRequired,omitempty"` } // ComponentType describes the type of component. @@ -824,6 +916,12 @@ type VolumeComponentPluginOverrideParentOverride struct { VolumePluginOverrideParentOverride `json:",inline"` } +// Component that allows the developer to build a runtime image for outerloop +type ImageComponentPluginOverrideParentOverride struct { + BaseComponentPluginOverrideParentOverride `json:",inline"` + ImagePluginOverrideParentOverride `json:",inline"` +} + // CommandType describes the type of command. // Only one of the following command type may be specified. type CommandTypePluginOverrideParentOverride string @@ -868,7 +966,7 @@ type ExecCommandPluginOverrideParentOverride struct { // If set to `true` the command won't be restarted and it is expected to handle file changes on its own. // // Default value is `false` - HotReloadCapable bool `json:"hotReloadCapable,omitempty"` + HotReloadCapable *bool `json:"hotReloadCapable,omitempty"` } type ApplyCommandPluginOverrideParentOverride struct { @@ -888,13 +986,44 @@ type CompositeCommandPluginOverrideParentOverride struct { // Indicates if the sub-commands should be executed concurrently // +optional - Parallel bool `json:"parallel,omitempty"` + Parallel *bool `json:"parallel,omitempty"` } // CommandGroupKind describes the kind of command group. -// +kubebuilder:validation:Enum=build;run;test;debug +// +kubebuilder:validation:Enum=build;run;test;debug;deploy type CommandGroupKindParentOverride string +// DockerfileSrcType describes the type of +// the src for the Dockerfile outerloop build. +// Only one of the following location type may be specified. +type DockerfileSrcTypeParentOverride string + +type DockerfileDevfileRegistrySourceParentOverride struct { + + // +optional + // Id in a devfile registry that contains a Dockerfile. The src in the OCI registry + // required for the Dockerfile build will be downloaded for building the image. + Id string `json:"id,omitempty"` + + // Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. + // To ensure the Dockerfile gets resolved consistently in different environments, + // it is recommended to always specify the `devfileRegistryUrl` when `Id` is used. + // +optional + RegistryUrl string `json:"registryUrl,omitempty"` +} + +type DockerfileGitProjectSourceParentOverride struct { + + // Git src for the Dockerfile build. The src required for the Dockerfile build will need to be + // cloned for building the image. + GitProjectSourceParentOverride `json:",inline"` + + // Location of the Dockerfile in the Git repository when using git as Dockerfile src. + // Defaults to Dockerfile. + // +optional + FileLocation string `json:"fileLocation,omitempty"` +} + // DevWorkspace component: Anything that will bring additional features / tooling / behaviour / context // to the devworkspace, in order to make working in it easier. type BaseComponentPluginOverrideParentOverride struct { @@ -963,7 +1092,7 @@ type ContainerPluginOverrideParentOverride struct { // // Default value is `false` // +optional - DedicatedPod bool `json:"dedicatedPod,omitempty"` + DedicatedPod *bool `json:"dedicatedPod,omitempty"` } type EndpointPluginOverrideParentOverride struct { @@ -1014,7 +1143,7 @@ type EndpointPluginOverrideParentOverride struct { // Describes whether the endpoint should be secured and protected by some // authentication process. This requires a protocol of `https` or `wss`. // +optional - Secure bool `json:"secure,omitempty"` + Secure *bool `json:"secure,omitempty"` // Path of the endpoint URL // +optional @@ -1050,7 +1179,15 @@ type VolumePluginOverrideParentOverride struct { // +optional // Ephemeral volumes are not stored persistently across restarts. Defaults // to false - Ephemeral bool `json:"ephemeral,omitempty"` + Ephemeral *bool `json:"ephemeral,omitempty"` +} + +type ImagePluginOverrideParentOverride struct { + + // +optional + // Name of the image for the resulting outerloop build + ImageName string `json:"imageName,omitempty"` + ImageUnionPluginOverrideParentOverride `json:",inline"` } type LabeledCommandPluginOverrideParentOverride struct { @@ -1114,6 +1251,21 @@ type K8sLikeComponentLocationPluginOverrideParentOverride struct { Inlined string `json:"inlined,omitempty"` } +// +union +type ImageUnionPluginOverrideParentOverride struct { + + // +kubebuilder:validation:Enum=Dockerfile + // Type of image + // + // +unionDiscriminator + // +optional + ImageType ImageTypePluginOverrideParentOverride `json:"imageType,omitempty"` + + // Allows specifying dockerfile type build + // +optional + Dockerfile *DockerfileImagePluginOverrideParentOverride `json:"dockerfile,omitempty"` +} + type BaseCommandPluginOverrideParentOverride struct { // +optional @@ -1126,6 +1278,17 @@ type BaseCommandPluginOverrideParentOverride struct { // Only one of the following component type may be specified. type K8sLikeComponentLocationTypePluginOverrideParentOverride string +// ImageType describes the type of image. +// Only one of the following image type may be specified. +type ImageTypePluginOverrideParentOverride string + +// Dockerfile Image type to specify the outerloop build using a Dockerfile +type DockerfileImagePluginOverrideParentOverride struct { + BaseImagePluginOverrideParentOverride `json:",inline"` + DockerfileSrcPluginOverrideParentOverride `json:",inline"` + DockerfilePluginOverrideParentOverride `json:",inline"` +} + type CommandGroupPluginOverrideParentOverride struct { // +optional @@ -1134,11 +1297,118 @@ type CommandGroupPluginOverrideParentOverride struct { // +optional // Identifies the default command for a given group kind - IsDefault bool `json:"isDefault,omitempty"` + IsDefault *bool `json:"isDefault,omitempty"` +} + +type BaseImagePluginOverrideParentOverride struct { +} + +// +union +type DockerfileSrcPluginOverrideParentOverride struct { + + // +kubebuilder:validation:Enum=Uri;DevfileRegistry;Git + // Type of Dockerfile src + // + + // +unionDiscriminator + // +optional + SrcType DockerfileSrcTypePluginOverrideParentOverride `json:"srcType,omitempty"` + + // URI Reference of a Dockerfile. + // It can be a full URL or a relative URI from the current devfile as the base URI. + // +optional + Uri string `json:"uri,omitempty"` + + // Dockerfile's Devfile Registry source + // +optional + DevfileRegistry *DockerfileDevfileRegistrySourcePluginOverrideParentOverride `json:"devfileRegistry,omitempty"` + + // Dockerfile's Git source + // +optional + Git *DockerfileGitProjectSourcePluginOverrideParentOverride `json:"git,omitempty"` +} + +type DockerfilePluginOverrideParentOverride struct { + + // Path of source directory to establish build context. Defaults to ${PROJECT_ROOT} in the container + // +optional + BuildContext string `json:"buildContext,omitempty"` + + // The arguments to supply to the dockerfile build. + // +optional + Args []string `json:"args,omitempty" patchStrategy:"replace"` + + // Specify if a privileged builder pod is required. + // + // Default value is `false` + // +optional + RootRequired *bool `json:"rootRequired,omitempty"` } // CommandGroupKind describes the kind of command group. -// +kubebuilder:validation:Enum=build;run;test;debug +// +kubebuilder:validation:Enum=build;run;test;debug;deploy type CommandGroupKindPluginOverrideParentOverride string +// DockerfileSrcType describes the type of +// the src for the Dockerfile outerloop build. +// Only one of the following location type may be specified. +type DockerfileSrcTypePluginOverrideParentOverride string + +type DockerfileDevfileRegistrySourcePluginOverrideParentOverride struct { + + // +optional + // Id in a devfile registry that contains a Dockerfile. The src in the OCI registry + // required for the Dockerfile build will be downloaded for building the image. + Id string `json:"id,omitempty"` + + // Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. + // To ensure the Dockerfile gets resolved consistently in different environments, + // it is recommended to always specify the `devfileRegistryUrl` when `Id` is used. + // +optional + RegistryUrl string `json:"registryUrl,omitempty"` +} + +type DockerfileGitProjectSourcePluginOverrideParentOverride struct { + + // Git src for the Dockerfile build. The src required for the Dockerfile build will need to be + // cloned for building the image. + GitProjectSourcePluginOverrideParentOverride `json:",inline"` + + // Location of the Dockerfile in the Git repository when using git as Dockerfile src. + // Defaults to Dockerfile. + // +optional + FileLocation string `json:"fileLocation,omitempty"` +} + +type GitProjectSourcePluginOverrideParentOverride struct { + GitLikeProjectSourcePluginOverrideParentOverride `json:",inline"` +} + +type GitLikeProjectSourcePluginOverrideParentOverride struct { + CommonProjectSourcePluginOverrideParentOverride `json:",inline"` + + // Defines from what the project should be checked out. Required if there are more than one remote configured + // +optional + CheckoutFrom *CheckoutFromPluginOverrideParentOverride `json:"checkoutFrom,omitempty"` + + // +optional + // The remotes map which should be initialized in the git project. + // Projects must have at least one remote configured while StarterProjects & Image Component's Git source can only have at most one remote configured. + Remotes map[string]string `json:"remotes,omitempty"` +} + +type CommonProjectSourcePluginOverrideParentOverride struct { +} + +type CheckoutFromPluginOverrideParentOverride struct { + + // The revision to checkout from. Should be branch name, tag or commit id. + // Default branch is used if missing or specified revision is not found. + // +optional + Revision string `json:"revision,omitempty"` + + // The remote name should be used as init. Required if there are more than one remote configured + // +optional + Remote string `json:"remote,omitempty"` +} + func (overrides ParentOverrides) isOverride() {} diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.plugin_overrides.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.plugin_overrides.go index 00efd4512..93ccf8102 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.plugin_overrides.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.plugin_overrides.go @@ -65,7 +65,7 @@ type CommandPluginOverride struct { // +union type ComponentUnionPluginOverride struct { - // +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume + // +kubebuilder:validation:Enum=Container;Kubernetes;Openshift;Volume;Image // Type of component // // +unionDiscriminator @@ -94,6 +94,10 @@ type ComponentUnionPluginOverride struct { // shared by several other components // +optional Volume *VolumeComponentPluginOverride `json:"volume,omitempty"` + + // Allows specifying the definition of an image for outer loop builds + // +optional + Image *ImageComponentPluginOverride `json:"image,omitempty"` } // +union @@ -156,6 +160,12 @@ type VolumeComponentPluginOverride struct { VolumePluginOverride `json:",inline"` } +// Component that allows the developer to build a runtime image for outerloop +type ImageComponentPluginOverride struct { + BaseComponentPluginOverride `json:",inline"` + ImagePluginOverride `json:",inline"` +} + // CommandType describes the type of command. // Only one of the following command type may be specified. type CommandTypePluginOverride string @@ -200,7 +210,7 @@ type ExecCommandPluginOverride struct { // If set to `true` the command won't be restarted and it is expected to handle file changes on its own. // // Default value is `false` - HotReloadCapable bool `json:"hotReloadCapable,omitempty"` + HotReloadCapable *bool `json:"hotReloadCapable,omitempty"` } type ApplyCommandPluginOverride struct { @@ -220,7 +230,7 @@ type CompositeCommandPluginOverride struct { // Indicates if the sub-commands should be executed concurrently // +optional - Parallel bool `json:"parallel,omitempty"` + Parallel *bool `json:"parallel,omitempty"` } // DevWorkspace component: Anything that will bring additional features / tooling / behaviour / context @@ -290,7 +300,7 @@ type ContainerPluginOverride struct { // // Default value is `false` // +optional - DedicatedPod bool `json:"dedicatedPod,omitempty"` + DedicatedPod *bool `json:"dedicatedPod,omitempty"` } type EndpointPluginOverride struct { @@ -341,7 +351,7 @@ type EndpointPluginOverride struct { // Describes whether the endpoint should be secured and protected by some // authentication process. This requires a protocol of `https` or `wss`. // +optional - Secure bool `json:"secure,omitempty"` + Secure *bool `json:"secure,omitempty"` // Path of the endpoint URL // +optional @@ -377,7 +387,15 @@ type VolumePluginOverride struct { // +optional // Ephemeral volumes are not stored persistently across restarts. Defaults // to false - Ephemeral bool `json:"ephemeral,omitempty"` + Ephemeral *bool `json:"ephemeral,omitempty"` +} + +type ImagePluginOverride struct { + + // +optional + // Name of the image for the resulting outerloop build + ImageName string `json:"imageName,omitempty"` + ImageUnionPluginOverride `json:",inline"` } type LabeledCommandPluginOverride struct { @@ -440,6 +458,21 @@ type K8sLikeComponentLocationPluginOverride struct { Inlined string `json:"inlined,omitempty"` } +// +union +type ImageUnionPluginOverride struct { + + // +kubebuilder:validation:Enum=Dockerfile + // Type of image + // + // +unionDiscriminator + // +optional + ImageType ImageTypePluginOverride `json:"imageType,omitempty"` + + // Allows specifying dockerfile type build + // +optional + Dockerfile *DockerfileImagePluginOverride `json:"dockerfile,omitempty"` +} + type BaseCommandPluginOverride struct { // +optional @@ -452,6 +485,17 @@ type BaseCommandPluginOverride struct { // Only one of the following component type may be specified. type K8sLikeComponentLocationTypePluginOverride string +// ImageType describes the type of image. +// Only one of the following image type may be specified. +type ImageTypePluginOverride string + +// Dockerfile Image type to specify the outerloop build using a Dockerfile +type DockerfileImagePluginOverride struct { + BaseImagePluginOverride `json:",inline"` + DockerfileSrcPluginOverride `json:",inline"` + DockerfilePluginOverride `json:",inline"` +} + type CommandGroupPluginOverride struct { // +optional @@ -460,11 +504,118 @@ type CommandGroupPluginOverride struct { // +optional // Identifies the default command for a given group kind - IsDefault bool `json:"isDefault,omitempty"` + IsDefault *bool `json:"isDefault,omitempty"` +} + +type BaseImagePluginOverride struct { +} + +// +union +type DockerfileSrcPluginOverride struct { + + // +kubebuilder:validation:Enum=Uri;DevfileRegistry;Git + // Type of Dockerfile src + // + + // +unionDiscriminator + // +optional + SrcType DockerfileSrcTypePluginOverride `json:"srcType,omitempty"` + + // URI Reference of a Dockerfile. + // It can be a full URL or a relative URI from the current devfile as the base URI. + // +optional + Uri string `json:"uri,omitempty"` + + // Dockerfile's Devfile Registry source + // +optional + DevfileRegistry *DockerfileDevfileRegistrySourcePluginOverride `json:"devfileRegistry,omitempty"` + + // Dockerfile's Git source + // +optional + Git *DockerfileGitProjectSourcePluginOverride `json:"git,omitempty"` +} + +type DockerfilePluginOverride struct { + + // Path of source directory to establish build context. Defaults to ${PROJECT_ROOT} in the container + // +optional + BuildContext string `json:"buildContext,omitempty"` + + // The arguments to supply to the dockerfile build. + // +optional + Args []string `json:"args,omitempty" patchStrategy:"replace"` + + // Specify if a privileged builder pod is required. + // + // Default value is `false` + // +optional + RootRequired *bool `json:"rootRequired,omitempty"` } // CommandGroupKind describes the kind of command group. -// +kubebuilder:validation:Enum=build;run;test;debug +// +kubebuilder:validation:Enum=build;run;test;debug;deploy type CommandGroupKindPluginOverride string +// DockerfileSrcType describes the type of +// the src for the Dockerfile outerloop build. +// Only one of the following location type may be specified. +type DockerfileSrcTypePluginOverride string + +type DockerfileDevfileRegistrySourcePluginOverride struct { + + // +optional + // Id in a devfile registry that contains a Dockerfile. The src in the OCI registry + // required for the Dockerfile build will be downloaded for building the image. + Id string `json:"id,omitempty"` + + // Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. + // To ensure the Dockerfile gets resolved consistently in different environments, + // it is recommended to always specify the `devfileRegistryUrl` when `Id` is used. + // +optional + RegistryUrl string `json:"registryUrl,omitempty"` +} + +type DockerfileGitProjectSourcePluginOverride struct { + + // Git src for the Dockerfile build. The src required for the Dockerfile build will need to be + // cloned for building the image. + GitProjectSourcePluginOverride `json:",inline"` + + // Location of the Dockerfile in the Git repository when using git as Dockerfile src. + // Defaults to Dockerfile. + // +optional + FileLocation string `json:"fileLocation,omitempty"` +} + +type GitProjectSourcePluginOverride struct { + GitLikeProjectSourcePluginOverride `json:",inline"` +} + +type GitLikeProjectSourcePluginOverride struct { + CommonProjectSourcePluginOverride `json:",inline"` + + // Defines from what the project should be checked out. Required if there are more than one remote configured + // +optional + CheckoutFrom *CheckoutFromPluginOverride `json:"checkoutFrom,omitempty"` + + // +optional + // The remotes map which should be initialized in the git project. + // Projects must have at least one remote configured while StarterProjects & Image Component's Git source can only have at most one remote configured. + Remotes map[string]string `json:"remotes,omitempty"` +} + +type CommonProjectSourcePluginOverride struct { +} + +type CheckoutFromPluginOverride struct { + + // The revision to checkout from. Should be branch name, tag or commit id. + // Default branch is used if missing or specified revision is not found. + // +optional + Revision string `json:"revision,omitempty"` + + // The remote name should be used as init. Required if there are more than one remote configured + // +optional + Remote string `json:"remote,omitempty"` +} + func (overrides PluginOverrides) isOverride() {} diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.union_definitions.go b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.union_definitions.go index 50116cb1b..3efd841ae 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.union_definitions.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/zz_generated.union_definitions.go @@ -27,6 +27,48 @@ type CommandUnionVisitor struct { Custom func(*CustomCommand) error } +var imageUnion reflect.Type = reflect.TypeOf(ImageUnionVisitor{}) + +func (union ImageUnion) Visit(visitor ImageUnionVisitor) error { + return visitUnion(union, visitor) +} +func (union *ImageUnion) discriminator() *string { + return (*string)(&union.ImageType) +} +func (union *ImageUnion) Normalize() error { + return normalizeUnion(union, imageUnion) +} +func (union *ImageUnion) Simplify() { + simplifyUnion(union, imageUnion) +} + +// +k8s:deepcopy-gen=false +type ImageUnionVisitor struct { + Dockerfile func(*DockerfileImage) error +} + +var dockerfileSrc reflect.Type = reflect.TypeOf(DockerfileSrcVisitor{}) + +func (union DockerfileSrc) Visit(visitor DockerfileSrcVisitor) error { + return visitUnion(union, visitor) +} +func (union *DockerfileSrc) discriminator() *string { + return (*string)(&union.SrcType) +} +func (union *DockerfileSrc) Normalize() error { + return normalizeUnion(union, dockerfileSrc) +} +func (union *DockerfileSrc) Simplify() { + simplifyUnion(union, dockerfileSrc) +} + +// +k8s:deepcopy-gen=false +type DockerfileSrcVisitor struct { + Uri func(string) error + DevfileRegistry func(*DockerfileDevfileRegistrySource) error + Git func(*DockerfileGitProjectSource) error +} + var k8sLikeComponentLocation reflect.Type = reflect.TypeOf(K8sLikeComponentLocationVisitor{}) func (union K8sLikeComponentLocation) Visit(visitor K8sLikeComponentLocationVisitor) error { @@ -69,6 +111,7 @@ type ComponentUnionVisitor struct { Kubernetes func(*KubernetesComponent) error Openshift func(*OpenshiftComponent) error Volume func(*VolumeComponent) error + Image func(*ImageComponent) error Plugin func(*PluginComponent) error Custom func(*CustomComponent) error } @@ -138,6 +181,7 @@ type ComponentUnionParentOverrideVisitor struct { Kubernetes func(*KubernetesComponentParentOverride) error Openshift func(*OpenshiftComponentParentOverride) error Volume func(*VolumeComponentParentOverride) error + Image func(*ImageComponentParentOverride) error Plugin func(*PluginComponentParentOverride) error } @@ -205,6 +249,26 @@ type K8sLikeComponentLocationParentOverrideVisitor struct { Inlined func(string) error } +var imageUnionParentOverride reflect.Type = reflect.TypeOf(ImageUnionParentOverrideVisitor{}) + +func (union ImageUnionParentOverride) Visit(visitor ImageUnionParentOverrideVisitor) error { + return visitUnion(union, visitor) +} +func (union *ImageUnionParentOverride) discriminator() *string { + return (*string)(&union.ImageType) +} +func (union *ImageUnionParentOverride) Normalize() error { + return normalizeUnion(union, imageUnionParentOverride) +} +func (union *ImageUnionParentOverride) Simplify() { + simplifyUnion(union, imageUnionParentOverride) +} + +// +k8s:deepcopy-gen=false +type ImageUnionParentOverrideVisitor struct { + Dockerfile func(*DockerfileImageParentOverride) error +} + var importReferenceUnionParentOverride reflect.Type = reflect.TypeOf(ImportReferenceUnionParentOverrideVisitor{}) func (union ImportReferenceUnionParentOverride) Visit(visitor ImportReferenceUnionParentOverrideVisitor) error { @@ -248,6 +312,7 @@ type ComponentUnionPluginOverrideParentOverrideVisitor struct { Kubernetes func(*KubernetesComponentPluginOverrideParentOverride) error Openshift func(*OpenshiftComponentPluginOverrideParentOverride) error Volume func(*VolumeComponentPluginOverrideParentOverride) error + Image func(*ImageComponentPluginOverrideParentOverride) error } var commandUnionPluginOverrideParentOverride reflect.Type = reflect.TypeOf(CommandUnionPluginOverrideParentOverrideVisitor{}) @@ -272,6 +337,28 @@ type CommandUnionPluginOverrideParentOverrideVisitor struct { Composite func(*CompositeCommandPluginOverrideParentOverride) error } +var dockerfileSrcParentOverride reflect.Type = reflect.TypeOf(DockerfileSrcParentOverrideVisitor{}) + +func (union DockerfileSrcParentOverride) Visit(visitor DockerfileSrcParentOverrideVisitor) error { + return visitUnion(union, visitor) +} +func (union *DockerfileSrcParentOverride) discriminator() *string { + return (*string)(&union.SrcType) +} +func (union *DockerfileSrcParentOverride) Normalize() error { + return normalizeUnion(union, dockerfileSrcParentOverride) +} +func (union *DockerfileSrcParentOverride) Simplify() { + simplifyUnion(union, dockerfileSrcParentOverride) +} + +// +k8s:deepcopy-gen=false +type DockerfileSrcParentOverrideVisitor struct { + Uri func(string) error + DevfileRegistry func(*DockerfileDevfileRegistrySourceParentOverride) error + Git func(*DockerfileGitProjectSourceParentOverride) error +} + var k8sLikeComponentLocationPluginOverrideParentOverride reflect.Type = reflect.TypeOf(K8sLikeComponentLocationPluginOverrideParentOverrideVisitor{}) func (union K8sLikeComponentLocationPluginOverrideParentOverride) Visit(visitor K8sLikeComponentLocationPluginOverrideParentOverrideVisitor) error { @@ -293,6 +380,48 @@ type K8sLikeComponentLocationPluginOverrideParentOverrideVisitor struct { Inlined func(string) error } +var imageUnionPluginOverrideParentOverride reflect.Type = reflect.TypeOf(ImageUnionPluginOverrideParentOverrideVisitor{}) + +func (union ImageUnionPluginOverrideParentOverride) Visit(visitor ImageUnionPluginOverrideParentOverrideVisitor) error { + return visitUnion(union, visitor) +} +func (union *ImageUnionPluginOverrideParentOverride) discriminator() *string { + return (*string)(&union.ImageType) +} +func (union *ImageUnionPluginOverrideParentOverride) Normalize() error { + return normalizeUnion(union, imageUnionPluginOverrideParentOverride) +} +func (union *ImageUnionPluginOverrideParentOverride) Simplify() { + simplifyUnion(union, imageUnionPluginOverrideParentOverride) +} + +// +k8s:deepcopy-gen=false +type ImageUnionPluginOverrideParentOverrideVisitor struct { + Dockerfile func(*DockerfileImagePluginOverrideParentOverride) error +} + +var dockerfileSrcPluginOverrideParentOverride reflect.Type = reflect.TypeOf(DockerfileSrcPluginOverrideParentOverrideVisitor{}) + +func (union DockerfileSrcPluginOverrideParentOverride) Visit(visitor DockerfileSrcPluginOverrideParentOverrideVisitor) error { + return visitUnion(union, visitor) +} +func (union *DockerfileSrcPluginOverrideParentOverride) discriminator() *string { + return (*string)(&union.SrcType) +} +func (union *DockerfileSrcPluginOverrideParentOverride) Normalize() error { + return normalizeUnion(union, dockerfileSrcPluginOverrideParentOverride) +} +func (union *DockerfileSrcPluginOverrideParentOverride) Simplify() { + simplifyUnion(union, dockerfileSrcPluginOverrideParentOverride) +} + +// +k8s:deepcopy-gen=false +type DockerfileSrcPluginOverrideParentOverrideVisitor struct { + Uri func(string) error + DevfileRegistry func(*DockerfileDevfileRegistrySourcePluginOverrideParentOverride) error + Git func(*DockerfileGitProjectSourcePluginOverrideParentOverride) error +} + var componentUnionPluginOverride reflect.Type = reflect.TypeOf(ComponentUnionPluginOverrideVisitor{}) func (union ComponentUnionPluginOverride) Visit(visitor ComponentUnionPluginOverrideVisitor) error { @@ -314,6 +443,7 @@ type ComponentUnionPluginOverrideVisitor struct { Kubernetes func(*KubernetesComponentPluginOverride) error Openshift func(*OpenshiftComponentPluginOverride) error Volume func(*VolumeComponentPluginOverride) error + Image func(*ImageComponentPluginOverride) error } var commandUnionPluginOverride reflect.Type = reflect.TypeOf(CommandUnionPluginOverrideVisitor{}) @@ -358,3 +488,45 @@ type K8sLikeComponentLocationPluginOverrideVisitor struct { Uri func(string) error Inlined func(string) error } + +var imageUnionPluginOverride reflect.Type = reflect.TypeOf(ImageUnionPluginOverrideVisitor{}) + +func (union ImageUnionPluginOverride) Visit(visitor ImageUnionPluginOverrideVisitor) error { + return visitUnion(union, visitor) +} +func (union *ImageUnionPluginOverride) discriminator() *string { + return (*string)(&union.ImageType) +} +func (union *ImageUnionPluginOverride) Normalize() error { + return normalizeUnion(union, imageUnionPluginOverride) +} +func (union *ImageUnionPluginOverride) Simplify() { + simplifyUnion(union, imageUnionPluginOverride) +} + +// +k8s:deepcopy-gen=false +type ImageUnionPluginOverrideVisitor struct { + Dockerfile func(*DockerfileImagePluginOverride) error +} + +var dockerfileSrcPluginOverride reflect.Type = reflect.TypeOf(DockerfileSrcPluginOverrideVisitor{}) + +func (union DockerfileSrcPluginOverride) Visit(visitor DockerfileSrcPluginOverrideVisitor) error { + return visitUnion(union, visitor) +} +func (union *DockerfileSrcPluginOverride) discriminator() *string { + return (*string)(&union.SrcType) +} +func (union *DockerfileSrcPluginOverride) Normalize() error { + return normalizeUnion(union, dockerfileSrcPluginOverride) +} +func (union *DockerfileSrcPluginOverride) Simplify() { + simplifyUnion(union, dockerfileSrcPluginOverride) +} + +// +k8s:deepcopy-gen=false +type DockerfileSrcPluginOverrideVisitor struct { + Uri func(string) error + DevfileRegistry func(*DockerfileDevfileRegistrySourcePluginOverride) error + Git func(*DockerfileGitProjectSourcePluginOverride) error +} diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/commands.go b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/commands.go index 567b5ddff..1ebf6d316 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/commands.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/commands.go @@ -67,7 +67,8 @@ func validateGroup(commands []v1alpha2.Command, groupKind v1alpha2.CommandGroupK var defaultCommands []v1alpha2.Command if len(commands) > 1 { for _, command := range commands { - if getGroup(command).IsDefault { + defaultVal := getGroup(command).IsDefault + if defaultVal != nil && *defaultVal { defaultCommandCount++ defaultCommands = append(defaultCommands, command) } @@ -127,13 +128,20 @@ func validateCommandComponent(command v1alpha2.Command, components []v1alpha2.Co commandComponent = command.Apply.Component } - // must map to a container component + // exec command must map to a container component + // apply command must map to a container/kubernetes/openshift/image component for _, component := range components { - if component.Container != nil && commandComponent == component.Name { - return nil + if commandComponent == component.Name { + if component.Container != nil { + return nil + } + if command.Apply != nil && (component.Image != nil || component.Kubernetes != nil || component.Openshift != nil) { + return nil + } + break } } - return &InvalidCommandError{commandId: command.Id, reason: "command does not map to a container component"} + return &InvalidCommandError{commandId: command.Id, reason: "command does not map to a valid component"} } // validateCompositeCommand checks that the specified composite command is valid. The command: diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/components.go b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/components.go index 8f0103b8e..10b3c89ad 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/components.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/components.go @@ -22,6 +22,7 @@ const ( // 2. makes sure the volume components are unique // 3. checks the URI specified in openshift components and kubernetes components are with valid format // 4. makes sure the component name is unique +// 5. makes sure the image dockerfile component git src has at most one remote func ValidateComponents(components []v1alpha2.Component) (returnedErr error) { processedVolumes := make(map[string]bool) @@ -100,6 +101,14 @@ func ValidateComponents(components []v1alpha2.Component) (returnedErr error) { returnedErr = multierror.Append(returnedErr, resolveErrorMessageWithImportAttributes(endpointErr, component.Attributes)) } } + case component.Image != nil: + var gitSource v1alpha2.GitLikeProjectSource + if component.Image.Dockerfile != nil && component.Image.Dockerfile.Git != nil { + gitSource = component.Image.Dockerfile.Git.GitLikeProjectSource + if err := validateSingleRemoteGitSrc("component", component.Name, gitSource); err != nil { + returnedErr = multierror.Append(returnedErr, resolveErrorMessageWithImportAttributes(err, component.Attributes)) + } + } case component.Plugin != nil: if component.Plugin.RegistryUrl != "" { err := ValidateURI(component.Plugin.RegistryUrl) diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/errors.go b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/errors.go index 7e71578dc..efb42a8c8 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/errors.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/errors.go @@ -2,6 +2,7 @@ package validation import ( "fmt" + "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" attributesAPI "github.com/devfile/api/v2/pkg/attributes" ) @@ -120,22 +121,24 @@ func (e *MissingProjectRemoteError) Error() string { return fmt.Sprintf("project %s should have at least one remote", e.projectName) } -//MissingStarterProjectRemoteError returns an error if the git remotes object under a starterProject is empty -type MissingStarterProjectRemoteError struct { - projectName string +//MissingRemoteError returns an error if the git remotes object is empty +type MissingRemoteError struct { + objectType string + objectName string } -func (e *MissingStarterProjectRemoteError) Error() string { - return fmt.Sprintf("starterProject %s should have at least one remote", e.projectName) +func (e *MissingRemoteError) Error() string { + return fmt.Sprintf("%s %s should have at least one remote", e.objectType, e.objectName) } -//MultipleStarterProjectRemoteError returns an error if multiple git remotes are specified. There can only be one remote. -type MultipleStarterProjectRemoteError struct { - projectName string +//MultipleRemoteError returns an error if multiple git remotes are specified. There can only be one remote. +type MultipleRemoteError struct { + objectType string + objectName string } -func (e *MultipleStarterProjectRemoteError) Error() string { - return fmt.Sprintf("starterProject %s should have one remote only", e.projectName) +func (e *MultipleRemoteError) Error() string { + return fmt.Sprintf("%s %s should have one remote only", e.objectType, e.objectName) } //MissingProjectCheckoutFromRemoteError returns an error if there are multiple git remotes but the checkoutFrom remote has not been specified @@ -149,12 +152,13 @@ func (e *MissingProjectCheckoutFromRemoteError) Error() string { //InvalidProjectCheckoutRemoteError returns an error if there is an unmatched, checkoutFrom remote specified type InvalidProjectCheckoutRemoteError struct { - projectName string + objectType string + objectName string checkoutRemote string } func (e *InvalidProjectCheckoutRemoteError) Error() string { - return fmt.Sprintf("unable to find the checkout remote %s in the remotes for project %s", e.checkoutRemote, e.projectName) + return fmt.Sprintf("unable to find the checkout remote %s in the remotes for %s %s", e.checkoutRemote, e.objectType, e.objectName) } // resolveErrorMessageWithImportAttributes returns an updated error message diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/projects.go b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/projects.go index 8fdd39bc3..4cbc875c0 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/projects.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/projects.go @@ -17,22 +17,8 @@ func ValidateStarterProjects(starterProjects []v1alpha2.StarterProject) (returne continue } - switch len(gitSource.Remotes) { - case 0: - - newErr := resolveErrorMessageWithImportAttributes(&MissingStarterProjectRemoteError{projectName: starterProject.Name}, starterProject.Attributes) - returnedErr = multierror.Append(returnedErr, newErr) - case 1: - if gitSource.CheckoutFrom != nil && gitSource.CheckoutFrom.Remote != "" { - err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, starterProject.Name) - if err != nil { - newErr := resolveErrorMessageWithImportAttributes(err, starterProject.Attributes) - returnedErr = multierror.Append(returnedErr, newErr) - } - } - default: // len(gitSource.Remotes) >= 2 - - newErr := resolveErrorMessageWithImportAttributes(&MultipleStarterProjectRemoteError{projectName: starterProject.Name}, starterProject.Attributes) + if starterProjectErr := validateSingleRemoteGitSrc("starterProject", starterProject.Name, gitSource); starterProjectErr != nil { + newErr := resolveErrorMessageWithImportAttributes(starterProjectErr, starterProject.Attributes) returnedErr = multierror.Append(returnedErr, newErr) } } @@ -58,7 +44,7 @@ func ValidateProjects(projects []v1alpha2.Project) (returnedErr error) { returnedErr = multierror.Append(returnedErr, newErr) case 1: if gitSource.CheckoutFrom != nil && gitSource.CheckoutFrom.Remote != "" { - if err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, project.Name); err != nil { + if err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, "project", project.Name); err != nil { newErr := resolveErrorMessageWithImportAttributes(err, project.Attributes) returnedErr = multierror.Append(returnedErr, newErr) } @@ -70,7 +56,7 @@ func ValidateProjects(projects []v1alpha2.Project) (returnedErr error) { returnedErr = multierror.Append(returnedErr, newErr) continue } - if err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, project.Name); err != nil { + if err := validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, "project", project.Name); err != nil { newErr := resolveErrorMessageWithImportAttributes(err, project.Attributes) returnedErr = multierror.Append(returnedErr, newErr) } @@ -81,12 +67,28 @@ func ValidateProjects(projects []v1alpha2.Project) (returnedErr error) { } // validateRemoteMap checks if the checkout remote is present in the project remote map -func validateRemoteMap(remotes map[string]string, checkoutRemote, projectName string) error { +func validateRemoteMap(remotes map[string]string, checkoutRemote, objectType, objectName string) error { if _, ok := remotes[checkoutRemote]; !ok { - return &InvalidProjectCheckoutRemoteError{projectName: projectName, checkoutRemote: checkoutRemote} + return &InvalidProjectCheckoutRemoteError{objectName: objectName, objectType: objectType, checkoutRemote: checkoutRemote} } return nil } + +// validateSingleRemoteGitSrc validates a git src for a single remote only +func validateSingleRemoteGitSrc(objectType, objectName string, gitSource v1alpha2.GitLikeProjectSource) (err error) { + switch len(gitSource.Remotes) { + case 0: + err = &MissingRemoteError{objectType: objectType, objectName: objectName} + case 1: + if gitSource.CheckoutFrom != nil && gitSource.CheckoutFrom.Remote != "" { + err = validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote, objectType, objectName) + } + default: // len(gitSource.Remotes) >= 2 + err = &MultipleRemoteError{objectType: objectType, objectName: objectName} + } + + return err +} diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/validation-rule.md b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/validation-rule.md index fd88efa69..e72d47bcf 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/validation-rule.md +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/validation-rule.md @@ -23,8 +23,9 @@ Since network is shared in the same pod, endpoint ports should be unique across - Should not reference itself via a subcommand - Should not indirectly reference itself via a subcommand which is a composite command - Should reference a valid devfile command -3. exec and apply command should: map to a valid container component -4. `{build, run, test, debug}`, each kind of group can only have one default command associated with it. If there are multiple commands of the same kind without a default, a warning will be displayed. +3. exec command should: map to a valid container component +4. apply command should: map to a valid container/kubernetes/openshift/image component +5. `{build, run, test, debug, deploy}`, each kind of group can only have one default command associated with it. If there are multiple commands of the same kind without a default, a warning will be displayed. ### Components: Common rules for all components types: @@ -41,6 +42,9 @@ Common rules for all components types: #### Kubernetes & Openshift component - URI needs to be in valid URI format +#### Image component +- A Dockerfile Image component's git source cannot have more than one remote defined. If checkout remote is mentioned, validate it against the remote configured map + ### Events: 1. preStart and postStop events can only be Apply commands @@ -60,7 +64,3 @@ Common rules for all components types: ### projects - if more than one remote is configured, a checkout remote is mandatory - if checkout remote is mentioned, validate it against the starter project remote configured map - -### Architectures - -Architectures list support the following values - `amd64`, `arm64`, `ppc64le`, `s390x`. These values are determined by the .manifests[].platform["architecture"] field from an image's manifests and manually selected. diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_command.go b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_command.go index 8e9c08679..eb51b230a 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_command.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_command.go @@ -41,31 +41,33 @@ func ValidateAndReplaceForCommands(variables map[string]string, commands []v1alp // validateAndReplaceForExecCommand validates the exec command data for global variable references and replaces them with the variable value func validateAndReplaceForExecCommand(variables map[string]string, exec *v1alpha2.ExecCommand) error { - var err error + if exec == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if exec != nil { - // Validate exec command line - if exec.CommandLine, err = validateAndReplaceDataWithVariable(exec.CommandLine, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate exec command line + if exec.CommandLine, err = validateAndReplaceDataWithVariable(exec.CommandLine, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate exec working dir - if exec.WorkingDir, err = validateAndReplaceDataWithVariable(exec.WorkingDir, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate exec working dir + if exec.WorkingDir, err = validateAndReplaceDataWithVariable(exec.WorkingDir, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate exec label - if exec.Label, err = validateAndReplaceDataWithVariable(exec.Label, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate exec label + if exec.Label, err = validateAndReplaceDataWithVariable(exec.Label, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate exec env - if len(exec.Env) > 0 { - if err = validateAndReplaceForEnv(variables, exec.Env); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate exec env + if len(exec.Env) > 0 { + if err = validateAndReplaceForEnv(variables, exec.Env); err != nil { + checkForInvalidError(invalidKeys, err) } } @@ -74,15 +76,17 @@ func validateAndReplaceForExecCommand(variables map[string]string, exec *v1alpha // validateAndReplaceForCompositeCommand validates the composite command data for global variable references and replaces them with the variable value func validateAndReplaceForCompositeCommand(variables map[string]string, composite *v1alpha2.CompositeCommand) error { - var err error + if composite == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if composite != nil { - // Validate composite label - if composite.Label, err = validateAndReplaceDataWithVariable(composite.Label, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate composite label + if composite.Label, err = validateAndReplaceDataWithVariable(composite.Label, variables); err != nil { + checkForInvalidError(invalidKeys, err) } return newInvalidKeysError(invalidKeys) @@ -90,15 +94,17 @@ func validateAndReplaceForCompositeCommand(variables map[string]string, composit // validateAndReplaceForApplyCommand validates the apply command data for global variable references and replaces them with the variable value func validateAndReplaceForApplyCommand(variables map[string]string, apply *v1alpha2.ApplyCommand) error { - var err error + if apply == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if apply != nil { - // Validate apply label - if apply.Label, err = validateAndReplaceDataWithVariable(apply.Label, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate apply label + if apply.Label, err = validateAndReplaceDataWithVariable(apply.Label, variables); err != nil { + checkForInvalidError(invalidKeys, err) } return newInvalidKeysError(invalidKeys) diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_component.go b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_component.go index ce5a3f1bc..a42aa2f17 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_component.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_component.go @@ -33,6 +33,12 @@ func ValidateAndReplaceForComponents(variables map[string]string, components []v componentsWarningMap[components[i].Name] = verr.Keys } } + case components[i].Image != nil: + if err = validateAndReplaceForImageComponent(variables, components[i].Image); err != nil { + if verr, ok := err.(*InvalidKeysError); ok { + componentsWarningMap[components[i].Name] = verr.Keys + } + } case components[i].Volume != nil: if err = validateAndReplaceForVolumeComponent(variables, components[i].Volume); err != nil { if verr, ok := err.(*InvalidKeysError); ok { @@ -47,64 +53,66 @@ func ValidateAndReplaceForComponents(variables map[string]string, components []v // validateAndReplaceForContainerComponent validates the container component data for global variable references and replaces them with the variable value func validateAndReplaceForContainerComponent(variables map[string]string, container *v1alpha2.ContainerComponent) error { - var err error + if container == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if container != nil { - // Validate container image - if container.Image, err = validateAndReplaceDataWithVariable(container.Image, variables); err != nil { + // Validate container image + if container.Image, err = validateAndReplaceDataWithVariable(container.Image, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + + // Validate container commands + for i := range container.Command { + if container.Command[i], err = validateAndReplaceDataWithVariable(container.Command[i], variables); err != nil { checkForInvalidError(invalidKeys, err) } + } - // Validate container commands - for i := range container.Command { - if container.Command[i], err = validateAndReplaceDataWithVariable(container.Command[i], variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate container args + for i := range container.Args { + if container.Args[i], err = validateAndReplaceDataWithVariable(container.Args[i], variables); err != nil { + checkForInvalidError(invalidKeys, err) } + } - // Validate container args - for i := range container.Args { - if container.Args[i], err = validateAndReplaceDataWithVariable(container.Args[i], variables); err != nil { - checkForInvalidError(invalidKeys, err) - } - } + // Validate memory limit + if container.MemoryLimit, err = validateAndReplaceDataWithVariable(container.MemoryLimit, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate memory limit - if container.MemoryLimit, err = validateAndReplaceDataWithVariable(container.MemoryLimit, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate memory request + if container.MemoryRequest, err = validateAndReplaceDataWithVariable(container.MemoryRequest, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate memory request - if container.MemoryRequest, err = validateAndReplaceDataWithVariable(container.MemoryRequest, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate source mapping + if container.SourceMapping, err = validateAndReplaceDataWithVariable(container.SourceMapping, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate source mapping - if container.SourceMapping, err = validateAndReplaceDataWithVariable(container.SourceMapping, variables); err != nil { + // Validate container env + if len(container.Env) > 0 { + if err = validateAndReplaceForEnv(variables, container.Env); err != nil { checkForInvalidError(invalidKeys, err) } + } - // Validate container env - if len(container.Env) > 0 { - if err = validateAndReplaceForEnv(variables, container.Env); err != nil { - checkForInvalidError(invalidKeys, err) - } - } - - // Validate container volume mounts - for i := range container.VolumeMounts { - if container.VolumeMounts[i].Path, err = validateAndReplaceDataWithVariable(container.VolumeMounts[i].Path, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate container volume mounts + for i := range container.VolumeMounts { + if container.VolumeMounts[i].Path, err = validateAndReplaceDataWithVariable(container.VolumeMounts[i].Path, variables); err != nil { + checkForInvalidError(invalidKeys, err) } + } - // Validate container endpoints - if len(container.Endpoints) > 0 { - if err = validateAndReplaceForEndpoint(variables, container.Endpoints); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate container endpoints + if len(container.Endpoints) > 0 { + if err = validateAndReplaceForEndpoint(variables, container.Endpoints); err != nil { + checkForInvalidError(invalidKeys, err) } } @@ -135,26 +143,28 @@ func validateAndReplaceForEnv(variables map[string]string, env []v1alpha2.EnvVar // validateAndReplaceForKubernetesComponent validates the kubernetes component data for global variable references and replaces them with the variable value func validateAndReplaceForKubernetesComponent(variables map[string]string, kubernetes *v1alpha2.KubernetesComponent) error { - var err error + if kubernetes == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if kubernetes != nil { - // Validate kubernetes uri - if kubernetes.Uri, err = validateAndReplaceDataWithVariable(kubernetes.Uri, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate kubernetes uri + if kubernetes.Uri, err = validateAndReplaceDataWithVariable(kubernetes.Uri, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate kubernetes inlined - if kubernetes.Inlined, err = validateAndReplaceDataWithVariable(kubernetes.Inlined, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate kubernetes inlined + if kubernetes.Inlined, err = validateAndReplaceDataWithVariable(kubernetes.Inlined, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } - // Validate kubernetes endpoints - if len(kubernetes.Endpoints) > 0 { - if err = validateAndReplaceForEndpoint(variables, kubernetes.Endpoints); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate kubernetes endpoints + if len(kubernetes.Endpoints) > 0 { + if err = validateAndReplaceForEndpoint(variables, kubernetes.Endpoints); err != nil { + checkForInvalidError(invalidKeys, err) } } @@ -163,26 +173,101 @@ func validateAndReplaceForKubernetesComponent(variables map[string]string, kuber // validateAndReplaceForOpenShiftComponent validates the openshift component data for global variable references and replaces them with the variable value func validateAndReplaceForOpenShiftComponent(variables map[string]string, openshift *v1alpha2.OpenshiftComponent) error { + + if openshift == nil { + return nil + } + var err error + invalidKeys := make(map[string]bool) + + // Validate openshift uri + if openshift.Uri, err = validateAndReplaceDataWithVariable(openshift.Uri, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + + // Validate openshift inlined + if openshift.Inlined, err = validateAndReplaceDataWithVariable(openshift.Inlined, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + + // Validate openshift endpoints + if len(openshift.Endpoints) > 0 { + if err = validateAndReplaceForEndpoint(variables, openshift.Endpoints); err != nil { + checkForInvalidError(invalidKeys, err) + } + } + + return newInvalidKeysError(invalidKeys) +} + +// validateAndReplaceForImageComponent validates the image component data for global variable references and replaces them with the variable value +func validateAndReplaceForImageComponent(variables map[string]string, image *v1alpha2.ImageComponent) error { + + if image == nil { + return nil + } + + var err error + invalidKeys := make(map[string]bool) + + // Validate image's image name + if image.ImageName, err = validateAndReplaceDataWithVariable(image.ImageName, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + + if err = validateAndReplaceForDockerfileImageComponent(variables, image.Dockerfile); err != nil { + checkForInvalidError(invalidKeys, err) + } + + return newInvalidKeysError(invalidKeys) +} + +// validateAndReplaceForDockerfileImageComponent validates the dockerfile image component data for global variable references and replaces them with the variable value +func validateAndReplaceForDockerfileImageComponent(variables map[string]string, dockerfileImage *v1alpha2.DockerfileImage) error { + if dockerfileImage == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if openshift != nil { - // Validate openshift uri - if openshift.Uri, err = validateAndReplaceDataWithVariable(openshift.Uri, variables); err != nil { + switch { + case dockerfileImage.Uri != "": + // Validate dockerfile image URI + if dockerfileImage.Uri, err = validateAndReplaceDataWithVariable(dockerfileImage.Uri, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + case dockerfileImage.Git != nil: + // Validate dockerfile Git location + if dockerfileImage.Git.FileLocation, err = validateAndReplaceDataWithVariable(dockerfileImage.Git.FileLocation, variables); err != nil { checkForInvalidError(invalidKeys, err) } - // Validate openshift inlined - if openshift.Inlined, err = validateAndReplaceDataWithVariable(openshift.Inlined, variables); err != nil { + gitProject := &dockerfileImage.Git.GitLikeProjectSource + if err = validateAndReplaceForGitProjectSource(variables, gitProject); err != nil { + checkForInvalidError(invalidKeys, err) + } + case dockerfileImage.DevfileRegistry != nil: + // Validate dockerfile devfile registry src + if dockerfileImage.DevfileRegistry.Id, err = validateAndReplaceDataWithVariable(dockerfileImage.DevfileRegistry.Id, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + if dockerfileImage.DevfileRegistry.RegistryUrl, err = validateAndReplaceDataWithVariable(dockerfileImage.DevfileRegistry.RegistryUrl, variables); err != nil { checkForInvalidError(invalidKeys, err) } + } - // Validate openshift endpoints - if len(openshift.Endpoints) > 0 { - if err = validateAndReplaceForEndpoint(variables, openshift.Endpoints); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate dockerfile image's build context + if dockerfileImage.BuildContext, err = validateAndReplaceDataWithVariable(dockerfileImage.BuildContext, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + + // Validate dockerfile image's args + for i := range dockerfileImage.Args { + if dockerfileImage.Args[i], err = validateAndReplaceDataWithVariable(dockerfileImage.Args[i], variables); err != nil { + checkForInvalidError(invalidKeys, err) } } @@ -191,15 +276,17 @@ func validateAndReplaceForOpenShiftComponent(variables map[string]string, opensh // validateAndReplaceForVolumeComponent validates the volume component data for global variable references and replaces them with the variable value func validateAndReplaceForVolumeComponent(variables map[string]string, volume *v1alpha2.VolumeComponent) error { - var err error + if volume == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if volume != nil { - // Validate volume size - if volume.Size, err = validateAndReplaceDataWithVariable(volume.Size, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } + // Validate volume size + if volume.Size, err = validateAndReplaceDataWithVariable(volume.Size, variables); err != nil { + checkForInvalidError(invalidKeys, err) } return newInvalidKeysError(invalidKeys) diff --git a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_project.go b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_project.go index 09d1cdab1..15afe4616 100644 --- a/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_project.go +++ b/index/server/vendor/github.com/devfile/api/v2/pkg/validation/variables/variables_project.go @@ -72,47 +72,65 @@ func ValidateAndReplaceForStarterProjects(variables map[string]string, starterPr // validateandReplaceForProjectSource validates a project source location for global variable references and replaces them with the variable value func validateandReplaceForProjectSource(variables map[string]string, projectSource *v1alpha2.ProjectSource) error { + if projectSource == nil { + return nil + } + var err error + invalidKeys := make(map[string]bool) + + switch { + case projectSource.Zip != nil: + if projectSource.Zip.Location, err = validateAndReplaceDataWithVariable(projectSource.Zip.Location, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + case projectSource.Git != nil: + gitProject := &projectSource.Git.GitLikeProjectSource + + if err = validateAndReplaceForGitProjectSource(variables, gitProject); err != nil { + checkForInvalidError(invalidKeys, err) + } + } + + return newInvalidKeysError(invalidKeys) +} + +// validateAndReplaceForGitProjectSource validates a project git src for global variable references and replaces them with the variable value +func validateAndReplaceForGitProjectSource(variables map[string]string, gitProject *v1alpha2.GitLikeProjectSource) error { + if gitProject == nil { + return nil + } + + var err error invalidKeys := make(map[string]bool) - if projectSource != nil { - switch { - case projectSource.Zip != nil: - if projectSource.Zip.Location, err = validateAndReplaceDataWithVariable(projectSource.Zip.Location, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } - case projectSource.Git != nil: - gitProject := &projectSource.Git.GitLikeProjectSource - - if gitProject.CheckoutFrom != nil { - // validate git checkout revision - if gitProject.CheckoutFrom.Revision, err = validateAndReplaceDataWithVariable(gitProject.CheckoutFrom.Revision, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } - - // // validate git checkout remote - if gitProject.CheckoutFrom.Remote, err = validateAndReplaceDataWithVariable(gitProject.CheckoutFrom.Remote, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } - } - - // validate git remotes - for k := range gitProject.Remotes { - // validate remote map value - if gitProject.Remotes[k], err = validateAndReplaceDataWithVariable(gitProject.Remotes[k], variables); err != nil { - checkForInvalidError(invalidKeys, err) - } - - // validate remote map key - var updatedKey string - if updatedKey, err = validateAndReplaceDataWithVariable(k, variables); err != nil { - checkForInvalidError(invalidKeys, err) - } else if updatedKey != k { - gitProject.Remotes[updatedKey] = gitProject.Remotes[k] - delete(gitProject.Remotes, k) - } - } + if gitProject.CheckoutFrom != nil { + // validate git checkout revision + if gitProject.CheckoutFrom.Revision, err = validateAndReplaceDataWithVariable(gitProject.CheckoutFrom.Revision, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + + // // validate git checkout remote + if gitProject.CheckoutFrom.Remote, err = validateAndReplaceDataWithVariable(gitProject.CheckoutFrom.Remote, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + } + + // validate git remotes + for k := range gitProject.Remotes { + // validate remote map value + if gitProject.Remotes[k], err = validateAndReplaceDataWithVariable(gitProject.Remotes[k], variables); err != nil { + checkForInvalidError(invalidKeys, err) + } + + // validate remote map key + var updatedKey string + if updatedKey, err = validateAndReplaceDataWithVariable(k, variables); err != nil { + checkForInvalidError(invalidKeys, err) + } else if updatedKey != k { + gitProject.Remotes[updatedKey] = gitProject.Remotes[k] + delete(gitProject.Remotes, k) } } diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/context/apiVersion.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/context/apiVersion.go index a6928a6e2..e07d706dc 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/context/apiVersion.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/context/apiVersion.go @@ -3,6 +3,7 @@ package parser import ( "encoding/json" "fmt" + "strings" "github.com/devfile/library/pkg/devfile/parser/data" "github.com/pkg/errors" @@ -38,7 +39,9 @@ func (d *DevfileCtx) SetDevfileAPIVersion() error { } // Successful - d.apiVersion = schemaVersion.(string) + // split by `-` and get the first substring as schema version, schemaVersion without `-` won't get affected + // e.g. 2.2.0-latest => 2.2.0, 2.2.0 => 2.2.0 + d.apiVersion = strings.Split(schemaVersion.(string), "-")[0] klog.V(4).Infof("devfile schemaVersion: '%s'", d.apiVersion) return nil } diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go index 0357afe3a..15c05b635 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go @@ -69,7 +69,8 @@ const JsonSchema220 = `{ "build", "run", "test", - "debug" + "debug", + "deploy" ] } }, @@ -116,7 +117,8 @@ const JsonSchema220 = `{ "build", "run", "test", - "debug" + "debug", + "deploy" ] } }, @@ -187,7 +189,8 @@ const JsonSchema220 = `{ "build", "run", "test", - "debug" + "debug", + "deploy" ] } }, @@ -246,6 +249,11 @@ const JsonSchema220 = `{ "required": [ "volume" ] + }, + { + "required": [ + "image" + ] } ], "properties": { @@ -407,6 +415,124 @@ const JsonSchema220 = `{ }, "additionalProperties": false }, + "image": { + "description": "Allows specifying the definition of an image for outer loop builds", + "type": "object", + "required": [ + "imageName" + ], + "oneOf": [ + { + "required": [ + "dockerfile" + ] + } + ], + "properties": { + "dockerfile": { + "description": "Allows specifying dockerfile type build", + "type": "object", + "oneOf": [ + { + "required": [ + "uri" + ] + }, + { + "required": [ + "devfileRegistry" + ] + }, + { + "required": [ + "git" + ] + } + ], + "properties": { + "args": { + "description": "The arguments to supply to the dockerfile build.", + "type": "array", + "items": { + "type": "string" + } + }, + "buildContext": { + "description": "Path of source directory to establish build context. Defaults to ${PROJECT_ROOT} in the container", + "type": "string" + }, + "devfileRegistry": { + "description": "Dockerfile's Devfile Registry source", + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "description": "Id in a devfile registry that contains a Dockerfile. The src in the OCI registry required for the Dockerfile build will be downloaded for building the image.", + "type": "string" + }, + "registryUrl": { + "description": "Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. To ensure the Dockerfile gets resolved consistently in different environments, it is recommended to always specify the 'devfileRegistryUrl' when 'Id' is used.", + "type": "string" + } + }, + "additionalProperties": false + }, + "git": { + "description": "Dockerfile's Git source", + "type": "object", + "required": [ + "remotes" + ], + "properties": { + "checkoutFrom": { + "description": "Defines from what the project should be checked out. Required if there are more than one remote configured", + "type": "object", + "properties": { + "remote": { + "description": "The remote name should be used as init. Required if there are more than one remote configured", + "type": "string" + }, + "revision": { + "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.", + "type": "string" + } + }, + "additionalProperties": false + }, + "fileLocation": { + "description": "Location of the Dockerfile in the Git repository when using git as Dockerfile src. Defaults to Dockerfile.", + "type": "string" + }, + "remotes": { + "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "rootRequired": { + "description": "Specify if a privileged builder pod is required.\n\nDefault value is 'false'", + "type": "boolean" + }, + "uri": { + "description": "URI Reference of a Dockerfile. It can be a full URL or a relative URI from the current devfile as the base URI.", + "type": "string" + } + }, + "additionalProperties": false + }, + "imageName": { + "description": "Name of the image for the resulting outerloop build", + "type": "string" + } + }, + "additionalProperties": false + }, "kubernetes": { "description": "Allows importing into the devworkspace the Kubernetes resources defined in a given manifest. For example this allows reusing the Kubernetes definitions used to deploy some runtime components in production.", "type": "object", @@ -789,7 +915,8 @@ const JsonSchema220 = `{ "build", "run", "test", - "debug" + "debug", + "deploy" ] } }, @@ -833,7 +960,8 @@ const JsonSchema220 = `{ "build", "run", "test", - "debug" + "debug", + "deploy" ] } }, @@ -896,7 +1024,8 @@ const JsonSchema220 = `{ "build", "run", "test", - "debug" + "debug", + "deploy" ] } }, @@ -955,6 +1084,11 @@ const JsonSchema220 = `{ "required": [ "volume" ] + }, + { + "required": [ + "image" + ] } ], "properties": { @@ -1108,6 +1242,115 @@ const JsonSchema220 = `{ }, "additionalProperties": false }, + "image": { + "description": "Allows specifying the definition of an image for outer loop builds", + "type": "object", + "oneOf": [ + { + "required": [ + "dockerfile" + ] + } + ], + "properties": { + "dockerfile": { + "description": "Allows specifying dockerfile type build", + "type": "object", + "oneOf": [ + { + "required": [ + "uri" + ] + }, + { + "required": [ + "devfileRegistry" + ] + }, + { + "required": [ + "git" + ] + } + ], + "properties": { + "args": { + "description": "The arguments to supply to the dockerfile build.", + "type": "array", + "items": { + "type": "string" + } + }, + "buildContext": { + "description": "Path of source directory to establish build context. Defaults to ${PROJECT_ROOT} in the container", + "type": "string" + }, + "devfileRegistry": { + "description": "Dockerfile's Devfile Registry source", + "type": "object", + "properties": { + "id": { + "description": "Id in a devfile registry that contains a Dockerfile. The src in the OCI registry required for the Dockerfile build will be downloaded for building the image.", + "type": "string" + }, + "registryUrl": { + "description": "Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. To ensure the Dockerfile gets resolved consistently in different environments, it is recommended to always specify the 'devfileRegistryUrl' when 'Id' is used.", + "type": "string" + } + }, + "additionalProperties": false + }, + "git": { + "description": "Dockerfile's Git source", + "type": "object", + "properties": { + "checkoutFrom": { + "description": "Defines from what the project should be checked out. Required if there are more than one remote configured", + "type": "object", + "properties": { + "remote": { + "description": "The remote name should be used as init. Required if there are more than one remote configured", + "type": "string" + }, + "revision": { + "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.", + "type": "string" + } + }, + "additionalProperties": false + }, + "fileLocation": { + "description": "Location of the Dockerfile in the Git repository when using git as Dockerfile src. Defaults to Dockerfile.", + "type": "string" + }, + "remotes": { + "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "rootRequired": { + "description": "Specify if a privileged builder pod is required.\n\nDefault value is 'false'", + "type": "boolean" + }, + "uri": { + "description": "URI Reference of a Dockerfile. It can be a full URL or a relative URI from the current devfile as the base URI.", + "type": "string" + } + }, + "additionalProperties": false + }, + "imageName": { + "description": "Name of the image for the resulting outerloop build", + "type": "string" + } + }, + "additionalProperties": false + }, "kubernetes": { "description": "Allows importing into the devworkspace the Kubernetes resources defined in a given manifest. For example this allows reusing the Kubernetes definitions used to deploy some runtime components in production.", "type": "object", @@ -1365,7 +1608,7 @@ const JsonSchema220 = `{ "additionalProperties": false }, "remotes": { - "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects can only have at most one remote configured.", + "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.", "type": "object", "additionalProperties": { "type": "string" @@ -1449,7 +1692,7 @@ const JsonSchema220 = `{ "additionalProperties": false }, "remotes": { - "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects can only have at most one remote configured.", + "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.", "type": "object", "additionalProperties": { "type": "string" @@ -1550,7 +1793,7 @@ const JsonSchema220 = `{ "additionalProperties": false }, "remotes": { - "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects can only have at most one remote configured.", + "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.", "type": "object", "additionalProperties": { "type": "string" @@ -1638,7 +1881,7 @@ const JsonSchema220 = `{ "additionalProperties": false }, "remotes": { - "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects can only have at most one remote configured.", + "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.", "type": "object", "additionalProperties": { "type": "string" diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/commands.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/commands.go index 0bb29a8ab..42a1b6a12 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/commands.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/commands.go @@ -55,13 +55,17 @@ func (d *DevfileV2) GetCommands(options common.DevfileOptions) ([]v1.Command, er func (d *DevfileV2) AddCommands(commands []v1.Command) error { var errorsList []string for _, command := range commands { + var err error for _, devfileCommand := range d.Commands { if command.Id == devfileCommand.Id { - errorsList = append(errorsList, (&common.FieldAlreadyExistError{Name: command.Id, Field: "command"}).Error()) - continue + err = &common.FieldAlreadyExistError{Name: command.Id, Field: "command"} + errorsList = append(errorsList, err.Error()) + break } } - d.Commands = append(d.Commands, command) + if err == nil { + d.Commands = append(d.Commands, command) + } } if len(errorsList) > 0 { return fmt.Errorf("errors while adding commands:\n%s", strings.Join(errorsList, "\n")) diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/common/component_helper.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/common/component_helper.go index dede54285..1a5ba3323 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/common/component_helper.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/common/component_helper.go @@ -29,6 +29,8 @@ func GetComponentType(component v1.Component) (v1.ComponentType, error) { return v1.KubernetesComponentType, nil case component.Openshift != nil: return v1.OpenshiftComponentType, nil + case component.Image != nil: + return v1.ImageComponentType, nil case component.Custom != nil: return v1.CustomComponentType, nil diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/components.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/components.go index acd62ec1f..13a905b65 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/components.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/v2/components.go @@ -79,13 +79,17 @@ func (d *DevfileV2) GetDevfileVolumeComponents(options common.DevfileOptions) ([ func (d *DevfileV2) AddComponents(components []v1.Component) error { var errorsList []string for _, component := range components { + var err error for _, devfileComponent := range d.Components { if component.Name == devfileComponent.Name { - errorsList = append(errorsList, (&common.FieldAlreadyExistError{Name: component.Name, Field: "component"}).Error()) - continue + err = &common.FieldAlreadyExistError{Name: component.Name, Field: "component"} + errorsList = append(errorsList, err.Error()) + break } } - d.Components = append(d.Components, component) + if err == nil { + d.Components = append(d.Components, component) + } } if len(errorsList) > 0 { return fmt.Errorf("errors while adding components:\n%s", strings.Join(errorsList, "\n")) diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/versions.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/versions.go index bec46aff9..e85a026e2 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/versions.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/data/versions.go @@ -44,5 +44,5 @@ func init() { devfileApiVersionToJSONSchema[APISchemaVersion210] = v210.JsonSchema210 devfileApiVersionToJSONSchema[APISchemaVersion220] = v220.JsonSchema220 // should use hightest v2 schema version since it is expected to be backward compatible with the same api version - devfileApiVersionToJSONSchema[APIVersionAlpha2] = v210.JsonSchema210 + devfileApiVersionToJSONSchema[APIVersionAlpha2] = v220.JsonSchema220 } diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/devfileobj.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/devfileobj.go index f7ee33e9e..65c669c8c 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/devfileobj.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/devfileobj.go @@ -7,7 +7,6 @@ import ( // Default filenames for create devfile const ( - OutputDevfileJsonPath = "devfile.json" OutputDevfileYamlPath = "devfile.yaml" ) diff --git a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/parse.go b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/parse.go index 8c9481596..e9a12aa2a 100644 --- a/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/parse.go +++ b/index/server/vendor/github.com/devfile/library/pkg/devfile/parser/parse.go @@ -110,7 +110,14 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) { flattenedDevfile = *args.FlattenedDevfile } - return populateAndParseDevfile(d, &resolutionContextTree{}, tool, flattenedDevfile) + d, err = populateAndParseDevfile(d, &resolutionContextTree{}, tool, flattenedDevfile) + + //set defaults only if we are flattening parent and parsing succeeded + if flattenedDevfile && err == nil { + setDefaults(d) + } + + return d, err } // resolverTools contains required structs and data for resolving remote components of a devfile (plugins and parents) @@ -428,3 +435,104 @@ func convertDevWorskapceTemplateToDevObj(dwTemplate v1.DevWorkspaceTemplate) (d return d, nil } + +//setDefaults sets the default values for nil boolean properties after the merging of devWorkspaceTemplateSpec is complete +func setDefaults(d DevfileObj) (err error) { + commands, err := d.Data.GetCommands(common.DevfileOptions{}) + + if err != nil { + return err + } + + //set defaults on the commands + var cmdGroup *v1.CommandGroup + for i := range commands { + command := commands[i] + cmdGroup = nil + + if command.Exec != nil { + exec := command.Exec + val := exec.GetHotReloadCapable() + exec.HotReloadCapable = &val + cmdGroup = exec.Group + + } else if command.Composite != nil { + composite := command.Composite + val := composite.GetParallel() + composite.Parallel = &val + cmdGroup = composite.Group + + } else if command.Apply != nil { + cmdGroup = command.Apply.Group + } + + if cmdGroup != nil { + setIsDefault(cmdGroup) + } + + } + + //set defaults on the components + + components, err := d.Data.GetComponents(common.DevfileOptions{}) + + if err != nil { + return err + } + + var endpoints []v1.Endpoint + for i := range components { + component := components[i] + endpoints = nil + + if component.Container != nil { + container := component.Container + val := container.GetDedicatedPod() + container.DedicatedPod = &val + + val = container.GetMountSources() + container.MountSources = &val + + endpoints = container.Endpoints + + } else if component.Kubernetes != nil { + endpoints = component.Kubernetes.Endpoints + + } else if component.Openshift != nil { + + endpoints = component.Openshift.Endpoints + + } else if component.Volume != nil { + volume := component.Volume + val := volume.GetEphemeral() + volume.Ephemeral = &val + + } else if component.Image != nil { + dockerImage := component.Image.Dockerfile + if dockerImage != nil { + val := dockerImage.GetRootRequired() + dockerImage.RootRequired = &val + } + } + + if endpoints != nil { + setEndpoints(endpoints) + } + } + + return nil +} + +///setIsDefault sets the default value of CommandGroup.IsDefault if nil +func setIsDefault(cmdGroup *v1.CommandGroup) { + val := cmdGroup.GetIsDefault() + cmdGroup.IsDefault = &val +} + +//setEndpoints sets the default value of Endpoint.Secure if nil +func setEndpoints(endpoints []v1.Endpoint) { + for i := range endpoints { + val := endpoints[i].GetSecure() + endpoints[i].Secure = &val + } +} diff --git a/index/server/vendor/github.com/devfile/registry-support/index/generator/LICENSE b/index/server/vendor/github.com/devfile/registry-support/index/generator/LICENSE index e48e09634..261eeb9e9 100644 --- a/index/server/vendor/github.com/devfile/registry-support/index/generator/LICENSE +++ b/index/server/vendor/github.com/devfile/registry-support/index/generator/LICENSE @@ -1,277 +1,201 @@ -Eclipse Public License - v 2.0 - - THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE - PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION - OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - - a) in the case of the initial Contributor, the initial content - Distributed under this Agreement, and - - b) in the case of each subsequent Contributor: - i) changes to the Program, and - ii) additions to the Program; - where such changes and/or additions to the Program originate from - and are Distributed by that particular Contributor. A Contribution - "originates" from a Contributor if it was added to the Program by - such Contributor itself or anyone acting on such Contributor's behalf. - Contributions do not include changes or additions to the Program that - are not Modified Works. - -"Contributor" means any person or entity that Distributes the Program. - -"Licensed Patents" mean patent claims licensable by a Contributor which -are necessarily infringed by the use or sale of its Contribution alone -or when combined with the Program. - -"Program" means the Contributions Distributed in accordance with this -Agreement. - -"Recipient" means anyone who receives the Program under this Agreement -or any Secondary License (as applicable), including Contributors. - -"Derivative Works" shall mean any work, whether in Source Code or other -form, that is based on (or derived from) the Program and for which the -editorial revisions, annotations, elaborations, or other modifications -represent, as a whole, an original work of authorship. - -"Modified Works" shall mean any work in Source Code or other form that -results from an addition to, deletion from, or modification of the -contents of the Program, including, for purposes of clarity any new file -in Source Code form that contains any contents of the Program. Modified -Works shall not include works that contain only declarations, -interfaces, types, classes, structures, or files of the Program solely -in each case in order to link to, bind by name, or subclass the Program -or Modified Works thereof. - -"Distribute" means the acts of a) distributing or b) making available -in any manner that enables the transfer of a copy. - -"Source Code" means the form of a Program preferred for making -modifications, including but not limited to software source code, -documentation source, and configuration files. - -"Secondary License" means either the GNU General Public License, -Version 2.0, or any later versions of that license, including any -exceptions or additional permissions as identified by the initial -Contributor. - -2. GRANT OF RIGHTS - - a) Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free copyright - license to reproduce, prepare Derivative Works of, publicly display, - publicly perform, Distribute and sublicense the Contribution of such - Contributor, if any, and such Derivative Works. - - b) Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free patent - license under Licensed Patents to make, use, sell, offer to sell, - import and otherwise transfer the Contribution of such Contributor, - if any, in Source Code or other form. This patent license shall - apply to the combination of the Contribution and the Program if, at - the time the Contribution is added by the Contributor, such addition - of the Contribution causes such combination to be covered by the - Licensed Patents. The patent license shall not apply to any other - combinations which include the Contribution. No hardware per se is - licensed hereunder. - - c) Recipient understands that although each Contributor grants the - licenses to its Contributions set forth herein, no assurances are - provided by any Contributor that the Program does not infringe the - patent or other intellectual property rights of any other entity. - Each Contributor disclaims any liability to Recipient for claims - brought by any other entity based on infringement of intellectual - property rights or otherwise. As a condition to exercising the - rights and licenses granted hereunder, each Recipient hereby - assumes sole responsibility to secure any other intellectual - property rights needed, if any. For example, if a third party - patent license is required to allow Recipient to Distribute the - Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - - d) Each Contributor represents that to its knowledge it has - sufficient copyright rights in its Contribution, if any, to grant - the copyright license set forth in this Agreement. - - e) Notwithstanding the terms of any Secondary License, no - Contributor makes additional grants to any Recipient (other than - those set forth in this Agreement) as a result of such Recipient's - receipt of the Program under the terms of a Secondary License - (if permitted under the terms of Section 3). - -3. REQUIREMENTS - -3.1 If a Contributor Distributes the Program in any form, then: - - a) the Program must also be made available as Source Code, in - accordance with section 3.2, and the Contributor must accompany - the Program with a statement that the Source Code for the Program - is available under this Agreement, and informs Recipients how to - obtain it in a reasonable manner on or through a medium customarily - used for software exchange; and - - b) the Contributor may Distribute the Program under a license - different than this Agreement, provided that such license: - i) effectively disclaims on behalf of all other Contributors all - warranties and conditions, express and implied, including - warranties or conditions of title and non-infringement, and - implied warranties or conditions of merchantability and fitness - for a particular purpose; - - ii) effectively excludes on behalf of all other Contributors all - liability for damages, including direct, indirect, special, - incidental and consequential damages, such as lost profits; - - iii) does not attempt to limit or alter the recipients' rights - in the Source Code under section 3.2; and - - iv) requires any subsequent distribution of the Program by any - party to be under a license that satisfies the requirements - of this section 3. - -3.2 When the Program is Distributed as Source Code: - - a) it must be made available under this Agreement, or if the - Program (i) is combined with other material in a separate file or - files made available under a Secondary License, and (ii) the initial - Contributor attached to the Source Code the notice described in - Exhibit A of this Agreement, then the Program may be made available - under the terms of such Secondary Licenses, and - - b) a copy of this Agreement must be included with each copy of - the Program. - -3.3 Contributors may not remove or alter any copyright, patent, -trademark, attribution notices, disclaimers of warranty, or limitations -of liability ("notices") contained within the Program from any copy of -the Program which they Distribute, provided that Contributors may add -their own appropriate notices. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain responsibilities -with respect to end users, business partners and the like. While this -license is intended to facilitate the commercial use of the Program, -the Contributor who includes the Program in a commercial product -offering should do so in a manner which does not create potential -liability for other Contributors. Therefore, if a Contributor includes -the Program in a commercial product offering, such Contributor -("Commercial Contributor") hereby agrees to defend and indemnify every -other Contributor ("Indemnified Contributor") against any losses, -damages and costs (collectively "Losses") arising from claims, lawsuits -and other legal actions brought by a third party against the Indemnified -Contributor to the extent caused by the acts or omissions of such -Commercial Contributor in connection with its distribution of the Program -in a commercial product offering. The obligations in this section do not -apply to any claims or Losses relating to any actual or alleged -intellectual property infringement. In order to qualify, an Indemnified -Contributor must: a) promptly notify the Commercial Contributor in -writing of such claim, and b) allow the Commercial Contributor to control, -and cooperate with the Commercial Contributor in, the defense and any -related settlement negotiations. The Indemnified Contributor may -participate in any such claim at its own expense. - -For example, a Contributor might include the Program in a commercial -product offering, Product X. That Contributor is then a Commercial -Contributor. If that Commercial Contributor then makes performance -claims, or offers warranties related to Product X, those performance -claims and warranties are such Commercial Contributor's responsibility -alone. Under this section, the Commercial Contributor would have to -defend claims against the other Contributors related to those performance -claims and warranties, and if a court requires any other Contributor to -pay any damages as a result, the Commercial Contributor must pay -those damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" -BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR -IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF -TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR -PURPOSE. Each Recipient is solely responsible for determining the -appropriateness of using and distributing the Program and assumes all -risks associated with its exercise of rights under this Agreement, -including but not limited to the risks and costs of program errors, -compliance with applicable laws, damage to or loss of data, programs -or equipment, and unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS -SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST -PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE -EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -7. GENERAL - -If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of -the remainder of the terms of this Agreement, and without further -action by the parties hereto, such provision shall be reformed to the -minimum extent necessary to make such provision valid and enforceable. - -If Recipient institutes patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the -Program itself (excluding combinations of the Program with other software -or hardware) infringes such Recipient's patent(s), then such Recipient's -rights granted under Section 2(b) shall terminate as of the date such -litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it -fails to comply with any of the material terms or conditions of this -Agreement and does not cure such failure in a reasonable period of -time after becoming aware of such noncompliance. If all Recipient's -rights under this Agreement terminate, Recipient agrees to cease use -and distribution of the Program as soon as reasonably practicable. -However, Recipient's obligations under this Agreement and any licenses -granted by Recipient relating to the Program shall continue and survive. - -Everyone is permitted to copy and distribute copies of this Agreement, -but in order to avoid inconsistency the Agreement is copyrighted and -may only be modified in the following manner. The Agreement Steward -reserves the right to publish new versions (including revisions) of -this Agreement from time to time. No one other than the Agreement -Steward has the right to modify this Agreement. The Eclipse Foundation -is the initial Agreement Steward. The Eclipse Foundation may assign the -responsibility to serve as the Agreement Steward to a suitable separate -entity. Each new version of the Agreement will be given a distinguishing -version number. The Program (including Contributions) may always be -Distributed subject to the version of the Agreement under which it was -received. In addition, after a new version of the Agreement is published, -Contributor may elect to Distribute the Program (including its -Contributions) under the new version. - -Except as expressly stated in Sections 2(a) and 2(b) above, Recipient -receives no rights or licenses to the intellectual property of any -Contributor under this Agreement, whether expressly, by implication, -estoppel or otherwise. All rights in the Program not expressly granted -under this Agreement are reserved. Nothing in this Agreement is intended -to be enforceable by any entity that is not a Contributor or Recipient. -No third-party beneficiary rights are created under this Agreement. - -Exhibit A - Form of Secondary Licenses Notice - -"This Source Code may also be made available under the following -Secondary Licenses when the conditions for such availability set forth -in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), -version(s), and exceptions or additional permissions here}." - - Simply including a copy of this Agreement, including this Exhibit A - is not sufficient to license the Source Code under Secondary Licenses. - - If it is not possible or desirable to put the notice in a particular - file, then You may include the notice in a location (such as a LICENSE - file in a relevant directory) where a recipient would be likely to - look for such a notice. - - You may add additional accurate notices of copyright ownership. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go b/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go index a64aaeb92..4f7a8b8d8 100644 --- a/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go +++ b/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go @@ -9,6 +9,7 @@ import ( "path/filepath" devfileParser "github.com/devfile/library/pkg/devfile" + "github.com/devfile/library/pkg/devfile/parser" "github.com/devfile/registry-support/index/generator/schema" "gopkg.in/yaml.v2" ) @@ -17,6 +18,7 @@ const ( devfile = "devfile.yaml" devfileHidden = ".devfile.yaml" extraDevfileEntries = "extraDevfileEntries.yaml" + stackYaml = "stack.yaml" ) // MissingArchError is an error if the architecture list is empty @@ -87,27 +89,76 @@ func validateIndexComponent(indexComponent schema.Schema, componentType schema.D if indexComponent.Name == "" { return fmt.Errorf("index component name is not initialized") } - if indexComponent.Links == nil { - return fmt.Errorf("index component links are empty") - } - if indexComponent.Resources == nil { - return fmt.Errorf("index component resources are empty") - } - if indexComponent.Provider == "" { - return &MissingProviderError{devfile: indexComponent.Name} - } - if indexComponent.SupportUrl == "" { - return &MissingSupportUrlError{devfile: indexComponent.Name} + if indexComponent.Versions == nil || len(indexComponent.Versions) == 0 { + return fmt.Errorf("index component versions list is empty") + } else { + defaultFound := false + for _, version := range indexComponent.Versions { + if version.Version == "" { + return fmt.Errorf("index component versions list contains an entry with no version specified") + } + if version.SchemaVersion == "" { + return fmt.Errorf("index component version %s: schema version is empty", version.Version) + } + if version.Links == nil || len(version.Links) == 0 { + return fmt.Errorf("index component version %s: links are empty", version.Version) + } + if version.Resources == nil || len(version.Resources) == 0 { + return fmt.Errorf("index component version %s: resources are empty", version.Version) + } + if version.Default { + if !defaultFound { + defaultFound = true + } else { + return fmt.Errorf("index component has multiple default versions") + } + } + } + if !defaultFound { + return fmt.Errorf("index component has no default version defined") + } } } else if componentType == schema.SampleDevfileType { - if indexComponent.Git == nil { - return fmt.Errorf("index component git is empty") - } - if len(indexComponent.Git.Remotes) > 1 { - return fmt.Errorf("index component has multiple remotes") + if indexComponent.Versions != nil && len(indexComponent.Versions) > 0 { + defaultFound := false + for _, version := range indexComponent.Versions { + if version.Version == "" { + return fmt.Errorf("index component versions list contains an entry with no version specified") + } + if version.SchemaVersion == "" { + return fmt.Errorf("index component version %s: schema version is empty", version.Version) + } + if version.Git == nil { + return fmt.Errorf("index component version %s: git is empty", version.Version) + } + if version.Default { + if !defaultFound { + defaultFound = true + } else { + return fmt.Errorf("index component has multiple default versions") + } + } + } + if !defaultFound { + return fmt.Errorf("index component has no default version defined") + } + } else { + if indexComponent.Git == nil { + return fmt.Errorf("index component git is empty") + } + if len(indexComponent.Git.Remotes) > 1 { + return fmt.Errorf("index component has multiple remotes") + } } } + // Fields to be validated for both stacks and samples + if indexComponent.Provider == "" { + return &MissingProviderError{devfile: indexComponent.Name} + } + if indexComponent.SupportUrl == "" { + return &MissingSupportUrlError{devfile: indexComponent.Name} + } if len(indexComponent.Architectures) == 0 { return &MissingArchError{devfile: indexComponent.Name} } @@ -123,78 +174,86 @@ func fileExists(filepath string) bool { return true } +func dirExists(dirpath string) error { + dir, err := os.Stat(dirpath) + if os.IsNotExist(err){ + return fmt.Errorf("path: %s does not exist: %w",dirpath, err) + } + if !dir.IsDir() { + return fmt.Errorf("%s is not a directory", dirpath) + } + return nil +} + func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, error) { + var index []schema.Schema stackDirPath := path.Join(registryDirPath, "stacks") stackDir, err := ioutil.ReadDir(stackDirPath) if err != nil { return nil, fmt.Errorf("failed to read stack directory %s: %v", stackDirPath, err) } - for _, devfileDir := range stackDir { - if !devfileDir.IsDir() { + for _, stackFolderDir := range stackDir { + if !stackFolderDir.IsDir() { continue } - - // Allow devfile.yaml or .devfile.yaml - devfilePath := filepath.Join(stackDirPath, devfileDir.Name(), devfile) - devfileHiddenPath := filepath.Join(stackDirPath, devfileDir.Name(), devfileHidden) - if fileExists(devfilePath) && fileExists(devfileHiddenPath) { - return nil, fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) - } - if fileExists(devfileHiddenPath) { - devfilePath = devfileHiddenPath - } - - if !force { - // Devfile validation - _, err := devfileParser.ParseAndValidate(devfilePath) + stackFolderPath := filepath.Join(stackDirPath, stackFolderDir.Name()) + stackYamlPath := filepath.Join(stackFolderPath, stackYaml) + // if stack.yaml exist, parse stack.yaml + var indexComponent schema.Schema + if fileExists(stackYamlPath) { + indexComponent, err = parseStackInfo(stackYamlPath) if err != nil { - return nil, fmt.Errorf("%s devfile is not valid: %v", devfileDir.Name(), err) + return nil, err + } + if !force { + stackYamlErrors := validateStackInfo(indexComponent, stackFolderPath) + if stackYamlErrors != nil { + return nil, fmt.Errorf("%s stack.yaml is not valid: %v", stackFolderDir.Name(), stackYamlErrors) + } } - } - - bytes, err := ioutil.ReadFile(devfilePath) - if err != nil { - return nil, fmt.Errorf("failed to read %s: %v", devfilePath, err) - } - var devfile schema.Devfile - err = yaml.Unmarshal(bytes, &devfile) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) - } - indexComponent := devfile.Meta - if indexComponent.Links == nil { - indexComponent.Links = make(map[string]string) - } - indexComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", indexComponent.Name, "latest") - indexComponent.Type = schema.StackDevfileType - for _, starterProject := range devfile.StarterProjects { - indexComponent.StarterProjects = append(indexComponent.StarterProjects, starterProject.Name) - } + i:= 0 + for i < len(indexComponent.Versions) { + versionComponent := indexComponent.Versions[i] + if versionComponent.Git != nil { + // Todo: implement Git reference support, get stack content from remote repository and store in OCI registry + fmt.Printf("stack: %v, version:%v, Git reference is currently not supported", stackFolderDir.Name(), versionComponent.Version) + indexComponent.Versions = append(indexComponent.Versions[:i], indexComponent.Versions[i+1:]...) + continue + } + stackVersonDirPath := filepath.Join(stackFolderPath, versionComponent.Version) - // Get the files in the stack folder - stackFolder := filepath.Join(stackDirPath, devfileDir.Name()) - stackFiles, err := ioutil.ReadDir(stackFolder) - for _, stackFile := range stackFiles { - // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file - // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. - if !stackFile.IsDir() { - indexComponent.Resources = append(indexComponent.Resources, stackFile.Name()) + err := parseStackDevfile(stackVersonDirPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) + if err != nil { + return nil, err + } + indexComponent.Versions[i] = versionComponent + i++ + } + } else { // if stack.yaml not exist, old stack repo struct, directly lookfor & parse devfile.yaml + versionComponent := schema.Version{} + err := parseStackDevfile(stackFolderPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) + if err != nil { + return nil, err } + versionComponent.Default = true + indexComponent.Versions = append(indexComponent.Versions, versionComponent) } + indexComponent.Type = schema.StackDevfileType if !force { // Index component validation err := validateIndexComponent(indexComponent, schema.StackDevfileType) switch err.(type) { - case *MissingProviderError: - case *MissingSupportUrlError: - case *MissingArchError: - // log to the console as FYI if the devfile has no architectures/provider/supportUrl - fmt.Printf("%s", err.Error()) - default: - return nil, fmt.Errorf("%s index component is not valid: %v", devfileDir.Name(), err) + case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: + // log to the console as FYI if the devfile has no architectures/provider/supportUrl + fmt.Printf("%s", err.Error()) + default: + // only return error if we dont want to print + if err != nil { + return nil, fmt.Errorf("%s index component is not valid: %v", stackFolderDir.Name(), err) + } } } @@ -204,6 +263,119 @@ func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, return index, nil } +func parseStackDevfile(devfileDirPath string, stackName string, force bool, versionComponent *schema.Version, indexComponent *schema.Schema) error { + // Allow devfile.yaml or .devfile.yaml + devfilePath := filepath.Join(devfileDirPath, devfile) + devfileHiddenPath := filepath.Join(devfileDirPath, devfileHidden) + if fileExists(devfilePath) && fileExists(devfileHiddenPath) { + return fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) + } + if fileExists(devfileHiddenPath) { + devfilePath = devfileHiddenPath + } + + if !force { + // Devfile validation + devfileObj,_, err := devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) + if err != nil { + return fmt.Errorf("%s devfile is not valid: %v", devfileDirPath, err) + } + + metadataErrors := checkForRequiredMetadata(devfileObj) + if metadataErrors != nil { + return fmt.Errorf("%s devfile is not valid: %v", devfileDirPath, metadataErrors) + } + } + + bytes, err := ioutil.ReadFile(devfilePath) + if err != nil { + return fmt.Errorf("failed to read %s: %v", devfilePath, err) + } + + + var devfile schema.Devfile + err = yaml.Unmarshal(bytes, &devfile) + if err != nil { + return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + } + metaBytes, err := yaml.Marshal(devfile.Meta) + if err != nil { + return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + } + var versionProp schema.Version + err = yaml.Unmarshal(metaBytes, &versionProp) + if err != nil { + return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + } + + // set common properties if not set + if indexComponent.ProjectType == "" { + indexComponent.ProjectType = devfile.Meta.ProjectType + } + if indexComponent.Language == "" { + indexComponent.Language = devfile.Meta.Language + } + if indexComponent.Provider == "" { + indexComponent.Provider = devfile.Meta.Provider + } + if indexComponent.SupportUrl == "" { + indexComponent.SupportUrl = devfile.Meta.SupportUrl + } + + // for single version stack with only devfile.yaml, without stack.yaml + // set the top-level properties for this stack + if indexComponent.Name == "" { + indexComponent.Name = devfile.Meta.Name + } + if indexComponent.DisplayName == "" { + indexComponent.DisplayName = devfile.Meta.DisplayName + } + if indexComponent.Description == "" { + indexComponent.Description = devfile.Meta.Description + } + if indexComponent.Icon == "" { + indexComponent.Icon = devfile.Meta.Icon + } + + versionProp.Default = versionComponent.Default + *versionComponent = versionProp + if versionComponent.Links == nil { + versionComponent.Links = make(map[string]string) + } + versionComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", stackName, versionComponent.Version) + versionComponent.SchemaVersion = devfile.SchemaVersion + + for _, starterProject := range devfile.StarterProjects { + versionComponent.StarterProjects = append(versionComponent.StarterProjects, starterProject.Name) + } + + for _, tag := range versionComponent.Tags { + if !inArray(indexComponent.Tags, tag) { + indexComponent.Tags = append(indexComponent.Tags, tag) + } + } + + for _, arch := range versionComponent.Architectures { + if !inArray(indexComponent.Architectures, arch) { + indexComponent.Architectures = append(indexComponent.Architectures, arch) + } + } + + // Get the files in the stack folder + stackFiles, err := ioutil.ReadDir(devfileDirPath) + if err != nil { + return err + } + for _, stackFile := range stackFiles { + // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file + // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. + if !stackFile.IsDir() { + versionComponent.Resources = append(versionComponent.Resources, stackFile.Name()) + } + } + return nil +} + func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Schema, error) { var index []schema.Schema extraDevfileEntriesPath := path.Join(registryDirPath, extraDevfileEntries) @@ -236,34 +408,52 @@ func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Sche indexComponent := devfileEntry indexComponent.Type = devfileType if !force { - // If sample, validate devfile associated with sample as well // Can't handle during registry build since we don't have access to devfile library/parser if indexComponent.Type == schema.SampleDevfileType && validateSamples { - devfilePath := filepath.Join(samplesDir, devfileEntry.Name, "devfile.yaml") - _, err := os.Stat(filepath.Join(devfilePath)) - if err != nil { - // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless - return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) - } - - // Validate the sample devfile - _, err = devfileParser.ParseAndValidate(devfilePath) - if err != nil { - return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) + if indexComponent.Versions != nil && len(indexComponent.Versions) > 0 { + for _, version := range indexComponent.Versions{ + sampleVersonDirPath := filepath.Join(samplesDir, devfileEntry.Name, version.Version) + devfilePath := filepath.Join(sampleVersonDirPath, "devfile.yaml") + _, err := os.Stat(filepath.Join(devfilePath)) + if err != nil { + // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless + return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) + } + + // Validate the sample devfile + _, _, err = devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) + if err != nil { + return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) + } + } + } else { + devfilePath := filepath.Join(samplesDir, devfileEntry.Name, "devfile.yaml") + _, err := os.Stat(filepath.Join(devfilePath)) + if err != nil { + // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless + return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) + } + + // Validate the sample devfile + _, _, err = devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) + if err != nil { + return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) + } } } // Index component validation err := validateIndexComponent(indexComponent, devfileType) switch err.(type) { - case *MissingProviderError: - case *MissingSupportUrlError: - case *MissingArchError: - // log to the console as FYI if the devfile has no architectures/provider/supportUrl - fmt.Printf("%s", err.Error()) - default: + case *MissingProviderError, *MissingSupportUrlError, *MissingArchError: + // log to the console as FYI if the devfile has no architectures/provider/supportUrl + fmt.Printf("%s", err.Error()) + default: + // only return error if we dont want to print + if err != nil { return nil, fmt.Errorf("%s index component is not valid: %v", indexComponent.Name, err) + } } } index = append(index, indexComponent) @@ -272,3 +462,88 @@ func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Sche return index, nil } + +func parseStackInfo(stackYamlPath string) (schema.Schema, error) { + var index schema.Schema + bytes, err := ioutil.ReadFile(stackYamlPath) + if err != nil { + return schema.Schema{}, fmt.Errorf("failed to read %s: %v", stackYamlPath, err) + } + err = yaml.Unmarshal(bytes, &index) + if err != nil { + return schema.Schema{}, fmt.Errorf("failed to unmarshal %s data: %v", stackYamlPath, err) + } + return index, nil +} + +// checkForRequiredMetadata validates that a given devfile has the necessary metadata fields +func checkForRequiredMetadata(devfileObj parser.DevfileObj) []error { + devfileMetadata := devfileObj.Data.GetMetadata() + var metadataErrors []error + + if devfileMetadata.Name == "" { + metadataErrors = append(metadataErrors, fmt.Errorf("metadata.name is not set")) + } + if devfileMetadata.DisplayName == "" { + metadataErrors = append(metadataErrors, fmt.Errorf("metadata.displayName is not set")) + } + if devfileMetadata.Language == "" { + metadataErrors = append(metadataErrors, fmt.Errorf("metadata.language is not set")) + } + if devfileMetadata.ProjectType == "" { + metadataErrors = append(metadataErrors, fmt.Errorf("metadata.projectType is not set")) + } + + return metadataErrors +} + +func validateStackInfo (stackInfo schema.Schema, stackfolderDir string) []error { + var errors []error + + if stackInfo.Name == "" { + errors = append(errors, fmt.Errorf("name is not set in stack.yaml")) + } + if stackInfo.DisplayName == "" { + errors = append(errors, fmt.Errorf("displayName is not set stack.yaml")) + } + if stackInfo.Icon == "" { + errors = append(errors, fmt.Errorf("icon is not set stack.yaml")) + } + if stackInfo.Versions == nil || len(stackInfo.Versions) == 0 { + errors = append(errors, fmt.Errorf("versions list is not set stack.yaml, or is empty")) + } + hasDefault := false + for _, version := range stackInfo.Versions { + if version.Default { + if !hasDefault { + hasDefault = true + } else { + errors = append(errors, fmt.Errorf("stack.yaml has multiple default versions")) + } + } + + if version.Git == nil { + versionFolder := path.Join(stackfolderDir, version.Version) + err := dirExists(versionFolder) + if err != nil { + errors = append(errors, fmt.Errorf("cannot find resorce folder for version %s defined in stack.yaml: %v", version.Version, err)) + } + } + } + if !hasDefault { + errors = append(errors, fmt.Errorf("stack.yaml does not contain a default version")) + } + + return errors +} + + +// In checks if the value is in the array +func inArray(arr []string, value string) bool { + for _, item := range arr { + if item == value { + return true + } + } + return false +} \ No newline at end of file diff --git a/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go b/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go index adeb72a72..99a56d5d6 100644 --- a/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go +++ b/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go @@ -90,6 +90,7 @@ type Schema struct { Git *Git `yaml:"git,omitempty" json:"git,omitempty"` Provider string `yaml:"provider,omitempty" json:"provider,omitempty"` SupportUrl string `yaml:"supportUrl,omitempty" json:"supportUrl,omitempty"` + Versions []Version `yaml:"versions,omitempty" json:"versions,omitempty"` } // DevfileType describes the type of devfile @@ -112,11 +113,16 @@ type StarterProject struct { type Devfile struct { Meta Schema `yaml:"metadata,omitempty" json:"metadata,omitempty"` StarterProjects []StarterProject `yaml:"starterProjects,omitempty" json:"starterProjects,omitempty"` + SchemaVersion string `yaml:"schemaVersion,omitempty" json:"schemaVersion,omitempty"` } // Git stores the information of remote repositories type Git struct { - Remotes map[string]string `yaml:"remotes,omitempty" json:"remotes,omitempty"` + Remotes map[string]string `yaml:"remotes,omitempty" json:"remotes,omitempty"` + Url string `yaml:"url,omitempty" json:"url,omitempty"` + RemoteName string `yaml:"remoteName,omitempty" json:"remoteName,omitempty"` + SubDir string `yaml:"subDir,omitempty" json:"subDir,omitempty"` + Revision string `yaml:"revision,omitempty" json:"revision,omitempty"` } // ExtraDevfileEntries is the extraDevfileEntries structure that is used by index component @@ -124,3 +130,25 @@ type ExtraDevfileEntries struct { Samples []Schema `yaml:"samples,omitempty" json:"samples,omitempty"` Stacks []Schema `yaml:"stacks,omitempty" json:"stacks,omitempty"` } + +type StackInfo struct { + Name string `yaml:"name,omitempty" json:"name,omitempty"` + DisplayName string `yaml:"displayName,omitempty" json:"displayName,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` + Versions []Version `yaml:"versions,omitempty" json:"versions,omitempty"` +} + +type Version struct { + Version string `yaml:"version,omitempty" json:"version,omitempty"` + SchemaVersion string `yaml:"schemaVersion,omitempty" json:"schemaVersion,omitempty"` + Default bool `yaml:"default,omitempty" json:"default,omitempty"` + Git *Git `yaml:"git,omitempty" json:"git,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"` + Architectures []string `yaml:"architectures,omitempty" json:"architectures,omitempty"` + Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` + Links map[string]string `yaml:"links,omitempty" json:"links,omitempty"` + Resources []string `yaml:"resources,omitempty" json:"resources,omitempty"` + StarterProjects []string `yaml:"starterProjects,omitempty" json:"starterProjects,omitempty"` +} \ No newline at end of file diff --git a/index/server/vendor/modules.txt b/index/server/vendor/modules.txt index 838648e13..b2a74e490 100644 --- a/index/server/vendor/modules.txt +++ b/index/server/vendor/modules.txt @@ -50,7 +50,7 @@ github.com/davecgh/go-spew/spew github.com/deislabs/oras/pkg/artifact github.com/deislabs/oras/pkg/content github.com/deislabs/oras/pkg/oras -# github.com/devfile/api/v2 v2.0.0-20210910153124-da620cd1a7a1 +# github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed ## explicit github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2 github.com/devfile/api/v2/pkg/attributes @@ -59,7 +59,7 @@ github.com/devfile/api/v2/pkg/utils/overriding github.com/devfile/api/v2/pkg/utils/unions github.com/devfile/api/v2/pkg/validation github.com/devfile/api/v2/pkg/validation/variables -# github.com/devfile/library v1.1.1-0.20210910214722-7c5ff63711ec +# github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f github.com/devfile/library/pkg/devfile github.com/devfile/library/pkg/devfile/parser github.com/devfile/library/pkg/devfile/parser/context @@ -72,7 +72,7 @@ github.com/devfile/library/pkg/devfile/parser/data/v2/common github.com/devfile/library/pkg/devfile/validate github.com/devfile/library/pkg/testingutil/filesystem github.com/devfile/library/pkg/util -# github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0 +# github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0 => github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee ## explicit github.com/devfile/registry-support/index/generator/library github.com/devfile/registry-support/index/generator/schema @@ -444,3 +444,4 @@ sigs.k8s.io/controller-runtime/pkg/scheme sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml +# github.com/devfile/registry-support/index/generator => github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee From 8f9a064b8df8b80dbea447d9f81fb7500548f2d0 Mon Sep 17 00:00:00 2001 From: Stephanie Date: Tue, 22 Feb 2022 14:51:03 -0500 Subject: [PATCH 6/9] fix script bug Signed-off-by: Stephanie --- build-tools/build.sh | 4 ++-- build-tools/cache_samples.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build-tools/build.sh b/build-tools/build.sh index 43c164098..16ff6a309 100755 --- a/build-tools/build.sh +++ b/build-tools/build.sh @@ -66,11 +66,11 @@ build_registry() { cd "$OLDPWD" # Generate the tar archive - for stackDir in $outputFolder/stacks/*/ + for stackDir in $outputFolder/stacks/* do cd $stackDir if [[ -f "stack.yaml" ]]; then - for versionDir in $stackDir/*/ + for versionDir in $stackDir/* do cd $versionDir tar_files_and_cleanup diff --git a/build-tools/cache_samples.sh b/build-tools/cache_samples.sh index 47c132c2f..ee057b103 100755 --- a/build-tools/cache_samples.sh +++ b/build-tools/cache_samples.sh @@ -19,8 +19,8 @@ function cache_sample() { # Git clone the sample project gitRepository="$(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.git.remotes.origin)' -)" if [[ $gitRepository == "null" ]]; then - for version in $(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.versions[].version)'); do - gitRepository="$(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.versions[] | select(.version == "'${version}'")' | yq e '.git.remotes.origin' )" + for version in $(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.versions[].version)' -); do + gitRepository="$(yq e '(.samples[] | select(.name == "'${sampleName}'")' $devfileEntriesFile | yq e '(.versions[] | select(.version == "'${version}'")' -| yq e '.git.remotes.origin' -)" git clone "$gitRepository" "$sampleDir/$version" mkdir $outputDir/$version cache_devfile $sampleDir/$version $outputDir/$version $sampleName From eed32e5ca4495c7ca12590619bfa7f60c800d302 Mon Sep 17 00:00:00 2001 From: Stephanie Date: Tue, 22 Feb 2022 17:06:59 -0500 Subject: [PATCH 7/9] update tests and server go mod Signed-off-by: Stephanie --- index/server/go.mod | 4 +- index/server/go.sum | 12 + index/server/pkg/server/endpoint.go | 4 +- index/server/pkg/util/util.go | 8 +- index/server/pkg/util/util_test.go | 27 +- .../tests/resources/newIndexStruct.json | 280 +++++++++++++ .../tests/resources/oldIndexStruct.json | 178 ++++++++ .../index/generator/library/library.go | 392 ++++-------------- .../index/generator/schema/schema.go | 90 +++- index/server/vendor/modules.txt | 3 +- tests/registry/extraDevfileEntries.yaml | 34 +- tests/registry/stacks/go/1.1.0/devfile.yaml | 47 +++ tests/registry/stacks/go/1.2.0/devfile.yaml | 47 +++ tests/registry/stacks/go/stack.yaml | 8 + 14 files changed, 770 insertions(+), 364 deletions(-) create mode 100644 index/server/tests/resources/newIndexStruct.json create mode 100644 index/server/tests/resources/oldIndexStruct.json create mode 100644 tests/registry/stacks/go/1.1.0/devfile.yaml create mode 100644 tests/registry/stacks/go/1.2.0/devfile.yaml create mode 100644 tests/registry/stacks/go/stack.yaml diff --git a/index/server/go.mod b/index/server/go.mod index 47dcd501a..a731d0eb3 100644 --- a/index/server/go.mod +++ b/index/server/go.mod @@ -6,7 +6,7 @@ require ( github.com/containerd/containerd v1.4.1 github.com/deislabs/oras v0.8.1 github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed - github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0 + github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e github.com/gin-gonic/gin v1.6.3 github.com/gorilla/mux v1.7.3 // indirect github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 @@ -18,5 +18,3 @@ require ( gopkg.in/segmentio/analytics-go.v3 v3.1.0 k8s.io/apimachinery v0.21.3 ) - -replace github.com/devfile/registry-support/index/generator => github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee diff --git a/index/server/go.sum b/index/server/go.sum index d8fc4e581..b61bf8e69 100644 --- a/index/server/go.sum +++ b/index/server/go.sum @@ -138,6 +138,8 @@ github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f h1:kKsBWkFiD7tSI github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f/go.mod h1:uFZZdTuRqA68FVe/JoJHP92CgINyQkyWnM2Qyiim+50= github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0 h1:F2OkuW0ASrSz5d06tJxWfweUNYTnsOCyiGTEORisokE= github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0/go.mod h1:bLGagbW2SFn7jo5+kUPlCMehIGqWkRtLKc5O0OyJMJM= +github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e h1:3WAjUoyAmCBzUpx+sO0dSgkH74uSW1y886wGbojD2D8= +github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e/go.mod h1:iRPBxs+ZjfLEduVXpCCIOzdD2588Zv9OCs/CcXMcCCY= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -326,6 +328,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= @@ -375,6 +378,7 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -396,11 +400,13 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= @@ -455,6 +461,7 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f/go.mod h1:Si/I9UGeRR3qzg01YWPmtlr0GeGk2fnuggXJRmjAZ6U= github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -525,12 +532,14 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -540,6 +549,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -552,6 +562,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -902,6 +913,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/index/server/pkg/server/endpoint.go b/index/server/pkg/server/endpoint.go index 350bfa546..519380caf 100644 --- a/index/server/pkg/server/endpoint.go +++ b/index/server/pkg/server/endpoint.go @@ -89,8 +89,8 @@ func serveDevfile(c *gin.Context) { if devfileIndex.Name == name { var sampleDevfilePath string var bytes []byte - if devfileIndex.Type == indexSchema.SampleDevfileType { - if devfileIndex.Versions == nil || len(devfileIndex.Versions) == 0 { + if devfileIndex.Versions == nil || len(devfileIndex.Versions) == 0 { + if devfileIndex.Type == indexSchema.SampleDevfileType { sampleDevfilePath = path.Join(samplesPath, devfileIndex.Name, devfileName) } } else { diff --git a/index/server/pkg/util/util.go b/index/server/pkg/util/util.go index 480438fce..81a58616b 100644 --- a/index/server/pkg/util/util.go +++ b/index/server/pkg/util/util.go @@ -155,8 +155,12 @@ func ConvertToOldIndexFormat(schemaList []indexSchema.Schema) []indexSchema.Sche if !versionComponent.Default { continue } - oldSchema.Tags = versionComponent.Tags - oldSchema.Architectures = versionComponent.Architectures + if versionComponent.Tags != nil && len(versionComponent.Tags) > 0 { + oldSchema.Tags = versionComponent.Tags + } + if versionComponent.Architectures != nil && len(versionComponent.Architectures) > 0 { + oldSchema.Architectures = versionComponent.Architectures + } if schema.Type == indexSchema.SampleDevfileType { oldSchema.Git = versionComponent.Git } else { diff --git a/index/server/pkg/util/util_test.go b/index/server/pkg/util/util_test.go index 54c239084..45c2076de 100644 --- a/index/server/pkg/util/util_test.go +++ b/index/server/pkg/util/util_test.go @@ -2,10 +2,10 @@ package util import ( "encoding/json" - indexLibrary "github.com/devfile/registry-support/index/generator/library" "github.com/devfile/registry-support/index/generator/schema" "io/ioutil" "os" + "reflect" "testing" ) @@ -197,25 +197,32 @@ func TestGetOptionalEnv(t *testing.T) { func TestConvertToOldIndexFormat(t *testing.T) { - inputIndexFilePath := "../../../generator/index.json" - // wantIndexFilePath := "../tests/registry/index_main.json" + const inputIndexFilePath = "../../tests/resources/newIndexStruct.json" + const wantIndexFilePath = "../../tests/resources/oldIndexStruct.json" bytes,err := ioutil.ReadFile(inputIndexFilePath) - // bytes, err := ioutil.ReadFile(wantIndexFilePath) if err != nil { - t.Errorf("Failed to read index.json: %v", err) + t.Errorf("Failed to read newIndexStruct.json: %v", err) + } + expected, err := ioutil.ReadFile(wantIndexFilePath) + if err != nil { + t.Errorf("Failed to oldIndexStruct.json: %v", err) } var inputIndex []schema.Schema err = json.Unmarshal(bytes, &inputIndex) if err != nil { - t.Errorf("Failed to unmarshal inputIndex.json") + t.Errorf("Failed to unmarshal inputIndex json") + } + var wantIndex []schema.Schema + err = json.Unmarshal(expected, &wantIndex) + if err != nil { + t.Errorf("Failed to unmarshal wantIndex json") } t.Run("Test generate index", func(t *testing.T) { gotIndex:= ConvertToOldIndexFormat(inputIndex) - //if !reflect.DeepEqual(wantIndex, gotIndex) { - // t.Errorf("Want index %v, got index %v", wantIndex, gotIndex) - //} - indexLibrary.CreateIndexFile(gotIndex, "./index.json") + if !reflect.DeepEqual(wantIndex, gotIndex) { + t.Errorf("Want index %v, got index %v", wantIndex, gotIndex) + } }) } \ No newline at end of file diff --git a/index/server/tests/resources/newIndexStruct.json b/index/server/tests/resources/newIndexStruct.json new file mode 100644 index 000000000..87efeb801 --- /dev/null +++ b/index/server/tests/resources/newIndexStruct.json @@ -0,0 +1,280 @@ +[ + { + "name": "go", + "displayName": "Go Runtime", + "description": "Stack with the latest Go version", + "type": "stack", + "tags": [ + "Go", + "testtag" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "projectType": "go", + "language": "go", + "provider": "Red Hat", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "description": "Stack with the latest Go version with devfile v2.0.0 schema verison", + "tags": [ + "Go" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "links": { + "self": "devfile-catalog/go:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ] + }, + { + "version": "1.2.0", + "schemaVersion": "2.1.0", + "description": "Stack with the latest Go version with devfile v2.1.0 schema verison", + "tags": [ + "testtag" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "links": { + "self": "devfile-catalog/go:1.2.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ] + } + ] + }, + { + "name": "java-maven", + "displayName": "Maven Java", + "description": "Upstream Maven and OpenJDK 11", + "type": "stack", + "tags": [ + "Java", + "Maven" + ], + "architectures": [ + "amd64", + "arm64", + "s390x" + ], + "projectType": "maven", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.1.0", + "default": true, + "description": "Upstream Maven and OpenJDK 11", + "tags": [ + "Java", + "Maven" + ], + "architectures": [ + "amd64", + "arm64", + "s390x" + ], + "links": { + "self": "devfile-catalog/java-maven:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + } + ] + }, + { + "name": "java-quarkus", + "displayName": "Quarkus Java", + "description": "Quarkus with Java", + "type": "stack", + "tags": [ + "Java", + "Quarkus" + ], + "architectures": [ + "amd64" + ], + "projectType": "quarkus", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "description": "Quarkus with Java", + "tags": [ + "Java", + "Quarkus" + ], + "architectures": [ + "amd64" + ], + "links": { + "self": "devfile-catalog/java-quarkus:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "community", + "redhat-product" + ] + } + ] + }, + { + "name": "nodejs", + "displayName": "NodeJS Runtime", + "description": "Stack with NodeJS 12", + "type": "stack", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "architectures": [ + "amd64", + "arm64" + ], + "projectType": "nodejs", + "language": "nodejs", + "provider": "Red Hat", + "supportUrl": "http://testurl/support.md", + "versions": [ + { + "version": "1.0.0", + "schemaVersion": "2.0.0", + "default": true, + "description": "Stack with NodeJS 12", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "architectures": [ + "amd64", + "arm64" + ], + "links": { + "self": "devfile-catalog/nodejs:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "nodejs-starter" + ] + } + ] + }, + { + "name": "nodejs-basic", + "displayName": "Basic Node.js", + "description": "A simple Hello World Node.js application", + "type": "sample", + "tags": [ + "NodeJS", + "Express" + ], + "icon": "https://nodejs.org/static/images/logos/nodejs-new-pantone-black.svg", + "projectType": "nodejs", + "language": "nodejs", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "git": { + "remotes": { + "origin": "/~https://github.com/nodeshift-starters/devfile-sample.git" + } + }, + "description": "nodejs with devfile v2.2.0" + } + ] + }, + { + "name": "code-with-quarkus", + "displayName": "Basic Quarkus", + "description": "A simple Hello World Java application using Quarkus", + "type": "sample", + "tags": [ + "Java", + "Quarkus" + ], + "icon": "https://design.jboss.org/quarkus/logo/final/SVG/quarkus_icon_rgb_default.svg", + "projectType": "quarkus", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.2.0", + "default": true, + "git": { + "remotes": { + "origin": "/~https://github.com/devfile-samples/devfile-sample-code-with-quarkus.git" + } + }, + "description": "java quarkus with devfile v2.2.0" + }, + { + "version": "1.0.0", + "schemaVersion": "2.0.0", + "git": { + "remotes": { + "origin": "/~https://github.com/elsony/devfile-sample-code-with-quarkus.git" + } + }, + "description": "java quarkus with devfile v2.0.0" + } + ] + }, + { + "name": "java-springboot-basic", + "displayName": "Basic Spring Boot", + "description": "A simple Hello World Java Spring Boot application using Maven", + "type": "sample", + "tags": [ + "Java", + "Spring" + ], + "icon": "https://spring.io/images/projects/spring-edf462fec682b9d48cf628eaf9e19521.svg", + "projectType": "springboot", + "language": "java", + "git": { + "remotes": { + "origin": "/~https://github.com/devfile-samples/devfile-sample-java-springboot-basic.git" + } + } + }, + { + "name": "python-basic", + "displayName": "Basic Python", + "description": "A simple Hello World application using Python", + "type": "sample", + "tags": [ + "Python" + ], + "icon": "https://www.python.org/static/community_logos/python-logo-generic.svg", + "projectType": "python", + "language": "python", + "git": { + "remotes": { + "origin": "/~https://github.com/devfile-samples/devfile-sample-python-basic.git" + } + } + } +] \ No newline at end of file diff --git a/index/server/tests/resources/oldIndexStruct.json b/index/server/tests/resources/oldIndexStruct.json new file mode 100644 index 000000000..e6a76b901 --- /dev/null +++ b/index/server/tests/resources/oldIndexStruct.json @@ -0,0 +1,178 @@ +[ + { + "name": "go", + "version": "1.1.0", + "displayName": "Go Runtime", + "description": "Stack with the latest Go version", + "type": "stack", + "tags": [ + "Go" + ], + "icon": "https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg", + "projectType": "go", + "language": "go", + "links": { + "self": "devfile-catalog/go:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "go-starter" + ], + "provider": "Red Hat" + }, + { + "name": "java-maven", + "version": "1.1.0", + "displayName": "Maven Java", + "description": "Upstream Maven and OpenJDK 11", + "type": "stack", + "tags": [ + "Java", + "Maven" + ], + "architectures": [ + "amd64", + "arm64", + "s390x" + ], + "projectType": "maven", + "language": "java", + "links": { + "self": "devfile-catalog/java-maven:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + }, + { + "name": "java-quarkus", + "version": "1.1.0", + "displayName": "Quarkus Java", + "description": "Quarkus with Java", + "type": "stack", + "tags": [ + "Java", + "Quarkus" + ], + "architectures": [ + "amd64" + ], + "projectType": "quarkus", + "language": "java", + "links": { + "self": "devfile-catalog/java-quarkus:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "community", + "redhat-product" + ] + }, + { + "name": "nodejs", + "version": "1.0.0", + "displayName": "NodeJS Runtime", + "description": "Stack with NodeJS 12", + "type": "stack", + "tags": [ + "NodeJS", + "Express", + "ubi8" + ], + "architectures": [ + "amd64", + "arm64" + ], + "projectType": "nodejs", + "language": "nodejs", + "links": { + "self": "devfile-catalog/nodejs:1.0.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "nodejs-starter" + ], + "provider": "Red Hat", + "supportUrl": "http://testurl/support.md" + }, + { + "name": "nodejs-basic", + "displayName": "Basic Node.js", + "description": "A simple Hello World Node.js application", + "type": "sample", + "tags": [ + "NodeJS", + "Express" + ], + "icon": "https://nodejs.org/static/images/logos/nodejs-new-pantone-black.svg", + "projectType": "nodejs", + "language": "nodejs", + "git": { + "remotes": { + "origin": "/~https://github.com/nodeshift-starters/devfile-sample.git" + } + } + }, + { + "name": "code-with-quarkus", + "displayName": "Basic Quarkus", + "description": "A simple Hello World Java application using Quarkus", + "type": "sample", + "tags": [ + "Java", + "Quarkus" + ], + "icon": "https://design.jboss.org/quarkus/logo/final/SVG/quarkus_icon_rgb_default.svg", + "projectType": "quarkus", + "language": "java", + "git": { + "remotes": { + "origin": "/~https://github.com/devfile-samples/devfile-sample-code-with-quarkus.git" + } + } + }, + { + "name": "java-springboot-basic", + "displayName": "Basic Spring Boot", + "description": "A simple Hello World Java Spring Boot application using Maven", + "type": "sample", + "tags": [ + "Java", + "Spring" + ], + "icon": "https://spring.io/images/projects/spring-edf462fec682b9d48cf628eaf9e19521.svg", + "projectType": "springboot", + "language": "java", + "git": { + "remotes": { + "origin": "/~https://github.com/devfile-samples/devfile-sample-java-springboot-basic.git" + } + } + }, + { + "name": "python-basic", + "displayName": "Basic Python", + "description": "A simple Hello World application using Python", + "type": "sample", + "tags": [ + "Python" + ], + "icon": "https://www.python.org/static/community_logos/python-logo-generic.svg", + "projectType": "python", + "language": "python", + "git": { + "remotes": { + "origin": "/~https://github.com/devfile-samples/devfile-sample-python-basic.git" + } + } + } +] \ No newline at end of file diff --git a/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go b/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go index 4f7a8b8d8..dfaa8ce8d 100644 --- a/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go +++ b/index/server/vendor/github.com/devfile/registry-support/index/generator/library/library.go @@ -18,7 +18,6 @@ const ( devfile = "devfile.yaml" devfileHidden = ".devfile.yaml" extraDevfileEntries = "extraDevfileEntries.yaml" - stackYaml = "stack.yaml" ) // MissingArchError is an error if the architecture list is empty @@ -89,66 +88,18 @@ func validateIndexComponent(indexComponent schema.Schema, componentType schema.D if indexComponent.Name == "" { return fmt.Errorf("index component name is not initialized") } - if indexComponent.Versions == nil || len(indexComponent.Versions) == 0 { - return fmt.Errorf("index component versions list is empty") - } else { - defaultFound := false - for _, version := range indexComponent.Versions { - if version.Version == "" { - return fmt.Errorf("index component versions list contains an entry with no version specified") - } - if version.SchemaVersion == "" { - return fmt.Errorf("index component version %s: schema version is empty", version.Version) - } - if version.Links == nil || len(version.Links) == 0 { - return fmt.Errorf("index component version %s: links are empty", version.Version) - } - if version.Resources == nil || len(version.Resources) == 0 { - return fmt.Errorf("index component version %s: resources are empty", version.Version) - } - if version.Default { - if !defaultFound { - defaultFound = true - } else { - return fmt.Errorf("index component has multiple default versions") - } - } - } - if !defaultFound { - return fmt.Errorf("index component has no default version defined") - } + if indexComponent.Links == nil { + return fmt.Errorf("index component links are empty") + } + if indexComponent.Resources == nil { + return fmt.Errorf("index component resources are empty") } } else if componentType == schema.SampleDevfileType { - if indexComponent.Versions != nil && len(indexComponent.Versions) > 0 { - defaultFound := false - for _, version := range indexComponent.Versions { - if version.Version == "" { - return fmt.Errorf("index component versions list contains an entry with no version specified") - } - if version.SchemaVersion == "" { - return fmt.Errorf("index component version %s: schema version is empty", version.Version) - } - if version.Git == nil { - return fmt.Errorf("index component version %s: git is empty", version.Version) - } - if version.Default { - if !defaultFound { - defaultFound = true - } else { - return fmt.Errorf("index component has multiple default versions") - } - } - } - if !defaultFound { - return fmt.Errorf("index component has no default version defined") - } - } else { - if indexComponent.Git == nil { - return fmt.Errorf("index component git is empty") - } - if len(indexComponent.Git.Remotes) > 1 { - return fmt.Errorf("index component has multiple remotes") - } + if indexComponent.Git == nil { + return fmt.Errorf("index component git is empty") + } + if len(indexComponent.Git.Remotes) > 1 { + return fmt.Errorf("index component has multiple remotes") } } @@ -174,73 +125,74 @@ func fileExists(filepath string) bool { return true } -func dirExists(dirpath string) error { - dir, err := os.Stat(dirpath) - if os.IsNotExist(err){ - return fmt.Errorf("path: %s does not exist: %w",dirpath, err) - } - if !dir.IsDir() { - return fmt.Errorf("%s is not a directory", dirpath) - } - return nil -} - func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, error) { - var index []schema.Schema stackDirPath := path.Join(registryDirPath, "stacks") stackDir, err := ioutil.ReadDir(stackDirPath) if err != nil { return nil, fmt.Errorf("failed to read stack directory %s: %v", stackDirPath, err) } - for _, stackFolderDir := range stackDir { - if !stackFolderDir.IsDir() { + for _, devfileDir := range stackDir { + if !devfileDir.IsDir() { continue } - stackFolderPath := filepath.Join(stackDirPath, stackFolderDir.Name()) - stackYamlPath := filepath.Join(stackFolderPath, stackYaml) - // if stack.yaml exist, parse stack.yaml - var indexComponent schema.Schema - if fileExists(stackYamlPath) { - indexComponent, err = parseStackInfo(stackYamlPath) + + // Allow devfile.yaml or .devfile.yaml + devfilePath := filepath.Join(stackDirPath, devfileDir.Name(), devfile) + devfileHiddenPath := filepath.Join(stackDirPath, devfileDir.Name(), devfileHidden) + if fileExists(devfilePath) && fileExists(devfileHiddenPath) { + return nil, fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) + } + if fileExists(devfileHiddenPath) { + devfilePath = devfileHiddenPath + } + + if !force { + // Devfile validation + devfileObj, err := devfileParser.ParseAndValidate(devfilePath) if err != nil { - return nil, err + return nil, fmt.Errorf("%s devfile is not valid: %v", devfileDir.Name(), err) } - if !force { - stackYamlErrors := validateStackInfo(indexComponent, stackFolderPath) - if stackYamlErrors != nil { - return nil, fmt.Errorf("%s stack.yaml is not valid: %v", stackFolderDir.Name(), stackYamlErrors) - } + + metadataErrors := checkForRequiredMetadata(devfileObj) + if metadataErrors != nil { + return nil, fmt.Errorf("%s devfile is not valid: %v", devfileDir.Name(), metadataErrors) } + } - i:= 0 - for i < len(indexComponent.Versions) { - versionComponent := indexComponent.Versions[i] - if versionComponent.Git != nil { - // Todo: implement Git reference support, get stack content from remote repository and store in OCI registry - fmt.Printf("stack: %v, version:%v, Git reference is currently not supported", stackFolderDir.Name(), versionComponent.Version) - indexComponent.Versions = append(indexComponent.Versions[:i], indexComponent.Versions[i+1:]...) - continue - } - stackVersonDirPath := filepath.Join(stackFolderPath, versionComponent.Version) + bytes, err := ioutil.ReadFile(devfilePath) + if err != nil { + return nil, fmt.Errorf("failed to read %s: %v", devfilePath, err) + } + var devfile schema.Devfile + err = yaml.Unmarshal(bytes, &devfile) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) + } + indexComponent := devfile.Meta + if indexComponent.Links == nil { + indexComponent.Links = make(map[string]string) + } + indexComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", indexComponent.Name, "latest") + indexComponent.Type = schema.StackDevfileType - err := parseStackDevfile(stackVersonDirPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) - if err != nil { - return nil, err - } - indexComponent.Versions[i] = versionComponent - i++ - } - } else { // if stack.yaml not exist, old stack repo struct, directly lookfor & parse devfile.yaml - versionComponent := schema.Version{} - err := parseStackDevfile(stackFolderPath, stackFolderDir.Name(), force, &versionComponent, &indexComponent) - if err != nil { - return nil, err + for _, starterProject := range devfile.StarterProjects { + indexComponent.StarterProjects = append(indexComponent.StarterProjects, starterProject.Name) + } + + // Get the files in the stack folder + stackFolder := filepath.Join(stackDirPath, devfileDir.Name()) + stackFiles, err := ioutil.ReadDir(stackFolder) + if err != nil { + return index, err + } + for _, stackFile := range stackFiles { + // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file + // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. + if !stackFile.IsDir() { + indexComponent.Resources = append(indexComponent.Resources, stackFile.Name()) } - versionComponent.Default = true - indexComponent.Versions = append(indexComponent.Versions, versionComponent) } - indexComponent.Type = schema.StackDevfileType if !force { // Index component validation @@ -252,7 +204,7 @@ func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, default: // only return error if we dont want to print if err != nil { - return nil, fmt.Errorf("%s index component is not valid: %v", stackFolderDir.Name(), err) + return nil, fmt.Errorf("%s index component is not valid: %v", devfileDir.Name(), err) } } } @@ -263,119 +215,6 @@ func parseDevfileRegistry(registryDirPath string, force bool) ([]schema.Schema, return index, nil } -func parseStackDevfile(devfileDirPath string, stackName string, force bool, versionComponent *schema.Version, indexComponent *schema.Schema) error { - // Allow devfile.yaml or .devfile.yaml - devfilePath := filepath.Join(devfileDirPath, devfile) - devfileHiddenPath := filepath.Join(devfileDirPath, devfileHidden) - if fileExists(devfilePath) && fileExists(devfileHiddenPath) { - return fmt.Errorf("both %s and %s exist", devfilePath, devfileHiddenPath) - } - if fileExists(devfileHiddenPath) { - devfilePath = devfileHiddenPath - } - - if !force { - // Devfile validation - devfileObj,_, err := devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) - if err != nil { - return fmt.Errorf("%s devfile is not valid: %v", devfileDirPath, err) - } - - metadataErrors := checkForRequiredMetadata(devfileObj) - if metadataErrors != nil { - return fmt.Errorf("%s devfile is not valid: %v", devfileDirPath, metadataErrors) - } - } - - bytes, err := ioutil.ReadFile(devfilePath) - if err != nil { - return fmt.Errorf("failed to read %s: %v", devfilePath, err) - } - - - var devfile schema.Devfile - err = yaml.Unmarshal(bytes, &devfile) - if err != nil { - return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) - } - metaBytes, err := yaml.Marshal(devfile.Meta) - if err != nil { - return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) - } - var versionProp schema.Version - err = yaml.Unmarshal(metaBytes, &versionProp) - if err != nil { - return fmt.Errorf("failed to unmarshal %s data: %v", devfilePath, err) - } - - // set common properties if not set - if indexComponent.ProjectType == "" { - indexComponent.ProjectType = devfile.Meta.ProjectType - } - if indexComponent.Language == "" { - indexComponent.Language = devfile.Meta.Language - } - if indexComponent.Provider == "" { - indexComponent.Provider = devfile.Meta.Provider - } - if indexComponent.SupportUrl == "" { - indexComponent.SupportUrl = devfile.Meta.SupportUrl - } - - // for single version stack with only devfile.yaml, without stack.yaml - // set the top-level properties for this stack - if indexComponent.Name == "" { - indexComponent.Name = devfile.Meta.Name - } - if indexComponent.DisplayName == "" { - indexComponent.DisplayName = devfile.Meta.DisplayName - } - if indexComponent.Description == "" { - indexComponent.Description = devfile.Meta.Description - } - if indexComponent.Icon == "" { - indexComponent.Icon = devfile.Meta.Icon - } - - versionProp.Default = versionComponent.Default - *versionComponent = versionProp - if versionComponent.Links == nil { - versionComponent.Links = make(map[string]string) - } - versionComponent.Links["self"] = fmt.Sprintf("%s/%s:%s", "devfile-catalog", stackName, versionComponent.Version) - versionComponent.SchemaVersion = devfile.SchemaVersion - - for _, starterProject := range devfile.StarterProjects { - versionComponent.StarterProjects = append(versionComponent.StarterProjects, starterProject.Name) - } - - for _, tag := range versionComponent.Tags { - if !inArray(indexComponent.Tags, tag) { - indexComponent.Tags = append(indexComponent.Tags, tag) - } - } - - for _, arch := range versionComponent.Architectures { - if !inArray(indexComponent.Architectures, arch) { - indexComponent.Architectures = append(indexComponent.Architectures, arch) - } - } - - // Get the files in the stack folder - stackFiles, err := ioutil.ReadDir(devfileDirPath) - if err != nil { - return err - } - for _, stackFile := range stackFiles { - // The registry build should have already packaged any folders and miscellaneous files into an archive.tar file - // But, add this check as a safeguard, as OCI doesn't support unarchived folders being pushed up. - if !stackFile.IsDir() { - versionComponent.Resources = append(versionComponent.Resources, stackFile.Name()) - } - } - return nil -} - func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Schema, error) { var index []schema.Schema extraDevfileEntriesPath := path.Join(registryDirPath, extraDevfileEntries) @@ -408,38 +247,21 @@ func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Sche indexComponent := devfileEntry indexComponent.Type = devfileType if !force { + // If sample, validate devfile associated with sample as well // Can't handle during registry build since we don't have access to devfile library/parser if indexComponent.Type == schema.SampleDevfileType && validateSamples { - if indexComponent.Versions != nil && len(indexComponent.Versions) > 0 { - for _, version := range indexComponent.Versions{ - sampleVersonDirPath := filepath.Join(samplesDir, devfileEntry.Name, version.Version) - devfilePath := filepath.Join(sampleVersonDirPath, "devfile.yaml") - _, err := os.Stat(filepath.Join(devfilePath)) - if err != nil { - // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless - return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) - } - - // Validate the sample devfile - _, _, err = devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) - if err != nil { - return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) - } - } - } else { - devfilePath := filepath.Join(samplesDir, devfileEntry.Name, "devfile.yaml") - _, err := os.Stat(filepath.Join(devfilePath)) - if err != nil { - // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless - return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) - } - - // Validate the sample devfile - _, _, err = devfileParser.ParseDevfileAndValidate(parser.ParserArgs{Path: devfilePath}) - if err != nil { - return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) - } + devfilePath := filepath.Join(samplesDir, devfileEntry.Name, "devfile.yaml") + _, err := os.Stat(filepath.Join(devfilePath)) + if err != nil { + // This error shouldn't occur since we check for the devfile's existence during registry build, but check for it regardless + return nil, fmt.Errorf("%s devfile sample does not have a devfile.yaml: %v", indexComponent.Name, err) + } + + // Validate the sample devfile + _, err = devfileParser.ParseAndValidate(devfilePath) + if err != nil { + return nil, fmt.Errorf("%s sample devfile is not valid: %v", devfileEntry.Name, err) } } @@ -463,19 +285,6 @@ func parseExtraDevfileEntries(registryDirPath string, force bool) ([]schema.Sche return index, nil } -func parseStackInfo(stackYamlPath string) (schema.Schema, error) { - var index schema.Schema - bytes, err := ioutil.ReadFile(stackYamlPath) - if err != nil { - return schema.Schema{}, fmt.Errorf("failed to read %s: %v", stackYamlPath, err) - } - err = yaml.Unmarshal(bytes, &index) - if err != nil { - return schema.Schema{}, fmt.Errorf("failed to unmarshal %s data: %v", stackYamlPath, err) - } - return index, nil -} - // checkForRequiredMetadata validates that a given devfile has the necessary metadata fields func checkForRequiredMetadata(devfileObj parser.DevfileObj) []error { devfileMetadata := devfileObj.Data.GetMetadata() @@ -496,54 +305,3 @@ func checkForRequiredMetadata(devfileObj parser.DevfileObj) []error { return metadataErrors } - -func validateStackInfo (stackInfo schema.Schema, stackfolderDir string) []error { - var errors []error - - if stackInfo.Name == "" { - errors = append(errors, fmt.Errorf("name is not set in stack.yaml")) - } - if stackInfo.DisplayName == "" { - errors = append(errors, fmt.Errorf("displayName is not set stack.yaml")) - } - if stackInfo.Icon == "" { - errors = append(errors, fmt.Errorf("icon is not set stack.yaml")) - } - if stackInfo.Versions == nil || len(stackInfo.Versions) == 0 { - errors = append(errors, fmt.Errorf("versions list is not set stack.yaml, or is empty")) - } - hasDefault := false - for _, version := range stackInfo.Versions { - if version.Default { - if !hasDefault { - hasDefault = true - } else { - errors = append(errors, fmt.Errorf("stack.yaml has multiple default versions")) - } - } - - if version.Git == nil { - versionFolder := path.Join(stackfolderDir, version.Version) - err := dirExists(versionFolder) - if err != nil { - errors = append(errors, fmt.Errorf("cannot find resorce folder for version %s defined in stack.yaml: %v", version.Version, err)) - } - } - } - if !hasDefault { - errors = append(errors, fmt.Errorf("stack.yaml does not contain a default version")) - } - - return errors -} - - -// In checks if the value is in the array -func inArray(arr []string, value string) bool { - for _, item := range arr { - if item == value { - return true - } - } - return false -} \ No newline at end of file diff --git a/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go b/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go index 99a56d5d6..21c5db9ab 100644 --- a/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go +++ b/index/server/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go @@ -9,7 +9,6 @@ Sample index file: [ { "name": "java-maven", - "version": "1.1.0", "displayName": "Maven Java", "description": "Upstream Maven and OpenJDK 11", "type": "stack", @@ -17,34 +16,78 @@ Sample index file: "Java", "Maven" ], + "architectures": [ + "amd64", + "arm64", + "s390x" + ], "projectType": "maven", "language": "java", - "links": { - "self": "devfile-catalog/java-maven:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "springbootproject" + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.1.0", + "default": true, + "description": "Upstream Maven and OpenJDK 11", + "tags": [ + "Java", + "Maven" + ], + "architectures": [ + "amd64", + "arm64", + "s390x" + ], + "links": { + "self": "devfile-catalog/java-maven:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + } ] }, { - "name": "java-openliberty", - "version": "0.5.0", - "displayName": "Open Liberty", - "description": "Java application stack using Open Liberty runtime", + "name": "java-quarkus", + "displayName": "Quarkus Java", + "description": "Quarkus with Java", "type": "stack", - "projectType": "docker", - "language": "java", - "links": { - "self": "devfile-catalog/java-openliberty:latest" - }, - "resources": [ - "devfile.yaml" + "tags": [ + "Java", + "Quarkus" + ], + "architectures": [ + "amd64" ], - "starterProjects": [ - "user-app" + "projectType": "quarkus", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "description": "Quarkus with Java", + "tags": [ + "Java", + "Quarkus" + ], + "architectures": [ + "amd64" + ], + "links": { + "self": "devfile-catalog/java-quarkus:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "community", + "redhat-product" + ] + } ] } ] @@ -68,6 +111,7 @@ resources: []string - The file resources that compose a devfile stack. starterProjects: string[] - The project templates that can be used in the devfile git: *git - The information of remote repositories provider: string - The devfile provider information +versions: []Version - The list of stack versions information */ // Schema is the index file schema @@ -131,6 +175,7 @@ type ExtraDevfileEntries struct { Stacks []Schema `yaml:"stacks,omitempty" json:"stacks,omitempty"` } +// Version stores the top-level stack information defined within stack.yaml type StackInfo struct { Name string `yaml:"name,omitempty" json:"name,omitempty"` DisplayName string `yaml:"displayName,omitempty" json:"displayName,omitempty"` @@ -139,6 +184,7 @@ type StackInfo struct { Versions []Version `yaml:"versions,omitempty" json:"versions,omitempty"` } +// Version stores the information for each stack version type Version struct { Version string `yaml:"version,omitempty" json:"version,omitempty"` SchemaVersion string `yaml:"schemaVersion,omitempty" json:"schemaVersion,omitempty"` diff --git a/index/server/vendor/modules.txt b/index/server/vendor/modules.txt index b2a74e490..d25a49163 100644 --- a/index/server/vendor/modules.txt +++ b/index/server/vendor/modules.txt @@ -72,7 +72,7 @@ github.com/devfile/library/pkg/devfile/parser/data/v2/common github.com/devfile/library/pkg/devfile/validate github.com/devfile/library/pkg/testingutil/filesystem github.com/devfile/library/pkg/util -# github.com/devfile/registry-support/index/generator v0.0.0-20210916150157-08b31e03fdf0 => github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee +# github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e ## explicit github.com/devfile/registry-support/index/generator/library github.com/devfile/registry-support/index/generator/schema @@ -444,4 +444,3 @@ sigs.k8s.io/controller-runtime/pkg/scheme sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml -# github.com/devfile/registry-support/index/generator => github.com/yangcao77/registry-support/index/generator v0.0.0-20220217155801-d70e41e91aee diff --git a/tests/registry/extraDevfileEntries.yaml b/tests/registry/extraDevfileEntries.yaml index 6b9ebfd7c..9ecc37092 100644 --- a/tests/registry/extraDevfileEntries.yaml +++ b/tests/registry/extraDevfileEntries.yaml @@ -7,9 +7,17 @@ samples: tags: ["NodeJS", "Express"] projectType: nodejs language: nodejs - git: - remotes: - origin: /~https://github.com/nodeshift-starters/devfile-sample.git +# git: +# remotes: +# origin: /~https://github.com/nodeshift-starters/devfile-sample.git + versions: + - version: 1.1.0 + schemaVersion: 2.2.0 + default: true + description: nodejs with devfile v2.2.0 + git: + remotes: + origin: /~https://github.com/nodeshift-starters/devfile-sample.git - name: code-with-quarkus displayName: Basic Quarkus description: A simple Hello World Java application using Quarkus @@ -17,9 +25,23 @@ samples: tags: ["Java", "Quarkus"] projectType: quarkus language: java - git: - remotes: - origin: /~https://github.com/devfile-samples/devfile-sample-code-with-quarkus.git +# git: +# remotes: +# origin: /~https://github.com/devfile-samples/devfile-sample-code-with-quarkus.git\ + versions: + - version: 1.1.0 + schemaVersion: 2.2.0 + default: true + description: java quarkus with devfile v2.2.0 + git: + remotes: + origin: /~https://github.com/devfile-samples/devfile-sample-code-with-quarkus.git + - version: 1.0.0 + schemaVersion: 2.0.0 + description: java quarkus with devfile v2.0.0 + git: + remotes: + origin: /~https://github.com/elsony/devfile-sample-code-with-quarkus.git - name: java-springboot-basic displayName: Basic Spring Boot description: A simple Hello World Java Spring Boot application using Maven diff --git a/tests/registry/stacks/go/1.1.0/devfile.yaml b/tests/registry/stacks/go/1.1.0/devfile.yaml new file mode 100644 index 000000000..001d47077 --- /dev/null +++ b/tests/registry/stacks/go/1.1.0/devfile.yaml @@ -0,0 +1,47 @@ +schemaVersion: 2.0.0 +metadata: + description: Stack with the latest Go version with devfile v2.0.0 schema verison + displayName: Go Runtime + icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg + language: go + name: go + provider: Red Hat + projectType: go + tags: + - Go + version: 1.1.0 +starterProjects: + - name: go-starter + git: + checkoutFrom: + revision: main + remotes: + origin: /~https://github.com/devfile-samples/devfile-stack-go.git +components: + - container: + endpoints: + - name: http + targetPort: 8080 + image: golang:latest + memoryLimit: 1024Mi + mountSources: true + sourceMapping: /project + name: runtime +commands: + - exec: + commandLine: GOCACHE=/project/.cache go build main.go + component: runtime + group: + isDefault: true + kind: build + workingDir: /project + id: build + - exec: + commandLine: ./main + component: runtime + group: + isDefault: true + kind: run + workingDir: /project + id: run + diff --git a/tests/registry/stacks/go/1.2.0/devfile.yaml b/tests/registry/stacks/go/1.2.0/devfile.yaml new file mode 100644 index 000000000..a879fa8fd --- /dev/null +++ b/tests/registry/stacks/go/1.2.0/devfile.yaml @@ -0,0 +1,47 @@ +schemaVersion: 2.1.0 +metadata: + description: Stack with the latest Go version with devfile v2.1.0 schema verison + displayName: Go Runtime + icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg + language: go + name: go + provider: Red Hat + projectType: go + tags: + - testtag + version: 1.2.0 +starterProjects: + - name: go-starter + git: + checkoutFrom: + revision: main + remotes: + origin: /~https://github.com/devfile-samples/devfile-stack-go.git +components: + - container: + endpoints: + - name: http + targetPort: 8080 + image: golang:latest + memoryLimit: 1024Mi + mountSources: true + sourceMapping: /project + name: runtime +commands: + - exec: + commandLine: GOCACHE=/project/.cache go build main.go + component: runtime + group: + isDefault: true + kind: build + workingDir: /project + id: build + - exec: + commandLine: ./main + component: runtime + group: + isDefault: true + kind: run + workingDir: /project + id: run + diff --git a/tests/registry/stacks/go/stack.yaml b/tests/registry/stacks/go/stack.yaml new file mode 100644 index 000000000..4ac2bf82a --- /dev/null +++ b/tests/registry/stacks/go/stack.yaml @@ -0,0 +1,8 @@ +name: go +description: Stack with the latest Go version +displayName: Go Runtime +icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg +versions: + - version: 1.1.0 + default: true #should have one and only one default version + - version: 1.2.0 From 26a210bb00002227c598fd64afc3f6e86c74011f Mon Sep 17 00:00:00 2001 From: Stephanie Date: Tue, 22 Feb 2022 17:43:02 -0500 Subject: [PATCH 8/9] cleanup comments Signed-off-by: Stephanie --- build-tools/build.sh | 2 +- index/server/pkg/server/endpoint.go | 8 -------- tests/registry/extraDevfileEntries.yaml | 6 ------ 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/build-tools/build.sh b/build-tools/build.sh index e2de1f93c..69098f8bf 100755 --- a/build-tools/build.sh +++ b/build-tools/build.sh @@ -138,5 +138,5 @@ check_params build_registry if [ $? -ne 0 ]; then echo "Error building the devfile registry" - #cleanup_and_exit 1 + cleanup_and_exit 1 fi \ No newline at end of file diff --git a/index/server/pkg/server/endpoint.go b/index/server/pkg/server/endpoint.go index 519380caf..45fe1c13c 100644 --- a/index/server/pkg/server/endpoint.go +++ b/index/server/pkg/server/endpoint.go @@ -181,7 +181,6 @@ func buildIndexAPIResponse(c *gin.Context) { var bytes []byte var responseIndexPath, responseBase64IndexPath string - // isFiltered := false // Sets Access-Control-Allow-Origin response header to allow cross origin requests c.Header("Access-Control-Allow-Origin", "*") @@ -235,7 +234,6 @@ func buildIndexAPIResponse(c *gin.Context) { index = util.ConvertToOldIndexFormat(index) // Filter the index if archs has been requested if len(archs) > 0 { - // isFiltered = true index = util.FilterDevfileArchitectures(index, archs) } bytes, err = json.MarshalIndent(&index, "", " ") @@ -246,12 +244,6 @@ func buildIndexAPIResponse(c *gin.Context) { return } c.Data(http.StatusOK, http.DetectContentType(bytes), bytes) - // serve either the filtered index or the unfiltered index - //if isFiltered { - // c.Data(http.StatusOK, http.DetectContentType(bytes), bytes) - //} else { - // c.File(responseIndexPath) - //} // Track event for telemetry. Ignore events from the registry-viewer and DevConsole since those are tracked on the client side if enableTelemetry && !util.IsWebClient(c) { diff --git a/tests/registry/extraDevfileEntries.yaml b/tests/registry/extraDevfileEntries.yaml index 9ecc37092..c450eafa4 100644 --- a/tests/registry/extraDevfileEntries.yaml +++ b/tests/registry/extraDevfileEntries.yaml @@ -7,9 +7,6 @@ samples: tags: ["NodeJS", "Express"] projectType: nodejs language: nodejs -# git: -# remotes: -# origin: /~https://github.com/nodeshift-starters/devfile-sample.git versions: - version: 1.1.0 schemaVersion: 2.2.0 @@ -25,9 +22,6 @@ samples: tags: ["Java", "Quarkus"] projectType: quarkus language: java -# git: -# remotes: -# origin: /~https://github.com/devfile-samples/devfile-sample-code-with-quarkus.git\ versions: - version: 1.1.0 schemaVersion: 2.2.0 From 860d6d16b5f4a6432fe904905757527b4af25105 Mon Sep 17 00:00:00 2001 From: Stephanie Date: Wed, 23 Feb 2022 11:19:18 -0500 Subject: [PATCH 9/9] update to latest generator schema Signed-off-by: Stephanie --- registry-library/go.mod | 2 +- registry-library/go.sum | 31 +++++ .../index/generator/schema/schema.go | 120 ++++++++++++++---- registry-library/vendor/modules.txt | 2 +- 4 files changed, 130 insertions(+), 25 deletions(-) diff --git a/registry-library/go.mod b/registry-library/go.mod index e13aafe87..06de91209 100644 --- a/registry-library/go.mod +++ b/registry-library/go.mod @@ -4,7 +4,7 @@ go 1.14 require ( github.com/containerd/containerd v1.5.2 - github.com/devfile/registry-support/index/generator v0.0.0-20211012185733-0a73f866043f + github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e github.com/mitchellh/go-homedir v1.1.0 github.com/spf13/cobra v1.1.1 github.com/spf13/viper v1.7.1 diff --git a/registry-library/go.sum b/registry-library/go.sum index 5241f6b00..d057d0424 100644 --- a/registry-library/go.sum +++ b/registry-library/go.sum @@ -231,9 +231,15 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/devfile/api/v2 v2.0.0-20210910153124-da620cd1a7a1/go.mod h1:kLX/nW93gigOHXK3NLeJL2fSS/sgEe+OHu8bo3aoOi4= +github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed h1:OXF9l+MlJrirXAqKN6EZUVaHB0FKm7nh0EjpktwnBig= +github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q= github.com/devfile/library v1.1.1-0.20210910214722-7c5ff63711ec/go.mod h1:svPWwWb+BP15SXCHl0dyOeE4Sohrjl5a2BaOzc/riLc= +github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f h1:kKsBWkFiD7tSIpzwfmz7TH89U1U3yRxSJ9UPOo2OH1s= +github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f/go.mod h1:uFZZdTuRqA68FVe/JoJHP92CgINyQkyWnM2Qyiim+50= github.com/devfile/registry-support/index/generator v0.0.0-20211012185733-0a73f866043f h1:fKNUmoOPh7yAs69uMRZWHvev+m3e7T4jBL/hOXZB9ys= github.com/devfile/registry-support/index/generator v0.0.0-20211012185733-0a73f866043f/go.mod h1:bLGagbW2SFn7jo5+kUPlCMehIGqWkRtLKc5O0OyJMJM= +github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e h1:3WAjUoyAmCBzUpx+sO0dSgkH74uSW1y886wGbojD2D8= +github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e/go.mod h1:iRPBxs+ZjfLEduVXpCCIOzdD2588Zv9OCs/CcXMcCCY= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= @@ -267,7 +273,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -308,6 +316,7 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= @@ -334,6 +343,7 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -353,6 +363,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -382,6 +393,7 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -392,6 +404,7 @@ github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -401,6 +414,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -408,6 +422,7 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -430,6 +445,7 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -481,10 +497,12 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -506,6 +524,7 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= @@ -579,6 +598,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= @@ -709,9 +729,12 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -833,6 +856,7 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -919,6 +943,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -934,6 +959,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1001,6 +1027,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1105,6 +1132,7 @@ k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/api v0.21.3 h1:cblWILbLO8ar+Fj6xdDGr603HRsf8Wu9E9rngJeprZQ= k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg= k8s.io/apiextensions-apiserver v0.21.3 h1:+B6biyUWpqt41kz5x6peIsljlsuwvNAp/oFax/j2/aY= k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE= @@ -1121,6 +1149,7 @@ k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/client-go v0.21.3 h1:J9nxZTOmvkInRDCzcSNQmPJbDYN/PjlxXT9Mos3HcLg= k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU= k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo= @@ -1144,6 +1173,7 @@ k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -1159,6 +1189,7 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/controller-runtime v0.9.5 h1:WThcFE6cqctTn2jCZprLICO6BaKZfhsT37uAapTNfxc= sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/registry-library/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go b/registry-library/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go index adeb72a72..21c5db9ab 100644 --- a/registry-library/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go +++ b/registry-library/vendor/github.com/devfile/registry-support/index/generator/schema/schema.go @@ -9,7 +9,6 @@ Sample index file: [ { "name": "java-maven", - "version": "1.1.0", "displayName": "Maven Java", "description": "Upstream Maven and OpenJDK 11", "type": "stack", @@ -17,34 +16,78 @@ Sample index file: "Java", "Maven" ], + "architectures": [ + "amd64", + "arm64", + "s390x" + ], "projectType": "maven", "language": "java", - "links": { - "self": "devfile-catalog/java-maven:latest" - }, - "resources": [ - "devfile.yaml" - ], - "starterProjects": [ - "springbootproject" + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.1.0", + "default": true, + "description": "Upstream Maven and OpenJDK 11", + "tags": [ + "Java", + "Maven" + ], + "architectures": [ + "amd64", + "arm64", + "s390x" + ], + "links": { + "self": "devfile-catalog/java-maven:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "springbootproject" + ] + } ] }, { - "name": "java-openliberty", - "version": "0.5.0", - "displayName": "Open Liberty", - "description": "Java application stack using Open Liberty runtime", + "name": "java-quarkus", + "displayName": "Quarkus Java", + "description": "Quarkus with Java", "type": "stack", - "projectType": "docker", - "language": "java", - "links": { - "self": "devfile-catalog/java-openliberty:latest" - }, - "resources": [ - "devfile.yaml" + "tags": [ + "Java", + "Quarkus" + ], + "architectures": [ + "amd64" ], - "starterProjects": [ - "user-app" + "projectType": "quarkus", + "language": "java", + "versions": [ + { + "version": "1.1.0", + "schemaVersion": "2.0.0", + "default": true, + "description": "Quarkus with Java", + "tags": [ + "Java", + "Quarkus" + ], + "architectures": [ + "amd64" + ], + "links": { + "self": "devfile-catalog/java-quarkus:1.1.0" + }, + "resources": [ + "devfile.yaml" + ], + "starterProjects": [ + "community", + "redhat-product" + ] + } ] } ] @@ -68,6 +111,7 @@ resources: []string - The file resources that compose a devfile stack. starterProjects: string[] - The project templates that can be used in the devfile git: *git - The information of remote repositories provider: string - The devfile provider information +versions: []Version - The list of stack versions information */ // Schema is the index file schema @@ -90,6 +134,7 @@ type Schema struct { Git *Git `yaml:"git,omitempty" json:"git,omitempty"` Provider string `yaml:"provider,omitempty" json:"provider,omitempty"` SupportUrl string `yaml:"supportUrl,omitempty" json:"supportUrl,omitempty"` + Versions []Version `yaml:"versions,omitempty" json:"versions,omitempty"` } // DevfileType describes the type of devfile @@ -112,11 +157,16 @@ type StarterProject struct { type Devfile struct { Meta Schema `yaml:"metadata,omitempty" json:"metadata,omitempty"` StarterProjects []StarterProject `yaml:"starterProjects,omitempty" json:"starterProjects,omitempty"` + SchemaVersion string `yaml:"schemaVersion,omitempty" json:"schemaVersion,omitempty"` } // Git stores the information of remote repositories type Git struct { - Remotes map[string]string `yaml:"remotes,omitempty" json:"remotes,omitempty"` + Remotes map[string]string `yaml:"remotes,omitempty" json:"remotes,omitempty"` + Url string `yaml:"url,omitempty" json:"url,omitempty"` + RemoteName string `yaml:"remoteName,omitempty" json:"remoteName,omitempty"` + SubDir string `yaml:"subDir,omitempty" json:"subDir,omitempty"` + Revision string `yaml:"revision,omitempty" json:"revision,omitempty"` } // ExtraDevfileEntries is the extraDevfileEntries structure that is used by index component @@ -124,3 +174,27 @@ type ExtraDevfileEntries struct { Samples []Schema `yaml:"samples,omitempty" json:"samples,omitempty"` Stacks []Schema `yaml:"stacks,omitempty" json:"stacks,omitempty"` } + +// Version stores the top-level stack information defined within stack.yaml +type StackInfo struct { + Name string `yaml:"name,omitempty" json:"name,omitempty"` + DisplayName string `yaml:"displayName,omitempty" json:"displayName,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` + Versions []Version `yaml:"versions,omitempty" json:"versions,omitempty"` +} + +// Version stores the information for each stack version +type Version struct { + Version string `yaml:"version,omitempty" json:"version,omitempty"` + SchemaVersion string `yaml:"schemaVersion,omitempty" json:"schemaVersion,omitempty"` + Default bool `yaml:"default,omitempty" json:"default,omitempty"` + Git *Git `yaml:"git,omitempty" json:"git,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"` + Architectures []string `yaml:"architectures,omitempty" json:"architectures,omitempty"` + Icon string `yaml:"icon,omitempty" json:"icon,omitempty"` + Links map[string]string `yaml:"links,omitempty" json:"links,omitempty"` + Resources []string `yaml:"resources,omitempty" json:"resources,omitempty"` + StarterProjects []string `yaml:"starterProjects,omitempty" json:"starterProjects,omitempty"` +} \ No newline at end of file diff --git a/registry-library/vendor/modules.txt b/registry-library/vendor/modules.txt index 863403c8c..8e5a92e42 100644 --- a/registry-library/vendor/modules.txt +++ b/registry-library/vendor/modules.txt @@ -46,7 +46,7 @@ github.com/containerd/containerd/remotes/docker/schema1 github.com/containerd/containerd/remotes/errors github.com/containerd/containerd/sys github.com/containerd/containerd/version -# github.com/devfile/registry-support/index/generator v0.0.0-20211012185733-0a73f866043f +# github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e ## explicit github.com/devfile/registry-support/index/generator/schema # github.com/fsnotify/fsnotify v1.4.9