func buildContainers(userContainers []interface{}) []api.Container { if len(userContainers) == 0 { return nil } var containers []api.Container for _, c := range userContainers { userContainer := c.(map[string]interface{}) container := api.Container{ Image: userContainer["image"].(string), Name: userContainer["name"].(string), } if _, ok := userContainer["args"]; ok { container.Args = convertListToStringArray(userContainer["args"].([]interface{})) } if _, ok := userContainer["command"]; ok { container.Command = convertListToStringArray(userContainer["command"].([]interface{})) } if _, ok := userContainer["working_dir"]; ok { container.WorkingDir = userContainer["working_dir"].(string) } if _, ok := userContainer["ports"]; ok { container.Ports = buildContainerPorts(userContainer["ports"].([]interface{})) } if _, ok := userContainer["env"]; ok { container.Env = buildEnvVar(userContainer["env"].([]interface{})) } containers = append(containers, container) } return containers }
func Containers(userContainers []interface{}) []api.Container { if len(userContainers) == 0 { return nil } var containers []api.Container for _, c := range userContainers { userContainer := c.(map[string]interface{}) container := api.Container{ Image: userContainer["image"].(string), Name: userContainer["name"].(string), } if _, ok := userContainer["args"]; ok { container.Args = convertListToStringArray(userContainer["args"].([]interface{})) } if _, ok := userContainer["command"]; ok { container.Command = convertListToStringArray(userContainer["command"].([]interface{})) } if _, ok := userContainer["working_dir"]; ok { container.WorkingDir = userContainer["working_dir"].(string) } if _, ok := userContainer["ports"]; ok { container.Ports = ContainerPorts(userContainer["ports"].([]interface{})) } if _, ok := userContainer["env"]; ok { container.Env = EnvVar(userContainer["env"].([]interface{})) } if _, ok := userContainer["volume_mounts"]; ok { container.VolumeMounts = VolumeMounts(userContainer["volume_mounts"].([]interface{})) } if _, ok := userContainer["termination_message_path"]; ok { container.TerminationMessagePath = userContainer["termination_message_path"].(string) } if _, ok := userContainer["image_pull_policy"]; ok { container.ImagePullPolicy = api.PullPolicy(userContainer["image_pull_policy"].(string)) } // TODO: populate these fields: // resources // liveness_probe // readiness_probe // lifecycle // security_context containers = append(containers, container) } return containers }
func convert_v1beta3_Container_To_api_Container(in *Container, out *api.Container, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Container))(in) } out.Name = in.Name out.Image = in.Image if in.Command != nil { out.Command = make([]string, len(in.Command)) for i := range in.Command { out.Command[i] = in.Command[i] } } if in.Args != nil { out.Args = make([]string, len(in.Args)) for i := range in.Args { out.Args[i] = in.Args[i] } } out.WorkingDir = in.WorkingDir if in.Ports != nil { out.Ports = make([]api.ContainerPort, len(in.Ports)) for i := range in.Ports { if err := convert_v1beta3_ContainerPort_To_api_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { return err } } } if in.Env != nil { out.Env = make([]api.EnvVar, len(in.Env)) for i := range in.Env { if err := convert_v1beta3_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { return err } } } if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { return err } if in.VolumeMounts != nil { out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) for i := range in.VolumeMounts { if err := convert_v1beta3_VolumeMount_To_api_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { return err } } } if in.LivenessProbe != nil { out.LivenessProbe = new(api.Probe) if err := convert_v1beta3_Probe_To_api_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { return err } } else { out.LivenessProbe = nil } if in.ReadinessProbe != nil { out.ReadinessProbe = new(api.Probe) if err := convert_v1beta3_Probe_To_api_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { return err } } else { out.ReadinessProbe = nil } if in.Lifecycle != nil { out.Lifecycle = new(api.Lifecycle) if err := convert_v1beta3_Lifecycle_To_api_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { return err } } else { out.Lifecycle = nil } out.TerminationMessagePath = in.TerminationMessagePath out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) if in.SecurityContext != nil { if in.SecurityContext.Capabilities != nil { if !reflect.DeepEqual(in.SecurityContext.Capabilities.Add, in.Capabilities.Add) || !reflect.DeepEqual(in.SecurityContext.Capabilities.Drop, in.Capabilities.Drop) { return fmt.Errorf("container capability settings do not match security context settings, cannot convert") } } if in.SecurityContext.Privileged != nil { if in.Privileged != *in.SecurityContext.Privileged { return fmt.Errorf("container privileged settings do not match security context settings, cannot convert") } } } if in.SecurityContext != nil { out.SecurityContext = new(api.SecurityContext) if err := convert_v1beta3_SecurityContext_To_api_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { return err } } else { out.SecurityContext = nil } out.Stdin = in.Stdin out.TTY = in.TTY return nil }
testCount := int32(3) testStatuses := []testStatus{ {"terminate-cmd-rpa", api.RestartPolicyAlways, api.PodRunning, ContainerStateWaiting | ContainerStateRunning | ContainerStateTerminated, ">", testCount, false}, {"terminate-cmd-rpof", api.RestartPolicyOnFailure, api.PodSucceeded, ContainerStateTerminated, "==", testCount, false}, {"terminate-cmd-rpn", api.RestartPolicyNever, api.PodSucceeded, ContainerStateTerminated, "==", 0, false}, } for _, testStatus := range testStatuses { tmpFile, err := ioutil.TempFile("", "restartCount") Expect(err).NotTo(HaveOccurred()) defer os.Remove(tmpFile.Name()) // It fails in the first three runs and succeeds after that. tmpCmd := fmt.Sprintf("echo 'hello' >> /restart-count/%s ; test $(wc -l /restart-count/%s| awk {'print $1'}) -ge %d", path.Base(tmpFile.Name()), path.Base(tmpFile.Name()), testCount+1) testContainer.Name = testStatus.Name testContainer.Command = []string{"sh", "-c", tmpCmd} terminateContainer := ConformanceContainer{ Container: testContainer, Client: cl, RestartPolicy: testStatus.RestartPolicy, Volumes: testVolumes, NodeName: *nodeName, Namespace: namespace, } err = terminateContainer.Create() Expect(err).NotTo(HaveOccurred()) testCContainers = append(testCContainers, terminateContainer) Eventually(func() api.PodPhase { _, phase, _ := terminateContainer.GetStatus() return phase
func deepCopy_api_Container(in api.Container, out *api.Container, c *conversion.Cloner) error { out.Name = in.Name out.Image = in.Image if in.Command != nil { out.Command = make([]string, len(in.Command)) for i := range in.Command { out.Command[i] = in.Command[i] } } else { out.Command = nil } if in.Args != nil { out.Args = make([]string, len(in.Args)) for i := range in.Args { out.Args[i] = in.Args[i] } } else { out.Args = nil } out.WorkingDir = in.WorkingDir if in.Ports != nil { out.Ports = make([]api.ContainerPort, len(in.Ports)) for i := range in.Ports { if err := deepCopy_api_ContainerPort(in.Ports[i], &out.Ports[i], c); err != nil { return err } } } else { out.Ports = nil } if in.Env != nil { out.Env = make([]api.EnvVar, len(in.Env)) for i := range in.Env { if err := deepCopy_api_EnvVar(in.Env[i], &out.Env[i], c); err != nil { return err } } } else { out.Env = nil } if err := deepCopy_api_ResourceRequirements(in.Resources, &out.Resources, c); err != nil { return err } if in.VolumeMounts != nil { out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) for i := range in.VolumeMounts { if err := deepCopy_api_VolumeMount(in.VolumeMounts[i], &out.VolumeMounts[i], c); err != nil { return err } } } else { out.VolumeMounts = nil } if in.LivenessProbe != nil { out.LivenessProbe = new(api.Probe) if err := deepCopy_api_Probe(*in.LivenessProbe, out.LivenessProbe, c); err != nil { return err } } else { out.LivenessProbe = nil } if in.ReadinessProbe != nil { out.ReadinessProbe = new(api.Probe) if err := deepCopy_api_Probe(*in.ReadinessProbe, out.ReadinessProbe, c); err != nil { return err } } else { out.ReadinessProbe = nil } if in.Lifecycle != nil { out.Lifecycle = new(api.Lifecycle) if err := deepCopy_api_Lifecycle(*in.Lifecycle, out.Lifecycle, c); err != nil { return err } } else { out.Lifecycle = nil } out.TerminationMessagePath = in.TerminationMessagePath out.ImagePullPolicy = in.ImagePullPolicy if in.SecurityContext != nil { out.SecurityContext = new(api.SecurityContext) if err := deepCopy_api_SecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { return err } } else { out.SecurityContext = nil } out.Stdin = in.Stdin out.TTY = in.TTY return nil }
// Deploys an app based on the given configuration. The app is deployed using the given client. // App deployment consists of a replication controller and an optional service. Both of them share // common labels. func DeployApp(spec *AppDeploymentSpec, client client.Interface) error { log.Printf("Deploying %s application into %s namespace", spec.Name, spec.Namespace) annotations := map[string]string{} if spec.Description != nil { annotations[DescriptionAnnotationKey] = *spec.Description } labels := getLabelsMap(spec.Labels) objectMeta := api.ObjectMeta{ Annotations: annotations, Name: spec.Name, Labels: labels, } containerSpec := api.Container{ Name: spec.Name, Image: spec.ContainerImage, SecurityContext: &api.SecurityContext{ Privileged: &spec.RunAsPrivileged, }, Resources: api.ResourceRequirements{ Requests: make(map[api.ResourceName]resource.Quantity), }, Env: convertEnvVarsSpec(spec.Variables), } if spec.ContainerCommand != nil { containerSpec.Command = []string{*spec.ContainerCommand} } if spec.ContainerCommandArgs != nil { containerSpec.Args = []string{*spec.ContainerCommandArgs} } if spec.CpuRequirement != nil { containerSpec.Resources.Requests[api.ResourceCPU] = *spec.CpuRequirement } if spec.MemoryRequirement != nil { containerSpec.Resources.Requests[api.ResourceMemory] = *spec.MemoryRequirement } podSpec := api.PodSpec{ Containers: []api.Container{containerSpec}, } if spec.ImagePullSecret != nil { podSpec.ImagePullSecrets = []api.LocalObjectReference{{Name: *spec.ImagePullSecret}} } podTemplate := &api.PodTemplateSpec{ ObjectMeta: objectMeta, Spec: podSpec, } replicationController := &api.ReplicationController{ ObjectMeta: objectMeta, Spec: api.ReplicationControllerSpec{ Replicas: spec.Replicas, Selector: labels, Template: podTemplate, }, } _, err := client.ReplicationControllers(spec.Namespace).Create(replicationController) if err != nil { // TODO(bryk): Roll back created resources in case of error. return err } if len(spec.PortMappings) > 0 { service := &api.Service{ ObjectMeta: objectMeta, Spec: api.ServiceSpec{ Selector: labels, }, } if spec.IsExternal { service.Spec.Type = api.ServiceTypeLoadBalancer } else { service.Spec.Type = api.ServiceTypeClusterIP } for _, portMapping := range spec.PortMappings { servicePort := api.ServicePort{ Protocol: portMapping.Protocol, Port: portMapping.Port, Name: generatePortMappingName(portMapping), TargetPort: intstr.IntOrString{ Type: intstr.Int, IntVal: portMapping.TargetPort, }, } service.Spec.Ports = append(service.Spec.Ports, servicePort) } _, err = client.Services(spec.Namespace).Create(service) // TODO(bryk): Roll back created resources in case of error. return err } else { return nil } }
func writePodContainer(m map[string]interface{}, item *api.Container) error { if x, ok := m["name"].(string); ok { item.Name = x } if x, ok := m["image"].(string); ok { item.Image = x } if x, ok := m["image_pull_policy"].(string); ok { item.ImagePullPolicy = api.PullPolicy(x) } if x, ok := m["termination_message_path"].(string); ok { item.TerminationMessagePath = x } if x, ok := m["working_dir"].(string); ok { item.WorkingDir = x } if x, ok := m["command"].([]interface{}); ok { for _, y := range x { item.Command = append(item.Command, y.(string)) } } if x, ok := m["args"].([]interface{}); ok { for _, y := range x { item.Args = append(item.Args, y.(string)) } } if x, ok := m["port"].([]interface{}); ok { for _, y := range x { ref := api.ContainerPort{} writeContainerPort(y.(map[string]interface{}), &ref) item.Ports = append(item.Ports, ref) } } if x, ok := m["env"].([]interface{}); ok { for _, y := range x { ref := api.EnvVar{} writeEnvVar(y.(map[string]interface{}), &ref) item.Env = append(item.Env, ref) } } if x, ok := m["volume_mount"].([]interface{}); ok { for _, y := range x { ref := api.VolumeMount{} writeVolumeMount(y.(map[string]interface{}), &ref) item.VolumeMounts = append(item.VolumeMounts, ref) } } if n, ok := extractSingleMap(m["liveness_probe"]); ok { item.LivenessProbe = &api.Probe{} writeProbe(n, item.LivenessProbe) } if n, ok := extractSingleMap(m["readiness_probe"]); ok { item.ReadinessProbe = &api.Probe{} writeProbe(n, item.ReadinessProbe) } if n, ok := extractSingleMap(m["resources"]); ok { if o, ok := extractSingleMap(n["limits"]); ok { item.Resources.Limits = make(api.ResourceList) if x, ok := o["cpu"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Limits[api.ResourceCPU] = *q } if x, ok := o["memory"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Limits[api.ResourceMemory] = *q } } if o, ok := extractSingleMap(n["requests"]); ok { item.Resources.Requests = make(api.ResourceList) if x, ok := o["cpu"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Requests[api.ResourceCPU] = *q } if x, ok := o["memory"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Requests[api.ResourceMemory] = *q } } } return nil }
// Deploys an app based on the given configuration. The app is deployed using the given client. // App deployment consists of a replication controller and an optional service. Both of them share // common labels. // TODO(bryk): Write tests for this function. func DeployApp(spec *AppDeploymentSpec, client client.Interface) error { annotations := map[string]string{} if spec.Description != nil { annotations[DescriptionAnnotationKey] = *spec.Description } labels := getLabelsMap(spec.Labels) objectMeta := api.ObjectMeta{ Annotations: annotations, Name: spec.Name, Labels: labels, } containerSpec := api.Container{ Name: spec.Name, Image: spec.ContainerImage, SecurityContext: &api.SecurityContext{ Privileged: &spec.RunAsPrivileged, }, } if spec.ContainerCommand != nil { containerSpec.Command = []string{*spec.ContainerCommand} } if spec.ContainerCommandArgs != nil { containerSpec.Args = []string{*spec.ContainerCommandArgs} } podTemplate := &api.PodTemplateSpec{ ObjectMeta: objectMeta, Spec: api.PodSpec{ Containers: []api.Container{containerSpec}, }, } replicaSet := &api.ReplicationController{ ObjectMeta: objectMeta, Spec: api.ReplicationControllerSpec{ Replicas: spec.Replicas, Selector: labels, Template: podTemplate, }, } _, err := client.ReplicationControllers(spec.Namespace).Create(replicaSet) if err != nil { // TODO(bryk): Roll back created resources in case of error. return err } if len(spec.PortMappings) > 0 { service := &api.Service{ ObjectMeta: objectMeta, Spec: api.ServiceSpec{ Selector: labels, }, } if spec.IsExternal { service.Spec.Type = api.ServiceTypeLoadBalancer } else { service.Spec.Type = api.ServiceTypeNodePort } for _, portMapping := range spec.PortMappings { servicePort := api.ServicePort{ Protocol: portMapping.Protocol, Port: portMapping.Port, TargetPort: intstr.IntOrString{ Type: intstr.Int, IntVal: portMapping.TargetPort, }, } service.Spec.Ports = append(service.Spec.Ports, servicePort) } _, err = client.Services(spec.Namespace).Create(service) // TODO(bryk): Roll back created resources in case of error. return err } else { return nil } }