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 }