2018-03-19 18:56:51 -04:00
|
|
|
package containerizedengine
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
"github.com/containerd/containerd"
|
|
|
|
"github.com/containerd/containerd/images"
|
|
|
|
"github.com/containerd/containerd/remotes/docker"
|
2018-09-11 08:46:30 -04:00
|
|
|
clitypes "github.com/docker/cli/types"
|
2018-03-19 18:56:51 -04:00
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/pkg/jsonmessage"
|
|
|
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewClient returns a new containerizedengine client
|
|
|
|
// This client can be used to manage the lifecycle of
|
|
|
|
// dockerd running as a container on containerd.
|
2018-09-11 08:46:30 -04:00
|
|
|
func NewClient(sockPath string) (clitypes.ContainerizedClient, error) {
|
2018-03-19 18:56:51 -04:00
|
|
|
if sockPath == "" {
|
|
|
|
sockPath = containerdSockPath
|
|
|
|
}
|
|
|
|
cclient, err := containerd.New(sockPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-09-11 08:46:30 -04:00
|
|
|
return &baseClient{
|
2018-03-19 18:56:51 -04:00
|
|
|
cclient: cclient,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close will close the underlying clients
|
2018-09-11 08:46:30 -04:00
|
|
|
func (c *baseClient) Close() error {
|
2018-03-19 18:56:51 -04:00
|
|
|
return c.cclient.Close()
|
|
|
|
}
|
|
|
|
|
2018-09-11 08:46:30 -04:00
|
|
|
func (c *baseClient) pullWithAuth(ctx context.Context, imageName string, out clitypes.OutStream,
|
2018-03-19 18:56:51 -04:00
|
|
|
authConfig *types.AuthConfig) (containerd.Image, error) {
|
|
|
|
|
|
|
|
resolver := docker.NewResolver(docker.ResolverOptions{
|
|
|
|
Credentials: func(string) (string, string, error) {
|
|
|
|
return authConfig.Username, authConfig.Password, nil
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
ongoing := newJobs(imageName)
|
|
|
|
pctx, stopProgress := context.WithCancel(ctx)
|
|
|
|
progress := make(chan struct{})
|
|
|
|
bufin, bufout := io.Pipe()
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
showProgress(pctx, ongoing, c.cclient.ContentStore(), bufout)
|
|
|
|
}()
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
jsonmessage.DisplayJSONMessagesToStream(bufin, out, nil)
|
|
|
|
close(progress)
|
|
|
|
}()
|
|
|
|
|
|
|
|
h := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
|
|
|
if desc.MediaType != images.MediaTypeDockerSchema1Manifest {
|
|
|
|
ongoing.add(desc)
|
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
})
|
|
|
|
|
|
|
|
image, err := c.cclient.Pull(ctx, imageName,
|
|
|
|
containerd.WithResolver(resolver),
|
|
|
|
containerd.WithImageHandler(h),
|
|
|
|
containerd.WithPullUnpack)
|
|
|
|
stopProgress()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
<-progress
|
|
|
|
return image, nil
|
|
|
|
}
|