Skip to content

Commit

Permalink
switch logs to externals
Browse files Browse the repository at this point in the history
  • Loading branch information
juanvallejo committed Jul 26, 2018
1 parent 3f9f93f commit 70c7679
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 79 deletions.
103 changes: 56 additions & 47 deletions pkg/oc/cli/logs/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ import (
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"

"github.com/openshift/api/apps"
"github.com/openshift/api/build"
appsapi "github.com/openshift/origin/pkg/apps/apis/apps"
appsv1 "github.com/openshift/api/apps/v1"
buildapiv1 "github.com/openshift/api/build/v1"
buildv1client "github.com/openshift/client-go/build/clientset/versioned/typed/build/v1"
buildapi "github.com/openshift/origin/pkg/build/apis/build"
buildclientinternal "github.com/openshift/origin/pkg/build/generated/internalclientset"
buildclient "github.com/openshift/origin/pkg/build/generated/internalclientset/typed/build/internalversion"
buildutil "github.com/openshift/origin/pkg/build/util"
)

Expand Down Expand Up @@ -68,11 +67,15 @@ type LogsOptions struct {
KubeLogOptions *kcmd.LogsOptions
// Client enables access to the Build object when processing
// build logs for Jenkins Pipeline Strategy builds
Client buildclient.BuildsGetter
Client buildv1client.BuildV1Interface
// Namespace is a required parameter when accessing the Build object when processing
// build logs for Jenkins Pipeline Strategy builds
Namespace string
Version int64

Builder func() *resource.Builder
Resources []string

Version int64

genericclioptions.IOStreams
}
Expand Down Expand Up @@ -105,9 +108,9 @@ func NewCmdLogs(name, baseName string, f kcmdutil.Factory, streams genericcliopt
return cmd
}

