rkt: Unexport runtime, use Runtime interface

This commit is contained in:
Victor Marmol 2015-05-04 17:28:02 -07:00
parent f012d7f506
commit d84aac6498
2 changed files with 35 additions and 35 deletions

View File

@ -18,10 +18,10 @@ package rkt
// ImageManager manages and garbage collects the container images for rkt. // ImageManager manages and garbage collects the container images for rkt.
type ImageManager struct { type ImageManager struct {
runtime *Runtime runtime *runtime
} }
func NewImageManager(r *Runtime) *ImageManager { func NewImageManager(r *runtime) *ImageManager {
return &ImageManager{runtime: r} return &ImageManager{runtime: r}
} }

View File

@ -84,10 +84,10 @@ const (
defaultExpirePrepared = "1m" defaultExpirePrepared = "1m"
) )
// Runtime implements the ContainerRuntime for rkt. The implementation // runtime implements the Containerruntime for rkt. The implementation
// uses systemd, so in order to run this runtime, systemd must be installed // uses systemd, so in order to run this runtime, systemd must be installed
// on the machine. // on the machine.
type Runtime struct { type runtime struct {
generator kubecontainer.RunContainerOptionsGenerator generator kubecontainer.RunContainerOptionsGenerator
readinessManager *kubecontainer.ReadinessManager readinessManager *kubecontainer.ReadinessManager
prober prober.Prober prober prober.Prober
@ -99,12 +99,12 @@ type Runtime struct {
dockerKeyring credentialprovider.DockerKeyring dockerKeyring credentialprovider.DockerKeyring
} }
var _ kubecontainer.Runtime = &Runtime{} var _ kubecontainer.Runtime = &runtime{}
// New creates the rkt container runtime which implements the container runtime interface. // New creates the rkt container runtime which implements the container runtime interface.
// It will test if the rkt binary is in the $PATH, and whether we can get the // It will test if the rkt binary is in the $PATH, and whether we can get the
// version of it. If so, creates the rkt container runtime, otherwise returns an error. // version of it. If so, creates the rkt container runtime, otherwise returns an error.
func New(config *Config) (*Runtime, error) { func New(config *Config) (kubecontainer.Runtime, error) {
systemdVersion, err := getSystemdVersion() systemdVersion, err := getSystemdVersion()
if err != nil { if err != nil {
return nil, err return nil, err
@ -128,7 +128,7 @@ func New(config *Config) (*Runtime, error) {
return nil, fmt.Errorf("cannot find rkt binary: %v", err) return nil, fmt.Errorf("cannot find rkt binary: %v", err)
} }
rkt := &Runtime{ rkt := &runtime{
systemd: systemd, systemd: systemd,
rktBinAbsPath: rktBinAbsPath, rktBinAbsPath: rktBinAbsPath,
config: config, config: config,
@ -150,7 +150,7 @@ func New(config *Config) (*Runtime, error) {
return rkt, nil return rkt, nil
} }
func (r *Runtime) buildCommand(args ...string) *exec.Cmd { func (r *runtime) buildCommand(args ...string) *exec.Cmd {
cmd := exec.Command(rktBinName) cmd := exec.Command(rktBinName)
cmd.Args = append(cmd.Args, r.config.buildGlobalOptions()...) cmd.Args = append(cmd.Args, r.config.buildGlobalOptions()...)
cmd.Args = append(cmd.Args, args...) cmd.Args = append(cmd.Args, args...)
@ -159,7 +159,7 @@ func (r *Runtime) buildCommand(args ...string) *exec.Cmd {
// runCommand invokes rkt binary with arguments and returns the result // runCommand invokes rkt binary with arguments and returns the result
// from stdout in a list of strings. // from stdout in a list of strings.
func (r *Runtime) runCommand(args ...string) ([]string, error) { func (r *runtime) runCommand(args ...string) ([]string, error) {
glog.V(4).Info("rkt: Run command:", args) glog.V(4).Info("rkt: Run command:", args)
output, err := r.buildCommand(args...).Output() output, err := r.buildCommand(args...).Output()
@ -329,7 +329,7 @@ func setApp(app *appctypes.App, c *api.Container) error {
// makePodManifest transforms a kubelet pod spec to the rkt pod manifest. // makePodManifest transforms a kubelet pod spec to the rkt pod manifest.
// TODO(yifan): Use the RunContainerOptions generated by GenerateRunContainerOptions(). // TODO(yifan): Use the RunContainerOptions generated by GenerateRunContainerOptions().
func (r *Runtime) makePodManifest(pod *api.Pod, volumeMap map[string]volume.Volume) (*appcschema.PodManifest, error) { func (r *runtime) makePodManifest(pod *api.Pod, volumeMap map[string]volume.Volume) (*appcschema.PodManifest, error) {
manifest := appcschema.BlankPodManifest() manifest := appcschema.BlankPodManifest()
// Get the image manifests, assume they are already in the cas, // Get the image manifests, assume they are already in the cas,
@ -403,7 +403,7 @@ func (r *Runtime) makePodManifest(pod *api.Pod, volumeMap map[string]volume.Volu
} }
// TODO(yifan): Replace with 'rkt images'. // TODO(yifan): Replace with 'rkt images'.
func (r *Runtime) getImageID(imageName string) (string, error) { func (r *runtime) getImageID(imageName string) (string, error) {
output, err := r.runCommand("fetch", imageName) output, err := r.runCommand("fetch", imageName)
if err != nil { if err != nil {
return "", err return "", err
@ -431,7 +431,7 @@ func hashContainer(container *api.Container) uint64 {
} }
// TODO(yifan): Remove the receiver once we can solve the appName->imageID problem. // TODO(yifan): Remove the receiver once we can solve the appName->imageID problem.
func (r *Runtime) apiPodToRuntimePod(uuid string, pod *api.Pod) *kubecontainer.Pod { func (r *runtime) apiPodToruntimePod(uuid string, pod *api.Pod) *kubecontainer.Pod {
p := &kubecontainer.Pod{ p := &kubecontainer.Pod{
ID: pod.UID, ID: pod.UID,
Name: pod.Name, Name: pod.Name,
@ -462,7 +462,7 @@ func (r *Runtime) apiPodToRuntimePod(uuid string, pod *api.Pod) *kubecontainer.P
// On success, it will return a string that represents name of the unit file // On success, it will return a string that represents name of the unit file
// and a boolean that indicates if the unit file needs to be reloaded (whether // and a boolean that indicates if the unit file needs to be reloaded (whether
// the file is already existed). // the file is already existed).
func (r *Runtime) preparePod(pod *api.Pod, volumeMap map[string]volume.Volume) (string, bool, error) { func (r *runtime) preparePod(pod *api.Pod, volumeMap map[string]volume.Volume) (string, bool, error) {
cmds := []string{"prepare", "--quiet", "--pod-manifest"} cmds := []string{"prepare", "--quiet", "--pod-manifest"}
// Generate the pod manifest from the pod spec. // Generate the pod manifest from the pod spec.
@ -502,7 +502,7 @@ func (r *Runtime) preparePod(pod *api.Pod, volumeMap map[string]volume.Volume) (
uuid := output[0] uuid := output[0]
glog.V(4).Infof("'rkt prepare' returns %q.", uuid) glog.V(4).Infof("'rkt prepare' returns %q.", uuid)
p := r.apiPodToRuntimePod(uuid, pod) p := r.apiPodToruntimePod(uuid, pod)
b, err := json.Marshal(p) b, err := json.Marshal(p)
if err != nil { if err != nil {
return "", false, err return "", false, err
@ -537,7 +537,7 @@ func (r *Runtime) preparePod(pod *api.Pod, volumeMap map[string]volume.Volume) (
// RunPod first creates the unit file for a pod, and then calls // RunPod first creates the unit file for a pod, and then calls
// StartUnit over d-bus. // StartUnit over d-bus.
func (r *Runtime) RunPod(pod *api.Pod, volumeMap map[string]volume.Volume) error { func (r *runtime) RunPod(pod *api.Pod, volumeMap map[string]volume.Volume) error {
glog.V(4).Infof("Rkt starts to run pod: name %q.", pod.Name) glog.V(4).Infof("Rkt starts to run pod: name %q.", pod.Name)
name, needReload, err := r.preparePod(pod, volumeMap) name, needReload, err := r.preparePod(pod, volumeMap)
@ -561,10 +561,10 @@ func (r *Runtime) RunPod(pod *api.Pod, volumeMap map[string]volume.Volume) error
return nil return nil
} }
// makeRuntimePod constructs the container runtime pod. It will: // makeruntimePod constructs the container runtime pod. It will:
// 1, Construct the pod by the information stored in the unit file. // 1, Construct the pod by the information stored in the unit file.
// 2, Construct the pod status from pod info. // 2, Construct the pod status from pod info.
func (r *Runtime) makeRuntimePod(unitName string, podInfos map[string]*podInfo) (*kubecontainer.Pod, error) { func (r *runtime) makeruntimePod(unitName string, podInfos map[string]*podInfo) (*kubecontainer.Pod, error) {
f, err := os.Open(path.Join(systemdServiceDir, unitName)) f, err := os.Open(path.Join(systemdServiceDir, unitName))
if err != nil { if err != nil {
return nil, err return nil, err
@ -610,7 +610,7 @@ func (r *Runtime) makeRuntimePod(unitName string, podInfos map[string]*podInfo)
// Then it will use the result to contruct a list of container runtime pods. // Then it will use the result to contruct a list of container runtime pods.
// If all is false, then only running pods will be returned, otherwise all pods will be // If all is false, then only running pods will be returned, otherwise all pods will be
// returned. // returned.
func (r *Runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) { func (r *runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) {
glog.V(4).Infof("Rkt getting pods") glog.V(4).Infof("Rkt getting pods")
units, err := r.systemd.ListUnits() units, err := r.systemd.ListUnits()
@ -631,7 +631,7 @@ func (r *Runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) {
if !all && u.SubState != "running" { if !all && u.SubState != "running" {
continue continue
} }
pod, err := r.makeRuntimePod(u.Name, podInfos) pod, err := r.makeruntimePod(u.Name, podInfos)
if err != nil { if err != nil {
glog.Warningf("rkt: Cannot construct pod from unit file: %v.", err) glog.Warningf("rkt: Cannot construct pod from unit file: %v.", err)
continue continue
@ -643,7 +643,7 @@ func (r *Runtime) GetPods(all bool) ([]*kubecontainer.Pod, error) {
} }
// KillPod invokes 'systemctl kill' to kill the unit that runs the pod. // KillPod invokes 'systemctl kill' to kill the unit that runs the pod.
func (r *Runtime) KillPod(pod kubecontainer.Pod) error { func (r *runtime) KillPod(pod kubecontainer.Pod) error {
glog.V(4).Infof("Rkt is killing pod: name %q.", pod.Name) glog.V(4).Infof("Rkt is killing pod: name %q.", pod.Name)
// TODO(yifan): More graceful stop. Replace with StopUnit and wait for a timeout. // TODO(yifan): More graceful stop. Replace with StopUnit and wait for a timeout.
@ -653,7 +653,7 @@ func (r *Runtime) KillPod(pod kubecontainer.Pod) error {
// GetPodStatus currently invokes GetPods() to return the status. // GetPodStatus currently invokes GetPods() to return the status.
// TODO(yifan): Split the get status logic from GetPods(). // TODO(yifan): Split the get status logic from GetPods().
func (r *Runtime) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) { func (r *runtime) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) {
pods, err := r.GetPods(true) pods, err := r.GetPods(true)
if err != nil { if err != nil {
return nil, err return nil, err
@ -672,7 +672,7 @@ func (r *Runtime) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) {
// Example: // Example:
// rkt:0.3.2+git --> []int{0, 3, 2}. // rkt:0.3.2+git --> []int{0, 3, 2}.
// //
func (r *Runtime) Version() (kubecontainer.Version, error) { func (r *runtime) Version() (kubecontainer.Version, error) {
output, err := r.runCommand("version") output, err := r.runCommand("version")
if err != nil { if err != nil {
return nil, err return nil, err
@ -696,7 +696,7 @@ func (r *Runtime) Version() (kubecontainer.Version, error) {
// writeDockerAuthConfig writes the docker credentials to rkt auth config files. // writeDockerAuthConfig writes the docker credentials to rkt auth config files.
// This enables rkt to pull docker images from docker registry with credentials. // This enables rkt to pull docker images from docker registry with credentials.
func (r *Runtime) writeDockerAuthConfig(image string, creds docker.AuthConfiguration) error { func (r *runtime) writeDockerAuthConfig(image string, creds docker.AuthConfiguration) error {
registry := "index.docker.io" registry := "index.docker.io"
// Image spec: [<registry>/]<repository>/<image>[:<version] // Image spec: [<registry>/]<repository>/<image>[:<version]
explicitRegistry := (strings.Count(image, "/") == 2) explicitRegistry := (strings.Count(image, "/") == 2)
@ -730,7 +730,7 @@ func (r *Runtime) writeDockerAuthConfig(image string, creds docker.AuthConfigura
} }
// PullImage invokes 'rkt fetch' to download an aci. // PullImage invokes 'rkt fetch' to download an aci.
func (r *Runtime) PullImage(img string) error { func (r *runtime) PullImage(img string) error {
// Use credentials for docker images. This string operation can be cleaned up // Use credentials for docker images. This string operation can be cleaned up
// once the format of image is landed, see: // once the format of image is landed, see:
// https://github.com/GoogleCloudPlatform/kubernetes/issues/7203 // https://github.com/GoogleCloudPlatform/kubernetes/issues/7203
@ -764,23 +764,23 @@ func (r *Runtime) PullImage(img string) error {
// IsImagePresent returns true if the image is available on the machine. // IsImagePresent returns true if the image is available on the machine.
// TODO(yifan): 'rkt image' is now landed on master, use that once we bump up // TODO(yifan): 'rkt image' is now landed on master, use that once we bump up
// the rkt version. // the rkt version.
func (r *Runtime) IsImagePresent(img string) (bool, error) { func (r *runtime) IsImagePresent(img string) (bool, error) {
if _, err := r.runCommand("prepare", "--local=true", img); err != nil { if _, err := r.runCommand("prepare", "--local=true", img); err != nil {
return false, nil return false, nil
} }
return true, nil return true, nil
} }
func (r *Runtime) ListImages() ([]kubecontainer.Image, error) { func (r *runtime) ListImages() ([]kubecontainer.Image, error) {
return []kubecontainer.Image{}, fmt.Errorf("rkt: ListImages unimplemented") return []kubecontainer.Image{}, fmt.Errorf("rkt: ListImages unimplemented")
} }
func (r *Runtime) RemoveImage(image string) error { func (r *runtime) RemoveImage(image string) error {
return fmt.Errorf("rkt: RemoveImages unimplemented") return fmt.Errorf("rkt: RemoveImages unimplemented")
} }
// SyncPod syncs the running pod to match the specified desired pod. // SyncPod syncs the running pod to match the specified desired pod.
func (r *Runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus api.PodStatus) error { func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus api.PodStatus) error {
podFullName := kubecontainer.GetPodFullName(pod) podFullName := kubecontainer.GetPodFullName(pod)
if len(runningPod.Containers) == 0 { if len(runningPod.Containers) == 0 {
glog.V(4).Infof("Pod %q is not running, will start it", podFullName) glog.V(4).Infof("Pod %q is not running, will start it", podFullName)
@ -856,7 +856,7 @@ func (r *Runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus
// TODO(yifan): Currently, it fetches all the containers' log within a pod. We will // TODO(yifan): Currently, it fetches all the containers' log within a pod. We will
// be able to fetch individual container's log once https://github.com/coreos/rkt/pull/841 // be able to fetch individual container's log once https://github.com/coreos/rkt/pull/841
// landed. // landed.
func (r *Runtime) GetContainerLogs(pod *api.Pod, containerID string, tail string, follow bool, stdout, stderr io.Writer) error { func (r *runtime) GetContainerLogs(pod *api.Pod, containerID string, tail string, follow bool, stdout, stderr io.Writer) error {
unitName := makePodServiceFileName(pod.UID) unitName := makePodServiceFileName(pod.UID)
cmd := exec.Command("journalctl", "-u", unitName) cmd := exec.Command("journalctl", "-u", unitName)
if follow { if follow {
@ -875,7 +875,7 @@ func (r *Runtime) GetContainerLogs(pod *api.Pod, containerID string, tail string
} }
// GarbageCollect collects the pods/containers. TODO(yifan): Enforce the gc policy. // GarbageCollect collects the pods/containers. TODO(yifan): Enforce the gc policy.
func (r *Runtime) GarbageCollect() error { func (r *runtime) GarbageCollect() error {
if err := exec.Command("systemctl", "reset-failed").Run(); err != nil { if err := exec.Command("systemctl", "reset-failed").Run(); err != nil {
glog.Errorf("rkt: Failed to reset failed systemd services: %v", err) glog.Errorf("rkt: Failed to reset failed systemd services: %v", err)
} }
@ -888,7 +888,7 @@ func (r *Runtime) GarbageCollect() error {
// Note: In rkt, the container ID is in the form of "UUID:appName:ImageID", where // Note: In rkt, the container ID is in the form of "UUID:appName:ImageID", where
// appName is the container name. // appName is the container name.
func (r *Runtime) RunInContainer(containerID string, cmd []string) ([]byte, error) { func (r *runtime) RunInContainer(containerID string, cmd []string) ([]byte, error) {
glog.V(4).Infof("Rkt running in container.") glog.V(4).Infof("Rkt running in container.")
id, err := parseContainerID(containerID) id, err := parseContainerID(containerID)
@ -906,7 +906,7 @@ func (r *Runtime) RunInContainer(containerID string, cmd []string) ([]byte, erro
// Note: In rkt, the container ID is in the form of "UUID:appName:ImageID", where // Note: In rkt, the container ID is in the form of "UUID:appName:ImageID", where
// appName is the container name. // appName is the container name.
func (r *Runtime) ExecInContainer(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { func (r *runtime) ExecInContainer(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
glog.V(4).Infof("Rkt execing in container.") glog.V(4).Infof("Rkt execing in container.")
id, err := parseContainerID(containerID) id, err := parseContainerID(containerID)
@ -963,7 +963,7 @@ func (r *Runtime) ExecInContainer(containerID string, cmd []string, stdin io.Rea
// findRktID returns the rkt uuid for the pod. // findRktID returns the rkt uuid for the pod.
// TODO(yifan): This is unefficient which require us to list // TODO(yifan): This is unefficient which require us to list
// all the unit files. // all the unit files.
func (r *Runtime) findRktID(pod *kubecontainer.Pod) (string, error) { func (r *runtime) findRktID(pod *kubecontainer.Pod) (string, error) {
units, err := r.systemd.ListUnits() units, err := r.systemd.ListUnits()
if err != nil { if err != nil {
return "", err return "", err
@ -1006,7 +1006,7 @@ func (r *Runtime) findRktID(pod *kubecontainer.Pod) (string, error) {
// - should we support nsenter + socat in a container, running with elevated privs and --pid=host? // - should we support nsenter + socat in a container, running with elevated privs and --pid=host?
// //
// TODO(yifan): Merge with the same function in dockertools. // TODO(yifan): Merge with the same function in dockertools.
func (r *Runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error { func (r *runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error {
glog.V(4).Infof("Rkt port forwarding in container.") glog.V(4).Infof("Rkt port forwarding in container.")
podInfos, err := r.getPodInfos() podInfos, err := r.getPodInfos()
@ -1044,7 +1044,7 @@ func (r *Runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.Rea
} }
// getPodInfos returns a map of [pod-uuid]:*podInfo // getPodInfos returns a map of [pod-uuid]:*podInfo
func (r *Runtime) getPodInfos() (map[string]*podInfo, error) { func (r *runtime) getPodInfos() (map[string]*podInfo, error) {
result := make(map[string]*podInfo) result := make(map[string]*podInfo)
output, err := r.runCommand("list", "--no-legend", "--full") output, err := r.runCommand("list", "--no-legend", "--full")