10
"github.com/containers/podman/v5/libpod/define"
11
"github.com/containers/storage"
12
"github.com/sirupsen/logrus"
15
// StorageContainer represents a container present in c/storage but not in
17
type StorageContainer struct {
25
// ListStorageContainers lists all containers visible to c/storage.
26
func (r *Runtime) ListStorageContainers() ([]*StorageContainer, error) {
27
finalCtrs := []*StorageContainer{}
29
ctrs, err := r.store.Containers()
34
for _, ctr := range ctrs {
35
storageCtr := new(StorageContainer)
36
storageCtr.ID = ctr.ID
37
storageCtr.Names = ctr.Names
38
storageCtr.Image = ctr.ImageID
39
storageCtr.CreateTime = ctr.Created
41
// Look up if container is in state
42
hasCtr, err := r.state.HasContainer(ctr.ID)
44
return nil, fmt.Errorf("looking up container %s in state: %w", ctr.ID, err)
47
storageCtr.PresentInLibpod = hasCtr
49
finalCtrs = append(finalCtrs, storageCtr)
55
func (r *Runtime) StorageContainer(idOrName string) (*storage.Container, error) {
56
return r.store.Container(idOrName)
59
// RemoveStorageContainer removes a container from c/storage.
60
// The container WILL NOT be removed if it exists in libpod.
61
// Accepts ID or full name of container.
62
// If force is set, the container will be unmounted first to ensure removal.
63
func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error {
64
targetID, err := r.store.Lookup(idOrName)
66
if errors.Is(err, storage.ErrLayerUnknown) {
67
return fmt.Errorf("no container with ID or name %q found: %w", idOrName, define.ErrNoSuchCtr)
69
return fmt.Errorf("looking up container %q: %w", idOrName, err)
72
// Lookup returns an ID but it's not guaranteed to be a container ID.
73
// So we can still error here.
74
ctr, err := r.store.Container(targetID)
76
if errors.Is(err, storage.ErrContainerUnknown) {
77
return fmt.Errorf("%q does not refer to a container: %w", idOrName, define.ErrNoSuchCtr)
79
return fmt.Errorf("retrieving container %q: %w", idOrName, err)
82
// Error out if the container exists in libpod
83
exists, err := r.state.HasContainer(ctr.ID)
88
return fmt.Errorf("refusing to remove %q as it exists in libpod as container %s: %w", idOrName, ctr.ID, define.ErrCtrExists)
91
// Error out if this is an image-backed volume
92
allVols, err := r.state.AllVolumes()
96
for _, vol := range allVols {
97
if vol.config.Driver == define.VolumeDriverImage && vol.config.StorageID == ctr.ID {
98
return fmt.Errorf("refusing to remove %q as it exists in libpod as an image-backed volume %s: %w", idOrName, vol.Name(), define.ErrCtrExists)
103
timesMounted, err := r.store.Mounted(ctr.ID)
105
if errors.Is(err, storage.ErrContainerUnknown) {
106
// Container was removed from under us.
107
// It's gone, so don't bother erroring.
108
logrus.Infof("Storage for container %s already removed", ctr.ID)
111
logrus.Warnf("Checking if container %q is mounted, attempting to delete: %v", idOrName, err)
113
if timesMounted > 0 {
114
return fmt.Errorf("container %q is mounted and cannot be removed without using force: %w", idOrName, define.ErrCtrStateInvalid)
116
} else if _, err := r.store.Unmount(ctr.ID, true); err != nil {
117
if errors.Is(err, storage.ErrContainerUnknown) {
118
// Container again gone, no error
119
logrus.Infof("Storage for container %s already removed", ctr.ID)
122
logrus.Warnf("Unmounting container %q while attempting to delete storage: %v", idOrName, err)
125
if err := r.store.DeleteContainer(ctr.ID); err != nil {
126
if errors.Is(err, storage.ErrNotAContainer) || errors.Is(err, storage.ErrContainerUnknown) {
127
// Container again gone, no error
128
logrus.Infof("Storage for container %s already removed", ctr.ID)
131
return fmt.Errorf("removing storage for container %q: %w", idOrName, err)