ref: e7ce17381f525328073577d60583447fc9412c18
dir: /receivepack/service/quarantine.go/
package service
import (
"bytes"
"crypto/rand"
"errors"
"fmt"
"io"
"io/fs"
"os"
"path"
"slices"
)
// createQuarantineRoot creates one per-push quarantine directory beneath the
// permanent objects root.
//
// It returns both the quarantine directory name relative to ObjectsRoot and an
// opened root for that directory. Callers use the name for later promotion or
// removal relative to ObjectsRoot, and use the opened root for capability-based
// access within the quarantine itself.
func (service *Service) createQuarantineRoot() (string, *os.Root, error) {
name := "tmp_objdir-incoming-" + rand.Text()
err := service.opts.ObjectsRoot.Mkdir(name, 0o700)
if err != nil {
return "", nil, err
}
root, err := service.opts.ObjectsRoot.OpenRoot(name)
if err != nil {
_ = service.opts.ObjectsRoot.RemoveAll(name)
return "", nil, err
}
return name, root, nil
}
func (service *Service) openQuarantinePackRoot(quarantineRoot *os.Root) (*os.Root, error) {
err := quarantineRoot.Mkdir("pack", 0o755)
if err != nil && !os.IsExist(err) {
return nil, err
}
return quarantineRoot.OpenRoot("pack")
}
func (service *Service) promoteQuarantine(quarantineName string, quarantineRoot *os.Root) error {
if quarantineName == "" || quarantineRoot == nil {
return nil
}
return service.promoteQuarantineDir(quarantineName, quarantineRoot, ".")
}
func (service *Service) promoteQuarantineDir(quarantineName string, quarantineRoot *os.Root, rel string) error {
entries, err := fs.ReadDir(quarantineRoot.FS(), rel)
if err != nil && !os.IsNotExist(err) {
return err
}
slices.SortFunc(entries, func(left, right fs.DirEntry) int {
return packCopyPriority(left.Name()) - packCopyPriority(right.Name())
})
for _, entry := range entries {
childRel := entry.Name()
if rel != "." {
childRel = path.Join(rel, entry.Name())
}
if entry.IsDir() {
err = service.opts.ObjectsRoot.Mkdir(childRel, 0o755)
if err != nil && !os.IsExist(err) {
return err
}
err = service.applyPromotedDirectoryPermissions(childRel)
if err != nil {
return err
}
err = service.promoteQuarantineDir(quarantineName, quarantineRoot, childRel)
if err != nil {
return err
}
continue
}
err = finalizeQuarantineFile(
service.opts.ObjectsRoot,
path.Join(quarantineName, childRel),
childRel,
isLooseObjectShardPath(rel),
service.opts.PromotedObjectPermissions,
)
if err == nil {
continue
}
return err
}
return nil
}
func packCopyPriority(name string) int {
if !pathHasPackPrefix(name) {
return 0
}
switch {
case path.Ext(name) == ".keep":
return 1
case path.Ext(name) == ".pack":
return 2
case path.Ext(name) == ".rev":
return 3
case path.Ext(name) == ".idx":
return 4
default:
return 5
}
}
func pathHasPackPrefix(name string) bool {
return len(name) >= 4 && name[:4] == "pack"
}
func isLooseObjectShardPath(rel string) bool {
return len(rel) == 2 && isHex(rel[0]) && isHex(rel[1])
}
func isHex(ch byte) bool {
return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
}
func (service *Service) applyPromotedDirectoryPermissions(name string) error {
if service.opts.PromotedObjectPermissions == nil {
return nil
}
return service.opts.ObjectsRoot.Chmod(name, service.opts.PromotedObjectPermissions.DirMode)
}
func applyPromotedFilePermissions(
root *os.Root,
name string,
perms *PromotedObjectPermissions,
) error {
if perms == nil {
return nil
}
return root.Chmod(name, perms.FileMode)
}
func finalizeQuarantineFile(
root *os.Root,
src, dst string,
skipCollisionCheck bool,
perms *PromotedObjectPermissions,
) error {
const maxVanishedRetries = 5
for retries := 0; ; retries++ {
err := root.Link(src, dst)
switch {
case err == nil:
_ = root.Remove(src)
return applyPromotedFilePermissions(root, dst, perms)
case !errors.Is(err, fs.ErrExist):
_, statErr := root.Stat(dst)
switch {
case statErr == nil:
err = fs.ErrExist
case errors.Is(statErr, fs.ErrNotExist):
renameErr := root.Rename(src, dst)
if renameErr == nil {
return applyPromotedFilePermissions(root, dst, perms)
}
err = renameErr
default:
_ = root.Remove(src)
return statErr
}
}
if !errors.Is(err, fs.ErrExist) {
_ = root.Remove(src)
return fmt.Errorf("promote quarantine %q -> %q: %w", src, dst, err)
}
if skipCollisionCheck {
_ = root.Remove(src)
return applyPromotedFilePermissions(root, dst, perms)
}
equal, vanished, cmpErr := compareRootFiles(root, src, dst)
if vanished {
if retries >= maxVanishedRetries {
return fmt.Errorf("promote quarantine %q -> %q: destination repeatedly vanished", src, dst)
}
continue
}
if cmpErr != nil {
return cmpErr
}
if !equal {
return fmt.Errorf("promote quarantine %q -> %q: files differ in contents", src, dst)
}
_ = root.Remove(src)
return applyPromotedFilePermissions(root, dst, perms)
}
}
func compareRootFiles(root *os.Root, left, right string) (equal bool, vanished bool, err error) {
leftFile, err := root.Open(left)
if err != nil {
return false, false, err
}
defer func() {
_ = leftFile.Close()
}()
rightFile, err := root.Open(right)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return false, true, nil
}
return false, false, err
}
defer func() {
_ = rightFile.Close()
}()
var leftBuf, rightBuf [4096]byte
for {
leftN, leftErr := leftFile.Read(leftBuf[:])
rightN, rightErr := rightFile.Read(rightBuf[:])
if leftErr != nil && !errors.Is(leftErr, io.EOF) {
return false, false, leftErr
}
if rightErr != nil && !errors.Is(rightErr, io.EOF) {
return false, false, rightErr
}
if leftN != rightN || !bytes.Equal(leftBuf[:leftN], rightBuf[:rightN]) {
return false, false, nil
}
if leftErr != nil || rightErr != nil {
return true, false, nil
}
}
}