github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/domain/infra/abi/pods.go (about) 1 package abi 2 3 import ( 4 "context" 5 6 "github.com/containers/podman/v2/libpod" 7 "github.com/containers/podman/v2/libpod/define" 8 lpfilters "github.com/containers/podman/v2/libpod/filters" 9 "github.com/containers/podman/v2/pkg/domain/entities" 10 "github.com/containers/podman/v2/pkg/signal" 11 "github.com/containers/podman/v2/pkg/specgen" 12 "github.com/containers/podman/v2/pkg/specgen/generate" 13 "github.com/pkg/errors" 14 "github.com/sirupsen/logrus" 15 ) 16 17 // getPodsByContext returns a slice of pods. Note that all, latest and pods are 18 // mutually exclusive arguments. 19 func getPodsByContext(all, latest bool, pods []string, runtime *libpod.Runtime) ([]*libpod.Pod, error) { 20 var outpods []*libpod.Pod 21 if all { 22 return runtime.GetAllPods() 23 } 24 if latest { 25 p, err := runtime.GetLatestPod() 26 if err != nil { 27 return nil, err 28 } 29 outpods = append(outpods, p) 30 return outpods, nil 31 } 32 var err error 33 for _, p := range pods { 34 pod, e := runtime.LookupPod(p) 35 if e != nil { 36 // Log all errors here, so callers don't need to. 37 logrus.Debugf("Error looking up pod %q: %v", p, e) 38 if err == nil { 39 err = e 40 } 41 } else { 42 outpods = append(outpods, pod) 43 } 44 } 45 return outpods, err 46 } 47 48 func (ic *ContainerEngine) PodExists(ctx context.Context, nameOrID string) (*entities.BoolReport, error) { 49 _, err := ic.Libpod.LookupPod(nameOrID) 50 if err != nil && errors.Cause(err) != define.ErrNoSuchPod { 51 return nil, err 52 } 53 return &entities.BoolReport{Value: err == nil}, nil 54 } 55 56 func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, options entities.PodKillOptions) ([]*entities.PodKillReport, error) { 57 reports := []*entities.PodKillReport{} 58 sig, err := signal.ParseSignalNameOrNumber(options.Signal) 59 if err != nil { 60 return nil, err 61 } 62 pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod) 63 if err != nil { 64 return nil, err 65 } 66 67 for _, p := range pods { 68 report := entities.PodKillReport{Id: p.ID()} 69 conErrs, err := p.Kill(ctx, uint(sig)) 70 if err != nil && errors.Cause(err) != define.ErrPodPartialFail { 71 report.Errs = []error{err} 72 reports = append(reports, &report) 73 continue 74 } 75 if len(conErrs) > 0 { 76 for id, err := range conErrs { 77 report.Errs = append(report.Errs, errors.Wrapf(err, "error killing container %s", id)) 78 } 79 reports = append(reports, &report) 80 continue 81 } 82 reports = append(reports, &report) 83 } 84 return reports, nil 85 } 86 87 func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) { 88 reports := []*entities.PodPauseReport{} 89 pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod) 90 if err != nil { 91 return nil, err 92 } 93 for _, p := range pods { 94 report := entities.PodPauseReport{Id: p.ID()} 95 errs, err := p.Pause(ctx) 96 if err != nil && errors.Cause(err) != define.ErrPodPartialFail { 97 report.Errs = []error{err} 98 continue 99 } 100 if len(errs) > 0 { 101 for id, v := range errs { 102 report.Errs = append(report.Errs, errors.Wrapf(v, "error pausing container %s", id)) 103 } 104 reports = append(reports, &report) 105 continue 106 } 107 reports = append(reports, &report) 108 } 109 return reports, nil 110 } 111 112 func (ic *ContainerEngine) PodUnpause(ctx context.Context, namesOrIds []string, options entities.PodunpauseOptions) ([]*entities.PodUnpauseReport, error) { 113 reports := []*entities.PodUnpauseReport{} 114 pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod) 115 if err != nil { 116 return nil, err 117 } 118 for _, p := range pods { 119 report := entities.PodUnpauseReport{Id: p.ID()} 120 errs, err := p.Unpause(ctx) 121 if err != nil && errors.Cause(err) != define.ErrPodPartialFail { 122 report.Errs = []error{err} 123 continue 124 } 125 if len(errs) > 0 { 126 for id, v := range errs { 127 report.Errs = append(report.Errs, errors.Wrapf(v, "error unpausing container %s", id)) 128 } 129 reports = append(reports, &report) 130 continue 131 } 132 reports = append(reports, &report) 133 } 134 return reports, nil 135 } 136 137 func (ic *ContainerEngine) PodStop(ctx context.Context, namesOrIds []string, options entities.PodStopOptions) ([]*entities.PodStopReport, error) { 138 reports := []*entities.PodStopReport{} 139 pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod) 140 if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchPod) { 141 return nil, err 142 } 143 for _, p := range pods { 144 report := entities.PodStopReport{Id: p.ID()} 145 errs, err := p.StopWithTimeout(ctx, false, options.Timeout) 146 if err != nil && errors.Cause(err) != define.ErrPodPartialFail { 147 report.Errs = []error{err} 148 continue 149 } 150 if len(errs) > 0 { 151 for id, v := range errs { 152 report.Errs = append(report.Errs, errors.Wrapf(v, "error stopping container %s", id)) 153 } 154 reports = append(reports, &report) 155 continue 156 } 157 reports = append(reports, &report) 158 } 159 return reports, nil 160 } 161 162 func (ic *ContainerEngine) PodRestart(ctx context.Context, namesOrIds []string, options entities.PodRestartOptions) ([]*entities.PodRestartReport, error) { 163 reports := []*entities.PodRestartReport{} 164 pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod) 165 if err != nil { 166 return nil, err 167 } 168 for _, p := range pods { 169 report := entities.PodRestartReport{Id: p.ID()} 170 errs, err := p.Restart(ctx) 171 if err != nil && errors.Cause(err) != define.ErrPodPartialFail { 172 report.Errs = []error{err} 173 reports = append(reports, &report) 174 continue 175 } 176 if len(errs) > 0 { 177 for id, v := range errs { 178 report.Errs = append(report.Errs, errors.Wrapf(v, "error restarting container %s", id)) 179 } 180 reports = append(reports, &report) 181 continue 182 } 183 reports = append(reports, &report) 184 } 185 return reports, nil 186 } 187 188 func (ic *ContainerEngine) PodStart(ctx context.Context, namesOrIds []string, options entities.PodStartOptions) ([]*entities.PodStartReport, error) { 189 reports := []*entities.PodStartReport{} 190 pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod) 191 if err != nil { 192 return nil, err 193 } 194 195 for _, p := range pods { 196 report := entities.PodStartReport{Id: p.ID()} 197 errs, err := p.Start(ctx) 198 if err != nil && errors.Cause(err) != define.ErrPodPartialFail { 199 report.Errs = []error{err} 200 reports = append(reports, &report) 201 continue 202 } 203 if len(errs) > 0 { 204 for id, v := range errs { 205 report.Errs = append(report.Errs, errors.Wrapf(v, "error starting container %s", id)) 206 } 207 reports = append(reports, &report) 208 continue 209 } 210 reports = append(reports, &report) 211 } 212 return reports, nil 213 } 214 215 func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, options entities.PodRmOptions) ([]*entities.PodRmReport, error) { 216 pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod) 217 if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchPod) { 218 return nil, err 219 } 220 reports := make([]*entities.PodRmReport, 0, len(pods)) 221 for _, p := range pods { 222 report := entities.PodRmReport{Id: p.ID()} 223 err := ic.Libpod.RemovePod(ctx, p, true, options.Force) 224 if err != nil { 225 report.Err = err 226 } 227 reports = append(reports, &report) 228 } 229 return reports, nil 230 } 231 232 func (ic *ContainerEngine) PodPrune(ctx context.Context, options entities.PodPruneOptions) ([]*entities.PodPruneReport, error) { 233 return ic.prunePodHelper(ctx) 234 } 235 236 func (ic *ContainerEngine) prunePodHelper(ctx context.Context) ([]*entities.PodPruneReport, error) { 237 response, err := ic.Libpod.PrunePods(ctx) 238 if err != nil { 239 return nil, err 240 } 241 reports := make([]*entities.PodPruneReport, 0, len(response)) 242 for k, v := range response { 243 reports = append(reports, &entities.PodPruneReport{ 244 Err: v, 245 Id: k, 246 }) 247 } 248 return reports, nil 249 } 250 251 func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) { 252 podSpec := specgen.NewPodSpecGenerator() 253 opts.ToPodSpecGen(podSpec) 254 pod, err := generate.MakePod(podSpec, ic.Libpod) 255 if err != nil { 256 return nil, err 257 } 258 return &entities.PodCreateReport{Id: pod.ID()}, nil 259 } 260 261 func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOptions) (*entities.StringSliceReport, error) { 262 var ( 263 pod *libpod.Pod 264 err error 265 ) 266 267 // Look up the pod. 268 if options.Latest { 269 pod, err = ic.Libpod.GetLatestPod() 270 } else { 271 pod, err = ic.Libpod.LookupPod(options.NameOrID) 272 } 273 if err != nil { 274 return nil, errors.Wrap(err, "unable to lookup requested container") 275 } 276 277 // Run Top. 278 report := &entities.StringSliceReport{} 279 report.Value, err = pod.GetPodPidInformation(options.Descriptors) 280 return report, err 281 } 282 283 func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOptions) ([]*entities.ListPodsReport, error) { 284 var ( 285 err error 286 pds = []*libpod.Pod{} 287 ) 288 289 filters := make([]libpod.PodFilter, 0, len(options.Filters)) 290 for k, v := range options.Filters { 291 f, err := lpfilters.GeneratePodFilterFunc(k, v) 292 if err != nil { 293 return nil, err 294 } 295 filters = append(filters, f) 296 } 297 if options.Latest { 298 pod, err := ic.Libpod.GetLatestPod() 299 if err != nil { 300 return nil, err 301 } 302 pds = append(pds, pod) 303 } else { 304 pds, err = ic.Libpod.Pods(filters...) 305 if err != nil { 306 return nil, err 307 } 308 } 309 310 reports := make([]*entities.ListPodsReport, 0, len(pds)) 311 for _, p := range pds { 312 var lpcs []*entities.ListPodContainer 313 status, err := p.GetPodStatus() 314 if err != nil { 315 return nil, err 316 } 317 cons, err := p.AllContainers() 318 if err != nil { 319 return nil, err 320 } 321 for _, c := range cons { 322 state, err := c.State() 323 if err != nil { 324 return nil, err 325 } 326 lpcs = append(lpcs, &entities.ListPodContainer{ 327 Id: c.ID(), 328 Names: c.Name(), 329 Status: state.String(), 330 }) 331 } 332 infraID, err := p.InfraContainerID() 333 if err != nil { 334 return nil, err 335 } 336 reports = append(reports, &entities.ListPodsReport{ 337 Cgroup: p.CgroupParent(), 338 Containers: lpcs, 339 Created: p.CreatedTime(), 340 Id: p.ID(), 341 InfraId: infraID, 342 Name: p.Name(), 343 Namespace: p.Namespace(), 344 Status: status, 345 Labels: p.Labels(), 346 }) 347 } 348 return reports, nil 349 } 350 351 func (ic *ContainerEngine) PodInspect(ctx context.Context, options entities.PodInspectOptions) (*entities.PodInspectReport, error) { 352 var ( 353 pod *libpod.Pod 354 err error 355 ) 356 // Look up the pod. 357 if options.Latest { 358 pod, err = ic.Libpod.GetLatestPod() 359 } else { 360 pod, err = ic.Libpod.LookupPod(options.NameOrID) 361 } 362 if err != nil { 363 return nil, errors.Wrap(err, "unable to lookup requested container") 364 } 365 inspect, err := pod.Inspect() 366 if err != nil { 367 return nil, err 368 } 369 return &entities.PodInspectReport{InspectPodData: inspect}, nil 370 }