mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 19:23:40 +00:00
Merge pull request #8146 from yifan-gu/runtime_opt
kubelet/container: Refactor RunContainerOptions.
This commit is contained in:
commit
67eab52b9e
@ -185,14 +185,43 @@ type Image struct {
|
|||||||
Size int64
|
Size int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EnvVar struct {
|
||||||
|
Name string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mount struct {
|
||||||
|
// Name of the volume mount.
|
||||||
|
Name string
|
||||||
|
// Path of the mount within the container.
|
||||||
|
ContainerPath string
|
||||||
|
// Path of the mount on the host.
|
||||||
|
HostPath string
|
||||||
|
// Whether the mount is read-only.
|
||||||
|
ReadOnly bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type PortMapping struct {
|
||||||
|
// Name of the port mapping
|
||||||
|
Name string
|
||||||
|
// Protocol of the port mapping.
|
||||||
|
Protocol api.Protocol
|
||||||
|
// The port number within the container.
|
||||||
|
ContainerPort int
|
||||||
|
// The port number on the host.
|
||||||
|
HostPort int
|
||||||
|
// The host IP.
|
||||||
|
HostIP string
|
||||||
|
}
|
||||||
|
|
||||||
// RunContainerOptions specify the options which are necessary for running containers
|
// RunContainerOptions specify the options which are necessary for running containers
|
||||||
type RunContainerOptions struct {
|
type RunContainerOptions struct {
|
||||||
// The environment variables, they are in the form of 'key=value'.
|
// The environment variables list.
|
||||||
Envs []string
|
Envs []EnvVar
|
||||||
// The mounts for the containers, they are in the form of:
|
// The mounts for the containers.
|
||||||
// 'hostPath:containerPath', or
|
Mounts []Mount
|
||||||
// 'hostPath:containerPath:ro', if the path read only.
|
// The port mappings for the containers.
|
||||||
Binds []string
|
PortMappings []PortMapping
|
||||||
// If the container has specified the TerminationMessagePath, then
|
// If the container has specified the TerminationMessagePath, then
|
||||||
// this directory will be used to create and mount the log file to
|
// this directory will be used to create and mount the log file to
|
||||||
// container.TerminationMessagePath
|
// container.TerminationMessagePath
|
||||||
|
@ -572,8 +572,7 @@ func TestFindContainersByPod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMakePortsAndBindings(t *testing.T) {
|
func TestMakePortsAndBindings(t *testing.T) {
|
||||||
container := api.Container{
|
ports := []kubecontainer.PortMapping{
|
||||||
Ports: []api.ContainerPort{
|
|
||||||
{
|
{
|
||||||
ContainerPort: 80,
|
ContainerPort: 80,
|
||||||
HostPort: 8080,
|
HostPort: 8080,
|
||||||
@ -594,12 +593,11 @@ func TestMakePortsAndBindings(t *testing.T) {
|
|||||||
HostPort: 445,
|
HostPort: 445,
|
||||||
Protocol: "foobar",
|
Protocol: "foobar",
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
exposedPorts, bindings := makePortsAndBindings(&container)
|
exposedPorts, bindings := makePortsAndBindings(ports)
|
||||||
if len(container.Ports) != len(exposedPorts) ||
|
if len(ports) != len(exposedPorts) ||
|
||||||
len(container.Ports) != len(bindings) {
|
len(ports) != len(bindings) {
|
||||||
t.Errorf("Unexpected ports and bindings, %#v %#v %#v", container, exposedPorts, bindings)
|
t.Errorf("Unexpected ports and bindings, %#v %#v %#v", ports, exposedPorts, bindings)
|
||||||
}
|
}
|
||||||
for key, value := range bindings {
|
for key, value := range bindings {
|
||||||
switch value[0].HostPort {
|
switch value[0].HostPort {
|
||||||
|
@ -477,6 +477,65 @@ func (dm *DockerManager) GetPodInfraContainer(pod kubecontainer.Pod) (kubecontai
|
|||||||
return kubecontainer.Container{}, fmt.Errorf("unable to find pod infra container for pod %v", pod.ID)
|
return kubecontainer.Container{}, fmt.Errorf("unable to find pod infra container for pod %v", pod.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// makeEnvList converts EnvVar list to a list of strings, in the form of
|
||||||
|
// '<key>=<value>', which can be understood by docker.
|
||||||
|
func makeEnvList(envs []kubecontainer.EnvVar) (result []string) {
|
||||||
|
for _, env := range envs {
|
||||||
|
result = append(result, fmt.Sprintf("%s=%s", env.Name, env.Value))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeMountBindings converts the mount list to a list of strings that
|
||||||
|
// can be understood by docker.
|
||||||
|
// Each element in the string is in the form of:
|
||||||
|
// '<HostPath>:<ContainerPath>', or
|
||||||
|
// '<HostPath>:<ContainerPath>:ro', if the path is read only.
|
||||||
|
func makeMountBindings(mounts []kubecontainer.Mount) (result []string) {
|
||||||
|
for _, m := range mounts {
|
||||||
|
bind := fmt.Sprintf("%s:%s", m.HostPath, m.ContainerPath)
|
||||||
|
if m.ReadOnly {
|
||||||
|
bind += ":ro"
|
||||||
|
}
|
||||||
|
result = append(result, bind)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker.Port]struct{}, map[docker.Port][]docker.PortBinding) {
|
||||||
|
exposedPorts := map[docker.Port]struct{}{}
|
||||||
|
portBindings := map[docker.Port][]docker.PortBinding{}
|
||||||
|
for _, port := range portMappings {
|
||||||
|
exteriorPort := port.HostPort
|
||||||
|
if exteriorPort == 0 {
|
||||||
|
// No need to do port binding when HostPort is not specified
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
interiorPort := port.ContainerPort
|
||||||
|
// Some of this port stuff is under-documented voodoo.
|
||||||
|
// See http://stackoverflow.com/questions/20428302/binding-a-port-to-a-host-interface-using-the-rest-api
|
||||||
|
var protocol string
|
||||||
|
switch strings.ToUpper(string(port.Protocol)) {
|
||||||
|
case "UDP":
|
||||||
|
protocol = "/udp"
|
||||||
|
case "TCP":
|
||||||
|
protocol = "/tcp"
|
||||||
|
default:
|
||||||
|
glog.Warningf("Unknown protocol %q: defaulting to TCP", port.Protocol)
|
||||||
|
protocol = "/tcp"
|
||||||
|
}
|
||||||
|
dockerPort := docker.Port(strconv.Itoa(interiorPort) + protocol)
|
||||||
|
exposedPorts[dockerPort] = struct{}{}
|
||||||
|
portBindings[dockerPort] = []docker.PortBinding{
|
||||||
|
{
|
||||||
|
HostPort: strconv.Itoa(exteriorPort),
|
||||||
|
HostIP: port.HostIP,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exposedPorts, portBindings
|
||||||
|
}
|
||||||
|
|
||||||
func (dm *DockerManager) runContainer(
|
func (dm *DockerManager) runContainer(
|
||||||
pod *api.Pod,
|
pod *api.Pod,
|
||||||
container *api.Container,
|
container *api.Container,
|
||||||
@ -490,7 +549,7 @@ func (dm *DockerManager) runContainer(
|
|||||||
PodUID: pod.UID,
|
PodUID: pod.UID,
|
||||||
ContainerName: container.Name,
|
ContainerName: container.Name,
|
||||||
}
|
}
|
||||||
exposedPorts, portBindings := makePortsAndBindings(container)
|
exposedPorts, portBindings := makePortsAndBindings(opts.PortMappings)
|
||||||
|
|
||||||
// TODO(vmarmol): Handle better.
|
// TODO(vmarmol): Handle better.
|
||||||
// Cap hostname at 63 chars (specification is 64bytes which is 63 chars and the null terminating char).
|
// Cap hostname at 63 chars (specification is 64bytes which is 63 chars and the null terminating char).
|
||||||
@ -517,7 +576,7 @@ func (dm *DockerManager) runContainer(
|
|||||||
dockerOpts := docker.CreateContainerOptions{
|
dockerOpts := docker.CreateContainerOptions{
|
||||||
Name: BuildDockerName(dockerName, container),
|
Name: BuildDockerName(dockerName, container),
|
||||||
Config: &docker.Config{
|
Config: &docker.Config{
|
||||||
Env: opts.Envs,
|
Env: makeEnvList(opts.Envs),
|
||||||
ExposedPorts: exposedPorts,
|
ExposedPorts: exposedPorts,
|
||||||
Hostname: containerHostname,
|
Hostname: containerHostname,
|
||||||
Image: container.Image,
|
Image: container.Image,
|
||||||
@ -546,6 +605,8 @@ func (dm *DockerManager) runContainer(
|
|||||||
dm.recorder.Eventf(ref, "created", "Created with docker id %v", dockerContainer.ID)
|
dm.recorder.Eventf(ref, "created", "Created with docker id %v", dockerContainer.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binds := makeMountBindings(opts.Mounts)
|
||||||
|
|
||||||
// The reason we create and mount the log file in here (not in kubelet) is because
|
// The reason we create and mount the log file in here (not in kubelet) is because
|
||||||
// the file's location depends on the ID of the container, and we need to create and
|
// the file's location depends on the ID of the container, and we need to create and
|
||||||
// mount the file before actually starting the container.
|
// mount the file before actually starting the container.
|
||||||
@ -560,13 +621,13 @@ func (dm *DockerManager) runContainer(
|
|||||||
} else {
|
} else {
|
||||||
fs.Close() // Close immediately; we're just doing a `touch` here
|
fs.Close() // Close immediately; we're just doing a `touch` here
|
||||||
b := fmt.Sprintf("%s:%s", containerLogPath, container.TerminationMessagePath)
|
b := fmt.Sprintf("%s:%s", containerLogPath, container.TerminationMessagePath)
|
||||||
opts.Binds = append(opts.Binds, b)
|
binds = append(binds, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hc := &docker.HostConfig{
|
hc := &docker.HostConfig{
|
||||||
PortBindings: portBindings,
|
PortBindings: portBindings,
|
||||||
Binds: opts.Binds,
|
Binds: binds,
|
||||||
NetworkMode: netMode,
|
NetworkMode: netMode,
|
||||||
IpcMode: ipcMode,
|
IpcMode: ipcMode,
|
||||||
}
|
}
|
||||||
@ -603,40 +664,6 @@ func setEntrypointAndCommand(container *api.Container, opts *docker.CreateContai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makePortsAndBindings(container *api.Container) (map[docker.Port]struct{}, map[docker.Port][]docker.PortBinding) {
|
|
||||||
exposedPorts := map[docker.Port]struct{}{}
|
|
||||||
portBindings := map[docker.Port][]docker.PortBinding{}
|
|
||||||
for _, port := range container.Ports {
|
|
||||||
exteriorPort := port.HostPort
|
|
||||||
if exteriorPort == 0 {
|
|
||||||
// No need to do port binding when HostPort is not specified
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
interiorPort := port.ContainerPort
|
|
||||||
// Some of this port stuff is under-documented voodoo.
|
|
||||||
// See http://stackoverflow.com/questions/20428302/binding-a-port-to-a-host-interface-using-the-rest-api
|
|
||||||
var protocol string
|
|
||||||
switch strings.ToUpper(string(port.Protocol)) {
|
|
||||||
case "UDP":
|
|
||||||
protocol = "/udp"
|
|
||||||
case "TCP":
|
|
||||||
protocol = "/tcp"
|
|
||||||
default:
|
|
||||||
glog.Warningf("Unknown protocol %q: defaulting to TCP", port.Protocol)
|
|
||||||
protocol = "/tcp"
|
|
||||||
}
|
|
||||||
dockerPort := docker.Port(strconv.Itoa(interiorPort) + protocol)
|
|
||||||
exposedPorts[dockerPort] = struct{}{}
|
|
||||||
portBindings[dockerPort] = []docker.PortBinding{
|
|
||||||
{
|
|
||||||
HostPort: strconv.Itoa(exteriorPort),
|
|
||||||
HostIP: port.HostIP,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exposedPorts, portBindings
|
|
||||||
}
|
|
||||||
|
|
||||||
// A helper function to get the KubeletContainerName and hash from a docker
|
// A helper function to get the KubeletContainerName and hash from a docker
|
||||||
// container.
|
// container.
|
||||||
func getDockerContainerNameInfo(c *docker.APIContainers) (*KubeletContainerName, uint64, error) {
|
func getDockerContainerNameInfo(c *docker.APIContainers) (*KubeletContainerName, uint64, error) {
|
||||||
|
@ -696,18 +696,49 @@ func (kl *Kubelet) syncNodeStatus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBinds(container *api.Container, podVolumes kubecontainer.VolumeMap) (binds []string) {
|
func makeMounts(container *api.Container, podVolumes kubecontainer.VolumeMap) (mounts []kubecontainer.Mount) {
|
||||||
for _, mount := range container.VolumeMounts {
|
for _, mount := range container.VolumeMounts {
|
||||||
vol, ok := podVolumes[mount.Name]
|
vol, ok := podVolumes[mount.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
glog.Warningf("Mount cannot be satisified for container %q, because the volume is missing: %q", container.Name, mount)
|
glog.Warningf("Mount cannot be satisified for container %q, because the volume is missing: %q", container.Name, mount)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
b := fmt.Sprintf("%s:%s", vol.GetPath(), mount.MountPath)
|
mounts = append(mounts, kubecontainer.Mount{
|
||||||
if mount.ReadOnly {
|
Name: mount.Name,
|
||||||
b += ":ro"
|
ContainerPath: mount.MountPath,
|
||||||
|
HostPath: vol.GetPath(),
|
||||||
|
ReadOnly: mount.ReadOnly,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
binds = append(binds, b)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func makePortMappings(container *api.Container) (ports []kubecontainer.PortMapping) {
|
||||||
|
names := make(map[string]struct{})
|
||||||
|
for _, p := range container.Ports {
|
||||||
|
pm := kubecontainer.PortMapping{
|
||||||
|
HostPort: p.HostPort,
|
||||||
|
ContainerPort: p.ContainerPort,
|
||||||
|
Protocol: p.Protocol,
|
||||||
|
HostIP: p.HostIP,
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to create some default port name if it's not specified, since
|
||||||
|
// this is necessary for rkt.
|
||||||
|
// https://github.com/GoogleCloudPlatform/kubernetes/issues/7710
|
||||||
|
if p.Name == "" {
|
||||||
|
pm.Name = fmt.Sprintf("%s-%s:%d", container.Name, p.Protocol, p.ContainerPort)
|
||||||
|
} else {
|
||||||
|
pm.Name = fmt.Sprintf("%s-%s", container.Name, p.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protect against exposing the same protocol-port more than once in a container.
|
||||||
|
if _, ok := names[pm.Name]; ok {
|
||||||
|
glog.Warningf("Port name conflicted, %q is defined more than once", pm.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ports = append(ports, pm)
|
||||||
|
names[pm.Name] = struct{}{}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -722,7 +753,9 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *api.Pod, container *api.Cont
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("impossible: cannot find the mounted volumes for pod %q", kubecontainer.GetPodFullName(pod))
|
return nil, fmt.Errorf("impossible: cannot find the mounted volumes for pod %q", kubecontainer.GetPodFullName(pod))
|
||||||
}
|
}
|
||||||
opts.Binds = makeBinds(container, vol)
|
|
||||||
|
opts.PortMappings = makePortMappings(container)
|
||||||
|
opts.Mounts = makeMounts(container, vol)
|
||||||
opts.Envs, err = kl.makeEnvironmentVariables(pod, container)
|
opts.Envs, err = kl.makeEnvironmentVariables(pod, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -801,8 +834,8 @@ func (kl *Kubelet) getServiceEnvVarMap(ns string) (map[string]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make the service environment variables for a pod in the given namespace.
|
// Make the service environment variables for a pod in the given namespace.
|
||||||
func (kl *Kubelet) makeEnvironmentVariables(pod *api.Pod, container *api.Container) ([]string, error) {
|
func (kl *Kubelet) makeEnvironmentVariables(pod *api.Pod, container *api.Container) ([]kubecontainer.EnvVar, error) {
|
||||||
var result []string
|
var result []kubecontainer.EnvVar
|
||||||
// Note: These are added to the docker.Config, but are not included in the checksum computed
|
// Note: These are added to the docker.Config, but are not included in the checksum computed
|
||||||
// by dockertools.BuildDockerName(...). That way, we can still determine whether an
|
// by dockertools.BuildDockerName(...). That way, we can still determine whether an
|
||||||
// api.Container is already running by its hash. (We don't want to restart a container just
|
// api.Container is already running by its hash. (We don't want to restart a container just
|
||||||
@ -830,12 +863,12 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *api.Pod, container *api.Contain
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, fmt.Sprintf("%s=%s", value.Name, runtimeValue))
|
result = append(result, kubecontainer.EnvVar{Name: value.Name, Value: runtimeValue})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append remaining service env vars.
|
// Append remaining service env vars.
|
||||||
for k, v := range serviceEnv {
|
for k, v := range serviceEnv {
|
||||||
result = append(result, fmt.Sprintf("%s=%s", k, v))
|
result = append(result, kubecontainer.EnvVar{Name: k, Value: v})
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
@ -1308,7 +1308,7 @@ func (f *stubVolume) GetPath() string {
|
|||||||
return f.path
|
return f.path
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMakeVolumesAndBinds(t *testing.T) {
|
func TestMakeVolumeMounts(t *testing.T) {
|
||||||
container := api.Container{
|
container := api.Container{
|
||||||
VolumeMounts: []api.VolumeMount{
|
VolumeMounts: []api.VolumeMount{
|
||||||
{
|
{
|
||||||
@ -1340,19 +1340,37 @@ func TestMakeVolumesAndBinds(t *testing.T) {
|
|||||||
"disk5": &stubVolume{"/var/lib/kubelet/podID/volumes/empty/disk5"},
|
"disk5": &stubVolume{"/var/lib/kubelet/podID/volumes/empty/disk5"},
|
||||||
}
|
}
|
||||||
|
|
||||||
binds := makeBinds(&container, podVolumes)
|
mounts := makeMounts(&container, podVolumes)
|
||||||
|
|
||||||
expectedBinds := []string{
|
expectedMounts := []kubecontainer.Mount{
|
||||||
"/mnt/disk:/mnt/path",
|
{
|
||||||
"/mnt/disk:/mnt/path3:ro",
|
"disk",
|
||||||
"/mnt/host:/mnt/path4",
|
"/mnt/path",
|
||||||
"/var/lib/kubelet/podID/volumes/empty/disk5:/mnt/path5",
|
"/mnt/disk",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"disk",
|
||||||
|
"/mnt/path3",
|
||||||
|
"/mnt/disk",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"disk4",
|
||||||
|
"/mnt/path4",
|
||||||
|
"/mnt/host",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"disk5",
|
||||||
|
"/mnt/path5",
|
||||||
|
"/var/lib/kubelet/podID/volumes/empty/disk5",
|
||||||
|
false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
if !reflect.DeepEqual(mounts, expectedMounts) {
|
||||||
if len(binds) != len(expectedBinds) {
|
t.Errorf("Unexpected mounts: Expected %#v got %#v. Container was: %#v", expectedMounts, mounts, container)
|
||||||
t.Errorf("Unexpected binds: Expected %#v got %#v. Container was: %#v", expectedBinds, binds, container)
|
|
||||||
}
|
}
|
||||||
verifyStringArrayEquals(t, binds, expectedBinds)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetContainerInfo(t *testing.T) {
|
func TestGetContainerInfo(t *testing.T) {
|
||||||
@ -1884,6 +1902,16 @@ func (ls testNodeLister) List() (api.NodeList, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type envs []kubecontainer.EnvVar
|
||||||
|
|
||||||
|
func (e envs) Len() int {
|
||||||
|
return len(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e envs) Swap(i, j int) { e[i], e[j] = e[j], e[i] }
|
||||||
|
|
||||||
|
func (e envs) Less(i, j int) bool { return e[i].Name < e[j].Name }
|
||||||
|
|
||||||
func TestMakeEnvironmentVariables(t *testing.T) {
|
func TestMakeEnvironmentVariables(t *testing.T) {
|
||||||
services := []api.Service{
|
services := []api.Service{
|
||||||
{
|
{
|
||||||
@ -2033,7 +2061,7 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
container *api.Container // the container to use
|
container *api.Container // the container to use
|
||||||
masterServiceNs string // the namespace to read master service info from
|
masterServiceNs string // the namespace to read master service info from
|
||||||
nilLister bool // whether the lister should be nil
|
nilLister bool // whether the lister should be nil
|
||||||
expectedEnvs util.StringSet // a set of expected environment vars
|
expectedEnvs []kubecontainer.EnvVar // a set of expected environment vars
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "api server = Y, kubelet = Y",
|
name: "api server = Y, kubelet = Y",
|
||||||
@ -2052,29 +2080,30 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
},
|
},
|
||||||
masterServiceNs: api.NamespaceDefault,
|
masterServiceNs: api.NamespaceDefault,
|
||||||
nilLister: false,
|
nilLister: false,
|
||||||
expectedEnvs: util.NewStringSet(
|
expectedEnvs: []kubecontainer.EnvVar{
|
||||||
"FOO=BAR",
|
{Name: "FOO", Value: "BAR"},
|
||||||
"TEST_SERVICE_HOST=1.2.3.3",
|
{Name: "TEST_SERVICE_HOST", Value: "1.2.3.3"},
|
||||||
"TEST_SERVICE_PORT=8083",
|
{Name: "TEST_SERVICE_PORT", Value: "8083"},
|
||||||
"TEST_PORT=tcp://1.2.3.3:8083",
|
{Name: "TEST_PORT", Value: "tcp://1.2.3.3:8083"},
|
||||||
"TEST_PORT_8083_TCP=tcp://1.2.3.3:8083",
|
{Name: "TEST_PORT_8083_TCP", Value: "tcp://1.2.3.3:8083"},
|
||||||
"TEST_PORT_8083_TCP_PROTO=tcp",
|
{Name: "TEST_PORT_8083_TCP_PROTO", Value: "tcp"},
|
||||||
"TEST_PORT_8083_TCP_PORT=8083",
|
{Name: "TEST_PORT_8083_TCP_PORT", Value: "8083"},
|
||||||
"TEST_PORT_8083_TCP_ADDR=1.2.3.3",
|
{Name: "TEST_PORT_8083_TCP_ADDR", Value: "1.2.3.3"},
|
||||||
"KUBERNETES_SERVICE_HOST=1.2.3.1",
|
{Name: "KUBERNETES_SERVICE_PORT", Value: "8081"},
|
||||||
"KUBERNETES_SERVICE_PORT=8081",
|
{Name: "KUBERNETES_SERVICE_HOST", Value: "1.2.3.1"},
|
||||||
"KUBERNETES_PORT=tcp://1.2.3.1:8081",
|
{Name: "KUBERNETES_PORT", Value: "tcp://1.2.3.1:8081"},
|
||||||
"KUBERNETES_PORT_8081_TCP=tcp://1.2.3.1:8081",
|
{Name: "KUBERNETES_PORT_8081_TCP", Value: "tcp://1.2.3.1:8081"},
|
||||||
"KUBERNETES_PORT_8081_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_PORT_8081_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_PORT_8081_TCP_PORT=8081",
|
{Name: "KUBERNETES_PORT_8081_TCP_PORT", Value: "8081"},
|
||||||
"KUBERNETES_PORT_8081_TCP_ADDR=1.2.3.1",
|
{Name: "KUBERNETES_PORT_8081_TCP_ADDR", Value: "1.2.3.1"},
|
||||||
"KUBERNETES_RO_SERVICE_HOST=1.2.3.2",
|
{Name: "KUBERNETES_RO_SERVICE_HOST", Value: "1.2.3.2"},
|
||||||
"KUBERNETES_RO_SERVICE_PORT=8082",
|
{Name: "KUBERNETES_RO_SERVICE_PORT", Value: "8082"},
|
||||||
"KUBERNETES_RO_PORT=tcp://1.2.3.2:8082",
|
{Name: "KUBERNETES_RO_PORT", Value: "tcp://1.2.3.2:8082"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP=tcp://1.2.3.2:8082",
|
{Name: "KUBERNETES_RO_PORT_8082_TCP", Value: "tcp://1.2.3.2:8082"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_RO_PORT_8082_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP_PORT=8082",
|
{Name: "KUBERNETES_RO_PORT_8082_TCP_PORT", Value: "8082"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP_ADDR=1.2.3.2"),
|
{Name: "KUBERNETES_RO_PORT_8082_TCP_ADDR", Value: "1.2.3.2"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "api server = Y, kubelet = N",
|
name: "api server = Y, kubelet = N",
|
||||||
@ -2093,15 +2122,16 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
},
|
},
|
||||||
masterServiceNs: api.NamespaceDefault,
|
masterServiceNs: api.NamespaceDefault,
|
||||||
nilLister: true,
|
nilLister: true,
|
||||||
expectedEnvs: util.NewStringSet(
|
expectedEnvs: []kubecontainer.EnvVar{
|
||||||
"FOO=BAR",
|
{Name: "FOO", Value: "BAR"},
|
||||||
"TEST_SERVICE_HOST=1.2.3.3",
|
{Name: "TEST_SERVICE_HOST", Value: "1.2.3.3"},
|
||||||
"TEST_SERVICE_PORT=8083",
|
{Name: "TEST_SERVICE_PORT", Value: "8083"},
|
||||||
"TEST_PORT=tcp://1.2.3.3:8083",
|
{Name: "TEST_PORT", Value: "tcp://1.2.3.3:8083"},
|
||||||
"TEST_PORT_8083_TCP=tcp://1.2.3.3:8083",
|
{Name: "TEST_PORT_8083_TCP", Value: "tcp://1.2.3.3:8083"},
|
||||||
"TEST_PORT_8083_TCP_PROTO=tcp",
|
{Name: "TEST_PORT_8083_TCP_PROTO", Value: "tcp"},
|
||||||
"TEST_PORT_8083_TCP_PORT=8083",
|
{Name: "TEST_PORT_8083_TCP_PORT", Value: "8083"},
|
||||||
"TEST_PORT_8083_TCP_ADDR=1.2.3.3"),
|
{Name: "TEST_PORT_8083_TCP_ADDR", Value: "1.2.3.3"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "api server = N; kubelet = Y",
|
name: "api server = N; kubelet = Y",
|
||||||
@ -2113,29 +2143,30 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
},
|
},
|
||||||
masterServiceNs: api.NamespaceDefault,
|
masterServiceNs: api.NamespaceDefault,
|
||||||
nilLister: false,
|
nilLister: false,
|
||||||
expectedEnvs: util.NewStringSet(
|
expectedEnvs: []kubecontainer.EnvVar{
|
||||||
"FOO=BAZ",
|
{Name: "FOO", Value: "BAZ"},
|
||||||
"TEST_SERVICE_HOST=1.2.3.3",
|
{Name: "TEST_SERVICE_HOST", Value: "1.2.3.3"},
|
||||||
"TEST_SERVICE_PORT=8083",
|
{Name: "TEST_SERVICE_PORT", Value: "8083"},
|
||||||
"TEST_PORT=tcp://1.2.3.3:8083",
|
{Name: "TEST_PORT", Value: "tcp://1.2.3.3:8083"},
|
||||||
"TEST_PORT_8083_TCP=tcp://1.2.3.3:8083",
|
{Name: "TEST_PORT_8083_TCP", Value: "tcp://1.2.3.3:8083"},
|
||||||
"TEST_PORT_8083_TCP_PROTO=tcp",
|
{Name: "TEST_PORT_8083_TCP_PROTO", Value: "tcp"},
|
||||||
"TEST_PORT_8083_TCP_PORT=8083",
|
{Name: "TEST_PORT_8083_TCP_PORT", Value: "8083"},
|
||||||
"TEST_PORT_8083_TCP_ADDR=1.2.3.3",
|
{Name: "TEST_PORT_8083_TCP_ADDR", Value: "1.2.3.3"},
|
||||||
"KUBERNETES_SERVICE_HOST=1.2.3.1",
|
{Name: "KUBERNETES_SERVICE_HOST", Value: "1.2.3.1"},
|
||||||
"KUBERNETES_SERVICE_PORT=8081",
|
{Name: "KUBERNETES_SERVICE_PORT", Value: "8081"},
|
||||||
"KUBERNETES_PORT=tcp://1.2.3.1:8081",
|
{Name: "KUBERNETES_PORT", Value: "tcp://1.2.3.1:8081"},
|
||||||
"KUBERNETES_PORT_8081_TCP=tcp://1.2.3.1:8081",
|
{Name: "KUBERNETES_PORT_8081_TCP", Value: "tcp://1.2.3.1:8081"},
|
||||||
"KUBERNETES_PORT_8081_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_PORT_8081_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_PORT_8081_TCP_PORT=8081",
|
{Name: "KUBERNETES_PORT_8081_TCP_PORT", Value: "8081"},
|
||||||
"KUBERNETES_PORT_8081_TCP_ADDR=1.2.3.1",
|
{Name: "KUBERNETES_PORT_8081_TCP_ADDR", Value: "1.2.3.1"},
|
||||||
"KUBERNETES_RO_SERVICE_HOST=1.2.3.2",
|
{Name: "KUBERNETES_RO_SERVICE_HOST", Value: "1.2.3.2"},
|
||||||
"KUBERNETES_RO_SERVICE_PORT=8082",
|
{Name: "KUBERNETES_RO_SERVICE_PORT", Value: "8082"},
|
||||||
"KUBERNETES_RO_PORT=tcp://1.2.3.2:8082",
|
{Name: "KUBERNETES_RO_PORT", Value: "tcp://1.2.3.2:8082"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP=tcp://1.2.3.2:8082",
|
{Name: "KUBERNETES_RO_PORT_8082_TCP", Value: "tcp://1.2.3.2:8082"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_RO_PORT_8082_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP_PORT=8082",
|
{Name: "KUBERNETES_RO_PORT_8082_TCP_PORT", Value: "8082"},
|
||||||
"KUBERNETES_RO_PORT_8082_TCP_ADDR=1.2.3.2"),
|
{Name: "KUBERNETES_RO_PORT_8082_TCP_ADDR", Value: "1.2.3.2"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "master service in pod ns",
|
name: "master service in pod ns",
|
||||||
@ -2147,29 +2178,30 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
},
|
},
|
||||||
masterServiceNs: "kubernetes",
|
masterServiceNs: "kubernetes",
|
||||||
nilLister: false,
|
nilLister: false,
|
||||||
expectedEnvs: util.NewStringSet(
|
expectedEnvs: []kubecontainer.EnvVar{
|
||||||
"FOO=ZAP",
|
{Name: "FOO", Value: "ZAP"},
|
||||||
"TEST_SERVICE_HOST=1.2.3.5",
|
{Name: "TEST_SERVICE_HOST", Value: "1.2.3.5"},
|
||||||
"TEST_SERVICE_PORT=8085",
|
{Name: "TEST_SERVICE_PORT", Value: "8085"},
|
||||||
"TEST_PORT=tcp://1.2.3.5:8085",
|
{Name: "TEST_PORT", Value: "tcp://1.2.3.5:8085"},
|
||||||
"TEST_PORT_8085_TCP=tcp://1.2.3.5:8085",
|
{Name: "TEST_PORT_8085_TCP", Value: "tcp://1.2.3.5:8085"},
|
||||||
"TEST_PORT_8085_TCP_PROTO=tcp",
|
{Name: "TEST_PORT_8085_TCP_PROTO", Value: "tcp"},
|
||||||
"TEST_PORT_8085_TCP_PORT=8085",
|
{Name: "TEST_PORT_8085_TCP_PORT", Value: "8085"},
|
||||||
"TEST_PORT_8085_TCP_ADDR=1.2.3.5",
|
{Name: "TEST_PORT_8085_TCP_ADDR", Value: "1.2.3.5"},
|
||||||
"KUBERNETES_SERVICE_HOST=1.2.3.4",
|
{Name: "KUBERNETES_SERVICE_HOST", Value: "1.2.3.4"},
|
||||||
"KUBERNETES_SERVICE_PORT=8084",
|
{Name: "KUBERNETES_SERVICE_PORT", Value: "8084"},
|
||||||
"KUBERNETES_PORT=tcp://1.2.3.4:8084",
|
{Name: "KUBERNETES_PORT", Value: "tcp://1.2.3.4:8084"},
|
||||||
"KUBERNETES_PORT_8084_TCP=tcp://1.2.3.4:8084",
|
{Name: "KUBERNETES_PORT_8084_TCP", Value: "tcp://1.2.3.4:8084"},
|
||||||
"KUBERNETES_PORT_8084_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_PORT_8084_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_PORT_8084_TCP_PORT=8084",
|
{Name: "KUBERNETES_PORT_8084_TCP_PORT", Value: "8084"},
|
||||||
"KUBERNETES_PORT_8084_TCP_ADDR=1.2.3.4",
|
{Name: "KUBERNETES_PORT_8084_TCP_ADDR", Value: "1.2.3.4"},
|
||||||
"KUBERNETES_RO_SERVICE_HOST=1.2.3.7",
|
{Name: "KUBERNETES_RO_SERVICE_HOST", Value: "1.2.3.7"},
|
||||||
"KUBERNETES_RO_SERVICE_PORT=8087",
|
{Name: "KUBERNETES_RO_SERVICE_PORT", Value: "8087"},
|
||||||
"KUBERNETES_RO_PORT=tcp://1.2.3.7:8087",
|
{Name: "KUBERNETES_RO_PORT", Value: "tcp://1.2.3.7:8087"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP=tcp://1.2.3.7:8087",
|
{Name: "KUBERNETES_RO_PORT_8087_TCP", Value: "tcp://1.2.3.7:8087"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_RO_PORT_8087_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP_PORT=8087",
|
{Name: "KUBERNETES_RO_PORT_8087_TCP_PORT", Value: "8087"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP_ADDR=1.2.3.7"),
|
{Name: "KUBERNETES_RO_PORT_8087_TCP_ADDR", Value: "1.2.3.7"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod in master service ns",
|
name: "pod in master service ns",
|
||||||
@ -2177,28 +2209,29 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
container: &api.Container{},
|
container: &api.Container{},
|
||||||
masterServiceNs: "kubernetes",
|
masterServiceNs: "kubernetes",
|
||||||
nilLister: false,
|
nilLister: false,
|
||||||
expectedEnvs: util.NewStringSet(
|
expectedEnvs: []kubecontainer.EnvVar{
|
||||||
"NOT_SPECIAL_SERVICE_HOST=1.2.3.8",
|
{Name: "NOT_SPECIAL_SERVICE_HOST", Value: "1.2.3.8"},
|
||||||
"NOT_SPECIAL_SERVICE_PORT=8088",
|
{Name: "NOT_SPECIAL_SERVICE_PORT", Value: "8088"},
|
||||||
"NOT_SPECIAL_PORT=tcp://1.2.3.8:8088",
|
{Name: "NOT_SPECIAL_PORT", Value: "tcp://1.2.3.8:8088"},
|
||||||
"NOT_SPECIAL_PORT_8088_TCP=tcp://1.2.3.8:8088",
|
{Name: "NOT_SPECIAL_PORT_8088_TCP", Value: "tcp://1.2.3.8:8088"},
|
||||||
"NOT_SPECIAL_PORT_8088_TCP_PROTO=tcp",
|
{Name: "NOT_SPECIAL_PORT_8088_TCP_PROTO", Value: "tcp"},
|
||||||
"NOT_SPECIAL_PORT_8088_TCP_PORT=8088",
|
{Name: "NOT_SPECIAL_PORT_8088_TCP_PORT", Value: "8088"},
|
||||||
"NOT_SPECIAL_PORT_8088_TCP_ADDR=1.2.3.8",
|
{Name: "NOT_SPECIAL_PORT_8088_TCP_ADDR", Value: "1.2.3.8"},
|
||||||
"KUBERNETES_SERVICE_HOST=1.2.3.6",
|
{Name: "KUBERNETES_SERVICE_HOST", Value: "1.2.3.6"},
|
||||||
"KUBERNETES_SERVICE_PORT=8086",
|
{Name: "KUBERNETES_SERVICE_PORT", Value: "8086"},
|
||||||
"KUBERNETES_PORT=tcp://1.2.3.6:8086",
|
{Name: "KUBERNETES_PORT", Value: "tcp://1.2.3.6:8086"},
|
||||||
"KUBERNETES_PORT_8086_TCP=tcp://1.2.3.6:8086",
|
{Name: "KUBERNETES_PORT_8086_TCP", Value: "tcp://1.2.3.6:8086"},
|
||||||
"KUBERNETES_PORT_8086_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_PORT_8086_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_PORT_8086_TCP_PORT=8086",
|
{Name: "KUBERNETES_PORT_8086_TCP_PORT", Value: "8086"},
|
||||||
"KUBERNETES_PORT_8086_TCP_ADDR=1.2.3.6",
|
{Name: "KUBERNETES_PORT_8086_TCP_ADDR", Value: "1.2.3.6"},
|
||||||
"KUBERNETES_RO_SERVICE_HOST=1.2.3.7",
|
{Name: "KUBERNETES_RO_SERVICE_HOST", Value: "1.2.3.7"},
|
||||||
"KUBERNETES_RO_SERVICE_PORT=8087",
|
{Name: "KUBERNETES_RO_SERVICE_PORT", Value: "8087"},
|
||||||
"KUBERNETES_RO_PORT=tcp://1.2.3.7:8087",
|
{Name: "KUBERNETES_RO_PORT", Value: "tcp://1.2.3.7:8087"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP=tcp://1.2.3.7:8087",
|
{Name: "KUBERNETES_RO_PORT_8087_TCP", Value: "tcp://1.2.3.7:8087"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP_PROTO=tcp",
|
{Name: "KUBERNETES_RO_PORT_8087_TCP_PROTO", Value: "tcp"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP_PORT=8087",
|
{Name: "KUBERNETES_RO_PORT_8087_TCP_PORT", Value: "8087"},
|
||||||
"KUBERNETES_RO_PORT_8087_TCP_ADDR=1.2.3.7"),
|
{Name: "KUBERNETES_RO_PORT_8087_TCP_ADDR", Value: "1.2.3.7"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "downward api pod",
|
name: "downward api pod",
|
||||||
@ -2227,14 +2260,14 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
},
|
},
|
||||||
masterServiceNs: "nothing",
|
masterServiceNs: "nothing",
|
||||||
nilLister: true,
|
nilLister: true,
|
||||||
expectedEnvs: util.NewStringSet(
|
expectedEnvs: []kubecontainer.EnvVar{
|
||||||
"POD_NAME=dapi-test-pod-name",
|
{Name: "POD_NAME", Value: "dapi-test-pod-name"},
|
||||||
"POD_NAMESPACE=downward-api",
|
{Name: "POD_NAMESPACE", Value: "downward-api"},
|
||||||
),
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for i, tc := range testCases {
|
||||||
testKubelet := newTestKubelet(t)
|
testKubelet := newTestKubelet(t)
|
||||||
kl := testKubelet.kubelet
|
kl := testKubelet.kubelet
|
||||||
kl.masterServiceNamespace = tc.masterServiceNs
|
kl.masterServiceNamespace = tc.masterServiceNs
|
||||||
@ -2256,14 +2289,11 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
t.Errorf("[%v] Unexpected error: %v", tc.name, err)
|
t.Errorf("[%v] Unexpected error: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resultSet := util.NewStringSet(result...)
|
sort.Sort(envs(result))
|
||||||
if !resultSet.HasAll(tc.expectedEnvs.List()...) {
|
sort.Sort(envs(tc.expectedEnvs))
|
||||||
|
|
||||||
t.Errorf("[%v] Unexpected env entries; expected {%v}, got {%v}", tc.name, tc.expectedEnvs, resultSet)
|
if !reflect.DeepEqual(result, tc.expectedEnvs) {
|
||||||
}
|
t.Errorf("%d: [%v] Unexpected env entries; expected {%v}, got {%v}", i, tc.name, tc.expectedEnvs, result)
|
||||||
|
|
||||||
if a, e := len(resultSet), len(tc.expectedEnvs); e != a {
|
|
||||||
t.Errorf("[%v] Unexpected number of env vars; expected %v, got %v", tc.name, e, a)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4397,3 +4427,77 @@ func TestFilterOutTerminatedPods(t *testing.T) {
|
|||||||
t.Errorf("expected %#v, got %#v", expected, actual)
|
t.Errorf("expected %#v, got %#v", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMakePortMappings(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
container *api.Container
|
||||||
|
expectedPortMappings []kubecontainer.PortMapping
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
&api.Container{
|
||||||
|
Name: "fooContainer",
|
||||||
|
Ports: []api.ContainerPort{
|
||||||
|
{
|
||||||
|
Protocol: api.ProtocolTCP,
|
||||||
|
ContainerPort: 80,
|
||||||
|
HostPort: 8080,
|
||||||
|
HostIP: "127.0.0.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Protocol: api.ProtocolTCP,
|
||||||
|
ContainerPort: 443,
|
||||||
|
HostPort: 4343,
|
||||||
|
HostIP: "192.168.0.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "foo",
|
||||||
|
Protocol: api.ProtocolUDP,
|
||||||
|
ContainerPort: 555,
|
||||||
|
HostPort: 5555,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "foo", // Duplicated, should be ignored.
|
||||||
|
Protocol: api.ProtocolUDP,
|
||||||
|
ContainerPort: 888,
|
||||||
|
HostPort: 8888,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Protocol: api.ProtocolTCP, // Duplicated, should be ignored.
|
||||||
|
ContainerPort: 80,
|
||||||
|
HostPort: 8888,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[]kubecontainer.PortMapping{
|
||||||
|
{
|
||||||
|
Name: "fooContainer-TCP:80",
|
||||||
|
Protocol: api.ProtocolTCP,
|
||||||
|
ContainerPort: 80,
|
||||||
|
HostPort: 8080,
|
||||||
|
HostIP: "127.0.0.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "fooContainer-TCP:443",
|
||||||
|
Protocol: api.ProtocolTCP,
|
||||||
|
ContainerPort: 443,
|
||||||
|
HostPort: 4343,
|
||||||
|
HostIP: "192.168.0.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "fooContainer-foo",
|
||||||
|
Protocol: api.ProtocolUDP,
|
||||||
|
ContainerPort: 555,
|
||||||
|
HostPort: 5555,
|
||||||
|
HostIP: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
actual := makePortMappings(tt.container)
|
||||||
|
if !reflect.DeepEqual(tt.expectedPortMappings, actual) {
|
||||||
|
t.Errorf("%d: Expected: %#v, saw: %#v", i, tt.expectedPortMappings, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user