podman

Форк
0
/
oci_missing.go 
248 строк · 8.8 Кб
1
//go:build !remote
2

3
package libpod
4

5
import (
6
	"fmt"
7
	"net/http"
8
	"path/filepath"
9
	"sync"
10

11
	"github.com/containers/common/pkg/resize"
12
	"github.com/containers/podman/v5/libpod/define"
13
	spec "github.com/opencontainers/runtime-spec/specs-go"
14
	"github.com/sirupsen/logrus"
15
)
16

17
var (
18
	// Only create each missing runtime once.
19
	// Creation makes error messages we don't want to duplicate.
20
	missingRuntimes map[string]*MissingRuntime
21
	// We need a lock for this
22
	missingRuntimesLock sync.Mutex
23
)
24

25
// MissingRuntime is used when the OCI runtime requested by the container is
26
// missing (not installed or not in the configuration file).
27
type MissingRuntime struct {
28
	// Name is the name of the missing runtime. Will be used in errors.
29
	name string
30
	// exitsDir is the directory for exit files.
31
	exitsDir string
32
	// persistDir is the directory for exit and oom files.
33
	persistDir string
34
}
35

36
// Get a new MissingRuntime for the given name.
37
// Requires a libpod Runtime so we can make a sane path for the exits dir.
38
func getMissingRuntime(name string, r *Runtime) OCIRuntime {
39
	missingRuntimesLock.Lock()
40
	defer missingRuntimesLock.Unlock()
41

42
	if missingRuntimes == nil {
43
		missingRuntimes = make(map[string]*MissingRuntime)
44
	}
45

46
	runtime, ok := missingRuntimes[name]
47
	if ok {
48
		return runtime
49
	}
50

51
	// Once for each missing runtime, we want to error.
52
	logrus.Errorf("OCI Runtime %s is in use by a container, but is not available (not in configuration file or not installed)", name)
53

54
	newRuntime := new(MissingRuntime)
55
	newRuntime.name = name
56
	newRuntime.exitsDir = filepath.Join(r.config.Engine.TmpDir, "exits")
57
	newRuntime.persistDir = filepath.Join(r.config.Engine.TmpDir, "persist")
58

59
	missingRuntimes[name] = newRuntime
60

61
	return newRuntime
62
}
63

64
// Name is the name of the missing runtime
65
func (r *MissingRuntime) Name() string {
66
	return fmt.Sprintf("%s (missing/not available)", r.name)
67
}
68

69
// Path is not available as the runtime is missing
70
func (r *MissingRuntime) Path() string {
71
	return "(missing/not available)"
72
}
73

74
// CreateContainer is not available as the runtime is missing
75
func (r *MissingRuntime) CreateContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) (int64, error) {
76
	return 0, r.printError()
77
}
78

79
// UpdateContainerStatus is not available as the runtime is missing
80
func (r *MissingRuntime) UpdateContainerStatus(ctr *Container) error {
81
	return r.printError()
82
}
83

84
// StartContainer is not available as the runtime is missing
85
func (r *MissingRuntime) StartContainer(ctr *Container) error {
86
	return r.printError()
87
}
88

89
// UpdateContainer is not available as the runtime is missing
90
func (r *MissingRuntime) UpdateContainer(ctr *Container, resources *spec.LinuxResources) error {
91
	return r.printError()
92
}
93

94
// KillContainer is not available as the runtime is missing
95
// TODO: We could attempt to unix.Kill() the PID as recorded in the state if we
96
// really want to smooth things out? Won't be perfect, but if the container has
97
// a PID namespace it could be enough?
98
func (r *MissingRuntime) KillContainer(ctr *Container, signal uint, all bool) error {
99
	return r.printError()
100
}
101

102
// StopContainer is not available as the runtime is missing
103
func (r *MissingRuntime) StopContainer(ctr *Container, timeout uint, all bool) error {
104
	return r.printError()
105
}
106

107
// DeleteContainer is not available as the runtime is missing
108
func (r *MissingRuntime) DeleteContainer(ctr *Container) error {
109
	return r.printError()
110
}
111

112
// PauseContainer is not available as the runtime is missing
113
func (r *MissingRuntime) PauseContainer(ctr *Container) error {
114
	return r.printError()
115
}
116

117
// UnpauseContainer is not available as the runtime is missing
118
func (r *MissingRuntime) UnpauseContainer(ctr *Container) error {
119
	return r.printError()
120
}
121

122
// Attach is not available as the runtime is missing
123
func (r *MissingRuntime) Attach(ctr *Container, params *AttachOptions) error {
124
	return r.printError()
125
}
126

127
// HTTPAttach is not available as the runtime is missing
128
func (r *MissingRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, streamAttach, streamLogs bool) error {
129
	return r.printError()
130
}
131

132
// AttachResize is not available as the runtime is missing
133
func (r *MissingRuntime) AttachResize(ctr *Container, newSize resize.TerminalSize) error {
134
	return r.printError()
135
}
136

137
// ExecContainer is not available as the runtime is missing
138
func (r *MissingRuntime) ExecContainer(ctr *Container, sessionID string, options *ExecOptions, streams *define.AttachStreams, newSize *resize.TerminalSize) (int, chan error, error) {
139
	return -1, nil, r.printError()
140
}
141

