Skip to content

Commit 7c5a527

Browse files
committed
feat(stoneintg-1165): resolve pipelineruns from scenario
Support referencing pipelineruns from integrationtestscenario resolver field. Uses Tekton's ResolutionRequest CR to grab remote data then creates PipelineRun in the cluster Signed-off-by: Ryan Cole <[email protected]>
1 parent f8f63c0 commit 7c5a527

File tree

2 files changed

+93
-4
lines changed

2 files changed

+93
-4
lines changed

internal/controller/snapshot/snapshot_adapter.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -762,8 +762,12 @@ func (a *Adapter) createIntegrationPipelineRun(application *applicationapiv1alph
762762
a.logger.Info("Creating new pipelinerun for integrationTestscenario",
763763
"integrationTestScenario.Name", integrationTestScenario.Name)
764764

765-
pipelineRunBuilder := tekton.NewIntegrationPipelineRun(integrationTestScenario.Name, application.Namespace, *integrationTestScenario).
766-
WithSnapshot(snapshot).
765+
pipelineRunBuilder, err := tekton.NewIntegrationPipelineRun(a.client, integrationTestScenario.Name, application.Namespace, *integrationTestScenario)
766+
if err != nil {
767+
return nil, err
768+
}
769+
770+
pipelineRunBuilder = pipelineRunBuilder.WithSnapshot(snapshot).
767771
WithIntegrationLabels(integrationTestScenario).
768772
WithIntegrationAnnotations(integrationTestScenario).
769773
WithApplication(a.application).

tekton/integration_pipeline.go

+87-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (r *IntegrationPipelineRun) AsPipelineRun() *tektonv1.PipelineRun {
103103

104104
// NewIntegrationPipelineRun creates an empty PipelineRun in the given namespace. The name will be autogenerated,
105105
// using the prefix passed as an argument to the function.
106-
func NewIntegrationPipelineRun(prefix, namespace string, integrationTestScenario v1beta2.IntegrationTestScenario) *IntegrationPipelineRun {
106+
func NewIntegrationPipelineRun(client client.Client, ctx context.Context, prefix, namespace string, integrationTestScenario v1beta2.IntegrationTestScenario) (*IntegrationPipelineRun, err) {
107107
resolverParams := []tektonv1.Param{}
108108

109109
for _, scenarioParam := range integrationTestScenario.Spec.ResolverRef.Params {
@@ -117,6 +117,19 @@ func NewIntegrationPipelineRun(prefix, namespace string, integrationTestScenario
117117
resolverParams = append(resolverParams, resolverParam)
118118
}
119119

120+
resolver := tektonv1.ResolverName(integrationTestScenario.Spec.ResolverRef.Resolver)
121+
if integrationTestScenario.Spec.ResolverType == "pipeline" {
122+
return generateIntegrationPipelineRunFromPipelineResolver(prefix, namespace, resolver, resolverParams), nil
123+
} else if integrationTestScenario.Spec.ResolverType == "pipelinerun" {
124+
base64plr, err := getPipelineRunYamlFromPipelineRunResolver(clilent, ctx, prefix, namespace, resolver, resolverParams)
125+
if err != nil {
126+
return nil, err
127+
}
128+
return generateIntegrationPipelineRunFromBase64(base64plr)
129+
}
130+
}
131+
132+
func generateIntegrationPipelineRunFromPipelineResolver(prefix, namespace, resolver string, resolverParams []tektonv1.Param) *IntegrationPipelineRun {
120133
pipelineRun := tektonv1.PipelineRun{
121134
ObjectMeta: metav1.ObjectMeta{
122135
GenerateName: prefix + "-",
@@ -125,15 +138,87 @@ func NewIntegrationPipelineRun(prefix, namespace string, integrationTestScenario
125138
Spec: tektonv1.PipelineRunSpec{
126139
PipelineRef: &tektonv1.PipelineRef{
127140
ResolverRef: tektonv1.ResolverRef{
128-
Resolver: tektonv1.ResolverName(integrationTestScenario.Spec.ResolverRef.Resolver),
141+
Resolver: resolver,
129142
Params: resolverParams,
130143
},
131144
},
132145
},
133146
}
147+
134148
return &IntegrationPipelineRun{pipelineRun}
135149
}
136150

151+
func getPipelineRunYamlFromPipelineRunResolver(client client.Client, ctx context.Context, prefix, namespace, resolver string, resolverParams []tektonv1.Param) (*IntegrationPipelineRun, error) {
152+
request = tektonv1.ResolutionRequest{
153+
ObjectMeta: metav1.ObjectMeta{
154+
GenerateName: prefix + "-",
155+
Namespace: namespace,
156+
},
157+
Labels: map[string]string{
158+
"resolution.tekton.dev/type": resolver,
159+
},
160+
Annotations: map[string]string{
161+
"konflux-ci.dev/created-by": "integration-service", // for backup garbage collection
162+
},
163+
Spec: tektonv1.ResolverRequestSpec{
164+
Params: resolverParams,
165+
},
166+
}
167+
168+
err := retry.OnError(retry.DefaultBackoff, client.Create(ctx, request))
169+
if err != nil {
170+
return "", err
171+
}
172+
resolutionRequestName := request.ObjectMeta.Name
173+
defer func() {
174+
_ = retry.OnError(retry.DefaultBackoff, client.Delete(ctx, request))
175+
}()
176+
177+
resolverBackoff := wait.Backoff{
178+
Steps: 60,
179+
Duration: 1 * time.Second,
180+
Factor: 1.0,
181+
Jitter: 0.5,
182+
}
183+
var resolvedRequest tektonv1.ResolutionRequest
184+
err = retry.OnError(resolverBackoff, func() {
185+
namespace := "foo"
186+
name := "bar"
187+
err = client.Get(ctx, types.NamespacedName{Namespace: resolutionRequestName, Name: name}, &resolvedRequest)
188+
if err != nil {
189+
return err
190+
}
191+
for _, cond := range resolvedRequest.Status.Conditions {
192+
if strings.EqualFold(cond.Type, "succeeded") {
193+
if cond.Status == metav1.ConditionTrue {
194+
// request resolved successfully, we can terminate retry block
195+
return nil
196+
}
197+
}
198+
}
199+
return fmt.Errorf("Resolution for '%s' in namespace '%s' did not complete", namespace, name)
200+
})
201+
202+
if err != nil {
203+
return "", err
204+
}
205+
return resolvedRequest.Status.Data, nil
206+
}
207+
208+
func generateIntegrationPipelineRunFromBase64(base64plr string) (*IntegrationPipelineRun, error) {
209+
plrYaml, err := base64.StdEncoding.DecodeString(base64plr)
210+
if err != nil {
211+
return err
212+
}
213+
// TODO: Make sure this is sufficient to verify that kind is pipelineRun
214+
var pipelineRun tektonv1.PipelineRun
215+
err = yaml.Unmarshal(plrYaml, &pipelineRun)
216+
if err != nil {
217+
return err
218+
}
219+
return &IntegrationPipelineRun{pipelineRun}, nil
220+
}
221+
137222
// Updates git resolver values parameters with values of params specified in the input map
138223
// updates only exsitings parameters, doens't create new ones
139224
func (iplr *IntegrationPipelineRun) WithUpdatedTestsGitResolver(params map[string]string) *IntegrationPipelineRun {

0 commit comments

Comments
 (0)