Skip to content

fix: resolve libvgpu git metadata path for linked worktree Docker builds - #2042

Closed
pingxin403 wants to merge 2 commits into
Project-HAMi:masterfrom
pingxin403:fix/worktree-docker-build
Closed

fix: resolve libvgpu git metadata path for linked worktree Docker builds#2042
pingxin403 wants to merge 2 commits into
Project-HAMi:masterfrom
pingxin403:fix/worktree-docker-build

Conversation

@pingxin403

@pingxin403 pingxin403 commented Jul 9, 2026

Copy link
Copy Markdown

What does this PR do?

Fixes #2041 — Docker build fails when the repository is a linked git worktree because .git/modules/libvgpu does not exist (in worktrees, .git is a file, not a directory).

Root Cause

The Dockerfile uses COPY .git/modules/libvgpu /libvgpu-git to preserve libvgpu's git metadata for version detection inside the container. In a linked worktree, the repository root .git is a text file pointing to the real gitdir, so .git/modules/libvgpu is not a valid path.

Fix

In hack/build.sh's docker_build() function: detect worktrees via [ -f .git ], use git rev-parse --git-common-dir to find the real modules path, and temporarily create .git/modules/libvgpu for the Docker build context. The .git file is restored on exit via a trap.

Testing

  • ✅ Normal checkout: [ -f .git ] is false, code path skipped — no change in behavior
  • ✅ Linked worktree: verified path resolution logic with git rev-parse --git-common-dir
  • ✅ Cleanup: trap restores .git file on both success and failure

AI Assistance Disclosure

This PR was developed with the assistance of Claude Code (Anthropic) for code generation and debugging. The author reviewed, tested, and takes full responsibility for all changes.

Summary by CodeRabbit

  • Bug Fixes
    • Improved build reliability when the project is checked out using linked Git worktrees, preventing Docker builds from failing due to missing or unexpected repository metadata.
    • Ensures required Git module metadata is correctly available during the Docker build, while keeping the existing build and image-tagging flow unchanged.

@hami-robot

hami-robot Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: pingxin403
Once this PR has been reviewed and has the lgtm label, please assign wawa0210 for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@hami-robot
hami-robot Bot requested review from DSFans2014 and ouyangluwei163 July 9, 2026 11:59
@hami-robot hami-robot Bot added the size/L label Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4cc613c3-d7bf-46e7-81e9-59cd3f08795e

📥 Commits

Reviewing files that changed from the base of the PR and between d1d9274 and 7591a13.

📒 Files selected for processing (1)
  • hack/build.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • hack/build.sh

📝 Walkthrough

Walkthrough

The change modifies docker_build in hack/build.sh to handle linked git worktrees where .git is a file rather than a directory. It backs up .git, sets an EXIT trap for restoration, and copies modules/libvgpu from the git common directory into a temporary .git/modules path before the Docker build runs.

Changes

Docker build worktree workaround

Layer / File(s) Summary
Temporary .git restoration for worktrees
hack/build.sh
docker_build detects a linked worktree .git file, resolves the git common directory, backs up and removes .git, copies modules/libvgpu into a new .git/modules, and restores the original .git via an EXIT trap around the docker build call.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Poem

A rabbit hops through worktree maze,
Where .git hides in file-shaped ways,
I back it up, I trap the exit,
Copy libvgpu, no more deficit,
Build the image, then restore—
Hop, hop, hooray, build once more! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the linked-worktree Docker build fix for libvgpu git metadata.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions github-actions Bot added the kind/bug Something isn't working label Jul 9, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request addresses pod leaks during scheduling failures by introducing a restorePod helper in pkg/scheduler/scheduler.go to restore pod and quota manager states, and adds a corresponding unit test. It also updates hack/build.sh to handle linked git worktrees during Docker builds. The review feedback highlights two critical issues: first, the trap in hack/build.sh should be registered immediately after copying .git to prevent a broken repository state if subsequent setup steps fail; second, if util.PatchPodAnnotations fails, the newly added placement must be explicitly cleaned up before calling restorePod to avoid resource leaks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread hack/build.sh Outdated
Comment on lines +42 to +57
local _restore_git=""
if [ -f .git ]; then
local _git_common
_git_common=$(git rev-parse --git-common-dir 2>/dev/null)
if [ -n "$_git_common" ] && [ -d "$_git_common/modules/libvgpu" ]; then
_restore_git=$(mktemp)
cp .git "$_restore_git"
rm -f .git
mkdir -p .git/modules
cp -r "$_git_common/modules/libvgpu" .git/modules/
fi
fi
if [ -n "$_restore_git" ]; then
# shellcheck disable=SC2064
trap "rm -rf .git && cp '$_restore_git' .git && rm -f '$_restore_git'" EXIT
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

In the current implementation, if any command inside the if [ -f .git ] block fails after .git is deleted (such as mkdir -p .git/modules or cp -r ...), the script will exit immediately due to set -e. Since the trap is registered after the if block, it will never be registered, leaving the repository in a broken state with .git deleted.

Registering the trap immediately after copying .git to the temporary file ensures that the cleanup and restoration are guaranteed to run if any subsequent setup step fails.

