Commit 423a4154 authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #25062 from dcbw/kubenet-rkt

Automatic merge from submit-queue Hook rkt kubelet runtime up to network plugins
parents de76bfe7 552b648c
...@@ -97,6 +97,12 @@ type Runtime interface { ...@@ -97,6 +97,12 @@ type Runtime interface {
RemoveImage(image ImageSpec) error RemoveImage(image ImageSpec) error
// Returns Image statistics. // Returns Image statistics.
ImageStats() (*ImageStats, error) ImageStats() (*ImageStats, error)
// Returns the filesystem path of the pod's network namespace; if the
// runtime does not handle namespace creation itself, or cannot return
// the network namespace path, it should return an error.
// TODO: Change ContainerID to a Pod ID since the namespace is shared
// by all containers in the pod.
GetNetNS(containerID ContainerID) (string, error)
// TODO(vmarmol): Unify pod and containerID args. // TODO(vmarmol): Unify pod and containerID args.
// GetContainerLogs returns logs of a specific container. By // GetContainerLogs returns logs of a specific container. By
// default, it returns a snapshot of the container log. Set 'follow' to true to // default, it returns a snapshot of the container log. Set 'follow' to true to
......
...@@ -338,6 +338,14 @@ func (f *FakeRuntime) PortForward(pod *Pod, port uint16, stream io.ReadWriteClos ...@@ -338,6 +338,14 @@ func (f *FakeRuntime) PortForward(pod *Pod, port uint16, stream io.ReadWriteClos
return f.Err return f.Err
} }
func (f *FakeRuntime) GetNetNS(containerID ContainerID) (string, error) {
f.Lock()
defer f.Unlock()
f.CalledFunctions = append(f.CalledFunctions, "GetNetNS")
return "", f.Err
}
func (f *FakeRuntime) GarbageCollect(gcPolicy ContainerGCPolicy) error { func (f *FakeRuntime) GarbageCollect(gcPolicy ContainerGCPolicy) error {
f.Lock() f.Lock()
defer f.Unlock() defer f.Unlock()
......
...@@ -128,6 +128,11 @@ func (r *Mock) PortForward(pod *Pod, port uint16, stream io.ReadWriteCloser) err ...@@ -128,6 +128,11 @@ func (r *Mock) PortForward(pod *Pod, port uint16, stream io.ReadWriteCloser) err
return args.Error(0) return args.Error(0)
} }
func (r *Mock) GetNetNS(containerID ContainerID) (string, error) {
args := r.Called(containerID)
return "", args.Error(0)
}
func (r *Mock) GarbageCollect(gcPolicy ContainerGCPolicy) error { func (r *Mock) GarbageCollect(gcPolicy ContainerGCPolicy) error {
args := r.Called(gcPolicy) args := r.Called(gcPolicy)
return args.Error(0) return args.Error(0)
......
...@@ -1959,7 +1959,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec ...@@ -1959,7 +1959,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec
} }
if dm.configureHairpinMode { if dm.configureHairpinMode {
if err = hairpin.SetUpContainer(podInfraContainer.State.Pid, network.DefaultInterfaceName); err != nil { if err = hairpin.SetUpContainerPid(podInfraContainer.State.Pid, network.DefaultInterfaceName); err != nil {
glog.Warningf("Hairpin setup failed for pod %q: %v", format.Pod(pod), err) glog.Warningf("Hairpin setup failed for pod %q: %v", format.Pod(pod), err)
} }
} }
......
...@@ -439,6 +439,8 @@ func NewMainKubelet( ...@@ -439,6 +439,8 @@ func NewMainKubelet(
klet.livenessManager, klet.livenessManager,
klet.volumeManager, klet.volumeManager,
klet.httpClient, klet.httpClient,
klet.networkPlugin,
klet.hairpinMode == componentconfig.HairpinVeth,
utilexec.New(), utilexec.New(),
kubecontainer.RealOS{}, kubecontainer.RealOS{},
imageBackOff, imageBackOff,
......
...@@ -40,13 +40,23 @@ var ( ...@@ -40,13 +40,23 @@ var (
ethtoolOutputRegex = regexp.MustCompile("peer_ifindex: (\\d+)") ethtoolOutputRegex = regexp.MustCompile("peer_ifindex: (\\d+)")
) )
func SetUpContainer(containerPid int, containerInterfaceName string) error { func SetUpContainerPid(containerPid int, containerInterfaceName string) error {
e := exec.New() pidStr := fmt.Sprintf("%d", containerPid)
return setUpContainerInternal(e, containerPid, containerInterfaceName) nsenterArgs := []string{"-t", pidStr, "-n"}
return setUpContainerInternal(containerInterfaceName, pidStr, nsenterArgs)
}
func SetUpContainerPath(netnsPath string, containerInterfaceName string) error {
if netnsPath[0] != '/' {
return fmt.Errorf("netnsPath path '%s' was invalid", netnsPath)
}
nsenterArgs := []string{"-n", netnsPath}
return setUpContainerInternal(containerInterfaceName, netnsPath, nsenterArgs)
} }
func setUpContainerInternal(e exec.Interface, containerPid int, containerInterfaceName string) error { func setUpContainerInternal(containerInterfaceName, containerDesc string, nsenterArgs []string) error {
hostIfName, err := findPairInterfaceOfContainerInterface(e, containerPid, containerInterfaceName) e := exec.New()
hostIfName, err := findPairInterfaceOfContainerInterface(e, containerInterfaceName, containerDesc, nsenterArgs)
if err != nil { if err != nil {
glog.Infof("Unable to find pair interface, setting up all interfaces: %v", err) glog.Infof("Unable to find pair interface, setting up all interfaces: %v", err)
return setUpAllInterfaces() return setUpAllInterfaces()
...@@ -54,7 +64,7 @@ func setUpContainerInternal(e exec.Interface, containerPid int, containerInterfa ...@@ -54,7 +64,7 @@ func setUpContainerInternal(e exec.Interface, containerPid int, containerInterfa
return setUpInterface(hostIfName) return setUpInterface(hostIfName)
} }
func findPairInterfaceOfContainerInterface(e exec.Interface, containerPid int, containerInterfaceName string) (string, error) { func findPairInterfaceOfContainerInterface(e exec.Interface, containerInterfaceName, containerDesc string, nsenterArgs []string) (string, error) {
nsenterPath, err := e.LookPath("nsenter") nsenterPath, err := e.LookPath("nsenter")
if err != nil { if err != nil {
return "", err return "", err
...@@ -63,15 +73,16 @@ func findPairInterfaceOfContainerInterface(e exec.Interface, containerPid int, c ...@@ -63,15 +73,16 @@ func findPairInterfaceOfContainerInterface(e exec.Interface, containerPid int, c
if err != nil { if err != nil {
return "", err return "", err
} }
// Get container's interface index
output, err := e.Command(nsenterPath, "-t", fmt.Sprintf("%d", containerPid), "-n", "-F", "--", ethtoolPath, "--statistics", containerInterfaceName).CombinedOutput() nsenterArgs = append(nsenterArgs, "-F", "--", ethtoolPath, "--statistics", containerInterfaceName)
output, err := e.Command(nsenterPath, nsenterArgs...).CombinedOutput()
if err != nil { if err != nil {
return "", fmt.Errorf("Unable to query interface %s of container %d: %v: %s", containerInterfaceName, containerPid, err, string(output)) return "", fmt.Errorf("Unable to query interface %s of container %s: %v: %s", containerInterfaceName, containerDesc, err, string(output))
} }
// look for peer_ifindex // look for peer_ifindex
match := ethtoolOutputRegex.FindSubmatch(output) match := ethtoolOutputRegex.FindSubmatch(output)
if match == nil { if match == nil {
return "", fmt.Errorf("No peer_ifindex in interface statistics for %s of container %d", containerInterfaceName, containerPid) return "", fmt.Errorf("No peer_ifindex in interface statistics for %s of container %s", containerInterfaceName, containerDesc)
} }
peerIfIndex, err := strconv.Atoi(string(match[1])) peerIfIndex, err := strconv.Atoi(string(match[1]))
if err != nil { // seems impossible (\d+ not numeric) if err != nil { // seems impossible (\d+ not numeric)
......
...@@ -69,7 +69,8 @@ func TestFindPairInterfaceOfContainerInterface(t *testing.T) { ...@@ -69,7 +69,8 @@ func TestFindPairInterfaceOfContainerInterface(t *testing.T) {
return fmt.Sprintf("/fake-bin/%s", file), nil return fmt.Sprintf("/fake-bin/%s", file), nil
}, },
} }
name, err := findPairInterfaceOfContainerInterface(&fexec, 123, "eth0") nsenterArgs := []string{"-t", "123", "-n"}
name, err := findPairInterfaceOfContainerInterface(&fexec, "eth0", "123", nsenterArgs)
if test.expectErr { if test.expectErr {
if err == nil { if err == nil {
t.Errorf("unexpected non-error") t.Errorf("unexpected non-error")
......
...@@ -31,10 +31,10 @@ import ( ...@@ -31,10 +31,10 @@ import (
"github.com/vishvananda/netlink/nl" "github.com/vishvananda/netlink/nl"
"github.com/appc/cni/libcni" "github.com/appc/cni/libcni"
cnitypes "github.com/appc/cni/pkg/types"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/apis/componentconfig" "k8s.io/kubernetes/pkg/apis/componentconfig"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockertools"
"k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/network"
"k8s.io/kubernetes/pkg/util/bandwidth" "k8s.io/kubernetes/pkg/util/bandwidth"
utilexec "k8s.io/kubernetes/pkg/util/exec" utilexec "k8s.io/kubernetes/pkg/util/exec"
...@@ -55,6 +55,7 @@ type kubenetNetworkPlugin struct { ...@@ -55,6 +55,7 @@ type kubenetNetworkPlugin struct {
host network.Host host network.Host
netConfig *libcni.NetworkConfig netConfig *libcni.NetworkConfig
loConfig *libcni.NetworkConfig
cniConfig *libcni.CNIConfig cniConfig *libcni.CNIConfig
shaper bandwidth.BandwidthShaper shaper bandwidth.BandwidthShaper
podCIDRs map[kubecontainer.ContainerID]string podCIDRs map[kubecontainer.ContainerID]string
...@@ -94,10 +95,20 @@ func (plugin *kubenetNetworkPlugin) Init(host network.Host, hairpinMode componen ...@@ -94,10 +95,20 @@ func (plugin *kubenetNetworkPlugin) Init(host network.Host, hairpinMode componen
// was built-in, we simply ignore the error here. A better thing to do is // was built-in, we simply ignore the error here. A better thing to do is
// to check the kernel version in the future. // to check the kernel version in the future.
plugin.execer.Command("modprobe", "br-netfilter").CombinedOutput() plugin.execer.Command("modprobe", "br-netfilter").CombinedOutput()
if err := utilsysctl.SetSysctl(sysctlBridgeCallIptables, 1); err != nil { err := utilsysctl.SetSysctl(sysctlBridgeCallIptables, 1)
if err != nil {
glog.Warningf("can't set sysctl %s: %v", sysctlBridgeCallIptables, err) glog.Warningf("can't set sysctl %s: %v", sysctlBridgeCallIptables, err)
} }
plugin.loConfig, err = libcni.ConfFromBytes([]byte(`{
"cniVersion": "0.1.0",
"name": "kubenet-loopback",
"type": "loopback"
}`))
if err != nil {
return fmt.Errorf("Failed to generate loopback config: %v", err)
}
return nil return nil
} }
...@@ -250,7 +261,7 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k ...@@ -250,7 +261,7 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k
start := time.Now() start := time.Now()
defer func() { defer func() {
glog.V(4).Infof("TearDownPod took %v for %s/%s", time.Since(start), namespace, name) glog.V(4).Infof("SetUpPod took %v for %s/%s", time.Since(start), namespace, name)
}() }()
pod, ok := plugin.host.GetPodByName(namespace, name) pod, ok := plugin.host.GetPodByName(namespace, name)
...@@ -266,23 +277,20 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k ...@@ -266,23 +277,20 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k
return fmt.Errorf("Kubenet cannot SetUpPod: %v", err) return fmt.Errorf("Kubenet cannot SetUpPod: %v", err)
} }
runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) // Bring up container loopback interface
if !ok { if _, err := plugin.addContainerToNetwork(plugin.loConfig, "lo", namespace, name, id); err != nil {
return fmt.Errorf("Kubenet execution called on non-docker runtime") return err
}
netnsPath, err := runtime.GetNetNS(id)
if err != nil {
return fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err)
} }
rt := buildCNIRuntimeConf(name, namespace, id, netnsPath) // Hook container up with our bridge
res, err := plugin.addContainerToNetwork(plugin.netConfig, network.DefaultInterfaceName, namespace, name, id)
if err != nil { if err != nil {
return fmt.Errorf("Error building CNI config: %v", err)
}
if err = plugin.addContainerToNetwork(id, rt); err != nil {
return err return err
} }
if res.IP4 == nil || res.IP4.IP.String() == "" {
return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id)
}
plugin.podCIDRs[id] = res.IP4.IP.String()
// Put the container bridge into promiscuous mode to force it to accept hairpin packets. // Put the container bridge into promiscuous mode to force it to accept hairpin packets.
// TODO: Remove this once the kernel bug (#20096) is fixed. // TODO: Remove this once the kernel bug (#20096) is fixed.
...@@ -330,20 +338,6 @@ func (plugin *kubenetNetworkPlugin) TearDownPod(namespace string, name string, i ...@@ -330,20 +338,6 @@ func (plugin *kubenetNetworkPlugin) TearDownPod(namespace string, name string, i
return fmt.Errorf("Kubenet needs a PodCIDR to tear down pods") return fmt.Errorf("Kubenet needs a PodCIDR to tear down pods")
} }
runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager)
if !ok {
return fmt.Errorf("Kubenet execution called on non-docker runtime")
}
netnsPath, err := runtime.GetNetNS(id)
if err != nil {
return err
}
rt := buildCNIRuntimeConf(name, namespace, id, netnsPath)
if err != nil {
return fmt.Errorf("Error building CNI config: %v", err)
}
// no cached CIDR is Ok during teardown // no cached CIDR is Ok during teardown
if cidr, ok := plugin.podCIDRs[id]; ok { if cidr, ok := plugin.podCIDRs[id]; ok {
glog.V(5).Infof("Removing pod CIDR %s from shaper", cidr) glog.V(5).Infof("Removing pod CIDR %s from shaper", cidr)
...@@ -354,9 +348,10 @@ func (plugin *kubenetNetworkPlugin) TearDownPod(namespace string, name string, i ...@@ -354,9 +348,10 @@ func (plugin *kubenetNetworkPlugin) TearDownPod(namespace string, name string, i
} }
} }
} }
if err = plugin.delContainerFromNetwork(id, rt); err != nil { if err := plugin.delContainerFromNetwork(plugin.netConfig, network.DefaultInterfaceName, namespace, name, id); err != nil {
return err return err
} }
delete(plugin.podCIDRs, id)
return nil return nil
} }
...@@ -373,12 +368,8 @@ func (plugin *kubenetNetworkPlugin) GetPodNetworkStatus(namespace string, name s ...@@ -373,12 +368,8 @@ func (plugin *kubenetNetworkPlugin) GetPodNetworkStatus(namespace string, name s
return &network.PodNetworkStatus{IP: ip}, nil return &network.PodNetworkStatus{IP: ip}, nil
} }
} }
// TODO: remove type conversion once kubenet supports multiple runtime
runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) netnsPath, err := plugin.host.GetRuntime().GetNetNS(id)
if !ok {
return nil, fmt.Errorf("Kubenet execution called on non-docker runtime")
}
netnsPath, err := runtime.GetNetNS(id)
if err != nil { if err != nil {
return nil, fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err) return nil, fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err)
} }
...@@ -412,37 +403,43 @@ func (plugin *kubenetNetworkPlugin) Status() error { ...@@ -412,37 +403,43 @@ func (plugin *kubenetNetworkPlugin) Status() error {
return nil return nil
} }
func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) *libcni.RuntimeConf { func (plugin *kubenetNetworkPlugin) buildCNIRuntimeConf(ifName string, id kubecontainer.ContainerID) (*libcni.RuntimeConf, error) {
glog.V(4).Infof("Kubenet: using netns path %v", podNetnsPath) netnsPath, err := plugin.host.GetRuntime().GetNetNS(id)
glog.V(4).Infof("Kubenet: using podns path %v", podNs) if err != nil {
return nil, fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err)
}
return &libcni.RuntimeConf{ return &libcni.RuntimeConf{
ContainerID: podInfraContainerID.ID, ContainerID: id.ID,
NetNS: podNetnsPath, NetNS: netnsPath,
IfName: network.DefaultInterfaceName, IfName: ifName,
} }, nil
} }
func (plugin *kubenetNetworkPlugin) addContainerToNetwork(id kubecontainer.ContainerID, rt *libcni.RuntimeConf) error { func (plugin *kubenetNetworkPlugin) addContainerToNetwork(config *libcni.NetworkConfig, ifName, namespace, name string, id kubecontainer.ContainerID) (*cnitypes.Result, error) {
glog.V(3).Infof("Calling cni plugins to add container to network with cni runtime: %+v", rt) rt, err := plugin.buildCNIRuntimeConf(ifName, id)
res, err := plugin.cniConfig.AddNetwork(plugin.netConfig, rt)
if err != nil { if err != nil {
return fmt.Errorf("Error adding container to network: %v", err) return nil, fmt.Errorf("Error building CNI config: %v", err)
}
if res.IP4 == nil || res.IP4.IP.String() == "" {
return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id)
} }
plugin.podCIDRs[id] = res.IP4.IP.String() glog.V(3).Infof("Adding %s/%s to '%s' with CNI '%s' plugin and runtime: %+v", namespace, name, config.Network.Name, config.Network.Type, rt)
return nil res, err := plugin.cniConfig.AddNetwork(config, rt)
if err != nil {
return nil, fmt.Errorf("Error adding container to network: %v", err)
}
return res, nil
} }
func (plugin *kubenetNetworkPlugin) delContainerFromNetwork(id kubecontainer.ContainerID, rt *libcni.RuntimeConf) error { func (plugin *kubenetNetworkPlugin) delContainerFromNetwork(config *libcni.NetworkConfig, ifName, namespace, name string, id kubecontainer.ContainerID) error {
glog.V(3).Infof("Calling cni plugins to remove container from network with cni runtime: %+v", rt) rt, err := plugin.buildCNIRuntimeConf(ifName, id)
if err := plugin.cniConfig.DelNetwork(plugin.netConfig, rt); err != nil { if err != nil {
return fmt.Errorf("Error building CNI config: %v", err)
}
glog.V(3).Infof("Removing %s/%s from '%s' with CNI '%s' plugin and runtime: %+v", namespace, name, config.Network.Name, config.Network.Type, rt)
if err := plugin.cniConfig.DelNetwork(config, rt); err != nil {
return fmt.Errorf("Error removing container from network: %v", err) return fmt.Errorf("Error removing container from network: %v", err)
} }
delete(plugin.podCIDRs, id)
return nil return nil
} }
......
...@@ -17,6 +17,8 @@ limitations under the License. ...@@ -17,6 +17,8 @@ limitations under the License.
package kubenet package kubenet
import ( import (
"fmt"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/network"
nettest "k8s.io/kubernetes/pkg/kubelet/network/testing" nettest "k8s.io/kubernetes/pkg/kubelet/network/testing"
...@@ -38,9 +40,6 @@ func TestGetPodNetworkStatus(t *testing.T) { ...@@ -38,9 +40,6 @@ func TestGetPodNetworkStatus(t *testing.T) {
podIPMap[kubecontainer.ContainerID{ID: "1"}] = "10.245.0.2/32" podIPMap[kubecontainer.ContainerID{ID: "1"}] = "10.245.0.2/32"
podIPMap[kubecontainer.ContainerID{ID: "2"}] = "10.245.0.3/32" podIPMap[kubecontainer.ContainerID{ID: "2"}] = "10.245.0.3/32"
fhost := nettest.NewFakeHost(nil)
fakeKubenet := newFakeKubenetPlugin(podIPMap, nil, fhost)
testCases := []struct { testCases := []struct {
id string id string
expectError bool expectError bool
...@@ -66,6 +65,34 @@ func TestGetPodNetworkStatus(t *testing.T) { ...@@ -66,6 +65,34 @@ func TestGetPodNetworkStatus(t *testing.T) {
//TODO: add test cases for retrieving ip inside container network namespace //TODO: add test cases for retrieving ip inside container network namespace
} }
fakeCmds := make([]exec.FakeCommandAction, 0)
for _, t := range testCases {
// the fake commands return the IP from the given index, or an error
fCmd := exec.FakeCmd{
CombinedOutputScript: []exec.FakeCombinedOutputAction{
func() ([]byte, error) {
ip, ok := podIPMap[kubecontainer.ContainerID{ID: t.id}]
if !ok {
return nil, fmt.Errorf("Pod IP %q not found", t.id)
}
return []byte(ip), nil
},
},
}
fakeCmds = append(fakeCmds, func(cmd string, args ...string) exec.Cmd {
return exec.InitFakeCmd(&fCmd, cmd, args...)
})
}
fexec := exec.FakeExec{
CommandScript: fakeCmds,
LookPathFunc: func(file string) (string, error) {
return fmt.Sprintf("/fake-bin/%s", file), nil
},
}
fhost := nettest.NewFakeHost(nil)
fakeKubenet := newFakeKubenetPlugin(podIPMap, &fexec, fhost)
for i, tc := range testCases { for i, tc := range testCases {
out, err := fakeKubenet.GetPodNetworkStatus("", "", kubecontainer.ContainerID{ID: tc.id}) out, err := fakeKubenet.GetPodNetworkStatus("", "", kubecontainer.ContainerID{ID: tc.id})
if tc.expectError { if tc.expectError {
......
...@@ -1078,6 +1078,7 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1078,6 +1078,7 @@ func TestGenerateRunCommand(t *testing.T) {
tests := []struct { tests := []struct {
pod *api.Pod pod *api.Pod
uuid string uuid string
netnsName string
dnsServers []string dnsServers []string
dnsSearches []string dnsSearches []string
...@@ -1095,6 +1096,7 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1095,6 +1096,7 @@ func TestGenerateRunCommand(t *testing.T) {
Spec: api.PodSpec{}, Spec: api.PodSpec{},
}, },
"rkt-uuid-foo", "rkt-uuid-foo",
"default",
[]string{}, []string{},
[]string{}, []string{},
"", "",
...@@ -1109,11 +1111,12 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1109,11 +1111,12 @@ func TestGenerateRunCommand(t *testing.T) {
}, },
}, },
"rkt-uuid-foo", "rkt-uuid-foo",
"default",
[]string{}, []string{},
[]string{}, []string{},
"pod-hostname-foo", "pod-hostname-foo",
nil, nil,
"/bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --net=rkt.kubernetes.io --hostname=pod-hostname-foo rkt-uuid-foo", " --net=\"/var/run/netns/default\" -- /bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --net=host --hostname=pod-hostname-foo rkt-uuid-foo",
}, },
// Case #2, returns no dns, with host-net. // Case #2, returns no dns, with host-net.
{ {
...@@ -1128,6 +1131,7 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1128,6 +1131,7 @@ func TestGenerateRunCommand(t *testing.T) {
}, },
}, },
"rkt-uuid-foo", "rkt-uuid-foo",
"",
[]string{}, []string{},
[]string{}, []string{},
"", "",
...@@ -1147,11 +1151,12 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1147,11 +1151,12 @@ func TestGenerateRunCommand(t *testing.T) {
}, },
}, },
"rkt-uuid-foo", "rkt-uuid-foo",
"default",
[]string{"127.0.0.1"}, []string{"127.0.0.1"},
[]string{"."}, []string{"."},
"pod-hostname-foo", "pod-hostname-foo",
nil, nil,
"/bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --net=rkt.kubernetes.io --dns=127.0.0.1 --dns-search=. --dns-opt=ndots:5 --hostname=pod-hostname-foo rkt-uuid-foo", " --net=\"/var/run/netns/default\" -- /bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --net=host --dns=127.0.0.1 --dns-search=. --dns-opt=ndots:5 --hostname=pod-hostname-foo rkt-uuid-foo",
}, },
// Case #4, returns no dns, dns searches, with host-network. // Case #4, returns no dns, dns searches, with host-network.
{ {
...@@ -1166,6 +1171,7 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1166,6 +1171,7 @@ func TestGenerateRunCommand(t *testing.T) {
}, },
}, },
"rkt-uuid-foo", "rkt-uuid-foo",
"",
[]string{"127.0.0.1"}, []string{"127.0.0.1"},
[]string{"."}, []string{"."},
"pod-hostname-foo", "pod-hostname-foo",
...@@ -1189,7 +1195,7 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1189,7 +1195,7 @@ func TestGenerateRunCommand(t *testing.T) {
testCaseHint := fmt.Sprintf("test case #%d", i) testCaseHint := fmt.Sprintf("test case #%d", i)
rkt.runtimeHelper = &fakeRuntimeHelper{tt.dnsServers, tt.dnsSearches, tt.hostName, "", tt.err} rkt.runtimeHelper = &fakeRuntimeHelper{tt.dnsServers, tt.dnsSearches, tt.hostName, "", tt.err}
result, err := rkt.generateRunCommand(tt.pod, tt.uuid) result, err := rkt.generateRunCommand(tt.pod, tt.uuid, tt.netnsName)
assert.Equal(t, tt.err, err, testCaseHint) assert.Equal(t, tt.err, err, testCaseHint)
assert.Equal(t, tt.expect, result, testCaseHint) assert.Equal(t, tt.expect, result, testCaseHint)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment