# We have to emulate directory layout as in the repo so that imports in go files work fine.
ARG roxpath=/workspace/src/github.com/stackrox/rox

# Use CentOS Stream 8 image as the base builder because it has recent Go and git packages needed for the build.
# https://wiki.centos.org/FAQ/CentOSStream#Where_do_I_get_CentOS_Stream_container_images.3F
FROM quay.io/centos/centos:stream8 as builder-base
RUN yum update --security -y && yum install -y golang git

# Build the manager binary
FROM builder-base as builder
ARG roxpath

WORKDIR ${roxpath}/
ENV GOPATH=/workspace

# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum

# Add GitHub hosts as known ones so that git does not complain.
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

# Make sure that private and source-only packages on github.com can be downloaded successfully as go modules.
RUN echo '[url "git@github.com:"]' >> ~/.gitconfig && echo -e '\tinsteadOf = https://github.com/' >> ~/.gitconfig
ENV GOPRIVATE="github.com/stackrox/*"

# Cache deps before building and copying source so that we don't need to re-download as much and so that source changes
# don't invalidate our downloaded layer.
# We're not using `go mod tidy` here becuase go mod tidy needs to examine _source code_ in order to find unused modules.
# There's no source code in this docker layer yet and so `go mod tidy` would empty go.mod and go.sum which is not what
# we want. If we're to COPY source before running `go mod tidy`, local docker build times would go up because any code
# change will invalidate docker layers and will cause modules redownload (during `tidy`). Therefore we use
# `go mod download` as a compromise for shorter local build times due to docker layer caching. There are CI checks
# ensuring that there will not be unused modules for the repo overall.
# Note that `go mod download` can donwload more stuff than `go mod tidy` https://github.com/golang/go/issues/43994
# However it does _not_ seem to resolve packages _incorrectly_ and so should be safe especially given that downloaded
# packages are only used during build and later this docker layer is discarded (only resulting binary goes in the final
# image).
RUN --mount=type=ssh,required=true go mod download

# Copy operator source
COPY operator/ operator/

# Copy common packages from repo root
COPY pkg/ pkg/
COPY image/ image/

# Copy generated files from repo root.
# Not generating them during this docker build because they anyway need to be generated by the orchestrating makefiles.
COPY generated/ generated/

# Copy scripts/go-build.sh and dependencies.
COPY scripts/ scripts/
COPY operator/build/status.sh status.sh

# This creates a git repo in workdir so that `git grep` command in build.sh can succeed and actually find //XDef-s.
RUN git init && git add .

# Build the operator binary.
RUN GOOS=$(go env GOOS) scripts/go-build.sh operator
# Copy the operator binary to a location from where it will be taken into the final image.
RUN cp -a bin/$(go env GOOS)/operator stackrox-operator

# https://access.redhat.com/containers/?tab=tags#/registry.access.redhat.com/ubi8-minimal
FROM registry.access.redhat.com/ubi8-minimal:8.5

ARG roxpath

ARG ROX_IMAGE_FLAVOR
ENV ROX_IMAGE_FLAVOR=${ROX_IMAGE_FLAVOR}

RUN microdnf update && microdnf clean all && rm -rf /var/cache/yum/*

COPY --from=builder ${roxpath}/stackrox-operator /usr/local/bin/

# The following are numeric uid and gid of `nobody` user in UBI.
# We can't use symbolic names because otherwise k8s will fail to start the pod with an error like this:
# Error: container has runAsNonRoot and image has non-numeric user (nobody), cannot verify user is non-root (pod: "stackrox-operator-controller-manager-75bc744454-bkbjr_stackrox-operator-system(49874aae-2695-4d3a-afd3-8723914d2af5)", container: manager)
USER 65534:65534

ENTRYPOINT ["/usr/local/bin/stackrox-operator"]
