/
container_backend.go
149 lines (129 loc) · 4.71 KB
/
container_backend.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package common
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/werf/werf/pkg/buildah"
"github.com/werf/werf/pkg/buildah/thirdparty"
"github.com/werf/werf/pkg/container_backend"
"github.com/werf/werf/pkg/docker"
"github.com/werf/werf/pkg/util"
"github.com/werf/werf/pkg/werf"
)
func ContainerBackendProcessStartupHook() (bool, error) {
buildahMode, _, err := GetBuildahMode()
if err != nil {
return false, fmt.Errorf("unable to determine buildah mode: %w", err)
}
switch {
case *buildahMode != buildah.ModeDisabled:
return buildah.ProcessStartupHook(*buildahMode)
case strings.HasPrefix(os.Args[0], "buildah-") || strings.HasPrefix(os.Args[0], "chrootuser-") || strings.HasPrefix(os.Args[0], "storage-"):
return buildah.ProcessStartupHook(buildah.ModeNative)
}
return false, nil
}
func GetBuildahMode() (*buildah.Mode, *thirdparty.Isolation, error) {
var (
mode buildah.Mode
isolation thirdparty.Isolation
)
modeRaw := os.Getenv("WERF_BUILDAH_MODE")
switch modeRaw {
case "native-rootless":
if util.IsInContainer() {
return nil, nil, fmt.Errorf("native rootless mode is not available in containers")
}
mode = buildah.ModeNative
isolation = thirdparty.IsolationOCIRootless
case "native-chroot":
mode = buildah.ModeNative
isolation = thirdparty.IsolationChroot
case "docker-with-fuse":
mode = buildah.ModeDockerWithFuse
isolation = thirdparty.IsolationChroot
case "default", "auto":
mode = buildah.ModeAuto
var err error
isolation, err = buildah.GetDefaultIsolation()
if err != nil {
return nil, nil, fmt.Errorf("unable to determine default isolation: %w", err)
}
case "docker", "":
mode = buildah.ModeDisabled
default:
return nil, nil, fmt.Errorf("unexpected mode specified: %s", modeRaw)
}
return &mode, &isolation, nil
}
func GetBuildahStorageDriver() (*buildah.StorageDriver, error) {
storageDriverRaw := os.Getenv("WERF_BUILDAH_STORAGE_DRIVER")
var storageDriver buildah.StorageDriver
switch storageDriverRaw {
case string(buildah.StorageDriverOverlay), string(buildah.StorageDriverVFS):
storageDriver = buildah.StorageDriver(storageDriverRaw)
case "default", "auto", "":
storageDriver = buildah.DefaultStorageDriver
default:
return nil, fmt.Errorf("unexpected driver specified: %s", storageDriverRaw)
}
return &storageDriver, nil
}
func wrapContainerBackend(containerBackend container_backend.ContainerBackend) container_backend.ContainerBackend {
if os.Getenv("WERF_PERF_TEST_CONTAINER_RUNTIME") == "1" {
return container_backend.NewPerfCheckContainerBackend(containerBackend)
}
return containerBackend
}
func InitProcessContainerBackend(ctx context.Context, cmdData *CmdData) (container_backend.ContainerBackend, context.Context, error) {
buildahMode, buildahIsolation, err := GetBuildahMode()
if err != nil {
return nil, ctx, fmt.Errorf("unable to determine buildah mode: %w", err)
}
if *buildahMode != buildah.ModeDisabled {
resolvedMode := buildah.ResolveMode(*buildahMode)
if resolvedMode == buildah.ModeDockerWithFuse {
newCtx, err := InitProcessDocker(ctx, cmdData)
if err != nil {
return nil, ctx, fmt.Errorf("unable to init process docker for buildah container backend: %w", err)
}
ctx = newCtx
}
storageDriver, err := GetBuildahStorageDriver()
if err != nil {
return nil, ctx, fmt.Errorf("unable to determine buildah container backend storage driver: %w", err)
}
insecure := *cmdData.InsecureRegistry || *cmdData.SkipTlsVerifyRegistry
b, err := buildah.NewBuildah(resolvedMode, buildah.BuildahOpts{
CommonBuildahOpts: buildah.CommonBuildahOpts{
TmpDir: filepath.Join(werf.GetServiceDir(), "tmp", "buildah"),
Insecure: insecure,
Isolation: buildahIsolation,
StorageDriver: storageDriver,
},
})
if err != nil {
return nil, ctx, fmt.Errorf("unable to get buildah client: %w", err)
}
return wrapContainerBackend(container_backend.NewBuildahBackend(b, filepath.Join(werf.GetServiceDir(), "tmp", "buildah"))), ctx, nil
}
newCtx, err := InitProcessDocker(ctx, cmdData)
if err != nil {
return nil, ctx, fmt.Errorf("unable to init process docker for docker-server container backend: %w", err)
}
ctx = newCtx
return wrapContainerBackend(container_backend.NewDockerServerBackend()), ctx, nil
}
func InitProcessDocker(ctx context.Context, cmdData *CmdData) (context.Context, error) {
if err := docker.Init(ctx, *cmdData.DockerConfig, *cmdData.LogVerbose, *cmdData.LogDebug, *cmdData.Platform); err != nil {
return ctx, fmt.Errorf("unable to init docker for buildah container backend: %w", err)
}
ctxWithDockerCli, err := docker.NewContext(ctx)
if err != nil {
return ctx, fmt.Errorf("unable to init context for docker: %w", err)
}
ctx = ctxWithDockerCli
return ctx, nil
}