cmd/dist: port commands over to use GRPC content store

Following from the rest of the work in this branch, we now are porting
the dist command to work directly against the containerd content API.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day 2017-02-17 16:49:59 -08:00
parent 621164bc84
commit e6efb397cf
No known key found for this signature in database
GPG key ID: 67B3DED84EDC823F
6 changed files with 496 additions and 15 deletions

View file

@ -7,6 +7,7 @@ import (
_ "net/http/pprof"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
@ -15,7 +16,9 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/containerd"
contentapi "github.com/docker/containerd/api/services/content"
api "github.com/docker/containerd/api/services/execution"
"github.com/docker/containerd/content"
_ "github.com/docker/containerd/linux"
"github.com/docker/containerd/log"
"github.com/docker/containerd/services/execution"
@ -55,10 +58,6 @@ func main() {
Name: "log-level,l",
Usage: "set the logging level [debug, info, warn, error, fatal, panic]",
},
cli.StringFlag{
Name: "root,r",
Usage: "containerd root directory",
},
cli.StringFlag{
Name: "state",
Usage: "containerd state directory",
@ -90,14 +89,27 @@ func main() {
return err
}
serveMetricsAPI()
contentStore, err := resolveContentStore(context)
if err != nil {
return err
}
contentService := content.NewService(contentStore)
// start the GRPC api with the execution service registered
server := newGRPCServer(execution.New(supervisor))
server := newGRPCServer()
api.RegisterContainerServiceServer(server, execution.New(supervisor))
contentapi.RegisterContentServer(server, contentService)
// start the GRPC api with registered services
if err := serveGRPC(server); err != nil {
return err
}
log.G(global).Infof("containerd successfully booted in %fs", time.Now().Sub(start).Seconds())
return handleSignals(signals, server)
}
if err := app.Run(os.Args); err != nil {
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
os.Exit(1)
@ -192,8 +204,13 @@ func serveDebugAPI() error {
return nil
}
func resolveContentStore(context *cli.Context) (*content.Store, error) {
cp := filepath.Join(conf.Root, "content")
return content.NewStore(cp)
}
func loadRuntimes() (map[string]containerd.Runtime, error) {
o := make(map[string]containerd.Runtime)
o := map[string]containerd.Runtime{}
for _, name := range containerd.Runtimes() {
r, err := containerd.NewRuntime(name, conf.State)
if err != nil {
@ -205,9 +222,8 @@ func loadRuntimes() (map[string]containerd.Runtime, error) {
return o, nil
}
func newGRPCServer(service api.ContainerServiceServer) *grpc.Server {
func newGRPCServer() *grpc.Server {
s := grpc.NewServer(grpc.UnaryInterceptor(interceptor))
api.RegisterContainerServiceServer(s, service)
return s
}

18
cmd/dist/get.go vendored
View file

@ -4,6 +4,8 @@ import (
"io"
"os"
contentapi "github.com/docker/containerd/api/services/content"
"github.com/docker/containerd/content"
digest "github.com/opencontainers/go-digest"
"github.com/urfave/cli"
)
@ -17,17 +19,23 @@ var getCommand = cli.Command{
Output paths can be used to directly access blobs on disk.`,
Flags: []cli.Flag{},
Action: func(context *cli.Context) error {
cs, err := resolveContentStore(context)
if err != nil {
return err
}
var (
ctx = background
)
dgst, err := digest.Parse(context.Args().First())
if err != nil {
return err
}
rc, err := cs.Open(dgst)
conn, err := connectGRPC(context)
if err != nil {
return err
}
cs := content.NewProviderFromClient(contentapi.NewContentClient(conn))
rc, err := cs.Reader(ctx, dgst)
if err != nil {
return err
}

7
cmd/dist/ingest.go vendored
View file

@ -5,6 +5,7 @@ import (
"fmt"
"os"
contentapi "github.com/docker/containerd/api/services/content"
"github.com/docker/containerd/content"
"github.com/opencontainers/go-digest"
"github.com/urfave/cli"
@ -41,7 +42,7 @@ var ingestCommand = cli.Command{
return err
}
cs, err := resolveContentStore(context)
conn, err := connectGRPC(context)
if err != nil {
return err
}
@ -50,9 +51,11 @@ var ingestCommand = cli.Command{
return fmt.Errorf("must specify a transaction reference")
}
ingester := content.NewIngesterFromClient(contentapi.NewContentClient(conn))
// TODO(stevvooe): Allow ingest to be reentrant. Currently, we expect
// all data to be written in a single invocation. Allow multiple writes
// to the same transaction key followed by a commit.
return content.WriteBlob(ctx, cs, os.Stdin, ref, expectedSize, expectedDigest)
return content.WriteBlob(ctx, ingester, os.Stdin, ref, expectedSize, expectedDigest)
},
}

5
cmd/dist/main.go vendored
View file

@ -42,6 +42,11 @@ distribution tool
Usage: "path to content store root",
Value: "/tmp/content", // TODO(stevvooe): for now, just use the PWD/.content
},
cli.StringFlag{
Name: "socket, s",
Usage: "socket path for containerd's GRPC server",
Value: "/run/containerd/containerd.sock",
},
}
app.Commands = []cli.Command{
fetchCommand,