github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/libpod/runtime_cstorage.go (about) 1 package libpod 2 3 import ( 4 "time" 5 6 "github.com/containers/libpod/libpod/define" 7 "github.com/containers/storage" 8 "github.com/pkg/errors" 9 "github.com/sirupsen/logrus" 10 ) 11 12 // StorageContainer represents a container present in c/storage but not in 13 // libpod. 14 type StorageContainer struct { 15 ID string 16 Names []string 17 Image string 18 CreateTime time.Time 19 PresentInLibpod bool 20 } 21 22 // ListStorageContainers lists all containers visible to c/storage. 23 func (r *Runtime) ListStorageContainers() ([]*StorageContainer, error) { 24 r.lock.RLock() 25 defer r.lock.RUnlock() 26 27 finalCtrs := []*StorageContainer{} 28 29 ctrs, err := r.store.Containers() 30 if err != nil { 31 return nil, err 32 } 33 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 40 41 // Look up if container is in state 42 hasCtr, err := r.state.HasContainer(ctr.ID) 43 if err != nil { 44 return nil, errors.Wrapf(err, "error looking up container %s in state", ctr.ID) 45 } 46 47 storageCtr.PresentInLibpod = hasCtr 48 49 finalCtrs = append(finalCtrs, storageCtr) 50 } 51 52 return finalCtrs, nil 53 } 54 55 // RemoveStorageContainer removes a container from c/storage. 56 // The container WILL NOT be removed if it exists in libpod. 57 // Accepts ID or full name of container. 58 // If force is set, the container will be unmounted first to ensure removal. 59 func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error { 60 r.lock.Lock() 61 defer r.lock.Unlock() 62 63 return r.removeStorageContainer(idOrName, force) 64 } 65 66 // Internal function to remove the container storage without 67 // locking the runtime. 68 func (r *Runtime) removeStorageContainer(idOrName string, force bool) error { 69 targetID, err := r.store.Lookup(idOrName) 70 if err != nil { 71 if errors.Cause(err) == storage.ErrLayerUnknown { 72 return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID or name %q found", idOrName) 73 } 74 return errors.Wrapf(err, "error looking up container %q", idOrName) 75 } 76 77 // Lookup returns an ID but it's not guaranteed to be a container ID. 78 // So we can still error here. 79 ctr, err := r.store.Container(targetID) 80 if err != nil { 81 if errors.Cause(err) == storage.ErrContainerUnknown { 82 return errors.Wrapf(define.ErrNoSuchCtr, "%q does not refer to a container", idOrName) 83 } 84 return errors.Wrapf(err, "error retrieving container %q", idOrName) 85 } 86 87 // Error out if the container exists in libpod 88 exists, err := r.state.HasContainer(ctr.ID) 89 if err != nil { 90 return err 91 } 92 if exists { 93 return errors.Wrapf(define.ErrCtrExists, "refusing to remove %q as it exists in libpod as container %s", idOrName, ctr.ID) 94 } 95 96 if !force { 97 timesMounted, err := r.store.Mounted(ctr.ID) 98 if err != nil { 99 if errors.Cause(err) == storage.ErrContainerUnknown { 100 // Container was removed from under us. 101 // It's gone, so don't bother erroring. 102 logrus.Warnf("Storage for container %s already removed", ctr.ID) 103 return nil 104 } 105 return errors.Wrapf(err, "error looking up container %q mounts", idOrName) 106 } 107 if timesMounted > 0 { 108 return errors.Wrapf(define.ErrCtrStateInvalid, "container %q is mounted and cannot be removed without using force", idOrName) 109 } 110 } else if _, err := r.store.Unmount(ctr.ID, true); err != nil { 111 if errors.Cause(err) == storage.ErrContainerUnknown { 112 // Container again gone, no error 113 logrus.Warnf("Storage for container %s already removed", ctr.ID) 114 return nil 115 } 116 return errors.Wrapf(err, "error unmounting container %q", idOrName) 117 } 118 119 if err := r.store.DeleteContainer(ctr.ID); err != nil { 120 if errors.Cause(err) == storage.ErrContainerUnknown { 121 // Container again gone, no error 122 logrus.Warnf("Storage for container %s already removed", ctr.ID) 123 return nil 124 } 125 return errors.Wrapf(err, "error removing storage for container %q", idOrName) 126 } 127 128 return nil 129 }