Skip to content

embed manifest in ImageBuild#117

Merged
bennyz merged 4 commits into
centos-automotive-suite:mainfrom
bennyz:embed-manifest-imagebuild
Feb 16, 2026
Merged

embed manifest in ImageBuild#117
bennyz merged 4 commits into
centos-automotive-suite:mainfrom
bennyz:embed-manifest-imagebuild

Conversation

@bennyz

@bennyz bennyz commented Feb 15, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Upgraded Operator SDK to v1.42.0
    • ImageBuild now accepts an inline AIB manifest with an explicit manifest filename, plus custom environment definitions and extra builder arguments
    • Auto-generated and user-provided build names are sanitized/truncated to be Kubernetes-safe
  • Documentation

    • Updated build creation and monitoring steps (apply ImageBuild YAML; tail build job logs)
  • Chores

    • Removed the configurable manifest size limit from operator config.

@coderabbitai

coderabbitai Bot commented Feb 15, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@bennyz has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 31 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Replaces external ConfigMap-based AIB manifest with inline aib.manifest + manifestFileName, adds customDefs and aibExtraArgs, propagates through API/CRD/server/controller, controller materializes a manifest ConfigMap at reconcile, adds name sanitization/safe-derived naming, vendor additions for fake client/interceptor/rand, Operator SDK bumped.

Changes

Cohort / File(s) Summary
Operator SDK
Makefile
Bumped OPERATOR_SDK_VERSION from v1.39.1v1.42.0.
API types & deepcopy
api/v1alpha1/imagebuild_types.go, api/v1alpha1/zz_generated.deepcopy.go
Replaced manifestConfigMap with manifest + manifestFileName; added customDefs and aibExtraArgs; new accessors; deepcopy copies new slices.
API unit tests
api/v1alpha1/imagebuild_types_test.go
New tests for GetManifest, GetManifestFileName, GetCustomDefs, GetAIBExtraArgs covering edge cases.
CRD / CSV / sample
config/crd/bases/...imagebuilds.yaml, config/manifests/...clusterserviceversion.yaml, config/samples/automotive_v1_imagebuild.yaml
CRD/CSV/sample updated to inline aib.manifest + manifestFileName; removed manifestConfigMap; added customDefs and aibExtraArgs schema entries.
Build API server & tests
internal/buildapi/server.go, internal/buildapi/build_aib_spec_test.go, internal/buildapi/internal_registry_test.go
buildAIBSpec signature changed to accept manifest + manifestFileName; manifest size handling centralized via internal constant; removed APILimits.MaxManifestSize; tests adapted/added.
Controller & tests
internal/controller/imagebuild/controller.go, internal/controller/imagebuild/manifest_configmap_test.go, internal/controller/imagebuild/controller_test.go
Added safeDerivedName (truncate+hash) and createOrUpdateManifestConfigMap to materialize inline manifest (plus customDefs/aibExtraArgs); replaced GenerateName uses; tests for naming and ConfigMap behavior.
CLI sanitization & tests
cmd/caib/main.go, cmd/caib/main_test.go
Added sanitizeBuildName() and validation in runBuild/runDisk/runBuildDev flows; unit tests added (duplicate block present).
E2E test update
test/e2e/e2e_test.go
E2E uses inline manifest/manifestFileName; removed explicit manifest ConfigMap create/delete steps.
Build script tweak
internal/common/tasks/scripts/build_image.sh
Arg-file parsing: treat each file line as a single item (no per-word splitting).
Vendored rand util
vendor/k8s.io/apimachinery/pkg/util/rand/rand.go
Added thread-safe rand helpers and SafeEncodeString for deterministic encoding.
Vendored controller-runtime fake client
vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/...
Large vendored addition: configurable fake client builder with indexing, status/subresource, interceptors, in-memory behavior for tests.
Vendored interceptor & objectutil
vendor/sigs.k8s.io/controller-runtime/pkg/client/interceptor/intercept.go, vendor/sigs.k8s.io/controller-runtime/pkg/internal/objectutil/objectutil.go, vendor/modules.txt
Added client interception hooks (Funcs, NewClient), FilterWithLabels helper, and vendor modules updates.
Misc tests
internal/buildapi/build_aib_spec_test.go, internal/controller/imagebuild/manifest_configmap_test.go
New/updated tests exercising buildAIBSpec outputs and createOrUpdateManifestConfigMap behavior (content, keys, owner refs, idempotence).

