chore: adding alpine packages #2994

Merged
mfreeman451 merged 4 commits from refs/pull/2994/head into staging 2026-03-01 00:36:24 +00:00
mfreeman451 commented 2026-03-01 00:10:37 +00:00 (Migrated from github.com)
Owner

Imported from GitHub pull request.

Original GitHub pull request: #2953
Original author: @mfreeman451
Original URL: https://github.com/carverauto/serviceradar/pull/2953
Original created: 2026-03-01T00:10:37Z
Original updated: 2026-03-01T00:36:32Z
Original head: carverauto/serviceradar:1872-chore-add-additional-tools-to-serviceradar-tools-image
Original base: staging
Original merged: 2026-03-01T00:36:24Z by @mfreeman451

User description

IMPORTANT: Please sign the Developer Certificate of Origin

Thank you for your contribution to ServiceRadar. Please note, when contributing, the developer must include
a DCO sign-off statement indicating the DCO acceptance in one commit message. Here
is an example DCO Signed-off-by line in a commit message:

Signed-off-by: J. Doe <j.doe@domain.com>

Describe your changes

Code checklist before requesting a review

  • I have signed the DCO?
  • The build completes without errors?
  • All tests are passing when running make test?

PR Type

Enhancement


Description

  • Add four new Alpine Linux packages to build system

  • Include inetutils-telnet, libcap2, libbsd, libmd APK files

  • Create extraction rules for each new package

  • Integrate new packages into alpine_netutils rootfs


Diagram Walkthrough

flowchart LR
  A["New Alpine Packages"] -->|inetutils-telnet| B["APK HTTP Files"]
  A -->|libcap2| B
  A -->|libbsd| B
  A -->|libmd| B
  B -->|Extract Rules| C["Genrules"]
  C -->|Integrate| D["alpine_netutils_rootfs"]

File Walkthrough

Relevant files
Configuration changes
MODULE.bazel
Add Alpine package HTTP file definitions                                 

MODULE.bazel

  • Add four new http_file rules for Alpine packages
  • Define inetutils-telnet, libcap2, libbsd, libmd with SHA256 checksums
  • Reference Alpine v3.20 repository URLs for each package
+32/-0   
BUILD.bazel
Add APK extraction rules and integrate packages                   

docker/images/BUILD.bazel

  • Add four new genrule targets for extracting APK files
  • Create extraction logic for inetutils-telnet, libcap2, libbsd, libmd
    packages
  • Each rule handles tar extraction with support for multiple compression
    formats
  • Integrate new package tarballs into alpine_netutils_rootfs
    dependencies
+136/-0 

