Repository: openshift-kni/lifecycle-agent
Pull request #762: Pre-Konflux Alignment for LCA Repo
Author: login: fontivan
Labels: name: lgtm
description: Indicates that a PR is ready to be merged.
name: approved
description: Indicates a PR has been approved by an approver from all required OWNERS files.
Created: 2025-03-25T20:00:05Z | Merged: 2025-04-01T13:57:11Z

<!---
This template is not mandatory, but it is highly recommended. If you feel like
it's a bad fit for your PR, feel free to delete some or all of it. By filling
it, it will help you to think through the changes you are making and why you
are making them, and hopefully even regret some of them early. It will also
help the reviewer to understand your changes better, which will help them to
review your code more effectively. Remember reviewers time is valuable, and
often without this information, reviewing feels a bit like tedious reverse
engineering.

Be as verbose as you like! You don't have to write paragraphs if you don't
want, even brief notes can be helpful. But a lot of information never hurts.
Remember that often this will be the only record of our decisions / design, and
our only form of communication with other team members about our changes. So
it's good to be thorough.
-->

# Background / Context
Some project alignment is necessary alongside Konflux onboarding

<!---
Not all reviewers know everything there is to know about the project, use this
section to give a bit of background knowledge about the part of the project
you're changing. Things like links to previous relevant commits, existing
system behavior, how things currently work. Don't describe your changes or what
issue you're solving, just things that are already established. Even if these
seem obvious and the reviewer likely already knows them, it still helps
establish the context of the change.
-->

# Issue / Requirement / Reason for change
https://issues.redhat.com/browse/CNF-15329

<!---
The reason for making this PR. Use this section to describe the issue you're
solving. The shortcomings of the above background. This doesn't have to be an
actual issue/bug, but could also be a requirement that is being addressed or
the need for a new feature. Don't describe your solution just yet, focus on the
problem/requirement. If there's a relevant ticket, also link it here.
-->

# Solution / Feature Overview
- Update project to golang 1.23.0
- Prep Dockerfile for Konflux build
- Update golangci-lint to a version compatible with golang 1.23
- Ignore new warnings exposed by linter update as they are out of scope for this

<!---
Use this section to give a general overview of the solution you're proposing.
Explain how it helps to solve the issue you described above. No need to go into
code specifics.
-->

# Implementation Details
These changes are necessary to support Konflux onboarding: https://github.com/openshift-kni/lifecycle-agent/pull/763

<!---
If your change is complicated, use this section to describe the implementation
details of your PR. This is mostly good for huge PRs where it's easy to get
lost in a lot of diff, or when the changes are complicated. Not everything
needs to be described, just the main points.
-->

# Other Information
n/a

<!---
Any other relevant information that doesn't fit into the above sections. Extra
changes you did as part of your PR that you want to point out, considerations
such as performance, security. Future follow-up work that might be needed
(maybe create a ticket?), concerns you might have about your changes, etc.
-->

<!---

# Checklist

This is a personal checklist that should be applicable to most PRs. It's good
to go over it in order to make sure you haven't missed anything. If you feel
like some of these points are not relevant to your PR, feel free to keep them
unchecked and if you want also explain why you think they're inapplicable.

