/
host_cleanup.go
183 lines (152 loc) · 6.49 KB
/
host_cleanup.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package host_cleaning
import (
"context"
"fmt"
"os"
"os/exec"
"strings"
"github.com/werf/logboek"
"github.com/werf/werf/pkg/git_repo/gitdata"
"github.com/werf/werf/pkg/tmp_manager"
)
const (
DefaultAllowedDockerStorageVolumeUsagePercentage float64 = 70.0
DefaultAllowedDockerStorageVolumeUsageMarginPercentage float64 = 5.0
DefaultAllowedLocalCacheVolumeUsagePercentage float64 = 70.0
DefaultAllowedLocalCacheVolumeUsageMarginPercentage float64 = 5.0
)
type HostCleanupOptions struct {
AllowedDockerStorageVolumeUsagePercentage *uint
AllowedDockerStorageVolumeUsageMarginPercentage *uint
AllowedLocalCacheVolumeUsagePercentage *uint
AllowedLocalCacheVolumeUsageMarginPercentage *uint
DockerServerStoragePath *string
DryRun bool
Force bool
}
type AutoHostCleanupOptions struct {
HostCleanupOptions
ForceShouldRun bool
}
func getOptionValueOrDefault(optionValue *uint, defaultValue float64) float64 {
var res float64
if optionValue != nil {
res = float64(*optionValue)
} else {
res = defaultValue
}
return res
}
func RunAutoHostCleanup(ctx context.Context, options AutoHostCleanupOptions) error {
if !options.ForceShouldRun {
shouldRun, err := ShouldRunAutoHostCleanup(ctx, options.HostCleanupOptions)
if err != nil {
logboek.Context(ctx).Warn().LogF("WARNING: unable to check if auto host cleanup should be run: %s\n", err)
return nil
}
if !shouldRun {
return nil
}
}
logboek.Context(ctx).Debug().LogF("RunAutoHostCleanup forking ...\n")
var args []string
args = append(args,
"host", "cleanup",
fmt.Sprintf("--dry-run=%v", options.DryRun),
fmt.Sprintf("--force=%v", options.Force),
)
if options.AllowedDockerStorageVolumeUsagePercentage != nil {
args = append(args, "--allowed-docker-storage-volume-usage", fmt.Sprintf("%d", *options.AllowedDockerStorageVolumeUsagePercentage))
}
if options.AllowedDockerStorageVolumeUsageMarginPercentage != nil {
args = append(args, "--allowed-docker-storage-volume-usage-margin", fmt.Sprintf("%d", *options.AllowedDockerStorageVolumeUsageMarginPercentage))
}
if options.AllowedLocalCacheVolumeUsagePercentage != nil {
args = append(args, "--allowed-local-cache-volume-usage", fmt.Sprintf("%d", *options.AllowedLocalCacheVolumeUsagePercentage))
}
if options.AllowedLocalCacheVolumeUsageMarginPercentage != nil {
args = append(args, "--allowed-docker-storage-volume-usage-margin", fmt.Sprintf("%d", *options.AllowedLocalCacheVolumeUsageMarginPercentage))
}
if options.DockerServerStoragePath != nil && *options.DockerServerStoragePath != "" {
args = append(args, "--docker-server-storage-path", *options.DockerServerStoragePath)
}
cmd := exec.Command(os.Args[0], args...)
var env []string
for _, spec := range os.Environ() {
k := strings.SplitN(spec, "=", 2)[0]
if k == "WERF_ENABLE_PROCESS_EXTERMINATOR" {
continue
}
env = append(env, spec)
}
env = append(env, "_WERF_BACKGROUND_MODE_ENABLED=1")
cmd.Env = env
if err := cmd.Start(); err != nil {
logboek.Context(ctx).Warn().LogF("WARNING: unable to start background auto host cleanup process: %s\n", err)
return nil
}
if err := cmd.Process.Release(); err != nil {
logboek.Context(ctx).Warn().LogF("WARNING: unable to detach background auto host cleanup process: %s\n", err)
return nil
}
return nil
}
func RunHostCleanup(ctx context.Context, options HostCleanupOptions) error {
if err := logboek.Context(ctx).LogProcess("Running GC for tmp data").DoError(func() error {
if err := tmp_manager.RunGC(ctx, options.DryRun); err != nil {
return fmt.Errorf("tmp files GC failed: %s", err)
}
return nil
}); err != nil {
return err
}
allowedLocalCacheVolumeUsagePercentage := getOptionValueOrDefault(options.AllowedLocalCacheVolumeUsagePercentage, DefaultAllowedLocalCacheVolumeUsagePercentage)
allowedLocalCacheVolumeUsageMarginPercentage := getOptionValueOrDefault(options.AllowedLocalCacheVolumeUsageMarginPercentage, DefaultAllowedLocalCacheVolumeUsageMarginPercentage)
allowedDockerStorageVolumeUsagePercentage := getOptionValueOrDefault(options.AllowedDockerStorageVolumeUsagePercentage, DefaultAllowedDockerStorageVolumeUsagePercentage)
allowedDockerStorageVolumeUsageMarginPercentage := getOptionValueOrDefault(options.AllowedDockerStorageVolumeUsageMarginPercentage, DefaultAllowedDockerStorageVolumeUsageMarginPercentage)
if err := logboek.Context(ctx).Default().LogProcess("Running GC for git data").DoError(func() error {
if err := gitdata.RunGC(ctx, allowedLocalCacheVolumeUsagePercentage, allowedLocalCacheVolumeUsageMarginPercentage); err != nil {
return fmt.Errorf("git repo GC failed: %s", err)
}
return nil
}); err != nil {
return err
}
dockerServerStoragePath, err := getDockerServerStoragePath(ctx, options.DockerServerStoragePath)
if err != nil {
return fmt.Errorf("error getting local docker server storage path: %s", err)
}
return logboek.Context(ctx).Default().LogProcess("Running GC for local docker server").DoError(func() error {
if err := RunGCForLocalDockerServer(ctx, allowedDockerStorageVolumeUsagePercentage, allowedDockerStorageVolumeUsageMarginPercentage, dockerServerStoragePath, options.Force, options.DryRun); err != nil {
return fmt.Errorf("local docker server GC failed: %s", err)
}
return nil
})
}
func ShouldRunAutoHostCleanup(ctx context.Context, options HostCleanupOptions) (bool, error) {
shouldRun, err := tmp_manager.ShouldRunAutoGC()
if err != nil {
return false, fmt.Errorf("failed to check tmp manager GC: %s", err)
}
if shouldRun {
return true, nil
}
allowedLocalCacheVolumeUsagePercentage := getOptionValueOrDefault(options.AllowedLocalCacheVolumeUsagePercentage, DefaultAllowedLocalCacheVolumeUsagePercentage)
allowedDockerStorageVolumeUsagePercentage := getOptionValueOrDefault(options.AllowedDockerStorageVolumeUsagePercentage, DefaultAllowedDockerStorageVolumeUsagePercentage)
shouldRun, err = gitdata.ShouldRunAutoGC(ctx, allowedLocalCacheVolumeUsagePercentage)
if err != nil {
return false, fmt.Errorf("failed to check git repo GC: %s", err)
}
if shouldRun {
return true, nil
}
dockerServerStoragePath, err := getDockerServerStoragePath(ctx, options.DockerServerStoragePath)
if err != nil {
return false, fmt.Errorf("error getting local docker server storage path: %s", err)
}
shouldRun, err = ShouldRunAutoGCForLocalDockerServer(ctx, allowedDockerStorageVolumeUsagePercentage, dockerServerStoragePath)
if err != nil {
return false, fmt.Errorf("failed to check local docker server host cleaner GC: %s", err)
}
return shouldRun, nil
}