Skip to content
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

git: add push.refspec to push using a refspec #514

Merged
merged 3 commits into from
Aug 23, 2023

Conversation

aryan9600
Copy link
Member

@aryan9600 aryan9600 commented May 10, 2023

Add .spec.git.push.refspec to allow specifying a refspec to be used for performing a push operation. If specified alongside .spec.git.push.branch, two push operations, one for each specified push configuration will be performed.

TODO: add docs for how to use this with Gerrit, will do that once we confirm that it works as expected.

Fixes: #509
Depends on: fluxcd/pkg#550

@aryan9600 aryan9600 force-pushed the push-refspec branch 3 times, most recently from 98d44bd to 2cbf9fd Compare May 15, 2023 14:16
@aryan9600
Copy link
Member Author

@aristapimenta, could you please try these changes and see if it works as expected for you with Gerrit? The image can be pulled by running docker pull quay.io/aryan9600/image-automation-controller:push-refspec-2cbf9fd and the updated CRD (config/crd/bases/image.toolkit.fluxcd.io_imageupdateautomations.yaml) can be found by cloning the repository and then doing a gh pr checkout 514. thanks :)

@aristapimenta
Copy link

Sure! Is this time sensitive? I just left on PTO for the next two weeks, do we have time to do this when I'm back?

@hiddeco hiddeco added enhancement New feature or request area/git Git related issues and pull requests labels May 16, 2023
@aryan9600
Copy link
Member Author

aryan9600 commented May 16, 2023

@aristapimenta no pressure take your time, but it'd be great to have your confirmation soon. enjoy your time off :)

@aristapimenta
Copy link

@aryan9600 I tested the change today, and with info log level I'm getting a weird already up-to-date error. then I changed log level to trace and got this:

{"level":"debug","ts":"2023-05-29T17:16:25.877Z","msg":"fetching git repository","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","gitrepository":{"namespace":"flux-system","name":"flux-system"}}
{"level":"Level(-2)","ts":"2023-05-29T17:16:25.877Z","msg":"using git repository ref from .spec.git.checkout","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","ref":{"branch":"main"}}
{"level":"debug","ts":"2023-05-29T17:16:25.877Z","msg":"attempting to clone git repository","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","gitrepository":{"namespace":"flux-system","name":"flux-system"},"ref":{"branch":"main"},"working":"/tmp/flux-system-flux-system2736337656"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.592Z","msg":"adjusting update path according to .spec.update.path","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","base":"/tmp/flux-system-flux-system2736337656","spec-path":"./apps/podinfo/podinfo.yaml"}
{"level":"debug","ts":"2023-05-29T17:16:28.592Z","msg":"updating with setters according to image policies","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","count":1,"manifests-path":"/tmp/flux-system-flux-system2736337656/apps/podinfo/podinfo.yaml"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.592Z","msg":"found policy","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","namespace":"podinfo","name":"podinfo","latest-image":"ghcr.io/stefanprodan/podinfo:5.0.3"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.592Z","msg":"adding setter","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","name":"podinfo:podinfo"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.592Z","msg":"adding setter","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","name":"podinfo:podinfo:tag"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.592Z","msg":"adding setter","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","name":"podinfo:podinfo:name"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.592Z","msg":"scanning files","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","path":"/tmp/flux-system-flux-system2736337656/apps/podinfo/podinfo.yaml","token":"\"$imagepolicy\""}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.593Z","msg":"reading file","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","path":"podinfo.yaml"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.594Z","msg":"found schema extension","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","path":".spec.template.spec.containers.image"}
{"level":"Level(-2)","ts":"2023-05-29T17:16:28.594Z","msg":"applying setter","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","setter":"podinfo:podinfo","old":"ghcr.io/stefanprodan/podinfo:5.0.0","new":"ghcr.io/stefanprodan/podinfo:5.0.3"}
{"level":"debug","ts":"2023-05-29T17:16:28.597Z","msg":"ran updates to working dir","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","working":"/tmp/flux-system-flux-system2736337656"}
{"level":"error","ts":"2023-05-29T17:16:30.977Z","msg":"already up-to-date","name":"podinfo","namespace":"podinfo","reconciler kind":"ImageUpdateAutomation","annotations":null,"error":"error","stacktrace":"github.com/fluxcd/pkg/runtime/events.(*Recorder).AnnotatedEventf\n\tgithub.com/fluxcd/pkg/[email protected]/events/recorder.go:137\ngithub.com/fluxcd/pkg/runtime/events.(*Recorder).Eventf\n\tgithub.com/fluxcd/pkg/[email protected]/events/recorder.go:114\ngithub.com/fluxcd/image-automation-controller/internal/controllers.(*ImageUpdateAutomationReconciler).event\n\tgithub.com/fluxcd/image-automation-controller/internal/controllers/imageupdateautomation_controller.go:654\ngithub.com/fluxcd/image-automation-controller/internal/controllers.(*ImageUpdateAutomationReconciler).Reconcile.func2\n\tgithub.com/fluxcd/image-automation-controller/internal/controllers/imageupdateautomation_controller.go:165\ngithub.com/fluxcd/image-automation-controller/internal/controllers.(*ImageUpdateAutomationReconciler).Reconcile\n\tgithub.com/fluxcd/image-automation-controller/internal/controllers/imageupdateautomation_controller.go:412\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Reconcile\n\tsigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:122\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\tsigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:323\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\tsigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:274\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2\n\tsigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:235"}
{"level":"debug","ts":"2023-05-29T17:16:30.977Z","logger":"events","msg":"already up-to-date","type":"Warning","object":{"kind":"ImageUpdateAutomation","namespace":"podinfo","name":"podinfo","uid":"9b2a7691-3ad9-48d7-8ab5-64f9be8c9af8","apiVersion":"image.toolkit.fluxcd.io/v1beta1","resourceVersion":"5678"},"reason":"error"}
{"level":"error","ts":"2023-05-29T17:16:31.026Z","msg":"Reconciler error","controller":"imageupdateautomation","controllerGroup":"image.toolkit.fluxcd.io","controllerKind":"ImageUpdateAutomation","ImageUpdateAutomation":{"name":"podinfo","namespace":"podinfo"},"namespace":"podinfo","name":"podinfo","reconcileID":"bd721ab7-a3c3-4400-a103-df248f5ff7e8","error":"already up-to-date","stacktrace":"sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\tsigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:329\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\tsigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:274\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2\n\tsigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:235"}

