/
chroot.go
82 lines (65 loc) · 2.06 KB
/
chroot.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
func getOverlay(logger *logrus.Logger, cacheDir, sourceDir string) (func(), string, error) {
var stat unix.Statfs_t
// Skip overlay on xfs and zfs
for _, dir := range []string{cacheDir, sourceDir} {
err := unix.Statfs(dir, &stat)
if err != nil {
return nil, "", err
}
switch stat.Type {
case unix.XFS_SUPER_MAGIC:
return nil, "", errors.New("overlay not supported on xfs")
case 0x2fc12fc1:
return nil, "", errors.New("overlay not supported on zfs")
}
}
upperDir := filepath.Join(cacheDir, "upper")
overlayDir := filepath.Join(cacheDir, "overlay")
workDir := filepath.Join(cacheDir, "work")
err := os.Mkdir(upperDir, 0755)
if err != nil {
return nil, "", fmt.Errorf("Failed to create directory %q: %w", upperDir, err)
}
err = os.Mkdir(overlayDir, 0755)
if err != nil {
return nil, "", fmt.Errorf("Failed to create directory %q: %w", overlayDir, err)
}
err = os.Mkdir(workDir, 0755)
if err != nil {
return nil, "", fmt.Errorf("Failed to create directory %q: %w", workDir, err)
}
opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", sourceDir, upperDir, workDir)
err = unix.Mount("overlay", overlayDir, "overlay", 0, opts)
if err != nil {
return nil, "", fmt.Errorf("Failed to mount overlay: %w", err)
}
cleanup := func() {
unix.Sync()
err := unix.Unmount(overlayDir, 0)
if err != nil {
logger.WithFields(logrus.Fields{"err": err, "dir": overlayDir}).Warn("Failed to unmount overlay directory")
}
err = os.RemoveAll(upperDir)
if err != nil {
logger.WithFields(logrus.Fields{"err": err, "dir": upperDir}).Warn("Failed to remove upper directory")
}
err = os.RemoveAll(workDir)
if err != nil {
logger.WithFields(logrus.Fields{"err": err, "dir": workDir}).Warn("Failed to remove work directory")
}
err = os.Remove(overlayDir)
if err != nil {
logger.WithFields(logrus.Fields{"err": err, "dir": overlayDir}).Warn("Failed to remove overlay directory")
}
}
return cleanup, overlayDir, nil
}