230 lines
5.6 KiB
Go
230 lines
5.6 KiB
Go
package containerd
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1"
|
|
"github.com/containerd/containerd/api/types"
|
|
"github.com/containerd/containerd/errdefs"
|
|
"github.com/containerd/containerd/mount"
|
|
"github.com/containerd/containerd/snapshot"
|
|
protobuftypes "github.com/gogo/protobuf/types"
|
|
)
|
|
|
|
// NewSnapshotterFromClient returns a new Snapshotter which communicates
|
|
// over a GRPC connection.
|
|
func NewSnapshotterFromClient(client snapshotapi.SnapshotsClient, snapshotterName string) snapshot.Snapshotter {
|
|
return &remoteSnapshotter{
|
|
client: client,
|
|
snapshotterName: snapshotterName,
|
|
}
|
|
}
|
|
|
|
type remoteSnapshotter struct {
|
|
client snapshotapi.SnapshotsClient
|
|
snapshotterName string
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Stat(ctx context.Context, key string) (snapshot.Info, error) {
|
|
resp, err := r.client.Stat(ctx,
|
|
&snapshotapi.StatSnapshotRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Key: key,
|
|
})
|
|
if err != nil {
|
|
return snapshot.Info{}, errdefs.FromGRPC(err)
|
|
}
|
|
return toInfo(resp.Info), nil
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Update(ctx context.Context, info snapshot.Info, fieldpaths ...string) (snapshot.Info, error) {
|
|
resp, err := r.client.Update(ctx,
|
|
&snapshotapi.UpdateSnapshotRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Info: fromInfo(info),
|
|
UpdateMask: &protobuftypes.FieldMask{
|
|
Paths: fieldpaths,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return snapshot.Info{}, errdefs.FromGRPC(err)
|
|
}
|
|
return toInfo(resp.Info), nil
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Usage(ctx context.Context, key string) (snapshot.Usage, error) {
|
|
resp, err := r.client.Usage(ctx, &snapshotapi.UsageRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Key: key,
|
|
})
|
|
if err != nil {
|
|
return snapshot.Usage{}, errdefs.FromGRPC(err)
|
|
}
|
|
return toUsage(resp), nil
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) {
|
|
resp, err := r.client.Mounts(ctx, &snapshotapi.MountsRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Key: key,
|
|
})
|
|
if err != nil {
|
|
return nil, errdefs.FromGRPC(err)
|
|
}
|
|
return toMounts(resp.Mounts), nil
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshot.Opt) ([]mount.Mount, error) {
|
|
var local snapshot.Info
|
|
for _, opt := range opts {
|
|
if err := opt(&local); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
resp, err := r.client.Prepare(ctx, &snapshotapi.PrepareSnapshotRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Key: key,
|
|
Parent: parent,
|
|
Labels: local.Labels,
|
|
})
|
|
if err != nil {
|
|
return nil, errdefs.FromGRPC(err)
|
|
}
|
|
return toMounts(resp.Mounts), nil
|
|
}
|
|
|
|
func (r *remoteSnapshotter) View(ctx context.Context, key, parent string, opts ...snapshot.Opt) ([]mount.Mount, error) {
|
|
var local snapshot.Info
|
|
for _, opt := range opts {
|
|
if err := opt(&local); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
resp, err := r.client.View(ctx, &snapshotapi.ViewSnapshotRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Key: key,
|
|
Parent: parent,
|
|
Labels: local.Labels,
|
|
})
|
|
if err != nil {
|
|
return nil, errdefs.FromGRPC(err)
|
|
}
|
|
return toMounts(resp.Mounts), nil
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Commit(ctx context.Context, name, key string, opts ...snapshot.Opt) error {
|
|
var local snapshot.Info
|
|
for _, opt := range opts {
|
|
if err := opt(&local); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
_, err := r.client.Commit(ctx, &snapshotapi.CommitSnapshotRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Name: name,
|
|
Key: key,
|
|
Labels: local.Labels,
|
|
})
|
|
return errdefs.FromGRPC(err)
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Remove(ctx context.Context, key string) error {
|
|
_, err := r.client.Remove(ctx, &snapshotapi.RemoveSnapshotRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
Key: key,
|
|
})
|
|
return errdefs.FromGRPC(err)
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Walk(ctx context.Context, fn func(context.Context, snapshot.Info) error) error {
|
|
sc, err := r.client.List(ctx, &snapshotapi.ListSnapshotsRequest{
|
|
Snapshotter: r.snapshotterName,
|
|
})
|
|
if err != nil {
|
|
return errdefs.FromGRPC(err)
|
|
}
|
|
for {
|
|
resp, err := sc.Recv()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return nil
|
|
}
|
|
return errdefs.FromGRPC(err)
|
|
}
|
|
if resp == nil {
|
|
return nil
|
|
}
|
|
for _, info := range resp.Info {
|
|
if err := fn(ctx, toInfo(info)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *remoteSnapshotter) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func toKind(kind snapshotapi.Kind) snapshot.Kind {
|
|
if kind == snapshotapi.KindActive {
|
|
return snapshot.KindActive
|
|
}
|
|
if kind == snapshotapi.KindView {
|
|
return snapshot.KindView
|
|
}
|
|
return snapshot.KindCommitted
|
|
}
|
|
|
|
func toInfo(info snapshotapi.Info) snapshot.Info {
|
|
return snapshot.Info{
|
|
Name: info.Name,
|
|
Parent: info.Parent,
|
|
Kind: toKind(info.Kind),
|
|
Created: info.CreatedAt,
|
|
Updated: info.UpdatedAt,
|
|
Labels: info.Labels,
|
|
}
|
|
}
|
|
|
|
func toUsage(resp *snapshotapi.UsageResponse) snapshot.Usage {
|
|
return snapshot.Usage{
|
|
Inodes: resp.Inodes,
|
|
Size: resp.Size_,
|
|
}
|
|
}
|
|
|
|
func toMounts(mm []*types.Mount) []mount.Mount {
|
|
mounts := make([]mount.Mount, len(mm))
|
|
for i, m := range mm {
|
|
mounts[i] = mount.Mount{
|
|
Type: m.Type,
|
|
Source: m.Source,
|
|
Options: m.Options,
|
|
}
|
|
}
|
|
return mounts
|
|
}
|
|
|
|
func fromKind(kind snapshot.Kind) snapshotapi.Kind {
|
|
if kind == snapshot.KindActive {
|
|
return snapshotapi.KindActive
|
|
}
|
|
if kind == snapshot.KindView {
|
|
return snapshotapi.KindView
|
|
}
|
|
return snapshotapi.KindCommitted
|
|
}
|
|
|
|
func fromInfo(info snapshot.Info) snapshotapi.Info {
|
|
return snapshotapi.Info{
|
|
Name: info.Name,
|
|
Parent: info.Parent,
|
|
Kind: fromKind(info.Kind),
|
|
CreatedAt: info.Created,
|
|
UpdatedAt: info.Updated,
|
|
Labels: info.Labels,
|
|
}
|
|
}
|