Skip to content

Commit

Permalink
Refactor TektonResults to use TektonInstallerSets
Browse files Browse the repository at this point in the history
Since Tekton Operator is using TektonInstallerSets for reconciling all the
components shipped by it except for TektonResults, hence this PR
addresses that

Signed-off-by: vinamra28 <[email protected]>
  • Loading branch information
vinamra28 authored and tekton-robot committed Apr 13, 2022
1 parent 1406b84 commit daf2a73
Show file tree
Hide file tree
Showing 8 changed files with 331 additions and 132 deletions.
86 changes: 57 additions & 29 deletions pkg/apis/operator/v1alpha1/tektonresult_lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ var (
_ TektonComponentStatus = (*TektonResultStatus)(nil)
resultsCondSet = apis.NewLivingConditionSet(
DependenciesInstalled,
DeploymentsAvailable,
InstallSucceeded,
InstallerSetAvailable,
InstallerSetReady,
)
)

Expand All @@ -35,6 +35,10 @@ func (tr *TektonResult) GroupVersionKind() schema.GroupVersionKind {
return SchemeGroupVersion.WithKind(KindTektonResult)
}

func (tr *TektonResult) GetGroupVersionKind() schema.GroupVersionKind {
return SchemeGroupVersion.WithKind(KindTektonResult)
}

