Merge pull request #29919 from tmrts/kubelet-rkt-cri/container-api

Automatic merge from submit-queue

Kubelet rkt CRI stubs & fakes

Adds stubs for CRI interfaces and creates a fake for `ContainerRuntime` interface
This commit is contained in:
Kubernetes Submit Queue 2016-08-21 07:14:03 -07:00 committed by GitHub
commit 6dabf60114
3 changed files with 345 additions and 0 deletions

View File

@ -0,0 +1,71 @@
/*
Copyright 2016 The Kubernetes Authors.
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 rktshim
import (
"io"
kubeletApi "k8s.io/kubernetes/pkg/kubelet/api"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// Runtime provides an API for lifecycle, inspection and introspection
// operations in a blocking manner using the App level API provided by rkt.
type Runtime struct{}
// TODO(tmrts): Fill out the creation configuration fields.
type RuntimeConfig struct{}
// NewRuntime creates a container.Runtime instance using the Runtime.
func NewRuntime(RuntimeConfig) (kubeletApi.ContainerManager, error) {
return &Runtime{}, nil
}
// CreateContainer creates an app inside the provided pod sandbox and returns the RawContainerID.
func (*Runtime) CreateContainer(string, *runtimeApi.ContainerConfig, *runtimeApi.PodSandboxConfig) (string, error) {
panic("not implemented")
}
// StartContainer starts a created app.
func (*Runtime) StartContainer(string) error {
panic("not implemented")
}
// StopContainer stops a running app with a grace period (i.e. timeout).
func (*Runtime) StopContainer(string, int64) error {
panic("not implemented")
}
// RemoveContainer removes the app from a pod sandbox.
func (*Runtime) RemoveContainer(string) error {
panic("not implemented")
}
// ListContainers lists out the apps residing inside the pod sandbox using the ContainerFilter.
func (*Runtime) ListContainers(*runtimeApi.ContainerFilter) ([]*runtimeApi.Container, error) {
panic("not implemented")
}
// ContainerStatus returns the RawContainerStatus of an app inside the pod sandbox.
func (*Runtime) ContainerStatus(string) (*runtimeApi.ContainerStatus, error) {
panic("not implemented")
}
// Exec executes a command inside an app running inside a pod sanbox.
func (*Runtime) Exec(string, []string, bool, io.Reader, io.WriteCloser, io.WriteCloser) error {
panic("not implemented")
}

View File

@ -0,0 +1,215 @@
/*
Copyright 2016 The Kubernetes Authors.
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 rktshim
import (
"errors"
"io"
"math/rand"
"time"
kubeletApi "k8s.io/kubernetes/pkg/kubelet/api"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
func init() {
// Don't randomize due to testing purposes
// rand.Seed(time.Now().UnixNano())
}
func randString(n int) string {
runeAlphabet := []rune("abcdefghijklmnopqrstuvwxyz")
dictLen := len(runeAlphabet)
buf := make([]rune, n)
for i := range buf {
buf[i] = runeAlphabet[rand.Intn(dictLen)]
}
return string(buf)
}
var (
ErrContainerNotFound = errors.New("rktshim: container not found")
ErrInvalidContainerStateTransition = errors.New("rktshim: wrong container operation for current state")
)
type FakeRuntime struct {
Containers containerRegistry
}
type FakeRuntimeConfig struct{}
func NewFakeRuntime() (kubeletApi.ContainerManager, error) {
return &FakeRuntime{Containers: make(containerRegistry)}, nil
}
type characterStreams struct {
In io.Reader
Out io.Writer
Err io.Writer
}
func newCharacterStreams(in io.Reader, out io.Writer, err io.Writer) characterStreams {
std := characterStreams{in, out, err}
return std
}
type fakeContainer struct {
Config *runtimeApi.ContainerConfig
Status runtimeApi.ContainerStatus
State runtimeApi.ContainerState
Streams characterStreams
}
func (c *fakeContainer) Start() {
c.State = runtimeApi.ContainerState_RUNNING
c.Status.State = &c.State
}
func (c *fakeContainer) Stop() {
c.State = runtimeApi.ContainerState_EXITED
c.Status.State = &c.State
exitSuccess := int32(0)
c.Status.ExitCode = &exitSuccess
// c.Status.Reason
}
func (c *fakeContainer) Exec(cmd []string, in io.Reader, out, err io.WriteCloser) error {
// TODO(tmrts): incomplete command execution logic
// c.StreamCompare(c.Streams.In, s.InputStream)
// c.StreamFlush(c.Streams.Out, s.OutputStream)
// c.StreamFlush(c.Streams.Err, s.ErrorStream)
return nil
}
type containerRegistry map[string]*fakeContainer
func (r *FakeRuntime) CreateContainer(pid string, cfg *runtimeApi.ContainerConfig, sandboxCfg *runtimeApi.PodSandboxConfig) (string, error) {
// TODO(tmrts): allow customization
containerIDLength := 8
cid := randString(containerIDLength)
r.Containers[cid] = &fakeContainer{
Config: cfg,
Streams: newCharacterStreams(nil, nil, nil),
}
return cid, nil
}
func (r *FakeRuntime) StartContainer(id string) error {
c, ok := r.Containers[id]
if !ok {
return ErrContainerNotFound
}
switch c.State {
case runtimeApi.ContainerState_EXITED:
fallthrough
case runtimeApi.ContainerState_CREATED:
c.Start()
case runtimeApi.ContainerState_UNKNOWN:
// TODO(tmrts): add timeout to Start API or generalize timeout somehow
//<-time.After(time.Duration(timeout) * time.Second)
fallthrough
default:
return ErrInvalidContainerStateTransition
}
return nil
}
func (r *FakeRuntime) StopContainer(id string, timeout int64) error {
c, ok := r.Containers[id]
if !ok {
return ErrContainerNotFound
}
switch c.State {
case runtimeApi.ContainerState_RUNNING:
c.State = runtimeApi.ContainerState_EXITED // This state might not be the best one
case runtimeApi.ContainerState_UNKNOWN:
<-time.After(time.Duration(timeout) * time.Second)
fallthrough
default:
return ErrInvalidContainerStateTransition
}
return nil
}
func (r *FakeRuntime) RemoveContainer(id string) error {
_, ok := r.Containers[id]
if !ok {
return ErrContainerNotFound
}
// Remove regardless of the container state
delete(r.Containers, id)
return nil
}
func (r *FakeRuntime) ListContainers(*runtimeApi.ContainerFilter) ([]*runtimeApi.Container, error) {
list := []*runtimeApi.Container{}
// TODO(tmrts): apply the filter
for _, c := range r.Containers {
list = append(list, &runtimeApi.Container{
Id: c.Status.Id,
Name: c.Config.Name,
Labels: c.Config.Labels,
ImageRef: c.Status.ImageRef,
State: &c.State,
})
}
return list, nil
}
func (r *FakeRuntime) ContainerStatus(id string) (*runtimeApi.ContainerStatus, error) {
c, ok := r.Containers[id]
if !ok {
return &runtimeApi.ContainerStatus{}, ErrContainerNotFound
}
return &c.Status, nil
}
func (r *FakeRuntime) Exec(id string, cmd []string, tty bool, in io.Reader, out, err io.WriteCloser) error {
c, ok := r.Containers[id]
if !ok {
return ErrContainerNotFound
}
// TODO(tmrts): Validate the assumption that container has to be running for exec to work.
if c.State != runtimeApi.ContainerState_RUNNING {
return ErrInvalidContainerStateTransition
}
return c.Exec(cmd, in, out, err)
}

View File

@ -0,0 +1,59 @@
/*
Copyright 2016 The Kubernetes Authors.
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 rktshim
import (
kubeletApi "k8s.io/kubernetes/pkg/kubelet/api"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// PodSandboxManager provides basic operations to create/delete and examine
// the pod sandboxes in a blocking manner.
type PodSandboxManager struct{}
// TODO(tmrts): Fill the configuration struct fields.
type PodSandboxManagerConfig struct{}
// NewPodSandboxManager creates a PodSandboxManager.
func NewPodSandboxManager(PodSandboxManagerConfig) (kubeletApi.PodSandboxManager, error) {
return &PodSandboxManager{}, nil
}
// CreatePodSandbox creates a pod sandbox given a pod sandbox configuration.
func (*PodSandboxManager) CreatePodSandbox(*runtimeApi.PodSandboxConfig) (string, error) {
panic("not implemented")
}
// StopPodSandbox stops a pod sandbox and the apps inside the sandbox.
func (*PodSandboxManager) StopPodSandbox(string) error {
panic("not implemented")
}
// RemovePodSandbox deletes the pod sandbox and the apps inside the sandbox.
func (*PodSandboxManager) RemovePodSandbox(string) error {
panic("not implemented")
}
// PodSandboxStatus queries the status of the pod sandbox.
func (*PodSandboxManager) PodSandboxStatus(string) (*runtimeApi.PodSandboxStatus, error) {
panic("not implemented")
}
// ListPodSandbox lists existing sandboxes, filtered by the PodSandboxFilter.
func (*PodSandboxManager) ListPodSandbox(*runtimeApi.PodSandboxFilter) ([]*runtimeApi.PodSandbox, error) {
panic("not implemented")
}