github.com/demonoid81/containerd@v1.3.4/snapshots/proxy/proxy.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package proxy
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  
    23  	snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1"
    24  	"github.com/containerd/containerd/api/types"
    25  	"github.com/containerd/containerd/errdefs"
    26  	"github.com/containerd/containerd/mount"
    27  	"github.com/containerd/containerd/snapshots"
    28  	protobuftypes "github.com/gogo/protobuf/types"
    29  )
    30  
    31  // NewSnapshotter returns a new Snapshotter which communicates over a GRPC
    32  // connection using the containerd snapshot GRPC API.
    33  func NewSnapshotter(client snapshotsapi.SnapshotsClient, snapshotterName string) snapshots.Snapshotter {
    34  	return &proxySnapshotter{
    35  		client:          client,
    36  		snapshotterName: snapshotterName,
    37  	}
    38  }
    39  
    40  type proxySnapshotter struct {
    41  	client          snapshotsapi.SnapshotsClient
    42  	snapshotterName string
    43  }
    44  
    45  func (p *proxySnapshotter) Stat(ctx context.Context, key string) (snapshots.Info, error) {
    46  	resp, err := p.client.Stat(ctx,
    47  		&snapshotsapi.StatSnapshotRequest{
    48  			Snapshotter: p.snapshotterName,
    49  			Key:         key,
    50  		})
    51  	if err != nil {
    52  		return snapshots.Info{}, errdefs.FromGRPC(err)
    53  	}
    54  	return toInfo(resp.Info), nil
    55  }
    56  
    57  func (p *proxySnapshotter) Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error) {
    58  	resp, err := p.client.Update(ctx,
    59  		&snapshotsapi.UpdateSnapshotRequest{
    60  			Snapshotter: p.snapshotterName,
    61  			Info:        fromInfo(info),
    62  			UpdateMask: &protobuftypes.FieldMask{
    63  				Paths: fieldpaths,
    64  			},
    65  		})
    66  	if err != nil {
    67  		return snapshots.Info{}, errdefs.FromGRPC(err)
    68  	}
    69  	return toInfo(resp.Info), nil
    70  }
    71  
    72  func (p *proxySnapshotter) Usage(ctx context.Context, key string) (snapshots.Usage, error) {
    73  	resp, err := p.client.Usage(ctx, &snapshotsapi.UsageRequest{
    74  		Snapshotter: p.snapshotterName,
    75  		Key:         key,
    76  	})
    77  	if err != nil {
    78  		return snapshots.Usage{}, errdefs.FromGRPC(err)
    79  	}
    80  	return toUsage(resp), nil
    81  }
    82  
    83  func (p *proxySnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) {
    84  	resp, err := p.client.Mounts(ctx, &snapshotsapi.MountsRequest{
    85  		Snapshotter: p.snapshotterName,
    86  		Key:         key,
    87  	})
    88  	if err != nil {
    89  		return nil, errdefs.FromGRPC(err)
    90  	}
    91  	return toMounts(resp.Mounts), nil
    92  }
    93  
    94  func (p *proxySnapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
    95  	var local snapshots.Info
    96  	for _, opt := range opts {
    97  		if err := opt(&local); err != nil {
    98  			return nil, err
    99  		}
   100  	}
   101  	resp, err := p.client.Prepare(ctx, &snapshotsapi.PrepareSnapshotRequest{
   102  		Snapshotter: p.snapshotterName,
   103  		Key:         key,
   104  		Parent:      parent,
   105  		Labels:      local.Labels,
   106  	})
   107  	if err != nil {
   108  		return nil, errdefs.FromGRPC(err)
   109  	}
   110  	return toMounts(resp.Mounts), nil
   111  }
   112  
   113  func (p *proxySnapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
   114  	var local snapshots.Info
   115  	for _, opt := range opts {
   116  		if err := opt(&local); err != nil {
   117  			return nil, err
   118  		}
   119  	}
   120  	resp, err := p.client.View(ctx, &snapshotsapi.ViewSnapshotRequest{
   121  		Snapshotter: p.snapshotterName,
   122  		Key:         key,
   123  		Parent:      parent,
   124  		Labels:      local.Labels,
   125  	})
   126  	if err != nil {
   127  		return nil, errdefs.FromGRPC(err)
   128  	}
   129  	return toMounts(resp.Mounts), nil
   130  }
   131  
   132  func (p *proxySnapshotter) Commit(ctx context.Context, name, key string, opts ...snapshots.Opt) error {
   133  	var local snapshots.Info
   134  	for _, opt := range opts {
   135  		if err := opt(&local); err != nil {
   136  			return err
   137  		}
   138  	}
   139  	_, err := p.client.Commit(ctx, &snapshotsapi.CommitSnapshotRequest{
   140  		Snapshotter: p.snapshotterName,
   141  		Name:        name,
   142  		Key:         key,
   143  		Labels:      local.Labels,
   144  	})
   145  	return errdefs.FromGRPC(err)
   146  }
   147  
   148  func (p *proxySnapshotter) Remove(ctx context.Context, key string) error {
   149  	_, err := p.client.Remove(ctx, &snapshotsapi.RemoveSnapshotRequest{
   150  		Snapshotter: p.snapshotterName,
   151  		Key:         key,
   152  	})
   153  	return errdefs.FromGRPC(err)
   154  }
   155  
   156  func (p *proxySnapshotter) Walk(ctx context.Context, fn func(context.Context, snapshots.Info) error) error {
   157  	sc, err := p.client.List(ctx, &snapshotsapi.ListSnapshotsRequest{
   158  		Snapshotter: p.snapshotterName,
   159  	})
   160  	if err != nil {
   161  		return errdefs.FromGRPC(err)
   162  	}
   163  	for {
   164  		resp, err := sc.Recv()
   165  		if err != nil {
   166  			if err == io.EOF {
   167  				return nil
   168  			}
   169  			return errdefs.FromGRPC(err)
   170  		}
   171  		if resp == nil {
   172  			return nil
   173  		}
   174  		for _, info := range resp.Info {
   175  			if err := fn(ctx, toInfo(info)); err != nil {
   176  				return err
   177  			}
   178  		}
   179  	}
   180  }
   181  
   182  func (p *proxySnapshotter) Close() error {
   183  	return nil
   184  }
   185  
   186  func toKind(kind snapshotsapi.Kind) snapshots.Kind {
   187  	if kind == snapshotsapi.KindActive {
   188  		return snapshots.KindActive
   189  	}
   190  	if kind == snapshotsapi.KindView {
   191  		return snapshots.KindView
   192  	}
   193  	return snapshots.KindCommitted
   194  }
   195  
   196  func toInfo(info snapshotsapi.Info) snapshots.Info {
   197  	return snapshots.Info{
   198  		Name:    info.Name,
   199  		Parent:  info.Parent,
   200  		Kind:    toKind(info.Kind),
   201  		Created: info.CreatedAt,
   202  		Updated: info.UpdatedAt,
   203  		Labels:  info.Labels,
   204  	}
   205  }
   206  
   207  func toUsage(resp *snapshotsapi.UsageResponse) snapshots.Usage {
   208  	return snapshots.Usage{
   209  		Inodes: resp.Inodes,
   210  		Size:   resp.Size_,
   211  	}
   212  }
   213  
   214  func toMounts(mm []*types.Mount) []mount.Mount {
   215  	mounts := make([]mount.Mount, len(mm))
   216  	for i, m := range mm {
   217  		mounts[i] = mount.Mount{
   218  			Type:    m.Type,
   219  			Source:  m.Source,
   220  			Options: m.Options,
   221  		}
   222  	}
   223  	return mounts
   224  }
   225  
   226  func fromKind(kind snapshots.Kind) snapshotsapi.Kind {
   227  	if kind == snapshots.KindActive {
   228  		return snapshotsapi.KindActive
   229  	}
   230  	if kind == snapshots.KindView {
   231  		return snapshotsapi.KindView
   232  	}
   233  	return snapshotsapi.KindCommitted
   234  }
   235  
   236  func fromInfo(info snapshots.Info) snapshotsapi.Info {
   237  	return snapshotsapi.Info{
   238  		Name:      info.Name,
   239  		Parent:    info.Parent,
   240  		Kind:      fromKind(info.Kind),
   241  		CreatedAt: info.Created,
   242  		UpdatedAt: info.Updated,
   243  		Labels:    info.Labels,
   244  	}
   245  }