I'm gonna investigate further tomorrow to make sure this is not a configuration mistake

@aristapimenta
Copy link

This is the object:

apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
  name: podinfo
spec:
  interval: 1m0s
  sourceRef:
    kind: GitRepository
    name: flux-system
    namespace: flux-system
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        email: [email protected]
        name: fluxcdbot
      messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
    push:
      refspec: HEAD:refs/for/main
  update:
    path: ./apps/podinfo/podinfo.yaml

@aristapimenta
Copy link

From the stack trace in the logs I posted above, looks like the error is specifically from the push:

		if err := gitClient.Push(pushCtx, pushConfig); err != nil {
			return failWithError(err)
		}

@stefanprodan
Copy link
Member

stefanprodan commented May 29, 2023

The update path must be a directory, instead of a file path https://fluxcd.io/flux/components/image/imageupdateautomations/#update-strategy

@aryan9600 aryan9600 force-pushed the push-refspec branch 2 times, most recently from 2be3cfc to f0e3a36 Compare May 30, 2023 07:34
@aryan9600
Copy link
Member Author

@aristapimenta what do the ImageUpdate object events show?

@aristapimenta
Copy link

The update path must be a directory, instead of a file path https://fluxcd.io/flux/components/image/imageupdateautomations/#update-strategy

@stefanprodan did this change recently? I copied this config from a previous attempt which worked well with GitHub (but not Gerrit). Anyways, I updated to path: ./apps/podinfo/ here and I'm seeing the same error.

@aristapimenta what do the ImageUpdate object events show?

This:

Warning  error   13s (x7 over 113s)  image-automation-controller  already up-to-date

@aristapimenta
Copy link

I'm suspecting that this is because Gerrit has a commit-msg Git hook that adds the Change-Id: ... line to the commit message (see this), and the Gerrit server is replying this already up-to-date because the message of the commit trying to be pushed doesn't have this line.

@aryan9600
Copy link
Member Author

i'd like to see the error that originates because of:

if err := gitClient.Push(pushCtx, pushConfig); err != nil {
	return failWithError(err)
}

i don't know why the actual error is missing from the logs, but it should be in the events. Could you change the ImagePolicy in such a way that it'll be forced to push a commit?