Sequence Diagram

sequenceDiagram
    participant User as User/Client
    participant API as ImageBuild API
    participant Server as Build API Server
    participant Controller as ImageBuild Controller
    participant K8s as Kubernetes
    participant Pipeline as PipelineRun

    User->>API: Submit ImageBuild (spec.aib.manifest, manifestFileName, customDefs, aibExtraArgs)
    API->>Server: buildAIBSpec(req, manifest, manifestFileName)
    Server-->>API: AIBSpec {Manifest, ManifestFileName, CustomDefs, AIBExtraArgs}

    Controller->>Controller: Reconcile ImageBuild
    Controller->>K8s: createOrUpdateManifestConfigMap(imageBuild) (manifest file, customDefs, aibExtraArgs)
    K8s-->>Controller: ConfigMap created/updated
    Controller->>Pipeline: Create PipelineRun referencing manifest ConfigMap workspace
    Pipeline->>K8s: Run build pods/jobs using manifest file from ConfigMap
    K8s-->>Pipeline: Build job/pods execute (logs, results)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • bkhizgiy

Poem

🐰
I tuck the manifest safe in my chest,
no wandering ConfigMap to digest.
I trim the names and hop with cheer,
defs and args stay close and near.
Carrots for builds — go, engineer! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (21 files):

⚔️ Makefile (content)
⚔️ README.md (content)
⚔️ api/v1alpha1/imagebuild_types.go (content)
⚔️ api/v1alpha1/operatorconfig_types.go (content)
⚔️ api/v1alpha1/zz_generated.deepcopy.go (content)
⚔️ cmd/build-api/main.go (content)
⚔️ cmd/caib/main.go (content)
⚔️ cmd/caib/main_test.go (content)
⚔️ config/crd/bases/automotive.sdv.cloud.redhat.com_imagebuilds.yaml (content)
⚔️ config/crd/bases/automotive.sdv.cloud.redhat.com_operatorconfigs.yaml (content)
⚔️ config/manifests/bases/automotive-dev-operator.clusterserviceversion.yaml (content)
⚔️ config/samples/automotive_v1_imagebuild.yaml (content)
⚔️ internal/buildapi/internal_registry_test.go (content)
⚔️ internal/buildapi/server.go (content)
⚔️ internal/common/tasks/scripts/build_image.sh (content)
⚔️ internal/common/tasks/scripts/push_artifact.sh (content)
⚔️ internal/common/tasks/tasks.go (content)
⚔️ internal/controller/imagebuild/controller.go (content)
⚔️ internal/controller/imagebuild/controller_test.go (content)
⚔️ test/e2e/e2e_test.go (content)
⚔️ vendor/modules.txt (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'embed manifest in ImageBuild' clearly and concisely describes the main change: transitioning from ConfigMap-based manifest management to inline manifest embedding in the ImageBuild resource specification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/buildapi/server.go (1)

1672-1711: ⚠️ Potential issue | 🟡 Minor

getBuildTemplate discards CustomDefs and AIBExtraArgs from the stored build.

aibExtra (line 1678) is declared but never assigned, resulting in a nil AIBExtraArgs in the response. Similarly, CustomDefs is hardcoded to nil (line 1706). If the template endpoint is meant to produce a re-usable build request, both values should be populated from the stored spec.

Proposed fix
-	var aibExtra []string
-
 	var sourceFiles []string
 	for _, line := range strings.Split(manifest, "\n") {
 ...
 	writeJSON(c, http.StatusOK, BuildTemplateResponse{
 		BuildRequest: BuildRequest{
 			...
-			CustomDefs:             nil,
-			AIBExtraArgs:           aibExtra,
+			CustomDefs:             build.Spec.GetCustomDefs(),
+			AIBExtraArgs:           build.Spec.GetAIBExtraArgs(),
 			...
 		},
 		SourceFiles: sourceFiles,
 	})
🤖 Fix all issues with AI agents
In `@cmd/caib/main.go`:
- Around line 1327-1344: Move the sanitizeBuildName function so it does not
split sanitizeFilename's doc comment (place sanitizeBuildName above the
sanitizeFilename doc block or elsewhere outside that comment), and replace the
inline regexp.MustCompile(`-{2,}`) inside sanitizeBuildName with a package-level
precompiled variable (e.g., declare var multiHyphenRe =
regexp.MustCompile(`-{2,}`) near the other package vars/consts) and use
multiHyphenRe.ReplaceAllString(...) in sanitizeBuildName so the regex is
compiled once.

In `@internal/controller/imagebuild/controller.go`:
- Line 816: The derived resource name generation can exceed Kubernetes' 253-char
limit when appending suffixes (e.g. configMapName := fmt.Sprintf("%s-manifest",
imageBuild.Name)); instead add a helper to produce safe derived names that
truncates imageBuild.Name to (253 - len(suffix)) chars and appends a short hash
of the full name to preserve uniqueness, then use that helper for all derived
names (configMapName, upload pod, build-*, etc.); update callers that currently
rely on raw imageBuild.Name and keep validateBuildName as-is or tighten it
later, but ensure configMapName and other formatted names are produced via the
new helper so final lengths never exceed 253.
- Around line 809-857: createOrUpdateManifestConfigMap writes the inline
manifest (imageBuild.Spec.GetManifest()) into a ConfigMap (named configMapName)
but Kubernetes/etcd enforces ~1MB object limits while the API MaxManifestSize
allows up to 10MB, so large manifests will cause opaque apiserver/etcd failures;
fix by detecting manifest size in createOrUpdateManifestConfigMap (or earlier
during validation) and if it exceeds a configurable CONFIGMAP_MAX_BYTES
threshold (≤ etcd limit) either 1) reject the request / lower the API
MaxManifestSize to that threshold, or 2) fall back to a different backing store
(e.g., persist to the existing PVC-based approach or another storage backend)
and update the ImageBuild to reference that storage instead; implement the check
against imageBuild.Spec.GetManifest() and branch to the alternate storage path
(or return a clear validation error) so ConfigMap creation of configMapName
never exceeds the etcd size limit.
🧹 Nitpick comments (5)
cmd/caib/main_test.go (1)

