2 Commits

Author SHA1 Message Date
christoph-zededa
3f54a80824 git: synchronize update-index with a mutex (#4130)
if `pkglib.NewFromConfig` is used in parallel, it calls
```
git -C /some/directory update-index -q --refresh
```
in parallel.

But `git` does not like this and exits with 128.

This can be easily tried with:
```
git -C /some/dir update-index -q --refresh & \
git -C /some/dir update-index -q --refresh
```

Signed-off-by: Christoph Ostarek <christoph@zededa.com>
2025-06-25 21:59:47 +03:00
Avi Deitcher
d45d3e8c6e more builder race condition; do restart if could not remove, and only go via container ID (#4129)
Signed-off-by: Avi Deitcher <avi@deitcher.net>
2025-06-25 21:21:51 +03:00
2 changed files with 24 additions and 4 deletions

View File

@@ -276,6 +276,7 @@ func (dr *dockerRunnerImpl) builderEnsureContainer(ctx context.Context, name, im
) )
for range buildKitCheckRetryCount { for range buildKitCheckRetryCount {
var b bytes.Buffer var b bytes.Buffer
var cid string
if err := dr.command(nil, &b, io.Discard, "--context", dockerContext, "container", "inspect", name); err == nil { if err := dr.command(nil, &b, io.Discard, "--context", dockerContext, "container", "inspect", name); err == nil {
// we already have a container named "linuxkit-builder" in the provided context. // we already have a container named "linuxkit-builder" in the provided context.
// get its state and config // get its state and config
@@ -284,6 +285,7 @@ func (dr *dockerRunnerImpl) builderEnsureContainer(ctx context.Context, name, im
return nil, fmt.Errorf("unable to read results of 'container inspect %s': %v", name, err) return nil, fmt.Errorf("unable to read results of 'container inspect %s': %v", name, err)
} }
cid = containerJSON[0].ID
existingImage := containerJSON[0].Config.Image existingImage := containerJSON[0].Config.Image
isRunning := containerJSON[0].State.Status == "running" isRunning := containerJSON[0].State.Status == "running"
@@ -326,13 +328,25 @@ func (dr *dockerRunnerImpl) builderEnsureContainer(ctx context.Context, name, im
// if we made it here, we need to stop and remove the container, either because of a config mismatch, // if we made it here, we need to stop and remove the container, either because of a config mismatch,
// or because we received the CLI option // or because we received the CLI option
if stop { if stop {
if err := dr.command(nil, io.Discard, io.Discard, "--context", dockerContext, "container", "stop", name); err != nil { if cid == "" {
return nil, fmt.Errorf("failed to stop existing container %s", name) // we don't have a container ID, so we can't stop it
return nil, fmt.Errorf("unable to stop existing container %s, no ID found", name)
}
if err := dr.command(nil, io.Discard, io.Discard, "--context", dockerContext, "container", "stop", cid); err != nil {
// if we failed, do a retry; maybe it does not even exist anymore
time.Sleep(buildkitCheckInterval)
continue
} }
} }
if remove { if remove {
if err := dr.command(nil, io.Discard, io.Discard, "--context", dockerContext, "container", "rm", name); err != nil { if cid == "" {
return nil, fmt.Errorf("failed to remove existing container %s", name) // we don't have a container ID, so we can't remove it
return nil, fmt.Errorf("unable to remove existing container %s, no ID found", name)
}
if err := dr.command(nil, io.Discard, io.Discard, "--context", dockerContext, "container", "rm", cid); err != nil {
// if we failed, do a retry; maybe it does not even exist anymore
time.Sleep(buildkitCheckInterval)
continue
} }
} }
if recreate { if recreate {

View File

@@ -12,6 +12,7 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"sync"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -27,6 +28,8 @@ type git struct {
dir string dir string
} }
var gitMutex sync.Mutex
// Returns git==nil and no error if the path is not within a git repository // Returns git==nil and no error if the path is not within a git repository
func newGit(dir string) (*git, error) { func newGit(dir string) (*git, error) {
g := &git{dir} g := &git{dir}
@@ -190,9 +193,12 @@ func (g git) isDirty(pkg, commit string) (bool, error) {
// because `git diff-index` only uses the `lstat` result and // because `git diff-index` only uses the `lstat` result and
// not the actual file contents. Running `git update-index // not the actual file contents. Running `git update-index
// --refresh` updates the cache. // --refresh` updates the cache.
gitMutex.Lock()
if err := g.command("update-index", "-q", "--refresh"); err != nil { if err := g.command("update-index", "-q", "--refresh"); err != nil {
gitMutex.Unlock()
return false, err return false, err
} }
gitMutex.Unlock()
// diff-index works pretty well, except that // diff-index works pretty well, except that
err := g.command("diff-index", "--quiet", commit, "--", pkg) err := g.command("diff-index", "--quiet", commit, "--", pkg)