Imported from GitHub pull request. Original GitHub pull request: #2953 Original author: @mfreeman451 Original URL: https://github.com/carverauto/serviceradar/pull/2953 Original created: 2026-03-01T00:10:37Z Original updated: 2026-03-01T00:36:32Z Original head: carverauto/serviceradar:1872-chore-add-additional-tools-to-serviceradar-tools-image Original base: staging Original merged: 2026-03-01T00:36:24Z by @mfreeman451 --- ### **User description** ## IMPORTANT: Please sign the Developer Certificate of Origin Thank you for your contribution to ServiceRadar. Please note, when contributing, the developer must include a [DCO sign-off statement]( https://developercertificate.org/) indicating the DCO acceptance in one commit message. Here is an example DCO Signed-off-by line in a commit message: ``` Signed-off-by: J. Doe <j.doe@domain.com> ``` ## Describe your changes ## Issue ticket number and link ## Code checklist before requesting a review - [ ] I have signed the DCO? - [ ] The build completes without errors? - [ ] All tests are passing when running make test? ___ ### **PR Type** Enhancement ___ ### **Description** - Add four new Alpine Linux packages to build system - Include inetutils-telnet, libcap2, libbsd, libmd APK files - Create extraction rules for each new package - Integrate new packages into alpine_netutils rootfs ___ ### Diagram Walkthrough ```mermaid flowchart LR A["New Alpine Packages"] -->|inetutils-telnet| B["APK HTTP Files"] A -->|libcap2| B A -->|libbsd| B A -->|libmd| B B -->|Extract Rules| C["Genrules"] C -->|Integrate| D["alpine_netutils_rootfs"] ``` <details><summary><h3>File Walkthrough</h3></summary> <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Configuration changes</strong></td><td><table> <tr> <td> <details> <summary><strong>MODULE.bazel</strong><dd><code>Add Alpine package HTTP file definitions</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> MODULE.bazel <ul><li>Add four new <code>http_file</code> rules for Alpine packages<br> <li> Define inetutils-telnet, libcap2, libbsd, libmd with SHA256 checksums<br> <li> Reference Alpine v3.20 repository URLs for each package</ul> </details> </td> <td><a href="https://github.com/carverauto/serviceradar/pull/2953/files#diff-6136fc12446089c3db7360e923203dd114b6a1466252e71667c6791c20fe6bdc">+32/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td> <details> <summary><strong>BUILD.bazel</strong><dd><code>Add APK extraction rules and integrate packages</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary> <hr> docker/images/BUILD.bazel <ul><li>Add four new <code>genrule</code> targets for extracting APK files<br> <li> Create extraction logic for inetutils-telnet, libcap2, libbsd, libmd <br>packages<br> <li> Each rule handles tar extraction with support for multiple compression <br>formats<br> <li> Integrate new package tarballs into alpine_netutils_rootfs <br>dependencies</ul> </details> </td> <td><a href="https://github.com/carverauto/serviceradar/pull/2953/files#diff-0e4db31c224a8f72ae8e870a849e38a59d74a2c7f7b04347b0b3eb07e20c5a80">+136/-0</a>&nbsp; </td> </tr> </table></td></tr></tbody></table> </details> ___
qodo-code-review[bot] commented 2026-03-01 00:10:58 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2953#issuecomment-3978676772
Original created: 2026-03-01T00:10:58Z

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🟡
🎫 #1872
🟢 Add `telnet` to the `serviceradar-tools` image so the `telnet` command is available.
Fix ping in the serviceradar-tools image by ensuring the required libcap.so.2 dependency
is present (and ping runs without the shared-library relocation errors shown).
Update the build system/image definition to include any additional Alpine packages
required to support the above tooling.
Confirm in a built/published serviceradar-tools image that telnet executes successfully
and ping runs without libcap.so.2 errors (runtime verification in the container).
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
- Requires Further Human Verification
🏷️ - Compliance label
Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2953#issuecomment-3978676772 Original created: 2026-03-01T00:10:58Z --- ## PR Compliance Guide 🔍 <!-- https://github.com/carverauto/serviceradar/commit/1353d93506f94e014c570738b79fbe9837e7fb08 --> Below is a summary of compliance checks for this PR:<br> <table><tbody><tr><td colspan='2'><strong>Security Compliance</strong></td></tr> <tr><td>🟢</td><td><details><summary><strong>No security concerns identified</strong></summary> No security vulnerabilities detected by AI analysis. Human verification advised for critical code. </details></td></tr> <tr><td colspan='2'><strong>Ticket Compliance</strong></td></tr> <tr><td>🟡</td> <td> <details> <summary>🎫 <a href=https://github.com/carverauto/serviceradar/issues/1872>#1872</a></summary> <table width='100%'><tbody> <tr><td rowspan=3>🟢</td> <td>Add `telnet` to the `serviceradar-tools` image so the `telnet` command is available. </td></tr> <tr><td>Fix <code>ping</code> in the <code>serviceradar-tools</code> image by ensuring the required <code>libcap.so.2</code> dependency <br>is present (and <code>ping</code> runs without the shared-library relocation errors shown).<br></td></tr> <tr><td>Update the build system/image definition to include any additional Alpine packages <br>required to support the above tooling.<br></td></tr> <tr><td rowspan=1>⚪</td> <td>Confirm in a built/published <code>serviceradar-tools</code> image that <code>telnet</code> executes successfully <br>and <code>ping</code> runs without <code>libcap.so.2</code> errors (runtime verification in the container).<br></td></tr> </tbody></table> </details> </td></tr> <tr><td colspan='2'><strong>Codebase Duplication Compliance</strong></td></tr> <tr><td>⚪</td><td><details><summary><strong>Codebase context is not defined </strong></summary> Follow the <a href='https://qodo-merge-docs.qodo.ai/core-abilities/rag_context_enrichment/'>guide</a> to enable codebase context checks. </details></td></tr> <tr><td colspan='2'><strong>Custom Compliance</strong></td></tr> <tr><td rowspan=6>🟢</td><td> <details><summary><strong>Generic: Comprehensive Audit Trails</strong></summary><br> **Objective:** To create a detailed and reliable record of critical system actions for security analysis <br>and compliance.<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Meaningful Naming and Self-Documenting Code</strong></summary><br> **Objective:** Ensure all identifiers clearly express their purpose and intent, making code <br>self-documenting<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Robust Error Handling and Edge Case Management</strong></summary><br> **Objective:** Ensure comprehensive error handling that provides meaningful context and graceful <br>degradation<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Secure Error Handling</strong></summary><br> **Objective:** To prevent the leakage of sensitive system information through error messages while <br>providing sufficient detail for internal debugging.<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Secure Logging Practices</strong></summary><br> **Objective:** To ensure logs are useful for debugging and auditing without exposing sensitive <br>information like PII, PHI, or cardholder data.<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td> <details><summary><strong>Generic: Security-First Input Validation and Data Handling</strong></summary><br> **Objective:** Ensure all data inputs are validated, sanitized, and handled securely to prevent <br>vulnerabilities<br> **Status:** Passed<br> > Learn more about managing compliance <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#configuration-options'>generic rules</a> or creating your own <a href='https://qodo-merge-docs.qodo.ai/tools/compliance/#custom-compliance'>custom rules</a> </details></td></tr> <tr><td align="center" colspan="2"> - [ ] Update <!-- /compliance --update_compliance=true --> </td></tr></tbody></table> <details><summary>Compliance status legend</summary> 🟢 - Fully Compliant<br> 🟡 - Partial Compliant<br> 🔴 - Not Compliant<br> ⚪ - Requires Further Human Verification<br> 🏷️ - Compliance label<br> </details>
qodo-code-review[bot] commented 2026-03-01 00:12:07 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2953#issuecomment-3978678732
Original created: 2026-03-01T00:12:07Z

PR Code Suggestions

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Refactor duplicated logic into a macro
Suggestion Impact:The four duplicated genrule definitions were removed and replaced by calls to a loaded macro (apk_rootfs_amd64), consolidating the shared shell logic into a single reusable definition.

code diff:

