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  }