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

feat: self-contained container image build #514

Merged
merged 2 commits into from
Feb 12, 2025

Conversation

COLDTURNIP
Copy link
Contributor

@COLDTURNIP COLDTURNIP commented Feb 3, 2025

Which issue(s) this PR fixes:

Supports security build.

What this PR does / why we need it:

  • Merge binary building process into container build as a separate building stage.
  • Prepare for potential secure release

Special notes for your reviewer:

The secrets provided by EIO MUST NOT present in any visible output.

Additional documentation or context

Guidance on achieving SLSA Level 3

@COLDTURNIP COLDTURNIP self-assigned this Feb 3, 2025
Copy link

coderabbitai bot commented Feb 3, 2025

Walkthrough

The changes update the CI/CD workflow, build automation, Dockerfile, and packaging script. The GitHub Actions workflow now extracts and exports versioning details, removes legacy binary steps, and adds a secure image build job based on tag conditions. The Makefile introduces new variables and targets for Docker Buildx setup and image publishing workflows. The Dockerfile is refactored with a multi-stage build that compiles the application in a builder stage and then prepares the final image. The packaging script now has clearer variable naming and logic to select the build command and assign image tags.

Changes

File(s) Change Summary
.github/workflows/build.yml - Adds output variables (version_major, version_minor, version_patch, image_tag) in the build job.
- Introduces a "Declare build info" step to derive versioning details.
- Removes "Upload binaries" step; modifies "Build and push image" to "Build and publish image".
Makefile - Defines new variables MACHINE and DEFAULT_PLATFORMS.
- Adds the buildx-machine target to set up a Docker Buildx instance.
- Introduces workflow-image-build-push and workflow-image-build-push-secure targets that call the package script with environment variables, with the secure target setting IS_SECURE to true.
package/Dockerfile - Introduces a multi-stage build with a new builder stage using registry.suse.com/bci/golang:1.23.
- Copies the entire context and runs a build script in the builder stage.
- Updates the final image stage to use registry.suse.com/bci/bci-base:15.6, copying the compiled binary from the builder and setting executable permissions.
scripts/package - Changes the variable PROJECT syntax from backticks to $().
- Removes the conditional check and command for ./bin/longhorn.
- Implements logic to determine the build command based on buildx availability.
- Adds new configurable parameters and modifies the logic to set the TAG based on the current date if empty.

Sequence Diagram(s)

sequenceDiagram
    participant Trigger as GitHub Trigger
    participant Build as Build Job
    participant Secure as Secure Image Job

    Trigger->>Build: Initiate build event
    Build->>Build: Execute "Declare build info" to set version outputs
    Build->>Build: Run "Build and publish image" step
    alt Tag condition met
        Build->>Secure: Conditionally trigger secure image build
        Secure->>Secure: Checkout code, read secrets, build & push secure image
    end
Loading
sequenceDiagram
    participant Builder as Builder Stage
    participant Final as Final Stage

    Builder->>Builder: Copy code and run build script
    Builder-->>Final: Provide compiled binary
    Final->>Final: Copy binary and set executable permissions
Loading

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
Makefile (1)

19-21: Enhance buildx machine setup resilience.

The buildx machine setup should handle the case where the machine exists but is unhealthy.

-	docker buildx ls | grep $(MACHINE) >/dev/null || \
-		docker buildx create --name=$(MACHINE) --platform=$(DEFAULT_PLATFORMS)
+	@if ! docker buildx inspect $(MACHINE) >/dev/null 2>&1; then \
+		echo "Creating buildx instance $(MACHINE)..."; \
+		docker buildx create --name=$(MACHINE) --platform=$(DEFAULT_PLATFORMS); \
+	elif ! docker buildx inspect $(MACHINE) | grep -q "Status: running"; then \
+		echo "Removing unhealthy buildx instance $(MACHINE)..."; \
+		docker buildx rm $(MACHINE); \
+		echo "Creating new buildx instance $(MACHINE)..."; \
+		docker buildx create --name=$(MACHINE) --platform=$(DEFAULT_PLATFORMS); \
+	fi
package/Dockerfile (1)

35-36: Consider using COPY with mode instead of separate chmod.

The separate chmod command can be combined with COPY for better efficiency.

-COPY --from=builder /app/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager
-RUN chmod +x /usr/local/bin/backing-image-manager
+COPY --from=builder --chmod=755 /app/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a73ea9 and fbe3324.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/build.yml

[error] 42-42: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)


[warning] 92-92: wrong indentation: expected 4 but found 6

(indentation)

🪛 actionlint (1.7.4)
.github/workflows/build.yml