142
// ExecContainerHTTP is not available as the runtime is missing
143
func (r *MissingRuntime) ExecContainerHTTP(ctr *Container, sessionID string, options *ExecOptions, req *http.Request, w http.ResponseWriter,
144
	streams *HTTPAttachStreams, cancel <-chan bool, hijackDone chan<- bool, holdConnOpen <-chan bool, newSize *resize.TerminalSize) (int, chan error, error) {
145
	return -1, nil, r.printError()
146
}
147

148
// ExecContainerDetached is not available as the runtime is missing
149
func (r *MissingRuntime) ExecContainerDetached(ctr *Container, sessionID string, options *ExecOptions, stdin bool) (int, error) {
150
	return -1, r.printError()
151
}
152

153
// ExecAttachResize is not available as the runtime is missing.
154
func (r *MissingRuntime) ExecAttachResize(ctr *Container, sessionID string, newSize resize.TerminalSize) error {
155
	return r.printError()
156
}
157

158
// ExecStopContainer is not available as the runtime is missing.
159
// TODO: We can also investigate using unix.Kill() on the PID of the exec
160
// session here if we want to make stopping containers possible. Won't be
161
// perfect, though.
162
func (r *MissingRuntime) ExecStopContainer(ctr *Container, sessionID string, timeout uint) error {
163
	return r.printError()
164
}
165

166
// ExecUpdateStatus is not available as the runtime is missing.
167
func (r *MissingRuntime) ExecUpdateStatus(ctr *Container, sessionID string) (bool, error) {
168
	return false, r.printError()
169
}
170

171
// CheckpointContainer is not available as the runtime is missing
172
func (r *MissingRuntime) CheckpointContainer(ctr *Container, options ContainerCheckpointOptions) (int64, error) {
173
	return 0, r.printError()
174
}
175

176
// CheckConmonRunning is not available as the runtime is missing
177
func (r *MissingRuntime) CheckConmonRunning(ctr *Container) (bool, error) {
178
	return false, r.printError()
179
}
180

181
// SupportsCheckpoint returns false as checkpointing requires a working runtime
182
func (r *MissingRuntime) SupportsCheckpoint() bool {
183
	return false
184
}
185

186
// SupportsJSONErrors returns false as there is no runtime to give errors
187
func (r *MissingRuntime) SupportsJSONErrors() bool {
188
	return false
189
}
190

191
// SupportsNoCgroups returns false as there is no runtime to create containers
192
func (r *MissingRuntime) SupportsNoCgroups() bool {
193
	return false
194
}
195

196
// SupportsKVM checks if the OCI runtime supports running containers
197
// without KVM separation
198
func (r *MissingRuntime) SupportsKVM() bool {
199
	return false
200
}
201

202
// AttachSocketPath does not work as there is no runtime to attach to.
203
// (Theoretically we could follow ExitFilePath but there is no guarantee the
204
// container is running and thus has an attach socket...)
205
func (r *MissingRuntime) AttachSocketPath(ctr *Container) (string, error) {
206
	return "", r.printError()
207
}
208

209
// ExecAttachSocketPath does not work as there is no runtime to attach to.
210
// (Again, we could follow ExitFilePath, but no guarantee there is an existing
211
// and running exec session)
212
func (r *MissingRuntime) ExecAttachSocketPath(ctr *Container, sessionID string) (string, error) {
213
	return "", r.printError()
214
}
215

216
// ExitFilePath returns the exit file path for containers.
217
// Here, we mimic what ConmonOCIRuntime does, because there is a chance that the
218
// container in question is still running happily (config file modified to
219
// remove a runtime, for example). We can't find the runtime to do anything to
220
// the container, but Conmon should still place an exit file for it.
221
func (r *MissingRuntime) ExitFilePath(ctr *Container) (string, error) {
222
	if ctr == nil {
223
		return "", fmt.Errorf("must provide a valid container to get exit file path: %w", define.ErrInvalidArg)
224
	}
225
	return filepath.Join(r.exitsDir, ctr.ID()), nil
226
}
227

228
// OOMFilePath returns the oom file path for a container.
229
// The oom file will only exist if the container was oom killed.
230
func (r *MissingRuntime) OOMFilePath(ctr *Container) (string, error) {
231
	return filepath.Join(r.persistDir, ctr.ID(), "oom"), nil
232
}
233

234
// RuntimeInfo returns information on the missing runtime
235
func (r *MissingRuntime) RuntimeInfo() (*define.ConmonInfo, *define.OCIRuntimeInfo, error) {
236
	ocirt := define.OCIRuntimeInfo{
237
		Name:    r.name,
238
		Path:    "missing",
239
		Package: "missing",
240
		Version: "missing",
241
	}
242
	return nil, &ocirt, nil
243
}
244

245
// Return an error indicating the runtime is missing
246
func (r *MissingRuntime) printError() error {
247
	return fmt.Errorf("runtime %s is missing: %w", r.name, define.ErrOCIRuntimeNotFound)
248
}
249

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

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

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

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