func isPipelineBuild(obj runtime.Object) (bool, *buildapi.BuildConfig, bool, *buildapi.Build, bool) {
bc, isBC := obj.(*buildapi.BuildConfig)
build, isBld := obj.(*buildapi.Build)
func isPipelineBuild(obj runtime.Object) (bool, *buildapiv1.BuildConfig, bool, *buildapiv1.Build, bool) {
bc, isBC := obj.(*buildapiv1.BuildConfig)
build, isBld := obj.(*buildapiv1.Build)
isPipeline := false
switch {
case isBC:
Expand Down Expand Up @@ -135,17 +138,49 @@ func (o *LogsOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st
if err != nil {
return err
}
client, err := buildclientinternal.NewForConfig(clientConfig)
o.Client, err = buildv1client.NewForConfig(clientConfig)
if err != nil {
return err
}
o.Client = client.Build()

o.Builder = f.NewBuilder
o.Resources = args

return nil
}

// Validate runs the upstream validation for the logs command and then it
// will validate any OpenShift-specific log options.
func (o *LogsOptions) Validate() error {
if err := o.KubeLogOptions.Validate(); err != nil {
return err
}
if o.Options == nil {
return nil
}
switch t := o.Options.(type) {
case *buildapiv1.BuildLogOptions:
if t.Previous && t.Version != nil {
return errors.New("cannot use both --previous and --version")
}
case *appsv1.DeploymentLogOptions:
if t.Previous && t.Version != nil {
return errors.New("cannot use both --previous and --version")
}
default:
return errors.New("invalid log options object provided")
}
return nil
}

// RunLog will run the upstream logs command and may use an OpenShift
// logOptions object.
func (o *LogsOptions) RunLog() error {
podLogOptions := o.KubeLogOptions.Options.(*kapi.PodLogOptions)
infos, err := f.NewBuilder().
infos, err := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
ResourceNames("pods", args...).
ResourceNames("pods", o.Resources...).
SingleResourceType().RequireObject(false).
Do().Infos()
if err != nil {
Expand All @@ -157,9 +192,9 @@ func (o *LogsOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st

// TODO: podLogOptions should be included in our own logOptions objects.
switch gr := infos[0].Mapping.Resource.GroupResource(); gr {
case build.Resource("builds"),
build.Resource("buildconfigs"):
bopts := &buildapi.BuildLogOptions{
case buildapiv1.Resource("builds"),
buildapiv1.Resource("buildconfigs"):
bopts := &buildapiv1.BuildLogOptions{
Follow: podLogOptions.Follow,
Previous: podLogOptions.Previous,
SinceSeconds: podLogOptions.SinceSeconds,
Expand All @@ -173,8 +208,8 @@ func (o *LogsOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st
}
o.Options = bopts

case apps.Resource("deploymentconfigs"):
dopts := &appsapi.DeploymentLogOptions{
case appsv1.Resource("deploymentconfigs"):
dopts := &appsv1.DeploymentLogOptions{
Container: podLogOptions.Container,
Follow: podLogOptions.Follow,
Previous: podLogOptions.Previous,
Expand All @@ -192,36 +227,10 @@ func (o *LogsOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st
o.Options = nil
}

return nil
}

// Validate runs the upstream validation for the logs command and then it
// will validate any OpenShift-specific log options.
func (o *LogsOptions) Validate() error {
if err := o.KubeLogOptions.Validate(); err != nil {
return err
}
if o.Options == nil {
return nil
}
switch t := o.Options.(type) {
case *buildapi.BuildLogOptions:
if t.Previous && t.Version != nil {
return errors.New("cannot use both --previous and --version")
}
case *appsapi.DeploymentLogOptions:
if t.Previous && t.Version != nil {
return errors.New("cannot use both --previous and --version")
}
default:
return errors.New("invalid log options object provided")
}
return nil
return o.runLogPipeline()
}

// RunLog will run the upstream logs command and may use an OpenShift
// logOptions object.
func (o *LogsOptions) RunLog() error {
func (o *LogsOptions) runLogPipeline() error {
if o.Options != nil {
// Use our own options object.
o.KubeLogOptions.Options = o.Options
Expand Down
66 changes: 34 additions & 32 deletions pkg/oc/cli/logs/logs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (
kcmd "k8s.io/kubernetes/pkg/kubectl/cmd"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"

buildv1 "github.com/openshift/api/build/v1"
buildfake "github.com/openshift/client-go/build/clientset/versioned/fake"
appsapi "github.com/openshift/origin/pkg/apps/apis/apps"
buildapi "github.com/openshift/origin/pkg/build/apis/build"
buildfake "github.com/openshift/origin/pkg/build/generated/internalclientset/fake"
)

// TestLogsFlagParity makes sure that our copied flags don't slip during rebases
Expand Down Expand Up @@ -46,16 +47,16 @@ func (f *fakeWriter) Write(p []byte) (n int, err error) {
}

func TestRunLogForPipelineStrategy(t *testing.T) {
bld := buildapi.Build{
bld := buildv1.Build{
ObjectMeta: metav1.ObjectMeta{
Name: "foo-0",
Namespace: "foo",
Annotations: map[string]string{buildapi.BuildJenkinsBlueOceanLogURLAnnotation: "https://foo"},
},
Spec: buildapi.BuildSpec{
CommonSpec: buildapi.CommonSpec{
Strategy: buildapi.BuildStrategy{
JenkinsPipelineStrategy: &buildapi.JenkinsPipelineBuildStrategy{},
Spec: buildv1.BuildSpec{
CommonSpec: buildv1.CommonSpec{
Strategy: buildv1.BuildStrategy{
JenkinsPipelineStrategy: &buildv1.JenkinsPipelineBuildStrategy{},
},
},
},
Expand All @@ -71,15 +72,15 @@ func TestRunLogForPipelineStrategy(t *testing.T) {
o: &bld,
},
{
o: &buildapi.BuildConfig{
o: &buildv1.BuildConfig{
ObjectMeta: metav1.ObjectMeta{
Namespace: "foo",
Name: "foo",
},
Spec: buildapi.BuildConfigSpec{
CommonSpec: buildapi.CommonSpec{
Strategy: buildapi.BuildStrategy{
JenkinsPipelineStrategy: &buildapi.JenkinsPipelineBuildStrategy{},
Spec: buildv1.BuildConfigSpec{
CommonSpec: buildv1.CommonSpec{
Strategy: buildv1.BuildStrategy{
JenkinsPipelineStrategy: &buildv1.JenkinsPipelineBuildStrategy{},
},
},
},
Expand All @@ -91,12 +92,13 @@ func TestRunLogForPipelineStrategy(t *testing.T) {
o := &LogsOptions{
IOStreams: streams,
KubeLogOptions: &kcmd.LogsOptions{
IOStreams: streams,
Object: tc.o,
Namespace: "foo",
},
Client: fakebc.Build(),
}
if err := o.RunLog(); err != nil {
if err := o.runLogPipeline(); err != nil {
t.Errorf("%#v: RunLog error %v", tc.o, err)
}
if !strings.Contains(out.String(), "https://foo") {
Expand All @@ -112,47 +114,47 @@ func TestIsPipelineBuild(t *testing.T) {
isPipeline bool
}{
{
o: &buildapi.Build{
Spec: buildapi.BuildSpec{
CommonSpec: buildapi.CommonSpec{
Strategy: buildapi.BuildStrategy{
JenkinsPipelineStrategy: &buildapi.JenkinsPipelineBuildStrategy{},
o: &buildv1.Build{
Spec: buildv1.BuildSpec{
CommonSpec: buildv1.CommonSpec{
Strategy: buildv1.BuildStrategy{
JenkinsPipelineStrategy: &buildv1.JenkinsPipelineBuildStrategy{},
},
},
},
},
isPipeline: true,
},
{
o: &buildapi.Build{
Spec: buildapi.BuildSpec{
CommonSpec: buildapi.CommonSpec{
Strategy: buildapi.BuildStrategy{
SourceStrategy: &buildapi.SourceBuildStrategy{},
o: &buildv1.Build{
Spec: buildv1.BuildSpec{
CommonSpec: buildv1.CommonSpec{
Strategy: buildv1.BuildStrategy{
SourceStrategy: &buildv1.SourceBuildStrategy{},
},
},
},
},
isPipeline: false,
},
{
o: &buildapi.BuildConfig{
Spec: buildapi.BuildConfigSpec{
CommonSpec: buildapi.CommonSpec{
Strategy: buildapi.BuildStrategy{
JenkinsPipelineStrategy: &buildapi.JenkinsPipelineBuildStrategy{},
o: &buildv1.BuildConfig{
Spec: buildv1.BuildConfigSpec{
CommonSpec: buildv1.CommonSpec{
Strategy: buildv1.BuildStrategy{
JenkinsPipelineStrategy: &buildv1.JenkinsPipelineBuildStrategy{},
},
},
},
},
isPipeline: true,
},
{
o: &buildapi.BuildConfig{
Spec: buildapi.BuildConfigSpec{
CommonSpec: buildapi.CommonSpec{
Strategy: buildapi.BuildStrategy{
DockerStrategy: &buildapi.DockerBuildStrategy{},
o: &buildv1.BuildConfig{
Spec: buildv1.BuildConfigSpec{
CommonSpec: buildv1.CommonSpec{
Strategy: buildv1.BuildStrategy{
DockerStrategy: &buildv1.DockerBuildStrategy{},
},
},
},
Expand Down
69 changes: 69 additions & 0 deletions pkg/oc/originpolymorphichelpers/logsforobject.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ import (
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"

appsv1 "github.com/openshift/api/apps/v1"
buildv1 "github.com/openshift/api/build/v1"
appsv1client "github.com/openshift/client-go/apps/clientset/versioned/typed/apps/v1"
buildv1client "github.com/openshift/client-go/build/clientset/versioned/typed/build/v1"
appsapi "github.com/openshift/origin/pkg/apps/apis/apps"
appsmanualclient "github.com/openshift/origin/pkg/apps/client/internalversion"
appsmanualclientv1 "github.com/openshift/origin/pkg/apps/client/v1"
appsclientinternal "github.com/openshift/origin/pkg/apps/generated/internalclientset"
buildapi "github.com/openshift/origin/pkg/build/apis/build"
buildapiv1 "github.com/openshift/origin/pkg/build/apis/build/v1"
buildmanualclient "github.com/openshift/origin/pkg/build/client/internalversion"
buildmanualclientv1 "github.com/openshift/origin/pkg/build/client/v1"
buildclientinternal "github.com/openshift/origin/pkg/build/generated/internalclientset"
buildutil "github.com/openshift/origin/pkg/build/util"
ocbuildapihelpers "github.com/openshift/origin/pkg/oc/lib/buildapihelpers"
Expand All @@ -40,6 +47,68 @@ func NewLogsForObjectFn(delegate polymorphichelpers.LogsForObjectFunc) polymorph
return nil, err
}
return appsmanualclient.NewRolloutLogClient(appsClient.Apps().RESTClient(), t.Namespace).Logs(t.Name, *dopts), nil
case *appsv1.DeploymentConfig:
dopts, ok := options.(*appsv1.DeploymentLogOptions)
if !ok {
return nil, errors.New("provided options object is not a DeploymentLogOptions")
}
appsClient, err := appsv1client.NewForConfig(clientConfig)
if err != nil {
return nil, err
}
return appsmanualclientv1.NewRolloutLogClient(appsClient.RESTClient(), t.Namespace).Logs(t.Name, *dopts), nil
case *buildv1.Build:
bopts, ok := options.(*buildv1.BuildLogOptions)
if !ok {
return nil, errors.New("provided options object is not a v1.BuildLogOptions")
}
if bopts.Version != nil {
return nil, errors.New("cannot specify a version and a build")
}
buildClient, err := buildv1client.NewForConfig(clientConfig)
if err != nil {
return nil, err
}
return buildmanualclientv1.NewBuildLogClient(buildClient.RESTClient(), t.Namespace).Logs(t.Name, *bopts), nil
case *buildv1.BuildConfig:
bopts, ok := options.(*buildv1.BuildLogOptions)
if !ok {
return nil, errors.New("provided options object is not a v1.BuildLogOptions")
}
if bopts.Version != nil {
return nil, errors.New("cannot specify a version and a build")
}
buildClient, err := buildv1client.NewForConfig(clientConfig)
if err != nil {
return nil, err
}
logClient := buildmanualclientv1.NewBuildLogClient(buildClient.RESTClient(), t.Namespace)
builds, err := buildClient.Builds(t.Namespace).List(metav1.ListOptions{})
if err != nil {
return nil, err
}

// convert to internal in order to filter
internalBuildItems := []buildapi.Build{}
for _, external := range builds.Items {
internal := &buildapi.Build{}
if err := buildapiv1.Convert_v1_Build_To_build_Build(&external, internal, nil); err != nil {
return nil, err
}
internalBuildItems = append(internalBuildItems, *internal)
}

filteredInternalBuildItems := ocbuildapihelpers.FilterBuilds(internalBuildItems, ocbuildapihelpers.ByBuildConfigPredicate(t.Name))
if len(filteredInternalBuildItems) == 0 {
return nil, fmt.Errorf("no builds found for %q", t.Name)
}
if bopts.Version != nil {
// If a version has been specified, try to get the logs from that build.
desired := buildutil.BuildNameForConfigVersion(t.Name, int(*bopts.Version))
return logClient.Logs(desired, *bopts), nil
}
sort.Sort(sort.Reverse(ocbuildapihelpers.BuildSliceByCreationTimestamp(filteredInternalBuildItems)))
return logClient.Logs(filteredInternalBuildItems[0].Name, *bopts), nil
case *buildapi.Build:
bopts, ok := options.(*buildapi.BuildLogOptions)
if !ok {
Expand Down

0 comments on commit 70c7679

Please sign in to comment.