Skip to content

Commit

Permalink
Add initial containerd *Client
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
  • Loading branch information
crosbymichael committed May 24, 2017
1 parent 17033dc commit d0e5732
Show file tree
Hide file tree
Showing 10 changed files with 482 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/bin/
**/coverage.txt
**/coverage.out
containerd.test
61 changes: 61 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package containerd

import (
"context"
"io/ioutil"
"log"
"time"

"github.com/containerd/containerd/api/services/containers"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
)

// New returns a new containerd client that is connected to the containerd
// instance provided by address
func New(address string) (*Client, error) {
// reset the grpc logger so that it does not output in the STDIO of the calling process
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))

opts := []grpc.DialOption{
grpc.WithInsecure(),
grpc.WithTimeout(100 * time.Second),
grpc.WithDialer(dialer),
}
conn, err := grpc.Dial(dialAddress(address), opts...)
if err != nil {
return nil, errors.Wrapf(err, "failed to dial %q", address)
}
return &Client{
conn: conn,
}, nil
}

// Client is the client to interact with containerd and its various services
// using a uniform interface
type Client struct {
conn *grpc.ClientConn
}

// Containers returns all containers created in containerd
func (c *Client) Containers(ctx context.Context) ([]*Container, error) {
r, err := c.containers().List(ctx, &containers.ListContainersRequest{})
if err != nil {
return nil, err
}
var out []*Container
for _, container := range r.Containers {
out = append(out, containerFromProto(c, container))
}
return out, nil
}

// Close closes the clients connection to containerd
func (c *Client) Close() error {
return c.conn.Close()
}

func (c *Client) containers() containers.ContainersClient {
return containers.NewContainersClient(c.conn)
}
18 changes: 18 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package containerd

import "testing"

const defaultAddress = "/run/containerd/containerd.sock"

func TestNewClient(t *testing.T) {
client, err := New(defaultAddress)
if err != nil {
t.Fatal(err)
}
if client == nil {
t.Fatal("New() returned nil client")
}
if err := client.Close(); err != nil {
t.Errorf("client closed returned errror %v", err)
}
}
17 changes: 17 additions & 0 deletions client_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package containerd

import (
"fmt"
"net"
"strings"
"time"
)

func dialer(address string, timeout time.Duration) (net.Conn, error) {
address = strings.TrimPrefix(address, "unix://")
return net.DialTimeout("unix", address, timeout)
}

func dialAddress(address string) string {
return fmt.Sprintf("unix://%s", address)
}
16 changes: 16 additions & 0 deletions client_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package containerd

import (
"net"
"time"

winio "github.com/Microsoft/go-winio"
)

func dialer(address string, timeout time.Duration) (net.Conn, error) {
return winio.DialPipe(bindAddress, &timeout)
}

func dialAddress(address string) string {
return address
}
21 changes: 21 additions & 0 deletions container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package containerd

import "github.com/containerd/containerd/api/services/containers"

func containerFromProto(client *Client, c containers.Container) *Container {
return &Container{
client: client,
id: c.ID,
}
}

type Container struct {
client *Client

id string
}

// ID returns the container's unique id
func (c *Container) ID() string {
return c.id
}
23 changes: 23 additions & 0 deletions container_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package containerd

import (
"context"
"testing"
)

func TestContainerList(t *testing.T) {
client, err := New(defaultAddress)
if err != nil {
t.Fatal(err)
}
defer client.Close()

containers, err := client.Containers(context.Background())
if err != nil {
t.Errorf("container list returned error %v", err)
return
}
if len(containers) != 0 {
t.Errorf("expected 0 containers but received %d", len(containers))
}
}
44 changes: 44 additions & 0 deletions spec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package containerd

import specs "github.com/opencontainers/runtime-spec/specs-go"

type SpecOpts func(s *specs.Spec) error

func WithImageRef(ref 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 WithHostname(id string) SpecOpts {
return func(s *specs.Spec) error {
s.Hostname = id
return nil
}
}

func WithArgs(args ...string) SpecOpts {
return func(s *specs.Spec) error {
s.Process.Args = args
return nil
}
}

// GenerateSpec will generate a default spec from the provided image
// for use as a containerd container
func GenerateSpec(opts ...SpecOpts) (*specs.Spec, error) {
s, err := createDefaultSpec()
if err != nil {
return nil, err
}
for _, o := range opts {
if err := o(s); err != nil {
return nil, err
}
}
return s, nil
}
Loading

0 comments on commit d0e5732

Please sign in to comment.