api, metadata: use map type for Container.Extensions

To allow for updating extensions without collisions, we have moved to
using a map type that can be explicitly selected via the field path for
updates. This ensures that multiple parties can operate on their
extensions without stepping on each other's toes or incurring an
inordinate number of round trips.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day
2017-09-08 14:51:30 -07:00
parent 3552ce5688
commit f7d31e2be4
9 changed files with 349 additions and 123 deletions

View File

@@ -135,13 +135,20 @@ func setSnapshotterIfEmpty(c *containers.Container) {
// Make sure to register the type of `extension` in the typeurl package via
// `typeurl.Register` otherwise the type data will be inferred, including how
// to encode and decode the object.
func WithContainerExtension(extension interface{}) NewContainerOpts {
func WithContainerExtension(name string, extension interface{}) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
any, err := typeurl.MarshalAny(extension)
if err != nil {
return err
}
c.Extensions = append(c.Extensions, *any)
if name == "" {
return errors.Wrapf(errdefs.ErrInvalidArgument, "extension key must not be zero-length")
}
if c.Extensions == nil {
c.Extensions = make(map[string]types.Any)
}
c.Extensions[name] = *any
return nil
}
}