mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #7543 from yifan-gu/pod_manifest
kubelet/rkt: Add routines for converting kubelet pod to rkt pod.
This commit is contained in:
		
							
								
								
									
										128
									
								
								pkg/kubelet/rkt/cap.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								pkg/kubelet/rkt/cap.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2015 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package rkt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO(yifan): Export this to higher level package.
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						CAP_CHOWN = iota
 | 
				
			||||||
 | 
						CAP_DAC_OVERRIDE
 | 
				
			||||||
 | 
						CAP_DAC_READ_SEARCH
 | 
				
			||||||
 | 
						CAP_FOWNER
 | 
				
			||||||
 | 
						CAP_FSETID
 | 
				
			||||||
 | 
						CAP_KILL
 | 
				
			||||||
 | 
						CAP_SETGID
 | 
				
			||||||
 | 
						CAP_SETUID
 | 
				
			||||||
 | 
						CAP_SETPCAP
 | 
				
			||||||
 | 
						CAP_LINUX_IMMUTABLE
 | 
				
			||||||
 | 
						CAP_NET_BIND_SERVICE
 | 
				
			||||||
 | 
						CAP_NET_BROADCAST
 | 
				
			||||||
 | 
						CAP_NET_ADMIN
 | 
				
			||||||
 | 
						CAP_NET_RAW
 | 
				
			||||||
 | 
						CAP_IPC_LOCK
 | 
				
			||||||
 | 
						CAP_IPC_OWNER
 | 
				
			||||||
 | 
						CAP_SYS_MODULE
 | 
				
			||||||
 | 
						CAP_SYS_RAWIO
 | 
				
			||||||
 | 
						CAP_SYS_CHROOT
 | 
				
			||||||
 | 
						CAP_SYS_PTRACE
 | 
				
			||||||
 | 
						CAP_SYS_PACCT
 | 
				
			||||||
 | 
						CAP_SYS_ADMIN
 | 
				
			||||||
 | 
						CAP_SYS_BOOT
 | 
				
			||||||
 | 
						CAP_SYS_NICE
 | 
				
			||||||
 | 
						CAP_SYS_RESOURCE
 | 
				
			||||||
 | 
						CAP_SYS_TIME
 | 
				
			||||||
 | 
						CAP_SYS_TTY_CONFIG
 | 
				
			||||||
 | 
						CAP_MKNOD
 | 
				
			||||||
 | 
						CAP_LEASE
 | 
				
			||||||
 | 
						CAP_AUDIT_WRITE
 | 
				
			||||||
 | 
						CAP_AUDIT_CONTROL
 | 
				
			||||||
 | 
						CAP_SETFCAP
 | 
				
			||||||
 | 
						CAP_MAC_OVERRIDE
 | 
				
			||||||
 | 
						CAP_MAC_ADMIN
 | 
				
			||||||
 | 
						CAP_SYSLOG
 | 
				
			||||||
 | 
						CAP_WAKE_ALARM
 | 
				
			||||||
 | 
						CAP_BLOCK_SUSPEND
 | 
				
			||||||
 | 
						CAP_AUDIT_READ
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO(yifan): Export this to higher level package.
 | 
				
			||||||
 | 
					var capabilityList = map[int]string{
 | 
				
			||||||
 | 
						CAP_CHOWN:            "CAP_CHOWN",
 | 
				
			||||||
 | 
						CAP_DAC_OVERRIDE:     "CAP_DAC_OVERRIDE",
 | 
				
			||||||
 | 
						CAP_DAC_READ_SEARCH:  "CAP_DAC_READ_SEARCH",
 | 
				
			||||||
 | 
						CAP_FOWNER:           "CAP_FOWNER",
 | 
				
			||||||
 | 
						CAP_FSETID:           "CAP_FSETID",
 | 
				
			||||||
 | 
						CAP_KILL:             "CAP_KILL",
 | 
				
			||||||
 | 
						CAP_SETGID:           "CAP_SETGID",
 | 
				
			||||||
 | 
						CAP_SETUID:           "CAP_SETUID",
 | 
				
			||||||
 | 
						CAP_SETPCAP:          "CAP_SETPCAP",
 | 
				
			||||||
 | 
						CAP_LINUX_IMMUTABLE:  "CAP_LINUX_IMMUTABLE",
 | 
				
			||||||
 | 
						CAP_NET_BIND_SERVICE: "CAP_NET_BIND_SERVICE",
 | 
				
			||||||
 | 
						CAP_NET_BROADCAST:    "CAP_NET_BROADCAST",
 | 
				
			||||||
 | 
						CAP_NET_ADMIN:        "CAP_NET_ADMIN",
 | 
				
			||||||
 | 
						CAP_NET_RAW:          "CAP_NET_RAW",
 | 
				
			||||||
 | 
						CAP_IPC_LOCK:         "CAP_IPC_LOCK",
 | 
				
			||||||
 | 
						CAP_IPC_OWNER:        "CAP_IPC_OWNER",
 | 
				
			||||||
 | 
						CAP_SYS_MODULE:       "CAP_SYS_MODULE",
 | 
				
			||||||
 | 
						CAP_SYS_RAWIO:        "CAP_SYS_RAWIO",
 | 
				
			||||||
 | 
						CAP_SYS_CHROOT:       "CAP_SYS_CHROOT",
 | 
				
			||||||
 | 
						CAP_SYS_PTRACE:       "CAP_SYS_PTRACE",
 | 
				
			||||||
 | 
						CAP_SYS_PACCT:        "CAP_SYS_PACCT",
 | 
				
			||||||
 | 
						CAP_SYS_ADMIN:        "CAP_SYS_ADMIN",
 | 
				
			||||||
 | 
						CAP_SYS_BOOT:         "CAP_SYS_BOOT",
 | 
				
			||||||
 | 
						CAP_SYS_NICE:         "CAP_SYS_NICE",
 | 
				
			||||||
 | 
						CAP_SYS_RESOURCE:     "CAP_SYS_RESOURCE",
 | 
				
			||||||
 | 
						CAP_SYS_TIME:         "CAP_SYS_TIME",
 | 
				
			||||||
 | 
						CAP_SYS_TTY_CONFIG:   "CAP_SYS_TTY_CONFIG",
 | 
				
			||||||
 | 
						CAP_MKNOD:            "CAP_MKNOD",
 | 
				
			||||||
 | 
						CAP_LEASE:            "CAP_LEASE",
 | 
				
			||||||
 | 
						CAP_AUDIT_WRITE:      "CAP_AUDIT_WRITE",
 | 
				
			||||||
 | 
						CAP_AUDIT_CONTROL:    "CAP_AUDIT_CONTROL",
 | 
				
			||||||
 | 
						CAP_SETFCAP:          "CAP_SETFCAP",
 | 
				
			||||||
 | 
						CAP_MAC_OVERRIDE:     "CAP_MAC_OVERRIDE",
 | 
				
			||||||
 | 
						CAP_MAC_ADMIN:        "CAP_MAC_ADMIN",
 | 
				
			||||||
 | 
						CAP_SYSLOG:           "CAP_SYSLOG",
 | 
				
			||||||
 | 
						CAP_WAKE_ALARM:       "CAP_WAKE_ALARM",
 | 
				
			||||||
 | 
						CAP_BLOCK_SUSPEND:    "CAP_BLOCK_SUSPEND",
 | 
				
			||||||
 | 
						CAP_AUDIT_READ:       "CAP_AUDIT_READ",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getAllCapabilities returns the capability list with all capabilities.
 | 
				
			||||||
 | 
					func getAllCapabilities() string {
 | 
				
			||||||
 | 
						var capabilities []string
 | 
				
			||||||
 | 
						for _, cap := range capabilityList {
 | 
				
			||||||
 | 
							capabilities = append(capabilities, fmt.Sprintf("%q", cap))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return strings.Join(capabilities, ",")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO(yifan): This assumes that api.CapabilityType has the form of
 | 
				
			||||||
 | 
					// "CAP_SYS_ADMIN". We need to have a formal definition for
 | 
				
			||||||
 | 
					// capabilities.
 | 
				
			||||||
 | 
					func getCapabilities(caps []api.CapabilityType) string {
 | 
				
			||||||
 | 
						var capList []string
 | 
				
			||||||
 | 
						for _, cap := range caps {
 | 
				
			||||||
 | 
							capList = append(capList, fmt.Sprintf("%q", cap))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return strings.Join(capList, ",")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -17,13 +17,20 @@ limitations under the License.
 | 
				
			|||||||
package rkt
 | 
					package rkt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
 | 
				
			||||||
 | 
						appcschema "github.com/appc/spec/schema"
 | 
				
			||||||
 | 
						appctypes "github.com/appc/spec/schema/types"
 | 
				
			||||||
	"github.com/coreos/go-systemd/dbus"
 | 
						"github.com/coreos/go-systemd/dbus"
 | 
				
			||||||
 | 
						"github.com/coreos/rkt/store"
 | 
				
			||||||
	"github.com/golang/glog"
 | 
						"github.com/golang/glog"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,15 +84,13 @@ func New(config *Config) (*Runtime, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	systemd, err := dbus.New()
 | 
						systemd, err := dbus.New()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		glog.Errorf("rkt: Cannot connect to dbus: %v", err)
 | 
							return nil, fmt.Errorf("cannot connect to dbus: %v", err)
 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Test if rkt binary is in $PATH.
 | 
						// Test if rkt binary is in $PATH.
 | 
				
			||||||
	absPath, err := exec.LookPath(rktBinName)
 | 
						absPath, err := exec.LookPath(rktBinName)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		glog.Errorf("rkt: Cannot find rkt binary: %v", err)
 | 
							return nil, fmt.Errorf("cannot find rkt binary: %v", err)
 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rkt := &Runtime{
 | 
						rkt := &Runtime{
 | 
				
			||||||
@@ -134,3 +139,246 @@ func makePodServiceFileName(uid types.UID) string {
 | 
				
			|||||||
	// TODO(yifan): Revisit this later, decide whether we want to use UID.
 | 
						// TODO(yifan): Revisit this later, decide whether we want to use UID.
 | 
				
			||||||
	return fmt.Sprintf("%s_%s.service", kubernetesUnitPrefix, uid)
 | 
						return fmt.Sprintf("%s_%s.service", kubernetesUnitPrefix, uid)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type resource struct {
 | 
				
			||||||
 | 
						limit   string
 | 
				
			||||||
 | 
						request string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// rawValue converts a string to *json.RawMessage
 | 
				
			||||||
 | 
					func rawValue(value string) *json.RawMessage {
 | 
				
			||||||
 | 
						msg := json.RawMessage(value)
 | 
				
			||||||
 | 
						return &msg
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setIsolators overrides the isolators of the pod manifest if necessary.
 | 
				
			||||||
 | 
					func setIsolators(app *appctypes.App, c *api.Container) error {
 | 
				
			||||||
 | 
						if len(c.Capabilities.Add) > 0 || len(c.Capabilities.Drop) > 0 || len(c.Resources.Limits) > 0 || len(c.Resources.Requests) > 0 {
 | 
				
			||||||
 | 
							app.Isolators = []appctypes.Isolator{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Retained capabilities/privileged.
 | 
				
			||||||
 | 
						privileged := false
 | 
				
			||||||
 | 
						if capabilities.Get().AllowPrivileged {
 | 
				
			||||||
 | 
							privileged = c.Privileged
 | 
				
			||||||
 | 
						} else if c.Privileged {
 | 
				
			||||||
 | 
							return fmt.Errorf("privileged is disallowed globally")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var addCaps string
 | 
				
			||||||
 | 
						if privileged {
 | 
				
			||||||
 | 
							addCaps = getAllCapabilities()
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							addCaps = getCapabilities(c.Capabilities.Add)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(addCaps) > 0 {
 | 
				
			||||||
 | 
							// TODO(yifan): Replace with constructor, see:
 | 
				
			||||||
 | 
							// https://github.com/appc/spec/issues/268
 | 
				
			||||||
 | 
							isolator := appctypes.Isolator{
 | 
				
			||||||
 | 
								Name:     "os/linux/capabilities-retain-set",
 | 
				
			||||||
 | 
								ValueRaw: rawValue(fmt.Sprintf(`{"set":[%s]}`, addCaps)),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							app.Isolators = append(app.Isolators, isolator)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Removed capabilities.
 | 
				
			||||||
 | 
						dropCaps := getCapabilities(c.Capabilities.Drop)
 | 
				
			||||||
 | 
						if len(dropCaps) > 0 {
 | 
				
			||||||
 | 
							// TODO(yifan): Replace with constructor, see:
 | 
				
			||||||
 | 
							// https://github.com/appc/spec/issues/268
 | 
				
			||||||
 | 
							isolator := appctypes.Isolator{
 | 
				
			||||||
 | 
								Name:     "os/linux/capabilities-remove-set",
 | 
				
			||||||
 | 
								ValueRaw: rawValue(fmt.Sprintf(`{"set":[%s]}`, dropCaps)),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							app.Isolators = append(app.Isolators, isolator)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Resources.
 | 
				
			||||||
 | 
						resources := make(map[api.ResourceName]resource)
 | 
				
			||||||
 | 
						for name, quantity := range c.Resources.Limits {
 | 
				
			||||||
 | 
							resources[name] = resource{limit: quantity.String()}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for name, quantity := range c.Resources.Requests {
 | 
				
			||||||
 | 
							r, ok := resources[name]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								r = resource{}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							r.request = quantity.String()
 | 
				
			||||||
 | 
							resources[name] = r
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var acName appctypes.ACName
 | 
				
			||||||
 | 
						for name, res := range resources {
 | 
				
			||||||
 | 
							switch name {
 | 
				
			||||||
 | 
							case api.ResourceCPU:
 | 
				
			||||||
 | 
								acName = "resource/cpu"
 | 
				
			||||||
 | 
							case api.ResourceMemory:
 | 
				
			||||||
 | 
								acName = "resource/memory"
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return fmt.Errorf("resource type not supported: %v", name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// TODO(yifan): Replace with constructor, see:
 | 
				
			||||||
 | 
							// https://github.com/appc/spec/issues/268
 | 
				
			||||||
 | 
							isolator := appctypes.Isolator{
 | 
				
			||||||
 | 
								Name:     acName,
 | 
				
			||||||
 | 
								ValueRaw: rawValue(fmt.Sprintf(`{"request":%q,"limit":%q}`, res.request, res.limit)),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							app.Isolators = append(app.Isolators, isolator)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setApp overrides the app's fields if any of them are specified in the
 | 
				
			||||||
 | 
					// container's spec.
 | 
				
			||||||
 | 
					func setApp(app *appctypes.App, c *api.Container) error {
 | 
				
			||||||
 | 
						// Override the exec.
 | 
				
			||||||
 | 
						// TOOD(yifan): Revisit this for the overriding rule.
 | 
				
			||||||
 | 
						if len(c.Command) > 0 || len(c.Args) > 0 {
 | 
				
			||||||
 | 
							app.Exec = append(c.Command, c.Args...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO(yifan): Use non-root user in the future, see:
 | 
				
			||||||
 | 
						// https://github.com/coreos/rkt/issues/820
 | 
				
			||||||
 | 
						app.User, app.Group = "0", "0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Override the working directory.
 | 
				
			||||||
 | 
						if len(c.WorkingDir) > 0 {
 | 
				
			||||||
 | 
							app.WorkingDirectory = c.WorkingDir
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Override the environment.
 | 
				
			||||||
 | 
						// TODO(yifan): Use RunContainerOptions.
 | 
				
			||||||
 | 
						if len(c.Env) > 0 {
 | 
				
			||||||
 | 
							app.Environment = []appctypes.EnvironmentVariable{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, env := range c.Env {
 | 
				
			||||||
 | 
							app.Environment = append(app.Environment, appctypes.EnvironmentVariable{
 | 
				
			||||||
 | 
								Name:  env.Name,
 | 
				
			||||||
 | 
								Value: env.Value,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Override the mount points.
 | 
				
			||||||
 | 
						if len(c.VolumeMounts) > 0 {
 | 
				
			||||||
 | 
							app.MountPoints = []appctypes.MountPoint{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, m := range c.VolumeMounts {
 | 
				
			||||||
 | 
							mountPointName, err := appctypes.NewACName(m.Name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							app.MountPoints = append(app.MountPoints, appctypes.MountPoint{
 | 
				
			||||||
 | 
								Name:     *mountPointName,
 | 
				
			||||||
 | 
								Path:     m.MountPath,
 | 
				
			||||||
 | 
								ReadOnly: m.ReadOnly,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Override the ports.
 | 
				
			||||||
 | 
						if len(c.Ports) > 0 {
 | 
				
			||||||
 | 
							app.Ports = []appctypes.Port{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, p := range c.Ports {
 | 
				
			||||||
 | 
							portName, err := appctypes.NewACName(p.Name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							app.Ports = append(app.Ports, appctypes.Port{
 | 
				
			||||||
 | 
								Name:     *portName,
 | 
				
			||||||
 | 
								Protocol: string(p.Protocol),
 | 
				
			||||||
 | 
								Port:     uint(p.ContainerPort),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Override isolators.
 | 
				
			||||||
 | 
						return setIsolators(app, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// makePodManifest transforms a kubelet pod spec to the rkt pod manifest.
 | 
				
			||||||
 | 
					// TODO(yifan): Use the RunContainerOptions generated by GenerateRunContainerOptions().
 | 
				
			||||||
 | 
					func (r *Runtime) makePodManifest(pod *api.Pod, volumeMap map[string]volume.Volume) (*appcschema.PodManifest, error) {
 | 
				
			||||||
 | 
						manifest := appcschema.BlankPodManifest()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get the image manifests, assume they are already in the cas,
 | 
				
			||||||
 | 
						// and extract the app field from the image and to be the 'base app'.
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// We do this is because we will fully replace the image manifest's app
 | 
				
			||||||
 | 
						// with the pod manifest's app in rkt runtime. See below:
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// https://github.com/coreos/rkt/issues/723.
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						s, err := store.NewStore(rktDataDir)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("cannot open store: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, c := range pod.Spec.Containers {
 | 
				
			||||||
 | 
							// Assume we are running docker images for now, see #7203.
 | 
				
			||||||
 | 
							imageID, err := r.getImageID(c.Image)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("cannot get image ID for %q: %v", c.Image, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							hash, err := appctypes.NewHash(imageID)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							im, err := s.GetImageManifest(hash.String())
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("cannot get image manifest: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Override the image manifest's app and store it in the pod manifest.
 | 
				
			||||||
 | 
							app := im.App
 | 
				
			||||||
 | 
							if err := setApp(app, &c); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							manifest.Apps = append(manifest.Apps, appcschema.RuntimeApp{
 | 
				
			||||||
 | 
								Name:  im.Name,
 | 
				
			||||||
 | 
								Image: appcschema.RuntimeImage{ID: *hash},
 | 
				
			||||||
 | 
								App:   app,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set global volumes.
 | 
				
			||||||
 | 
						for name, volume := range volumeMap {
 | 
				
			||||||
 | 
							volName, err := appctypes.NewACName(name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("cannot use the volume's name %q as ACName: %v", name, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							manifest.Volumes = append(manifest.Volumes, appctypes.Volume{
 | 
				
			||||||
 | 
								Name:   *volName,
 | 
				
			||||||
 | 
								Kind:   "host",
 | 
				
			||||||
 | 
								Source: volume.GetPath(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set global ports.
 | 
				
			||||||
 | 
						for _, c := range pod.Spec.Containers {
 | 
				
			||||||
 | 
							for _, port := range c.Ports {
 | 
				
			||||||
 | 
								portName, err := appctypes.NewACName(port.Name)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, fmt.Errorf("cannot use the port's name %q as ACName: %v", port.Name, err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								manifest.Ports = append(manifest.Ports, appctypes.ExposedPort{
 | 
				
			||||||
 | 
									Name:     *portName,
 | 
				
			||||||
 | 
									HostPort: uint(port.HostPort),
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// TODO(yifan): Set pod-level isolators once it's supported in kubernetes.
 | 
				
			||||||
 | 
						return manifest, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO(yifan): Replace with 'rkt images'.
 | 
				
			||||||
 | 
					func (r *Runtime) getImageID(imageName string) (string, error) {
 | 
				
			||||||
 | 
						output, err := r.runCommand("fetch", imageName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(output) == 0 {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("no result from rkt fetch")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						last := output[len(output)-1]
 | 
				
			||||||
 | 
						if !strings.HasPrefix(last, "sha512-") {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("unexpected result: %q", last)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return last, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user