Suggested change
local _restore_git=""
if [ -f .git ]; then
local _git_common
_git_common=$(git rev-parse --git-common-dir 2>/dev/null)
if [ -n "$_git_common" ] && [ -d "$_git_common/modules/libvgpu" ]; then
_restore_git=$(mktemp)
cp .git "$_restore_git"
rm -f .git
mkdir -p .git/modules
cp -r "$_git_common/modules/libvgpu" .git/modules/
fi
fi
if [ -n "$_restore_git" ]; then
# shellcheck disable=SC2064
trap "rm -rf .git && cp '$_restore_git' .git && rm -f '$_restore_git'" EXIT
fi
local _restore_git=""
if [ -f .git ]; then
local _git_common
_git_common=$(git rev-parse --git-common-dir 2>/dev/null)
if [ -n "$_git_common" ] && [ -d "$_git_common/modules/libvgpu" ]; then
_restore_git=$(mktemp)
cp .git "$_restore_git"
# shellcheck disable=SC2064
trap "rm -rf .git && cp '$_restore_git' .git && rm -f '$_restore_git'" EXIT
rm -f .git
mkdir -p .git/modules
cp -r "$_git_common/modules/libvgpu" .git/modules/
fi
fi

Comment on lines 826 to 831
err = util.PatchPodAnnotations(args.Pod, annotations)
if err != nil {
s.recordScheduleFilterResultEvent(args.Pod, EventReasonFilteringFailed, "", err)
if added {
s.quotaManager.RmUsage(args.Pod, m.Devices)
}
s.podManager.DelPod(args.Pod)
restorePod()
return nil, err
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If util.PatchPodAnnotations fails, the scheduler attempts to restore the old pod placement by calling restorePod(). However, the new placement has already been added to podManager and quotaManager (via s.podManager.AddPod and s.quotaManager.AddUsage). Calling restorePod() without first removing the new placement will result in a resource leak in quotaManager (since the new placement's usage is never removed) and potentially podManager (if removed was false, the new pod is never deleted).

To fix this, we should explicitly remove the new placement from both managers if added was true, before calling restorePod().

Suggested change
err = util.PatchPodAnnotations(args.Pod, annotations)
if err != nil {
s.recordScheduleFilterResultEvent(args.Pod, EventReasonFilteringFailed, "", err)
if added {
s.quotaManager.RmUsage(args.Pod, m.Devices)
}
s.podManager.DelPod(args.Pod)
restorePod()
return nil, err
}
err = util.PatchPodAnnotations(args.Pod, annotations)
if err != nil {
s.recordScheduleFilterResultEvent(args.Pod, EventReasonFilteringFailed, "", err)
if added {
s.quotaManager.RmUsage(args.Pod, m.Devices)
s.podManager.DelPod(args.Pod)
}
restorePod()
return nil, err
}

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
pkg/scheduler/scheduler.go (1)

821-831: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Rollback the tentative pod/quota add before restorePod()
restorePod() only restores the state from before TakeAndDeletePod(...). If PatchPodAnnotations(...) fails after AddPod(...)/AddUsage(...), the fresh-pod path leaks cache/quota state, and the re-schedule path leaves the entry on m.NodeID while only Devices gets overwritten back. Undo the tentative add first, then restore the prior state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/scheduler/scheduler.go` around lines 821 - 831, The post-patch failure
path in scheduler logic leaves tentative pod and quota state behind. In the
scheduling flow around AddPod, AddUsage, and util.PatchPodAnnotations, roll back
the fresh AddPod/quota update (and the re-schedule cache entry on m.NodeID)
before calling restorePod(), so the state is fully reverted prior to restoring
the previous pod assignment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hack/build.sh`:
- Around line 42-58: The EXIT restore trap in the git preservation logic is
registered too late, leaving a failure window after `.git` is removed and before
cleanup is guaranteed. In `build.sh` around the `_restore_git` handling, move
the `trap` setup so it is installed before any destructive `rm -f .git`, `mkdir
-p .git/modules`, or `cp -r` operations, and keep the restore behavior tied to
the same `_restore_git` variable so the worktree is always recoverable if any
step fails.

---

Outside diff comments:
In `@pkg/scheduler/scheduler.go`:
- Around line 821-831: The post-patch failure path in scheduler logic leaves
tentative pod and quota state behind. In the scheduling flow around AddPod,
AddUsage, and util.PatchPodAnnotations, roll back the fresh AddPod/quota update
(and the re-schedule cache entry on m.NodeID) before calling restorePod(), so
the state is fully reverted prior to restoring the previous pod assignment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b5c18fe1-fcd1-45cc-93bd-871bcb5ad178

📥 Commits

Reviewing files that changed from the base of the PR and between 4e23779 and 35e7f82.

📒 Files selected for processing (3)
  • hack/build.sh
  • pkg/scheduler/scheduler.go
  • pkg/scheduler/scheduler_test.go

Comment thread hack/build.sh
In linked git worktrees, .git is a file (not a directory), so the path
.git/modules/libvgpu does not exist in the Docker build context.
This causes the Dockerfile COPY command to fail with 'not found'.

Detect worktrees via [ -f .git ] and temporarily create the expected
.git/modules/libvgpu directory from the real common gitdir, restoring
the .git file on exit.

Fixes Project-HAMi#2041

Signed-off-by: pingxin403 <pingxin403@163.com>
…uild

Signed-off-by: pingxin403 <pingxin403@163.com>
@spencercjh

Copy link
Copy Markdown
Contributor

RUN bash ./build.sh is called after COPY .git/modules/libvgpu /libvgpu-git.

I think your fix won't work. Please check and test yourself or your agents, then create the PR.

@pingxin403

Copy link
Copy Markdown
Author

Close for now — the fix needs to be in docker_build() context preparation (pre-build), not in build.sh (runtime). Will revisit with correct approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] docker build fails from linked git worktree because Dockerfiles assume .git/modules/libvgpu exists

2 participants