228-258: Consider adding an empty-string edge case.

Good coverage of the sanitization rules. One missing scenario: sanitizeBuildName("") returns "", which would produce a build name like "-20260215-120000" (leading hyphen — invalid RFC 1123). While callers currently derive the input from filepath.Base() (never empty for valid paths), an explicit test documents the boundary behavior.

Suggested addition
 		{"already-valid-name", "already-valid-name"},
 		{"under_score.and.dots", "under-score-and-dots"},
+		{"", ""},
+		{"---", ""},
 	}
api/v1alpha1/imagebuild_types_test.go (1)

154-202: Consider adding an empty-slice test case for GetAIBExtraArgs.

TestGetCustomDefs includes a "returns empty slice when custom defs is empty" case, but TestGetAIBExtraArgs doesn't have an analogous case. Adding one would keep parity and ensure the accessor correctly returns []string{} vs nil.

Proposed additional test case
 		{
 			name: "returns nil when extra args is nil",
 			spec: ImageBuildSpec{
 				AIB: &AIBSpec{},
 			},
 			want: nil,
 		},
+		{
+			name: "returns empty slice when extra args is empty",
+			spec: ImageBuildSpec{
+				AIB: &AIBSpec{
+					AIBExtraArgs: []string{},
+				},
+			},
+			want: []string{},
+		},
 	}
internal/buildapi/build_aib_spec_test.go (1)

131-155: Nil/empty CustomDefs and AIBExtraArgs are not verified in the "basic" and "empty manifest filename" cases.

When wantCustomDefs is nil (zero value), the len(tt.wantCustomDefs) > 0 guard skips verification entirely. If buildAIBSpec incorrectly populates these fields, the test won't catch it.

