// NewCmdStartBuild implements the OpenShift cli start-build command func NewCmdStartBuild(fullName string, f *clientcmd.Factory, in io.Reader, out io.Writer) *cobra.Command { webhooks := util.StringFlag{} webhooks.Default("none") cmd := &cobra.Command{ Use: "start-build (BUILDCONFIG | --from-build=BUILD)", Short: "Start a new build", Long: startBuildLong, Example: fmt.Sprintf(startBuildExample, fullName), SuggestFor: []string{"build", "builds"}, Run: func(cmd *cobra.Command, args []string) { err := RunStartBuild(f, in, out, cmd, args, webhooks) cmdutil.CheckErr(err) }, } cmd.Flags().String("from-build", "", "Specify the name of a build which should be re-run") cmd.Flags().Bool("follow", false, "Start a build and watch its logs until it completes or fails") cmd.Flags().Bool("wait", false, "Wait for a build to complete and exit with a non-zero return code if the build fails") cmd.Flags().String("from-file", "", "A file use as the binary input for the build; example a pom.xml or Dockerfile. Will be the only file in the build source.") cmd.Flags().String("from-dir", "", "A directory to archive and use as the binary input for a build.") cmd.Flags().String("from-repo", "", "The path to a local source code repository to use as the binary input for a build.") cmd.Flags().String("commit", "", "Specify the source code commit identifier the build should use; requires a build based on a Git repository") cmd.Flags().Var(&webhooks, "list-webhooks", "List the webhooks for the specified build config or build; accepts 'all', 'generic', or 'github'") cmd.Flags().String("from-webhook", "", "Specify a webhook URL for an existing build config to trigger") cmd.Flags().String("git-post-receive", "", "The contents of the post-receive hook to trigger a build") cmd.Flags().String("git-repository", "", "The path to the git repository for post-receive; defaults to the current directory") return cmd }
// NewCmdStartBuild implements the OpenShift cli start-build command func NewCmdStartBuild(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { webhooks := util.StringFlag{} webhooks.Default("none") cmd := &cobra.Command{ Use: "start-build (BUILDCONFIG | --from-build=BUILD)", Short: "Starts a new build", Long: startBuildLong, Example: fmt.Sprintf(startBuildExample, fullName), SuggestFor: []string{"build", "builds"}, Run: func(cmd *cobra.Command, args []string) { err := RunStartBuild(f, out, cmd, args, webhooks) cmdutil.CheckErr(err) }, } cmd.Flags().String("from-build", "", "Specify the name of a build which should be re-run") cmd.Flags().String("commit", "", "Specify the commit hash the build should be run from") cmd.Flags().Bool("follow", false, "Start a build and watch its logs until it completes or fails") cmd.Flags().Bool("wait", false, "Wait for a build to complete and exit with a non-zero return code if the build fails") cmd.Flags().Var(&webhooks, "list-webhooks", "List the webhooks for the specified BuildConfig or build; accepts 'all', 'generic', or 'github'") cmd.Flags().String("from-webhook", "", "Specify a webhook URL for an existing BuildConfig to trigger") cmd.Flags().String("git-post-receive", "", "The contents of the post-receive hook to trigger a build") cmd.Flags().String("git-repository", "", "The path to the git repository for post-receive; defaults to the current directory") return cmd }
// RunStartBuild contains all the necessary functionality for the OpenShift cli start-build command func RunStartBuild(f *clientcmd.Factory, out io.Writer, cmd *cobra.Command, args []string, webhooks util.StringFlag) error { webhook := cmdutil.GetFlagString(cmd, "from-webhook") buildName := cmdutil.GetFlagString(cmd, "from-build") follow := cmdutil.GetFlagBool(cmd, "follow") switch { case len(webhook) > 0: if len(args) > 0 || len(buildName) > 0 { return cmdutil.UsageError(cmd, "The '--from-webhook' flag is incompatible with arguments or '--from-build'") } path := cmdutil.GetFlagString(cmd, "git-repository") postReceivePath := cmdutil.GetFlagString(cmd, "git-post-receive") repo := git.NewRepository() return RunStartBuildWebHook(f, out, webhook, path, postReceivePath, repo) case len(args) != 1 && len(buildName) == 0: return cmdutil.UsageError(cmd, "Must pass a name of a BuildConfig or specify build name with '--from-build' flag") } name := buildName isBuild := true if len(name) == 0 { name = args[0] isBuild = false } if webhooks.Provided() { return RunListBuildWebHooks(f, out, cmd.Out(), name, isBuild, webhooks.String()) } client, _, err := f.Clients() if err != nil { return err } namespace, _, err := f.DefaultNamespace() if err != nil { return err } request := &buildapi.BuildRequest{ ObjectMeta: kapi.ObjectMeta{Name: name}, } var newBuild *buildapi.Build if isBuild { if newBuild, err = client.Builds(namespace).Clone(request); err != nil { return err } } else { if newBuild, err = client.BuildConfigs(namespace).Instantiate(request); err != nil { return err } } fmt.Fprintf(out, "%s\n", newBuild.Name) if follow { opts := buildapi.BuildLogOptions{ Follow: true, NoWait: false, } rd, err := client.BuildLogs(namespace).Get(newBuild.Name, opts).Stream() if err != nil { return fmt.Errorf("error getting logs: %v", err) } defer rd.Close() _, err = io.Copy(out, rd) if err != nil { return fmt.Errorf("error streaming logs: %v", err) } } return nil }
// RunStartBuild contains all the necessary functionality for the OpenShift cli start-build command func RunStartBuild(f *clientcmd.Factory, in io.Reader, out io.Writer, cmd *cobra.Command, envParams []string, args []string, webhooks util.StringFlag) error { webhook := cmdutil.GetFlagString(cmd, "from-webhook") buildName := cmdutil.GetFlagString(cmd, "from-build") follow := cmdutil.GetFlagBool(cmd, "follow") commit := cmdutil.GetFlagString(cmd, "commit") waitForComplete := cmdutil.GetFlagBool(cmd, "wait") fromFile := cmdutil.GetFlagString(cmd, "from-file") fromDir := cmdutil.GetFlagString(cmd, "from-dir") fromRepo := cmdutil.GetFlagString(cmd, "from-repo") buildLogLevel := cmdutil.GetFlagString(cmd, "build-loglevel") switch { case len(webhook) > 0: if len(args) > 0 || len(buildName) > 0 || len(fromFile) > 0 || len(fromDir) > 0 || len(fromRepo) > 0 { return cmdutil.UsageError(cmd, "The '--from-webhook' flag is incompatible with arguments and all '--from-*' flags") } path := cmdutil.GetFlagString(cmd, "git-repository") postReceivePath := cmdutil.GetFlagString(cmd, "git-post-receive") repo := git.NewRepository() return RunStartBuildWebHook(f, out, webhook, path, postReceivePath, repo) case len(args) != 1 && len(buildName) == 0: return cmdutil.UsageError(cmd, "Must pass a name of a build config or specify build name with '--from-build' flag") } namespace, _, err := f.DefaultNamespace() if err != nil { return err } var ( name = buildName resource = "builds" ) if len(name) == 0 && len(args) > 0 && len(args[0]) > 0 { mapper, _ := f.Object() resource, name, err = osutil.ResolveResource("buildconfigs", args[0], mapper) if err != nil { return err } switch resource { case "buildconfigs": // no special handling required case "builds": return fmt.Errorf("use --from-build to rerun your builds") default: return fmt.Errorf("invalid resource provided: %s", resource) } } if len(name) == 0 { return fmt.Errorf("a resource name is required either as an argument or by using --from-build") } if webhooks.Provided() { return RunListBuildWebHooks(f, out, cmd.Out(), name, resource, webhooks.String()) } client, _, err := f.Clients() if err != nil { return err } env, _, err := ParseEnv(envParams, in) if err != nil { return err } if len(buildLogLevel) > 0 { env = append(env, kapi.EnvVar{Name: "BUILD_LOGLEVEL", Value: buildLogLevel}) } request := &buildapi.BuildRequest{ ObjectMeta: kapi.ObjectMeta{Name: name}, } if len(env) > 0 { request.Env = env } if len(commit) > 0 { request.Revision = &buildapi.SourceRevision{ Type: buildapi.BuildSourceGit, Git: &buildapi.GitSourceRevision{ Commit: commit, }, } } git := git.NewRepository() var newBuild *buildapi.Build switch { case len(args) > 0 && (len(fromFile) > 0 || len(fromDir) > 0 || len(fromRepo) > 0): request := &buildapi.BinaryBuildRequestOptions{ ObjectMeta: kapi.ObjectMeta{ Name: name, Namespace: namespace, }, Commit: commit, } if newBuild, err = streamPathToBuild(git, in, cmd.Out(), client.BuildConfigs(namespace), fromDir, fromFile, fromRepo, request); err != nil { return err } case resource == "builds": if newBuild, err = client.Builds(namespace).Clone(request); err != nil { return err } case resource == "buildconfigs": if newBuild, err = client.BuildConfigs(namespace).Instantiate(request); err != nil { return err } default: return fmt.Errorf("invalid resource provided: %s", resource) } fmt.Fprintln(out, newBuild.Name) // mapper, typer := f.Object() // resourceMapper := &resource.Mapper{ObjectTyper: typer, RESTMapper: mapper, ClientMapper: f.ClientMapperForCommand()} // info, err := resourceMapper.InfoForObject(newBuild) // if err != nil { // return err // } // shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" // cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "started") var ( wg sync.WaitGroup exitErr error ) // Wait for the build to complete if waitForComplete { wg.Add(1) go func() { defer wg.Done() exitErr = WaitForBuildComplete(client.Builds(namespace), newBuild.Name) }() } // Stream the logs from the build if follow { wg.Add(1) go func() { defer wg.Done() opts := buildapi.BuildLogOptions{ Follow: true, NoWait: false, } rd, err := client.BuildLogs(namespace).Get(newBuild.Name, opts).Stream() if err != nil { fmt.Fprintf(cmd.Out(), "error getting logs: %v\n", err) return } defer rd.Close() if _, err = io.Copy(out, rd); err != nil { fmt.Fprintf(cmd.Out(), "error streaming logs: %v\n", err) } }() } wg.Wait() return exitErr }
// RunStartBuild contains all the necessary functionality for the OpenShift cli start-build command func RunStartBuild(f *clientcmd.Factory, in io.Reader, out io.Writer, cmd *cobra.Command, args []string, webhooks util.StringFlag) error { webhook := cmdutil.GetFlagString(cmd, "from-webhook") buildName := cmdutil.GetFlagString(cmd, "from-build") follow := cmdutil.GetFlagBool(cmd, "follow") commit := cmdutil.GetFlagString(cmd, "commit") waitForComplete := cmdutil.GetFlagBool(cmd, "wait") fromFile := cmdutil.GetFlagString(cmd, "from-file") fromDir := cmdutil.GetFlagString(cmd, "from-dir") fromRepo := cmdutil.GetFlagString(cmd, "from-repo") //shortOutput := false //mapper, _ := f.Object() switch { case len(webhook) > 0: if len(args) > 0 || len(buildName) > 0 || len(fromFile) > 0 || len(fromDir) > 0 || len(fromRepo) > 0 { return cmdutil.UsageError(cmd, "The '--from-webhook' flag is incompatible with arguments and all '--from-*' flags") } path := cmdutil.GetFlagString(cmd, "git-repository") postReceivePath := cmdutil.GetFlagString(cmd, "git-post-receive") repo := git.NewRepository() return RunStartBuildWebHook(f, out, webhook, path, postReceivePath, repo) case len(args) != 1 && len(buildName) == 0: return cmdutil.UsageError(cmd, "Must pass a name of a build config or specify build name with '--from-build' flag") } name := buildName isBuild := true if len(name) == 0 { name = args[0] isBuild = false } if webhooks.Provided() { return RunListBuildWebHooks(f, out, cmd.Out(), name, isBuild, webhooks.String()) } client, _, err := f.Clients() if err != nil { return err } namespace, _, err := f.DefaultNamespace() if err != nil { return err } request := &buildapi.BuildRequest{ ObjectMeta: kapi.ObjectMeta{Name: name}, } if len(commit) > 0 { request.Revision = &buildapi.SourceRevision{ Type: buildapi.BuildSourceGit, Git: &buildapi.GitSourceRevision{ Commit: commit, }, } } git := git.NewRepository() var newBuild *buildapi.Build switch { case !isBuild && (len(fromFile) > 0 || len(fromDir) > 0 || len(fromRepo) > 0): request := &buildapi.BinaryBuildRequestOptions{ ObjectMeta: kapi.ObjectMeta{ Name: name, Namespace: namespace, }, Commit: commit, } if newBuild, err = streamPathToBuild(git, in, cmd.Out(), client.BuildConfigs(namespace), fromDir, fromFile, fromRepo, request); err != nil { return err } case isBuild: if newBuild, err = client.Builds(namespace).Clone(request); err != nil { return err } default: if newBuild, err = client.BuildConfigs(namespace).Instantiate(request); err != nil { return err } } //cmdutil.PrintSuccess(mapper, shortOutput, out, "Build", newBuild.Name, "started") fmt.Fprintln(out, newBuild.Name) var ( wg sync.WaitGroup exitErr error ) // Wait for the build to complete if waitForComplete { wg.Add(1) go func() { defer wg.Done() exitErr = WaitForBuildComplete(client.Builds(namespace), newBuild.Name) }() } // Stream the logs from the build if follow { wg.Add(1) go func() { defer wg.Done() opts := buildapi.BuildLogOptions{ Follow: true, NoWait: false, } rd, err := client.BuildLogs(namespace).Get(newBuild.Name, opts).Stream() if err != nil { fmt.Fprintf(cmd.Out(), "error getting logs: %v\n", err) return } defer rd.Close() if _, err = io.Copy(out, rd); err != nil { fmt.Fprintf(cmd.Out(), "error streaming logs: %v\n", err) } }() } wg.Wait() return exitErr }
func stringFlagFor(s string) util.StringFlag { var f util.StringFlag f.Set(s) return f }