diff options
-rw-r--r-- | cmd/podman/containers/run.go | 8 | ||||
-rw-r--r-- | docs/source/markdown/podman-manifest-add.1.md | 22 | ||||
-rw-r--r-- | libpod/network/config.go | 43 | ||||
-rw-r--r-- | libpod/network/netconflist.go | 18 | ||||
-rw-r--r-- | test/e2e/common_test.go | 18 | ||||
-rw-r--r-- | test/e2e/network_test.go | 26 | ||||
-rw-r--r-- | test/e2e/run_device_test.go | 6 | ||||
-rw-r--r-- | test/system/045-start.bats | 2 |
8 files changed, 108 insertions, 35 deletions
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index 8e27977c0..4bd06a47b 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -77,6 +77,11 @@ func runFlags(cmd *cobra.Command) { flags.StringVar(&runOpts.DetachKeys, detachKeysFlagName, containerConfig.DetachKeys(), "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-cf`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") _ = cmd.RegisterFlagCompletionFunc(detachKeysFlagName, common.AutocompleteDetachKeys) + gpuFlagName := "gpus" + flags.String(gpuFlagName, "", "This is a Docker specific option and is a NOOP") + _ = cmd.RegisterFlagCompletionFunc(gpuFlagName, completion.AutocompleteNone) + _ = flags.MarkHidden("gpus") + if registry.IsRemote() { _ = flags.MarkHidden("preserve-fds") _ = flags.MarkHidden("conmon-pidfile") @@ -204,5 +209,8 @@ func run(cmd *cobra.Command, args []string) error { logrus.Errorf("%s", errorhandling.JoinErrors(rmErrors)) } } + if cmd.Flag("gpus").Changed { + logrus.Info("--gpus is a Docker specific option and is a NOOP") + } return nil } diff --git a/docs/source/markdown/podman-manifest-add.1.md b/docs/source/markdown/podman-manifest-add.1.md index 3a0e34ee5..376301589 100644 --- a/docs/source/markdown/podman-manifest-add.1.md +++ b/docs/source/markdown/podman-manifest-add.1.md @@ -93,6 +93,28 @@ architecture value, but which expect different versions of its instruction set. $ podman manifest add mylist:v1.11 containers-storage:quay.io/username/myimage + **dir:**_path_ + An existing local directory _path_ storing the manifest, layer tarballs, and signatures as individual files. This + is a non-standardized format, primarily useful for debugging or noninvasive container inspection. + + $ podman manifest add dir:/tmp/myimage + + **docker-archive:**_path_[**:**_docker-reference_] + An image is stored in the `docker save` formatted file. _docker-reference_ is only used when creating such a + file, and it must not contain a digest. + + $ podman manifest add docker-archive:/tmp/myimage + + **docker-daemon:**_docker-reference_ + An image in _docker-reference_ format stored in the docker daemon internal storage. The _docker-reference_ can also be an image ID (docker-daemon:algo:digest). + + $ sudo podman manifest add docker-daemon:docker.io/library/myimage:33 + + **oci-archive:**_path_**:**_tag_ + An image _tag_ in a directory compliant with "Open Container Image Layout Specification" at _path_. + + $ podman manifest add oci-archive:/tmp/myimage + ## EXAMPLE ``` diff --git a/libpod/network/config.go b/libpod/network/config.go index ac4478602..9a3bc4763 100644 --- a/libpod/network/config.go +++ b/libpod/network/config.go @@ -44,17 +44,17 @@ type CNIPlugins interface { // HostLocalBridge describes a configuration for a bridge plugin // https://github.com/containernetworking/plugins/tree/master/plugins/main/bridge#network-configuration-reference type HostLocalBridge struct { - PluginType string `json:"type"` - BrName string `json:"bridge,omitempty"` - IsGW bool `json:"isGateway"` - IsDefaultGW bool `json:"isDefaultGateway,omitempty"` - ForceAddress bool `json:"forceAddress,omitempty"` - IPMasq bool `json:"ipMasq,omitempty"` - MTU int `json:"mtu,omitempty"` - HairpinMode bool `json:"hairpinMode,omitempty"` - PromiscMode bool `json:"promiscMode,omitempty"` - Vlan int `json:"vlan,omitempty"` - IPAM IPAMHostLocalConf `json:"ipam"` + PluginType string `json:"type"` + BrName string `json:"bridge,omitempty"` + IsGW bool `json:"isGateway"` + IsDefaultGW bool `json:"isDefaultGateway,omitempty"` + ForceAddress bool `json:"forceAddress,omitempty"` + IPMasq bool `json:"ipMasq,omitempty"` + MTU int `json:"mtu,omitempty"` + HairpinMode bool `json:"hairpinMode,omitempty"` + PromiscMode bool `json:"promiscMode,omitempty"` + Vlan int `json:"vlan,omitempty"` + IPAM IPAMConfig `json:"ipam"` } // Bytes outputs []byte @@ -62,9 +62,9 @@ func (h *HostLocalBridge) Bytes() ([]byte, error) { return json.MarshalIndent(h, "", "\t") } -// IPAMHostLocalConf describes an IPAM configuration +// IPAMConfig describes an IPAM configuration // https://github.com/containernetworking/plugins/tree/master/plugins/ipam/host-local#network-configuration-reference -type IPAMHostLocalConf struct { +type IPAMConfig struct { PluginType string `json:"type"` Routes []IPAMRoute `json:"routes,omitempty"` ResolveConf string `json:"resolveConf,omitempty"` @@ -81,7 +81,7 @@ type IPAMLocalHostRangeConf struct { } // Bytes outputs the configuration as []byte -func (i IPAMHostLocalConf) Bytes() ([]byte, error) { +func (i IPAMConfig) Bytes() ([]byte, error) { return json.MarshalIndent(i, "", "\t") } @@ -101,19 +101,12 @@ func (p PortMapConfig) Bytes() ([]byte, error) { return json.MarshalIndent(p, "", "\t") } -// IPAMDHCP describes the ipamdhcp config -type IPAMDHCP struct { - DHCP string `json:"type"` - Routes []IPAMRoute `json:"routes,omitempty"` - Ranges [][]IPAMLocalHostRangeConf `json:"ranges,omitempty"` -} - // MacVLANConfig describes the macvlan config type MacVLANConfig struct { - PluginType string `json:"type"` - Master string `json:"master"` - IPAM IPAMDHCP `json:"ipam"` - MTU int `json:"mtu,omitempty"` + PluginType string `json:"type"` + Master string `json:"master"` + IPAM IPAMConfig `json:"ipam"` + MTU int `json:"mtu,omitempty"` } // Bytes outputs the configuration as []byte diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go index d2031df6d..d6c33740e 100644 --- a/libpod/network/netconflist.go +++ b/libpod/network/netconflist.go @@ -45,7 +45,7 @@ func NewNcList(name, version string, labels NcLabels) NcList { } // NewHostLocalBridge creates a new LocalBridge for host-local -func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, mtu int, vlan int, ipamConf IPAMHostLocalConf) *HostLocalBridge { +func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, mtu int, vlan int, ipamConf IPAMConfig) *HostLocalBridge { hostLocalBridge := HostLocalBridge{ PluginType: "bridge", BrName: name, @@ -65,8 +65,8 @@ func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, mtu in } // NewIPAMHostLocalConf creates a new IPAMHostLocal configuration -func NewIPAMHostLocalConf(routes []IPAMRoute, ipamRanges [][]IPAMLocalHostRangeConf) (IPAMHostLocalConf, error) { - ipamConf := IPAMHostLocalConf{ +func NewIPAMHostLocalConf(routes []IPAMRoute, ipamRanges [][]IPAMLocalHostRangeConf) (IPAMConfig, error) { + ipamConf := IPAMConfig{ PluginType: "host-local", Routes: routes, // Possible future support ? Leaving for clues @@ -177,8 +177,10 @@ func HasDNSNamePlugin(paths []string) bool { // NewMacVLANPlugin creates a macvlanconfig with a given device name func NewMacVLANPlugin(device string, gateway net.IP, ipRange *net.IPNet, subnet *net.IPNet, mtu int) (MacVLANConfig, error) { - i := IPAMDHCP{DHCP: "dhcp"} - if gateway != nil || ipRange != nil || subnet != nil { + i := IPAMConfig{PluginType: "dhcp"} + if gateway != nil || + (ipRange != nil && ipRange.IP != nil && ipRange.Mask != nil) || + (subnet != nil && subnet.IP != nil && subnet.Mask != nil) { ipam, err := NewIPAMLocalHostRange(subnet, ipRange, gateway) if err != nil { return MacVLANConfig{}, err @@ -186,6 +188,12 @@ func NewMacVLANPlugin(device string, gateway net.IP, ipRange *net.IPNet, subnet ranges := make([][]IPAMLocalHostRangeConf, 0) ranges = append(ranges, ipam) i.Ranges = ranges + route, err := NewIPAMDefaultRoute(IsIPv6(subnet.IP)) + if err != nil { + return MacVLANConfig{}, err + } + i.Routes = []IPAMRoute{route} + i.PluginType = "host-local" } m := MacVLANConfig{ diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 359345096..7ffee961c 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -408,7 +408,14 @@ func (p *PodmanTestIntegration) RunLsContainer(name string) (*PodmanSessionInteg podmanArgs = append(podmanArgs, "-d", ALPINE, "ls") session := p.Podman(podmanArgs) session.WaitWithDefaultTimeout() - return session, session.ExitCode(), session.OutputToString() + if session.ExitCode() != 0 { + return session, session.ExitCode(), session.OutputToString() + } + cid := session.OutputToString() + + wsession := p.Podman([]string{"wait", cid}) + wsession.WaitWithDefaultTimeout() + return session, wsession.ExitCode(), cid } // RunNginxWithHealthCheck runs the alpine nginx container with an optional name and adds a healthcheck into it @@ -431,7 +438,14 @@ func (p *PodmanTestIntegration) RunLsContainerInPod(name, pod string) (*PodmanSe podmanArgs = append(podmanArgs, "-d", ALPINE, "ls") session := p.Podman(podmanArgs) session.WaitWithDefaultTimeout() - return session, session.ExitCode(), session.OutputToString() + if session.ExitCode() != 0 { + return session, session.ExitCode(), session.OutputToString() + } + cid := session.OutputToString() + + wsession := p.Podman([]string{"wait", cid}) + wsession.WaitWithDefaultTimeout() + return session, wsession.ExitCode(), cid } // BuildImage uses podman build and buildah to build an image diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index 6f28d7e19..a7e61932e 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -533,7 +533,11 @@ var _ = Describe("Podman network", func() { out, err := inspect.jq(".[0].plugins[0].master") Expect(err).To(BeNil()) - Expect(out).To(Equal("\"lo\"")) + Expect(out).To(Equal(`"lo"`)) + + ipamType, err := inspect.jq(".[0].plugins[0].ipam.type") + Expect(err).To(BeNil()) + Expect(ipamType).To(Equal(`"dhcp"`)) nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() @@ -571,13 +575,29 @@ var _ = Describe("Podman network", func() { Expect(err).To(BeNil()) Expect(mtu).To(Equal("1500")) + name, err := inspect.jq(".[0].plugins[0].type") + Expect(err).To(BeNil()) + Expect(name).To(Equal(`"macvlan"`)) + + netInt, err := inspect.jq(".[0].plugins[0].master") + Expect(err).To(BeNil()) + Expect(netInt).To(Equal(`"lo"`)) + + ipamType, err := inspect.jq(".[0].plugins[0].ipam.type") + Expect(err).To(BeNil()) + Expect(ipamType).To(Equal(`"host-local"`)) + gw, err := inspect.jq(".[0].plugins[0].ipam.ranges[0][0].gateway") Expect(err).To(BeNil()) - Expect(gw).To(Equal("\"192.168.1.254\"")) + Expect(gw).To(Equal(`"192.168.1.254"`)) subnet, err := inspect.jq(".[0].plugins[0].ipam.ranges[0][0].subnet") Expect(err).To(BeNil()) - Expect(subnet).To(Equal("\"192.168.1.0/24\"")) + Expect(subnet).To(Equal(`"192.168.1.0/24"`)) + + routes, err := inspect.jq(".[0].plugins[0].ipam.routes[0].dst") + Expect(err).To(BeNil()) + Expect(routes).To(Equal(`"0.0.0.0/0"`)) nc = podmanTest.Podman([]string{"network", "rm", net}) nc.WaitWithDefaultTimeout() diff --git a/test/e2e/run_device_test.go b/test/e2e/run_device_test.go index 3137e3fe4..735e44d3e 100644 --- a/test/e2e/run_device_test.go +++ b/test/e2e/run_device_test.go @@ -113,4 +113,10 @@ var _ = Describe("Podman run device", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg1")) }) + + It("podman run --gpus noop", func() { + session := podmanTest.Podman([]string{"run", "--gpus", "all", ALPINE, "ls", "/"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) }) diff --git a/test/system/045-start.bats b/test/system/045-start.bats index 542f9d1c2..3e0118dba 100644 --- a/test/system/045-start.bats +++ b/test/system/045-start.bats @@ -25,6 +25,8 @@ load helpers die "podman start --all restarted a running container" fi + run_podman wait $cid_none_implicit $cid_none_explicit $cid_on_failure + run_podman rm $cid_none_implicit $cid_none_explicit $cid_on_failure run_podman stop -t 1 $cid_always run_podman rm $cid_always |