summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/containers.go1
-rw-r--r--pkg/domain/entities/engine_image.go2
-rw-r--r--pkg/domain/entities/images.go36
-rw-r--r--pkg/domain/entities/network.go6
-rw-r--r--pkg/domain/entities/play.go4
-rw-r--r--pkg/domain/entities/pods.go12
-rw-r--r--pkg/domain/entities/types.go22
-rw-r--r--pkg/domain/filters/containers.go20
-rw-r--r--pkg/domain/filters/pods.go22
-rw-r--r--pkg/domain/infra/abi/containers.go1
-rw-r--r--pkg/domain/infra/abi/images.go179
-rw-r--r--pkg/domain/infra/abi/network.go6
-rw-r--r--pkg/domain/infra/abi/play.go53
-rw-r--r--pkg/domain/infra/abi/pods.go4
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/domain/infra/tunnel/network.go3
-rw-r--r--pkg/domain/infra/tunnel/play.go2
17 files changed, 234 insertions, 141 deletions
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 1677c067f..ae441b7f3 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -341,6 +341,7 @@ type ContainerRunOptions struct {
Rm bool
SigProxy bool
Spec *specgen.SpecGenerator
+ Passwd bool
}
// ContainerRunReport describes the results of running
diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go
index d72f64b5e..bec505163 100644
--- a/pkg/domain/entities/engine_image.go
+++ b/pkg/domain/entities/engine_image.go
@@ -27,7 +27,7 @@ type ImageEngine interface {
ShowTrust(ctx context.Context, args []string, options ShowTrustOptions) (*ShowTrustReport, error)
Shutdown(ctx context.Context)
Tag(ctx context.Context, nameOrID string, tags []string, options ImageTagOptions) error
- Transfer(ctx context.Context, scpOpts ImageScpOptions) error
+ Transfer(ctx context.Context, source ImageScpOptions, dest ImageScpOptions, parentFlags []string) error
Tree(ctx context.Context, nameOrID string, options ImageTreeOptions) (*ImageTreeReport, error)
Unmount(ctx context.Context, images []string, options ImageUnmountOptions) ([]*ImageUnmountReport, error)
Untag(ctx context.Context, nameOrID string, tags []string, options ImageUntagOptions) error
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 8b0fd2b85..62e7f67c8 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -311,30 +311,28 @@ type ImageSaveOptions struct {
Quiet bool
}
-// ImageScpOptions provide options for securely copying images to podman remote
+// ImageScpOptions provide options for securely copying images to and from a remote host
type ImageScpOptions struct {
- // SoureImageName is the image the user is providing to load on a remote machine
- SourceImageName string
- // Tag allows for a new image to be created under the given name
- Tag string
- // ToRemote specifies that we are loading to the remote host
- ToRemote bool
- // FromRemote specifies that we are loading from the remote host
- FromRemote bool
+ // Remote determines if this entity is operating on a remote machine
+ Remote bool `json:"remote,omitempty"`
+ // File is the input/output file for the save and load Operation
+ File string `json:"file,omitempty"`
+ // Quiet Determines if the save and load operation will be done quietly
+ Quiet bool `json:"quiet,omitempty"`
+ // Image is the image the user is providing to save and load
+ Image string `json:"image,omitempty"`
+ // User is used in conjunction with Transfer to determine if a valid user was given to save from/load into
+ User string `json:"user,omitempty"`
+}
+
+// ImageScpConnections provides the ssh related information used in remote image transfer
+type ImageScpConnections struct {
// Connections holds the raw string values for connections (ssh or unix)
Connections []string
// URI contains the ssh connection URLs to be used by the client
URI []*url.URL
- // Iden contains ssh identity keys to be used by the client
- Iden []string
- // Save Options used for first half of the scp operation
- Save ImageSaveOptions
- // Load options used for the second half of the scp operation
- Load ImageLoadOptions
- // Rootless determines whether we are loading locally from root storage to rootless storage
- Rootless bool
- // User is used in conjunction with Rootless to determine which user to use to obtain the uid
- User string
+ // Identities contains ssh identity keys to be used by the client
+ Identities []string
}
// ImageTreeOptions provides options for ImageEngine.Tree()
diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go
index d7389a699..34b89ae7d 100644
--- a/pkg/domain/entities/network.go
+++ b/pkg/domain/entities/network.go
@@ -2,6 +2,8 @@ package entities
import (
"net"
+
+ "github.com/containers/podman/v3/libpod/network/types"
)
// NetworkListOptions describes options for listing networks in cli
@@ -67,8 +69,8 @@ type NetworkDisconnectOptions struct {
// NetworkConnectOptions describes options for connecting
// a container to a network
type NetworkConnectOptions struct {
- Aliases []string
- Container string
+ Container string `json:"container"`
+ types.PerNetworkOptions
}
// NetworkPruneReport containers the name of network and an error
diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go
index ad35dfe25..39234caf8 100644
--- a/pkg/domain/entities/play.go
+++ b/pkg/domain/entities/play.go
@@ -26,8 +26,8 @@ type PlayKubeOptions struct {
Username string
// Password for authenticating against the registry.
Password string
- // Network - name of the CNI network to connect to.
- Network string
+ // Networks - name of the network to connect to.
+ Networks []string
// Quiet - suppress output when pulling images.
Quiet bool
// SignaturePolicy - path to a signature-policy file.
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index b255785c2..1b5a1be51 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -7,7 +7,6 @@ import (
commonFlag "github.com/containers/common/pkg/flag"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
"github.com/opencontainers/runtime-spec/specs-go"
@@ -139,6 +138,7 @@ type PodCreateOptions struct {
Userns specgen.Namespace `json:"-"`
Volume []string `json:"volume,omitempty"`
VolumesFrom []string `json:"volumes_from,omitempty"`
+ SecurityOpt []string `json:"security_opt,omitempty"`
}
// PodLogsOptions describes the options to extract pod logs.
@@ -190,13 +190,13 @@ type ContainerCreateOptions struct {
HealthTimeout string
Hostname string `json:"hostname,omitempty"`
HTTPProxy bool
+ HostUsers []string
ImageVolume string
Init bool
InitContainerType string
InitPath string
Interactive bool
IPC string
- KernelMemory string
Label []string
LabelFile []string
LogDriver string
@@ -231,7 +231,7 @@ type ContainerCreateOptions struct {
Rm bool
RootFS bool
Secrets []string
- SecurityOpt []string
+ SecurityOpt []string `json:"security_opt,omitempty"`
SdNotifyMode string
ShmSize string
SignaturePolicy string
@@ -313,6 +313,7 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
s.Hostname = p.Hostname
s.Labels = p.Labels
s.Devices = p.Devices
+ s.SecurityOpt = p.SecurityOpt
s.NoInfra = !p.Infra
if p.InfraCommand != nil && len(*p.InfraCommand) > 0 {
s.InfraCommand = strings.Split(*p.InfraCommand, " ")
@@ -329,11 +330,8 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
if p.Net != nil {
s.NetNS = p.Net.Network
- s.StaticIP = p.Net.StaticIP
- // type cast to types.HardwareAddr
- s.StaticMAC = (*types.HardwareAddr)(p.Net.StaticMAC)
s.PortMappings = p.Net.PublishPorts
- s.CNINetworks = p.Net.CNINetworks
+ s.Networks = p.Net.Networks
s.NetworkOptions = p.Net.NetworkOptions
if p.Net.UseImageResolvConf {
s.NoManageResolvConf = true
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index e062b9442..0348c0af5 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -45,18 +45,16 @@ type NetFlags struct {
// NetOptions reflect the shared network options between
// pods and containers
type NetOptions struct {
- AddHosts []string `json:"hostadd,omitempty"`
- Aliases []string `json:"network_alias,omitempty"`
- CNINetworks []string `json:"cni_networks,omitempty"`
- UseImageResolvConf bool `json:"no_manage_resolv_conf,omitempty"`
- DNSOptions []string `json:"dns_option,omitempty"`
- DNSSearch []string `json:"dns_search,omitempty"`
- DNSServers []net.IP `json:"dns_server,omitempty"`
- Network specgen.Namespace `json:"netns,omitempty"`
- NoHosts bool `json:"no_manage_hosts,omitempty"`
- PublishPorts []types.PortMapping `json:"portmappings,omitempty"`
- StaticIP *net.IP `json:"static_ip,omitempty"`
- StaticMAC *net.HardwareAddr `json:"static_mac,omitempty"`
+ AddHosts []string `json:"hostadd,omitempty"`
+ Aliases []string `json:"network_alias,omitempty"`
+ Networks map[string]types.PerNetworkOptions `json:"networks,omitempty"`
+ UseImageResolvConf bool `json:"no_manage_resolv_conf,omitempty"`
+ DNSOptions []string `json:"dns_option,omitempty"`
+ DNSSearch []string `json:"dns_search,omitempty"`
+ DNSServers []net.IP `json:"dns_server,omitempty"`
+ Network specgen.Namespace `json:"netns,omitempty"`
+ NoHosts bool `json:"no_manage_hosts,omitempty"`
+ PublishPorts []types.PortMapping `json:"portmappings,omitempty"`
// NetworkOptions are additional options for each network
NetworkOptions map[string][]string `json:"network_options,omitempty"`
}
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go
index 269cd2d27..60a1efb22 100644
--- a/pkg/domain/filters/containers.go
+++ b/pkg/domain/filters/containers.go
@@ -8,7 +8,6 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/pkg/network"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
@@ -210,6 +209,15 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
return false
}, nil
case "network":
+ var inputNetNames []string
+ for _, val := range filterValues {
+ net, err := r.Network().NetworkInspect(val)
+ if err != nil {
+ // ignore not found errors
+ break
+ }
+ inputNetNames = append(inputNetNames, net.Name)
+ }
return func(c *libpod.Container) bool {
networkMode := c.NetworkMode()
// support docker like `--filter network=container:<IDorName>`
@@ -241,18 +249,14 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
return false
}
- networks, _, err := c.Networks()
+ networks, err := c.Networks()
// if err or no networks, quick out
if err != nil || len(networks) == 0 {
return false
}
for _, net := range networks {
- netID := network.GetNetworkID(net)
- for _, val := range filterValues {
- // match by network name or id
- if val == net || val == netID {
- return true
- }
+ if util.StringInSlice(net, inputNetNames) {
+ return true
}
}
return false
diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go
index 9a2f0a3ba..8231dbc79 100644
--- a/pkg/domain/filters/pods.go
+++ b/pkg/domain/filters/pods.go
@@ -6,7 +6,6 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/pkg/network"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
@@ -14,7 +13,7 @@ import (
// GeneratePodFilterFunc takes a filter and filtervalue (key, value)
// and generates a libpod function that can be used to filter
// pods
-func GeneratePodFilterFunc(filter string, filterValues []string) (
+func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runtime) (
func(pod *libpod.Pod) bool, error) {
switch filter {
case "ctr-ids":
@@ -128,24 +127,29 @@ func GeneratePodFilterFunc(filter string, filterValues []string) (
return false
}, nil
case "network":
+ var inputNetNames []string
+ for _, val := range filterValues {
+ net, err := r.Network().NetworkInspect(val)
+ if err != nil {
+ // ignore not found errors
+ break
+ }
+ inputNetNames = append(inputNetNames, net.Name)
+ }
return func(p *libpod.Pod) bool {
infra, err := p.InfraContainer()
// no infra, quick out
if err != nil {
return false
}
- networks, _, err := infra.Networks()
+ networks, err := infra.Networks()
// if err or no networks, quick out
if err != nil || len(networks) == 0 {
return false
}
for _, net := range networks {
- netID := network.GetNetworkID(net)
- for _, val := range filterValues {
- // match by network name or id
- if val == net || val == netID {
- return true
- }
+ if util.StringInSlice(net, inputNetNames) {
+ return true
}
}
return false
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index d1af4a479..bf4dcff62 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -927,6 +927,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
for _, w := range warn {
fmt.Fprintf(os.Stderr, "%s\n", w)
}
+
rtSpec, spec, optsN, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec)
if err != nil {
return nil, err
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 4346182d6..84c83ea8e 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -28,6 +28,7 @@ import (
domainUtils "github.com/containers/podman/v3/pkg/domain/utils"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/utils"
"github.com/containers/storage"
dockerRef "github.com/docker/distribution/reference"
"github.com/opencontainers/go-digest"
@@ -351,65 +352,19 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
return pushError
}
-// Transfer moves images from root to rootless storage so the user specified in the scp call can access and use the image modified by root
-func (ir *ImageEngine) Transfer(ctx context.Context, scpOpts entities.ImageScpOptions) error {
- if scpOpts.User == "" {
+// Transfer moves images between root and rootless storage so the user specified in the scp call can access and use the image modified by root
+func (ir *ImageEngine) Transfer(ctx context.Context, source entities.ImageScpOptions, dest entities.ImageScpOptions, parentFlags []string) error {
+ if source.User == "" {
return errors.Wrapf(define.ErrInvalidArg, "you must define a user when transferring from root to rootless storage")
}
- var u *user.User
- scpOpts.User = strings.Split(scpOpts.User, ":")[0] // split in case provided with uid:gid
- _, err := strconv.Atoi(scpOpts.User)
- if err != nil {
- u, err = user.Lookup(scpOpts.User)
- if err != nil {
- return err
- }
- } else {
- u, err = user.LookupId(scpOpts.User)
- if err != nil {
- return err
- }
- }
- uid, err := strconv.Atoi(u.Uid)
- if err != nil {
- return err
- }
- gid, err := strconv.Atoi(u.Gid)
- if err != nil {
- return err
- }
- err = os.Chown(scpOpts.Save.Output, uid, gid) // chown the output because was created by root so we need to give th euser read access
- if err != nil {
- return err
- }
-
podman, err := os.Executable()
if err != nil {
return err
}
- machinectl, err := exec.LookPath("machinectl")
- if err != nil {
- logrus.Warn("defaulting to su since machinectl is not available, su will fail if no user session is available")
- cmd := exec.Command("su", "-l", u.Username, "--command", podman+" --log-level="+logrus.GetLevel().String()+" --cgroup-manager=cgroupfs load --input="+scpOpts.Save.Output) // load the new image to the rootless storage
- cmd.Stderr = os.Stderr
- cmd.Stdout = os.Stdout
- logrus.Debug("Executing load command su")
- err = cmd.Run()
- if err != nil {
- return err
- }
- } else {
- cmd := exec.Command(machinectl, "shell", "-q", u.Username+"@.host", podman, "--log-level="+logrus.GetLevel().String(), "--cgroup-manager=cgroupfs", "load", "--input", scpOpts.Save.Output) // load the new image to the rootless storage
- cmd.Stderr = os.Stderr
- cmd.Stdout = os.Stdout
- logrus.Debug("Executing load command machinectl")
- err = cmd.Run()
- if err != nil {
- return err
- }
+ if rootless.IsRootless() && (len(dest.User) == 0 || dest.User == "root") { // if we are rootless and do not have a destination user we can just use sudo
+ return transferRootless(source, dest, podman, parentFlags)
}
-
- return nil
+ return transferRootful(source, dest, podman, parentFlags)
}
func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error {
@@ -786,3 +741,123 @@ func putSignature(manifestBlob []byte, mech signature.SigningMechanism, sigStore
}
return nil
}
+
+// TransferRootless creates new podman processes using exec.Command and sudo, transferring images between the given source and destination users
+func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
+ var cmdSave *exec.Cmd
+ saveCommand := parentFlags
+ saveCommand = append(saveCommand, []string{"save", "--output", source.File, source.Image}...)
+
+ loadCommand := parentFlags
+ loadCommand = append(loadCommand, []string{"load", "--input", dest.File}...)
+
+ if source.User == "root" {
+ cmdSave = exec.Command("sudo", podman)
+ } else {
+ cmdSave = exec.Command(podman)
+ }
+ cmdSave = utils.CreateSCPCommand(cmdSave, saveCommand)
+ logrus.Debug("Executing save command")
+ err := cmdSave.Run()
+ if err != nil {
+ return err
+ }
+
+ var cmdLoad *exec.Cmd
+ if source.User != "root" {
+ cmdLoad = exec.Command("sudo", podman)
+ } else {
+ cmdLoad = exec.Command(podman)
+ }
+ cmdLoad = utils.CreateSCPCommand(cmdLoad, loadCommand)
+ logrus.Debug("Executing load command")
+ err = cmdLoad.Run()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// TransferRootless creates new podman processes using exec.Command and su/machinectl, transferring images between the given source and destination users
+func transferRootful(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
+ basicCommand := []string{podman}
+ basicCommand = append(basicCommand, parentFlags...)
+ saveCommand := append(basicCommand, []string{"save", "--output", source.File, source.Image}...)
+ loadCommand := append(basicCommand, []string{"load", "--input", dest.File}...)
+ save := []string{strings.Join(saveCommand, " ")}
+ load := []string{strings.Join(loadCommand, " ")}
+
+ // if executing using sudo or transferring between two users, the TransferRootless approach will not work, default to using machinectl or su as necessary.
+ // the approach using sudo is preferable and more straightforward. There is no reason for using sudo in these situations
+ // since the feature is meant to transfer from root to rootless an vice versa without explicit sudo evocaiton.
+ var uSave *user.User
+ var uLoad *user.User
+ var err error
+ source.User = strings.Split(source.User, ":")[0] // split in case provided with uid:gid
+ dest.User = strings.Split(dest.User, ":")[0]
+ uSave, err = lookupUser(source.User)
+ if err != nil {
+ return err
+ }
+ switch {
+ case dest.User != "": // if we are given a destination user, check that first
+ uLoad, err = lookupUser(dest.User)
+ if err != nil {
+ return err
+ }
+ case uSave.Name != "root": // else if we have no destination user, and source is not root that means we should be root
+ uLoad, err = user.LookupId("0")
+ if err != nil {
+ return err
+ }
+ default: // else if we have no dest user, and source user IS root, we want to be the default user.
+ uString := os.Getenv("SUDO_USER")
+ if uString == "" {
+ return errors.New("$SUDO_USER must be defined to find the default rootless user")
+ }
+ uLoad, err = user.Lookup(uString)
+ if err != nil {
+ return err
+ }
+ }
+ machinectl, err := exec.LookPath("machinectl")
+ if err != nil {
+ logrus.Warn("defaulting to su since machinectl is not available, su will fail if no user session is available")
+ err = execSu(uSave, save)
+ if err != nil {
+ return err
+ }
+ return execSu(uLoad, load)
+ }
+ err = execMachine(uSave, saveCommand, machinectl)
+ if err != nil {
+ return err
+ }
+ return execMachine(uLoad, loadCommand, machinectl)
+}
+
+func lookupUser(u string) (*user.User, error) {
+ if u, err := user.LookupId(u); err == nil {
+ return u, nil
+ }
+ return user.Lookup(u)
+}
+
+func execSu(execUser *user.User, command []string) error {
+ cmd := exec.Command("su", "-l", execUser.Username, "--command")
+ cmd = utils.CreateSCPCommand(cmd, command)
+ logrus.Debug("Executing command su")
+ return cmd.Run()
+}
+
+func execMachine(execUser *user.User, command []string, machinectl string) error {
+ var cmd *exec.Cmd
+ if execUser.Uid == "0" {
+ cmd = exec.Command("sudo", machinectl, "shell", "-q", execUser.Username+"@.host")
+ } else {
+ cmd = exec.Command(machinectl, "shell", "-q", execUser.Username+"@.host")
+ }
+ cmd = utils.CreateSCPCommand(cmd, command)
+ logrus.Debug("Executing command machinectl")
+ return cmd.Run()
+}
diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go
index ee7403ed5..c7b12663c 100644
--- a/pkg/domain/infra/abi/network.go
+++ b/pkg/domain/infra/abi/network.go
@@ -71,7 +71,7 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o
}
// We need to iterate containers looking to see if they belong to the given network
for _, c := range containers {
- networks, _, err := c.Networks()
+ networks, err := c.Networks()
// if container vanished or network does not exist, go to next container
if errors.Is(err, define.ErrNoSuchNetwork) || errors.Is(err, define.ErrNoSuchCtr) {
continue
@@ -124,7 +124,7 @@ func (ic *ContainerEngine) NetworkDisconnect(ctx context.Context, networkname st
}
func (ic *ContainerEngine) NetworkConnect(ctx context.Context, networkname string, options entities.NetworkConnectOptions) error {
- return ic.Libpod.ConnectContainerToNetwork(options.Container, networkname, options.Aliases)
+ return ic.Libpod.ConnectContainerToNetwork(options.Container, networkname, options.PerNetworkOptions)
}
// NetworkExists checks if the given network exists
@@ -152,7 +152,7 @@ func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.Ne
// containers want
networksToKeep := make(map[string]bool)
for _, c := range cons {
- nets, _, err := c.Networks()
+ nets, err := c.Networks()
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 4c024a3d8..6b3b04a0b 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -6,7 +6,6 @@ import (
"fmt"
"io"
"io/ioutil"
- "net"
"os"
"path/filepath"
"strconv"
@@ -18,6 +17,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
+ nettypes "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/autoupdate"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
@@ -190,39 +190,52 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
}
- podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{StaticIP: &net.IP{}, StaticMAC: &net.HardwareAddr{}, NoHosts: options.NoHosts}}
+ podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{NoHosts: options.NoHosts}}
podOpt, err = kube.ToPodOpt(ctx, podName, podOpt, podYAML)
if err != nil {
return nil, err
}
- if options.Network != "" {
- ns, cniNets, netOpts, err := specgen.ParseNetworkString(options.Network)
- if err != nil {
- return nil, err
- }
-
- if (ns.IsBridge() && len(cniNets) == 0) || ns.IsHost() {
- return nil, errors.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML")
- }
+ ns, networks, netOpts, err := specgen.ParseNetworkFlag(options.Networks)
+ if err != nil {
+ return nil, err
+ }
- podOpt.Net.Network = ns
- if len(cniNets) > 0 {
- podOpt.Net.CNINetworks = append(podOpt.Net.CNINetworks, cniNets...)
- }
- if len(netOpts) > 0 {
- podOpt.Net.NetworkOptions = netOpts
- }
+ if (ns.IsBridge() && len(networks) == 0) || ns.IsHost() {
+ return nil, errors.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML")
}
+ podOpt.Net.Network = ns
+ podOpt.Net.Networks = networks
+ podOpt.Net.NetworkOptions = netOpts
+
+ // FIXME This is very hard to support properly with a good ux
if len(options.StaticIPs) > *ipIndex {
- podOpt.Net.StaticIP = &options.StaticIPs[*ipIndex]
+ if !podOpt.Net.Network.IsBridge() {
+ errors.Wrap(define.ErrInvalidArg, "static ip addresses can only be set when the network mode is bridge")
+ }
+ if len(podOpt.Net.Networks) != 1 {
+ return nil, errors.Wrap(define.ErrInvalidArg, "cannot set static ip addresses for more than network, use netname:ip=<ip> syntax to specify ips for more than network")
+ }
+ for name, netOpts := range podOpt.Net.Networks {
+ netOpts.StaticIPs = append(netOpts.StaticIPs, options.StaticIPs[*ipIndex])
+ podOpt.Net.Networks[name] = netOpts
+ }
} else if len(options.StaticIPs) > 0 {
// only warn if the user has set at least one ip
logrus.Warn("No more static ips left using a random one")
}
if len(options.StaticMACs) > *ipIndex {
- podOpt.Net.StaticMAC = &options.StaticMACs[*ipIndex]
+ if !podOpt.Net.Network.IsBridge() {
+ errors.Wrap(define.ErrInvalidArg, "static mac address can only be set when the network mode is bridge")
+ }
+ if len(podOpt.Net.Networks) != 1 {
+ return nil, errors.Wrap(define.ErrInvalidArg, "cannot set static mac address for more than network, use netname:mac=<mac> syntax to specify mac for more than network")
+ }
+ for name, netOpts := range podOpt.Net.Networks {
+ netOpts.StaticMAC = nettypes.HardwareAddr(options.StaticMACs[*ipIndex])
+ podOpt.Net.Networks[name] = netOpts
+ }
} else if len(options.StaticIPs) > 0 {
// only warn if the user has set at least one mac
logrus.Warn("No more static macs left using a random one")
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 028de9e81..7bda7e994 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -325,7 +325,7 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
filters := make([]libpod.PodFilter, 0, len(options.Filters))
for k, v := range options.Filters {
- f, err := dfilters.GeneratePodFilterFunc(k, v)
+ f, err := dfilters.GeneratePodFilterFunc(k, v, ic.Libpod)
if err != nil {
return nil, err
}
@@ -376,7 +376,7 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
if err != nil {
return nil, err
}
- networks, _, err = infra.Networks()
+ networks, err = infra.Networks()
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 2feb9d7ad..f26a489e6 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -123,7 +123,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, opts entities.
return &entities.ImagePullReport{Images: pulledImages}, nil
}
-func (ir *ImageEngine) Transfer(ctx context.Context, scpOpts entities.ImageScpOptions) error {
+func (ir *ImageEngine) Transfer(ctx context.Context, source entities.ImageScpOptions, dest entities.ImageScpOptions, parentFlags []string) error {
return errors.Wrapf(define.ErrNotImplemented, "cannot use the remote client to transfer images between root and rootless storage")
}
diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go
index 069982d30..b5050345a 100644
--- a/pkg/domain/infra/tunnel/network.go
+++ b/pkg/domain/infra/tunnel/network.go
@@ -81,8 +81,7 @@ func (ic *ContainerEngine) NetworkDisconnect(ctx context.Context, networkname st
// NetworkConnect removes a container from a given network
func (ic *ContainerEngine) NetworkConnect(ctx context.Context, networkname string, opts entities.NetworkConnectOptions) error {
- options := new(network.ConnectOptions).WithAliases(opts.Aliases)
- return network.Connect(ic.ClientCtx, networkname, opts.Container, options)
+ return network.Connect(ic.ClientCtx, networkname, opts.Container, &opts.PerNetworkOptions)
}
// NetworkExists checks if the given network exists
diff --git a/pkg/domain/infra/tunnel/play.go b/pkg/domain/infra/tunnel/play.go
index 75952ce2c..103be0cf1 100644
--- a/pkg/domain/infra/tunnel/play.go
+++ b/pkg/domain/infra/tunnel/play.go
@@ -11,7 +11,7 @@ import (
func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, opts entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
options := new(play.KubeOptions).WithAuthfile(opts.Authfile).WithUsername(opts.Username).WithPassword(opts.Password)
options.WithCertDir(opts.CertDir).WithQuiet(opts.Quiet).WithSignaturePolicy(opts.SignaturePolicy).WithConfigMaps(opts.ConfigMaps)
- options.WithLogDriver(opts.LogDriver).WithNetwork(opts.Network).WithSeccompProfileRoot(opts.SeccompProfileRoot)
+ options.WithLogDriver(opts.LogDriver).WithNetwork(opts.Networks).WithSeccompProfileRoot(opts.SeccompProfileRoot)
options.WithStaticIPs(opts.StaticIPs).WithStaticMACs(opts.StaticMACs)
if len(opts.LogOptions) > 0 {
options.WithLogOptions(opts.LogOptions)