Skip to content

Commit

Permalink
[v2.10] init patches for v2.10.2
Browse files Browse the repository at this point in the history
Signed-off-by: Chanwit Kaewkasi <[email protected]>
  • Loading branch information
chanwit committed Mar 4, 2024
1 parent 909efcb commit d2c9a8c
Show file tree
Hide file tree
Showing 27 changed files with 11,368 additions and 0 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/build_v210.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: build_v210
on:
workflow_dispatch:
pull_request:
push:
branches:
- main
paths:
- patches-argo-cd-v2.10/**
- patches-gitops-engine-v2.2.0/**
- VERSION_210
- .github/workflows/build_v210.yaml

permissions:
contents: write
id-token: write
packages: write

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: install stgit
shell: bash
run: |
sudo apt-get install -y stgit
git config --global user.name "Chanwit Kaewkasi"
git config --global user.email "[email protected]"
- name: Get branch names
id: branch-name
uses: tj-actions/[email protected]
- name: Prepare
id: prep
run: |
VERSION="${{ steps.branch-name.outputs.current_branch }}-${GITHUB_SHA::8}"
echo ::set-output name=VERSION::${VERSION}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build v2.10
run: |
ln -s VERSION_210 VERSION
ln -s patches-argo-cd-v2.10 patches-argo-cd
ln -s patches-gitops-engine-v2.2.0 patches-gitops-engine
rm -rf argo-cd || true
bash -x ./init.sh
source ./VERSION
VERSION=${BASE_VERSION}-${SUFFIX_VERSION}-${{ steps.prep.outputs.VERSION }}
( cd argo-cd && IMAGE_NAMESPACE=ghcr.io/flux-subsystem-argo/fsa IMAGE_TAG=$VERSION DOCKER_PUSH=true make image )
unlink patches-argo-cd
unlink VERSION
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
.PHONY: init-v210
init-v210:
ln -s VERSION_210 VERSION
ln -s patches-gitops-engine-v2.2.0 patches-gitops-engine
ln -s patches-argo-cd-v2.10 patches-argo-cd
make init

.PHONY: init-v29
init-v29:
ln -s VERSION_29 VERSION
Expand Down
3 changes: 3 additions & 0 deletions VERSION_210
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
BASE_VERSION=v2.10.2
SUFFIX_VERSION=fl.$(cat patches-argo-cd/series | cut -d- -f1 | tail -1)
GITOPS_ENGINE_VERSION=792124280fcc67d9b3498bc0a27e05844ddb1e30
62 changes: 62 additions & 0 deletions patches-argo-cd-v2.10/01-build-with-local-gitops-engine.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
build with local gitops engine

From: Chanwit Kaewkasi <[email protected]>

Signed-off-by: Chanwit Kaewkasi <[email protected]>
---
.gitignore | 2 ++
Dockerfile | 9 +++++++++
go.mod | 1 +
3 files changed, 12 insertions(+)

diff --git a/.gitignore b/.gitignore
index ab17deb0d..c28c77a6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,5 @@ cmd/argocd/argocd
cmd/argocd-application-controller/argocd-application-controller
cmd/argocd-repo-server/argocd-repo-server
cmd/argocd-server/argocd-server
+
+gitops-engine/
diff --git a/Dockerfile b/Dockerfile
index 2c31b5077..5e6bb92f0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -105,7 +105,9 @@ FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.21.3@sha256:02d7116222

WORKDIR /go/src/github.com/argoproj/argo-cd

+COPY ./gitops-engine ./gitops-engine
COPY go.* ./
+
RUN go mod download

# Perform the build
@@ -130,9 +132,16 @@ RUN GIT_COMMIT=$GIT_COMMIT \
# Final image
####################################################################################################
FROM argocd-base
+
+LABEL org.opencontainers.image.source https://github.com/flux-subsystem-argo/fsa
+
COPY --from=argocd-build /go/src/github.com/argoproj/argo-cd/dist/argocd* /usr/local/bin/

USER root
+
+RUN chmod +x /usr/local/bin/gpg-wrapper.sh && \
+ chmod +x /usr/local/bin/git-verify-wrapper.sh
+
RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server && \
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-repo-server && \
ln -s /usr/local/bin/argocd /usr/local/bin/argocd-cmp-server && \
diff --git a/go.mod b/go.mod
index 7113f82d6..ca987953e 100644
--- a/go.mod
+++ b/go.mod
@@ -334,4 +334,5 @@ replace (
k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.26.11
k8s.io/sample-controller => k8s.io/sample-controller v0.26.11

+ github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc => ./gitops-engine
)
210 changes: 210 additions & 0 deletions patches-argo-cd-v2.10/02-implement-loopback.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
implement loopback reconciliation

From: Chanwit Kaewkasi <[email protected]>

Signed-off-by: Chanwit Kaewkasi <[email protected]>
---
controller/state.go | 40 ++++++++------
controller/state_fsa.go | 139 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 162 insertions(+), 17 deletions(-)
create mode 100644 controller/state_fsa.go

diff --git a/controller/state.go b/controller/state.go
index 5121fa68f..3d2e44c7d 100644
--- a/controller/state.go
+++ b/controller/state.go
@@ -418,26 +418,32 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
}
}

- targetObjs, manifestInfos, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project)
- if err != nil {
- targetObjs = make([]*unstructured.Unstructured, 0)
- msg := fmt.Sprintf("Failed to load target state: %s", err.Error())
- conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now})
- if firstSeen, ok := m.repoErrorCache.Load(app.Name); ok {
- if time.Since(firstSeen.(time.Time)) <= m.repoErrorGracePeriod && !noRevisionCache {
- // if first seen is less than grace period and it's not a Level 3 comparison,
- // ignore error and short circuit
- logCtx.Debugf("Ignoring repo error %v, already encountered error in grace period", err.Error())
+ if isFluxSubsystemEnabled(app) && app.Spec.Source.IsHelm() {
+ targetObjs, conditions, failedToLoadObjs = m.getFluxHelmTargetObjects(app, conditions, now)
+ } else if isFluxSubsystemEnabled(app) && !app.Spec.Source.IsHelm() {
+ targetObjs, conditions, failedToLoadObjs = m.getFluxKustomizeTargetObjects(app, conditions, now)
+ } else {
+ targetObjs, manifestInfos, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project)
+ if err != nil {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ msg := fmt.Sprintf("Failed to load target state: %s", err.Error())
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now})
+ if firstSeen, ok := m.repoErrorCache.Load(app.Name); ok {
+ if time.Since(firstSeen.(time.Time)) <= m.repoErrorGracePeriod && !noRevisionCache {
+ // if first seen is less than grace period and it's not a Level 3 comparison,
+ // ignore error and short circuit
+ logCtx.Debugf("Ignoring repo error %v, already encountered error in grace period", err.Error())
+ return nil, CompareStateRepoError
+ }
+ } else if !noRevisionCache {
+ logCtx.Debugf("Ignoring repo error %v, new occurrence", err.Error())
+ m.repoErrorCache.Store(app.Name, time.Now())
return nil, CompareStateRepoError
}
- } else if !noRevisionCache {
- logCtx.Debugf("Ignoring repo error %v, new occurrence", err.Error())
- m.repoErrorCache.Store(app.Name, time.Now())
- return nil, CompareStateRepoError
+ failedToLoadObjs = true
+ } else {
+ m.repoErrorCache.Delete(app.Name)
}
- failedToLoadObjs = true
- } else {
- m.repoErrorCache.Delete(app.Name)
}
} else {
// Prevent applying local manifests for now when signature verification is enabled
diff --git a/controller/state_fsa.go b/controller/state_fsa.go
new file mode 100644
index 000000000..0892309d2
--- /dev/null
+++ b/controller/state_fsa.go
@@ -0,0 +1,139 @@
+package controller
+
+import (
+ "context"
+ "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+func isFluxSubsystemEnabled(app *v1alpha1.Application) bool {
+ if app == nil {
+ return false
+ }
+ if app.Spec.SyncPolicy == nil {
+ return false
+ }
+ if app.Spec.SyncPolicy.SyncOptions == nil {
+ return false
+ }
+ if app.Spec.SyncPolicy.SyncOptions.HasOption("FluxSubsystem=true") == false {
+ return false
+ }
+ return true
+}
+
+func (m *appStateManager) getFluxHelmTargetObjects(app *v1alpha1.Application, conditions []v1alpha1.ApplicationCondition, now v1.Time) ([]*unstructured.Unstructured, []v1alpha1.ApplicationCondition, bool) {
+ var (
+ targetObjs []*unstructured.Unstructured
+ failedToLoadObjs bool
+ )
+
+ cluster, err := m.db.GetCluster(context.TODO(), app.Spec.Destination.Server)
+ if err != nil {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ }
+ config := cluster.RESTConfig()
+
+ var hl *unstructured.Unstructured
+ hl, err = m.kubectl.GetResource(context.TODO(), config, schema.GroupVersionKind{
+ Group: "helm.toolkit.fluxcd.io",
+ Version: "v2beta2",
+ Kind: "HelmRelease",
+ }, app.Name, app.Spec.Destination.Namespace)
+ if err != nil {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ }
+
+ if hl == nil {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ } else {
+ var source *unstructured.Unstructured
+ if sourceKind, found, err := unstructured.NestedString(hl.Object, "spec", "chart", "spec", "sourceRef", "kind"); found && err == nil {
+ if sourceName, found, err := unstructured.NestedString(hl.Object, "spec", "chart", "spec", "sourceRef", "name"); found && err == nil {
+ if sourceNS, found, err := unstructured.NestedString(hl.Object, "spec", "chart", "spec", "sourceRef", "namespace"); err == nil {
+ if !found {
+ sourceNS = hl.GetNamespace()
+ }
+ source, err = m.kubectl.GetResource(context.Background(), config, schema.GroupVersionKind{
+ Group: "source.toolkit.fluxcd.io",
+ Version: "v1beta1",
+ Kind: sourceKind,
+ }, sourceName, sourceNS)
+ }
+ }
+ }
+ if source != nil {
+ targetObjs = []*unstructured.Unstructured{hl, source}
+ } else {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ }
+ }
+ return targetObjs, conditions, failedToLoadObjs
+}
+
+func (m *appStateManager) getFluxKustomizeTargetObjects(app *v1alpha1.Application, conditions []v1alpha1.ApplicationCondition, now v1.Time) ([]*unstructured.Unstructured, []v1alpha1.ApplicationCondition, bool) {
+ var (
+ targetObjs []*unstructured.Unstructured
+ failedToLoadObjs bool
+ )
+
+ cluster, err := m.db.GetCluster(context.TODO(), app.Spec.Destination.Server)
+ if err != nil {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ }
+ config := cluster.RESTConfig()
+
+ var ks *unstructured.Unstructured
+ ks, err = m.kubectl.GetResource(context.TODO(), config, schema.GroupVersionKind{
+ Group: "kustomize.toolkit.fluxcd.io",
+ Version: "v1beta2",
+ Kind: "Kustomization",
+ }, app.Name, app.Spec.Destination.Namespace)
+ if err != nil {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ }
+
+ if ks == nil {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ } else {
+ var source *unstructured.Unstructured
+ if sourceKind, found, err := unstructured.NestedString(ks.Object, "spec", "sourceRef", "kind"); found && err == nil {
+ if sourceName, found, err := unstructured.NestedString(ks.Object, "spec", "sourceRef", "name"); found && err == nil {
+ if sourceNS, found, err := unstructured.NestedString(ks.Object, "spec", "sourceRef", "namespace"); err == nil {
+ if !found {
+ sourceNS = ks.GetNamespace()
+ }
+ source, err = m.kubectl.GetResource(context.Background(), config, schema.GroupVersionKind{
+ Group: "source.toolkit.fluxcd.io",
+ Version: "v1beta1",
+ Kind: sourceKind,
+ }, sourceName, sourceNS)
+ }
+ }
+ }
+ if source != nil {
+ targetObjs = []*unstructured.Unstructured{ks, source}
+ } else {
+ targetObjs = make([]*unstructured.Unstructured, 0)
+ conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now})
+ failedToLoadObjs = true
+ }
+ }
+ return targetObjs, conditions, failedToLoadObjs
+}
Loading

0 comments on commit d2c9a8c

Please sign in to comment.