Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for PipelineRun minimal embedded status #1617

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 36 additions & 22 deletions pkg/cmd/pipelinerun/logs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
pipelinetest "github.com/tektoncd/pipeline/test/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"knative.dev/pkg/apis"
Expand Down Expand Up @@ -258,13 +259,13 @@ func TestPipelinerunLogs(t *testing.T) {
},
}

trs := []*v1alpha1.TaskRun{
trs := []*v1beta1.TaskRun{
{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns,
Name: tr1Name,
},
Spec: v1alpha1.TaskRunSpec{
Spec: v1beta1.TaskRunSpec{
TaskRef: &v1beta1.TaskRef{
Name: task1Name,
},
Expand Down Expand Up @@ -307,7 +308,7 @@ func TestPipelinerunLogs(t *testing.T) {
Namespace: ns,
Name: tr2Name,
},
Spec: v1alpha1.TaskRunSpec{
Spec: v1beta1.TaskRunSpec{
TaskRef: &v1beta1.TaskRef{
Name: task2Name,
},
Expand Down Expand Up @@ -347,23 +348,36 @@ func TestPipelinerunLogs(t *testing.T) {
},
}

prs := []*v1alpha1.PipelineRun{
prs := []*v1beta1.PipelineRun{
{
ObjectMeta: metav1.ObjectMeta{
Name: prName,
Namespace: ns,
Labels: map[string]string{"tekton.dev/pipeline": prName},
},
Spec: v1alpha1.PipelineRunSpec{
PipelineRef: &v1alpha1.PipelineRef{
Spec: v1beta1.PipelineRunSpec{
PipelineRef: &v1beta1.PipelineRef{
Name: pipelineName,
},
},
Status: v1alpha1.PipelineRunStatus{
PipelineRunStatusFields: v1alpha1.PipelineRunStatusFields{
TaskRuns: map[string]*v1alpha1.PipelineRunTaskRunStatus{
tr1Name: {PipelineTaskName: task1Name, Status: &trs[0].Status},
tr2Name: {PipelineTaskName: task2Name, Status: &trs[1].Status},
Status: v1beta1.PipelineRunStatus{
PipelineRunStatusFields: v1beta1.PipelineRunStatusFields{
ChildReferences: []v1beta1.ChildStatusReference{
{
Name: tr1Name,
PipelineTaskName: task1Name,
TypeMeta: runtime.TypeMeta{
APIVersion: "tekton.dev/v1beta1",
Kind: "TaskRun",
},
}, {
Name: tr2Name,
PipelineTaskName: task2Name,
TypeMeta: runtime.TypeMeta{
APIVersion: "tekton.dev/v1beta1",
Kind: "TaskRun",
},
},
},
},
Status: duckv1beta1.Status{
Expand All @@ -377,23 +391,23 @@ func TestPipelinerunLogs(t *testing.T) {
},
},
}
pps := []*v1alpha1.Pipeline{
pps := []*v1beta1.Pipeline{
{
ObjectMeta: metav1.ObjectMeta{
Name: pipelineName,
Namespace: ns,
},
Spec: v1alpha1.PipelineSpec{
Tasks: []v1alpha1.PipelineTask{
Spec: v1beta1.PipelineSpec{
Tasks: []v1beta1.PipelineTask{
{
Name: task1Name,
TaskRef: &v1alpha1.TaskRef{
TaskRef: &v1beta1.TaskRef{
Name: task1Name,
},
},
{
Name: task2Name,
TaskRef: &v1alpha1.TaskRef{
TaskRef: &v1beta1.TaskRef{
Name: task2Name,
},
},
Expand Down Expand Up @@ -532,19 +546,19 @@ func TestPipelinerunLogs(t *testing.T) {

for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
cs, _ := test.SeedTestData(t, pipelinetest.Data{PipelineRuns: prs, Pipelines: pps, TaskRuns: trs, Pods: p, Namespaces: nsList})
cs, _ := test.SeedV1beta1TestData(t, pipelinev1beta1test.Data{PipelineRuns: prs, Pipelines: pps, TaskRuns: trs, Pods: p, Namespaces: nsList})
cs.Pipeline.Resources = cb.APIResourceList(versionA1, []string{"task", "taskrun", "pipeline", "pipelinerun"})
tdc := testDynamic.Options{}
dc, err := tdc.Client(
cb.UnstructuredP(pps[0], versionA1),
cb.UnstructuredPR(prs[0], versionA1),
cb.UnstructuredTR(trs[0], versionA1),
cb.UnstructuredTR(trs[1], versionA1),
cb.UnstructuredV1beta1P(pps[0], versionA1),
cb.UnstructuredV1beta1PR(prs[0], versionA1),
cb.UnstructuredV1beta1TR(trs[0], versionA1),
cb.UnstructuredV1beta1TR(trs[1], versionA1),
)
if err != nil {
t.Errorf("unable to create dynamic client: %v", err)
}
prlo := logOptsv1aplha1(prName, ns, cs, dc, fake.Streamer(fakeLogs), s.allSteps, false, s.prefixing, s.tasks...)
prlo := logOptsv1beta1(prName, ns, cs, dc, fake.Streamer(fakeLogs), s.allSteps, false, s.prefixing, s.tasks...)
output, _ := fetchLogs(prlo)

expected := strings.Join(s.expectedLogs, "\n") + "\n"
Expand Down
96 changes: 92 additions & 4 deletions pkg/pipelinerun/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
prsort "github.com/tektoncd/cli/pkg/pipelinerun/sort"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -71,16 +73,28 @@ func List(c *cli.Clients, opts metav1.ListOptions, ns string) (*v1beta1.Pipeline
return nil, err
}

var runs *v1beta1.PipelineRunList
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPR.UnstructuredContent(), &runs); err != nil {
var prList *v1beta1.PipelineRunList
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPR.UnstructuredContent(), &prList); err != nil {
return nil, err
}
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to list pipelineruns from %s namespace \n", ns)
return nil, err
}

return runs, nil
var populatedPRs []v1beta1.PipelineRun

for _, pr := range prList.Items {
updatedPR, err := populatePipelineRunTaskStatuses(c, ns, pr)
if err != nil {
return nil, err
}
populatedPRs = append(populatedPRs, *updatedPR)
}

prList.Items = populatedPRs

return prList, nil
}

// It will fetch the resource based on the api available and return v1beta1 form
Expand Down Expand Up @@ -117,7 +131,13 @@ func GetV1beta1(c *cli.Clients, prname string, opts metav1.GetOptions, ns string
fmt.Fprintf(os.Stderr, "Failed to get pipelinerun from %s namespace \n", ns)
return nil, err
}
return pipelinerun, nil

populatedPR, err := populatePipelineRunTaskStatuses(c, ns, *pipelinerun)
if err != nil {
return nil, err
}

return populatedPR, nil
}

// It will fetch the resource in v1alpha1 struct format
Expand Down Expand Up @@ -209,3 +229,71 @@ func createUnstructured(obj runtime.Object, c *cli.Clients, opts metav1.CreateOp

return pipelinerun, nil
}

func populatePipelineRunTaskStatuses(c *cli.Clients, ns string, pr v1beta1.PipelineRun) (*v1beta1.PipelineRun, error) {
taskRunMap, runMap, err := getFullPipelineTaskStatuses(context.Background(), c.Tekton, ns, &pr)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get TaskRun and Run statuses for PipelineRun %s from namespace %s\n", pr.Name, ns)
return nil, err
}
pr.Status.TaskRuns = taskRunMap
pr.Status.Runs = runMap

return &pr, nil
}

// getFullPipelineTaskStatuses returns populated TaskRun and Run status maps for a PipelineRun from its ChildReferences.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// If the PipelineRun has no ChildReferences, its .Status.TaskRuns and .Status.Runs will be returned instead.
// TODO(abayer): Remove in favor of github.com/tektoncd/pipeline/pkg/status.GetFullPipelineTaskStatuses when CLI can move to Pipeline v0.36.0 or later.
func getFullPipelineTaskStatuses(ctx context.Context, client versioned.Interface, ns string, pr *v1beta1.PipelineRun) (map[string]*v1beta1.PipelineRunTaskRunStatus,
map[string]*v1beta1.PipelineRunRunStatus, error) {
// If the PipelineRun is nil, just return
if pr == nil {
return nil, nil, nil
}

// If there are no child references or either TaskRuns or Runs is non-zero, return the existing TaskRuns and Runs maps
if len(pr.Status.ChildReferences) == 0 || len(pr.Status.TaskRuns) > 0 || len(pr.Status.Runs) > 0 {
return pr.Status.TaskRuns, pr.Status.Runs, nil
}

trStatuses := make(map[string]*v1beta1.PipelineRunTaskRunStatus)
runStatuses := make(map[string]*v1beta1.PipelineRunRunStatus)

for _, cr := range pr.Status.ChildReferences {
switch cr.Kind {
case "TaskRun":
tr, err := client.TektonV1beta1().TaskRuns(ns).Get(ctx, cr.Name, metav1.GetOptions{})
if err != nil && !errors.IsNotFound(err) {
return nil, nil, err
}

trStatuses[cr.Name] = &v1beta1.PipelineRunTaskRunStatus{
PipelineTaskName: cr.PipelineTaskName,
WhenExpressions: cr.WhenExpressions,
}

if tr != nil {
trStatuses[cr.Name].Status = &tr.Status
}
case "Run":
r, err := client.TektonV1alpha1().Runs(ns).Get(ctx, cr.Name, metav1.GetOptions{})
if err != nil && !errors.IsNotFound(err) {
return nil, nil, err
}

runStatuses[cr.Name] = &v1beta1.PipelineRunRunStatus{
PipelineTaskName: cr.PipelineTaskName,
WhenExpressions: cr.WhenExpressions,
}

if r != nil {
runStatuses[cr.Name].Status = &r.Status
}
default:
// Don't do anything for unknown types.
}
}

return trStatuses, runStatuses, nil
}
Loading