github.com/AbhinandanKurakure/podman/v3@v3.4.10/libpod/runtime_pod.go (about) 1 package libpod 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/containers/podman/v3/libpod/define" 8 "github.com/containers/podman/v3/pkg/util" 9 "github.com/pkg/errors" 10 ) 11 12 // Contains the public Runtime API for pods 13 14 // A PodCreateOption is a functional option which alters the Pod created by 15 // NewPod 16 type PodCreateOption func(*Pod) error 17 18 // PodFilter is a function to determine whether a pod is included in command 19 // output. Pods to be outputted are tested using the function. A true return 20 // will include the pod, a false return will exclude it. 21 type PodFilter func(*Pod) bool 22 23 // RemovePod removes a pod 24 // If removeCtrs is specified, containers will be removed 25 // Otherwise, a pod that is not empty will return an error and not be removed 26 // If force is specified with removeCtrs, all containers will be stopped before 27 // being removed 28 // Otherwise, the pod will not be removed if any containers are running 29 func (r *Runtime) RemovePod(ctx context.Context, p *Pod, removeCtrs, force bool) error { 30 r.lock.Lock() 31 defer r.lock.Unlock() 32 33 if !r.valid { 34 return define.ErrRuntimeStopped 35 } 36 37 if !p.valid { 38 if ok, _ := r.state.HasPod(p.ID()); !ok { 39 // Pod probably already removed 40 // Or was never in the runtime to begin with 41 return nil 42 } 43 } 44 45 p.lock.Lock() 46 defer p.lock.Unlock() 47 48 return r.removePod(ctx, p, removeCtrs, force) 49 } 50 51 // GetPod retrieves a pod by its ID 52 func (r *Runtime) GetPod(id string) (*Pod, error) { 53 r.lock.RLock() 54 defer r.lock.RUnlock() 55 56 if !r.valid { 57 return nil, define.ErrRuntimeStopped 58 } 59 60 return r.state.Pod(id) 61 } 62 63 // HasPod checks to see if a pod with the given ID exists 64 func (r *Runtime) HasPod(id string) (bool, error) { 65 r.lock.RLock() 66 defer r.lock.RUnlock() 67 68 if !r.valid { 69 return false, define.ErrRuntimeStopped 70 } 71 72 return r.state.HasPod(id) 73 } 74 75 // LookupPod retrieves a pod by its name or a partial ID 76 // If a partial ID is not unique, an error will be returned 77 func (r *Runtime) LookupPod(idOrName string) (*Pod, error) { 78 r.lock.RLock() 79 defer r.lock.RUnlock() 80 81 if !r.valid { 82 return nil, define.ErrRuntimeStopped 83 } 84 85 return r.state.LookupPod(idOrName) 86 } 87 88 // Pods retrieves all pods 89 // Filters can be provided which will determine which pods are included in the 90 // output. Multiple filters are handled by ANDing their output, so only pods 91 // matching all filters are returned 92 func (r *Runtime) Pods(filters ...PodFilter) ([]*Pod, error) { 93 pods, err := r.GetAllPods() 94 if err != nil { 95 return nil, err 96 } 97 podsFiltered := make([]*Pod, 0, len(pods)) 98 for _, pod := range pods { 99 include := true 100 for _, filter := range filters { 101 include = include && filter(pod) 102 } 103 104 if include { 105 podsFiltered = append(podsFiltered, pod) 106 } 107 } 108 109 return podsFiltered, nil 110 } 111 112 // GetAllPods retrieves all pods 113 func (r *Runtime) GetAllPods() ([]*Pod, error) { 114 r.lock.RLock() 115 defer r.lock.RUnlock() 116 117 if !r.valid { 118 return nil, define.ErrRuntimeStopped 119 } 120 121 return r.state.AllPods() 122 } 123 124 // GetLatestPod returns a pod object of the latest created pod. 125 func (r *Runtime) GetLatestPod() (*Pod, error) { 126 lastCreatedIndex := -1 127 var lastCreatedTime time.Time 128 pods, err := r.GetAllPods() 129 if err != nil { 130 return nil, errors.Wrapf(err, "unable to get all pods") 131 } 132 if len(pods) == 0 { 133 return nil, define.ErrNoSuchPod 134 } 135 for podIndex, pod := range pods { 136 createdTime := pod.config.CreatedTime 137 if createdTime.After(lastCreatedTime) { 138 lastCreatedTime = createdTime 139 lastCreatedIndex = podIndex 140 } 141 } 142 return pods[lastCreatedIndex], nil 143 } 144 145 // GetRunningPods returns an array of running pods 146 func (r *Runtime) GetRunningPods() ([]*Pod, error) { 147 var ( 148 pods []string 149 runningPods []*Pod 150 ) 151 r.lock.RLock() 152 defer r.lock.RUnlock() 153 154 if !r.valid { 155 return nil, define.ErrRuntimeStopped 156 } 157 containers, err := r.GetRunningContainers() 158 if err != nil { 159 return nil, err 160 } 161 // Assemble running pods 162 for _, c := range containers { 163 if !util.StringInSlice(c.PodID(), pods) { 164 pods = append(pods, c.PodID()) 165 pod, err := r.GetPod(c.PodID()) 166 if err != nil { 167 if errors.Cause(err) == define.ErrPodRemoved || errors.Cause(err) == define.ErrNoSuchPod { 168 continue 169 } 170 return nil, err 171 } 172 runningPods = append(runningPods, pod) 173 } 174 } 175 return runningPods, nil 176 } 177 178 // PrunePods removes unused pods and their containers from local storage. 179 func (r *Runtime) PrunePods(ctx context.Context) (map[string]error, error) { 180 response := make(map[string]error) 181 states := []string{define.PodStateStopped, define.PodStateExited} 182 filterFunc := func(p *Pod) bool { 183 state, _ := p.GetPodStatus() 184 for _, status := range states { 185 if state == status { 186 return true 187 } 188 } 189 return false 190 } 191 pods, err := r.Pods(filterFunc) 192 if err != nil { 193 return nil, err 194 } 195 if len(pods) < 1 { 196 return response, nil 197 } 198 for _, pod := range pods { 199 err := r.removePod(context.TODO(), pod, true, false) 200 response[pod.ID()] = err 201 } 202 return response, nil 203 }