Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Add DisableGarbageCollect annotation #2858

Merged
merged 5 commits into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ Now restart `fluxd` to re-read the k8s secret (if it is running):

`kubectl delete $(kubectl get pod -o name -l name=flux)`

If you have installed flux through Helm, make sure to pass
If you have installed flux through Helm, make sure to pass
`--set git.secretName=flux-git-deploy` when installing/upgrading the chart.

### How do I use a private git host (or one that's not github.com, gitlab.com, bitbucket.org, dev.azure.com, or vs-ssh.visualstudio.com)?
Expand Down Expand Up @@ -341,6 +341,18 @@ how/where to undo the change (cf [flux#1211](https://github.com/fluxcd/flux/issu
annotation exists in either the cluster or in git, it will be respected, so you may need to remove
it from both places.

Additionally, when garbage collection is enabled, Flux will not garbage collect resources in the cluster
with the ignore annotation if the resource is removed from git.

### Can I disable garbage collection for a specific resource?

Yes. By adding the annotation below to a resource Flux will sync updates from git, but it will not
garbage collect when the resource is removed from git.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


```yaml
fluxcd.io/ignore: sync_only
```

### How can I prevent Flux overriding the replicas when using HPA?

When using a horizontal pod autoscaler you have to remove the `spec.replicas` from your deployment definition.
Expand Down
11 changes: 11 additions & 0 deletions pkg/cluster/kubernetes/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ func (c *Cluster) collectGarbage(

switch {
case !ok: // was not recorded as having been staged for application
if res.Policies().Has(policy.Ignore) {
c.logger.Log("info", "skipping GC of cluster resource; resource has ignore policy true", "dry-run", dryRun, "resource", resourceID)
continue
}

v, ok := res.Policies().Get(policy.Ignore)
if ok && v == policy.IgnoreSyncOnly {
c.logger.Log("info", "skipping GC of cluster resource; resource has ignore policy sync_only ", "dry-run", dryRun, "resource", resourceID)
continue
}

c.logger.Log("info", "cluster resource not in resources to be synced; deleting", "dry-run", dryRun, "resource", resourceID)
if !dryRun {
orphanedResources.stage("delete", res.ResourceID(), "<cluster>", res.IdentifyingBytes())
Expand Down
74 changes: 71 additions & 3 deletions pkg/cluster/kubernetes/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ metadata:
name: dep3
namespace: other
`

// checkSame is a check that a result returned from the cluster is
// the same as an expected. labels and annotations may be altered
// by the sync process; we'll look at the "spec" field as an
Expand Down Expand Up @@ -607,7 +608,7 @@ metadata:
test(t, kube, ns1+defs1invalid, ns1+defs1invalid, true)
})

t.Run("sync doesn't apply or delete manifests marked with ignore", func(t *testing.T) {
t.Run("sync doesn't apply or GC manifests marked with ignore: 'true'", func(t *testing.T) {
kube, _, cancel := setup(t)
defer cancel()
kube.GC = true
Expand Down Expand Up @@ -651,7 +652,7 @@ spec:
test(t, kube, ns1+dep1ignored+dep2, ns1+dep1, false)
})

t.Run("sync doesn't update a cluster resource marked with ignore", func(t *testing.T) {
t.Run("sync doesn't update a cluster resource marked with ignore: 'true'", func(t *testing.T) {
const dep1 = `---
apiVersion: apps/v1
kind: Deployment
Expand Down Expand Up @@ -703,7 +704,74 @@ spec:
test(t, kube, ns1+mod1, ns1+dep1, false)
})

t.Run("sync doesn't update or delete a pre-existing resource marked with ignore", func(t *testing.T) {
t.Run("sync doesn't GC resources annotated with ignore: 'sync_only'", func(t *testing.T) {
kube, _, cancel := setup(t)
defer cancel()
kube.GC = true

const dep1 = `---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep1
namespace: foobar
annotations: {flux.weave.works/ignore: "sync_only"}
`

// sync namespace and deployment
test(t, kube, ns1+dep1, ns1+dep1, false)

// sync namespace only but expect deployment to not be GC
test(t, kube, ns1, ns1+dep1, false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice and simple test case 👍

})

t.Run("sync doesn't GC resources annotated with ignore: 'true'", func(t *testing.T) {
kube, _, cancel := setup(t)
defer cancel()
kube.GC = true

const dep1 = `---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep1
namespace: foobar
`
const dep2 = `---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep2
namespace: foobar
annotations: {flux.weave.works/ignore: "false"}
`

// dep1 is created
test(t, kube, ns1+dep1+dep2, ns1+dep1+dep2, false)

// add ignore: 'true' annotation outside of sync loop
dc := kube.client.dynamicClient
rc := dc.Resource(schema.GroupVersionResource{
Group: "apps",
Version: "v1",
Resource: "deployments",
})
res, err := rc.Namespace("foobar").Get("dep1", metav1.GetOptions{})
if err != nil {
t.Fatal(err)
}
annots := res.GetAnnotations()
annots["flux.weave.works/ignore"] = "true"
res.SetAnnotations(annots)
if _, err = rc.Namespace("foobar").Update(res, metav1.UpdateOptions{}); err != nil {
t.Fatal(err)
}

// only sync ns1 but expect nothing to be GC
test(t, kube, ns1, ns1+dep1, false)
})

t.Run("sync doesn't update or delete a pre-existing resource marked with ignore: 'true'", func(t *testing.T) {
kube, _, cancel := setup(t)
defer cancel()

Expand Down
2 changes: 2 additions & 0 deletions pkg/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const (
TagAll = Policy("tag_all")
)

const IgnoreSyncOnly = "sync_only"

// Policy is an string, denoting the current deployment policy of a service,
// e.g. automated, or locked.
type Policy string
Expand Down