sg wolfi package ... - create build dir in OS-specific temp dir (#55853)

* Create build dir in OS-specific temp dir
instead of hardcoding `/tmp`

* Don't return an error if build dir delete fails
Instead, output a warning and return the status of the build.

* Check build dir prefix against OS-specific temp dir
Before deleting, instead of checking against "/tmp"

* Include reason for dir delete error

* Add nested build dir removal attempts
waiting 50ms between attempts to allow other build processes
(*cough* Docker *cough*) to release file locks.
Also move the call to the removal function out to the same place the call is made to create the dir.

* Tweak emoji and formatting for warning message
This commit is contained in:
Peter Guy 2023-08-15 10:07:39 -07:00 committed by GitHub
parent 097c2cdc95
commit b41a9f9b26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 14 deletions

View File

@ -6,6 +6,7 @@ import (
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/sourcegraph/sourcegraph/dev/sg/internal/std"
"github.com/sourcegraph/sourcegraph/dev/sg/root"
@ -106,7 +107,7 @@ func SetupPackageBuild(name string) (manifestBaseName string, buildDir string, e
}
// Create a temp dir
buildDir, err = os.MkdirTemp("/tmp", "sg-wolfi-package-tmp")
buildDir, err = os.MkdirTemp("", "sg-wolfi-package-tmp")
if err != nil {
return "", "", errors.Wrap(err, "unable to create temporary build directory")
}
@ -145,32 +146,35 @@ func (c PackageRepoConfig) DoPackageBuild(name string, buildDir string) error {
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return errors.Wrap(err, "failed to build package")
}
cmdErr := cmd.Run()
std.Out.Write("")
if err := deleteBuildDir(buildDir); err != nil {
return err
if cmdErr != nil {
return errors.Wrapf(cmdErr, "failed to build package %s", name)
}
std.Out.Write("")
std.Out.WriteSuccessf("Successfully built package %s\n", name)
std.Out.WriteLine(output.Linef("🛠️ ", output.StyleBold, "Use this package in local image builds by adding the package '%s@local' to the base image config\n", name))
return nil
}
// deleteTempDir deletes a build directory after checking that it's a temporary directory
func deleteBuildDir(path string) error {
if !strings.HasPrefix(path, "/tmp/") {
return errors.New(fmt.Sprintf("directory '%s' is not a temporary directory - not cleaning up", path))
// RemoveBuildDir recursively removes the temporary build directory if it is in the OS temp dir.
// If the initial removal fails, it waits 50ms and tries again.
// If all removal attempts fail, it prints a message to stdout.
func RemoveBuildDir(path string) {
if !strings.HasPrefix(path, os.TempDir()) {
return
}
if err := os.RemoveAll(path); err != nil {
return errors.Wrap(err, fmt.Sprintf("unable to remove build dir '%s'", path))
// wait a bit in case any build processes (I'm looking at you, Docker!) are still using the directory
time.Sleep(50 * time.Millisecond)
if err := os.RemoveAll(path); err != nil {
std.Out.WriteLine(output.Linef(output.EmojiWarningSign, output.StyleWarning, " Could not delete temp build dir %s because %s", path, err))
}
}
return nil
}

View File

@ -52,6 +52,8 @@ Base images containing locally-built packages can then be built using 'sg wolfi
return err
}
defer wolfi.RemoveBuildDir(buildDir)
err = c.DoPackageBuild(manifestBaseName, buildDir)
if err != nil {
return err