Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] allow static ip and mac with rootless cni network #8469

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contrib/rootless-cni-infra/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ COPY rootless-cni-infra /usr/local/bin
ENV CNI_PATH=/opt/cni/bin
CMD ["sleep", "infinity"]

ENV ROOTLESS_CNI_INFRA_VERSION=3
ENV ROOTLESS_CNI_INFRA_VERSION=4
14 changes: 11 additions & 3 deletions contrib/rootless-cni-infra/rootless-cni-infra
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ wait_unshare_net() {
done
}

# CLI subcommand: "alloc $CONTAINER_ID $NETWORK_NAME $POD_NAME"
# CLI subcommand: "alloc $CONTAINER_ID $NETWORK_NAME $POD_NAME $IP $MAC"
cmd_entrypoint_alloc() {
if [ "$#" -ne 3 ]; then
echo >&2 "Usage: $ARG0 alloc CONTAINER_ID NETWORK_NAME POD_NAME"
if [ "$#" -ne 5 ]; then
echo >&2 "Usage: $ARG0 alloc CONTAINER_ID NETWORK_NAME POD_NAME IP MAC"
exit 1
fi

ID="$1"
NET="$2"
K8S_POD_NAME="$3"
IP="$4"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting a static MAC but not a static IP is allowed - my Bash isn't good enough to know if this supports that, though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that works but it requires #8467 for test

MAC="$5"

dir="${BASE}/${ID}"
mkdir -p "${dir}/attached" "${dir}/attached-args"
Expand All @@ -46,6 +48,12 @@ cmd_entrypoint_alloc() {
nsenter -t "${pid}" -n ip link set lo up
fi
CNI_ARGS="IgnoreUnknown=1;K8S_POD_NAME=${K8S_POD_NAME}"
if [ "$IP" ]; then
CNI_ARGS="$CNI_ARGS;IP=${IP}"
fi
if [ "$MAC" ]; then
CNI_ARGS="$CNI_ARGS;MAC=${MAC}"
fi
nwcount=$(find "${dir}/attached" -type f | wc -l)
CNI_IFNAME="eth${nwcount}"
export CNI_ARGS CNI_IFNAME
Expand Down
19 changes: 14 additions & 5 deletions libpod/rootless_cni_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

// Built from ../contrib/rootless-cni-infra.
var rootlessCNIInfraImage = map[string]string{
"amd64": "quay.io/libpod/rootless-cni-infra@sha256:304742d5d221211df4ec672807a5842ff11e3729c50bc424ea0cea858f69d7b7", // 3-amd64
"amd64": "quay.io/luap99/rootless-cni-infra@sha256:4e9f1e223463a46d9f9b019c0fa8c902494ed34872f75104d985b23812f19683", // 4-amd64
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somebody needs to build the new image and upload it to the libpod repo. After that I can add it here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomSweeneyRedHat is this something you can do?

}

const (
Expand Down Expand Up @@ -58,9 +58,18 @@ func AllocRootlessCNI(ctx context.Context, c *Container) (ns.NetNS, []*cnitypes.
return nil, nil, err
}
k8sPodName := getCNIPodName(c) // passed to CNI as K8S_POD_NAME
ip := ""
if c.config.StaticIP != nil {
ip = c.config.StaticIP.String()
}
mac := ""
if c.config.StaticMAC != nil {
mac = c.config.StaticMAC.String()
}

cniResults := make([]*cnitypes.Result, len(networks))
for i, nw := range networks {
cniRes, err := rootlessCNIInfraCallAlloc(infra, c.ID(), nw, k8sPodName)
cniRes, err := rootlessCNIInfraCallAlloc(infra, c.ID(), nw, k8sPodName, ip, mac)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -135,11 +144,11 @@ func getCNIPodName(c *Container) string {
return c.Name()
}

func rootlessCNIInfraCallAlloc(infra *Container, id, nw, k8sPodName string) (*cnitypes.Result, error) {
logrus.Debugf("rootless CNI: alloc %q, %q, %q", id, nw, k8sPodName)
func rootlessCNIInfraCallAlloc(infra *Container, id, nw, k8sPodName, ip, mac string) (*cnitypes.Result, error) {
logrus.Debugf("rootless CNI: alloc %q, %q, %q, %q, %q", id, nw, k8sPodName, ip, mac)
var err error

_, err = rootlessCNIInfraExec(infra, "alloc", id, nw, k8sPodName)
_, err = rootlessCNIInfraExec(infra, "alloc", id, nw, k8sPodName, ip, mac)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/specgen/container_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func exclusiveOptions(opt1, opt2 string) error {
// input for creating a container.
func (s *SpecGenerator) Validate() error {

if rootless.IsRootless() {
if rootless.IsRootless() && len(s.CNINetworks) == 0 {
if s.StaticIP != nil || s.StaticIPv6 != nil {
return ErrNoStaticIPRootless
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/specgen/pod_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func exclusivePodOptions(opt1, opt2 string) error {
// Validate verifies the input is valid
func (p *PodSpecGenerator) Validate() error {

if rootless.IsRootless() {
if rootless.IsRootless() && len(p.CNINetworks) == 0 {
if p.StaticIP != nil {
return ErrNoStaticIPRootless
}
Expand Down
5 changes: 2 additions & 3 deletions test/e2e/create_staticip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ var _ = Describe("Podman create with --ip flag", func() {
})

It("Podman create --ip with non-allocatable IP", func() {
SkipIfRootless("--ip is not supported in rootless mode")
result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", "203.0.113.124", ALPINE, "ls"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expand All @@ -63,7 +62,7 @@ var _ = Describe("Podman create with --ip flag", func() {
ip := GetRandomIPAddress()
result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", ip, ALPINE, "ip", "addr"})
result.WaitWithDefaultTimeout()
// Rootless static ip assignment should error
// Rootless static ip assignment without network should error
if rootless.IsRootless() {
Expect(result.ExitCode()).To(Equal(125))
} else {
Expand All @@ -81,7 +80,7 @@ var _ = Describe("Podman create with --ip flag", func() {
})

It("Podman create two containers with the same IP", func() {
SkipIfRootless("--ip not supported in rootless mode")
SkipIfRootless("--ip not supported without network in rootless mode")
ip := GetRandomIPAddress()
result := podmanTest.Podman([]string{"create", "--name", "test1", "--ip", ip, ALPINE, "sleep", "999"})
result.WaitWithDefaultTimeout()
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ var _ = Describe("Podman create", func() {
})

It("create container in pod with IP should fail", func() {
SkipIfRootless("Setting IP not supported in rootless mode")
SkipIfRootless("Setting IP not supported in rootless mode without network")
name := "createwithstaticip"
pod := podmanTest.RunTopContainerInPod("", "new:"+name)
pod.WaitWithDefaultTimeout()
Expand All @@ -564,7 +564,7 @@ var _ = Describe("Podman create", func() {
})

It("create container in pod with mac should fail", func() {
SkipIfRootless("Setting MAC Address not supported in rootless mode")
SkipIfRootless("Setting MAC Address not supported in rootless mode without network")
name := "createwithstaticmac"
pod := podmanTest.RunTopContainerInPod("", "new:"+name)
pod.WaitWithDefaultTimeout()
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/pod_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ var _ = Describe("Podman pod create", func() {
ip := GetRandomIPAddress()
podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name})
podCreate.WaitWithDefaultTimeout()
// Rootless should error
// Rootless should error without network
if rootless.IsRootless() {
Expect(podCreate.ExitCode()).To(Equal(125))
} else {
Expand All @@ -247,7 +247,7 @@ var _ = Describe("Podman pod create", func() {
})

It("podman container in pod with IP address shares IP address", func() {
SkipIfRootless("Rootless does not support --ip")
SkipIfRootless("Rootless does not support --ip without network")
podName := "test"
ctrName := "testCtr"
ip := GetRandomIPAddress()
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/pod_inspect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ var _ = Describe("Podman pod inspect", func() {
})

It("podman pod inspect outputs show correct MAC", func() {
SkipIfRootless("--mac-address is not supported in rootless mode")
SkipIfRootless("--mac-address is not supported in rootless mode without network")
podName := "testPod"
macAddr := "42:43:44:00:00:01"
create := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--mac-address", macAddr})
Expand Down
6 changes: 0 additions & 6 deletions test/e2e/run_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,6 @@ var _ = Describe("Podman run networking", func() {
})

It("podman run in custom CNI network with --static-ip", func() {
SkipIfRootless("Rootless mode does not support --ip")
netName := "podmantestnetwork"
ipAddr := "10.25.30.128"
create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.25.30.0/24", netName})
Expand All @@ -551,14 +550,9 @@ var _ = Describe("Podman run networking", func() {
run.WaitWithDefaultTimeout()
Expect(run.ExitCode()).To(BeZero())
Expect(run.OutputToString()).To(ContainSubstring(ipAddr))

create = podmanTest.Podman([]string{"network", "rm", netName})
create.WaitWithDefaultTimeout()
Expect(create.ExitCode()).To(BeZero())
})

It("podman run with new:pod and static-ip", func() {
SkipIfRootless("Rootless does not support --ip")
netName := "podmantestnetwork2"
ipAddr := "10.25.40.128"
podname := "testpod"
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/run_staticip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var _ = Describe("Podman run with --ip flag", func() {
)

BeforeEach(func() {
SkipIfRootless("rootless does not support --ip")
SkipIfRootless("rootless does not support --ip without network")
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
Expand Down