Skip to content

Commit efbf366

Browse files
Merge pull request #20208 from soltysh/the_new_oc_2
Update expose, cancel-build & build-logs
2 parents a361b8d + 496e755 commit efbf366

File tree

9 files changed

+220
-146
lines changed

9 files changed

+220
-146
lines changed

Diff for: pkg/oc/cli/cmd/buildlogs.go

+51-36
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import (
44
"fmt"
55
"io"
66
"net/http"
7-
"os"
8-
"strings"
97

108
"github.com/spf13/cobra"
119

@@ -17,7 +15,6 @@ import (
1715
buildapi "github.com/openshift/origin/pkg/build/apis/build"
1816
buildmanualclient "github.com/openshift/origin/pkg/build/client/internalversion"
1917
buildclientinternal "github.com/openshift/origin/pkg/build/generated/internalclientset"
20-
buildutil "github.com/openshift/origin/pkg/build/util"
2118
)
2219

2320
var (
@@ -33,9 +30,27 @@ var (
3330
%[1]s build-logs 566bed879d2d`)
3431
)
3532

33+
type BuildLogsOptions struct {
34+
Follow bool
35+
NoWait bool
36+
37+
Name string
38+
Namespace string
39+
BuildClient buildclientinternal.Interface
40+
41+
genericclioptions.IOStreams
42+
}
43+
44+
func NewBuildLogsOptions(streams genericclioptions.IOStreams) *BuildLogsOptions {
45+
return &BuildLogsOptions{
46+
IOStreams: streams,
47+
Follow: true,
48+
}
49+
}
50+
3651
// NewCmdBuildLogs implements the OpenShift cli build-logs command
3752
func NewCmdBuildLogs(fullName string, f kcmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
38-
opts := buildapi.BuildLogOptions{}
53+
o := NewBuildLogsOptions(streams)
3954
cmd := &cobra.Command{
4055
Use: "build-logs BUILD",
4156
Short: "Show logs from a build",
@@ -44,43 +59,24 @@ func NewCmdBuildLogs(fullName string, f kcmdutil.Factory, streams genericcliopti
4459
Deprecated: fmt.Sprintf("use oc %v build/<build-name>", LogsRecommendedCommandName),
4560
Hidden: true,
4661
Run: func(cmd *cobra.Command, args []string) {
47-
err := RunBuildLogs(fullName, f, streams.Out, cmd, opts, args)
48-
49-
if err, ok := err.(errors.APIStatus); ok {
50-
if msg := err.Status().Message; strings.HasSuffix(msg, buildutil.NoBuildLogsMessage) {
51-
fmt.Fprintf(streams.Out, msg)
52-
os.Exit(1)
53-
}
54-
if err.Status().Code == http.StatusNotFound {
55-
switch err.Status().Details.Kind {
56-
case "build":
57-
fmt.Fprintf(streams.Out, "The build %s could not be found. Therefore build logs cannot be retrieved.\n", err.Status().Details.Name)
58-
case "pod":
59-
fmt.Fprintf(streams.Out, "The pod %s for build %s could not be found. Therefore build logs cannot be retrieved.\n", err.Status().Details.Name, args[0])
60-
}
61-
os.Exit(1)
62-
}
63-
}
64-
kcmdutil.CheckErr(err)
62+
kcmdutil.CheckErr(o.Complete(f, cmd, args))
63+
kcmdutil.CheckErr(o.RunBuildLogs())
6564
},
6665
}
67-
cmd.Flags().BoolVarP(&opts.Follow, "follow", "f", true, "Specify whether logs should be followed; default is true.")
68-
cmd.Flags().BoolVarP(&opts.NoWait, "nowait", "w", false, "Specify whether to return immediately without waiting for logs to be available; default is false.")
66+
cmd.Flags().BoolVarP(&o.Follow, "follow", "f", o.Follow, "Specify whether logs should be followed; default is true.")
67+
cmd.Flags().BoolVarP(&o.NoWait, "nowait", "w", o.NoWait, "Specify whether to return immediately without waiting for logs to be available; default is false.")
68+
6969
return cmd
7070
}
7171

72-
// RunBuildLogs contains all the necessary functionality for the OpenShift cli build-logs command
73-
func RunBuildLogs(fullName string, f kcmdutil.Factory, out io.Writer, cmd *cobra.Command, opts buildapi.BuildLogOptions, args []string) error {
72+
func (o *BuildLogsOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error {
7473
if len(args) != 1 {
75-
cmdNamespace := kcmdutil.GetFlagString(cmd, "namespace")
76-
var namespace string
77-
if cmdNamespace != "" {
78-
namespace = " -n " + cmdNamespace
79-
}
80-
return kcmdutil.UsageErrorf(cmd, "A build name is required - you can run `%s get builds%s` to list builds", fullName, namespace)
74+
return fmt.Errorf("build name is required")
8175
}
76+
o.Name = args[0]
8277

83-
namespace, _, err := f.ToRawKubeConfigLoader().Namespace()
78+
var err error
79+
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
8480
if err != nil {
8581
return err
8682
}
@@ -89,17 +85,36 @@ func RunBuildLogs(fullName string, f kcmdutil.Factory, out io.Writer, cmd *cobra
8985
if err != nil {
9086
return err
9187
}
92-
buildClient, err := buildclientinternal.NewForConfig(clientConfig)
88+
o.BuildClient, err = buildclientinternal.NewForConfig(clientConfig)
9389
if err != nil {
9490
return err
9591
}
9692

97-
readCloser, err := buildmanualclient.NewBuildLogClient(buildClient.Build().RESTClient(), namespace).Logs(args[0], opts).Stream()
93+
return nil
94+
}
95+
96+
// RunBuildLogs contains all the necessary functionality for the OpenShift cli build-logs command
97+
func (o *BuildLogsOptions) RunBuildLogs() error {
98+
opts := buildapi.BuildLogOptions{
99+
Follow: o.Follow,
100+
NoWait: o.NoWait,
101+
}
102+
readCloser, err := buildmanualclient.NewBuildLogClient(o.BuildClient.Build().RESTClient(), o.Namespace).Logs(o.Name, opts).Stream()
98103
if err != nil {
99104
return err
100105
}
101106
defer readCloser.Close()
102107

103-
_, err = io.Copy(out, readCloser)
108+
_, err = io.Copy(o.Out, readCloser)
109+
if err, ok := err.(errors.APIStatus); ok {
110+
if err.Status().Code == http.StatusNotFound {
111+
switch err.Status().Details.Kind {
112+
case "build":
113+
return fmt.Errorf("the build %s could not be found, therefore build logs cannot be retrieved", err.Status().Details.Name)
114+
case "pod":
115+
return fmt.Errorf("the pod %s for build %s could not be found, therefore build logs cannot be retrieved", err.Status().Details.Name, o.Name)
116+
}
117+
}
118+
}
104119
return err
105120
}

Diff for: pkg/oc/cli/cmd/cancelbuild.go

+54-43
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package cmd
33
import (
44
"errors"
55
"fmt"
6-
"io"
76
"strings"
87
"sync"
98
"time"
@@ -16,6 +15,7 @@ import (
1615
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
1716
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
1817
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
18+
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
1919

2020
buildapi "github.com/openshift/origin/pkg/build/apis/build"
2121
buildclient "github.com/openshift/origin/pkg/build/client"
@@ -56,96 +56,92 @@ var (
5656

5757
// CancelBuildOptions contains all the options for running the CancelBuild cli command.
5858
type CancelBuildOptions struct {
59-
In io.Reader
60-
Out, ErrOut io.Writer
61-
6259
DumpLogs bool
6360
Restart bool
6461
States []string
6562
Namespace string
6663
BuildNames []string
6764

68-
HasError bool
69-
ReportError func(error)
70-
Mapper meta.RESTMapper
71-
Client buildinternalclient.Interface
72-
BuildClient buildtypedclient.BuildResourceInterface
73-
BuildLister buildlister.BuildLister
65+
HasError bool
66+
ReportError func(error)
67+
PrinterCancel printers.ResourcePrinter
68+
PrinterRestart printers.ResourcePrinter
69+
Mapper meta.RESTMapper
70+
Client buildinternalclient.Interface
71+
BuildClient buildtypedclient.BuildResourceInterface
72+
BuildLister buildlister.BuildLister
7473

7574
// timeout is used by unit tests to shorten the polling period
7675
timeout time.Duration
76+
77+
genericclioptions.IOStreams
78+
}
79+
80+
func NewCancelBuildOptions(streams genericclioptions.IOStreams) *CancelBuildOptions {
81+
return &CancelBuildOptions{
82+
IOStreams: streams,
83+
States: []string{"new", "pending", "running"},
84+
}
7785
}
7886

7987
// NewCmdCancelBuild implements the OpenShift cli cancel-build command
8088
func NewCmdCancelBuild(name, baseName string, f kcmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
81-
o := &CancelBuildOptions{}
82-
89+
o := NewCancelBuildOptions(streams)
8390
cmd := &cobra.Command{
8491
Use: fmt.Sprintf("%s (BUILD | BUILDCONFIG)", name),
8592
Short: "Cancel running, pending, or new builds",
8693
Long: cancelBuildLong,
8794
Example: fmt.Sprintf(cancelBuildExample, baseName, name),
8895
SuggestFor: []string{"builds", "stop-build"},
8996
Run: func(cmd *cobra.Command, args []string) {
90-
kcmdutil.CheckErr(o.Complete(f, cmd, args, streams.In, streams.Out, streams.ErrOut))
97+
kcmdutil.CheckErr(o.Complete(f, cmd, args))
98+
kcmdutil.CheckErr(o.Validate())
9199
kcmdutil.CheckErr(o.RunCancelBuild())
92100
},
93101
}
94102

95103
cmd.Flags().StringSliceVar(&o.States, "state", o.States, "Only cancel builds in this state")
96104
cmd.Flags().BoolVar(&o.DumpLogs, "dump-logs", o.DumpLogs, "Specify if the build logs for the cancelled build should be shown.")
97105
cmd.Flags().BoolVar(&o.Restart, "restart", o.Restart, "Specify if a new build should be created after the current build is cancelled.")
106+
98107
return cmd
99108
}
100109

101110
// Complete completes all the required options.
102-
func (o *CancelBuildOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string, in io.Reader, out, errout io.Writer) error {
103-
o.In = in
104-
o.Out = out
105-
o.ErrOut = errout
111+
func (o *CancelBuildOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error {
112+
if len(args) == 0 {
113+
return fmt.Errorf("build or a buildconfig name is required")
114+
}
115+
106116
o.ReportError = func(err error) {
107117
o.HasError = true
108118
fmt.Fprintf(o.ErrOut, "error: %s\n", err.Error())
109119
}
110120

121+
// FIXME: this double printers should not be necessary
122+
o.PrinterCancel = &printers.NamePrinter{Operation: "cancelled"}
123+
o.PrinterRestart = &printers.NamePrinter{Operation: "restarted"}
124+
111125
if o.timeout.Seconds() == 0 {
112126
o.timeout = 30 * time.Second
113127
}
114128

115-
if len(args) == 0 {
116-
return kcmdutil.UsageErrorf(cmd, "Must pass a name of a build or a buildconfig to cancel")
117-
}
118-
119-
namespace, _, err := f.ToRawKubeConfigLoader().Namespace()
129+
var err error
130+
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
120131
if err != nil {
121132
return err
122133
}
123134

124-
if len(o.States) == 0 {
125-
// If --state is not specified, set the default to "new", "pending" and
126-
// "running".
127-
o.States = []string{"new", "pending", "running"}
128-
} else {
129-
for _, state := range o.States {
130-
if len(state) > 0 && !isStateCancellable(state) {
131-
return kcmdutil.UsageErrorf(cmd, "The '--state' flag has invalid value. Must be one of 'new', 'pending', or 'running'")
132-
}
133-
}
134-
}
135-
136135
config, err := f.ToRESTConfig()
137136
if err != nil {
138137
return err
139138
}
140-
client, err := buildinternalclient.NewForConfig(config)
139+
o.Client, err = buildinternalclient.NewForConfig(config)
141140
if err != nil {
142141
return err
143142
}
144-
145-
o.Namespace = namespace
146-
o.Client = client
147-
o.BuildLister = buildclient.NewClientBuildLister(client.Build())
148-
o.BuildClient = client.Build().Builds(namespace)
143+
o.BuildLister = buildclient.NewClientBuildLister(o.Client.Build())
144+
o.BuildClient = o.Client.Build().Builds(o.Namespace)
149145
o.Mapper, err = f.ToRESTMapper()
150146
if err != nil {
151147
return err
@@ -176,10 +172,19 @@ func (o *CancelBuildOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, ar
176172
return nil
177173
}
178174

175+
func (o *CancelBuildOptions) Validate() error {
176+
for _, state := range o.States {
177+
if len(state) > 0 && !isStateCancellable(state) {
178+
return fmt.Errorf("invalid --state flag value, must be one of 'new', 'pending', or 'running'")
179+
}
180+
}
181+
182+
return nil
183+
}
184+
179185
// RunCancelBuild implements all the necessary functionality for CancelBuild.
180186
func (o *CancelBuildOptions) RunCancelBuild() error {
181187
var builds []*buildapi.Build
182-
183188
for _, name := range o.BuildNames {
184189
build, err := o.BuildClient.Get(name, metav1.GetOptions{})
185190
if err != nil {
@@ -252,7 +257,10 @@ func (o *CancelBuildOptions) RunCancelBuild() error {
252257
return
253258
}
254259

255-
kcmdutil.PrintSuccess(false, o.Out, build, false, "cancelled")
260+
if err := o.PrinterCancel.PrintObj(kcmdutil.AsDefaultVersionedOrOriginal(build, nil), o.Out); err != nil {
261+
o.ReportError(fmt.Errorf("build %s/%s failed to print: %v", build.Namespace, build.Name, err))
262+
return
263+
}
256264
}(b)
257265
}
258266
wg.Wait()
@@ -265,7 +273,10 @@ func (o *CancelBuildOptions) RunCancelBuild() error {
265273
o.ReportError(fmt.Errorf("build %s/%s failed to restart: %v", b.Namespace, b.Name, err))
266274
continue
267275
}
268-
kcmdutil.PrintSuccess(false, o.Out, build, false, fmt.Sprintf("restarted build %q", b.Name))
276+
if err := o.PrinterRestart.PrintObj(kcmdutil.AsDefaultVersionedOrOriginal(b, nil), o.Out); err != nil {
277+
o.ReportError(fmt.Errorf("build %s/%s failed to print: %v", build.Namespace, build.Name, err))
278+
continue
279+
}
269280
}
270281
}
271282

0 commit comments

Comments
 (0)