+load("//docker/images:apk.bzl", "apk_rootfs_amd64")
 load("//docker/images:push_targets.bzl", "declare_ghcr_push_targets")
 
 exports_files([
@@ -146,136 +147,24 @@
 """,
 )
 
-genrule(
-    name = "apk_inetutils_telnet_rootfs_amd64",
-    srcs = ["@alpine_inetutils_telnet_apk//file"],
-    outs = ["apk_inetutils_telnet_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_inetutils_telnet_apk//file)
-TMP=$(@D)/inetutils_telnet_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libcap2_rootfs_amd64",
-    srcs = ["@alpine_libcap2_apk//file"],
-    outs = ["apk_libcap2_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libcap2_apk//file)
-TMP=$(@D)/libcap2_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libbsd_rootfs_amd64",
-    srcs = ["@alpine_libbsd_apk//file"],
-    outs = ["apk_libbsd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libbsd_apk//file)
-TMP=$(@D)/libbsd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libmd_rootfs_amd64",
-    srcs = ["@alpine_libmd_apk//file"],
-    outs = ["apk_libmd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libmd_apk//file)
-TMP=$(@D)/libmd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
+apk_rootfs_amd64(
+    name = "inetutils_telnet",
+    apk_target = "@alpine_inetutils_telnet_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libcap2",
+    apk_target = "@alpine_libcap2_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libbsd",
+    apk_target = "@alpine_libbsd_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libmd",
+    apk_target = "@alpine_libmd_apk//file",
 )

Refactor the four new genrule targets into a single Bazel macro to eliminate
duplicated shell script logic and improve maintainability.

docker/images/BUILD.bazel [149-279]

-genrule(
-    name = "apk_inetutils_telnet_rootfs_amd64",
-    srcs = ["@alpine_inetutils_telnet_apk//file"],
-    outs = ["apk_inetutils_telnet_rootfs_amd64.tar"],
-    cmd = """
+# In a new file, e.g., docker/images/apk.bzl
+def apk_rootfs(name, apk_target):
+    """Generates a rule to extract an apk and create a rootfs tarball."""
+    genrule(
+        name = "apk_{}_rootfs_amd64".format(name),
+        srcs = [apk_target],
+        outs = ["apk_{}_rootfs_amd64.tar".format(name)],
+        cmd = """
 set -euo pipefail
-APK=$(location @alpine_inetutils_telnet_apk//file)
-TMP=$(@D)/inetutils_telnet_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
+APK=$(location {apk_target})
+TMP=$(@D)/{name}_extract
+rm -rf "$${{TMP}}"
+mkdir -p "$${{TMP}}/extracted" "$${{TMP}}/rootfs"
+tar -xzf "$${{APK}}" -C "$${{TMP}}/extracted"
+DATA_TAR=`find "$${{TMP}}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
+if [ -n "$${{DATA_TAR}}" ]; then
+  case "$${{DATA_TAR}}" in
+    *.gz) tar -xzf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;;
+    *.xz) tar -xJf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;;
+    *.bz2) tar -xjf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;;
+    *) tar -xf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;;
   esac
 else
   shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
+  for entry in "$${{TMP}}/extracted"/*; do
+    base=`basename "$${{entry}}"`
+    case "$${{base}}" in
       .SIGN*|.PKGINFO) continue ;;
     esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
+    cp -a "$${{entry}}" "$${{TMP}}/rootfs/"
   done
 fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
+tar -czf "$@" -C "$${{TMP}}/rootfs" .
+""".format(name = name, apk_target = apk_target),
+    )
+
+# In docker/images/BUILD.bazel
+# load("//docker/images:apk.bzl", "apk_rootfs")
+
+apk_rootfs(
+    name = "inetutils_telnet",
+    apk_target = "@alpine_inetutils_telnet_apk//file",
 )
 
-genrule(
-    name = "apk_libcap2_rootfs_amd64",
-    srcs = ["@alpine_libcap2_apk//file"],
-    outs = ["apk_libcap2_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libcap2_apk//file)
-TMP=$(@D)/libcap2_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
+apk_rootfs(
+    name = "libcap2",
+    apk_target = "@alpine_libcap2_apk//file",
 )
 
-genrule(
-    name = "apk_libbsd_rootfs_amd64",
-    srcs = ["@alpine_libbsd_apk//file"],
-    outs = ["apk_libbsd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libbsd_apk//file)
-TMP=$(@D)/libbsd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
+apk_rootfs(
+    name = "libbsd",
+    apk_target = "@alpine_libbsd_apk//file",
 )
 
-genrule(
-    name = "apk_libmd_rootfs_amd64",
-    srcs = ["@alpine_libmd_apk//file"],
-    outs = ["apk_libmd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libmd_apk//file)
-TMP=$(@D)/libmd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
+apk_rootfs(
+    name = "libmd",
+    apk_target = "@alpine_libmd_apk//file",
 )

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies significant code duplication in the newly added genrule targets and proposes an idiomatic Bazel solution by refactoring the logic into a macro, which greatly improves maintainability.

Medium
Unify tar extraction call
Suggestion Impact:The commit removed the duplicated genrule shell scripts containing the tar-extension case statement entirely, replacing them with a shared apk_rootfs_amd64 macro, thereby eliminating the need for the multi-branch tar extraction logic the suggestion targeted (though not by introducing the specific tar --auto-compress line in this diff).

code diff:

-genrule(
-    name = "apk_inetutils_telnet_rootfs_amd64",
-    srcs = ["@alpine_inetutils_telnet_apk//file"],
-    outs = ["apk_inetutils_telnet_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_inetutils_telnet_apk//file)
-TMP=$(@D)/inetutils_telnet_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libcap2_rootfs_amd64",
-    srcs = ["@alpine_libcap2_apk//file"],
-    outs = ["apk_libcap2_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libcap2_apk//file)
-TMP=$(@D)/libcap2_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libbsd_rootfs_amd64",
-    srcs = ["@alpine_libbsd_apk//file"],
-    outs = ["apk_libbsd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libbsd_apk//file)
-TMP=$(@D)/libbsd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libmd_rootfs_amd64",
-    srcs = ["@alpine_libmd_apk//file"],
-    outs = ["apk_libmd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libmd_apk//file)
-TMP=$(@D)/libmd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
+apk_rootfs_amd64(
+    name = "inetutils_telnet",
+    apk_target = "@alpine_inetutils_telnet_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libcap2",
+    apk_target = "@alpine_libcap2_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libbsd",
+    apk_target = "@alpine_libbsd_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libmd",
+    apk_target = "@alpine_libmd_apk//file",
 )

Replace the case statement for tar extraction with a single tar --auto-compress
command to simplify the logic.

docker/images/BUILD.bazel [162-167]

-case "$${DATA_TAR}" in
-  *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  *)    tar -xf   "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-esac
+tar --no-same-owner --auto-compress -xf "$${DATA_TAR}" -C "$${TMP}/rootfs"

[Suggestion processed]

Suggestion importance[1-10]: 5

__

Why: This is a good suggestion that simplifies the shell script by replacing a multi-branch case statement with a single tar command using --auto-compress, making the code more concise and easier to maintain.

Low
Replace backticks with $(…)
Suggestion Impact:The commit removed the genrule shell snippets that contained backtick command substitutions (including the DATA_TAR assignment) by refactoring them into apk_rootfs_amd64 macro calls, thereby eliminating the backtick usage rather than directly converting it to $(...).

code diff:

-genrule(
-    name = "apk_inetutils_telnet_rootfs_amd64",
-    srcs = ["@alpine_inetutils_telnet_apk//file"],
-    outs = ["apk_inetutils_telnet_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_inetutils_telnet_apk//file)
-TMP=$(@D)/inetutils_telnet_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libcap2_rootfs_amd64",
-    srcs = ["@alpine_libcap2_apk//file"],
-    outs = ["apk_libcap2_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libcap2_apk//file)
-TMP=$(@D)/libcap2_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libbsd_rootfs_amd64",
-    srcs = ["@alpine_libbsd_apk//file"],
-    outs = ["apk_libbsd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libbsd_apk//file)
-TMP=$(@D)/libbsd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
-)
-
-genrule(
-    name = "apk_libmd_rootfs_amd64",
-    srcs = ["@alpine_libmd_apk//file"],
-    outs = ["apk_libmd_rootfs_amd64.tar"],
-    cmd = """
-set -euo pipefail
-APK=$(location @alpine_libmd_apk//file)
-TMP=$(@D)/libmd_extract
-rm -rf "$${TMP}"
-mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs"
-tar -xzf "$${APK}" -C "$${TMP}/extracted"
-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
-if [ -n "$${DATA_TAR}" ]; then
-  case "$${DATA_TAR}" in
-    *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-    *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;;
-  esac
-else
-  shopt -s nullglob
-  for entry in "$${TMP}/extracted"/*; do
-    base=`basename "$${entry}"`
-    case "$${base}" in
-      .SIGN*|.PKGINFO) continue ;;
-    esac
-    cp -a "$${entry}" "$${TMP}/rootfs/"
-  done
-fi
-tar -czf "$@" -C "$${TMP}/rootfs" .
-""",
+apk_rootfs_amd64(
+    name = "inetutils_telnet",
+    apk_target = "@alpine_inetutils_telnet_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libcap2",
+    apk_target = "@alpine_libcap2_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libbsd",
+    apk_target = "@alpine_libbsd_apk//file",
+)
+
+apk_rootfs_amd64(
+    name = "libmd",
+    apk_target = "@alpine_libmd_apk//file",
 )

Replace backticks ( ... ) with the modern $(...) syntax for command substitution
in the shell script.

docker/images/BUILD.bazel [160]

-DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit`
+DATA_TAR=$(find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit)

[Suggestion processed]

Suggestion importance[1-10]: 3

__

Why: The suggestion correctly points out that using $(...) is preferred over backticks for command substitution, which is a good practice for shell script readability and robustness, although it is a minor style improvement.

Low
  • Update
Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2953#issuecomment-3978678732 Original created: 2026-03-01T00:12:07Z --- ## PR Code Suggestions ✨ <!-- 1353d93 --> Explore these optional code suggestions: <table><thead><tr><td><strong>Category</strong></td><td align=left><strong>Suggestion&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </strong></td><td align=center><strong>Impact</strong></td></tr><tbody><tr><td rowspan=3>General</td> <td> <details><summary>✅ <s>Refactor duplicated logic into a macro</s></summary> ___ <details><summary><b>Suggestion Impact:</b></summary>The four duplicated genrule definitions were removed and replaced by calls to a loaded macro (apk_rootfs_amd64), consolidating the shared shell logic into a single reusable definition. code diff: ```diff +load("//docker/images:apk.bzl", "apk_rootfs_amd64") load("//docker/images:push_targets.bzl", "declare_ghcr_push_targets") exports_files([ @@ -146,136 +147,24 @@ """, ) -genrule( - name = "apk_inetutils_telnet_rootfs_amd64", - srcs = ["@alpine_inetutils_telnet_apk//file"], - outs = ["apk_inetutils_telnet_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_inetutils_telnet_apk//file) -TMP=$(@D)/inetutils_telnet_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libcap2_rootfs_amd64", - srcs = ["@alpine_libcap2_apk//file"], - outs = ["apk_libcap2_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libcap2_apk//file) -TMP=$(@D)/libcap2_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libbsd_rootfs_amd64", - srcs = ["@alpine_libbsd_apk//file"], - outs = ["apk_libbsd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libbsd_apk//file) -TMP=$(@D)/libbsd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libmd_rootfs_amd64", - srcs = ["@alpine_libmd_apk//file"], - outs = ["apk_libmd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libmd_apk//file) -TMP=$(@D)/libmd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", +apk_rootfs_amd64( + name = "inetutils_telnet", + apk_target = "@alpine_inetutils_telnet_apk//file", +) + +apk_rootfs_amd64( + name = "libcap2", + apk_target = "@alpine_libcap2_apk//file", +) + +apk_rootfs_amd64( + name = "libbsd", + apk_target = "@alpine_libbsd_apk//file", +) + +apk_rootfs_amd64( + name = "libmd", + apk_target = "@alpine_libmd_apk//file", ) ``` </details> ___ **Refactor the four new <code>genrule</code> targets into a single Bazel macro to eliminate <br>duplicated shell script logic and improve maintainability.** [docker/images/BUILD.bazel [149-279]](https://github.com/carverauto/serviceradar/pull/2953/files#diff-0e4db31c224a8f72ae8e870a849e38a59d74a2c7f7b04347b0b3eb07e20c5a80R149-R279) ```diff -genrule( - name = "apk_inetutils_telnet_rootfs_amd64", - srcs = ["@alpine_inetutils_telnet_apk//file"], - outs = ["apk_inetutils_telnet_rootfs_amd64.tar"], - cmd = """ +# In a new file, e.g., docker/images/apk.bzl +def apk_rootfs(name, apk_target): + """Generates a rule to extract an apk and create a rootfs tarball.""" + genrule( + name = "apk_{}_rootfs_amd64".format(name), + srcs = [apk_target], + outs = ["apk_{}_rootfs_amd64.tar".format(name)], + cmd = """ set -euo pipefail -APK=$(location @alpine_inetutils_telnet_apk//file) -TMP=$(@D)/inetutils_telnet_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; +APK=$(location {apk_target}) +TMP=$(@D)/{name}_extract +rm -rf "$${{TMP}}" +mkdir -p "$${{TMP}}/extracted" "$${{TMP}}/rootfs" +tar -xzf "$${{APK}}" -C "$${{TMP}}/extracted" +DATA_TAR=`find "$${{TMP}}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` +if [ -n "$${{DATA_TAR}}" ]; then + case "$${{DATA_TAR}}" in + *.gz) tar -xzf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;; + *.xz) tar -xJf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;; + *.bz2) tar -xjf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;; + *) tar -xf "$${{DATA_TAR}}" -C "$${{TMP}}/rootfs" ;; esac else shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in + for entry in "$${{TMP}}/extracted"/*; do + base=`basename "$${{entry}}"` + case "$${{base}}" in .SIGN*|.PKGINFO) continue ;; esac - cp -a "$${entry}" "$${TMP}/rootfs/" + cp -a "$${{entry}}" "$${{TMP}}/rootfs/" done fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", +tar -czf "$@" -C "$${{TMP}}/rootfs" . +""".format(name = name, apk_target = apk_target), + ) + +# In docker/images/BUILD.bazel +# load("//docker/images:apk.bzl", "apk_rootfs") + +apk_rootfs( + name = "inetutils_telnet", + apk_target = "@alpine_inetutils_telnet_apk//file", ) -genrule( - name = "apk_libcap2_rootfs_amd64", - srcs = ["@alpine_libcap2_apk//file"], - outs = ["apk_libcap2_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libcap2_apk//file) -TMP=$(@D)/libcap2_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", +apk_rootfs( + name = "libcap2", + apk_target = "@alpine_libcap2_apk//file", ) -genrule( - name = "apk_libbsd_rootfs_amd64", - srcs = ["@alpine_libbsd_apk//file"], - outs = ["apk_libbsd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libbsd_apk//file) -TMP=$(@D)/libbsd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", +apk_rootfs( + name = "libbsd", + apk_target = "@alpine_libbsd_apk//file", ) -genrule( - name = "apk_libmd_rootfs_amd64", - srcs = ["@alpine_libmd_apk//file"], - outs = ["apk_libmd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libmd_apk//file) -TMP=$(@D)/libmd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", +apk_rootfs( + name = "libmd", + apk_target = "@alpine_libmd_apk//file", ) ``` `[Suggestion processed]` <details><summary>Suggestion importance[1-10]: 7</summary> __ Why: The suggestion correctly identifies significant code duplication in the newly added `genrule` targets and proposes an idiomatic Bazel solution by refactoring the logic into a macro, which greatly improves maintainability. </details></details></td><td align=center>Medium </td></tr><tr><td> <details><summary>✅ <s>Unify tar extraction call</s></summary> ___ <details><summary><b>Suggestion Impact:</b></summary>The commit removed the duplicated genrule shell scripts containing the tar-extension case statement entirely, replacing them with a shared apk_rootfs_amd64 macro, thereby eliminating the need for the multi-branch tar extraction logic the suggestion targeted (though not by introducing the specific tar --auto-compress line in this diff). code diff: ```diff -genrule( - name = "apk_inetutils_telnet_rootfs_amd64", - srcs = ["@alpine_inetutils_telnet_apk//file"], - outs = ["apk_inetutils_telnet_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_inetutils_telnet_apk//file) -TMP=$(@D)/inetutils_telnet_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libcap2_rootfs_amd64", - srcs = ["@alpine_libcap2_apk//file"], - outs = ["apk_libcap2_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libcap2_apk//file) -TMP=$(@D)/libcap2_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libbsd_rootfs_amd64", - srcs = ["@alpine_libbsd_apk//file"], - outs = ["apk_libbsd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libbsd_apk//file) -TMP=$(@D)/libbsd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libmd_rootfs_amd64", - srcs = ["@alpine_libmd_apk//file"], - outs = ["apk_libmd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libmd_apk//file) -TMP=$(@D)/libmd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", +apk_rootfs_amd64( + name = "inetutils_telnet", + apk_target = "@alpine_inetutils_telnet_apk//file", +) + +apk_rootfs_amd64( + name = "libcap2", + apk_target = "@alpine_libcap2_apk//file", +) + +apk_rootfs_amd64( + name = "libbsd", + apk_target = "@alpine_libbsd_apk//file", +) + +apk_rootfs_amd64( + name = "libmd", + apk_target = "@alpine_libmd_apk//file", ) ``` </details> ___ **Replace the <code>case</code> statement for <code>tar</code> extraction with a single <code>tar --auto-compress</code> <br>command to simplify the logic.** [docker/images/BUILD.bazel [162-167]](https://github.com/carverauto/serviceradar/pull/2953/files#diff-0e4db31c224a8f72ae8e870a849e38a59d74a2c7f7b04347b0b3eb07e20c5a80R162-R167) ```diff -case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; -esac +tar --no-same-owner --auto-compress -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ``` `[Suggestion processed]` <details><summary>Suggestion importance[1-10]: 5</summary> __ Why: This is a good suggestion that simplifies the shell script by replacing a multi-branch `case` statement with a single `tar` command using `--auto-compress`, making the code more concise and easier to maintain. </details></details></td><td align=center>Low </td></tr><tr><td> <details><summary>✅ <s>Replace backticks with $(…)<!-- not_implemented --></s></summary> ___ <details><summary><b>Suggestion Impact:</b></summary>The commit removed the genrule shell snippets that contained backtick command substitutions (including the DATA_TAR assignment) by refactoring them into apk_rootfs_amd64 macro calls, thereby eliminating the backtick usage rather than directly converting it to $(...). code diff: ```diff -genrule( - name = "apk_inetutils_telnet_rootfs_amd64", - srcs = ["@alpine_inetutils_telnet_apk//file"], - outs = ["apk_inetutils_telnet_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_inetutils_telnet_apk//file) -TMP=$(@D)/inetutils_telnet_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libcap2_rootfs_amd64", - srcs = ["@alpine_libcap2_apk//file"], - outs = ["apk_libcap2_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libcap2_apk//file) -TMP=$(@D)/libcap2_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libbsd_rootfs_amd64", - srcs = ["@alpine_libbsd_apk//file"], - outs = ["apk_libbsd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libbsd_apk//file) -TMP=$(@D)/libbsd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", -) - -genrule( - name = "apk_libmd_rootfs_amd64", - srcs = ["@alpine_libmd_apk//file"], - outs = ["apk_libmd_rootfs_amd64.tar"], - cmd = """ -set -euo pipefail -APK=$(location @alpine_libmd_apk//file) -TMP=$(@D)/libmd_extract -rm -rf "$${TMP}" -mkdir -p "$${TMP}/extracted" "$${TMP}/rootfs" -tar -xzf "$${APK}" -C "$${TMP}/extracted" -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` -if [ -n "$${DATA_TAR}" ]; then - case "$${DATA_TAR}" in - *.gz) tar -xzf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.xz) tar -xJf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *.bz2) tar -xjf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - *) tar -xf "$${DATA_TAR}" -C "$${TMP}/rootfs" ;; - esac -else - shopt -s nullglob - for entry in "$${TMP}/extracted"/*; do - base=`basename "$${entry}"` - case "$${base}" in - .SIGN*|.PKGINFO) continue ;; - esac - cp -a "$${entry}" "$${TMP}/rootfs/" - done -fi -tar -czf "$@" -C "$${TMP}/rootfs" . -""", +apk_rootfs_amd64( + name = "inetutils_telnet", + apk_target = "@alpine_inetutils_telnet_apk//file", +) + +apk_rootfs_amd64( + name = "libcap2", + apk_target = "@alpine_libcap2_apk//file", +) + +apk_rootfs_amd64( + name = "libbsd", + apk_target = "@alpine_libbsd_apk//file", +) + +apk_rootfs_amd64( + name = "libmd", + apk_target = "@alpine_libmd_apk//file", ) ``` </details> ___ **Replace backticks (<code></code> <code>...</code> <code></code>) with the modern <code>$(...)</code> syntax for command substitution <br>in the shell script.** [docker/images/BUILD.bazel [160]](https://github.com/carverauto/serviceradar/pull/2953/files#diff-0e4db31c224a8f72ae8e870a849e38a59d74a2c7f7b04347b0b3eb07e20c5a80R160-R160) ```diff -DATA_TAR=`find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit` +DATA_TAR=$(find "$${TMP}/extracted" -maxdepth 1 -type f -name 'data.tar.*' -print -quit) ``` `[Suggestion processed]` <details><summary>Suggestion importance[1-10]: 3</summary> __ Why: The suggestion correctly points out that using `$(...)` is preferred over backticks for command substitution, which is a good practice for shell script readability and robustness, although it is a minor style improvement. </details></details></td><td align=center>Low </td></tr> <tr><td align="center" colspan="2"> - [ ] Update <!-- /improve_multi --more_suggestions=true --> </td><td></td></tr></tbody></table>
qodo-code-review[bot] commented 2026-03-01 00:30:09 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2953#issuecomment-3978707969
Original created: 2026-03-01T00:30:09Z

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: build

Failed stage: Configure SRQL fixture database for tests []

Failed test name: ""

Failure summary:

The action failed because a required secret/environment variable for the test/fixture setup was
missing:
- The job explicitly exited with: SRQL_TEST_DATABASE_CA_CERT secret must be configured to
verify SRQL fixture TLS. followed by Process completed with exit code 1. (around lines 707-708).
-
In the environment, SRQL_TEST_DATABASE_CA_CERT is shown as empty, so the workflow halted before
running further steps.

An additional issue occurred during post-job cleanup:
- fatal: No url found for submodule path
'swift/FieldSurvey/LocalPackages/arrow-swift' in .gitmodules caused a git command in cleanup to exit
128 (lines 718-719), but the primary job failure is the missing SRQL_TEST_DATABASE_CA_CERT.

Relevant error logs:
1:  Runner name: 'arc-runner-set-hk6mk-runner-6j94f'
2:  Runner group name: 'Default'
...

139:  ^[[36;1mif command -v apt-get >/dev/null 2>&1; then^[[0m
140:  ^[[36;1m  sudo apt-get update^[[0m
141:  ^[[36;1m  sudo apt-get install -y build-essential pkg-config libssl-dev protobuf-compiler cmake flex bison^[[0m
142:  ^[[36;1melif command -v dnf >/dev/null 2>&1; then^[[0m
143:  ^[[36;1m  sudo dnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m
144:  ^[[36;1melif command -v yum >/dev/null 2>&1; then^[[0m
145:  ^[[36;1m  sudo yum install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m
146:  ^[[36;1melif command -v microdnf >/dev/null 2>&1; then^[[0m
147:  ^[[36;1m  sudo microdnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m
148:  ^[[36;1melse^[[0m
149:  ^[[36;1m  echo "Unsupported package manager; please install gcc, g++ (or clang), make, OpenSSL headers, pkg-config, and protoc manually." >&2^[[0m
150:  ^[[36;1m  exit 1^[[0m
151:  ^[[36;1mfi^[[0m
152:  ^[[36;1m^[[0m
153:  ^[[36;1mensure_pkg_config^[[0m
154:  ^[[36;1mprotoc --version || (echo "protoc installation failed" && exit 1)^[[0m
155:  shell: /usr/bin/bash -e {0}
...

387:  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
388:  env:
389:  BUILDBUDDY_ORG_API_KEY: ***
390:  SRQL_TEST_DATABASE_URL: ***
391:  SRQL_TEST_ADMIN_URL: ***
392:  SRQL_TEST_DATABASE_CA_CERT: 
393:  DOCKERHUB_USERNAME: ***
394:  DOCKERHUB_TOKEN: ***
395:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
396:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
397:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
398:  ##[endgroup]
399:  ##[group]Run : install rustup if needed
400:  ^[[36;1m: install rustup if needed^[[0m
401:  ^[[36;1mif ! command -v rustup &>/dev/null; then^[[0m
402:  ^[[36;1m  curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://sh.rustup.rs | sh -s -- --default-toolchain none -y^[[0m
403:  ^[[36;1m  echo "$CARGO_HOME/bin" >> $GITHUB_PATH^[[0m
...

543:  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
544:  env:
545:  BUILDBUDDY_ORG_API_KEY: ***
546:  SRQL_TEST_DATABASE_URL: ***
547:  SRQL_TEST_ADMIN_URL: ***
548:  SRQL_TEST_DATABASE_CA_CERT: 
549:  DOCKERHUB_USERNAME: ***
550:  DOCKERHUB_TOKEN: ***
551:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
552:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
553:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
554:  CARGO_HOME: /home/runner/.cargo
555:  CARGO_INCREMENTAL: 0
556:  CARGO_TERM_COLOR: always
557:  ##[endgroup]
558:  ##[group]Run : work around spurious network errors in curl 8.0
559:  ^[[36;1m: work around spurious network errors in curl 8.0^[[0m
560:  ^[[36;1m# https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/timeout.20investigation^[[0m
...

611:  SRQL_TEST_DATABASE_CA_CERT: 
612:  DOCKERHUB_USERNAME: ***
613:  DOCKERHUB_TOKEN: ***
614:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
615:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
616:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
617:  CARGO_HOME: /home/runner/.cargo
618:  CARGO_INCREMENTAL: 0
619:  CARGO_TERM_COLOR: always
620:  ##[endgroup]
621:  Attempting to download 1.x...
622:  Acquiring v1.28.1 from https://github.com/bazelbuild/bazelisk/releases/download/v1.28.1/bazelisk-linux-amd64
623:  Adding to the cache ...
624:  Successfully cached bazelisk to /home/runner/_work/_tool/bazelisk/1.28.1/x64
625:  Added bazelisk to the path
626:  ##[warning]Failed to restore: Cache service responded with 400
627:  Restored bazelisk cache dir @ /home/runner/.cache/bazelisk
...

693:  env:
694:  BUILDBUDDY_ORG_API_KEY: ***
695:  SRQL_TEST_DATABASE_URL: ***
696:  SRQL_TEST_ADMIN_URL: ***
697:  SRQL_TEST_DATABASE_CA_CERT: 
698:  DOCKERHUB_USERNAME: ***
699:  DOCKERHUB_TOKEN: ***
700:  TEST_CNPG_DATABASE: serviceradar_web_ng_test
701:  INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp
702:  INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir
703:  CARGO_HOME: /home/runner/.cargo
704:  CARGO_INCREMENTAL: 0
705:  CARGO_TERM_COLOR: always
706:  ##[endgroup]
707:  SRQL_TEST_DATABASE_CA_CERT secret must be configured to verify SRQL fixture TLS.
708:  ##[error]Process completed with exit code 1.
709:  Post job cleanup.
710:  [command]/usr/bin/git version
711:  git version 2.52.0
712:  Temporarily overriding HOME='/home/runner/_work/_temp/599534ff-d376-4ec9-a72f-41b952f91f34' before making global git config changes
713:  Adding repository directory to the temporary git global config as a safe directory
714:  [command]/usr/bin/git config --global --add safe.directory /home/runner/_work/serviceradar/serviceradar
715:  Removing SSH command configuration
716:  [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand
717:  [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
718:  fatal: No url found for submodule path 'swift/FieldSurvey/LocalPackages/arrow-swift' in .gitmodules
719:  ##[warning]The process '/usr/bin/git' failed with exit code 128
720:  Cleaning up orphan processes

Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2953#issuecomment-3978707969 Original created: 2026-03-01T00:30:09Z --- ## CI Feedback 🧐 A test triggered by this PR failed. Here is an AI-generated analysis of the failure: <table><tr><td> **Action:** build</td></tr> <tr><td> **Failed stage:** [Configure SRQL fixture database for tests](https://github.com/carverauto/serviceradar/actions/runs/22532300047/job/65273507223) [❌] </td></tr> <tr><td> **Failed test name:** "" </td></tr> <tr><td> **Failure summary:** The action failed because a required secret/environment variable for the test/fixture setup was <br>missing:<br> - The job explicitly exited with: <code>SRQL_TEST_DATABASE_CA_CERT secret must be configured to </code><br><code>verify SRQL fixture TLS.</code> followed by <code>Process completed with exit code 1.</code> (around lines 707-708).<br> - <br>In the environment, <code>SRQL_TEST_DATABASE_CA_CERT</code> is shown as empty, so the workflow halted before <br>running further steps.<br> <br> An additional issue occurred during post-job cleanup:<br> - <code>fatal: No url found for submodule path </code><br><code>'swift/FieldSurvey/LocalPackages/arrow-swift' in .gitmodules</code> caused a git command in cleanup to exit <br>128 (lines 718-719), but the primary job failure is the missing <code>SRQL_TEST_DATABASE_CA_CERT</code>.<br> </td></tr> <tr><td> <details><summary>Relevant error logs:</summary> ```yaml 1: Runner name: 'arc-runner-set-hk6mk-runner-6j94f' 2: Runner group name: 'Default' ... 139: ^[[36;1mif command -v apt-get >/dev/null 2>&1; then^[[0m 140: ^[[36;1m sudo apt-get update^[[0m 141: ^[[36;1m sudo apt-get install -y build-essential pkg-config libssl-dev protobuf-compiler cmake flex bison^[[0m 142: ^[[36;1melif command -v dnf >/dev/null 2>&1; then^[[0m 143: ^[[36;1m sudo dnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m 144: ^[[36;1melif command -v yum >/dev/null 2>&1; then^[[0m 145: ^[[36;1m sudo yum install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m 146: ^[[36;1melif command -v microdnf >/dev/null 2>&1; then^[[0m 147: ^[[36;1m sudo microdnf install -y gcc gcc-c++ make openssl-devel protobuf-compiler cmake flex bison^[[0m 148: ^[[36;1melse^[[0m 149: ^[[36;1m echo "Unsupported package manager; please install gcc, g++ (or clang), make, OpenSSL headers, pkg-config, and protoc manually." >&2^[[0m 150: ^[[36;1m exit 1^[[0m 151: ^[[36;1mfi^[[0m 152: ^[[36;1m^[[0m 153: ^[[36;1mensure_pkg_config^[[0m 154: ^[[36;1mprotoc --version || (echo "protoc installation failed" && exit 1)^[[0m 155: shell: /usr/bin/bash -e {0} ... 387: shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} 388: env: 389: BUILDBUDDY_ORG_API_KEY: *** 390: SRQL_TEST_DATABASE_URL: *** 391: SRQL_TEST_ADMIN_URL: *** 392: SRQL_TEST_DATABASE_CA_CERT: 393: DOCKERHUB_USERNAME: *** 394: DOCKERHUB_TOKEN: *** 395: TEST_CNPG_DATABASE: serviceradar_web_ng_test 396: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 397: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 398: ##[endgroup] 399: ##[group]Run : install rustup if needed 400: ^[[36;1m: install rustup if needed^[[0m 401: ^[[36;1mif ! command -v rustup &>/dev/null; then^[[0m 402: ^[[36;1m curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://sh.rustup.rs | sh -s -- --default-toolchain none -y^[[0m 403: ^[[36;1m echo "$CARGO_HOME/bin" >> $GITHUB_PATH^[[0m ... 543: shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0} 544: env: 545: BUILDBUDDY_ORG_API_KEY: *** 546: SRQL_TEST_DATABASE_URL: *** 547: SRQL_TEST_ADMIN_URL: *** 548: SRQL_TEST_DATABASE_CA_CERT: 549: DOCKERHUB_USERNAME: *** 550: DOCKERHUB_TOKEN: *** 551: TEST_CNPG_DATABASE: serviceradar_web_ng_test 552: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 553: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 554: CARGO_HOME: /home/runner/.cargo 555: CARGO_INCREMENTAL: 0 556: CARGO_TERM_COLOR: always 557: ##[endgroup] 558: ##[group]Run : work around spurious network errors in curl 8.0 559: ^[[36;1m: work around spurious network errors in curl 8.0^[[0m 560: ^[[36;1m# https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/timeout.20investigation^[[0m ... 611: SRQL_TEST_DATABASE_CA_CERT: 612: DOCKERHUB_USERNAME: *** 613: DOCKERHUB_TOKEN: *** 614: TEST_CNPG_DATABASE: serviceradar_web_ng_test 615: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 616: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 617: CARGO_HOME: /home/runner/.cargo 618: CARGO_INCREMENTAL: 0 619: CARGO_TERM_COLOR: always 620: ##[endgroup] 621: Attempting to download 1.x... 622: Acquiring v1.28.1 from https://github.com/bazelbuild/bazelisk/releases/download/v1.28.1/bazelisk-linux-amd64 623: Adding to the cache ... 624: Successfully cached bazelisk to /home/runner/_work/_tool/bazelisk/1.28.1/x64 625: Added bazelisk to the path 626: ##[warning]Failed to restore: Cache service responded with 400 627: Restored bazelisk cache dir @ /home/runner/.cache/bazelisk ... 693: env: 694: BUILDBUDDY_ORG_API_KEY: *** 695: SRQL_TEST_DATABASE_URL: *** 696: SRQL_TEST_ADMIN_URL: *** 697: SRQL_TEST_DATABASE_CA_CERT: 698: DOCKERHUB_USERNAME: *** 699: DOCKERHUB_TOKEN: *** 700: TEST_CNPG_DATABASE: serviceradar_web_ng_test 701: INSTALL_DIR_FOR_OTP: /home/runner/_work/_temp/.setup-beam/otp 702: INSTALL_DIR_FOR_ELIXIR: /home/runner/_work/_temp/.setup-beam/elixir 703: CARGO_HOME: /home/runner/.cargo 704: CARGO_INCREMENTAL: 0 705: CARGO_TERM_COLOR: always 706: ##[endgroup] 707: SRQL_TEST_DATABASE_CA_CERT secret must be configured to verify SRQL fixture TLS. 708: ##[error]Process completed with exit code 1. 709: Post job cleanup. 710: [command]/usr/bin/git version 711: git version 2.52.0 712: Temporarily overriding HOME='/home/runner/_work/_temp/599534ff-d376-4ec9-a72f-41b952f91f34' before making global git config changes 713: Adding repository directory to the temporary git global config as a safe directory 714: [command]/usr/bin/git config --global --add safe.directory /home/runner/_work/serviceradar/serviceradar 715: Removing SSH command configuration 716: [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand 717: [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" 718: fatal: No url found for submodule path 'swift/FieldSurvey/LocalPackages/arrow-swift' in .gitmodules 719: ##[warning]The process '/usr/bin/git' failed with exit code 128 720: Cleaning up orphan processes ``` </details></td></tr></table>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
carverauto/serviceradar!2994
No description provided.