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

     1  package abi
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/containers/common/libnetwork/types"
     7  	netutil "github.com/containers/common/libnetwork/util"
     8  	"github.com/containers/common/pkg/util"
     9  	"github.com/hanks177/podman/v4/libpod/define"
    10  	"github.com/hanks177/podman/v4/pkg/domain/entities"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]types.Network, error) {
    15  	filters, err := netutil.GenerateNetworkFilters(options.Filters)
    16  	if err != nil {
    17  		return nil, err
    18  	}
    19  	nets, err := ic.Libpod.Network().NetworkList(filters...)
    20  	return nets, err
    21  }
    22  
    23  func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]types.Network, []error, error) {
    24  	var errs []error
    25  	networks := make([]types.Network, 0, len(namesOrIds))
    26  	for _, name := range namesOrIds {
    27  		net, err := ic.Libpod.Network().NetworkInspect(name)
    28  		if err != nil {
    29  			if errors.Cause(err) == define.ErrNoSuchNetwork {
    30  				errs = append(errs, errors.Wrapf(err, "network %s", name))
    31  				continue
    32  			} else {
    33  				return nil, nil, errors.Wrapf(err, "error inspecting network %s", name)
    34  			}
    35  		}
    36  		networks = append(networks, net)
    37  	}
    38  	return networks, errs, nil
    39  }
    40  
    41  func (ic *ContainerEngine) NetworkReload(ctx context.Context, names []string, options entities.NetworkReloadOptions) ([]*entities.NetworkReloadReport, error) {
    42  	ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	reports := make([]*entities.NetworkReloadReport, 0, len(ctrs))
    48  	for _, ctr := range ctrs {
    49  		report := new(entities.NetworkReloadReport)
    50  		report.Id = ctr.ID()
    51  		report.Err = ctr.ReloadNetwork()
    52  		// ignore errors for invalid ctr state and network mode when --all is used
    53  		if options.All && (errors.Cause(report.Err) == define.ErrCtrStateInvalid ||
    54  			errors.Cause(report.Err) == define.ErrNetworkModeInvalid) {
    55  			continue
    56  		}
    57  		reports = append(reports, report)
    58  	}
    59  
    60  	return reports, nil
    61  }
    62  
    63  func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) {
    64  	reports := make([]*entities.NetworkRmReport, 0, len(namesOrIds))
    65  
    66  	for _, name := range namesOrIds {
    67  		report := entities.NetworkRmReport{Name: name}
    68  		containers, err := ic.Libpod.GetAllContainers()
    69  		if err != nil {
    70  			return reports, err
    71  		}
    72  		// We need to iterate containers looking to see if they belong to the given network
    73  		for _, c := range containers {
    74  			networks, err := c.Networks()
    75  			// if container vanished or network does not exist, go to next container
    76  			if errors.Is(err, define.ErrNoSuchNetwork) || errors.Is(err, define.ErrNoSuchCtr) {
    77  				continue
    78  			}
    79  			if err != nil {
    80  				return reports, err
    81  			}
    82  			if util.StringInSlice(name, networks) {
    83  				// if user passes force, we nuke containers and pods
    84  				if !options.Force {
    85  					// Without the force option, we return an error
    86  					return reports, errors.Wrapf(define.ErrNetworkInUse, "%q has associated containers with it. Use -f to forcibly delete containers and pods", name)
    87  				}
    88  				if c.IsInfra() {
    89  					// if we have a infra container we need to remove the pod
    90  					pod, err := ic.Libpod.GetPod(c.PodID())
    91  					if err != nil {
    92  						return reports, err
    93  					}
    94  					if err := ic.Libpod.RemovePod(ctx, pod, true, true, options.Timeout); err != nil {
    95  						return reports, err
    96  					}
    97  				} else if err := ic.Libpod.RemoveContainer(ctx, c, true, true, options.Timeout); err != nil && errors.Cause(err) != define.ErrNoSuchCtr {
    98  					return reports, err
    99  				}
   100  			}
   101  		}
   102  		if err := ic.Libpod.Network().NetworkRemove(name); err != nil {
   103  			report.Err = err
   104  		}
   105  		reports = append(reports, &report)
   106  	}
   107  	return reports, nil
   108  }
   109  
   110  func (ic *ContainerEngine) NetworkCreate(ctx context.Context, network types.Network) (*types.Network, error) {
   111  	if util.StringInSlice(network.Name, []string{"none", "host", "bridge", "private", "slirp4netns", "container", "ns"}) {
   112  		return nil, errors.Errorf("cannot create network with name %q because it conflicts with a valid network mode", network.Name)
   113  	}
   114  	network, err := ic.Libpod.Network().NetworkCreate(network)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	return &network, nil
   119  }
   120  
   121  // NetworkDisconnect removes a container from a given network
   122  func (ic *ContainerEngine) NetworkDisconnect(ctx context.Context, networkname string, options entities.NetworkDisconnectOptions) error {
   123  	return ic.Libpod.DisconnectContainerFromNetwork(options.Container, networkname, options.Force)
   124  }
   125  
   126  func (ic *ContainerEngine) NetworkConnect(ctx context.Context, networkname string, options entities.NetworkConnectOptions) error {
   127  	return ic.Libpod.ConnectContainerToNetwork(options.Container, networkname, options.PerNetworkOptions)
   128  }
   129  
   130  // NetworkExists checks if the given network exists
   131  func (ic *ContainerEngine) NetworkExists(ctx context.Context, networkname string) (*entities.BoolReport, error) {
   132  	_, err := ic.Libpod.Network().NetworkInspect(networkname)
   133  	exists := true
   134  	// if err is ErrNoSuchNetwork do not return it
   135  	if errors.Is(err, define.ErrNoSuchNetwork) {
   136  		exists = false
   137  	} else if err != nil {
   138  		return nil, err
   139  	}
   140  	return &entities.BoolReport{
   141  		Value: exists,
   142  	}, nil
   143  }
   144  
   145  // Network prune removes unused cni networks
   146  func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.NetworkPruneOptions) ([]*entities.NetworkPruneReport, error) {
   147  	cons, err := ic.Libpod.GetAllContainers()
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  	// Gather up all the non-default networks that the
   152  	// containers want
   153  	networksToKeep := make(map[string]bool)
   154  	for _, c := range cons {
   155  		nets, err := c.Networks()
   156  		if err != nil {
   157  			return nil, err
   158  		}
   159  		for _, n := range nets {
   160  			networksToKeep[n] = true
   161  		}
   162  	}
   163  	// ignore the default network, this one cannot be deleted
   164  	networksToKeep[ic.Libpod.GetDefaultNetworkName()] = true
   165  
   166  	// get all filters
   167  	filters, err := netutil.GenerateNetworkPruneFilters(options.Filters)
   168  	if err != nil {
   169  		return nil, err
   170  	}
   171  	danglingFilterFunc := func(net types.Network) bool {
   172  		for network := range networksToKeep {
   173  			if network == net.Name {
   174  				return false
   175  			}
   176  		}
   177  		return true
   178  	}
   179  	filters = append(filters, danglingFilterFunc)
   180  	nets, err := ic.Libpod.Network().NetworkList(filters...)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  
   185  	pruneReport := make([]*entities.NetworkPruneReport, 0, len(nets))
   186  	for _, net := range nets {
   187  		pruneReport = append(pruneReport, &entities.NetworkPruneReport{
   188  			Name:  net.Name,
   189  			Error: ic.Libpod.Network().NetworkRemove(net.Name),
   190  		})
   191  	}
   192  	return pruneReport, nil
   193  }