github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/domain/infra/tunnel/helpers.go (about)

     1  package tunnel
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/hanks177/podman/v4/libpod/define"
     7  	"github.com/hanks177/podman/v4/pkg/bindings/containers"
     8  	"github.com/hanks177/podman/v4/pkg/bindings/pods"
     9  	"github.com/hanks177/podman/v4/pkg/domain/entities"
    10  	"github.com/hanks177/podman/v4/pkg/errorhandling"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  // FIXME: the `ignore` parameter is very likely wrong here as it should rather
    15  //        be used on *errors* from operations such as remove.
    16  func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) {
    17  	ctrs, _, err := getContainersAndInputByContext(contextWithConnection, all, ignore, namesOrIDs)
    18  	return ctrs, err
    19  }
    20  
    21  func getContainersAndInputByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, []string, error) {
    22  	if all && len(namesOrIDs) > 0 {
    23  		return nil, nil, errors.New("cannot lookup containers and all")
    24  	}
    25  	options := new(containers.ListOptions).WithAll(true).WithSync(true)
    26  	allContainers, err := containers.List(contextWithConnection, options)
    27  	if err != nil {
    28  		return nil, nil, err
    29  	}
    30  	rawInputs := []string{}
    31  	if all {
    32  		for i := range allContainers {
    33  			rawInputs = append(rawInputs, allContainers[i].ID)
    34  		}
    35  
    36  		return allContainers, rawInputs, err
    37  	}
    38  
    39  	// Note: it would be nicer if the lists endpoint would support that as
    40  	// we could use the libpod backend for looking up containers rather
    41  	// than risking diverging the local and remote lookups.
    42  	//
    43  	// A `--filter nameOrId=abc` that can be specified multiple times would
    44  	// be awesome to have.
    45  	filtered := []entities.ListContainer{}
    46  	for _, nameOrID := range namesOrIDs {
    47  		// First determine if the container exists by doing an inspect.
    48  		// Inspect takes supports names and IDs and let's us determine
    49  		// a containers full ID.
    50  		inspectData, err := containers.Inspect(contextWithConnection, nameOrID, new(containers.InspectOptions).WithSize(false))
    51  		if err != nil {
    52  			if ignore && errorhandling.Contains(err, define.ErrNoSuchCtr) {
    53  				continue
    54  			}
    55  			return nil, nil, err
    56  		}
    57  
    58  		// Now we can do a full match of the ID to find the right
    59  		// container. Note that we *really* need a full ID match to
    60  		// prevent any ambiguities between IDs and names (see #7837).
    61  		found := false
    62  		for _, ctr := range allContainers {
    63  			if ctr.ID == inspectData.ID {
    64  				filtered = append(filtered, ctr)
    65  				rawInputs = append(rawInputs, nameOrID)
    66  				found = true
    67  				break
    68  			}
    69  		}
    70  
    71  		if !found && !ignore {
    72  			return nil, nil, errors.Wrapf(define.ErrNoSuchCtr, "unable to find container %q", nameOrID)
    73  		}
    74  	}
    75  	return filtered, rawInputs, nil
    76  }
    77  
    78  func getPodsByContext(contextWithConnection context.Context, all bool, namesOrIDs []string) ([]*entities.ListPodsReport, error) {
    79  	if all && len(namesOrIDs) > 0 {
    80  		return nil, errors.New("cannot lookup specific pods and all")
    81  	}
    82  
    83  	allPods, err := pods.List(contextWithConnection, nil)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	if all {
    88  		return allPods, nil
    89  	}
    90  
    91  	filtered := []*entities.ListPodsReport{}
    92  	// Note: it would be nicer if the lists endpoint would support that as
    93  	// we could use the libpod backend for looking up pods rather than
    94  	// risking diverging the local and remote lookups.
    95  	//
    96  	// A `--filter nameOrId=abc` that can be specified multiple times would
    97  	// be awesome to have.
    98  	for _, nameOrID := range namesOrIDs {
    99  		// First determine if the pod exists by doing an inspect.
   100  		// Inspect takes supports names and IDs and let's us determine
   101  		// a containers full ID.
   102  		inspectData, err := pods.Inspect(contextWithConnection, nameOrID, nil)
   103  		if err != nil {
   104  			if errorhandling.Contains(err, define.ErrNoSuchPod) {
   105  				return nil, errors.Wrapf(define.ErrNoSuchPod, "unable to find pod %q", nameOrID)
   106  			}
   107  			return nil, err
   108  		}
   109  
   110  		// Now we can do a full match of the ID to find the right pod.
   111  		// Note that we *really* need a full ID match to prevent any
   112  		// ambiguities between IDs and names (see #7837).
   113  		found := false
   114  		for _, pod := range allPods {
   115  			if pod.Id == inspectData.ID {
   116  				filtered = append(filtered, pod)
   117  				found = true
   118  				break
   119  			}
   120  		}
   121  
   122  		if !found {
   123  			return nil, errors.Wrapf(define.ErrNoSuchPod, "unable to find pod %q", nameOrID)
   124  		}
   125  	}
   126  	return filtered, nil
   127  }