- [ ] I also copied this entire text into my commit message, and not just the GitHub PR description (`git config commit.template .github/pull_request_template.md`)
- [ ] I performed a rough self-review of my changes
- [x ] I explained non-trivial motivation for my code using code-comments
- [x ] I made sure my code passes linting, tests, and builds correctly
- [ ] I have ran the code and made sure it works as intended, and doesn't introduce any obvious regressions
- [x ] I have not committed any irrelevant changes (if you did, please point them out and why, ideally separate them into a different PR)
- [x ] I added tests (or decided that tests aren't really necessary)
- [ ] I deleted this checklist and all the "<!---" comments (like this one) from the commit message and the PR description, leaving only my own text
-->



Diff:
diff --git a/.ci-operator.yaml b/.ci-operator.yaml
index 1e59c02c25..7c15f83e3e 100644
--- a/.ci-operator.yaml
+++ b/.ci-operator.yaml
@@ -1,4 +1,4 @@
 build_root_image:
   name: release
   namespace: openshift
-  tag: rhel-9-release-golang-1.22-openshift-4.17
+  tag: rhel-9-release-golang-1.23-openshift-4.19
diff --git a/Dockerfile b/Dockerfile
index aede98f446..3471871700 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,21 @@
 #####################################################################################################
+# Build arguments
+ARG BUILDER_IMAGE=quay.io/projectquay/golang:1.23
+ARG RUNTIME_IMAGE=registry.access.redhat.com/ubi9-minimal:9.4
+# note: update origin-cli-artifacts from `latest` to an appropriate OCP version during release e.g `4.18`
+ARG ORIGIN_CLI_IMAGE=quay.io/openshift/origin-cli-artifacts:latest
+
+# Assume x86 unless otherwise specified
+ARG GOARCH="amd64"
+
 # Build the binaries
-FROM registry.access.redhat.com/ubi9/go-toolset:1.22.5-1730550521 as builder
+FROM ${BUILDER_IMAGE} as builder
+
+# Pass GOARCH into builder
+ARG GOARCH
+
+# Explicitly set the working directory
+WORKDIR /opt/app-root
 
 # Bring in the go dependencies before anything else so we can take
 # advantage of caching these layers in future builds.
@@ -18,14 +33,19 @@ COPY main main
 COPY utils utils
 
 # Build the binaries
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -mod=vendor -a -o build/manager main/main.go
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -mod=vendor -a -o build/lca-cli main/lca-cli/main.go
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} GO111MODULE=on go build -mod=vendor -a -o build/manager main/main.go
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} GO111MODULE=on go build -mod=vendor -a -o build/lca-cli main/lca-cli/main.go
 
 #####################################################################################################
 # Build the operator image
-# note: update origin-cli-artifacts from `latest` to an appropriate OCP verison during release e.g `4.18`
-FROM quay.io/openshift/origin-cli-artifacts:latest AS origincli
-FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
+FROM ${ORIGIN_CLI_IMAGE} AS origincli
+FROM ${RUNTIME_IMAGE}
+
+# Pass GOARCH into runtime
+ARG GOARCH
+
+# Explicitly set the working directory
+WORKDIR /
 
 RUN if [[ ! -f /bin/nsenter ]]; then \
         microdnf -y install util-linux-core && \
@@ -35,14 +55,15 @@ RUN if [[ ! -f /bin/nsenter ]]; then \
         rm -rf /var/cache/yum ; \
     fi
 
+
 COPY --from=builder \
-    /opt/app-root/src/build/manager \
-    /opt/app-root/src/build/lca-cli \
+    /opt/app-root/build/manager \
+    /opt/app-root/build/lca-cli \
     /usr/local/bin/
 
 COPY lca-cli/installation_configuration_files/ /usr/local/installation_configuration_files/
 
-COPY --from=origincli /usr/share/openshift/linux_amd64/oc.rhel9 /usr/bin/oc
+COPY --from=origincli /usr/share/openshift/linux_${GOARCH}/oc.rhel9 /usr/bin/oc
 
 COPY must-gather/collection-scripts/ /usr/bin/
 
