Skip to content

Commit a78d0bd

Browse files
committed
Update the content interface to return info from update
Namespace keys used by client for uncompressed Signed-off-by: Derek McGowan <derek@mcgstyle.net>
1 parent 4f388e0 commit a78d0bd

File tree

10 files changed

+308
-171
lines changed

10 files changed

+308
-171
lines changed

api/services/content/v1/content.pb.go

Lines changed: 229 additions & 95 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/services/content/v1/content.proto

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ service Content {
2222
// This call can be used to manage the mutable content labels. The
2323
// immutable metadata such as digest, size, and committed at cannot
2424
// be updated.
25-
rpc Update(UpdateRequest) returns (google.protobuf.Empty);
25+
rpc Update(UpdateRequest) returns (UpdateResponse);
2626

2727
// List streams the entire set of content as Info objects and closes the
2828
// stream.
@@ -111,6 +111,10 @@ message UpdateRequest {
111111
google.protobuf.FieldMask update_mask = 2;
112112
}
113113

114+
message UpdateResponse {
115+
Info info = 1 [(gogoproto.nullable) = false];
116+
}
117+
114118
message ListContentRequest {
115119
// Filters contains one or more filters using the syntax defined in the
116120
// containerd filter package.

cmd/dist/labels.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"strings"
66

7+
"github.com/containerd/containerd/content"
78
digest "github.com/opencontainers/go-digest"
89
"github.com/urfave/cli"
910
)
@@ -16,8 +17,7 @@ var labelCommand = cli.Command{
1617
Flags: []cli.Flag{},
1718
Action: func(context *cli.Context) error {
1819
var (
19-
object = context.Args().First()
20-
labelArgs = context.Args().Tail()
20+
object, labels = objectWithLabelArgs(context)
2121
)
2222
ctx, cancel := appContext(context)
2323
defer cancel()
@@ -32,32 +32,36 @@ var labelCommand = cli.Command{
3232
return err
3333
}
3434

35-
info, err := cs.Info(ctx, dgst)
36-
if err != nil {
37-
return err
38-
}
39-
40-
if info.Labels == nil {
41-
info.Labels = map[string]string{}
35+
info := content.Info{
36+
Digest: dgst,
37+
Labels: map[string]string{},
4238
}
4339

4440
var paths []string
45-
for _, arg := range labelArgs {
46-
var k, v string
47-
if idx := strings.IndexByte(arg, '='); idx > 0 {
48-
k = arg[:idx]
49-
v = arg[idx+1:]
50-
} else {
51-
k = arg
52-
}
41+
for k, v := range labels {
5342
paths = append(paths, fmt.Sprintf("labels.%s", k))
54-
if v == "" {
55-
delete(info.Labels, k)
56-
} else {
43+
if v != "" {
5744
info.Labels[k] = v
5845
}
5946
}
6047

61-
return cs.Update(ctx, info, paths...)
48+
// Nothing updated, do no clear
49+
if len(paths) == 0 {
50+
info, err = cs.Info(ctx, info.Digest)
51+
} else {
52+
info, err = cs.Update(ctx, info, paths...)
53+
}
54+
if err != nil {
55+
return err
56+
}
57+
58+
var labelStrings []string
59+
for k, v := range info.Labels {
60+
labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v))
61+
}
62+
63+
fmt.Println(strings.Join(labelStrings, ","))
64+
65+
return nil
6266
},
6367
}

content/content.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type Manager interface {
6060
// fields will be updated.
6161
// Mutable fields:
6262
// labels.*
63-
Update(ctx context.Context, info Info, fieldpaths ...string) error
63+
Update(ctx context.Context, info Info, fieldpaths ...string) (Info, error)
6464

6565
// Walk will call fn for each item in the content store which
6666
// match the provided filters. If no filters are given all

content/store.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ func (cs *store) Delete(ctx context.Context, dgst digest.Digest) error {
9393
return nil
9494
}
9595

96-
func (cs *store) Update(ctx context.Context, info Info, fieldpaths ...string) error {
96+
func (cs *store) Update(ctx context.Context, info Info, fieldpaths ...string) (Info, error) {
9797
// TODO: Support persisting and updating mutable content data
98-
return errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store")
98+
return Info{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store")
9999
}
100100

101101
func (cs *store) Walk(ctx context.Context, fn WalkFunc, filters ...string) error {

image.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ func (i *image) Unpack(ctx context.Context, snapshotterName string) error {
5757
if err != nil {
5858
return err
5959
}
60-
if info.Labels["uncompressed"] != layer.Diff.Digest.String() {
60+
if info.Labels["containerd.io/uncompressed"] != layer.Diff.Digest.String() {
6161
if info.Labels == nil {
6262
info.Labels = map[string]string{}
6363
}
64-
info.Labels["uncompressed"] = layer.Diff.Digest.String()
65-
if err := cs.Update(ctx, info, "labels.uncompressed"); err != nil {
64+
info.Labels["containerd.io/uncompressed"] = layer.Diff.Digest.String()
65+
if _, err := cs.Update(ctx, info, "labels.containerd.io/uncompressed"); err != nil {
6666
return err
6767
}
6868
}

metadata/adaptors.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,25 @@ func adaptContainer(o interface{}) filters.Adaptor {
7070
})
7171
}
7272

73+
func adaptContentInfo(info content.Info) filters.Adaptor {
74+
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
75+
if len(fieldpath) == 0 {
76+
return "", false
77+
}
78+
79+
switch fieldpath[0] {
80+
case "digest":
81+
return info.Digest.String(), true
82+
case "size":
83+
// TODO: support size based filtering
84+
case "labels":
85+
return checkMap(fieldpath[1:], info.Labels)
86+
}
87+
88+
return "", false
89+
})
90+
}
91+
7392
func adaptContentStatus(status content.Status) filters.Adaptor {
7493
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
7594
if len(fieldpath) == 0 {

metadata/content.go

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,21 @@ func (cs *contentStore) Info(ctx context.Context, dgst digest.Digest) (content.I
5252
return info, nil
5353
}
5454

55-
func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpaths ...string) error {
55+
func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) {
5656
ns, err := namespaces.NamespaceRequired(ctx)
5757
if err != nil {
58-
return err
58+
return content.Info{}, err
5959
}
6060

61+
updated := content.Info{
62+
Digest: info.Digest,
63+
}
6164
if err := update(ctx, cs.db, func(tx *bolt.Tx) error {
6265
bkt := getBlobBucket(tx, ns, info.Digest)
6366
if bkt == nil {
6467
return errors.Wrapf(errdefs.ErrNotFound, "content digest %v", info.Digest)
6568
}
6669

67-
updated := content.Info{
68-
Digest: info.Digest,
69-
}
70-
7170
if err := readInfo(&updated, bkt); err != nil {
7271
return errors.Wrapf(err, "info %q", info.Digest)
7372
}
@@ -92,16 +91,16 @@ func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpath
9291
}
9392
}
9493
} else {
95-
info.CommittedAt = updated.CommittedAt
96-
updated = info
94+
// Set mutable fields
95+
updated.Labels = info.Labels
9796
}
9897

9998
updated.UpdatedAt = time.Now().UTC()
10099
return writeInfo(&updated, bkt)
101100
}); err != nil {
102-
return err
101+
return content.Info{}, err
103102
}
104-
return nil
103+
return updated, nil
105104
}
106105

107106
func (cs *contentStore) Walk(ctx context.Context, fn content.WalkFunc, fs ...string) error {
@@ -110,17 +109,9 @@ func (cs *contentStore) Walk(ctx context.Context, fn content.WalkFunc, fs ...str
110109
return err
111110
}
112111

113-
var filter filters.Filter = filters.Always
114-
if len(fs) > 0 {
115-
fa := make([]filters.Filter, 0, len(fs))
116-
for _, s := range fs {
117-
f, err := filters.Parse(s)
118-
if err != nil {
119-
return errors.Wrapf(errdefs.ErrInvalidArgument, "bad filter %q", s)
120-
}
121-
fa = append(fa, f)
122-
}
123-
filter = filters.Filter(filters.Any(fa))
112+
filter, err := filters.ParseAll(fs...)
113+
if err != nil {
114+
return err
124115
}
125116

126117
// TODO: Batch results to keep from reading all info into memory
@@ -481,22 +472,3 @@ func writeInfo(info *content.Info, bkt *bolt.Bucket) error {
481472

482473
return nil
483474
}
484-
485-
func adaptContentInfo(info content.Info) filters.Adaptor {
486-
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
487-
if len(fieldpath) == 0 {
488-
return "", false
489-
}
490-
491-
switch fieldpath[0] {
492-
case "digest":
493-
return info.Digest.String(), true
494-
case "size":
495-
// TODO: support size based filtering
496-
case "labels":
497-
return checkMap(fieldpath[1:], info.Labels)
498-
}
499-
500-
return "", false
501-
})
502-
}

services/content/service.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,19 @@ func (s *Service) Info(ctx context.Context, req *api.InfoRequest) (*api.InfoResp
8383
}, nil
8484
}
8585

86-
func (s *Service) Update(ctx context.Context, req *api.UpdateRequest) (*empty.Empty, error) {
86+
func (s *Service) Update(ctx context.Context, req *api.UpdateRequest) (*api.UpdateResponse, error) {
8787
if err := req.Info.Digest.Validate(); err != nil {
8888
return nil, grpc.Errorf(codes.InvalidArgument, "%q failed validation", req.Info.Digest)
8989
}
9090

91-
if err := s.store.Update(ctx, infoFromGRPC(req.Info), req.UpdateMask.GetPaths()...); err != nil {
91+
info, err := s.store.Update(ctx, infoFromGRPC(req.Info), req.UpdateMask.GetPaths()...)
92+
if err != nil {
9293
return nil, errdefs.ToGRPC(err)
9394
}
9495

95-
return &empty.Empty{}, nil
96+
return &api.UpdateResponse{
97+
Info: infoToGRPC(info),
98+
}, nil
9699
}
97100

98101
func (s *Service) List(req *api.ListContentRequest, session api.Content_ListServer) error {

services/content/store.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,17 @@ func (rs *remoteStore) Status(ctx context.Context, ref string) (content.Status,
108108
}, nil
109109
}
110110

111-
func (rs *remoteStore) Update(ctx context.Context, info content.Info, fieldpaths ...string) error {
112-
if _, err := rs.client.Update(ctx, &contentapi.UpdateRequest{
111+
func (rs *remoteStore) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) {
112+
resp, err := rs.client.Update(ctx, &contentapi.UpdateRequest{
113113
Info: infoToGRPC(info),
114114
UpdateMask: &protobuftypes.FieldMask{
115115
Paths: fieldpaths,
116116
},
117-
}); err != nil {
118-
return errdefs.FromGRPC(err)
117+
})
118+
if err != nil {
119+
return content.Info{}, errdefs.FromGRPC(err)
119120
}
120-
return nil
121+
return infoFromGRPC(resp.Info), nil
121122
}
122123

123124
func (rs *remoteStore) ListStatuses(ctx context.Context, filters ...string) ([]content.Status, error) {

0 commit comments

Comments
 (0)