Don't require rootfs if not set on container

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2017-05-25 11:17:36 -07:00
parent a2b0824720
commit d0b22290ec
8 changed files with 35 additions and 29 deletions

View File

@ -158,7 +158,7 @@ func WithRuntime(name string) NewContainerOpts {
// NewContainer will create a new container in container with the provided id // NewContainer will create a new container in container with the provided id
// the id must be unique within the namespace // the id must be unique within the namespace
func (c *Client) NewContainer(ctx context.Context, id string, spec *specs.Spec, opts ...NewContainerOpts) (Container, error) { func (c *Client) NewContainer(ctx context.Context, id string, image Image, spec *specs.Spec, opts ...NewContainerOpts) (Container, error) {
data, err := json.Marshal(spec) data, err := json.Marshal(spec)
if err != nil { if err != nil {
return nil, err return nil, err
@ -170,6 +170,7 @@ func (c *Client) NewContainer(ctx context.Context, id string, spec *specs.Spec,
TypeUrl: specs.Version, TypeUrl: specs.Version,
Value: data, Value: data,
}, },
Image: image.Name(),
} }
for _, o := range opts { for _, o := range opts {
if err := o(ctx, c, &container); err != nil { if err := o(ctx, c, &container); err != nil {

View File

@ -9,6 +9,7 @@ const defaultAddress = "/run/containerd/containerd.sock"
func TestNewClient(t *testing.T) { func TestNewClient(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip()
return return
} }
client, err := New(defaultAddress) client, err := New(defaultAddress)
@ -25,6 +26,7 @@ func TestNewClient(t *testing.T) {
func TestImagePull(t *testing.T) { func TestImagePull(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip()
return return
} }
client, err := New(defaultAddress) client, err := New(defaultAddress)

View File

@ -8,7 +8,7 @@ import (
) )
func dialer(address string, timeout time.Duration) (net.Conn, error) { func dialer(address string, timeout time.Duration) (net.Conn, error) {
return winio.DialPipe(bindAddress, &timeout) return winio.DialPipe(address, &timeout)
} }
func dialAddress(address string) string { func dialAddress(address string) string {

View File

@ -50,10 +50,12 @@ func (c *container) Spec() (*specs.Spec, error) {
// Delete deletes an existing container // Delete deletes an existing container
// an error is returned if the container has running tasks // an error is returned if the container has running tasks
func (c *container) Delete(ctx context.Context) error { func (c *container) Delete(ctx context.Context) (err error) {
// TODO: should the client be the one removing resources attached // TODO: should the client be the one removing resources attached
// to the container at the moment before we have GC? // to the container at the moment before we have GC?
err := c.client.SnapshotService().Remove(ctx, c.c.RootFS) if c.c.RootFS != "" {
err = c.client.SnapshotService().Remove(ctx, c.c.RootFS)
}
if _, cerr := c.client.ContainerService().Delete(ctx, &containers.DeleteContainerRequest{ if _, cerr := c.client.ContainerService().Delete(ctx, &containers.DeleteContainerRequest{
ID: c.c.ID, ID: c.c.ID,
@ -79,17 +81,19 @@ func (c *container) NewTask(ctx context.Context, ioCreate IOCreation) (Task, err
Stdout: i.Stdout, Stdout: i.Stdout,
Stderr: i.Stderr, Stderr: i.Stderr,
} }
// get the rootfs from the snapshotter and add it to the request if c.c.RootFS != "" {
mounts, err := c.client.SnapshotService().Mounts(ctx, c.c.RootFS) // get the rootfs from the snapshotter and add it to the request
if err != nil { mounts, err := c.client.SnapshotService().Mounts(ctx, c.c.RootFS)
return nil, err if err != nil {
} return nil, err
for _, m := range mounts { }
request.Rootfs = append(request.Rootfs, &mount.Mount{ for _, m := range mounts {
Type: m.Type, request.Rootfs = append(request.Rootfs, &mount.Mount{
Source: m.Source, Type: m.Type,
Options: m.Options, Source: m.Source,
}) Options: m.Options,
})
}
} }
response, err := c.client.TaskService().Create(ctx, request) response, err := c.client.TaskService().Create(ctx, request)
if err != nil { if err != nil {

View File

@ -7,6 +7,7 @@ import (
func TestContainerList(t *testing.T) { func TestContainerList(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip()
return return
} }
client, err := New(defaultAddress) client, err := New(defaultAddress)
@ -27,6 +28,7 @@ func TestContainerList(t *testing.T) {
func TestNewContainer(t *testing.T) { func TestNewContainer(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip()
return return
} }
client, err := New(defaultAddress) client, err := New(defaultAddress)

View File

@ -3,6 +3,7 @@ package containerd
import "github.com/containerd/containerd/images" import "github.com/containerd/containerd/images"
type Image interface { type Image interface {
Name() string
} }
var _ = (Image)(&image{}) var _ = (Image)(&image{})
@ -12,3 +13,7 @@ type image struct {
i images.Image i images.Image
} }
func (i *image) Name() string {
return i.i.Name
}

12
spec.go
View File

@ -4,17 +4,7 @@ import specs "github.com/opencontainers/runtime-spec/specs-go"
type SpecOpts func(s *specs.Spec) error type SpecOpts func(s *specs.Spec) error
func WithImageRef(ref string) SpecOpts { func WithProcessArgs(args ...string) SpecOpts {
return func(s *specs.Spec) error {
if s.Annotations == nil {
s.Annotations = make(map[string]string)
}
s.Annotations["image"] = ref
return nil
}
}
func WithArgs(args ...string) SpecOpts {
return func(s *specs.Spec) error { return func(s *specs.Spec) error {
s.Process.Args = args s.Process.Args = args
return nil return nil

View File

@ -14,6 +14,8 @@ import (
"github.com/containerd/fifo" "github.com/containerd/fifo"
) )
const UnknownExitStatus = 255
type IO struct { type IO struct {
Terminal bool Terminal bool
Stdin string Stdin string
@ -230,12 +232,12 @@ func (t *task) Status(ctx context.Context) (string, error) {
func (t *task) Wait(ctx context.Context) (uint32, error) { func (t *task) Wait(ctx context.Context) (uint32, error) {
events, err := t.client.TaskService().Events(ctx, &execution.EventsRequest{}) events, err := t.client.TaskService().Events(ctx, &execution.EventsRequest{})
if err != nil { if err != nil {
return 255, err return UnknownExitStatus, err
} }
for { for {
e, err := events.Recv() e, err := events.Recv()
if err != nil { if err != nil {
return 255, err return UnknownExitStatus, err
} }
if e.Type != taskapi.Event_EXIT { if e.Type != taskapi.Event_EXIT {
continue continue
@ -255,7 +257,7 @@ func (t *task) Delete(ctx context.Context) (uint32, error) {
ContainerID: t.containerID, ContainerID: t.containerID,
}) })
if err != nil { if err != nil {
return 255, err return UnknownExitStatus, err
} }
return r.ExitStatus, cerr return r.ExitStatus, cerr
} }