aboutsummaryrefslogtreecommitdiff
path: root/libpod/state.go
blob: 21525107fd3c60d4e1b5a8fc248f4735fa43aa13 (plain)
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
package libpod

import "github.com/containers/podman/v3/libpod/network/types"

// State is a storage backend for libpod's current state.
// A State is only initialized once per instance of libpod.
// As such, initialization methods for State implementations may safely assume
// they will be run as a singleton.
// For all container and pod retrieval methods, a State must retrieve the
// Configuration struct of the container or pod and include it in the returned
// struct. The State of the container or pod may optionally be included as well,
// but this is not a requirement.
// As such, all containers and pods must be synced with the database via the
// UpdateContainer and UpdatePod calls before any state-specific information is
// retrieved after they are pulled from the database.
// Generally speaking, the syncContainer() call should be run at the beginning
// of all API operations, which will silently handle this.
type State interface {
	// Close performs any pre-exit cleanup (e.g. closing database
	// connections) that may be required
	Close() error

	// Refresh clears container and pod states after a reboot
	Refresh() error

	// GetDBConfig retrieves several paths configured within the database
	// when it was created - namely, Libpod root and tmp dirs, c/storage
	// root and tmp dirs, and c/storage graph driver.
	// This is not implemented by the in-memory state, as it has no need to
	// validate runtime configuration.
	GetDBConfig() (*DBConfig, error)

	// ValidateDBConfig validates the config in the given Runtime struct
	// against paths stored in the configured database.
	// Libpod root and tmp dirs and c/storage root and tmp dirs and graph
	// driver are validated.
	// This is not implemented by the in-memory state, as it has no need to
	// validate runtime configuration that may change over multiple runs of
	// the program.
	ValidateDBConfig(runtime *Runtime) error

	// SetNamespace() sets the namespace for the store, and will determine
	// what containers are retrieved with container and pod retrieval calls.
	// A namespace of "", the empty string, acts as no namespace, and
	// containers and pods in all namespaces will be returned.
	SetNamespace(ns string) error

	// Resolve an ID into a Name. Since Podman names and IDs are globally
	// unique between Pods and Containers, the ID may belong to either a pod
	// or container. Despite this, we will always return ErrNoSuchCtr if the
	// ID does not exist.
	GetName(id string) (string, error)

	// Return a container from the database from its full ID.
	// If the container is not in the set namespace, an error will be
	// returned.
	Container(id string) (*Container, error)
	// Return a container ID from the database by full or partial ID or full
	// name.
	LookupContainerID(idOrName string) (string, error)
	// Return a container from the database by full or partial ID or full
	// name.
	// Containers not in the set namespace will be ignored.
	LookupContainer(idOrName string) (*Container, error)
	// Check if a container with the given full ID exists in the database.
	// If the container exists but is not in the set namespace, false will
	// be returned.
	HasContainer(id string) (bool, error)
	// Adds container to state.
	// The container cannot be part of a pod.
	// The container must have globally unique name and ID - pod names and
	// IDs also conflict with container names and IDs.
	// The container must be in the set namespace if a namespace has been
	// set.
	// All containers this container depends on must be part of the same
	// namespace and must not be joined to a pod.
	AddContainer(ctr *Container) error
	// Removes container from state.
	// Containers that are part of pods must use RemoveContainerFromPod.
	// The container must be part of the set namespace.
	// All dependencies must be removed first.
	// All exec sessions referencing the container must be removed first.
	RemoveContainer(ctr *Container) error
	// UpdateContainer updates a container's state from the backing store.
	// The container must be part of the set namespace.
	UpdateContainer(ctr *Container) error
	// SaveContainer saves a container's current state to the backing store.
	// The container must be part of the set namespace.
	SaveContainer(ctr *Container) error
	// ContainerInUse checks if other containers depend upon a given
	// container.
	// It returns a slice of the IDs of containers which depend on the given
	// container. If the slice is empty, no container depend on the given
	// container.
	// A container cannot be removed if other containers depend on it.
	// The container being checked must be part of the set namespace.
	ContainerInUse(ctr *Container) ([]string, error)
	// Retrieves all containers presently in state.
	// If a namespace is set, only containers within the namespace will be
	// returned.
	AllContainers() ([]*Container, error)

	// Get networks the container is currently connected to.
	GetNetworks(ctr *Container) (map[string]types.PerNetworkOptions, error)
	// Add the container to the given network with the given options
	NetworkConnect(ctr *Container, network string, opts types.PerNetworkOptions) error
	// Remove the container from the given network, removing all aliases for
	// the container in that network in the process.
	NetworkDisconnect(ctr *Container, network string) error

	// Return a container config from the database by full ID
	GetContainerConfig(id string) (*ContainerConfig, error)

	// Add creates a reference to an exec session in the database.
	// The container the exec session is attached to will be recorded.
	// The container state will not be modified.
	// The actual exec session itself is part of the container's state.
	// We assume higher-level callers will add the session by saving the
	// container's state before calling this. This only ensures that the ID
	// of the exec session is associated with the ID of the container.
	// Implementations may, but are not required to, verify that the state
	// of the given container has an exec session with the ID given.
	AddExecSession(ctr *Container, session *ExecSession) error
	// Get retrieves the container a given exec session is attached to.
	GetExecSession(id string) (string, error)
	// Remove a reference to an exec session from the database.
	// This will not modify container state to remove the exec session there
	// and instead only removes the session ID -> container ID reference
	// added by AddExecSession.
	RemoveExecSession(session *ExecSession) error
	// Get the IDs of all exec sessions attached to a given container.
	GetContainerExecSessions(ctr *Container) ([]string, error)
	// Remove all exec sessions for a single container.
	// Usually used as part of removing the container.
	// As with RemoveExecSession, container state will not be modified.
	RemoveContainerExecSessions(ctr *Container) error

	// PLEASE READ FULL DESCRIPTION BEFORE USING.
	// Rewrite a container's configuration.
	// This function breaks libpod's normal prohibition on a read-only
	// configuration, and as such should be used EXTREMELY SPARINGLY and
	// only in very specific circumstances.
	// Specifically, it is ONLY safe to use thing function to make changes
	// that result in a functionally identical configuration (migrating to
	// newer, but identical, configuration fields), or during libpod init
	// WHILE HOLDING THE ALIVE LOCK (to prevent other libpod instances from
	// being initialized).
	// Most things in config can be changed by this, but container ID and
	// name ABSOLUTELY CANNOT BE ALTERED. If you do so, there is a high
	// potential for database corruption.
	// There are a lot of capital letters and conditions here, but the short
	// answer is this: use this only very sparingly, and only if you really
	// know what you're doing.
	RewriteContainerConfig(ctr *Container, newCfg *ContainerConfig) error
	// This is a more limited version of RewriteContainerConfig, though it
	// comes with the added ability to alter a container's name. In exchange
	// it loses the ability to manipulate the container's locks.
	// It is not intended to be as restrictive as RewriteContainerConfig, in
	// that we allow it to be run while other Podman processes are running,
	// and without holding the alive lock.
	// Container ID and pod membership still *ABSOLUTELY CANNOT* be altered.
	// Also, you cannot change a container's dependencies - shared namespace
	// containers or generic dependencies - at present. This is
	// theoretically possible but not yet implemented.
	// If newName is not "" the container will be renamed to the new name.
	// The oldName parameter is only required if newName is given.
	SafeRewriteContainerConfig(ctr *Container, oldName, newName string, newCfg *ContainerConfig) error
	// PLEASE READ THE DESCRIPTION FOR RewriteContainerConfig BEFORE USING.
	// This function is identical to RewriteContainerConfig, save for the
	// fact that it is used with pods instead.
	// It is subject to the same conditions as RewriteContainerConfig.
	// Please do not use this unless you know what you're doing.
	RewritePodConfig(pod *Pod, newCfg *PodConfig) error
	// PLEASE READ THE DESCRIPTION FOR RewriteContainerConfig BEFORE USING.
	// This function is identical to RewriteContainerConfig, save for the
	// fact that it is used with volumes instead.
	// It is subject to the same conditions as RewriteContainerConfig.
	// The exception is that volumes do not have IDs, so only volume name
	// cannot be altered.
	// Please do not use this unless you know what you're doing.
	RewriteVolumeConfig(volume *Volume, newCfg *VolumeConfig) error

	// Accepts full ID of pod.
	// If the pod given is not in the set namespace, an error will be
	// returned.
	Pod(id string) (*Pod, error)
	// Accepts full or partial IDs (as long as they are unique) and names.
	// Pods not in the set namespace are ignored.
	LookupPod(idOrName string) (*Pod, error)
	// Checks if a pod with the given ID is present in the state.
	// If the given pod is not in the set namespace, false is returned.
	HasPod(id string) (bool, error)
	// Check if a pod has a container with the given ID.
	// The pod must be part of the set namespace.
	PodHasContainer(pod *Pod, ctrID string) (bool, error)
	// Get the IDs of all containers in a pod.
	// The pod must be part of the set namespace.
	PodContainersByID(pod *Pod) ([]string, error)
	// Get all the containers in a pod.
	// The pod must be part of the set namespace.
	PodContainers(pod *Pod) ([]*Container, error)
	// Adds pod to state.
	// The pod must be part of the set namespace.
	// The pod's name and ID must be globally unique.
	AddPod(pod *Pod) error
	// Removes pod from state.
	// Only empty pods can be removed from the state.
	// The pod must be part of the set namespace.
	RemovePod(pod *Pod) error
	// Remove all containers from a pod.
	// Used to simultaneously remove containers that might otherwise have
	// dependency issues.
	// Will fail if a dependency outside the pod is encountered.
	// The pod must be part of the set namespace.
	RemovePodContainers(pod *Pod) error
	// AddContainerToPod adds a container to an existing pod.
	// The container given will be added to the state and the pod.
	// The container and its dependencies must be part of the given pod,
	// and the given pod's namespace.
	// The pod must be part of the set namespace.
	// The pod must already exist in the state.
	// The container's name and ID must be globally unique.
	AddContainerToPod(pod *Pod, ctr *Container) error
	// RemoveContainerFromPod removes a container from an existing pod.
	// The container will also be removed from the state.
	// The container must be in the given pod, and the pod must be in the
	// set namespace.
	RemoveContainerFromPod(pod *Pod, ctr *Container) error
	// UpdatePod updates a pod's state from the database.
	// The pod must be in the set namespace.
	UpdatePod(pod *Pod) error
	// SavePod saves a pod's state to the database.
	// The pod must be in the set namespace.
	SavePod(pod *Pod) error
	// Retrieves all pods presently in state.
	// If a namespace has been set, only pods in that namespace will be
	// returned.
	AllPods() ([]*Pod, error)

	// Volume accepts full name of volume
	// If the volume doesn't exist, an error will be returned
	Volume(volName string) (*Volume, error)
	// LookupVolume accepts an unambiguous partial name or full name of a
	// volume. Ambiguous names will result in an error.
	LookupVolume(name string) (*Volume, error)
	// HasVolume returns true if volName exists in the state,
	// otherwise it returns false
	HasVolume(volName string) (bool, error)
	// VolumeInUse goes through the container dependencies of a volume
	// and checks if the volume is being used by any container. If it is
	// a slice of container IDs using the volume is returned
	VolumeInUse(volume *Volume) ([]string, error)
	// AddVolume adds the specified volume to state. The volume's name
	// must be unique within the list of existing volumes
	AddVolume(volume *Volume) error
	// RemoveVolume removes the specified volume.
	// Only volumes that have no container dependencies can be removed
	RemoveVolume(volume *Volume) error
	// UpdateVolume updates the volume's state from the database.
	UpdateVolume(volume *Volume) error
	// SaveVolume saves a volume's state to the database.
	SaveVolume(volume *Volume) error
	// AllVolumes returns all the volumes available in the state
	AllVolumes() ([]*Volume, error)
}