@aristapimenta
Copy link

aristapimenta commented May 30, 2023

i'd like to see the error that originates because of:

if err := gitClient.Push(pushCtx, pushConfig); err != nil {
	return failWithError(err)
}

i don't know why the actual error is missing from the logs, but it should be in the events. Could you change the ImagePolicy in such a way that it'll be forced to push a commit?

I think already up-to-date is the actual error... Also, ImagePolicy is already in a way that a push must be triggered. The file has 5.0.0 and the ImagePolicy has found 5.0.3. You can see that from the logs I posted above. See this:

{
    "level": "Level(-2)",
    "ts": "2023-05-29T17:16:28.594Z",
    "msg": "applying setter",
    "controller": "imageupdateautomation",
    "controllerGroup": "image.toolkit.fluxcd.io",
    "controllerKind": "ImageUpdateAutomation",
    "ImageUpdateAutomation": {
        "name": "podinfo",
        "namespace": "podinfo"
    },
    "namespace": "podinfo",
    "name": "podinfo",
    "reconcileID": "bd721ab7-a3c3-4400-a103-df248f5ff7e8",
    "setter": "podinfo:podinfo",
    "old": "ghcr.io/stefanprodan/podinfo:5.0.0",
    "new": "ghcr.io/stefanprodan/podinfo:5.0.3"
}

@aristapimenta
Copy link

already up-to-date is the error being recorded as an event. See this stack trace:

{
    "level": "error",
    "ts": "2023-05-29T17:16:30.977Z",
    "msg": "already up-to-date",
    "name": "podinfo",
    "namespace": "podinfo",
    "reconciler kind": "ImageUpdateAutomation",
    "annotations": null,
    "error": "error",
    "stacktrace": "
github.com/fluxcd/pkg/runtime/events.(*Recorder).AnnotatedEventf
	github.com/fluxcd/pkg/[email protected]/events/recorder.go:137
github.com/fluxcd/pkg/runtime/events.(*Recorder).Eventf
	github.com/fluxcd/pkg/[email protected]/events/recorder.go:114
github.com/fluxcd/image-automation-controller/internal/controllers.(*ImageUpdateAutomationReconciler).event
	github.com/fluxcd/image-automation-controller/internal/controllers/imageupdateautomation_controller.go:654
github.com/fluxcd/image-automation-controller/internal/controllers.(*ImageUpdateAutomationReconciler).Reconcile.func2
	github.com/fluxcd/image-automation-controller/internal/controllers/imageupdateautomation_controller.go:165
github.com/fluxcd/image-automation-controller/internal/controllers.(*ImageUpdateAutomationReconciler).Reconcile
	github.com/fluxcd/image-automation-controller/internal/controllers/imageupdateautomation_controller.go:412
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Reconcile
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:122
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:323
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:274
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:235"
}

@aryan9600
Copy link
Member Author

