Merge pull request #6975 from baude/rootlessIPMAC

Error on rootless mac and ip addresses
This commit is contained in:
OpenShift Merge Robot
2020-07-15 16:38:36 -04:00
committed by GitHub
10 changed files with 86 additions and 41 deletions

View File

@ -28,6 +28,15 @@ func exclusiveOptions(opt1, opt2 string) error {
// input for creating a container.
func (s *SpecGenerator) Validate() error {
if rootless.IsRootless() {
if s.StaticIP != nil || s.StaticIPv6 != nil {
return ErrNoStaticIPRootless
}
if s.StaticMAC != nil {
return ErrNoStaticMACRootless
}
}
//
// ContainerBasicConfig
//

View File

@ -1,6 +1,7 @@
package specgen
import (
"github.com/containers/libpod/v2/pkg/rootless"
"github.com/containers/libpod/v2/pkg/util"
"github.com/pkg/errors"
)
@ -18,6 +19,16 @@ func exclusivePodOptions(opt1, opt2 string) error {
// Validate verifies the input is valid
func (p *PodSpecGenerator) Validate() error {
if rootless.IsRootless() {
if p.StaticIP != nil {
return ErrNoStaticIPRootless
}
if p.StaticMAC != nil {
return ErrNoStaticMACRootless
}
}
// PodBasicConfig
if p.NoInfra {
if len(p.InfraCommand) > 0 {

View File

@ -1,6 +1,7 @@
package specgen
import (
"errors"
"net"
"syscall"
@ -469,6 +470,15 @@ type PortMapping struct {
Protocol string `json:"protocol,omitempty"`
}
var (
// ErrNoStaticIPRootless is used when a rootless user requests to assign a static IP address
// to a pod or container
ErrNoStaticIPRootless error = errors.New("rootless containers and pods cannot be assigned static IP addresses")
// ErrNoStaticMACRootless is used when a rootless user requests to assign a static MAC address
// to a pod or container
ErrNoStaticMACRootless error = errors.New("rootless containers and pods cannot be assigned static MAC addresses")
)
// NewSpecGenerator returns a SpecGenerator struct given one of two mandatory inputs
func NewSpecGenerator(arg string, rootfs bool) *SpecGenerator {
csc := ContainerStorageConfig{}

View File

@ -595,3 +595,7 @@ func SkipIfNotFedora() {
ginkgo.Skip("Test can only run on Fedora")
}
}
func isRootless() bool {
return os.Geteuid() != 0
}

View File

@ -6,6 +6,7 @@ import (
"os"
"time"
"github.com/containers/libpod/v2/pkg/rootless"
. "github.com/containers/libpod/v2/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -19,7 +20,6 @@ var _ = Describe("Podman create with --ip flag", func() {
)
BeforeEach(func() {
SkipIfRootless()
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
@ -39,18 +39,21 @@ var _ = Describe("Podman create with --ip flag", func() {
})
It("Podman create --ip with garbage address", func() {
SkipIfRootless()
result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", "114232346", ALPINE, "ls"})
result.WaitWithDefaultTimeout()
Expect(result).To(ExitWithError())
})
It("Podman create --ip with v6 address", func() {
SkipIfRootless()
result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", "2001:db8:bad:beef::1", ALPINE, "ls"})
result.WaitWithDefaultTimeout()
Expect(result).To(ExitWithError())
})
It("Podman create --ip with non-allocatable IP", func() {
SkipIfRootless()
result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", "203.0.113.124", ALPINE, "ls"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
@ -64,19 +67,25 @@ var _ = Describe("Podman create with --ip flag", func() {
ip := GetRandomIPAddress()
result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", ip, ALPINE, "ip", "addr"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
// Rootless static ip assignment should error
if rootless.IsRootless() {
Expect(result.ExitCode()).To(Equal(125))
} else {
Expect(result.ExitCode()).To(Equal(0))
result = podmanTest.Podman([]string{"start", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
result = podmanTest.Podman([]string{"start", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
result = podmanTest.Podman([]string{"logs", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(ContainSubstring(ip + "/16"))
result = podmanTest.Podman([]string{"logs", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(ContainSubstring(ip + "/16"))
}
})
It("Podman create two containers with the same IP", func() {
SkipIfRootless()
ip := GetRandomIPAddress()
result := podmanTest.Podman([]string{"create", "--name", "test1", "--ip", ip, ALPINE, "sleep", "999"})
result.WaitWithDefaultTimeout()

View File

@ -1,10 +1,9 @@
// +build !remote
package integration
import (
"os"
"github.com/containers/libpod/v2/pkg/rootless"
. "github.com/containers/libpod/v2/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -18,7 +17,6 @@ var _ = Describe("Podman run with --mac-address flag", func() {
)
BeforeEach(func() {
SkipIfRootless()
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
@ -40,7 +38,11 @@ var _ = Describe("Podman run with --mac-address flag", func() {
It("Podman run --mac-address", func() {
result := podmanTest.Podman([]string{"run", "--mac-address", "92:d0:c6:0a:29:34", ALPINE, "ip", "addr"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(ContainSubstring("92:d0:c6:0a:29:34"))
if rootless.IsRootless() {
Expect(result.ExitCode()).To(Equal(125))
} else {
Expect(result.ExitCode()).To(Equal(0))
Expect(result.OutputToString()).To(ContainSubstring("92:d0:c6:0a:29:34"))
}
})
})

View File

@ -28,11 +28,6 @@ func SkipIfRootless() {
ginkgo.Skip("This function is not enabled for rootless podman")
}
}
func SkipIfRootlessV2() {
if os.Geteuid() != 0 {
ginkgo.Skip("This function is not enabled for v2 rootless podman")
}
}
// Podman is the exec call to podman on the filesystem
func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration {

View File

@ -41,12 +41,6 @@ func SkipIfRootless() {
}
}
func SkipIfRootlessV2() {
if os.Geteuid() != 0 {
Skip("This function is not enabled for v2 rootless podman")
}
}
// Podman is the exec call to podman on the filesystem
func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration {
podmanSession := p.PodmanBase(args, false, false)

View File

@ -7,6 +7,7 @@ import (
"path/filepath"
"strings"
"github.com/containers/libpod/v2/pkg/rootless"
. "github.com/containers/libpod/v2/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -238,17 +239,20 @@ var _ = Describe("Podman pod create", func() {
})
It("podman create pod with IP address", func() {
SkipIfRootless()
name := "test"
ip := GetRandomIPAddress()
podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate.ExitCode()).To(Equal(0))
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "ip", "addr"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf.ExitCode()).To(Equal(0))
Expect(strings.Contains(podResolvConf.OutputToString(), ip)).To(BeTrue())
// Rootless should error
if rootless.IsRootless() {
Expect(podCreate.ExitCode()).To(Equal(125))
} else {
Expect(podCreate.ExitCode()).To(Equal(0))
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "ip", "addr"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf.ExitCode()).To(Equal(0))
Expect(strings.Contains(podResolvConf.OutputToString(), ip)).To(BeTrue())
}
})
It("podman create pod with IP address and no infra should fail", func() {
@ -262,17 +266,20 @@ var _ = Describe("Podman pod create", func() {
It("podman create pod with MAC address", func() {
SkipIfRemote()
SkipIfRootless()
name := "test"
mac := "92:d0:c6:0a:29:35"
podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate.ExitCode()).To(Equal(0))
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "ip", "addr"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf.ExitCode()).To(Equal(0))
Expect(strings.Contains(podResolvConf.OutputToString(), mac)).To(BeTrue())
// Rootless should error
if rootless.IsRootless() {
Expect(podCreate.ExitCode()).To(Equal(125))
} else {
Expect(podCreate.ExitCode()).To(Equal(0))
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "-ti", "--rm", ALPINE, "ip", "addr"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf.ExitCode()).To(Equal(0))
Expect(strings.Contains(podResolvConf.OutputToString(), mac)).To(BeTrue())
}
})
It("podman create pod with MAC address and no infra should fail", func() {

View File

@ -165,9 +165,13 @@ function random_ip() {
# Create a pod with all the desired options
# FIXME: --ip=$ip fails:
# Error adding network: failed to allocate all requested IPs
local mac_option="--mac-address=$mac"
if is_rootless; then
mac_option=
fi
run_podman pod create --name=mypod \
--pod-id-file=$pod_id_file \
--mac-address=$mac \
$mac_option \
--hostname=$hostname \
--add-host "$add_host_n:$add_host_ip" \
--dns "$dns_server" \
@ -181,7 +185,7 @@ function random_ip() {
is "$(<$pod_id_file)" "$pod_id" "contents of pod-id-file"
# Check each of the options
if ! is_rootless; then
if [ -n "$mac_option" ]; then
run_podman run --rm --pod mypod $IMAGE ip link show
# 'ip' outputs hex in lower-case, ${expr,,} converts UC to lc
is "$output" ".* link/ether ${mac,,} " "requested MAC address was set"