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

Create Tekton based Pipeline which has capability to run against multiple tekton pipelines versions #373

Closed
bobcatfish opened this issue Jun 18, 2020 · 9 comments
Assignees
Labels
area/test-infra Issues or PRs related to the testing infrastructure kind/feature Categorizes issue or PR as related to a new feature. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.

Comments

@bobcatfish
Copy link
Contributor

Expected Behavior

Actual Behavior

All catalog Tasks are tested against 1 version of Tekton Pipelines, hard coded at https://github.com/tektoncd/catalog/blob/v1beta1/test/e2e-tests.sh#L19

Additional Info

Overall catalog test infrastructure proposal

@bobcatfish bobcatfish self-assigned this Jun 18, 2020
@bobcatfish bobcatfish added the kind/feature Categorizes issue or PR as related to a new feature. label Jun 18, 2020
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jun 18, 2020
Eventually we want to be able to have Tasks declare what versions they
are compatible with and test against those
(tektoncd#373) but in the meantime, it
seems reasonable to bump the version every time we do a release (and
even once we have tektoncd#373, we would want to be running tests against new
versions as well - and this could have the benefit of giving us
information about issues in a release early, before users notice them!)
bobcatfish added a commit to bobcatfish/pipeline that referenced this issue Jun 18, 2020
Eventually we want to be able to have Tasks declare what versions they
are compatible with and test against those
(tektoncd/catalog#373) but in the meantime, it
seems reasonable to bump the version used in catalog tests every time we
do a release (and even once we have tektoncd/catalog#373,
we would want to be running tests against new versions as well - and this
could have the benefit of giving us information about issues in a release
early, before users notice them!)

Question: how does the person making the release ensure that this bump
didn't make anything start failing? I think we should still make this
part of the process before we figure this out entirely, but we might
want to create a cron or something that runs all the tests nightly, and
maybe have the build cop trigger the release manually to ensure there
aren't any problems?
tekton-robot pushed a commit that referenced this issue Jun 18, 2020
Eventually we want to be able to have Tasks declare what versions they
are compatible with and test against those
(#373) but in the meantime, it
seems reasonable to bump the version every time we do a release (and
even once we have #373, we would want to be running tests against new
versions as well - and this could have the benefit of giving us
information about issues in a release early, before users notice them!)
@chmouel
Copy link
Member

chmouel commented Jun 23, 2020

Really cool, it would be really nice to have.

I wonder what's is the best way to do this tho. Since pipeline supports does not support per namespace install.

Perhaps something like this :

  • Collect all pipeline versions of all tasks in catalog
  • for each pipeline versions, un-install the previous and install the new pipeline version.
  • Run all catalog tasks that want that specifics version against it.
  • Redo the same for others.

Or IOW in pseudo code this may look like this :

  for version in all_unique_versions_from_all_tasks():
       if pipeline_installed() is True:
       		uninstall_pipeline()
       install_pipeline(version)
       for task in all_task_that_has_dependency_on_pipeline_version(version):
			test_task(task)

The main issue I see is that this is going to take a lot of time for test run..

Perhaps we want to start to implement the feature to only test tasks that has been changed/added first?

@bobcatfish
Copy link
Contributor Author

Hey @chmouel ! There's a sketch for how this could look in the test infra design doc - i'm (slowly) working on a prototype, my biggest goal is to do this using tekton pipelines

  1. Collect all pipeline versions of all tasks in catalog
  2. for each pipeline versions, un-install the previous and install the new pipeline version.

For (2) I want to do that with a Pipeline that takes a version as an argument - also if we use boskos we can create multiple clusters and install whatever versions we want. If we use a completely separate GCP project for each one we're going to run out pretty quickly tho.

This is the psuedo pipeline code I've got so far:

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: catalog-test
spec:
  params:
    - name: pipelines-version
      default: "v0.13.2"
      description: The verision of tekton-pipelines to install and test with
    - name: task-paths
      description: A comma separated lists of the paths to the catalog tasks to test
  workspaces:
    - name: kubeconfig
    - name: project-creds
    - name: cluster-creds
  tasks:
    - name: get-project
      taskRef:
        name: boskos
      workspaces:
        - name: project-creds
          workspace: project-creds
    - name: make-cluster
      params:
        - name: project-name
          value: $(tasks.get-boskos-project.project-name)
      taskRef:
        name: tbd
      # Post https://github.com/tektoncd/pipeline/issues/1878 indicate workspace dependency instead
      runAfter: [get-project]
      workspaces:
        - name: kubeconfig
          workspace: kubeconfig
        - name: project-creds
          workspace: project-creds
        - name: cluster-creds
          workspace: cluster-creds
    - name: install-pipelines
      taskRef:
        name: kubectl
      # Post https://github.com/tektoncd/pipeline/issues/1878 indicate workspace dependency instead
      runAfter: [make-cluster]
      workspaces:
        - name: kubeconfig
          workspace: kubeconfig
        - name: creds
          workspace: cluster-creds
    - name: apply-tasks
      taskRef:
        name: kubectl
      runAfter: [install-pipelines]
      workspaces:
        - name: kubeconfig
          workspace: kubeconfig
        - name: creds
          workspace: cluster-creds
    - name: release-project
      taskRef:
        name: boskos
      workspaces:
        - name: project-creds
          workspace: project-creds

My next step is to start creating some of the individual tasks we'd need, e.g. the boskos task.

tekton-robot pushed a commit to tektoncd/pipeline that referenced this issue Jun 23, 2020
Eventually we want to be able to have Tasks declare what versions they
are compatible with and test against those
(tektoncd/catalog#373) but in the meantime, it
seems reasonable to bump the version used in catalog tests every time we
do a release (and even once we have tektoncd/catalog#373,
we would want to be running tests against new versions as well - and this
could have the benefit of giving us information about issues in a release
early, before users notice them!)

Question: how does the person making the release ensure that this bump
didn't make anything start failing? I think we should still make this
part of the process before we figure this out entirely, but we might
want to create a cron or something that runs all the tests nightly, and
maybe have the build cop trigger the release manually to ensure there
aren't any problems?
@vdemeester vdemeester added the area/test-infra Issues or PRs related to the testing infrastructure label Jun 24, 2020
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 10, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 10, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 10, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 10, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 14, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 20, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 22, 2020
As part of tektoncd#373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog. This Task creates a cluster within a GKE
project and is based on the way we create clusters for the existing end
to end tests we have in Tekton, which are themselves based on Knative,
when are THEMselves based on k8s. These tests all use a tool called
kubetest, which is responsible for invoking boskos (see tektoncd#408) and
creating a GKE cluster
(https://github.com/kubernetes/test-infra/tree/master/kubetest).

This Task attempts to create a cluster in the same way, which based on the
output in the end to end logs seems to consist of creating the cluster
and setting up a firewall for it.

I'm not sure if this belongs in the catalog itself since it is specific
to our own end to end tests and isn't as generic as other catalog tests,
so if we want to move this into the test directory that seems fine, but
I also think it could be an okay addition to the catalog on its own (esp
if other k8s based projects that test against GKE want to use it.)
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 22, 2020
As part of tektoncd#373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog. This Task creates a cluster within a GKE
project and is based on the way we create clusters for the existing end
to end tests we have in Tekton, which are themselves based on Knative,
when are THEMselves based on k8s. These tests all use a tool called
kubetest, which is responsible for invoking boskos (see tektoncd#408) and
creating a GKE cluster
(https://github.com/kubernetes/test-infra/tree/master/kubetest).

This Task attempts to create a cluster in the same way, which based on the
output in the end to end logs seems to consist of creating the cluster
and setting up a firewall for it.

I'm not sure if this belongs in the catalog itself since it is specific
to our own end to end tests and isn't as generic as other catalog tests,
so if we want to move this into the test directory that seems fine, but
I also think it could be an okay addition to the catalog on its own (esp
if other k8s based projects that test against GKE want to use it.)
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 22, 2020
As part of tektoncd#373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog. This Task creates a cluster within a GKE
project and is based on the way we create clusters for the existing end
to end tests we have in Tekton, which are themselves based on Knative,
when are THEMselves based on k8s. These tests all use a tool called
kubetest, which is responsible for invoking boskos (see tektoncd#408) and
creating a GKE cluster
(https://github.com/kubernetes/test-infra/tree/master/kubetest).

This Task attempts to create a cluster in the same way, which based on the
output in the end to end logs seems to consist of creating the cluster
and setting up a firewall for it.

I'm not sure if this belongs in the catalog itself since it is specific
to our own end to end tests and isn't as generic as other catalog tests,
so if we want to move this into the test directory that seems fine, but
I also think it could be an okay addition to the catalog on its own (esp
if other k8s based projects that test against GKE want to use it.)
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 22, 2020
As part of tektoncd#373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog. This Task creates a cluster within a GKE
project and is based on the way we create clusters for the existing end
to end tests we have in Tekton, which are themselves based on Knative,
when are THEMselves based on k8s. These tests all use a tool called
kubetest, which is responsible for invoking boskos (see tektoncd#408) and
creating a GKE cluster
(https://github.com/kubernetes/test-infra/tree/master/kubetest).

This Task attempts to create a cluster in the same way, which based on the
output in the end to end logs seems to consist of creating the cluster
and setting up a firewall for it.

I'm not sure if this belongs in the catalog itself since it is specific
to our own end to end tests and isn't as generic as other catalog tests,
so if we want to move this into the test directory that seems fine, but
I also think it could be an okay addition to the catalog on its own (esp
if other k8s based projects that test against GKE want to use it.)
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 23, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 23, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in tektoncd#373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Jul 23, 2020
As part of tektoncd#373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog. This Task creates a cluster within a GKE
project and is based on the way we create clusters for the existing end
to end tests we have in Tekton, which are themselves based on Knative,
when are THEMselves based on k8s. These tests all use a tool called
kubetest, which is responsible for invoking boskos (see tektoncd#408) and
creating a GKE cluster
(https://github.com/kubernetes/test-infra/tree/master/kubetest).

This Task attempts to create a cluster in the same way, which based on the
output in the end to end logs seems to consist of creating the cluster
and setting up a firewall for it.

I'm not sure if this belongs in the catalog itself since it is specific
to our own end to end tests and isn't as generic as other catalog tests,
so if we want to move this into the test directory that seems fine, but
I also think it could be an okay addition to the catalog on its own (esp
if other k8s based projects that test against GKE want to use it.)
tekton-robot pushed a commit that referenced this issue Jul 24, 2020
As part of #373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog. This Task creates a cluster within a GKE
project and is based on the way we create clusters for the existing end
to end tests we have in Tekton, which are themselves based on Knative,
when are THEMselves based on k8s. These tests all use a tool called
kubetest, which is responsible for invoking boskos (see #408) and
creating a GKE cluster
(https://github.com/kubernetes/test-infra/tree/master/kubetest).

This Task attempts to create a cluster in the same way, which based on the
output in the end to end logs seems to consist of creating the cluster
and setting up a firewall for it.

I'm not sure if this belongs in the catalog itself since it is specific
to our own end to end tests and isn't as generic as other catalog tests,
so if we want to move this into the test directory that seems fine, but
I also think it could be an okay addition to the catalog on its own (esp
if other k8s based projects that test against GKE want to use it.)
tekton-robot pushed a commit that referenced this issue Jul 24, 2020
Boskos is a tool that allows one to create a pool of cloud projects
(definitely GCP, I think it supports other providers as well), and
manages acquiring, releasing, and cleaning them between leases.

We use it for Tekton test infrastructure for our end to end tests and
we'd like to use it for our catalog Tasks as well.

This commit adds boskos acquire and release Tasks.

The acquire Task also creates a pod in the running cluster to perform
heartbeating so that boskos knows that the resource is still in use.

The intention of the release Task is that it would be run in a
Pipeline's `finally` clause, however today that would be difficult
because finally Tasks can't yet use the results of other Tasks, but this
functionality is on the way: tektoncd/pipeline#2557

This is part of the work in #373 to create a Pipeline for the catalog.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Aug 5, 2020
As part of tektoncd#373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog.

The goal of the 2 Tasks in this commit is to install Tekton Pipelines into a
cluster that was created using the Task added in tektoncd#436.

There are a couple of options different from what I did in this commit
which I'd like people's opinions on:
1. I went to a lot of trouble to make it so that Pipelines can be
   installed with just a kubectl command, specifically creating a user
   with cluster admin priviledges. If instead I used a container with
   gcloud, I could use the same approach as other GKE specific Tasks,
   but I wanted to make the install Task not tied to GKE. I also had
   to give the prow-account more priviledges in all of our boskos
   projects for this to work :grimace:. So my question is: is this worth
   it, or am I better off just creating a GKE specific Task for
   installing Tekton Pipelines that uses gcloud to auth?
2. If we DO want a super generic Task, how useful is this Task that just
   applies a Tekton yaml? Would we be better off with a generic kubectl
   task that I could feed the exact arguments for installing Tekton
   Pipelines?

The other confusion I ran into here (which I am going to follow up with
@sbwsg about!) is around service accounts vs. secrets. The GKE Tasks
I've made so far rely on secrets provided via workspaces, but I feel
like it's not clear if it makes sense to go that route, or to rely on
service accounts. In the meantime this approach is at least consistent
with tektoncd#436.
bobcatfish added a commit to bobcatfish/catalog that referenced this issue Aug 5, 2020
As part of tektoncd#373 I'm continuing to create Tasks that we can use to run
tests for items in the catalog.

The goal of the 2 Tasks in this commit is to install Tekton Pipelines into a
cluster that was created using the Task added in tektoncd#436.

There are a couple of options different from what I did in this commit
which I'd like people's opinions on:
1. I went to a lot of trouble to make it so that Pipelines can be
   installed with just a kubectl command, specifically creating a user
   with cluster admin priviledges. If instead I used a container with
   gcloud, I could use the same approach as other GKE specific Tasks,
   but I wanted to make the install Task not tied to GKE. I also had
   to give the prow-account more priviledges in all of our boskos
   projects for this to work :grimace:. So my question is: is this worth
   it, or am I better off just creating a GKE specific Task for
   installing Tekton Pipelines that uses gcloud to auth?
2. If we DO want a super generic Task, how useful is this Task that just
   applies a Tekton yaml? Would we be better off with a generic kubectl
   task that I could feed the exact arguments for installing Tekton
   Pipelines?

The other confusion I ran into here (which I am going to follow up with
@sbwsg about!) is around service accounts vs. secrets. The GKE Tasks
I've made so far rely on secrets provided via workspaces, but I feel
like it's not clear if it makes sense to go that route, or to rely on
service accounts. In the meantime this approach is at least consistent
with tektoncd#436.
@tekton-robot
Copy link

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.
If this issue is safe to close now please do so with /close.

/lifecycle rotten

Send feedback to tektoncd/plumbing.

@tekton-robot
Copy link

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

/close

Send feedback to tektoncd/plumbing.

@tekton-robot tekton-robot added the lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. label Aug 14, 2020
@tekton-robot
Copy link

@tekton-robot: Closing this issue.

In response to this:

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

/close

Send feedback to tektoncd/plumbing.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@vdemeester
Copy link
Member

/remove-lifecycle rotten
/remove-lifecycle stale
/reopen

@tekton-robot tekton-robot reopened this Aug 17, 2020
@tekton-robot
Copy link

@vdemeester: Reopened this issue.

In response to this:

/remove-lifecycle rotten
/remove-lifecycle stale
/reopen

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@tekton-robot tekton-robot removed the lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. label Aug 17, 2020
@tekton-robot
Copy link

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.
If this issue is safe to close now please do so with /close.

/lifecycle stale

Send feedback to tektoncd/plumbing.

@tekton-robot tekton-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Nov 15, 2020
@bobcatfish
Copy link
Contributor Author

I'm going to close this since I've put the WIP TEP around verified catalog entries to rest for now: tektoncd/community#170

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/test-infra Issues or PRs related to the testing infrastructure kind/feature Categorizes issue or PR as related to a new feature. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.
Projects
None yet
Development

No branches or pull requests

4 participants