-
Notifications
You must be signed in to change notification settings - Fork 47
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
Operator Controller Release #133
Operator Controller Release #133
Conversation
e462cea
to
e812ab5
Compare
46447e9
to
af6453c
Compare
.dockerignore
Outdated
@@ -1,4 +1,3 @@ | |||
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file | |||
# Ignore build and test binaries. | |||
bin/ | |||
# Ignore test binaries. |
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.
it seems we are using bin
as the context for building the image - do we still need the .dockerignore?
@@ -132,6 +132,24 @@ docker-buildx: test ## Build and push docker image for the manager for cross-pla | |||
- docker buildx rm project-v3-builder | |||
rm Dockerfile.cross | |||
|
|||
########### |
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.
can we get some make help
docs around release - when/how it should be used?
internal/version/version.go
Outdated
package version | ||
|
||
// GitCommit indicates which commit the rukpak binaries were built from | ||
var GitCommit string |
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.
does the value get injected at build time? is it worth adding a comment?
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.
+1.
Also, I don't see this used anywhere else in the Go binary. Maybe we should take this out of this PR and create a separate issue to remind us to get version info into the binary and have a way to print it out.
IIRC the go compiler as of 1.18 or 1.19 now injects this git info automatically. We might not need to do it ourselves anymore.
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.
lgtm - I just had a couple of small questions/suggestions. Nothing blocking.
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.
Looks pretty good overall! The Rukpak setup mostly works, but I think it was somewhat rushed and probably is in need of some fine tuning.
I left some comments along those lines, but there's probably more to do as well. Regardless, I think further improvements could be done in one or more follow-ons.
Dockerfile
Outdated
FROM golang:1.19 as builder | ||
ARG TARGETOS | ||
ARG TARGETARCH | ||
FROM gcr.io/distroless/static:debug-nonroot |
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.
I don't think we need the debug variant for operator-controller do we?
FROM gcr.io/distroless/static:debug-nonroot | |
FROM gcr.io/distroless/static:nonroot |
|
||
ENTRYPOINT ["/manager"] | ||
COPY manager manager | ||
|
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 explicitly specify the user? Honestly not sure. I think my suggestion would be to specify it explicitly rather than inherit it from the base image.
We should also specify the entrypoint since this is the only binary we'll be using in this image.
USER 65532:65532 | |
ENTRYPOINT ["/manager"] |
Makefile
Outdated
@@ -95,10 +95,10 @@ kind-cluster-cleanup: kind ## Delete the kind cluster | |||
|
|||
.PHONY: build | |||
build: manifests generate fmt vet ## Build manager binary. | |||
go build -o bin/manager main.go | |||
CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o bin/manager main.go |
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.
I discovered goreleaser build
recently. WDYT about using that instead? The big benefit is that we essentially get local builds that use the exact same configuration as the release builds (same env, same ldflags, etc.)
@@ -109,7 +109,7 @@ wait: | |||
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ | |||
.PHONY: docker-build | |||
docker-build: generate ## Build docker image with the operator-controller. | |||
docker build -t ${IMG} . | |||
docker build -t ${IMG} -f Dockerfile ./bin/ |
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.
This seems like it'll fail because the Dockerfile expects the binary to be pre-built by goreleaser. The previous Dockerfile included the binary build as a pre-step in a multi-stage build.
I think we need to add build
to the list of pre-reqs?
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.
Also, the binary built in this case needs to be GOOS=linux, but in the non-docker build case should just take the default settings of the environment. That way, mac and linux machines can both build local binaries and container image binaries correctly.
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.
I've updated the build
target to use goreleaser build
, and I believe that's also resolved your concern here. By default, when running make build
, goreleaser will set GOARCH and GOOS to the user's setup. This won't apply though when building for release.
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.
For docker-build
I think we need to explicitly set GOOS=linux, right? If we don't won't a macOS user end up with a docker container that contains a darwin binary?
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.
TBH, building within the container generally improves compatibility within the container and improves build reproducibility.
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.
GoReleaser doesn't support that, so if we want binary builds happening inside docker, we can't use goreleaser I don't think.
I don't love this restriction, but my main interests are:
- we have exactly one way to build the the binaries snd containers
- the binaries we build ARE the binaries that end up in the container.
GoReleaser can be made to ensure reproducibility (except maybe Go compiler version) so I think we end up at the same place. It just takes a bit more care to get there.
Makefile
Outdated
.PHONY: docker-push | ||
docker-push: ## Push docker image with the manager. |
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.
WDYT about removing docker-push
? We don't use it anywhere else, and it isn't part of the normal dev flow.
substitute: | ||
envsubst < .goreleaser.template.yml > .goreleaser.yml |
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 this used anywhere other than release
? If not, I'd propose to consolidate this into the release
recipe.
Having a top-level target called substitute
seems like it could be both too vague and potentially confusing for contributors wondering if/when they should use it.
internal/version/version.go
Outdated
func String() string { | ||
return GitCommit | ||
} |
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.
I don't see this used anywhere. Remove it? Seems like anything that needs to know the git commit can just use version.GitCommit
directly.
Makefile
Outdated
|
||
quickstart: VERSION ?= $(shell git describe --abbrev=0 --tags) | ||
quickstart: generate ## Generate the installation release manifests | ||
kubectl kustomize config/default | sed "s/:latest/:$(VERSION)/g" > operator-controller.yaml |
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.
Kustomize can do image ref substitution directly. We may want to consider whether that is a viable alternative. If we aren't very careful, this approach could silently replace other image refs in our manifests if they happen to use :latest
.
Really anything referencing latest
in our manifests would be a problem, so maybe in practice this would be fine. But I'd rather not compound that problem if it does somehow happen.
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 I can definitely see that being a problem. Let me fix this up to make sure we're just using the substitutions provided by kustomize.
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.
OK, with the latest push I have this being done through kustomize using the VERSION
env set during release. Let me know what you think :)
use: github-native | ||
skip: $DISABLE_RELEASE_PIPELINE | ||
release: | ||
disable: $DISABLE_RELEASE_PIPELINE |
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.
I'm trying to remember why we do this convoluted envsubst thing rather than use the --snapshot
flag when invoking goreleaser.
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.
Ah I remember: we want to build/push images/manifests -- but NOT release -- for builds of the main branch.
It seems like this problem is half solved. It's possible to template release.disable
, but still not possible to template changelog.skip
.
I opened an issue in goreleaser to see if we can make changelog.skip
templatable as well: goreleaser/goreleaser#3828
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.
Sweet. The maintainer already merged a PR that fixes this. Once there's a release, we can directly reference {{ .Env.DISABLE_RELEASE_PIPELINE }}
as a template value in the actual goreleaser config file. No need for the envsubst shenanigans after that.
.goreleaser.template.yml
Outdated
```bash | ||
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/{{ .Env.CERT_MGR_VERSION }}/cert-manager.yaml | ||
kubectl wait --for=condition=Available --namespace=cert-manager deployment/cert-manager-webhook --timeout=60s | ||
kubectl apply -f https://github.com/operator-framework/rukpak/releases/latest/download/rukpak.yaml | ||
kubectl wait --for=condition=Available --namespace=rukpak-system deployment/core --timeout=60s | ||
kubectl wait --for=condition=Available --namespace=rukpak-system deployment/helm-provisioner --timeout=60s | ||
kubectl wait --for=condition=Available --namespace=rukpak-system deployment/rukpak-webhooks --timeout=60s | ||
kubectl apply -f https://github.com/operator-framework/operator-controller/releases/download/{{ .Tag }}/operator-controller.yaml | ||
kubectl wait --for=condition=Available --namespace=operator-controller-system deployment/operator-controller --timeout=60s | ||
``` |
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.
This is getting somewhat long. I suppose this is basically our "distribution", right? I wonder if we should think about consolidating this into a script and then having the header be a one-liner that shows how to curl | sh
the script? (could be a follow-on)
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, this is basically the distribution method at the moment. We have an upcoming issue though that should accomplish what you're asking for here: #110
b338664
to
3eba91d
Compare
FROM golang:1.19 as builder | ||
ARG TARGETOS | ||
ARG TARGETARCH | ||
FROM gcr.io/distroless/static:nonroot |
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.
Can we add a comment to this file that says it's intended to be used with make docker-build
or make release
?
Makefile
Outdated
.PHONY: goreleaser | ||
goreleaser: $(GORELEASER) ## Builds a local copy of goreleaser | ||
$(GORELEASER): $(LOCALBIN) | ||
test -s $(LOCALBIN)/goreleaser || GOBIN=$(LOCALBIN) go install github.com/goreleaser/goreleaser@v1.11.2 |
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.
For follow-up, but I'm noticing right now -- we should move LOCALBIN somewhere else because the docker build copies all these build tool binaries into the build context unnecessarily, which makes builds take longer.
Rukpak puts these in ./tools/bin
and reserves ./bin
for binaries built from the repo itself.
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.
Great point, I'll create a follow-up issue to take care of both these items.
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.
Added #135
0f860a5
to
d57ed68
Compare
@joelanford @perdasilva I believe I've addressed all your comments, please take another look when you have a moment. |
e2e is still failing for me on my Mac. To fix it for me, I added this line, directly above the declaration of the
|
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file | ||
# Ignore build and test binaries. | ||
bin/ | ||
testbin/ |
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 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.
Good point, I'll have this ignore all the tools binaries to speed up the build. We can remove it once the tools live in a different folder since there shouldn't be anything left to ignore for docker.
963d8a6
to
1bf6eef
Compare
The goreleaser config file wasn't being generated which is what was probably causing all of these environment based failures. I've fixed that issue now, so please pull and test again when you can :) |
1bf6eef
to
034bac8
Compare
Still failing for me on macOS (arm64, but I don't think that matters). After I run
So I'm still getting a darwin binary. Same fix from before still fixes it for me. |
034bac8
to
0ec29f4
Compare
Strange, it's not clear to me why that fix is necessary since the goos is set to linux in the goreleaser template for both the binary and docker build. I've updated the branch again with your fix in the meantime. |
I think the As far as the docker build, the config in the goreleaser file is only used during a release. The This docker build stuff could maybe be improved some as well (maybe the |
goos: | ||
- linux |
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 if GH ate my comment or if I managed not to submit it.
This seems to build only a single binary for linux/$GOARCH
. But we need to build binaries for the following:
linux/amd64
linux/arm64
linux/ppc64le
linux/s390x
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 then need to propagate these to separate individual docker images, and then build the manifest list that combines all of them.
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.
All this is probably fine to do in a follow-up, but might be good to do that before we tag this repo the first time.
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.
/lgtm
Nice work! A few more things are better left for smaller follow-ups:
- Multiarch binaries and containers
- Remove the
envsubst
and goreleaser template file when there's a new release of goreleaser - Move tools binaries to separate directory.
- Investigate calling goreleaser as part of the
docker-build
target.
Anything I missed?
Adds a release github action and implements goreleaser, borrowing heavily from rukpak but stripped down a bit. Signed-off-by: dtfranz <dfranz@redhat.com>
0ec29f4
to
26b9335
Compare
Thanks @joelanford! Yes, I think that about sums it up. |
Totally reasonable. I think that's another small cleanup thing we can do once this heavy lift has merged. /lgtm |
Adds a release github action and implements goreleaser, borrowing heavily from rukpak but stripped down a bit.
See my fork here for an example release output: https://github.com/dtfranz/operator-controller/releases/tag/v0.0.2
Some of the additional build targets found in rukpak have been stripped out to keep this smaller.
Addresses #132 and #109