90-90: got unexpected character '"' while lexing expression, expecting 'a'..'z', 'A'..'Z', '_', '0'..'9', ''', '}', '(', ')', '[', ']', '.', '!', '<', '>', '=', '&', '|', '*', ',', ' '. do you mean string literals? only single quotes are available for string delimiter

(expression)

🪛 GitHub Check: CodeFactor
scripts/package

[notice] 15-15: scripts/package#L15
This variable is assigned to itself, so the assignment does nothing. (SC2269)


[notice] 18-18: scripts/package#L18
This variable is assigned to itself, so the assignment does nothing. (SC2269)


[notice] 19-19: scripts/package#L19
This variable is assigned to itself, so the assignment does nothing. (SC2269)


[notice] 20-20: scripts/package#L20
This variable is assigned to itself, so the assignment does nothing. (SC2269)


[notice] 21-21: scripts/package#L21
This variable is assigned to itself, so the assignment does nothing. (SC2269)


[notice] 17-17: scripts/package#L17
This variable is assigned to itself, so the assignment does nothing. (SC2269)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Summary
🔇 Additional comments (6)
scripts/package (2)

37-38: LGTM! Secure build configuration.

The secure build configuration correctly adds SBOM generation and provenance attestation for enhanced supply chain security.


10-10: Verify buildx availability and handle errors.

The command check for buildx should handle the case where neither buildx nor docker buildx is available.

✅ Verification successful

Verified buildx availability check.

  • The command chain correctly attempts to locate standalone buildx or docker buildx.
  • In the test, neither command is available, causing the script to echo "buildx not found" as intended.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if buildx is available either as standalone or docker plugin
command -v buildx >/dev/null || command -v docker >/dev/null && docker buildx version >/dev/null 2>&1 || echo "buildx not found"

Length of output: 82

Makefile (2)

29-32: LGTM! Well-structured build targets.

The build targets are well-organized with clear separation between secure and non-secure builds.


2-6: Verify platform compatibility.

The DEFAULT_PLATFORMS includes darwin targets which may not be supported by all components. Verify compatibility.

✅ Verification successful

Darwin Support in Vendor Code Confirmed

The search revealed a reference in vendor/golang.org/x/sys/unix/syscall_bsd.go indicating that the vendor library includes code for darwin targets. This confirms that darwin is explicitly supported in a critical dependency, so the DEFAULT_PLATFORMS including darwin variants is in line with the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if darwin platforms are supported in the codebase
rg -l 'GOOS.*darwin|darwin.*GOOS' || echo "No explicit darwin support found"

Length of output: 79

package/Dockerfile (1)

2-13: LGTM! Secure multi-stage build implementation.

The multi-stage build correctly isolates build dependencies from the final image, reducing attack surface.

.github/workflows/build.yml (1)

95-102: LGTM! Secure secrets handling.

The vault secrets are correctly accessed and stored in environment variables, not exposed in logs.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
.github/workflows/build.yml (1)

24-54: ⚠️ Potential issue

Fix version extraction syntax and style issues.

The version extraction has syntax errors and style issues.

Apply these fixes:

-          version=$(sed -E 's/^v([0-9.]*)$/\1') <<<$ref )
+          version=$(echo "$ref" | sed -E 's/^refs\/tags\/v([0-9.]+)$/\1/')
           version_major=$(cut -d. -f1 <<<$version)
           version_minor=$(cut -d. -f2 <<<$version)
           version_build=$(cut -d. -f3 <<<$version)
           image_tag="$version"
-        elif [[ "$ref" =~ 'refs/heads/' ]]; then
+        elif [[ "$ref" =~ 'refs/heads/' ]]; then
           image_tag=${{ env.branch }}-head
-        fi
+        fi

-        
+
         echo "version_major=${version_major}" >>$GITHUB_OUTPUT
         echo "version_minor=${version_minor}" >>$GITHUB_OUTPUT
         echo "version_build=${version_build}" >>$GITHUB_OUTPUT
         echo "image_tag=${image_tag}" >>$GITHUB_OUTPUT
-        
+
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 42-42: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)

🧹 Nitpick comments (2)
scripts/package (1)

43-52: Consider conditional cache usage for faster builds.

While using --no-cache ensures clean builds, it might increase build times unnecessarily in CI/CD pipelines.

Consider making cache usage configurable:

+USE_CACHE=${USE_CACHE:-'false'}
+cache_args=()
+[[ $USE_CACHE != 'true' ]] && cache_args+=('--no-cache')
+
-echo "${build_cmd[@]}" build --no-cache \
+echo "${build_cmd[@]}" build "${cache_args[@]}" \
     "${builder_args[@]}" \
     "${iid_file_args[@]}" \
     "${buildx_args[@]}" \
     -t "$image" -f package/Dockerfile .
-"${build_cmd[@]}" build --no-cache \
+"${build_cmd[@]}" build "${cache_args[@]}" \
     "${builder_args[@]}" \
     "${iid_file_args[@]}" \
     "${buildx_args[@]}" \
     -t "$image" -f package/Dockerfile .
package/Dockerfile (1)

2-13: Consider optimizing build context.

While the current setup works, copying the entire context might include unnecessary files.

Consider using a .dockerignore file to exclude unnecessary files from the build context:

+# Add .dockerignore file with:
+.git/
+.github/
+.gitignore
+*.md
+coverage.out
+bin/
+dist/
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbe3324 and fcc3050.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Makefile
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/build.yml

[error] 42-42: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)


[warning] 92-92: wrong indentation: expected 4 but found 6

(indentation)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Summary
🔇 Additional comments (10)
scripts/package (5)

8-21: LGTM! Well-structured variable declarations.

The script follows shell scripting best practices with lowercase variable names and robust command detection.


23-29: Enhance version extraction error handling.

While basic error handling exists, the version extraction could be more robust.

Apply this diff to improve error handling:

 if [[ -z $TAG ]]; then
-    if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+    if ! ./bin/backing-image-manager version --client-only >/dev/null 2>&1; then
+        echo "Error: Failed to get version information" >&2
+        TAG="unknown_$(date -u +%Y%m%d)"
+    elif ! api_version=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version" >&2
+        TAG="unknown_$(date -u +%Y%m%d)"
+    else
       TAG="v${api_version}_$(date -u +%Y%m%d)"
-    else
-      TAG="unknown_$(date -u +%Y%m%d)"
     fi
 fi

31-31: LGTM! Clear image name construction.

The image name is constructed correctly using the provided variables.


54-56: LGTM! Clear output handling.

The image tag is properly saved and output messages are clear.


33-41: LGTM! Secure build features are well implemented.

The secure build features (SBOM and provenance) are correctly added when IS_SECURE is true. The array handling for build arguments is robust.

Run this script to verify the secure build features:

✅ Verification successful

Secure Build Features Verified

The secure build features (SBOM and attest with provenance mode) are added correctly when IS_SECURE is true, as confirmed by the search output. No issues were found with their implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify secure build features in the codebase
# Test: Search for secure build feature usage
rg -A 5 'sbom|provenance|attest' .

Length of output: 414

package/Dockerfile (3)

15-24: LGTM! Clear platform validation.

The platform validation ensures the image is built only for supported architectures with clear error messages.


35-36: LGTM! Secure binary setup.

The binary is securely copied from the builder stage and properly configured with executable permissions.


25-33: LGTM! Comprehensive package setup.

The repository setup and package installation are well-structured.

Run this script to check for any known vulnerabilities in the installed packages:

✅ Verification successful

Approval: Comprehensive Package Setup Verified

The package installation and repository setup have been confirmed. Our preliminary security check script listed the installed packages (with some extraneous tokens from the extraction method), and no known vulnerabilities were immediately apparent for the intended packages. A manual review of the extracted package list (focusing on the actual packages installed such as fuse, libaio-devel, libibverbs, librdmacm1, librdmacm-utils, perl-Config-General, sg3_utils, qemu-tools, etc.) is still advised to be thorough.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for vulnerabilities in installed packages
# Test: Extract package versions and check against known vulnerabilities
rg -A 1 'zypper.*install' . | grep -v 'zypper' | tr -s ' ' '\n' | sort -u > packages.txt
echo "Please check these packages for known vulnerabilities:"
cat packages.txt

Length of output: 530

.github/workflows/build.yml (2)

14-18: LGTM! Clear output structure.

The output variables are well-defined and follow a logical structure.


86-114: LGTM! Secure image build implementation.

The secure image build job correctly implements the security requirements with proper secret handling.

Run this script to verify the secure build configuration:

✅ Verification successful

Secure build configuration verified.

  • The workflow uses the workflow-image-build-push-secure target as intended.
  • The grep output confirms that both secure build settings (via IS_SECURE=true) and secret references (e.g., PRIME_REGISTRY and prime-password) are present in the Makefile.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify secure build configuration
# Test: Check for secure build features and secret usage
rg -A 5 'workflow-image-build-push-secure|PRIME_REGISTRY|prime-password' .

Length of output: 514

🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 92-92: wrong indentation: expected 4 but found 6

(indentation)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
.github/workflows/build.yml (2)

42-47: Nitpick: Remove Trailing Spaces

Static analysis has detected trailing spaces on these lines (42 and 47). Removing these will align the file with YAML best practices and avoid linting errors.

A suggested diff:

(Ensure no extraneous whitespace after the indentation.)

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 42-42: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)


86-114: Review of Secure Image Build and Push Job

The secure image build job correctly conditions its execution on the tag reference and a non-zero version_build. The steps correctly obtain secrets and build the image using those secrets.

Please note a formatting issue identified by the static analysis:

  • Indentation Issue: On line 92 the Checkout code step is indented with 6 spaces, whereas the linter expects 4 spaces. This inconsistency may trigger warnings. Consider aligning the step with the community image job's indentation. For example:

This adjustment will help conform to YAML indentation expectations.

🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 92-92: wrong indentation: expected 4 but found 6

(indentation)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fcc3050 and 0bae999.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • Makefile
  • scripts/package
  • package/Dockerfile
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/build.yml

[error] 42-42: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)


[warning] 92-92: wrong indentation: expected 4 but found 6

(indentation)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (5)
.github/workflows/build.yml (5)

14-19: Review of Build Job Outputs Declaration

The new outputs are declared correctly and reference the values from the build_info step. Verify that all downstream jobs are updated to use these outputs.


24-31: Review of Build Info Declaration Step

The build_info step initializes the required variables before they’re populated. The default empty-string initializations are acceptable, though you may want to add comments if future maintainers might question why defaults are set.


48-54: Review of Version Info Echo Block

The block echoing the version info to $GITHUB_OUTPUT and printing it via a heredoc is clear. Just ensure that this version information is not sensitive. Otherwise, the implementation is straightforward.


66-84: Review of Community Image Build and Push Step

The configuration for building and publishing the community image is consistent with the new outputs and appears correct. All the required inputs, such as image details and credentials, are properly referenced.


32-41: ⚠️ Potential issue

Critical Issue: Version Extraction Logic

The version extraction in line 34 uses a regex (s/^v([0-9.]*)$/\1) that expects the version string to start with v. However, the Git reference (github.ref) typically contains the full string (e.g., refs/tags/v1.2.3), so this regex will not match correctly. Please update the command to extract the version correctly. For example:

-          version=$(sed -E 's/^v([0-9.]*)$/\1' <<<$ref )
+          version=$(echo "$ref" | sed -E 's/^refs\/tags\/v([0-9.]+)$/\1/')

This change ensures the prefix is properly stripped.

Likely invalid or redundant comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
scripts/package (1)

23-29: 🛠️ Refactor suggestion

Improve version extraction error handling.

The version extraction logic could be more robust by adding proper error messages and validation.

Apply this diff to improve error handling:

 if [[ -z $TAG ]]; then
-    if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+    if ! api_version=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version" >&2
         TAG="unknown_$(date -u +%Y%m%d)"
+    else
+        TAG="v${api_version}_$(date -u +%Y%m%d)"
     fi
-      TAG="v${api_version}_$(date -u +%Y%m%d)"
-    else
-      TAG="unknown_$(date -u +%Y%m%d)"
-    fi
 fi
.github/workflows/build.yml (1)

32-41: ⚠️ Potential issue

Fix version extraction syntax and add validation.

The version extraction has syntax issues and lacks proper validation.

Apply this diff to fix the syntax and add validation:

-        ref=${{ github.ref }}
+        ref="${{ github.ref }}"
         if [[ "$ref" =~ 'refs/tags/' ]]; then
-          version=$(sed -E 's/^v([0-9.]*)$/\1' <<<$ref )
+          version=$(echo "$ref" | sed -E 's/^refs\/tags\/v([0-9.]+)$/\1/')
+          if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+            echo "Error: Invalid version format: $version" >&2
+            exit 1
+          fi
           version_major=$(cut -d. -f1 <<<$version)
           version_minor=$(cut -d. -f2 <<<$version)
           version_build=$(cut -d. -f3 <<<$version)
           image_tag="$version"
-        elif [[ "$ref" =~ 'refs/heads/' ]]
+        elif [[ "$ref" =~ 'refs/heads/' ]]; then
           image_tag=${{ env.branch }}-head
         fi
🧹 Nitpick comments (3)
scripts/package (1)

39-41: Enhance security attestation flags.

The secure build flags are correctly implemented but could benefit from additional security attestations.

Consider adding --provenance=true flag for enhanced supply chain security:

 IFS=' ' read -r -a buildx_args <<<"$OUTPUT_ARGS"
-[[ $IS_SECURE == 'true' ]] && buildx_args+=('--sbom=true' '--attest' 'type=provenance,mode=max')
+[[ $IS_SECURE == 'true' ]] && buildx_args+=('--sbom=true' '--provenance=true' '--attest' 'type=provenance,mode=max')
 [[ $TARGET_PLATFORMS ]] && buildx_args+=('--platform' "$TARGET_PLATFORMS")
package/Dockerfile (1)

35-36: Consider using more restrictive permissions.

The executable permissions are correctly set, but consider using more specific permissions for better security.

Apply this diff to set more restrictive permissions:

 COPY --from=builder /app/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager
-RUN chmod +x /usr/local/bin/backing-image-manager
+RUN chmod 755 /usr/local/bin/backing-image-manager
.github/workflows/build.yml (1)

42-42: Remove trailing whitespace.

There are trailing spaces on these lines.

Apply this diff to remove trailing whitespace:

-        
+

Also applies to: 47-47

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 42-42: trailing spaces

(trailing-spaces)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0bae999 and 5dd142e.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Makefile
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/build.yml

[error] 42-42: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (1)
package/Dockerfile (1)

2-13: ⚠️ Potential issue

Verify Go version compatibility.

The Dockerfile uses golang:1.23 which seems incorrect as Go 1.23 hasn't been released yet.

Update the Go version to a stable release:

-FROM registry.suse.com/bci/golang:1.23 AS builder
+FROM registry.suse.com/bci/golang:1.21 AS builder

@COLDTURNIP COLDTURNIP changed the title feat: support secure release feat: self-contained container image build Feb 5, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
scripts/package (1)

43-57: Secure sensitive build arguments.

The echo of the build command could expose sensitive information. Consider:

  1. Adding a warning about sensitive information.
  2. Redacting sensitive values in the echo.
  3. Making the echo conditional.
+# Warning: Build command may contain sensitive information
+if [[ "${DEBUG:-}" == "true" ]]; then
     echo "${build_cmd[@]}" build --no-cache \
         "${builder_args[@]}" \
         "${iid_file_args[@]}" \
         "${buildx_args[@]}" \
         -t "$image" -f package/Dockerfile .
+fi

 "${build_cmd[@]}" build --no-cache \
     "${builder_args[@]}" \
     "${iid_file_args[@]}" \
     "${buildx_args[@]}" \
     -t "$image" -f package/Dockerfile .

 echo "Built $image"
-echo "$image" > ./bin/latest_image
+# Add build metadata
+cat > ./bin/latest_image <<EOF
+image: $image
+built_at: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
+secure_build: $IS_SECURE
+EOF
🧹 Nitpick comments (5)
package/Dockerfile (1)

2-13: Multi-Stage Build: Builder Stage Initialization
The introduction of the builder stage using registry.suse.com/bci/golang:1.23 and setting the working directory to /app streamlines the build process and helps minimize the final image size. Be sure that the build script at /app/scripts/build does not print or expose any sensitive information during execution.

.github/workflows/build.yml (2)

43-47: Outputting Build Information
The script correctly appends the extracted version components to $GITHUB_OUTPUT for use by later steps. If the final cat <<EOF block is only meant for logging purposes, consider removing or limiting its output—especially if any sensitive details might be present—to keep the build logs lean and secure.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 47-47: trailing spaces

(trailing-spaces)


42-42: Remove Trailing Whitespace
Static analysis has flagged trailing spaces (on lines 42 and 47). Removing these will improve readability and maintain consistency across the workflow file.

Also applies to: 47-47

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 42-42: trailing spaces

(trailing-spaces)

scripts/package (2)

2-2: Enhance error handling and project name validation.

  1. Add more bash safety flags to catch common errors.
  2. Consider validating the project name against a known value.
-set -e
+set -euo pipefail
+
+# Validate project name
+expected_project="backing-image-manager"
+if [[ "$project" != "$expected_project" ]]; then
+    echo "Error: Unexpected project name: $project (expected: $expected_project)" >&2
+    exit 1
+fi

Also applies to: 8-8


31-31: Validate image name components.

Add validation for image name components to ensure they meet Docker naming requirements.

+# Validate image name components
+if [[ ! "$REPO" =~ ^[a-z0-9]+([._-][a-z0-9]+)*(/[a-z0-9]+([._-][a-z0-9]+)*)*$ ]]; then
+    echo "Error: Invalid repository name format: $REPO" >&2
+    exit 1
+fi
+if [[ ! "$IMAGE_NAME" =~ ^[a-z0-9]+([._-][a-z0-9]+)*$ ]]; then
+    echo "Error: Invalid image name format: $IMAGE_NAME" >&2
+    exit 1
+fi
 image="${REPO}/${IMAGE_NAME}:${TAG}"
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5dd142e and 815ffbd.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Makefile
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/build.yml

[error] 42-42: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (7)
package/Dockerfile (1)

35-36: Secure Transfer of the Compiled Binary
Using COPY --from=builder to bring in the backing-image-manager binary helps isolate build-time dependencies from the production image. Confirm that the ${ARCH} variable is resolved consistently with the environment defined earlier (via ENV ARCH ${TARGETPLATFORM#linux/}).

.github/workflows/build.yml (3)

14-19: Exposing Build Outputs
The outputs for version_major, version_minor, version_build, and image_tag are now properly defined for downstream jobs. Ensure that the values extracted later in the build_info step match your expectations.


80-84: Validate Image Tag and Repository Configuration
The “Build and publish image” step now uses the image_tag output from the build_info step. Double-check that the derived tag conforms to Docker tag naming conventions and that the repository (docker.io/longhornio) is correct for your secure build process.


32-41: ⚠️ Potential issue

Fix Version Extraction Logic in build_info Step
The current version extraction via sed does not account for the full ref format (refs/tags/v...). This may result in an empty or incorrect version string. Consider revising the command as follows:

-          version=$(sed -E 's/^v([0-9.]*)$/\1' <<<$ref )
+          version=$(echo "$ref" | sed -E 's#^refs/tags/v([0-9.]+)$#\1#')

Also, verify that env.branch is defined when the ref indicates a branch.

Likely invalid or redundant comment.

scripts/package (3)

23-29: Improve version extraction error handling.

While error handling has improved, the error case could be more informative.

 if [[ -z $TAG ]]; then
-    if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+    if ! api_version=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version" >&2
+        echo "Warning: Using fallback tag" >&2
         TAG="unknown_$(date -u +%Y%m%d)"
+    else
+        TAG="v${api_version}_$(date -u +%Y%m%d)"
     fi
 fi

39-41: LGTM! Good security feature implementation.

The implementation correctly enables SBOM generation and provenance attestation for secure builds, which aligns with the PR objectives for enhancing build security.


12-21: 🛠️ Refactor suggestion

Add parameter validation and documentation.

Security-sensitive parameters should be documented and validated to prevent misuse.

Add parameter validation and documentation:

+# Configuration parameters:
+# REPO: Container registry repository (default: longhornio)
+# IMAGE_NAME: Name of the container image (default: project name)
+# TAG: Image tag (default: auto-generated from version)
+# OUTPUT_ARGS: Docker buildx output arguments (default: --load)
+# IS_SECURE: Enable security features like SBOM and attestation (default: false)
+# MACHINE: Builder instance name (default: '')
+# TARGET_PLATFORMS: Target build platforms (default: '')
+# IID_FILE: Image ID file path (default: '')
+# IID_FILE_FLAG: Custom image ID file flag (default: '')

+# Validate security parameters
+if [[ "$IS_SECURE" != "true" && "$IS_SECURE" != "false" ]]; then
+    echo "Error: IS_SECURE must be 'true' or 'false'" >&2
+    exit 1
+fi
✅ Verification successful

Error: No shell scripts or web queries found


Parameter validation and documentation implemented correctly.

The changes now include clear inline documentation for all configuration parameters (with default values) and a validation check to ensure the security-sensitive parameter IS_SECURE has an acceptable value ("true" or "false"). This prevents misuse and improves clarity.

  • Documentation comments for parameters have been added.
  • A validation block is included for IS_SECURE.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
scripts/package (2)

8-10: ⚠️ Potential issue

Improve build command validation.

The current command check could fail silently and doesn't verify docker availability in the fallback case.

Apply this diff to improve error handling:

-command -v buildx >/dev/null && build_cmd=(buildx) || build_cmd=(docker buildx)
+if command -v buildx >/dev/null 2>&1; then
+    build_cmd=(buildx)
+elif command -v docker >/dev/null 2>&1; then
+    build_cmd=(docker buildx)
+else
+    echo "Error: Neither buildx nor docker commands are available" >&2
+    exit 1
+fi

23-29: ⚠️ Potential issue

Improve version extraction robustness.

The version extraction using jq assumes the command succeeds and returns valid JSON.

Apply this diff to add error handling:

-    if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+    if ! api_version=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version, falling back to VERSION" >&2
+        TAG="$VERSION"
+    else
       TAG="v${api_version}_$(date -u +%Y%m%d)"
-    else
-      TAG="$VERSION"
     fi
.github/workflows/build.yml (1)

32-42: ⚠️ Potential issue

Fix version extraction logic.

There are syntax errors in the version extraction code.

Apply this diff:

-          version=$(sed -E 's/^v([0-9.]*)$/\1' <<<$ref )
+          version=$(echo "$ref" | sed -E 's/^refs\/tags\/v([0-9.]+)$/\1/')
-        elif [[ "$ref" =~ 'refs/heads/' ]]
+        elif [[ "$ref" =~ 'refs/heads/' ]]; then
🧹 Nitpick comments (2)
package/Dockerfile (1)

25-33: Consider pinning package versions.

Installing packages without version pinning could lead to inconsistent builds and potential security vulnerabilities.

Apply this diff to pin versions:

-RUN zypper -n install kmod curl wget nfs-client nfs4-acl-tools fuse \
+RUN zypper -n install \
+    kmod-$(rpm -q --qf '%{VERSION}' kernel-default) \
+    curl-7.* wget-1.* nfs-client-2.* nfs4-acl-tools-0.* fuse-2.* \
.github/workflows/build.yml (1)

81-85: Consider adding image scan step.

For enhanced security, consider adding a container image vulnerability scan step before publishing.

Add this step before publishing:

    - name: Scan image for vulnerabilities
      uses: aquasecurity/trivy-action@master
      with:
        image: longhornio/backing-image-manager:${{ needs.build.outputs.image_tag }}
        format: 'table'
        exit-code: '1'
        ignore-unfixed: true
        vuln-type: 'os,library'
        severity: 'CRITICAL,HIGH'
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 815ffbd and 46063cc.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Makefile
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/build.yml

[error] 43-43: trailing spaces

(trailing-spaces)


[error] 48-48: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (4)
scripts/package (2)

12-21: LGTM! Good security configuration.

The script properly handles security-related parameters with sensible defaults:

  • IS_SECURE for enabling secure build features
  • IID_FILE for tracking image IDs
  • OUTPUT_ARGS for controlling build output

39-41: Verify secure build attestations.

The script enables SBOM generation and provenance attestation in secure mode, which is good for supply chain security. However, ensure these features are supported by your buildx version.

package/Dockerfile (2)

35-36: LGTM! Good security practice.

Setting proper executable permissions immediately after copying the binary is a good security practice.


2-13: ⚠️ Potential issue

Verify golang image version.

The specified golang version "1.23" seems incorrect as it's not a valid Go version.

✅ Verification successful

🌐 Web query:

What is the latest version of golang?

💡 Result:

The latest stable version of Go (Golang) as of February 2025 is **Go 1.23.5**, released on January 16, 2025[2][6]. This minor update includes security fixes for `crypto/x509` and `net/http` packages along with runtime bug fixes[2].

For developers wanting to test upcoming features, **Go 1.24rc2** is available as an unstable release candidate[5]. However, production environments should continue using the stable Go 1.23 series.

Key details about recent releases:
- **Go 1.23** (major release): Introduced toolchain improvements and library updates while maintaining compatibility[1][3]
- **Go 1.22** (previous major version): Last updated to v1.22.11 in January 2025 with security patches[2]
- **Installation**: Current stable can be installed via `go get go@1.23.5` or downloaded from official sources[6]

The Go team maintains regular release cycles with major versions every 6 months and frequent minor updates addressing security and stability[2][4].

Citations:

- 1: https://go.dev/blog/go1.23
- 2: https://go.dev/doc/devel/release
- 3: https://tip.golang.org/doc/go1.23
- 4: https://tip.golang.org/doc/go1.22
- 5: https://go.dev/dl/
- 6: https://go.dev/doc/install
- 7: https://groups.google.com/g/golang-nuts/c/_ROx_UGCCCg

Verified: Go version in Dockerfile is correct.

  • The Dockerfile uses golang:1.23, which is valid given that Go 1.23 is the current stable series.
  • The web query confirms that while the latest patch version is Go 1.23.5, specifying the major version "1.23" is acceptable for ensuring the use of the Go 1.23 series.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
.github/workflows/build.yml (1)

34-39: ⚠️ Potential issue

Version Extraction Logic Improvement
The current version extraction uses:

version=$(sed -E 's/^v([0-9.]*)$/\1' <<<$ref )

This will likely fail since $ref from GitHub is in the format refs/tags/vX.Y.Z. Please update the extraction logic to correctly remove the prefix. For example:

- version=$(sed -E 's/^v([0-9.]*)$/\1' <<<$ref )
+ version=$(echo "$ref" | sed -E 's/^refs\/tags\/v([0-9.]+)$/\1/')

This change addresses the known version extraction issues noted in previous reviews.

🧹 Nitpick comments (2)
package/Dockerfile (1)

2-8: Builder Stage & Source Copy Concerns
The introduction of the builder stage using registry.suse.com/bci/golang:1.23 AS builder along with setting the working directory (WORKDIR /app) and copying the entire context (COPY . /app) is implemented correctly. Please ensure that a proper .dockerignore is in place so that unnecessary or sensitive files are not included in the build context.

.github/workflows/build.yml (1)

40-42: Handling Branch References
For branch builds, setting the image tag as ${branch}-head is acceptable. If future requirements call for additional granularity or metadata in branch builds, consider extending this logic.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46063cc and d3dc18f.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • Makefile
  • scripts/package
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (7)
package/Dockerfile (2)

10-13: Build Script Execution & Secret Handling
The Dockerfile sets the build script (/app/scripts/build) as executable and executes it. Please verify that the build script handles failures gracefully and that it does not inadvertently log or expose any secret information (per the PR objective regarding EIO secrets).


35-36: Binary Retrieval from Builder Stage
The updated COPY command (COPY --from=builder /app/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager) and the subsequent permission fix (via RUN chmod +x /usr/local/bin/backing-image-manager) correctly retrieve and prepare the binary for the final image. Ensure that the build process reliably places the binary at /app/bin during the build stage.

.github/workflows/build.yml (5)

14-18: Job Outputs Definition
Defining job-level outputs (version_major, version_minor, version_build, and image_tag) to propagate build info is clear and aligns with the new versioning requirements.


24-33: Build Info Initialization & Branch Extraction
The new build_info step initializes version variables and extracts the branch name properly (using the fallback with GITHUB_HEAD_REF). One note: verify that ${{ github.ref }} expands as expected within the shell session.


44-47: Setting GitHub Action Outputs
Echoing the extracted version details to $GITHUB_OUTPUT is correctly implemented, ensuring downstream steps have access to the required information.


49-55: Logging Extracted Build Info
The multi-line echo (using cat <<EOF) provides clear logging of build information. Just double-check to ensure that no sensitive data is logged—even though version details are not secret—to align with security best practices.


66-86: Build & Publish Image Job Configuration
The build_push_image job, which logs into Docker Hub and then runs make workflow-image-build-push, is set up correctly. Ensure that the environment variable TAG, sourced from the earlier outputs, propagates as intended and that this job does not expose any secrets in its logs.

@COLDTURNIP COLDTURNIP force-pushed the feat-secure_build branch 3 times, most recently from b46d358 to 14e00b4 Compare February 7, 2025 09:25
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
scripts/package (2)

23-29: Enhance version fallback mechanism.

While error handling has been added, consider:

  1. Validating the format of api_version before using it
  2. Logging when falling back to VERSION
  3. Validating VERSION is set before using as fallback
 if [[ -z $TAG ]]; then
     if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+        if [[ ! $api_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+            echo "Warning: Invalid API version format: $api_version" >&2
+            api_version=$VERSION
+        fi
       TAG="v${api_version}_$(date -u +%Y%m%d)"
     else
+        if [[ -z $VERSION ]]; then
+            echo "Error: VERSION not set" >&2
+            exit 1
+        fi
+        echo "Warning: Falling back to VERSION: $VERSION" >&2
       TAG="$VERSION"
     fi
 fi

39-41: Consider additional secure build attestations.

The secure build configuration adds SBOM and provenance attestation, which is good. Consider:

  1. Adding vulnerability scanning attestation
  2. Documenting the security implications of each attestation
  3. Validating attestation outputs
 IFS=' ' read -r -a buildx_args <<<"$OUTPUT_ARGS"
-[[ $IS_SECURE == 'true' ]] && buildx_args+=('--sbom=true' '--attest' 'type=provenance,mode=max')
+[[ $IS_SECURE == 'true' ]] && buildx_args+=(
+    '--sbom=true'
+    '--attest' 'type=provenance,mode=max'
+    '--attest' 'type=vuln'
+)
 [[ $TARGET_PLATFORMS ]] && buildx_args+=('--platform' "$TARGET_PLATFORMS")
package/Dockerfile (1)

25-33: Enhance package installation security.

Consider improving package installation security:

  1. Pin package versions for reproducibility
  2. Clean package cache after installation
  3. Verify package signatures explicitly
 RUN zypper -n addrepo --refresh https://download.opensuse.org/repositories/system:/snappy/SLE_15/system:snappy.repo && \
     zypper -n addrepo --refresh https://download.opensuse.org/repositories/network:/utilities/SLE_15_SP5/network:utilities.repo && \
     zypper --gpg-auto-import-keys ref && \
     zypper -n ref && \
-    zypper update -y
+    zypper update -y && \
+    zypper clean -a

 RUN zypper -n install kmod curl wget nfs-client nfs4-acl-tools fuse \
     librdmacm1 librdmacm-utils libibverbs perl-Config-General libaio-devel sg3_utils \
-    iputils telnet iperf qemu-tools iproute2 e2fsprogs e2fsprogs-devel xfsprogs xfsprogs-devel
+    iputils telnet iperf qemu-tools iproute2 e2fsprogs e2fsprogs-devel xfsprogs xfsprogs-devel && \
+    zypper clean -a
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3dc18f and 14e00b4.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/build.yml
  • Makefile
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (3)
scripts/package (2)

10-10: Improve build command validation.

The current command check could fail silently and doesn't verify docker availability in the fallback case.


12-21: Consider secure parameter handling.

Given the PR's focus on secure builds and protecting EIO secrets, consider:

  1. Documenting which parameters might contain sensitive data
  2. Adding input validation for security-critical parameters
  3. Ensuring sensitive values aren't logged or exposed in build output
package/Dockerfile (1)

35-36: LGTM! Good security practice.

Explicitly setting executable permissions on the binary is a good security practice.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
scripts/package (2)

33-38: Improve array handling for builder and iidfile arguments.

The current approach using IFS for word splitting could be problematic with values containing spaces.

-IFS=' ' read -r -a iid_file_args <<<"$IID_FILE_FLAG"
-[[ -n "$IID_FILE" && ${#iid_file_args} == 0 ]] && iid_file_args=('--iidfile' "$IID_FILE")
+# Handle IID_FILE_FLAG as an array
+declare -a iid_file_args
+if [[ -n "$IID_FILE_FLAG" ]]; then
+    # shellcheck disable=SC2206
+    iid_file_args=($IID_FILE_FLAG)
+elif [[ -n "$IID_FILE" ]]; then
+    iid_file_args=('--iidfile' "$IID_FILE")
+fi

39-41: Improve array handling and secure build flags.

  1. The current approach using IFS for word splitting could be problematic.
  2. Consider adding more security-related flags for secure builds.
-IFS=' ' read -r -a buildx_args <<<"$OUTPUT_ARGS"
-[[ $IS_SECURE == 'true' ]] && buildx_args+=('--sbom=true' '--attest' 'type=provenance,mode=max')
-[[ $TARGET_PLATFORMS ]] && buildx_args+=('--platform' "$TARGET_PLATFORMS")
+# Handle OUTPUT_ARGS as an array
+declare -a buildx_args
+if [[ -n "$OUTPUT_ARGS" ]]; then
+    # shellcheck disable=SC2206
+    buildx_args=($OUTPUT_ARGS)
+fi
+
+# Add security-related flags for secure builds
+if [[ $IS_SECURE == 'true' ]]; then
+    buildx_args+=(
+        '--sbom=true'
+        '--attest' 'type=provenance,mode=max'
+        '--security-opt' 'no-new-privileges'
+        '--cap-drop' 'ALL'
+    )
+fi
+
+# Add platform flags
+[[ $TARGET_PLATFORMS ]] && buildx_args+=('--platform' "$TARGET_PLATFORMS")
package/Dockerfile (1)

35-36: Optimize permissions handling.

Consider setting permissions during COPY to reduce the number of layers.

-COPY --from=builder /app/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager
-RUN chmod +x /usr/local/bin/backing-image-manager
+COPY --from=builder --chmod=755 /app/bin/backing-image-manager-${ARCH} /usr/local/bin/backing-image-manager
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14e00b4 and 16012bf.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • Makefile
  • .github/workflows/build.yml
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (3)
scripts/package (2)

8-8: Improve build command validation.

The current command check could fail silently and doesn't verify docker availability in the fallback case.

-command -v buildx >/dev/null && build_cmd=(buildx) || build_cmd=(docker buildx)
+if command -v buildx >/dev/null 2>&1; then
+    build_cmd=(buildx)
+elif command -v docker >/dev/null 2>&1; then
+    build_cmd=(docker buildx)
+else
+    echo "Error: Neither buildx nor docker commands are available" >&2
+    exit 1
+fi

Also applies to: 10-10


23-29: Improve version extraction robustness.

The version extraction using jq assumes the command succeeds and returns valid JSON. Add error handling.

-    if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+    if ! api_version=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version" >&2
+        exit 1
+    fi
package/Dockerfile (1)

2-13: Enhance builder stage security.

Consider improving the security of the build stage:

  1. Use .dockerignore to minimize build context
  2. Consider using a distroless or minimal base image
  3. Add security scanning during build
+# Add .dockerignore file
+cat > .dockerignore << 'EOF'
+.git
+.github
+.gitignore
+*.md
+tests/
+docs/
+EOF

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
scripts/package (2)

8-10: Improve build command validation and error handling.

The current command check could fail silently. Consider adding proper error handling.

-command -v buildx >/dev/null && build_cmd=(buildx) || build_cmd=(docker buildx)
+if command -v buildx >/dev/null 2>&1; then
+    build_cmd=(buildx)
+elif command -v docker >/dev/null 2>&1; then
+    build_cmd=(docker buildx)
+else
+    echo "Error: Neither buildx nor docker commands are available" >&2
+    exit 1
+fi

56-58: Improve directory creation error handling.

The directory creation could fail silently if there are permission issues.

-mkdir ./bin || true
+if ! mkdir -p ./bin 2>/dev/null; then
+    echo "Error: Failed to create bin directory" >&2
+    exit 1
+fi
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c1c3cb and 7a852a6.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • Makefile
  • .github/workflows/build.yml
🧰 Additional context used
🧠 Learnings (1)
scripts/package (1)
Learnt from: COLDTURNIP
PR: longhorn/backing-image-manager#514
File: scripts/package:12-21
Timestamp: 2025-02-10T03:11:41.382Z
Learning: In the backing-image-manager project, the environment variables REPO, IMAGE_NAME, and TAG used in the package script are standard Docker image configuration parameters and should not be treated as sensitive information.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (6)
scripts/package (4)

12-21: LGTM! Well-organized configuration parameters.

The default values are properly set using parameter expansion, and the variables are clearly documented.


23-29: Improve version handling robustness.

The current version extraction needs better error handling and validation.

 if [[ -z $TAG ]]; then
-    if api_version=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+    if ! api_version=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version" >&2
+        if [[ -z $VERSION ]]; then
+            echo "Error: VERSION is not defined" >&2
+            exit 1
+        fi
+        TAG="$VERSION"
+    else
       TAG="v${api_version}_$(date -u +%Y%m%d)"
-    else
-      TAG="$VERSION"
     fi
 fi

33-41: LGTM! Well-implemented secure build features.

The build arguments are properly handled, and the secure build mode correctly adds SBOM and provenance attestation, aligning with the PR's security objectives.


43-52: Improve command logging to prevent secrets leakage.

The current approach of echoing the entire command could leak sensitive information in logs.

-echo "${build_cmd[@]}" build --no-cache \
-    "${builder_args[@]}" \
-    "${iid_file_args[@]}" \
-    "${buildx_args[@]}" \
-    -t "$image" -f package/Dockerfile .
+# Log command without sensitive information
+echo "Building image using ${build_cmd[*]}"
+
+"${build_cmd[@]}" build --no-cache \
    "${builder_args[@]}" \
    "${iid_file_args[@]}" \
    "${buildx_args[@]}" \
    -t "$image" -f package/Dockerfile .
package/Dockerfile (2)

2-13: Optimize build context and enhance builder stage security.

Consider improving the security and efficiency of the build stage:

  1. Use .dockerignore to minimize build context
  2. Consider using a distroless or minimal base image
  3. Add security scanning during build
+# Add .dockerignore file
+cat > .dockerignore << 'EOF'
+.git
+.github
+.gitignore
+*.md
+tests/
+docs/
+EOF

35-36: LGTM! Well-implemented multi-stage build.

The multi-stage build properly copies the binary and sets permissions, reducing the final image size.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
scripts/package (3)

12-21: LGTM! Well-organized configuration parameters.

The parameters are clearly defined with sensible defaults, making the script highly configurable.

Consider using consistent variable referencing syntax.

For better readability and consistency, consider using ${VAR} syntax throughout the script.

-REPO=${REPO:-longhornio}
-IMAGE_NAME=${IMAGE_NAME:-$PROJECT}
-TAG=${TAG:-''}
+REPO=${REPO:-longhornio}
+IMAGE_NAME=${IMAGE_NAME:-${PROJECT}}
+TAG=${TAG:-''}

36-37: Improve argument splitting robustness.

The current IFS usage for splitting arguments could be more robust against potential word splitting issues.

-IFS=' ' read -r -a IID_FILE_ARGS <<<"${IID_FILE_FLAG}"
-[[ -n "${IID_FILE}" && ${#IID_FILE_ARGS} == 0 ]] && IID_FILE_ARGS=('--iidfile' "${IID_FILE}")
+if [[ -n "${IID_FILE_FLAG}" ]]; then
+    IFS=' ' read -r -a IID_FILE_ARGS <<<"${IID_FILE_FLAG}"
+elif [[ -n "${IID_FILE}" ]]; then
+    IID_FILE_ARGS=('--iidfile' "${IID_FILE}")
+fi

-IFS=' ' read -r -a BUILDX_ARGS <<<"${OUTPUT_ARGS}"
-[[ ${IS_SECURE} == 'true' ]] && BUILDX_ARGS+=('--sbom=true' '--attest' 'type=provenance,mode=max')
+if [[ -n "${OUTPUT_ARGS}" ]]; then
+    IFS=' ' read -r -a BUILDX_ARGS <<<"${OUTPUT_ARGS}"
+fi
+[[ "${IS_SECURE}" == 'true' ]] && BUILDX_ARGS+=('--sbom=true' '--attest' 'type=provenance,mode=max')

Also applies to: 39-40


55-56: Improve error handling for file operations.

The directory creation and file write operations should handle potential permission issues.

-mkdir ./bin || true
-echo "${IMAGE}" > ./bin/latest_image
+if ! mkdir -p ./bin 2>/dev/null; then
+    echo "Error: Failed to create bin directory" >&2
+    exit 1
+fi
+if ! echo "${IMAGE}" > ./bin/latest_image 2>/dev/null; then
+    echo "Error: Failed to write latest image info" >&2
+    exit 1
+fi
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a852a6 and 102aa98.

📒 Files selected for processing (1)
  • scripts/package (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
scripts/package (1)
Learnt from: COLDTURNIP
PR: longhorn/backing-image-manager#514
File: scripts/package:12-21
Timestamp: 2025-02-10T03:11:41.382Z
Learning: In the backing-image-manager project, the environment variables REPO, IMAGE_NAME, and TAG used in the package script are standard Docker image configuration parameters and should not be treated as sensitive information.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (7)
scripts/package (7)

8-8: LGTM! Modern syntax for command substitution.

The change from backticks to $() improves readability and nestability.


10-10: Improve build command validation.

The current command check could fail silently and doesn't verify docker availability in the fallback case.


23-29: Improve version handling robustness.

Two issues need attention:

  1. The jq command output should be properly validated.
  2. The API_VERSION variable should be properly quoted.

31-31: Use consistent variable referencing syntax.

For better readability and consistency with the rest of the script.


39-41: LGTM! Good security features for secure builds.

The addition of SBOM and provenance attestation aligns well with secure build requirements.


43-49: LGTM! Clear and organized build command construction.

The build command array is well-structured with all necessary arguments.


50-51: Improve command logging to prevent secrets leakage.

The current approach of echoing the entire command could leak sensitive information in logs.

Copy link
Member

@innobead innobead left a comment

Choose a reason for hiding this comment

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

In general, LGTM. Well done. Just a few feedback.

cc @derekbit

BUILDER_ARGS=()
[[ ${MACHINE} ]] && BUILDER_ARGS+=('--builder' "${MACHINE}")

IFS=' ' read -r -a IID_FILE_ARGS <<<"${IID_FILE_FLAG}"
Copy link
Member

@innobead innobead Feb 11, 2025

Choose a reason for hiding this comment

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

Why not name $IID_FILE_FLAG to $IID_FILE_ARGS and IID_FILE_ARGS renamed to iid_file_args following your naming convention in the script.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IID_FILE_FLAG and/or IID_FILE would be externally assigned by rancher/ecm-distro-tools/actions/publish-image.


echo ${IMAGE} > ./bin/latest_image
mkdir ./bin || true
echo "${IMAGE}" > ./bin/latest_image
Copy link
Member

@innobead innobead Feb 11, 2025

Choose a reason for hiding this comment

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

What's the purpose of saving the image locally here? For debugging? If yes, suggest making a flag to enable it and disable it by default, since the image will be pushed to the registry instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We record the output image name into this text file for further automation.

@COLDTURNIP COLDTURNIP force-pushed the feat-secure_build branch 2 times, most recently from 892b38e to 35b6a6f Compare February 11, 2025 09:57
@COLDTURNIP COLDTURNIP requested a review from innobead February 11, 2025 09:57
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

Actionable comments posted: 1

♻️ Duplicate comments (3)
scripts/package (3)

10-10: 🛠️ Refactor suggestion

Improve build command validation.

The current command check could fail silently if neither buildx nor docker is available.

Apply this diff to add proper error handling:

-command -v buildx >/dev/null && BUILD_CMD=(buildx) || BUILD_CMD=(docker buildx)
+if command -v buildx >/dev/null 2>&1; then
+    BUILD_CMD=(buildx)
+elif command -v docker >/dev/null 2>&1; then
+    BUILD_CMD=(docker buildx)
+else
+    echo "Error: Neither buildx nor docker commands are available" >&2
+    exit 1
+fi

50-58: 🛠️ Refactor suggestion

Improve command logging to prevent secrets leakage.

While the command construction is well-organized, echoing the entire command could potentially leak sensitive information in logs.

Apply this diff to improve command logging:

-echo "${IMAGE_BUILD_CMD[@]}"
+"${IMAGE_BUILD_CMD[@]}" 2>&1 | grep -v "secret" || true

23-29: 🛠️ Refactor suggestion

Improve version extraction robustness.

The version extraction needs better error handling and proper variable quoting.

Apply this diff to improve the version extraction:

-if [[ -z "${TAG}" ]]; then
-    if API_VERSION=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
-      TAG="v${API_VERSION}_$(date -u +%Y%m%d)"
-    else
-      TAG="${VERSION}"
-    fi
-fi
+if [[ -z "${TAG}" ]]; then
+    if ! API_VERSION=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version, falling back to VERSION" >&2
+        TAG="${VERSION}"
+    else
+        TAG="v${API_VERSION}_$(date -u +%Y%m%d)"
+    fi
+fi
🧹 Nitpick comments (1)
.github/workflows/build.yml (1)

81-85: Consider making REPO configurable.

The REPO value is hardcoded which might limit reusability.

Consider making REPO configurable through repository secrets or workflow inputs:

       env:
-        REPO: docker.io/longhornio
+        REPO: ${{ secrets.DOCKER_REPO || 'docker.io/longhornio' }}
         TAG: ${{ needs.build.outputs.image_tag }}
🛑 Comments failed to post (1)
.github/workflows/build.yml (1)

35-39: 🛠️ Refactor suggestion

Improve version extraction robustness.

The version extraction logic needs better error handling for edge cases.

Apply this diff to improve version extraction:

-          version=$(sed -E 's/^v([0-9]*\.[0-9]*\.[0-9]*).*$/\1/' <<<${{ github.ref_name }} )
-          version_major=$(cut -d. -f1 <<<$version)
-          version_minor=$(cut -d. -f2 <<<$version)
-          version_build=$(cut -d. -f3 <<<$version)
+          if ! version=$(sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/' <<<${{ github.ref_name }}); then
+            echo "Error: Failed to extract version from tag" >&2
+            exit 1
+          fi
+          IFS='.' read -r version_major version_minor version_build <<<"$version"
+          [[ -z "$version_major" || -z "$version_minor" || -z "$version_build" ]] && {
+            echo "Error: Invalid version format" >&2
+            exit 1
+          }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

          if ! version=$(sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/' <<<${{ github.ref_name }}); then
            echo "Error: Failed to extract version from tag" >&2
            exit 1
          fi
          IFS='.' read -r version_major version_minor version_build <<<"$version"
          [[ -z "$version_major" || -z "$version_minor" || -z "$version_build" ]] && {
            echo "Error: Invalid version format" >&2
            exit 1
          }
          image_tag=${{ github.ref_name }}

@COLDTURNIP
Copy link
Contributor Author

@innobead @derekbit @c3y1huang
Improved the code readability per review comment. Please help review it again, thanks.

innobead
innobead previously approved these changes Feb 11, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
scripts/package (1)

2-8: 🛠️ Refactor suggestion

Enhance script safety with additional shell options.

Add set -u to exit on undefined variables and set -o pipefail to ensure pipeline failures are caught.

-set -e
+set -e
+set -u
+set -o pipefail
♻️ Duplicate comments (3)
scripts/package (3)

10-10: 🛠️ Refactor suggestion

Improve build command validation.

The current command check could fail silently and doesn't verify docker availability in the fallback case.

-command -v buildx >/dev/null && BUILD_CMD=(buildx) || BUILD_CMD=(docker buildx)
+if command -v buildx >/dev/null 2>&1; then
+    BUILD_CMD=(buildx)
+elif command -v docker >/dev/null 2>&1; then
+    BUILD_CMD=(docker buildx)
+else
+    echo "Error: Neither buildx nor docker commands are available" >&2
+    exit 1
+fi

23-29: 🛠️ Refactor suggestion

Improve version extraction robustness.

The version extraction using jq assumes the command succeeds and returns valid JSON.

-if [[ -z "${TAG}" ]]; then
-    if API_VERSION=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
-      TAG="v${API_VERSION}_$(date -u +%Y%m%d)"
-    else
-      TAG="${VERSION}"
-    fi
-fi
+if [[ -z "${TAG}" ]]; then
+    if ! API_VERSION=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version" >&2
+        if [[ -z "${VERSION}" ]]; then
+            echo "Error: VERSION is not defined" >&2
+            exit 1
+        fi
+        TAG="${VERSION}"
+    else
+        TAG="v${API_VERSION}_$(date -u +%Y%m%d)"
+    fi
+fi

50-58: 🛠️ Refactor suggestion

Improve command logging to prevent secrets leakage.

The current approach of echoing the entire command could leak sensitive information in logs.

-IMAGE_BUILD_CMD=(
-    "${BUILD_CMD[@]}" build --no-cache \
-    "${BUILDER_ARGS[@]}" \
-    "${IID_FILE_ARGS[@]}" \
-    "${BUILDX_ARGS[@]}" \
-    -t "${IMAGE}" -f package/Dockerfile .
-)
-echo "${IMAGE_BUILD_CMD[@]}"
-"${IMAGE_BUILD_CMD[@]}"
+# Log command without sensitive information
+echo "Building image using ${BUILD_CMD[*]}"
+
+IMAGE_BUILD_CMD=(
+    "${BUILD_CMD[@]}" build --no-cache \
+    "${BUILDER_ARGS[@]}" \
+    "${IID_FILE_ARGS[@]}" \
+    "${BUILDX_ARGS[@]}" \
+    -t "${IMAGE}" -f package/Dockerfile .
+)
+"${IMAGE_BUILD_CMD[@]}"
🧹 Nitpick comments (1)
scripts/package (1)

62-63: Improve directory creation.

Use mkdir -p instead of || true for better error handling and clarity.

-mkdir ./bin || true
+mkdir -p ./bin
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 892b38e and a85378e.

📒 Files selected for processing (3)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/build.yml
  • Makefile
🧰 Additional context used
🧠 Learnings (1)
scripts/package (1)
Learnt from: COLDTURNIP
PR: longhorn/backing-image-manager#514
File: scripts/package:12-21
Timestamp: 2025-02-10T03:11:41.382Z
Learning: In the backing-image-manager project, the environment variables REPO, IMAGE_NAME, and TAG used in the package script are standard Docker image configuration parameters and should not be treated as sensitive information.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (2)
scripts/package (2)

31-31: LGTM!

The image name construction follows standard Docker naming conventions.


33-48: Well-implemented secure build configuration!

The implementation properly configures:

  • Builder selection via MACHINE
  • Image ID file handling
  • Security features (SBOM and provenance) for secure builds
  • Multi-platform support

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
scripts/package (2)

10-10: 🛠️ Refactor suggestion

Improve build command validation.

The current command check could fail silently and doesn't verify docker availability in the fallback case.

-command -v buildx >/dev/null && BUILD_CMD=(buildx) || BUILD_CMD=(docker buildx)
+if command -v buildx >/dev/null 2>&1; then
+    BUILD_CMD=(buildx)
+elif command -v docker >/dev/null 2>&1; then
+    BUILD_CMD=(docker buildx)
+else
+    echo "Error: Neither buildx nor docker commands are available" >&2
+    exit 1
+fi

23-29: 🛠️ Refactor suggestion

Improve version extraction robustness.

The version extraction using jq needs proper error handling and validation.

-if [[ -z "${TAG}" ]]; then
-    if API_VERSION=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+if [[ -z "${TAG}" ]]; then
+    if ! API_VERSION=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version, falling back to VERSION" >&2
+        TAG="${VERSION}"
+    else
       TAG="v${API_VERSION}_$(date -u +%Y%m%d)"
-    else
-      TAG="${VERSION}"
     fi
 fi
🧹 Nitpick comments (1)
scripts/package (1)

62-63: Improve directory creation robustness.

The directory creation could be more robust by checking if it already exists.

-mkdir ./bin || true
+if [[ ! -d ./bin ]]; then
+    mkdir -p ./bin
+fi
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a85378e and 9038d62.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • Makefile
  • .github/workflows/build.yml
  • package/Dockerfile
🧰 Additional context used
🧠 Learnings (1)
scripts/package (1)
Learnt from: COLDTURNIP
PR: longhorn/backing-image-manager#514
File: scripts/package:12-21
Timestamp: 2025-02-10T03:11:41.382Z
Learning: In the backing-image-manager project, the environment variables REPO, IMAGE_NAME, and TAG used in the package script are standard Docker image configuration parameters and should not be treated as sensitive information.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (5)
scripts/package (5)

8-8: LGTM! Modern syntax and proper quoting.

The change from backticks to $() and the addition of quotes around ${PWD} improves both readability and robustness.


12-21: LGTM! Well-structured parameter configuration.

The configuration parameters are well-organized with appropriate defaults. The use of environment variables with fallback values follows shell scripting best practices.


31-31: LGTM! Clear and properly quoted image name construction.

The image name is constructed using properly quoted variables, following shell scripting best practices.


47-48: LGTM! Proper secure build configuration.

The secure build features are well-implemented:

  • SBOM generation is enabled
  • Maximum provenance attestation is configured
  • Platform targeting is properly handled

50-58: LGTM! Clear and maintainable build command structure.

The build command is well-organized:

  • Uses array to prevent word splitting issues
  • Provides command visibility for debugging
  • Properly handles all build arguments

Signed-off-by: Raphanus Lo <yunchang.lo@suse.com>
Signed-off-by: Raphanus Lo <yunchang.lo@suse.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
scripts/package (2)

12-21: Add validation for boolean parameters.

The boolean parameters PUSH and IS_SECURE should be validated to ensure they only accept 'true' or 'false' values.

 # read configurable parameters
 REPO=${REPO:-longhornio}
 IMAGE_NAME=${IMAGE_NAME:-${PROJECT}}
 TAG=${TAG:-''}
-PUSH=${PUSH:-'false'}
-IS_SECURE=${IS_SECURE:-'false'}
+# Validate boolean parameters
+case "${PUSH:-false}" in
+    true|false) PUSH="${PUSH:-false}" ;;
+    *) echo "Error: PUSH must be 'true' or 'false'" >&2; exit 1 ;;
+esac
+case "${IS_SECURE:-false}" in
+    true|false) IS_SECURE="${IS_SECURE:-false}" ;;
+    *) echo "Error: IS_SECURE must be 'true' or 'false'" >&2; exit 1 ;;
+esac
 MACHINE=${MACHINE:-''}
 TARGET_PLATFORMS=${TARGET_PLATFORMS:-''}
 IID_FILE=${IID_FILE:-''}
 IID_FILE_FLAG=${IID_FILE_FLAG:-''}

62-63: Improve directory and file handling.

The current approach to directory creation and file writing could fail silently.

-mkdir ./bin || true
-echo "${IMAGE}" > ./bin/latest_image
+if [[ ! -d ./bin ]]; then
+    if ! mkdir -p ./bin; then
+        echo "Error: Failed to create bin directory" >&2
+        exit 1
+    fi
+fi
+if ! echo "${IMAGE}" > ./bin/latest_image; then
+    echo "Error: Failed to write to latest_image file" >&2
+    exit 1
+fi
package/Dockerfile (1)

1-47: Consider implementing SLSA Level 3 requirements.

While the multi-stage build improves security by isolating the build environment, consider implementing additional SLSA Level 3 requirements mentioned in the PR objectives:

  1. Hermetic builds
  2. Reproducible builds
  3. Provenance generation

Consider:

  1. Pin all base image versions with SHA digests
  2. Lock all dependency versions
  3. Implement build provenance generation using SLSA framework

Let me verify the current base image versioning:

#!/bin/bash
# Check if base images use SHA digests
rg -i "FROM .+@sha256:" package/Dockerfile
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9038d62 and 521014c.

📒 Files selected for processing (4)
  • .github/workflows/build.yml (2 hunks)
  • Makefile (2 hunks)
  • package/Dockerfile (2 hunks)
  • scripts/package (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/build.yml
  • Makefile
🧰 Additional context used
🧠 Learnings (1)
scripts/package (1)
Learnt from: COLDTURNIP
PR: longhorn/backing-image-manager#514
File: scripts/package:12-21
Timestamp: 2025-02-10T03:11:41.382Z
Learning: In the backing-image-manager project, the environment variables REPO, IMAGE_NAME, and TAG used in the package script are standard Docker image configuration parameters and should not be treated as sensitive information.
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build binaries
  • GitHub Check: Summary
🔇 Additional comments (7)
scripts/package (5)

8-8: LGTM! Modern and safe variable assignment.

The use of $() instead of backticks and proper quoting improves readability and safety.


10-10: Improve build command validation.

The current command check could fail silently and doesn't verify docker availability in the fallback case.

-command -v buildx >/dev/null && BUILD_CMD=(buildx) || BUILD_CMD=(docker buildx)
+if command -v buildx >/dev/null 2>&1; then
+    BUILD_CMD=(buildx)
+elif command -v docker >/dev/null 2>&1; then
+    BUILD_CMD=(docker buildx)
+else
+    echo "Error: Neither buildx nor docker commands are available" >&2
+    exit 1
+fi

23-29: Improve version handling robustness.

Two issues need attention:

  1. The VERSION variable used in the fallback case is not defined.
  2. The jq command output should be properly validated.
 if [[ -z "${TAG}" ]]; then
-    if API_VERSION=$(./bin/backing-image-manager version --client-only | jq ".clientVersion.backingImageManagerAPIVersion"); then
+    if ! API_VERSION=$(./bin/backing-image-manager version --client-only | jq -e ".clientVersion.backingImageManagerAPIVersion" 2>/dev/null); then
+        echo "Error: Failed to extract API version" >&2
+        if [[ -z "${VERSION}" ]]; then
+            echo "Error: VERSION is not defined" >&2
+            exit 1
+        fi
+        TAG="${VERSION}"
+    else
       TAG="v${API_VERSION}_$(date -u +%Y%m%d)"
-    else
-      TAG="${VERSION}"
     fi
 fi

47-48: LGTM! Good security practices implemented.

The secure build configuration with SBOM generation and provenance attestation aligns well with the PR's security focus and SLSA Level 3 requirements.


50-58: Improve command logging to prevent secrets leakage.

The current approach of echoing the entire command could leak sensitive information in logs.

-echo "${BUILD_CMD[@]}" "${IMAGE_BUILD_CMD_ARGS[@]}"
+"${BUILD_CMD[@]}" "${IMAGE_BUILD_CMD_ARGS[@]}" 2>&1 | grep -v "secret" || true
package/Dockerfile (2)

6-7: Limit build context exposure.

Copying the entire context into the builder stage could expose sensitive files.

Previous review already suggested adding a .dockerignore file to minimize the build context and enhance security.


12-13: Enhance secrets handling during build.

Given the PR objective to keep EIO secrets confidential, ensure build secrets are properly handled and don't leak into image layers.

Consider using Docker's secret mounting feature:

-RUN /app/scripts/build
+RUN --mount=type=secret,id=eio_secrets \
+    export EIO_SECRETS_FILE=/run/secrets/eio_secrets && \
+    /app/scripts/build

Let me verify if the build script handles secrets:

❌ Verification inconclusive

🏁 Script executed:

#!/bin/bash
# Search for secrets handling in build script
rg -i "secret|credential|key|token" scripts/build

Length of output: 51


Enhance secret handling in the build process
The search in the build script did not reveal any handling for secrets (using keywords like "secret", "credential", "key", "token"). This confirms that the build script does not currently implement any secret validation or masking. Given the PR objective to protect EIO secrets, the Dockerfile should leverage Docker’s secret mounting (as suggested) to prevent secrets from leaking into image layers.

  • The build script (scripts/build) shows no explicit reference to secrets handling.
  • The Dockerfile’s RUN command lacks any Docker secrets mount options.

Please consider revising the Dockerfile to use Docker’s secret features as follows:

-RUN /app/scripts/build
+RUN --mount=type=secret,id=eio_secrets \
+    export EIO_SECRETS_FILE=/run/secrets/eio_secrets && \
+    /app/scripts/build

Copy link
Member

@derekbit derekbit left a comment

Choose a reason for hiding this comment

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

LGTM

@derekbit derekbit merged commit 6c5fcd6 into longhorn:master Feb 12, 2025
9 checks passed
@COLDTURNIP COLDTURNIP deleted the feat-secure_build branch February 12, 2025 08:35
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.

4 participants