230 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package containerd
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"io"
 | |
| 
 | |
| 	snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1"
 | |
| 	"github.com/containerd/containerd/api/types"
 | |
| 	"github.com/containerd/containerd/errdefs"
 | |
| 	"github.com/containerd/containerd/mount"
 | |
| 	"github.com/containerd/containerd/snapshots"
 | |
| 	protobuftypes "github.com/gogo/protobuf/types"
 | |
| )
 | |
| 
 | |
| // NewSnapshotterFromClient returns a new Snapshotter which communicates
 | |
| // over a GRPC connection.
 | |
| func NewSnapshotterFromClient(client snapshotsapi.SnapshotsClient, snapshotterName string) snapshots.Snapshotter {
 | |
| 	return &remoteSnapshotter{
 | |
| 		client:          client,
 | |
| 		snapshotterName: snapshotterName,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type remoteSnapshotter struct {
 | |
| 	client          snapshotsapi.SnapshotsClient
 | |
| 	snapshotterName string
 | |
| }
 | |
| 
 | |
| func (r *remoteSnapshotter) Stat(ctx context.Context, key string) (snapshots.Info, error) {
 | |
| 	resp, err := r.client.Stat(ctx,
 | |
| 		&snapshotsapi.StatSnapshotRequest{
 | |
| 			Snapshotter: r.snapshotterName,
 | |
| 			Key:         key,
 | |
| 		})
 | |
| 	if err != nil {
 | |
| 		return snapshots.Info{}, errdefs.FromGRPC(err)
 | |
| 	}
 | |
| 	return toInfo(resp.Info), nil
 | |
| }
 | |
| 
 | |
| func (r *remoteSnapshotter) Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error) {
 | |
| 	resp, err := r.client.Update(ctx,
 | |
| 		&snapshotsapi.UpdateSnapshotRequest{
 | |
| 			Snapshotter: r.snapshotterName,
 | |
| 			Info:        fromInfo(info),
 | |
| 			UpdateMask: &protobuftypes.FieldMask{
 | |
| 				Paths: fieldpaths,
 | |
| 			},
 | |
| 		})
 | |
| 	if err != nil {
 | |
| 		return snapshots.Info{}, errdefs.FromGRPC(err)
 | |
| 	}
 | |
| 	return toInfo(resp.Info), nil
 | |
| }
 | |
| 
 | |
| func (r *remoteSnapshotter) Usage(ctx context.Context, key string) (snapshots.Usage, error) {
 | |
| 	resp, err := r.client.Usage(ctx, &snapshotsapi.UsageRequest{
 | |
| 		Snapshotter: r.snapshotterName,
 | |
| 		Key:         key,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return snapshots.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, &snapshotsapi.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 ...snapshots.Opt) ([]mount.Mount, error) {
 | |
| 	var local snapshots.Info
 | |
| 	for _, opt := range opts {
 | |
| 		if err := opt(&local); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 	resp, err := r.client.Prepare(ctx, &snapshotsapi.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 ...snapshots.Opt) ([]mount.Mount, error) {
 | |
| 	var local snapshots.Info
 | |
| 	for _, opt := range opts {
 | |
| 		if err := opt(&local); err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 	resp, err := r.client.View(ctx, &snapshotsapi.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 ...snapshots.Opt) error {
 | |
| 	var local snapshots.Info
 | |
| 	for _, opt := range opts {
 | |
| 		if err := opt(&local); err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 	_, err := r.client.Commit(ctx, &snapshotsapi.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, &snapshotsapi.RemoveSnapshotRequest{
 | |
| 		Snapshotter: r.snapshotterName,
 | |
| 		Key:         key,
 | |
| 	})
 | |
| 	return errdefs.FromGRPC(err)
 | |
| }
 | |
| 
 | |
| func (r *remoteSnapshotter) Walk(ctx context.Context, fn func(context.Context, snapshots.Info) error) error {
 | |
| 	sc, err := r.client.List(ctx, &snapshotsapi.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 snapshotsapi.Kind) snapshots.Kind {
 | |
| 	if kind == snapshotsapi.KindActive {
 | |
| 		return snapshots.KindActive
 | |
| 	}
 | |
| 	if kind == snapshotsapi.KindView {
 | |
| 		return snapshots.KindView
 | |
| 	}
 | |
| 	return snapshots.KindCommitted
 | |
| }
 | |
| 
 | |
| func toInfo(info snapshotsapi.Info) snapshots.Info {
 | |
| 	return snapshots.Info{
 | |
| 		Name:    info.Name,
 | |
| 		Parent:  info.Parent,
 | |
| 		Kind:    toKind(info.Kind),
 | |
| 		Created: info.CreatedAt,
 | |
| 		Updated: info.UpdatedAt,
 | |
| 		Labels:  info.Labels,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func toUsage(resp *snapshotsapi.UsageResponse) snapshots.Usage {
 | |
| 	return snapshots.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 snapshots.Kind) snapshotsapi.Kind {
 | |
| 	if kind == snapshots.KindActive {
 | |
| 		return snapshotsapi.KindActive
 | |
| 	}
 | |
| 	if kind == snapshots.KindView {
 | |
| 		return snapshotsapi.KindView
 | |
| 	}
 | |
| 	return snapshotsapi.KindCommitted
 | |
| }
 | |
| 
 | |
| func fromInfo(info snapshots.Info) snapshotsapi.Info {
 | |
| 	return snapshotsapi.Info{
 | |
| 		Name:      info.Name,
 | |
| 		Parent:    info.Parent,
 | |
| 		Kind:      fromKind(info.Kind),
 | |
| 		CreatedAt: info.Created,
 | |
| 		UpdatedAt: info.Updated,
 | |
| 		Labels:    info.Labels,
 | |
| 	}
 | |
| }
 | 