Proposed fix: verify nil/empty cases too
-		// Check custom defs
-		if len(tt.wantCustomDefs) > 0 {
+		// Check custom defs
+		if len(tt.wantCustomDefs) > 0 {
 			if len(got.CustomDefs) != len(tt.wantCustomDefs) {
 				t.Errorf("CustomDefs length = %d, want %d", len(got.CustomDefs), len(tt.wantCustomDefs))
 			} else {
 				for i := range got.CustomDefs {
 					if got.CustomDefs[i] != tt.wantCustomDefs[i] {
 						t.Errorf("CustomDefs[%d] = %q, want %q", i, got.CustomDefs[i], tt.wantCustomDefs[i])
 					}
 				}
 			}
+		} else if len(got.CustomDefs) != 0 {
+			t.Errorf("CustomDefs should be empty, got %v", got.CustomDefs)
 		}

-		// Check extra args
-		if len(tt.wantExtraArgs) > 0 {
+		// Check extra args
+		if len(tt.wantExtraArgs) > 0 {
 			if len(got.AIBExtraArgs) != len(tt.wantExtraArgs) {
 				t.Errorf("AIBExtraArgs length = %d, want %d", len(got.AIBExtraArgs), len(tt.wantExtraArgs))
 			} else {
 				for i := range got.AIBExtraArgs {
 					if got.AIBExtraArgs[i] != tt.wantExtraArgs[i] {
 						t.Errorf("AIBExtraArgs[%d] = %q, want %q", i, got.AIBExtraArgs[i], tt.wantExtraArgs[i])
 					}
 				}
 			}
+		} else if len(got.AIBExtraArgs) != 0 {
+			t.Errorf("AIBExtraArgs should be empty, got %v", got.AIBExtraArgs)
 		}
config/crd/bases/automotive.sdv.cloud.redhat.com_imagebuilds.yaml (1)

80-87: Consider adding maxLength validation on the manifest field in the CRD.

The build API enforces MaxManifestSize at the HTTP layer, but direct kubectl apply bypasses that check. A CRD-level maxLength (aligned with the ConfigMap 1 MB limit mentioned earlier) would provide defense-in-depth against oversized manifests submitted through kubectl.

api/v1alpha1/imagebuild_types.go (1)

86-91: Unnecessary yaml struct tags on Kubernetes API types.

Standard Kubernetes API types use only json tags; the API machinery serializes exclusively via JSON. The yaml:"..." tags on Manifest and ManifestFileName are inert and may confuse future readers into thinking a YAML codec is in play.

Comment thread internal/controller/imagebuild/controller.go
Comment thread internal/controller/imagebuild/controller.go Outdated
@bennyz bennyz requested a review from bkhizgiy February 15, 2026 16:47
Comment thread cmd/caib/main.go
name = strings.ToLower(name)
var b strings.Builder
for _, r := range name {
if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '-' {

@bkhizgiy bkhizgiy Feb 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The names are also limited to 63 chars max (which is a lot for a manifest), but since you cover everything already I would add this check as well,
including any suffixes that added later.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@cmd/caib/main.go`:
- Around line 1327-1344: sanitizeBuildName can return an empty string for inputs
made only of invalid characters; update sanitizeBuildName (and leave
multiHyphenRe usage) so that after trimming if result == "" it returns a safe
fallback token (e.g., "unnamed" or "default") to avoid producing names that
begin with a hyphen when later concatenated with timestamps—modify the function
to set and return that fallback when the sanitized result is empty.

In `@internal/controller/imagebuild/controller.go`:
- Around line 858-867: Replace the space-delimited join for AIB extra args with
newline-delimited output and update the consumer to read one argument per line:
in the image build controller where you set cm.Data["aib-extra-args.txt"] (using
imageBuild.Spec.GetAIBExtraArgs()), change strings.Join(extraArgs, " ") to
strings.Join(extraArgs, "\n"); then modify the shell script that parses
aib-extra-args.txt (the loop that currently does `for item in $line`) to instead
read each line as a single argument (one-arg-per-line parsing), and update any
unit/integration tests that assert on aib-extra-args.txt or build_image.sh
behavior to expect newline-separated args.
🧹 Nitpick comments (1)
internal/controller/imagebuild/controller_test.go (1)

192-281: Good test coverage for safeDerivedName.

The tests cover the important properties: length constraint, suffix preservation, determinism, and hash-based uniqueness.

Minor note: the "exact length boundary" test (line 208) has a baseName of ~52 chars which exceeds maxBaseLength (45 for -manifest suffix), so it actually tests truncation rather than an exact boundary. Consider adding a test case where len(baseName) == maxBaseLength (i.e., 45 chars) to verify the no-truncation/truncation boundary precisely.

Comment thread cmd/caib/main.go
Comment thread internal/controller/imagebuild/controller.go
@bennyz bennyz force-pushed the embed-manifest-imagebuild branch from 10e872c to 2276390 Compare February 15, 2026 19:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/caib/main.go (1)

1042-1049: ⚠️ Potential issue | 🟠 Major

Missing validation of user-provided buildName in runDisk.

runBuild (lines 938-943) and runBuildDev (lines 1453-1458) validate that a user-supplied --name isn't entirely invalid characters, but runDisk skips this check. A user can pass --name "!!!" which will be sent to the API as-is.

Proposed fix
 	if buildName == "" {
 		parts := strings.Split(containerRef, "/")
 		imagePart := parts[len(parts)-1]
 		imagePart = strings.Split(imagePart, ":")[0] // remove tag
 		buildName = fmt.Sprintf("disk-%s-%s", sanitizeBuildName(imagePart), time.Now().Format("20060102-150405"))
 		fmt.Printf("Auto-generated build name: %s\n", buildName)
+	} else {
+		if sanitizeBuildName(buildName) == "" {
+			fmt.Printf("Error: build name '%s' contains only invalid characters\n", buildName)
+			fmt.Println("Build names must contain at least one letter or number")
+			os.Exit(1)
+		}
 	}
🧹 Nitpick comments (2)
internal/controller/imagebuild/controller_test.go (1)

192-281: Good test coverage for safeDerivedName.

Tests thoroughly cover length constraints, suffix preservation, determinism, and hash-based uniqueness for different long inputs. One minor note: the "exact length boundary" test case (baseName is ~52 chars) actually triggers truncation since maxBaseLength = 63 - 9 - 9 = 45. The test still passes because the assertions only check len <= 63 and suffix presence, but the name is slightly misleading. Consider renaming it or adjusting the base name to 45 chars to truly test the boundary.

internal/controller/imagebuild/controller.go (1)

46-60: safeDerivedName is well-designed but has a latent panic if suffix is ≥ 55 chars.

If len(suffix) >= 55, then maxBaseLength becomes ≤ 0. When len(baseName) > maxBaseLength (which is always true for any non-empty base), baseName[:maxBaseLength] will panic with a negative or zero slice index on a non-empty string, or produce an empty truncation.

All current callers use short suffixes (max 11 chars for "-upload-pod"), so this isn't exploitable today, but a guard clause would make this future-proof.

🛡️ Proposed defensive guard
 func safeDerivedName(baseName, suffix string) string {
 	maxBaseLength := maxK8sNameLength - len(suffix) - 9
+	if maxBaseLength < 1 {
+		// Suffix is too long; fall back to hash-only base
+		hash := sha256.Sum256([]byte(baseName))
+		return fmt.Sprintf("%x%s", hash[:4], suffix)
+	}
 
 	if len(baseName) <= maxBaseLength {
 		return fmt.Sprintf("%s%s", baseName, suffix)
 	}

@bennyz bennyz force-pushed the embed-manifest-imagebuild branch from 2276390 to 8b4fbbe Compare February 15, 2026 19:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/buildapi/server.go`:
- Around line 1340-1353: Validate the manifestFileName in validateBuildRequest
using k8s.io/apimachinery/pkg/util/validation.IsConfigMapKey to ensure it
contains only characters safe for ConfigMap data keys; call
IsConfigMapKey(req.ManifestFileName) (or the field passed into buildAIBSpec) and
if it returns any errors, return a validation error from validateBuildRequest
(with a clear message mentioning manifestFileName) so the request is rejected
before buildAIBSpec/ConfigMap creation proceeds.

Comment thread internal/buildapi/server.go
@bennyz bennyz force-pushed the embed-manifest-imagebuild branch from 8b4fbbe to c2f51e6 Compare February 15, 2026 20:02

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/buildapi/server.go (1)

1722-1738: ⚠️ Potential issue | 🟡 Minor

getBuildTemplate omits CustomDefs and AIBExtraArgs from the response.

This PR adds CustomDefs and AIBExtraArgs to BuildRequest/AIBSpec, but the template response hardcodes CustomDefs: nil (line 1733) and uses an always-empty aibExtra slice (line 1734). A "rebuild from template" flow would silently lose these fields.

Suggested fix
 	writeJSON(c, http.StatusOK, BuildTemplateResponse{
 		BuildRequest: BuildRequest{
 			Name:                   build.Name,
 			Manifest:               manifest,
 			ManifestFileName:       manifestFileName,
 			Distro:                 Distro(build.Spec.GetDistro()),
 			Target:                 Target(build.Spec.GetTarget()),
 			Architecture:           Architecture(build.Spec.Architecture),
 			ExportFormat:           ExportFormat(build.Spec.GetExportFormat()),
 			Mode:                   Mode(build.Spec.GetMode()),
 			AutomotiveImageBuilder: build.Spec.GetAIBImage(),
-			CustomDefs:             nil,
-			AIBExtraArgs:           aibExtra,
+			CustomDefs:             build.Spec.GetCustomDefs(),
+			AIBExtraArgs:           build.Spec.GetAIBExtraArgs(),
 			Compression:            build.Spec.GetCompression(),
 		},
 		SourceFiles: sourceFiles,
 	})

@bennyz bennyz force-pushed the embed-manifest-imagebuild branch from c2f51e6 to c2f6e53 Compare February 15, 2026 20:15
@coderabbitai

coderabbitai Bot commented Feb 16, 2026

Copy link
Copy Markdown
✅ Actions performed

Reviews resumed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/controller/imagebuild/controller.go`:
- Around line 851-853: The ConfigMap creation is hardcoding the key
"manifest.aib.yml" into cm.Data instead of using the configured
ManifestFileName; change the assignment so cm.Data uses the ManifestFileName
value as the key (e.g. cm.Data = map[string]string{
imgbuild.Spec.ManifestFileName: manifestContent } or the appropriate struct
field/name where ManifestFileName is stored) so the mounted file name matches
the configured ManifestFileName, and update the assertions in
manifest_configmap_test.go to expect the ConfigMap key to equal ManifestFileName
rather than the hardcoded string.
🧹 Nitpick comments (1)
internal/controller/imagebuild/controller.go (1)

46-60: safeDerivedName could panic if suffix length exceeds 54 characters.

If len(suffix) > 54, then maxBaseLength becomes negative, and baseName[:maxBaseLength] will panic with a slice-bounds-out-of-range error. Current callers are all safe (longest suffix is "-upload-pod" at 11 chars), but a defensive guard would prevent future surprises.

Suggested guard
 func safeDerivedName(baseName, suffix string) string {
 	maxBaseLength := maxK8sNameLength - len(suffix) - 9
+	if maxBaseLength < 1 {
+		// suffix too long; fall back to hash-only base
+		hash := sha256.Sum256([]byte(baseName))
+		return fmt.Sprintf("%x%s", hash[:4], suffix)
+	}
 
 	if len(baseName) <= maxBaseLength {

Comment thread internal/controller/imagebuild/controller.go
@bennyz bennyz force-pushed the embed-manifest-imagebuild branch from c2f6e53 to d01f4a5 Compare February 16, 2026 10:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/controller/imagebuild/controller.go`:
- Around line 46-60: The safeDerivedName function can compute a negative
maxBaseLength and then panic when slicing baseName; fix it by adding a defensive
guard in safeDerivedName (which uses maxK8sNameLength, suffix, and the 9-char
hash overhead): if maxBaseLength <= 0, skip truncating baseName and instead
build a name using only the hash and suffix (or a truncated hash+suf) that still
respects maxK8sNameLength; otherwise proceed with the existing truncation logic.
Ensure the final returned string is never longer than maxK8sNameLength.
🧹 Nitpick comments (1)
internal/buildapi/server.go (1)

1083-1098: Minor redundancy in double-dash collapsing.

The initial strings.ReplaceAll on line 1093 is redundant — the for loop on lines 1094–1096 already handles the same replacement iteratively.

Simplified version
-	result := strings.ReplaceAll(b.String(), "--", "-")
-	for strings.Contains(result, "--") {
+	result := b.String()
+	for strings.Contains(result, "--") {
 		result = strings.ReplaceAll(result, "--", "-")
 	}

@bennyz bennyz force-pushed the embed-manifest-imagebuild branch from d01f4a5 to 66584a6 Compare February 16, 2026 10:53
Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
to comply with RFC 1123

fixes centos-automotive-suite#103

Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@internal/buildapi/server.go`:
- Around line 1069-1098: The code validates build names but does not sanitize
req.Name before storing it in the ImageBuild CR, so metadata.Name and later
safeDerivedName receive unsanitized values that can violate Kubernetes DNS label
rules; update validateBuildName to either replace req.Name with a sanitized
value or enforce DNS label rules in validateInput and then use the sanitized
result when setting ImageBuild.Metadata.Name and when calling safeDerivedName.
Specifically, reuse sanitizeBuildNameForValidation (or implement equivalent
DNS-label sanitization) to produce a lowercase alphanumeric-and-hyphen name that
starts/ends with an alphanumeric character, ensure validateBuildName returns or
applies that sanitized name, and assign that sanitized name to the ImageBuild
name field (instead of raw req.Name) before any further processing.

In `@internal/controller/imagebuild/controller.go`:
- Around line 46-69: The fallback branch in safeDerivedName may produce a name
starting with a hyphen because hashStr is "-<hex>", which violates Kubernetes
DNS label rules when maxBaseLength <= 0; modify that branch to strip the leading
hyphen from the hash (or generate the 8-char hex without a hyphen) and construct
name = hexPart + suffix, and if that still does not begin with an alphanumeric
character ensure you prefix a safe character (e.g., 'a') before truncating to
maxK8sNameLength; keep references to safeDerivedName, maxK8sNameLength, and
hashStr when making the change.
🧹 Nitpick comments (2)
cmd/caib/main.go (1)

933-943: Duplicated build-name validation logic across three commands.

The same validation block (check sanitizeBuildName(buildName) == "", print error, os.Exit(1)) is copy-pasted in runBuild, runDisk, and runBuildDev. Consider extracting a helper to reduce duplication and ensure consistent behavior if the logic evolves.

Suggested helper
// validateBuildName checks a user-provided build name and exits if it
// contains only invalid characters.
func validateBuildName(name string) {
	if sanitizeBuildName(name) == "" {
		fmt.Printf("Error: build name '%s' contains only invalid characters\n", name)
		fmt.Println("Build names must contain at least one letter or number")
		os.Exit(1)
	}
}

Then each command simplifies to:

 	} else {
-		if sanitizeBuildName(buildName) == "" {
-			fmt.Printf("Error: build name '%s' contains only invalid characters\n", buildName)
-			fmt.Println("Build names must contain at least one letter or number")
-			os.Exit(1)
-		}
+		validateBuildName(buildName)
 	}

Also applies to: 1043-1054, 1453-1464

internal/controller/imagebuild/manifest_configmap_test.go (1)

24-227: Well-structured table-driven tests with good coverage.

The tests cover the key scenarios (manifest content, default filename, custom defs, extra args, labels, owner references). Consider adding a test case where AIB is nil to validate the error path (wantErr: true), since the controller would presumably fail in that scenario.

Comment thread internal/buildapi/server.go
Comment thread internal/controller/imagebuild/controller.go
Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
@bennyz bennyz force-pushed the embed-manifest-imagebuild branch from 66584a6 to 5c2b041 Compare February 16, 2026 11:10
@bennyz bennyz merged commit 66be237 into centos-automotive-suite:main Feb 16, 2026
4 checks passed
@bennyz bennyz deleted the embed-manifest-imagebuild branch February 16, 2026 11:15
@bennyz bennyz restored the embed-manifest-imagebuild branch February 16, 2026 11:55
@coderabbitai coderabbitai Bot mentioned this pull request Mar 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants