// AddDockerfile adds a Dockerfile passed in the command line to the reference // builder. func AddDockerfileToSourceRepositories(b *app.ReferenceBuilder, dockerfile string) error { _, repos, errs := b.Result() if err := kutilerrors.NewAggregate(errs); err != nil { return err } switch len(repos) { case 0: // Create a new SourceRepository with the Dockerfile. repo, err := app.NewSourceRepositoryForDockerfile(dockerfile) if err != nil { return fmt.Errorf("provided Dockerfile is not valid: %v", err) } b.AddExistingSourceRepository(repo) case 1: // Add the Dockerfile to the existing SourceRepository, so that // eventually we generate a single BuildConfig with multiple // sources. if err := repos[0].AddDockerfile(dockerfile); err != nil { return fmt.Errorf("provided Dockerfile is not valid: %v", err) } default: // Invalid. return errors.New("--dockerfile cannot be used with multiple source repositories") } return nil }
// set up the components to be used by the reference builder func (c *AppConfig) addReferenceBuilderComponents(b *app.ReferenceBuilder) { b.AddComponents(c.DockerImages, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--docker-image=%q", input.From) input.Searcher = c.dockerSearcher if c.dockerSearcher != nil { input.Resolver = app.UniqueExactOrInexactMatchResolver{Searcher: c.dockerSearcher} } return input }) b.AddComponents(c.ImageStreams, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--image-stream=%q", input.From) input.Searcher = c.imageStreamSearcher if c.imageStreamSearcher != nil { input.Resolver = app.FirstMatchResolver{Searcher: c.imageStreamSearcher} } return input }) b.AddComponents(c.Templates, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--template=%q", input.From) input.Searcher = c.templateSearcher if c.templateSearcher != nil { input.Resolver = app.HighestScoreResolver{Searcher: c.templateSearcher} } return input }) b.AddComponents(c.TemplateFiles, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--file=%q", input.From) input.Searcher = c.templateFileSearcher if c.templateFileSearcher != nil { input.Resolver = app.FirstMatchResolver{Searcher: c.templateFileSearcher} } return input }) b.AddComponents(c.Components, func(input *app.ComponentInput) app.ComponentReference { resolver := app.PerfectMatchWeightedResolver{} searcher := app.MultiWeightedSearcher{} if c.imageStreamSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.imageStreamSearcher, Weight: 0.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: c.imageStreamSearcher, Weight: 0.0}) } if c.templateSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.templateSearcher, Weight: 0.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: c.templateSearcher, Weight: 0.0}) } if c.templateFileSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.templateFileSearcher, Weight: 0.0}) } if c.dockerSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.dockerSearcher, Weight: 2.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: c.dockerSearcher, Weight: 1.0}) } input.Resolver = resolver input.Searcher = searcher return input }) }
// ComponentsForSourceRepositories creates components for repositories that have not been previously associated by a // builder. These components have already gone through source code detection and have a SourceRepositoryInfo attached // to them. func AddMissingComponentsToRefBuilder( b *app.ReferenceBuilder, repositories app.SourceRepositories, dockerfileResolver, sourceResolver app.Resolver, g *GenerationInputs, ) (app.ComponentReferences, error) { errs := []error{} result := app.ComponentReferences{} for _, repo := range repositories { info := repo.Info() switch { case info == nil: errs = append(errs, fmt.Errorf("source not detected for repository %q", repo)) continue case info.Dockerfile != nil && (len(g.Strategy) == 0 || g.Strategy == "docker"): node := info.Dockerfile.AST() baseImage := dockerfileutil.LastBaseImage(node) if baseImage == "" { errs = append(errs, fmt.Errorf("the Dockerfile in the repository %q has no FROM instruction", info.Path)) continue } refs := b.AddComponents([]string{baseImage}, func(input *app.ComponentInput) app.ComponentReference { input.Resolver = dockerfileResolver input.Use(repo) input.ExpectToBuild = true repo.UsedBy(input) repo.BuildWithDocker() return input }) result = append(result, refs...) default: // TODO: Add support for searching for more than one language if len(info.Types) > 1 if len(info.Types) == 0 { errs = append(errs, fmt.Errorf("no language was detected for repository at %q; please specify a builder image to use with your repository: [builder-image]~%s", repo, repo)) continue } refs := b.AddComponents([]string{info.Types[0].Term()}, func(input *app.ComponentInput) app.ComponentReference { input.Resolver = sourceResolver input.ExpectToBuild = true input.Use(repo) repo.UsedBy(input) return input }) result = append(result, refs...) } } return result, errors.NewAggregate(errs) }
// AddSourceRepositoriesToRefBuilder adds the provided repositories to the reference builder, identifies which // should be built using Docker, and then returns the full list of source repositories. func AddSourceRepositoriesToRefBuilder(b *app.ReferenceBuilder, repos []string, g *GenerationInputs) (app.SourceRepositories, error) { for _, s := range repos { if repo, ok := b.AddSourceRepository(s); ok { repo.SetContextDir(g.ContextDir) if g.Strategy == "docker" { repo.BuildWithDocker() } } } if len(g.Dockerfile) > 0 { if len(g.Strategy) != 0 && g.Strategy != "docker" { return nil, errors.New("when directly referencing a Dockerfile, the strategy must must be 'docker'") } if err := AddDockerfileToSourceRepositories(b, g.Dockerfile); err != nil { return nil, err } } _, result, errs := b.Result() return result, kutilerrors.NewAggregate(errs) }
// set up the components to be used by the reference builder func (c *AppConfig) addReferenceBuilderComponents(b *app.ReferenceBuilder) { b.AddComponents(c.DockerImages, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--docker-image=%q", input.From) input.Searcher = c.dockerSearcher if c.dockerSearcher != nil { resolver := app.PerfectMatchWeightedResolver{} resolver = append(resolver, app.WeightedResolver{Searcher: c.dockerSearcher, Weight: 0.0}) if c.AllowMissingImages { resolver = append(resolver, app.WeightedResolver{Searcher: app.MissingImageSearcher{}, Weight: 100.0}) } input.Resolver = resolver } return input }) b.AddComponents(c.ImageStreams, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--image-stream=%q", input.From) input.Searcher = c.imageStreamSearcher if c.imageStreamSearcher != nil { input.Resolver = app.FirstMatchResolver{Searcher: c.imageStreamSearcher} } return input }) b.AddComponents(c.Templates, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--template=%q", input.From) input.Searcher = c.templateSearcher if c.templateSearcher != nil { input.Resolver = app.HighestScoreResolver{Searcher: c.templateSearcher} } return input }) b.AddComponents(c.TemplateFiles, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--file=%q", input.From) input.Searcher = c.templateFileSearcher if c.templateFileSearcher != nil { input.Resolver = app.FirstMatchResolver{Searcher: c.templateFileSearcher} } return input }) b.AddComponents(c.Components, func(input *app.ComponentInput) app.ComponentReference { resolver := app.PerfectMatchWeightedResolver{} searcher := app.MultiWeightedSearcher{} if c.imageStreamSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.imageStreamSearcher, Weight: 0.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: c.imageStreamSearcher, Weight: 0.0}) } if c.templateSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.templateSearcher, Weight: 0.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: c.templateSearcher, Weight: 0.0}) } if c.templateFileSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.templateFileSearcher, Weight: 0.0}) } if c.dockerSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: c.dockerSearcher, Weight: 2.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: c.dockerSearcher, Weight: 1.0}) } if c.AllowMissingImages { resolver = append(resolver, app.WeightedResolver{Searcher: app.MissingImageSearcher{}, Weight: 100.0}) } input.Resolver = resolver input.Searcher = searcher return input }) _, repos, _ := b.Result() for _, repo := range repos { repo.SetContextDir(c.ContextDir) } }
// AddComponentInputsToRefBuilder set up the components to be used by the reference builder. func AddComponentInputsToRefBuilder(b *app.ReferenceBuilder, r *Resolvers, c *ComponentInputs, g *GenerationInputs) error { // lookup source repositories first (before processing the component inputs) repositories, err := AddSourceRepositoriesToRefBuilder(b, c.SourceRepositories, g) if err != nil { return err } // identify the types of the provided source locations if err := DetectSource(repositories, r.Detector, g); err != nil { return err } b.AddComponents(c.DockerImages, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--docker-image=%q", input.From) input.Searcher = r.DockerSearcher if r.DockerSearcher != nil { resolver := app.PerfectMatchWeightedResolver{} resolver = append(resolver, app.WeightedResolver{Searcher: r.DockerSearcher, Weight: 0.0}) if r.AllowMissingImages { resolver = append(resolver, app.WeightedResolver{Searcher: app.MissingImageSearcher{}, Weight: 100.0}) } input.Resolver = resolver } return input }) b.AddComponents(c.ImageStreams, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--image-stream=%q", input.From) input.Searcher = r.ImageStreamSearcher if r.ImageStreamSearcher != nil { resolver := app.PerfectMatchWeightedResolver{ app.WeightedResolver{Searcher: r.ImageStreamSearcher}, } input.Resolver = resolver } return input }) b.AddComponents(c.Templates, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--template=%q", input.From) input.Searcher = r.TemplateSearcher if r.TemplateSearcher != nil { input.Resolver = app.HighestUniqueScoreResolver{Searcher: r.TemplateSearcher} } return input }) b.AddComponents(c.TemplateFiles, func(input *app.ComponentInput) app.ComponentReference { input.Argument = fmt.Sprintf("--file=%q", input.From) if r.TemplateFileSearcher != nil { input.Resolver = app.FirstMatchResolver{Searcher: r.TemplateFileSearcher} } input.Searcher = r.TemplateFileSearcher return input }) b.AddComponents(c.Components, func(input *app.ComponentInput) app.ComponentReference { resolver := app.PerfectMatchWeightedResolver{} searcher := app.MultiWeightedSearcher{} if r.ImageStreamSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: r.ImageStreamSearcher, Weight: 0.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: r.ImageStreamSearcher, Weight: 0.0}) } if r.TemplateSearcher != nil && !input.ExpectToBuild { resolver = append(resolver, app.WeightedResolver{Searcher: r.TemplateSearcher, Weight: 0.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: r.TemplateSearcher, Weight: 0.0}) } if r.TemplateFileSearcher != nil && !input.ExpectToBuild { resolver = append(resolver, app.WeightedResolver{Searcher: r.TemplateFileSearcher, Weight: 0.0}) } if r.DockerSearcher != nil { resolver = append(resolver, app.WeightedResolver{Searcher: r.DockerSearcher, Weight: 2.0}) searcher = append(searcher, app.WeightedSearcher{Searcher: r.DockerSearcher, Weight: 1.0}) } if r.AllowMissingImages { resolver = append(resolver, app.WeightedResolver{Searcher: app.MissingImageSearcher{}, Weight: 100.0}) } input.Resolver = resolver input.Searcher = searcher return input }) b.AddGroups(c.Groups) return nil }