-
Notifications
You must be signed in to change notification settings - Fork 54
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
[DEVHAS-53] Use a Kubernetes Job to Generate GitOps Resources #256
Conversation
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
…e into newjobchanges Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
…e into newjobchanges Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
…e-system Signed-off-by: John Collier <jcollier@redhat.com>
…tart up Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
Signed-off-by: John Collier <jcollier@redhat.com>
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: johnmcollier The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Signed-off-by: John Collier <jcollier@redhat.com>
config/manager/kustomization.yaml
Outdated
@@ -29,5 +29,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 | |||
kind: Kustomization | |||
images: | |||
- name: controller | |||
newName: quay.io/redhat-appstudio/application-service | |||
newTag: next | |||
newName: quay.io/jcollier/application-service |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
gitops-generator/go.mod
Outdated
github.com/openshift-pipelines/pipelines-as-code v0.0.0-20220622161720-2a6007e17200 | ||
github.com/openshift/api v0.0.0-20210503193030-25175d9d392d | ||
github.com/redhat-appstudio/application-api v0.0.0-20221205185405-03f73a06d978 | ||
github.com/redhat-developer/gitops-generator v0.0.0-20230113152345-19efcd5ec104 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably pull the latest here
@@ -40,11 +39,11 @@ func GenerateTektonBuild(outputPath string, component appstudiov1alpha1.Componen | |||
tektonResourcesDirName := ".tekton" | |||
|
|||
if err := GenerateBuild(appFs, filepath.Join(componentPath, tektonResourcesDirName), component, gitopsConfig); err != nil { | |||
return util.SanitizeErrorMessage(fmt.Errorf("failed to generate tekton build in %q for component %q: %s", componentPath, componentName, err)) | |||
return fmt.Errorf("failed to generate tekton build in %q for component %q: %s", componentPath, componentName, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how come this is removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is... a good question. I think it's a holdover from earlier testing. This should be reverted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
return err | ||
} | ||
// Determine if we're using a Kubernetes job for gitops generation, or generating locally | ||
localGitopsGen := (r.AllowLocalGitopsGen && component.Annotations["allowLocalGitopsGen"] == "true") || (r.DoLocalGitOpsGen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If AllowLocalGitopsGen
allows certain resources to generate gitops locally then how come we need r.AllowLocalGitopsGen
? By this if statement the controller needs r.AllowLocalGitopsGen
to be true always irrespective of the annotation. Am I wrong or something? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I didn't want to always allow local GitOps generation, only if we explicitly chose to enable it.
TBH, this is primarily for testing, since suite_test.go
sets the fields for Reconcilers, so we can't toggle DoLocalGitopsGen
between false/true fort the controller tests
|
||
deployAssociatedComponents, err := devfileParser.GetDeployComponents(compDevfileData) | ||
if err != nil { | ||
//log.Error(err, "unable to get deploy components") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments here in these files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
jobNamespace := r.GitOpsJobNamespace | ||
if jobNamespace == "" { | ||
jobNamespace = component.Namespace | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we create job in the application service namespace as default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GitOps secret & service account are already present in the HAS namespace + avoids using up user quota for resources in the user namespace
pkg/gitopsjob/job.go
Outdated
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" | ||
) | ||
|
||
var gitopsJobImage = "quay.io/redhat-appstudio/gitops-generator:latest" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd declare this as a const
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, oops. Agreed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it wise to pull in the latest? what if there are breaking changes from the repo? We should probably consider having releases on the gitops-generator repo and pulling in image versions that we know are compatible/tested with HAS eventually
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to start doing releases in gitops-generator repo.. But if we dont pull in the latest here, we are going to get some of the errors back we faced in infra-deploy PR 1291!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, agreed for now but something to think about once we stabilize
…e into gitopsgenfinal
} | ||
|
||
func GetPodLogs(ctx context.Context, client ctrlclient.Client, clientset kubernetes.Interface, jobName string, jobNamespace string) (string, error) { | ||
jobPodList, err := clientset.CoreV1().Pods(jobNamespace).List(ctx, v1.ListOptions{LabelSelector: "job-name=" + jobName}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curious as to why a clientset is being used here, rather than a call with the client, something like:
err = client.List(ctx, jobPodList,
client.InNamespace(jobNamespace),
client.MatchingLabels{label: "job-name=" + jobName})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason in particular. Figured since I had to use the clientset to get the logs, I might as well be consistent and use it to get the pods too.
select { | ||
case <-timeout: | ||
stay = false | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need a default here if its empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, otherwise go linting complains about using it with a channel, but this was the most straightforward approach
controllers/component_controller.go
Outdated
// Wait for the job to succeed, error out if the 5 min timeout is reached | ||
err = gitopsjob.WaitForJob(log, context.Background(), r.Client, r.GitOpsJobClientSet, jobName, jobNamespace, 5*time.Minute) | ||
if err != nil { | ||
return r.CleanUpJobAndReturn(log, jobName, jobNamespace, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we return like return r.CleanUpJobAndReturn()
then the gitopsjob.WaitForJob()
err will be lost
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CleanUpJobAndReturn
explicitly only logs the error from the deletion, and we return the original error from WaitForJob.
func (r *ComponentReconciler) CleanUpJobAndReturn(log logr.Logger, jobName, jobNamespace string, err error) error {
delErr := gitopsjob.DeleteJob(context.Background(), r.Client, jobName, jobNamespace)
if delErr != nil {
log.Error(err, "unable to delete gitops-generation job")
}
return err
}
It's a little clunky but should do the trick
@@ -528,8 +543,7 @@ func (r *ComponentReconciler) generateGitops(ctx context.Context, req ctrl.Reque | |||
} | |||
component.Status.GitOps.CommitID = commitID | |||
|
|||
// Remove the temp folder that was created | |||
return r.AppFS.RemoveAll(tempDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to make this call in GenerateGitopsBase()
otherwise we will have a host of temp dirs for every reconcile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -154,5 +163,9 @@ var _ = AfterSuite(func() { | |||
cancel() | |||
By("tearing down the test environment") | |||
err := testEnv.Stop() | |||
if err != nil { | |||
time.Sleep(4 * time.Second) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 not sure why
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found on a GitHub issue I can no longer find. Without the sleep the tests will sometimes fail to stop at the end of execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r.SetConditionAndUpdateCR(ctx, req, &appSnapshotEnvBinding, err) | ||
return ctrl.Result{}, err | ||
} | ||
// If the Job succeeds, delete it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no delete happening
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's awkward. Oops
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
// AllowLocalGitopsGen allows for certain resources to generate gitops resources locally, *if* an annotation is present on the resource. Defaults to false | ||
AllowLocalGitopsGen bool | ||
|
||
GitOpsJobClientSet *kubernetes.Clientset | ||
} | ||
|
||
//+kubebuilder:rbac:groups=appstudio.redhat.com,resources=snapshotenvironmentbindings,verbs=get;list;watch;create;update;patch;delete |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to mention the job resource and its verbs here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not strictly necessary since the component controller specifies them, but I'll add them here to just to be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
…e into gitopsgenfinal
Co-authored-by: Maysun Faisal <31771087+maysunfaisal@users.noreply.github.com>
Co-authored-by: Maysun Faisal <31771087+maysunfaisal@users.noreply.github.com>
Signed-off-by: John Collier <jcollier@redhat.com>
@johnmcollier: The following tests failed, say
Full PR test history. Your PR dashboard. 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. I understand the commands that are listed here. |
What does this PR do?:
Note: This PR supersedes #231 and #241
This PR updates HAS to use a Kubernetes Job by default to generate GitOps resources.
In all the following is done:
DO_LOCAL_GITOPS_GEN
environment variable, HAS will instead generate the GitOps resources locally, instead of using a jobALLOW_LOCAL_GITOPS_GEN
environment variable, any Component or SEB with theallowLocalGitOpsGen
annotation set to true, will have its GitOps resources generated locallygitops/
package and subpackages have been moved to the newgitops-generator/
submodule.gitops-generator/
submoduleWhich issue(s)/story(ies) does this PR fixes:
https://issues.redhat.com/projects/DEVHAS/issues/DEVHAS-53?filter=allopenissues
PR acceptance criteria:
Unit/Functional tests
Documentation
Client Impact
How to test changes / Special notes to the reviewer: