podman

Форк
0
/
reset.go 
286 строк · 8.0 Кб
1
//go:build !remote
2

3
package libpod
4

5
import (
6
	"context"
7
	"errors"
8
	"fmt"
9
	"os"
10
	"path/filepath"
11

12
	"github.com/containers/common/libimage"
13
	"github.com/containers/common/libnetwork/types"
14
	"github.com/containers/podman/v5/libpod/define"
15
	"github.com/containers/podman/v5/pkg/errorhandling"
16
	"github.com/containers/podman/v5/pkg/util"
17
	"github.com/containers/storage"
18
	"github.com/containers/storage/pkg/lockfile"
19
	stypes "github.com/containers/storage/types"
20
	"github.com/sirupsen/logrus"
21
)
22

23
// removeAllDirs removes all Podman storage directories. It is intended to be
24
// used as a backup for reset() when that function cannot be used due to
25
// failures in initializing libpod.
26
// It does not expect that all the directories match what is in use by Podman,
27
// as this is a common failure point for `system reset`. As such, our ability to
28
// interface with containers and pods is somewhat limited.
29
// This function assumes that we do not have a working c/storage store.
30
func (r *Runtime) removeAllDirs() error {
31
	var lastErr error
32

33
	// Grab the runtime alive lock.
34
	// This ensures that no other Podman process can run while we are doing
35
	// a reset, so no race conditions with containers/pods/etc being created
36
	// while we are resetting storage.
37
	// TODO: maybe want a helper for getting the path? This is duped from
38
	// runtime.go
39
	runtimeAliveLock := filepath.Join(r.config.Engine.TmpDir, "alive.lck")
40
	aliveLock, err := lockfile.GetLockFile(runtimeAliveLock)
41
	if err != nil {
42
		logrus.Errorf("Lock runtime alive lock %s: %v", runtimeAliveLock, err)
43
	} else {
44
		aliveLock.Lock()
45
		defer aliveLock.Unlock()
46
	}
47

48
	// We do not have a store - so we can't really try and remove containers
49
	// or pods or volumes...
50
	// Try and remove the directories, in hopes that they are unmounted.
51
	// This is likely to fail but it's the best we can do.
52

53
	// Volume path
54
	if err := os.RemoveAll(r.config.Engine.VolumePath); err != nil {
55
		lastErr = fmt.Errorf("removing volume path: %w", err)
56
	}
57

58
	// Tmpdir
59
	if err := os.RemoveAll(r.config.Engine.TmpDir); err != nil {
60
		if lastErr != nil {
61
			logrus.Errorf("Reset: %v", lastErr)
62
		}
63
		lastErr = fmt.Errorf("removing tmp dir: %w", err)
64
	}
65

66
	// Runroot
67
	if err := os.RemoveAll(r.storageConfig.RunRoot); err != nil {
68
		if lastErr != nil {
69
			logrus.Errorf("Reset: %v", lastErr)
70
		}
71
		lastErr = fmt.Errorf("removing run root: %w", err)
72
	}
73

74
	// Static dir
75
	if err := os.RemoveAll(r.config.Engine.StaticDir); err != nil {
76
		if lastErr != nil {
77
			logrus.Errorf("Reset: %v", lastErr)
78
		}
79
		lastErr = fmt.Errorf("removing static dir: %w", err)
80
	}
81

82
	// Graph root
83
	if err := os.RemoveAll(r.storageConfig.GraphRoot); err != nil {
84
		if lastErr != nil {
85
			logrus.Errorf("Reset: %v", lastErr)
86
		}
87
		lastErr = fmt.Errorf("removing graph root: %w", err)
88
	}
89

90
	return lastErr
91
}
92

93
// Reset removes all Libpod files.
94
// All containers, images, volumes, pods, and networks will be removed.
95
// Calls Shutdown(), rendering the runtime unusable after this is run.
96
func (r *Runtime) Reset(ctx context.Context) error {
97
	// Acquire the alive lock and hold it.
98
	// Ensures that we don't let other Podman commands run while we are
99
	// removing everything.
100
	aliveLock, err := r.getRuntimeAliveLock()
101
	if err != nil {
102
		return fmt.Errorf("retrieving alive lock: %w", err)
103
	}
104
	aliveLock.Lock()
105
	defer aliveLock.Unlock()
106

107
	if !r.valid {
108
		return define.ErrRuntimeStopped
109
	}
110

111
	var timeout uint = 0
112
	pods, err := r.GetAllPods()
113
	if err != nil {
114
		return err
115
	}
116
	for _, p := range pods {
117
		if ctrs, err := r.RemovePod(ctx, p, true, true, &timeout); err != nil {
118
			if errors.Is(err, define.ErrNoSuchPod) {
119
				continue
120
			}
121
			for ctr, err := range ctrs {
122
				if err != nil {
123
					logrus.Errorf("Error removing pod %s container %s: %v", p.ID(), ctr, err)
124
				}
125
			}
126
			logrus.Errorf("Removing Pod %s: %v", p.ID(), err)
127
		}
128
	}
129

130
	ctrs, err := r.GetAllContainers()
131
	if err != nil {
132
		return err
133
	}
134

135
	for _, c := range ctrs {
136
		if ctrs, _, err := r.RemoveContainerAndDependencies(ctx, c, true, true, &timeout); err != nil {
137
			for ctr, err := range ctrs {
138
				logrus.Errorf("Error removing container %s: %v", ctr, err)
139
			}
140

141
			if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved) {
142
				continue
143
			}
144

145
			logrus.Errorf("Removing container %s: %v", c.ID(), err)
146

147
			// There's no point trying a storage container removal
148
			// here. High likelihood it doesn't work
149
			// (RemoveStorageContainer will refuse to remove if a
150
			// container exists in the Libpod database) and, even if
151
			// it would, we'll get the container later on during
152
			// image removal.
153
		}
154
	}
155

156
	if err := r.stopPauseProcess(); err != nil {
157
		logrus.Errorf("Stopping pause process: %v", err)
158
	}
159

160
	// Volumes before images, as volumes can mount images.
161
	volumes, err := r.state.AllVolumes()
162
	if err != nil {
163
		return err
164
	}
165
	for _, v := range volumes {
166
		if err := r.RemoveVolume(ctx, v, true, &timeout); err != nil {
167
			if errors.Is(err, define.ErrNoSuchVolume) {
168
				continue
169
			}
170
			logrus.Errorf("Removing volume %s: %v", v.config.Name, err)
171
		}
172
	}
173

174
	// Set force and ignore.
175
	// Ignore shouldn't be necessary, but it seems safer. We want everything
176
	// gone anyways...
177
	rmiOptions := &libimage.RemoveImagesOptions{
178
		Force:               true,
179
		Ignore:              true,
180
		RemoveContainerFunc: r.RemoveContainersForImageCallback(ctx),
181
		Filters:             []string{"readonly=false"},
182
	}
183
	if _, rmiErrors := r.LibimageRuntime().RemoveImages(ctx, nil, rmiOptions); rmiErrors != nil {
184
		return errorhandling.JoinErrors(rmiErrors)
185
	}
186

187
	// remove all networks
188
	nets, err := r.network.NetworkList()
189
	if err != nil {
190
		return err
191
	}
192
	for _, net := range nets {
193
		// do not delete the default network
194
		if net.Name == r.network.DefaultNetworkName() {
195
			continue
196
		}
197
		// ignore not exists errors because of the TOCTOU problem
198
		if err := r.network.NetworkRemove(net.Name); err != nil && !errors.Is(err, types.ErrNoSuchNetwork) {
199
			logrus.Errorf("Removing network %s: %v", net.Name, err)
200
		}
201
	}
202

203
	xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR")
204
	if xdgRuntimeDir != "" {
205
		xdgRuntimeDir, err = filepath.EvalSymlinks(xdgRuntimeDir)
206
		if err != nil {
207
			return err
208
		}
209
	}
210
	_, prevError := r.store.Shutdown(true)
211
	graphRoot := filepath.Clean(r.store.GraphRoot())
212
	if graphRoot == xdgRuntimeDir {
213
		if prevError != nil {
214
			logrus.Error(prevError)
215
		}
216
		prevError = fmt.Errorf("failed to remove runtime graph root dir %s, since it is the same as XDG_RUNTIME_DIR", graphRoot)
217
	} else {
218
		if err := os.RemoveAll(graphRoot); err != nil {
219
			if prevError != nil {
220
				logrus.Error(prevError)
221
			}
222
			prevError = err
223
		}
224
	}
225
	runRoot := filepath.Clean(r.store.RunRoot())
226
	if runRoot == xdgRuntimeDir {
227
		if prevError != nil {
228
			logrus.Error(prevError)
229
		}
230
		prevError = fmt.Errorf("failed to remove runtime root dir %s, since it is the same as XDG_RUNTIME_DIR", runRoot)
231
	} else {
232
		if err := os.RemoveAll(runRoot); err != nil {
233
			if prevError != nil {
234
				logrus.Error(prevError)
235
			}
236
			prevError = err
237
		}
238
	}
239
	runtimeDir, err := util.GetRootlessRuntimeDir()
240
	if err != nil {
241
		return err
242
	}
243
	tempDir := r.config.Engine.TmpDir
244
	if tempDir == runtimeDir {
245
		tempDir = filepath.Join(tempDir, "containers")
246
	}
247
	if filepath.Clean(tempDir) == xdgRuntimeDir {
248
		if prevError != nil {
249
			logrus.Error(prevError)
250
		}
251
		prevError = fmt.Errorf("failed to remove runtime tmpdir %s, since it is the same as XDG_RUNTIME_DIR", tempDir)
252
	} else {
253
		if err := os.RemoveAll(tempDir); err != nil {
254
			if prevError != nil {
255
				logrus.Error(prevError)
256
			}
257
			prevError = err
258
		}
259
	}
260
	if storageConfPath, err := storage.DefaultConfigFile(); err == nil {
261
		switch storageConfPath {
262
		case stypes.SystemConfigFile:
263
			break
264
		default:
265
			if _, err = os.Stat(storageConfPath); err == nil {
266
				fmt.Printf(" A %q config file exists.\n", storageConfPath)
267
				fmt.Println("Remove this file if you did not modify the configuration.")
268
			}
269
		}
270
	} else {
271
		if prevError != nil {
272
			logrus.Error(prevError)
273
		}
274
		prevError = err
275
	}
276

277
	// Shut down the runtime, it's no longer usable after mass-deletion.
278
	if err := r.Shutdown(false); err != nil {
279
		if prevError != nil {
280
			logrus.Error(prevError)
281
		}
282
		prevError = err
283
	}
284

285
	return prevError
286
}
287

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.