// GetCondition returns the current condition of a given condition type
func (trs *TektonResultStatus) GetCondition(t apis.ConditionType) *apis.Condition {
return resultsCondSet.Manage(trs).GetCondition(t)
Expand All @@ -50,36 +54,35 @@ func (trs *TektonResultStatus) IsReady() bool {
return resultsCondSet.Manage(trs).IsHappy()
}

// MarkInstallSucceeded marks the InstallationSucceeded status as true.
func (trs *TektonResultStatus) MarkInstallSucceeded() {
resultsCondSet.Manage(trs).MarkTrue(InstallSucceeded)
if trs.GetCondition(DependenciesInstalled).IsUnknown() {
// Assume deps are installed if we're not sure
trs.MarkDependenciesInstalled()
}
func (trs *TektonResultStatus) MarkNotReady(msg string) {
resultsCondSet.Manage(trs).MarkFalse(
apis.ConditionReady,
"Error",
"Ready: %s", msg)
}

// MarkInstallFailed marks the InstallationSucceeded status as false with the given
// message.
func (trs *TektonResultStatus) MarkInstallFailed(msg string) {
func (trs *TektonResultStatus) MarkInstallerSetAvailable() {
resultsCondSet.Manage(trs).MarkTrue(InstallerSetAvailable)
}

func (trs *TektonResultStatus) MarkInstallerSetNotAvailable(msg string) {
trs.MarkNotReady("TektonInstallerSet not ready")
resultsCondSet.Manage(trs).MarkFalse(
InstallSucceeded,
InstallerSetAvailable,
"Error",
"Install failed with message: %s", msg)
"Installer set not ready: %s", msg)
}

// MarkDeploymentsAvailable marks the DeploymentsAvailable status as true.
func (trs *TektonResultStatus) MarkDeploymentsAvailable() {
resultsCondSet.Manage(trs).MarkTrue(DeploymentsAvailable)
func (trs *TektonResultStatus) MarkInstallerSetReady() {
resultsCondSet.Manage(trs).MarkTrue(InstallerSetReady)
}

// MarkDeploymentsNotReady marks the DeploymentsAvailable status as false and calls out
// it's waiting for deployments.
func (trs *TektonResultStatus) MarkDeploymentsNotReady() {
func (trs *TektonResultStatus) MarkInstallerSetNotReady(msg string) {
trs.MarkNotReady("TektonInstallerSet not ready")
resultsCondSet.Manage(trs).MarkFalse(
DeploymentsAvailable,
"NotReady",
"Waiting on deployments")
InstallerSetReady,
"Error",
"Installer set not ready: %s", msg)
}

// MarkDependenciesInstalled marks the DependenciesInstalled status as true.
Expand All @@ -105,6 +108,14 @@ func (trs *TektonResultStatus) MarkDependencyMissing(msg string) {
"Dependency missing: %s", msg)
}

func (trs *TektonResultStatus) GetTektonInstallerSet() string {
return trs.TektonInstallerSet
}

func (trs *TektonResultStatus) SetTektonInstallerSet(installerSet string) {
trs.TektonInstallerSet = installerSet
}

// GetVersion gets the currently installed version of the component.
func (trs *TektonResultStatus) GetVersion() string {
return trs.Version
Expand All @@ -115,12 +126,29 @@ func (trs *TektonResultStatus) SetVersion(version string) {
trs.Version = version
}

// GetManifests gets the url links of the manifests.
func (trs *TektonResultStatus) GetManifests() []string {
return trs.Manifests
// MarkInstallSucceeded marks the InstallationSucceeded status as true.
func (trs *TektonResultStatus) MarkInstallSucceeded() {
panic("implement me")
}

// SetManifests sets the url links of the manifests.
func (trs *TektonResultStatus) SetManifests(manifests []string) {
trs.Manifests = manifests
// MarkInstallFailed marks the InstallationSucceeded status as false with the given
// message.
func (trs *TektonResultStatus) MarkInstallFailed(msg string) {
panic("implement me")
}

// MarkDeploymentsAvailable marks the DeploymentsAvailable status as true.
func (trs *TektonResultStatus) MarkDeploymentsAvailable() {
panic("implement me")
}

// MarkDeploymentsNotReady marks the DeploymentsAvailable status as false and calls out
// it's waiting for deployments.
func (trs *TektonResultStatus) MarkDeploymentsNotReady() {
panic("implement me")
}

// GetManifests gets the url links of the manifests.
func (trs *TektonResultStatus) GetManifests() []string {
panic("Implement me")
}
86 changes: 27 additions & 59 deletions pkg/apis/operator/v1alpha1/tektonresult_lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,19 @@ func TestTektonResultHappyPath(t *testing.T) {
tt.InitializeConditions()

apistest.CheckConditionOngoing(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionOngoing(tt, InstallSucceeded, t)
apistest.CheckConditionOngoing(tt, InstallerSetAvailable, t)
apistest.CheckConditionOngoing(tt, InstallerSetReady, t)

// Install succeeds.
tt.MarkInstallSucceeded()
// Dependencies are assumed successful too.
// Dependencies installed
tt.MarkDependenciesInstalled()
apistest.CheckConditionSucceeded(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)

// Deployments are not available at first.
tt.MarkDeploymentsNotReady()
apistest.CheckConditionSucceeded(tt, DependenciesInstalled, t)
apistest.CheckConditionFailed(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)
if ready := tt.IsReady(); ready {
t.Errorf("tt.IsReady() = %v, want false", ready)
}
tt.MarkInstallerSetAvailable()
apistest.CheckConditionSucceeded(tt, InstallerSetAvailable, t)

tt.MarkInstallerSetReady()
apistest.CheckConditionSucceeded(tt, InstallerSetReady, t)

// Deployments become ready and we're good.
tt.MarkDeploymentsAvailable()
apistest.CheckConditionSucceeded(tt, DependenciesInstalled, t)
apistest.CheckConditionSucceeded(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)
if ready := tt.IsReady(); !ready {
t.Errorf("tt.IsReady() = %v, want true", ready)
}
Expand All @@ -74,44 +63,24 @@ func TestTektonResultErrorPath(t *testing.T) {
tt.InitializeConditions()

apistest.CheckConditionOngoing(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionOngoing(tt, InstallSucceeded, t)
apistest.CheckConditionOngoing(tt, InstallerSetAvailable, t)
apistest.CheckConditionOngoing(tt, InstallerSetReady, t)

// Install fails.
tt.MarkInstallFailed("test")
apistest.CheckConditionOngoing(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionFailed(tt, InstallSucceeded, t)
// Dependencies installed
tt.MarkDependenciesInstalled()
apistest.CheckConditionSucceeded(tt, DependenciesInstalled, t)

// Dependencies are installing.
tt.MarkDependencyInstalling("testing")
apistest.CheckConditionFailed(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionFailed(tt, InstallSucceeded, t)
tt.MarkInstallerSetAvailable()
apistest.CheckConditionSucceeded(tt, InstallerSetAvailable, t)

// Install now succeeds.
tt.MarkInstallSucceeded()
apistest.CheckConditionFailed(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)
if ready := tt.IsReady(); ready {
t.Errorf("tt.IsReady() = %v, want false", ready)
}
// InstallerSet is not ready when deployment pods are not up
tt.MarkInstallerSetNotReady("waiting for deployments")
apistest.CheckConditionFailed(tt, InstallerSetReady, t)

// Deployments become ready
tt.MarkDeploymentsAvailable()
apistest.CheckConditionFailed(tt, DependenciesInstalled, t)
apistest.CheckConditionSucceeded(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)
if ready := tt.IsReady(); ready {
t.Errorf("tt.IsReady() = %v, want false", ready)
}
// InstallerSet and then PostReconciler become ready and we're good.
tt.MarkInstallerSetReady()
apistest.CheckConditionSucceeded(tt, InstallerSetReady, t)

// Finally, dependencies become available.
tt.MarkDependenciesInstalled()
apistest.CheckConditionSucceeded(tt, DependenciesInstalled, t)
apistest.CheckConditionSucceeded(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)
if ready := tt.IsReady(); !ready {
t.Errorf("tt.IsReady() = %v, want true", ready)
}
Expand All @@ -123,16 +92,15 @@ func TestTektonResultExternalDependency(t *testing.T) {

// External marks dependency as failed.
tt.MarkDependencyMissing("test")
tt.MarkInstallerSetReady()

// Install succeeds.
tt.MarkInstallSucceeded()
apistest.CheckConditionFailed(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)
apistest.CheckConditionOngoing(tt, InstallerSetAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallerSetReady, t)

// Dependencies are now ready.
tt.MarkDependenciesInstalled()
apistest.CheckConditionSucceeded(tt, DependenciesInstalled, t)
apistest.CheckConditionOngoing(tt, DeploymentsAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallSucceeded, t)
apistest.CheckConditionOngoing(tt, InstallerSetAvailable, t)
apistest.CheckConditionSucceeded(tt, InstallerSetReady, t)
}
4 changes: 2 additions & 2 deletions pkg/apis/operator/v1alpha1/tektonresult_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ type TektonResultStatus struct {
// +optional
Version string `json:"version,omitempty"`

// The url links of the manifests, separated by comma
// The current installer set name for TektonResult
// +optional
Manifests []string `json:"manifests,omitempty"`
TektonInstallerSet string `json:"tektonInstallerSet,omitempty"`
}

// TektonResultsList contains a list of TektonResult
Expand Down
5 changes: 0 additions & 5 deletions pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/reconciler/kubernetes/tektoninstallerset/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var (
jobPred = mf.ByKind("Job")
secretPred = mf.ByKind("Secret")
deploymentPred = mf.ByKind("Deployment")
statefulSetPred = mf.ByKind("StatefulSet")
servicePred = mf.ByKind("Service")
serviceAccountPred = mf.ByKind("ServiceAccount")
cronJobPred = mf.ByKind("CronJob")
Expand Down Expand Up @@ -153,6 +154,7 @@ func (i *installer) EnsureNamespaceScopedResources() error {
triggerTemplatePred,
servicePred,
routePred,
statefulSetPred,
))
return ensureResources(&resourceList)
}
Expand Down
18 changes: 14 additions & 4 deletions pkg/reconciler/kubernetes/tektonresult/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import (
mf "github.com/manifestival/manifestival"
"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
tektonInstallerinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektoninstallerset"
tektonPipelineInformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonpipeline"
tektonResultInformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonresult"
tektonResultReconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonresult"
"github.com/tektoncd/operator/pkg/reconciler/common"
"go.uber.org/zap"
"k8s.io/client-go/tools/cache"
kubeclient "knative.dev/pkg/client/injection/kube/client"
deploymentInformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment"
"knative.dev/pkg/configmap"
"knative.dev/pkg/controller"
"knative.dev/pkg/injection"
Expand Down Expand Up @@ -59,21 +59,31 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
logger.Fatalw("Error creating initial manifest", zap.Error(err))
}

operatorVer, err := common.OperatorVersion(ctx)
if err != nil {
logger.Fatal(err)
}

if err := common.AppendTarget(ctx, &manifest, &v1alpha1.TektonResult{}); err != nil {
logger.Fatalw("Error fetching manifests", zap.Error(err))
}

c := &Reconciler{
kubeClientSet: kubeclient.Get(ctx),
operatorClientSet: operatorclient.Get(ctx),
extension: generator(ctx),
manifest: manifest,
pipelineInformer: tektonPipelineInformer.Get(ctx),
operatorVersion: operatorVer,
}
impl := tektonResultReconciler.NewImpl(ctx, c)

logger.Info("Setting up event handlers")
logger.Info("Setting up event handlers for tekton-results")

tektonResultInformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue))

deploymentInformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: controller.FilterControllerGVK(v1alpha1.SchemeGroupVersion.WithKind("TektonResult")),
tektonInstallerinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: controller.FilterController(&v1alpha1.TektonResult{}),
Handler: controller.HandleAll(impl.EnqueueControllerOf),
})

Expand Down
Loading

0 comments on commit daf2a73

Please sign in to comment.