mirror of
https://github.com/golang/go
synced 2024-11-12 07:40:23 -07:00
cmd/go/internal/modfetch: make directories read-only after renaming, not before
The call to os.Rename was failing on the darwin builders, despite having passed in the TryBots. (I tested this change by running 'go test cmd/go' manually on a darwin gomote.) This fixes the builder failures after CL 146382. Updates #26794 Fixes #29030 Change-Id: I3644773421789f65e56f183d077b4e4fd17b8325 Reviewed-on: https://go-review.googlesource.com/c/151798 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
96a6bd4bf6
commit
42e8b9c3a4
@ -120,7 +120,14 @@ func download(mod module.Version, dir string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Rename(tmpDir, dir)
|
||||
if err := os.Rename(tmpDir, dir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Make dir read-only only *after* renaming it.
|
||||
// os.Rename was observed to fail for read-only directories on macOS.
|
||||
makeDirsReadOnly(dir)
|
||||
return nil
|
||||
}
|
||||
|
||||
var downloadZipCache par.Cache
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/modfetch/codehost"
|
||||
@ -98,18 +97,12 @@ func Unzip(dir, zipfile, prefix string, maxSize int64) error {
|
||||
}
|
||||
|
||||
// Unzip, enforcing sizes checked earlier.
|
||||
dirs := map[string]bool{dir: true}
|
||||
for _, zf := range z.File {
|
||||
if zf.Name == prefix || strings.HasSuffix(zf.Name, "/") {
|
||||
continue
|
||||
}
|
||||
name := zf.Name[len(prefix):]
|
||||
dst := filepath.Join(dir, name)
|
||||
parent := filepath.Dir(dst)
|
||||
for parent != dir {
|
||||
dirs[parent] = true
|
||||
parent = filepath.Dir(parent)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -137,21 +130,32 @@ func Unzip(dir, zipfile, prefix string, maxSize int64) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Mark directories unwritable, best effort.
|
||||
var dirlist []string
|
||||
for dir := range dirs {
|
||||
dirlist = append(dirlist, dir)
|
||||
}
|
||||
sort.Strings(dirlist)
|
||||
// Run over list backward to chmod children before parents.
|
||||
for i := len(dirlist) - 1; i >= 0; i-- {
|
||||
// TODO(bcmills): Does this end up stomping on the umask of the cache directory?
|
||||
os.Chmod(dirlist[i], 0555)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeDirsReadOnly makes a best-effort attempt to remove write permissions for dir
|
||||
// and its transitive contents.
|
||||
func makeDirsReadOnly(dir string) {
|
||||
type pathMode struct {
|
||||
path string
|
||||
mode os.FileMode
|
||||
}
|
||||
var dirs []pathMode // in lexical order
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err == nil && info.Mode()&0222 != 0 {
|
||||
if info.IsDir() {
|
||||
dirs = append(dirs, pathMode{path, info.Mode()})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// Run over list backward to chmod children before parents.
|
||||
for i := len(dirs) - 1; i >= 0; i-- {
|
||||
os.Chmod(dirs[i].path, dirs[i].mode&^0222)
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveAll removes a directory written by Download or Unzip, first applying
|
||||
// any permission changes needed to do so.
|
||||
func RemoveAll(dir string) error {
|
||||
|
Loading…
Reference in New Issue
Block a user