diff --git a/controllers/seedgen_controller.go b/controllers/seedgen_controller.go
index 3fdae9b35d..ce686b49ac 100644
--- a/controllers/seedgen_controller.go
+++ b/controllers/seedgen_controller.go
@@ -997,6 +997,7 @@ func (r *SeedGeneratorReconciler) Reconcile(ctx context.Context, req ctrl.Reques
 		return
 	case phases.PhaseInitial:
 		// Run the system validation
+		// nolint: gocritic
 		if rejection := r.validateSystem(ctx); len(rejection) > 0 {
 			setSeedGenStatusFailed(seedgen, rejection)
 			r.Log.Info(fmt.Sprintf("Seed generation rejected: system validation failed: %s", rejection))
diff --git a/go.mod b/go.mod
index 3304df75da..58b21af318 100644
--- a/go.mod
+++ b/go.mod
@@ -1,8 +1,6 @@
 module github.com/openshift-kni/lifecycle-agent
 
-go 1.22.4
-
-toolchain go1.22.7
+go 1.23.0
 
 require (
 	github.com/containers/image/v5 v5.29.3
diff --git a/hack/golangci-lint.sh b/hack/golangci-lint.sh
index da155d3384..8ff8ae48f1 100755
--- a/hack/golangci-lint.sh
+++ b/hack/golangci-lint.sh
@@ -1,42 +1,108 @@
-#!/bin/bash
+#!/usr/bin/env bash
+set -eou pipefail
 
-VERSION="1.55.2"
+# The version of golangci-lint that should be used
+GOLANGCI_LINT_VERSION="1.64.5"
 
-rootdir=$(git rev-parse --show-toplevel)
-if [ -z "${rootdir}" ]; then
-    echo "Failed to determine top level directory"
-    exit 1
-fi
+# IsGoLangCiLintInstalled is used to check whether golangci-lint executable is on the $PATH.
+function IsGolangCiLintInstalled {
 
-bindir="${rootdir}/bin"
-golangci_lint="${bindir}/golangci-lint"
-
-function get_tool {
-    mkdir -p "${bindir}"
-    echo "Downloading golangci-lint tool"
-    curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -d -b "${bindir}" "v${VERSION}"
-
-    if [ $? -ne 0 ]; then
-        echo "Install from script failed. Trying go install"
-        go install "github.com/golangci/golangci-lint/cmd/golangci-lint@v${VERSION}"
-        if [ $? -ne 0 ]; then
-            echo "Install of golangci-lint failed"
-            exit 1
-        else
-            golangci_lint=$(which golangci-lint)
-        fi
+    echo "Checking if golangci-lint is installed"
+
+    if which golangci-lint 1> /dev/null 2>&1; then
+        return 0
+    fi
+
+    echo "Could not find golangci-lint on path"
+
+    return 1
+}
+
+# IsGolangCiLintCorrectVersion is used to check the installed version of golangci-lint and ensure it is as expected.
+function IsGolangCiLintCorrectVersion {
+
+    local requiredVersion
+    requiredVersion="${1}"
+
+    local installedVersion
+    installedVersion="$(golangci-lint version 2> /dev/null | awk '{ print $4 }')"
+
+    echo "Checking if installed golang version matches requirement"
+
+    if [[ "${installedVersion}" == "${requiredVersion}" ]]; then
+        return 0
+    fi
+
+    echo "Installed version does not match expected version"
+
+    return 1
+}
+
+# DownloadGolangCiLint is used to download a specified version of golangci-lint
+function DownloadGolangCiLint {
+
+    local versionNumber
+    versionNumber="${1}"
+
+    echo "installing golangci-lint version ${versionNumber}"
+    if curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v${versionNumber}; then
+        return 0
     fi
+
+    return 1
+}
+
+# RunGolangCiLint is used to execute the lint command
+function RunGolangCiLint {
+
+    echo "Running golangci-lint"
+
+    if golangci-lint run -v; then
+        return 0;
+    fi
+
+    return 1
 }
 
-if [ ! -f "${golangci_lint}" ]; then
-    get_tool
-else
-    current_ver=$("${golangci_lint}" version)
-    if ! [[ "${current_ver}" =~ ${VERSION} ]]; then
-        get_tool
+# Main body of shell script
+function Main {
+
+    # Check whether we need to install golangci-lint
+    local installRequired
+    installRequired="false"
+
+    # Check if its present at all
+    if ! IsGolangCiLintInstalled; then
+        installRequired="true"
+    fi
+
+    # Check if its the right version
+    if ! IsGolangCiLintCorrectVersion "${GOLANGCI_LINT_VERSION}"; then
+        installRequired="true"
+    fi
+
+    # Install the correct version if we need to
+    if [[ "${installRequired}" == "true" ]]; then
+        if ! DownloadGolangCiLint "${GOLANGCI_LINT_VERSION}"; then
+            echo "failed to install golangci-lint"
+            return 0
+        fi
+    else
+        echo "golangci-lint already installed and correct version (${GOLANGCI_LINT_VERSION})"
+    fi
+
+    # Execute the linter
+    if ! RunGolangCiLint; then
+        echo "failed to pass linter checks"
+        return 0
     fi
+
+    # All passed!
+    return 1
+}
+
+if Main; then
+    exit 1
 fi
 
-export GOCACHE=/tmp/
-export GOLANGCI_LINT_CACHE=/tmp/.cache
-"${golangci_lint}" run --verbose --print-resources-usage --modules-download-mode=vendor --timeout=5m0s
+exit 0
diff --git a/internal/extramanifest/extramanifest.go b/internal/extramanifest/extramanifest.go
index 0bdc39b1c5..dce6da4ea4 100644
--- a/internal/extramanifest/extramanifest.go
+++ b/internal/extramanifest/extramanifest.go
@@ -319,6 +319,7 @@ func (h *EMHandler) ValidateExtraManifestConfigmaps(ctx context.Context, content
 				case k8serrors.IsInvalid(err), k8serrors.IsBadRequest(err): // Capture both invalid syntax and webhook validation errors
 					warnings = append(warnings, fmt.Sprintf("%s[%s] - dryrun failed in namespace %s: %s", mKind, mName, mNamespace, err.Error()))
 				default: // Capture unknown runtime error
+					// nolint: staticcheck
 					return validationWarn, fmt.Errorf(fmt.Sprintf("failed to validate manifest with dryrun: %v", err.Error()))
 				}
 			}
@@ -524,6 +525,7 @@ func (h *EMHandler) ApplyExtraManifests(ctx context.Context, fromDir string) err
 				if errors.As(err, &groupDiscoveryErr) || meta.IsNoMatchError(err) {
 					return NewEMFailedError(errMsg)
 				}
+				// nolint: staticcheck
 				return fmt.Errorf(errMsg)
 			}
 
diff --git a/internal/healthcheck/healthcheck.go b/internal/healthcheck/healthcheck.go
index 3d1d23e58b..953765e80d 100644
--- a/internal/healthcheck/healthcheck.go
+++ b/internal/healthcheck/healthcheck.go
@@ -102,6 +102,7 @@ func HealthChecks(ctx context.Context, c client.Reader, l logr.Logger) error {
 
 	if len(failures) > 0 {
 		l.Info("One or more health checks failed")
+		// nolint: staticcheck
 		return fmt.Errorf(strings.Join(append([]string{"one or more health checks failed"}, failures...), "\n  - "))
 	}
 
@@ -140,6 +141,7 @@ func IsDataProtectionApplicationReconciled(ctx context.Context, c client.Reader,
 
 	msg := "dataProtectionApplication not reconciled"
 	l.Info(msg)
+	// nolint: staticcheck
 	return false, fmt.Errorf(msg)
 }
 
@@ -152,6 +154,7 @@ func AreBackupStorageLocationsAvailable(ctx context.Context, c client.Reader, l
 	if len(backupStorageLocationList.Items) == 0 {
 		msg := "backupsStorageLocations not yet created"
 		l.Info(msg)
+		// nolint: staticcheck
 		return fmt.Errorf(msg)
 	}
 
@@ -159,6 +162,7 @@ func AreBackupStorageLocationsAvailable(ctx context.Context, c client.Reader, l
 		if bsl.Status.Phase != velerov1.BackupStorageLocationPhaseAvailable {
 			msg := fmt.Sprintf("backupStorageLocation %s not available", bsl.Name)
 			l.Info(msg)
+			// nolint: staticcheck
 			return fmt.Errorf(msg)
 		}
 	}
@@ -207,6 +211,7 @@ func IsClusterVersionReady(ctx context.Context, c client.Reader, l logr.Logger)
 		if !getClusterOperatorStatusCondition(co.Status.Conditions, configv1.OperatorAvailable) {
 			msg := fmt.Sprintf("clusterVersion %s not ready", co.Name)
 			l.Info(msg)
+			// nolint: staticcheck
 			return fmt.Errorf(msg)
 		}
 	}
@@ -247,6 +252,7 @@ func AreClusterOperatorsReady(ctx context.Context, c client.Reader, l logr.Logge
 
 	var notready []string
 	for _, co := range clusterOperatorList.Items {
+		// nolint: gocritic
 		if !getClusterOperatorStatusCondition(co.Status.Conditions, configv1.OperatorAvailable) {
 			notready = append(notready, co.Name)
 			l.Info(fmt.Sprintf("co not ready: %s", co.Name))
@@ -301,12 +307,14 @@ func IsNodeReady(ctx context.Context, c client.Reader, l logr.Logger) error {
 		if !getNodeStatusCondition(node.Status.Conditions, corev1.NodeReady) {
 			msg := fmt.Sprintf("node is not yet ready: %s", node.Name)
 			l.Info(msg)
+			// nolint: staticcheck
 			return fmt.Errorf(msg)
 		}
 
 		if getNodeStatusCondition(node.Status.Conditions, corev1.NodeNetworkUnavailable) {
 			msg := fmt.Sprintf("node network unavailable: %s", node.Name)
 			l.Info(msg)
+			// nolint: staticcheck
 			return fmt.Errorf(msg)
 		}
 
@@ -317,6 +325,7 @@ func IsNodeReady(ctx context.Context, c client.Reader, l logr.Logger) error {
 			if _, found := labels[label]; !found {
 				msg := fmt.Sprintf("node missing %s label: %s", label, node.Name)
 				l.Info(msg)
+				// nolint: staticcheck
 				return fmt.Errorf(msg)
 			}
 		}
@@ -354,6 +363,7 @@ func IsSriovNetworkNodeReady(ctx context.Context, c client.Reader, l logr.Logger
 	}
 
 	if len(nodeStates.Items) == 0 {
+		// nolint: staticcheck
 		return fmt.Errorf(SriovNetworkNodeStateNotPresentMsg)
 	}
 
diff --git a/internal/imagemgmt/imagemgmt.go b/internal/imagemgmt/imagemgmt.go
index 75cdae92b8..016507a8fa 100644
--- a/internal/imagemgmt/imagemgmt.go
+++ b/internal/imagemgmt/imagemgmt.go
@@ -86,6 +86,7 @@ func (c *ImageMgmtClient) CheckDiskUsageAgainstThreshold(thresholdPercent int) (
 	}
 
 	// Get disk usage percentage
+	// nolint: gosec
 	usedpct := int(((stat.Blocks - stat.Bavail) * 100) / stat.Blocks)
 	c.Log.Info(fmt.Sprintf("DEBUG: Disk usage of %s is currently %d%%", c.StoragePath, usedpct))
 	return (usedpct > thresholdPercent), nil
diff --git a/internal/precache/helper.go b/internal/precache/helper.go
index 7df7a33828..be39cf0b63 100644
--- a/internal/precache/helper.go
+++ b/internal/precache/helper.go
@@ -131,6 +131,7 @@ func renderJob(config *Config, log logr.Logger, ibu *ibuv1.ImageBasedUpgrade, sc
 	execPrecacheArgs := fmt.Sprintf("nice -n %d ionice -c %d -n %d lca-cli ibu-precache-workload",
 		nicePriority, ioNiceClass, ioNicePriority)
 
+	// nolint: gocritic
 	precacheEnvVars := append(config.EnvVars, []corev1.EnvVar{
 		{
 			Name:  EnvPrecacheSpecFile,
diff --git a/lca-cli/cmd/ibuStaterootSetup.go b/lca-cli/cmd/ibuStaterootSetup.go
index ad6ea9c030..cd22ef54f5 100644
--- a/lca-cli/cmd/ibuStaterootSetup.go
+++ b/lca-cli/cmd/ibuStaterootSetup.go
@@ -126,6 +126,7 @@ func initStaterootSetupSigHandler(logger logr.Logger, opsClient ops.Ops, seedIma
 			logger.Error(fmt.Errorf("proceeding to shutdown stateroot setup job"), "")
 			os.Exit(1)
 		default:
+			// nolint: staticcheck
 			logger.Error(fmt.Errorf(s.String()), "Unknown signal") // this is not expected to be hit
 		}
 	}()
diff --git a/lca-cli/ops/ops.go b/lca-cli/ops/ops.go
index 57d6365cea..2ceca40d21 100644
--- a/lca-cli/ops/ops.go
+++ b/lca-cli/ops/ops.go
@@ -176,6 +176,7 @@ func (o *ops) RunUnauthenticatedEtcdServer(authFile, name string) error {
 	o.log.Info("Run unauthenticated etcd server for recert tool")
 
 	command := podman
+	// nolint: gocritic
 	args := append(podmanRecertArgs,
 		"--authfile", authFile, "--detach",
 		"--name", name,
@@ -229,6 +230,7 @@ func (o *ops) RunRecert(recertContainerImage, authFile, recertConfigFile string,
 	o.log.Info("Start running recert")
 	command := podman
 
+	// nolint: gocritic
 	args := append(podmanRecertArgs, "--name", "recert",
 		"-v", fmt.Sprintf("/etc:%s", recert.EtcMount),
 		"-v", fmt.Sprintf("/etc/ssh:%s", recert.EtcSSHMount),
diff --git a/lca-cli/postpivot/postpivot.go b/lca-cli/postpivot/postpivot.go
index 8248b3c975..ac446151aa 100644
--- a/lca-cli/postpivot/postpivot.go
+++ b/lca-cli/postpivot/postpivot.go
@@ -299,6 +299,7 @@ func createServerSSHKeyFile(serverSSHKey clusterconfig_api.ServerSSHKey) error {
 	}
 
 	fullKeyPath := filepath.Join(common.SSHServerKeysDirectory, serverSSHKey.FileName)
+	// nolint: gosec
 	if err := os.WriteFile(fullKeyPath, []byte(serverSSHKey.FileContent), fs.FileMode(mode)); err != nil {
 		return fmt.Errorf("failed to write server SSH key %s: %w", fullKeyPath, err)
 	}
@@ -345,6 +346,7 @@ func (p *PostPivot) setProxyAndProxyStatus(seedReconfig *clusterconfig_api.SeedR
 		set.Insert(nss)
 	}
 
+	// nolint: gocritic
 	if len(seedReconfig.Proxy.NoProxy) > 0 {
 		for _, userValue := range strings.Split(seedReconfig.Proxy.NoProxy, ",") {
 			if userValue != "" {


Reviews:
user: login: jc-rh
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-31T15:30:43Z
user: login: fontivan
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-31T15:41:13Z
user: login: rauhersu
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-01T10:20:24Z
user: login: fontivan
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-01T12:45:24Z

Review comments:
diff_hunk: @@ -1,6 +1,21 @@
 #####################################################################################################
+# Build arguments
+ARG BUILDER_IMAGE=quay.io/projectquay/golang:1.23
+ARG RUNTIME_IMAGE=registry.access.redhat.com/ubi9-minimal:9.4
+# note: update origin-cli-artifacts from `latest` to an appropriate OCP version during release e.g `4.18`
+ARG ORIGIN_CLI_IMAGE=quay.io/openshift/origin-cli-artifacts:latest
+
+# Assume x86 unless otherwise specified
+ARG GOARCH="amd64"
+
 # Build the binaries
-FROM registry.access.redhat.com/ubi9/go-toolset:1.22.5-1730550521 as builder
path: Dockerfile
user: login: jc-rh
body: @mresvanis I can't recall why we started using the go-toolset image. It seems slow on releasing newer golang versions (no 1.23 yet). Can you double check if Steven's change is good?
created_at: 2025-03-31T15:30:43Z
author_association: MEMBER
diff_hunk: @@ -1,6 +1,21 @@
 #####################################################################################################
+# Build arguments
+ARG BUILDER_IMAGE=quay.io/projectquay/golang:1.23
+ARG RUNTIME_IMAGE=registry.access.redhat.com/ubi9-minimal:9.4
+# note: update origin-cli-artifacts from `latest` to an appropriate OCP version during release e.g `4.18`
+ARG ORIGIN_CLI_IMAGE=quay.io/openshift/origin-cli-artifacts:latest
+
+# Assume x86 unless otherwise specified
+ARG GOARCH="amd64"
+
 # Build the binaries
-FROM registry.access.redhat.com/ubi9/go-toolset:1.22.5-1730550521 as builder
path: Dockerfile
user: login: fontivan
body: I found the change here in an older PR: https://github.com/openshift-kni/lifecycle-agent/pull/65

and yeah it seems like go1.23 is not available yet in ubi.

Also note that for Konflux we will be using the openshift golang builder but that will be in a separate PR: https://github.com/openshift-kni/lifecycle-agent/pull/763/files#diff-e5b5fa6deab8f9cda1e5725b06bd8d766482779861b02c95a47669a7ff8a844e
created_at: 2025-03-31T15:41:13Z
author_association: COLLABORATOR
diff_hunk: @@ -18,14 +33,19 @@ COPY main main
 COPY utils utils
 
 # Build the binaries
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -mod=vendor -a -o build/manager main/main.go
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -mod=vendor -a -o build/lca-cli main/lca-cli/main.go
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} GO111MODULE=on go build -mod=vendor -a -o build/manager main/main.go
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} GO111MODULE=on go build -mod=vendor -a -o build/lca-cli main/lca-cli/main.go
 
 #####################################################################################################
 # Build the operator image
-# note: update origin-cli-artifacts from `latest` to an appropriate OCP verison during release e.g `4.18`
-FROM quay.io/openshift/origin-cli-artifacts:latest AS origincli
-FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
+FROM ${ORIGIN_CLI_IMAGE} AS origincli
+FROM ${RUNTIME_IMAGE}
+
+# Pass GOARCH into runtime
+ARG GOARCH
+
+# Explicitly set the working directory
+WORKDIR /
 
 RUN if [[ ! -f /bin/nsenter ]]; then \
         microdnf -y install util-linux-core && \
path: Dockerfile
user: login: rauhersu
body: todo: we need to start working on the hermetic build + subscription manager to install those packages on the konflux side here.
created_at: 2025-04-01T10:19:28Z
author_association: COLLABORATOR
diff_hunk: @@ -18,14 +33,19 @@ COPY main main
 COPY utils utils
 
 # Build the binaries
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -mod=vendor -a -o build/manager main/main.go
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -mod=vendor -a -o build/lca-cli main/lca-cli/main.go
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} GO111MODULE=on go build -mod=vendor -a -o build/manager main/main.go
+RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} GO111MODULE=on go build -mod=vendor -a -o build/lca-cli main/lca-cli/main.go
 
 #####################################################################################################
 # Build the operator image
-# note: update origin-cli-artifacts from `latest` to an appropriate OCP verison during release e.g `4.18`
-FROM quay.io/openshift/origin-cli-artifacts:latest AS origincli
-FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
+FROM ${ORIGIN_CLI_IMAGE} AS origincli
+FROM ${RUNTIME_IMAGE}
+
+# Pass GOARCH into runtime
+ARG GOARCH
+
+# Explicitly set the working directory
+WORKDIR /
 
 RUN if [[ ! -f /bin/nsenter ]]; then \
         microdnf -y install util-linux-core && \
path: Dockerfile
user: login: fontivan
body: I think I will do that in a separate PR once I go through the details

created_at: 2025-04-01T12:45:23Z
author_association: COLLABORATOR

PR comments:
user: login: fontivan
created_at: 2025-03-25T20:00:48Z
body: /hold WIP
author_association: COLLABORATOR
user: login: fontivan
created_at: 2025-03-25T20:01:47Z
body: /cc @rauhersu 
author_association: COLLABORATOR
user: login: fontivan
created_at: 2025-03-26T13:43:38Z
body: /retest
author_association: COLLABORATOR
user: login: fontivan
created_at: 2025-03-26T15:17:08Z
body: /retest
author_association: COLLABORATOR
user: login: fontivan
created_at: 2025-03-26T20:09:47Z
body: Depends on https://github.com/openshift/release/pull/63230 due to golangci-lint adding a cache directory in a place that is not writable in our default CI configuration

author_association: COLLABORATOR
user: login: fontivan
created_at: 2025-03-27T16:39:05Z
body: /retest
author_association: COLLABORATOR
user: login: fontivan
created_at: 2025-03-27T21:35:13Z
body: /unhold

author_association: COLLABORATOR
user: login: fontivan
created_at: 2025-03-28T15:05:22Z
body: /test ibu-e2e-flow
author_association: COLLABORATOR
user: login: rauhersu
created_at: 2025-04-01T10:32:24Z
body: /lgtm
author_association: COLLABORATOR
user: login: jc-rh
created_at: 2025-04-01T13:46:53Z
body: /approve
author_association: MEMBER
user: login: openshift-ci[bot]
created_at: 2025-04-01T13:47:08Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/openshift-kni/lifecycle-agent/pull/762#issuecomment-2769421015" title="Approved">jc-rh</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=openshift-kni%2Flifecycle-agent).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/openshift-kni/lifecycle-agent/blob/main/OWNERS)~~ [jc-rh]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: CONTRIBUTOR