since this PR no longer targets support for gerrit (ref: #509 (comment)), its unblocked and is ready for review

@aristapimenta
Copy link

@aryan9600 I'm testing @brovoca's message template here but I'm getting the same error. I'm gonna try to debug-print the generated message and see if look correct.

@aristapimenta
Copy link

@aryan9600 In fact, by using aryan9600#2 I was able to confirm that the commit message indeed contains a Change-Id which looks exactly like the ones I'm used to see in Gerrit internally:

Perform automatic image update

Automation name: podinfo/podinfo

Files:
- podinfo.yaml

Objects:
- Deployment podinfo

Images:
- ghcr.io/stefanprodan/podinfo:5.0.3

Change-Id: Ibe940b61e18469fa85062849e6bd065cc87a6f03

Below is a full sample of running with loglevel=trace. As you can see, the error returned by (*gogit.Client).Push is still already up-to-date. I'm gonna try to investigate what this means for gogit exactly.

{
    "level": "debug",
    "ts": "2023-07-27T16:48:30.644Z",
    "msg": "commit message templated",
    "controller": "imageupdateautomation",
    "controllerGroup": "image.toolkit.fluxcd.io",
    "controllerKind": "ImageUpdateAutomation",
    "ImageUpdateAutomation": {
        "name": "podinfo",
        "namespace": "podinfo"
    },
    "namespace": "podinfo",
    "name": "podinfo",
    "reconcileID": "b33ce48f-d846-471d-a28c-28aa446ee166",
    "template": "Perform automatic image update

Automation name: {{ .AutomationObject }}

Files:
{{ range $filename, $_ := .Updated.Files -}}
- {{ $filename }}
{{ end }}
Objects:
{{ range $resource, $_ := .Updated.Objects -}}
- {{ $resource.Kind }} {{ $resource.Name }}
{{ end }}
Images:
{{ range .Updated.Images -}}
- {{ . }}
{{ end }}
{{- $ChangeId := .AutomationObject -}}
{{- $ChangeId = printf \"%s%s\" $ChangeId ( .Updated.Files | toString ) -}}
{{- $ChangeId = printf \"%s%s\" $ChangeId ( .Updated.Objects | toString ) -}}
{{- $ChangeId = printf \"%s%s\" $ChangeId ( .Updated.Images | toString ) }}
Change-Id: {{ printf \"I%s\" ( sha256sum $ChangeId | trunc 40 ) }}
",
    "commitMessage": "Perform automatic image update

Automation name: podinfo/podinfo

Files:
- podinfo.yaml

Objects:
- Deployment podinfo

Images:
- ghcr.io/stefanprodan/podinfo:5.0.3

Change-Id: Ibe940b61e18469fa85062849e6bd065cc87a6f03
"
}
{
    "level": "error",
    "ts": "2023-07-27T16:48:32.829Z",
    "msg": "already up-to-date",
    "name": "podinfo",
    "namespace": "podinfo",
    "reconciler kind": "ImageUpdateAutomation",
    "annotations": null,
    "error": "error",
    "stacktrace": "github.com/fluxcd/pkg/runtime/events.(*Recorder).AnnotatedEventf
	github.com/fluxcd/pkg/[email protected]/events/recorder.go:137
github.com/fluxcd/pkg/runtime/events.(*Recorder).Eventf
	github.com/fluxcd/pkg/[email protected]/events/recorder.go:114
github.com/fluxcd/image-automation-controller/internal/controller.(*ImageUpdateAutomationReconciler).event
	github.com/fluxcd/image-automation-controller/internal/controller/imageupdateautomation_controller.go:637
github.com/fluxcd/image-automation-controller/internal/controller.(*ImageUpdateAutomationReconciler).Reconcile.func2
	github.com/fluxcd/image-automation-controller/internal/controller/imageupdateautomation_controller.go:160
github.com/fluxcd/image-automation-controller/internal/controller.(*ImageUpdateAutomationReconciler).Reconcile
	github.com/fluxcd/image-automation-controller/internal/controller/imageupdateautomation_controller.go:409
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Reconcile
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:118
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:314
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:265
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:226"
}
{
    "level": "debug",
    "ts": "2023-07-27T16:48:32.829Z",
    "logger": "events",
    "msg": "already up-to-date",
    "type": "Warning",
    "object": {
        "kind": "ImageUpdateAutomation",
        "namespace": "podinfo",
        "name": "podinfo",
        "uid": "9b2a7691-3ad9-48d7-8ab5-64f9be8c9af8",
        "apiVersion": "image.toolkit.fluxcd.io/v1beta1",
        "resourceVersion": "4743217"
    },
    "reason": "error"
}
{
    "level": "error",
    "ts": "2023-07-27T16:48:32.865Z",
    "msg": "Reconciler error",
    "controller": "imageupdateautomation",
    "controllerGroup": "image.toolkit.fluxcd.io",
    "controllerKind": "ImageUpdateAutomation",
    "ImageUpdateAutomation": {
        "name": "podinfo",
        "namespace": "podinfo"
    },
    "namespace": "podinfo",
    "name": "podinfo",
    "reconcileID": "b33ce48f-d846-471d-a28c-28aa446ee166",
    "error": "already up-to-date",
    "stacktrace": "sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:324
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:265
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2
	sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:226"
}

@aristapimenta
Copy link

The error is returned here: https://github.com/go-git/go-git/blob/v5.7.0/remote.go#L174

@aristapimenta
Copy link

I found the problem investigating [email protected]. The problem is using the refspec HEAD:refs/for/main, specifically the HEAD part. It turns out that go-git is not internally resolving this local reference to the respective hash reference (which in this case should be the hash of the commit just made by image-automation-controller to bump podinfo:5.0.0 to podinfo:5.0.3 in the ./apps/podinfo/podinfo.yaml file), which causes the following return line to execute:

https://github.com/go-git/go-git/blob/v5.7.0/remote.go#L720-L722

This in turn means that no *packp.Commands are added to packp.ReferenceUpdateRequest.Commands in the packp.ReferenceUpdateRequest created internally by (*extgogit.Remote).PushContext, which in turn causes the line mentioned in my previous comment to execute:

https://github.com/go-git/go-git/blob/v5.7.0/remote.go#L174

Which is the error already up-to-date that we have been seeing.

This is an easy problem to solve, just use refs/heads/main:refs/for/main instead of HEAD:refs/for/main. This successfully creates a *packp.Command:

&{Name:refs/for/main Old:0000000000000000000000000000000000000000 New:f6b9bcb640261a8e381a68238b0b85a29d5c1f50}

The Gerrit server accepted the push and opened a review! ✔️

@aristapimenta
Copy link

However looks like ImageUpdateAutomation will push a new commit to the Gerrit review every time it runs because the commit hash changes. In the screenshot below Patchset 2 is my first successful attempt, then 3, 4 and 5 happened at the configured spec.interval of 1m:

Screenshot from 2023-07-28 18-22-18

@aryan9600
Copy link
Member Author

aryan9600 commented Aug 8, 2023

it works, if both .spec.push.branch and .spec.push.refspec are specified and the reconciler is modified to perform two push operations, one for each specified push config. the problem with just pushing using the refspec refs/heads/main:refs/for/main is that every time the reconciler does a fresh clone, it runs the update logic and updates the files since the previously pushed changes don't exist in main yet.
if we push the changes to a branch and then use the head of that branch to open a Change to main, then the next time the repo is cloned, the changes are present and the reconciler exits early. this approach is also whats recommended in the Gerrit docs:

With Gerrit, you can also create a new local branch to develop in. While not required, it can be considered a best practice to sandbox this change from other changes you might be making.

while this solves the problem of multiple Patchsets for a single Change, it doesn't address of the issue of potential multiple Changes. since the Change-Id is calculated using information like the name of the files, the images, etc. if the reconciler updates a new file or changes the previously updated version to an even newer version while a change is already open, this will result in the commit having a new Change-Id which will consequently open a new Change. imo, this can't be solved without introducing some really specific Gerrit logic in the reconciler which isn't possible at this point. this should be documented as a limitation of using this controller with Gerrit.

@brovoca
Copy link

brovoca commented Aug 8, 2023

@aryan9600 wrote:

if we push the changes to a branch and then use the head of that branch to open a PR to main, then the next time the repo is cloned, the changes are present and the reconciler exits early. this approach is also whats recommended in the Gerrit docs:

Gerrit doesn't have a concept of "pull requests" as the tool uses "reviews" instead. See the Basic Gerrit Walkthrough — For GitHub Users which states:

Instead of using the Web UI to create a pull request, you use git push origin HEAD:refs/for/master to upload new local commits that are ready for review to Gerrit. You will find the URL to the review in the output of the push command.

Additionally, even if we'd push it to a separate branch, I don't see how that would prevent multiple patchsets from being created on that branch, because the main branch which the reconciler would clone still wouldn't contain the changes. Adding to that, now we'd have to merge that branch with main. Please help me if I'm missing some crucial detail here.

@aryan9600 wrote:

while this solves the problem of multiple Patchsets for a single Change, it doesn't address of the issue of potential multiple Changes. since the Change-Id is calculated using information like the name of the files, the images, etc. if the reconciler updates a new file or changes the previously updated version to an even newer version while a change is already open, this will result in the commit having a new Change-Id which will consequently open a new Change. imo, this can't be solved without introducing some really specific Gerrit logic in the reconciler which isn't possible at this point. this should be documented as a limitation of using this controller with Gerrit.

I am the author of the message template that applies this method of calculating the Change-Id. First of all I want to point out the necessity of Change-Id in Gerrit. It is used to uniquely identifying a "review" (PR in GH terms) as the commit hash is unreliable as it changes every time a rebase happens (GitHub uses separate branches to address this). You can thus update a review by including that same Change-Id in the end of the commit message.

It is important that the IA controller doesn't generate the same Change-Id twice as that would try to send a new "patch set" to an already merged "review", which is why multiple "reviews" would be created in case image grafana/grafana in deployment.yaml first got bumped to 9.5.2 and the next time to 9.5.7, even if the 9.5.2 review hasn't been merged yet.

Hope this helps bring clarity to the ways of working with Gerrit.

@aryan9600
Copy link
Member Author

I don't see how that would prevent multiple patchsets from being created on that branch, because the main branch which the reconciler would clone still wouldn't contain the changes

the main branch won't but the branch specified in .spec.push.branch would. if .spec.push.branch is specified, the reconciler first switches to that branch and then runs its update logic. since that branch already has the change (from a previous reconciliation), the reconciler won't update any files and just quit early.

@aryan9600
Copy link
Member Author

aryan9600 commented Aug 8, 2023

Gerrit doesn't have a concept of "pull requests" as the tool uses "reviews" instead.

sorry, i meant a "Change" here. still getting used to Gerrit :)

@aristapimenta
Copy link

aristapimenta commented Aug 8, 2023

the main branch won't but the branch specified in .spec.push.branch would. if .spec.push.branch is specified, the reconciler first switches to that branch and then runs its update logic. since that branch already has the change (from a previous reconciliation), the reconciler won't update any files and just quit early.

@aryan9600 this feels like the remote branch created by .spec.push.branch is like an auxiliary variable for Flux stored in Gerrit, and we would probably need to have one of those for each IUA / IP object or something like that, i.e. many. so we're basically trading lots of Patchsets for lots of remote branches. on top of that, I think most Gerrit users are not even used to working with remote branches at all, we just do git push origin HEAD:refs/for/master. so while this seems to work for preventing multiple Patchsets from being created by Flux in the same Change, an ideal solution would still be one that looks for the Change-Id on the Gerrit server and compares the files against its head.

that said, I don't think this should block this PR. we can address this in a future change, as it requires the code to be able to have Gerrit-specific logic, which probably needs some preparation.

we could probably just document this solution in the blog post along with the HEAD resolution issue so users are at least informed of these 2 workarounds 👍

@@ -427,6 +439,9 @@ Note that without force push in push branches, if the target branch is stale, th
be able to conclude the operation and will consistently fail until the branch is either deleted or
refreshed.

If both `push.refspec` and `push.branch` are specified, then the reconciler will perform two push
Copy link
Member

Choose a reason for hiding this comment

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

Besides what it enables for Gerrit, I think this behavior is surprising and could potentially result in issues when people define a branch and refspec which are essentially equal to each other.

Copy link
Member Author

Choose a reason for hiding this comment

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

maybe we should document that this will probably lead to an already up-to-date error?

Choose a reason for hiding this comment

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

that this will probably

what is "this" in this case?

Copy link
Member Author

Choose a reason for hiding this comment

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

the fact that if push.refspec and push.branch are essentially equal to each other (for eg: refs/heads/main:refs/heads/main and main), then the controller will fail while trying to perform the second push operation, since main will already be up to date with all the changes

Choose a reason for hiding this comment

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

I thought the reconciliation would return earlier in that case, since the commit would be empty or something, rather than trying to push

Copy link
Member Author

Choose a reason for hiding this comment

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

why would the commit be empty? both push operations are happening in a single reconciliation.

Choose a reason for hiding this comment

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

oh, got it!

@aryan9600 aryan9600 force-pushed the push-refspec branch 2 times, most recently from 5b935e3 to e216fa2 Compare August 21, 2023 13:32
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
docs/spec/v1beta1/imageupdateautomations.md Outdated Show resolved Hide resolved
Add `.spec.git.push.refspec` to allow specifying a refspec to be used
for performing a push operation. If specified alongside
`.spec.git.push.branch`, two push operations, one for each specified
push configuration will be performed.

Signed-off-by: Sanskar Jaiswal <[email protected]>
Signed-off-by: Sanskar Jaiswal <[email protected]>
Copy link
Member

@stefanprodan stefanprodan left a comment

Choose a reason for hiding this comment

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

LGTM

Thanks @aryan9600 🏅

@aryan9600 aryan9600 merged commit c120f91 into fluxcd:main Aug 23, 2023
7 checks passed
Copy link

@aristapimenta aristapimenta left a comment

Choose a reason for hiding this comment

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

(a bit too late)

LGTM!!!

@aryan9600 Very good docs! Thank you so much!! Good working with you 🤝

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/git Git related issues and pull requests enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Add git push option for arbitrary refspec
5 participants