registry.json: Add error response schema following the current description

From [1]:

> Errors
>
> Actionable failure conditions, covered in detail in their relevant
> sections, will be reported as part of 4xx responses, in a json
> response body. One or more errors will be returned in the following
> format:
>
> {
>   "errors:" [
>     {
>       "code": <error identifier>,
>       "message": <message describing condition>,
>       "detail": <unstructured>
>     },
>     ...
>   ]
> }
>
> The code field will be a unique identifier, all caps with
> underscores by convention. The message field will be a human
> readable string. The optional detail field may contain arbitrary
> json data providing information the client can use to resolve the
> issue.
>
> While the client can take action on certain error codes, the
> registry may add new error codes over time. All client
> implementations should treat unknown error codes as UNKNOWN,
> allowing future error codes to be added without breaking API
> compatibility. For the purposes of the specification error codes
> will only be added and never removed.  API Version Check

And then for DELETE /v2/<name>/blobs/uploads/<uuid>:

> Errors
>
> If an 502, 503 or 504 error is received, the client should assume
> that the download can proceed due to a temporary condition, honoring
> the appropriate retry mechanism. Other 5xx errors should be treated
> as terminal.
>
> If there is a problem with the upload, a 4xx error will be returned
> indicating the problem. After receiving a 4xx response (except 416,
> as called out above), the upload will be considered failed and the
> client should take appropriate action.
>
> The following table covers the various error conditions that may be
> returned after completing a layer upload:
>
> Code             Message
> INVALID_DIGEST   provided digest did not match uploaded content
> INVALID_LENGTH   provided size did not match content size
>
> Note that the upload url will not be available forever. If the
> upload uuid is unknown to the registry, a 404 Not Found response
> will be returned and the client must restart the upload process.

And for PUT /v2/<name>/manifests/<tag>:

> If there is a problem with pushing the manifest, a relevant 4xx
> response will be returned with a JSON error message. The following
> table covers the various error conditions and their corresponding
> codes:
>
> Code                  Message
> INVALID_NAME          Manifest name did not match URI
> INVALID_TAG           Manifest tag did not match URI
> UNVERIFIED_MANIFEST   Manifest failed signature validation
> UNKNOWN_LAYER         Referenced layer not available
> UNTRUSTED_SIGNATURE   Manifest signed by untrusted source
>
> For the UNKNOWN_LAYER error, the detail field of the error response
> will have an "unknown" field with information about the missing
> layer. For now, that will just be the tarsum. There will be an error
> returned for each unknown blob. The response format will be as
> follows:
>
> {
>   "errors:" [
>     {
>       "code": "UNKNOWN_LAYER",
>       "message": "Referenced layer not available",
>       "detail": {
>         "unknown": {
>           "blobSum": <tarsum>
>         }
>       }
>     },
>     ...
>   ]
> }

For now I've just rolled the two sets of enumerated codes into a
single type, and skipped the

  "unknown": {
    "blobSum": <tarsum>
  }

information that's required for the UNKNOWN_LAYER error.  We can split
these out later if we want to be more explicit.

I asked [2] Stephen about why we return

  {
    "errors": [...array of errors...]
  }

instead of:

  [...array of errors...]

and he explained that the wrapping object is to provide space for
future extensions like debugging data [3].  Major version bumps are
awkward, so anything that allows us to improve the API without
breaking backward compatibility is good :).

[1]: https://github.com/docker/docker/issues/9015
[2]: https://github.com/docker/docker/issues/9015#issuecomment-66549204
[3]: https://github.com/docker/docker/issues/9015#issuecomment-66550787
registry.json: Specify GET /

From [1]:

> API Version Check
>
> A minimal endpoint, mounted at /v2/ will provide version support
> information based on its response statuses. The request format is as
> follows:
>
> GET /v2/
>
> If a 200 OK response is returned, the registry implements the V2(.1)
> registry API and the client may proceed safely with other V2
> operations. Optionally, the response may contain information about
> the supported paths in the response body. The client should be
> prepared to ignore this data.
>
> If a 401 Unauthorized response is returned, the client should take
> action based on the contents of the "WWW-Authenticate" header and
> try the endpoint again. Depending on access control setup, the
> client may still have to authenticate against different resources,
> even if this check succeeds.
>
> If 404 Not Found response status, or other unexpected status, is
> returned, the client should proceed with the assumption that the
> registry does not implement V2 of the API.

I've dropped the 401 / WWW-Authenticate business, because that's
standard HTTP.  Eventually we'll want a schema for the "information
about the supported paths", but we don't have that now, so I've left
it open.

I've added a 'meta' tag for this sort of API-management endpoint.

[1]: https://github.com/docker/docker/issues/9015
registry.json: Add manifest schema, with layerMetadata and signature

From [1]:

> For reference, the relevant manifest fields for the registry are the
> following:
>
> field      description
> name       The name of the image.
> tag        The tag for this version of the image.
> fsLayers   A list of layer descriptors (including tarsum)
> signature  A JWS used to verify the manifest content
>
> For more information about the manifest format, please see
> docker/docker#8093.

And from [2]:

> Image Manifest
>
> The image manifest file will contain all the information which is
> needed to pull, install, validate and run an image. It will contain
> a list of layers by a content addressable id, history, run time
> configuration, and signatures.  This manifest is generated by the
> daemon. Initially this generation will happen when an image is
> published, and ultimately happen anytime an image is built or
> committed. Each manifest is required to be signed by the client
> creating the manifest on push or build with additional signatures
> which can be added post build to verify the quality of the manifest
> or validity of the builder. The history will contain fully backward
> compatible metadata to allow old style layer and metadata to be
> recreated from the manifest.
>
> Signable manifest (or payload) refers to portions of the manifest
> which will be signed by builder. The signable manifest is a JSON
> dictionary containing the layers, run configuration, and
> history. The entire signable manifest will signed, any changes
> including whitespace will require a new signature. To aid in
> readability the signable manifest should be well-formatted JSON.
>
> Example: (totally subject to change)
>
> {
>   "name": "dmcgowan/test-image",
>   "tag": "latest",
>   "architecture": "amd64",
>   "fsLayers": [
>     {
>       "blobSum": "tarsum+sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
>     },
>     {
>       "blobSum": "tarsum+sha256:cea0d2071b01b0a79aa4a05ea56ab6fdf3fafa03369d9f4eea8d46ea33c43e5f",
>     },
>     {
>       "blobSum": "tarsum+sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
>     },
>     {
>       "blobSum": "tarsum+sha256:2a7812e636235448785062100bb9103096aa6655a8f6bb9ac9b13fe8290f66df"
>     }
>  ],
>  "history": [
>    "{\"id\":\"a9eb172552348a9a49180694790b33a1097f546456d041b6e82e4d7716ddb721\",\"parent\":\"120e218dd395ec314e7b6249f39d2853911b3d6def6ea164ae05722649f34b16\",\"created\":\"2014-06-05T00:05:35.990887725Z\"...",
>    "{\"id\":\"120e218dd395ec314e7b6249f39d2853911b3d6def6ea164ae05722649f34b16\",\"parent\":\"42eed7f1bf2ac3f1610c5e616d2ab1ee9c7290234240388d6297bc0f32c34229\",\"created\":\"2014-06-05T00:05:35.692528634Z\"...",
>    "{\"id\":\"42eed7f1bf2ac3f1610c5e616d2ab1ee9c7290234240388d6297bc0f32c34229\",\"parent\":\"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158\",\"created\":\"2014-06-05T00:05:35.589531476Z\"...",
>    "{\"id\":\"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158\",\"comment\":\"Imported from -\",\"created\":\"2013-06-13T14:03:50.821769-07:00\"..."
>  ],
>  "schemaVersion": 1
> }
>
> Signed manifest refers to a manifest which includes the signature as
> well as the signable manifest. The signed manifest could be
> represented as either a JSON Web Signature (JSON serialization, see
> link), in which the payload is the base64 encoded signed manifest,
> or an altered version of the signed manifest JSON to include the
> signature as the last element of the JSON dictionary and a record of
> the alternations to the original signed manifest included in the
> signature. EIther format is fully verifiable and tamper-proof.
>
> http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-7.2
>
> Example: (human readable format)
>
> {
>   "name": "dmcgowan/test-image",
>   "tag": "latest",
>   "architecture": "amd64",
>   "blobSums": [
>     {
>       "blobSum": "tarsum+sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
>     },
>     {
>       "blobSum": "tarsum+sha256:cea0d2071b01b0a79aa4a05ea56ab6fdf3fafa03369d9f4eea8d46ea33c43e5f",
>     },
>     {
>       "blobSum": "tarsum+sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
>     },
>     {
>       "blobSum": "tarsum+sha256:2a7812e636235448785062100bb9103096aa6655a8f6bb9ac9b13fe8290f66df"
>     }
>   ],
>   "history": ["v1 compatible string encoded json for each layer"],
>   "schemaVersion": 1,
>   "signatures": [
>     {
>       "header": {
>         "jwk": {
>           "crv": "P-256",
>           "kid": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL",
>           "kty": "EC",
>           "x": "Cu_UyxwLgHzE9rvlYSmvVdqYCXY42E9eNhBb0xNv0SQ",
>           "y": "zUsjWJkeKQ5tv7S-hl1Tg71cd-CqnrtiiLxSi6N_yc8"
>         },
>         "alg": "ES256"
>       },
>       "signature": "m3bgdBXZYRQ4ssAbrgj8Kjl7GNgrKQvmCSY-00yzQosKi-8UBrIRrn3Iu5alj82B6u_jNrkGCjEx3TxrfT1rig",
>       "protected": "eyJmb3JtYXRMZW5ndGgiOjYwNjMsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNC0wOS0xMVQxNzoxNDozMFoifQ"
>     }
>   ]
> }

I didn't delve too deeply into the JWS spec [3], just enough to get:

> The following members are defined for use in top-level JSON objects
> used for the JWS JSON Serialization:
>
> payload
>    The "payload" member MUST be present and contain the value
>    BASE64URL(JWS Payload).
> signatures
>    The "signatures" member value MUST be an array of JSON objects.
>    Each object represents a signature or MAC over the JWS Payload and
>    the JWS Protected Header.
>
> The following members are defined for use in the JSON objects that
> are elements of the "signatures" array:
>
> protected
>    The "protected" member MUST be present and contain the value
>    BASE64URL(UTF8(JWS Protected Header)) when the JWS Protected
>    Header value is non-empty; otherwise, it MUST be absent.  These
>    Header Parameter values are integrity protected.
> header
>    The "header" member MUST be present and contain the value JWS
>    Unprotected Header when the JWS Unprotected Header value is non-
>    empty; otherwise, it MUST be absent.  This value is represented as
>    an unencoded JSON object, rather than as a string.  These Header
>    Parameter values are not integrity protected.
> signature
>    The "signature" member MUST be present and contain the value
>    BASE64URL(JWS Signature).
>
> At least one of the "protected" and "header" members MUST be present
> for each signature/MAC computation so that an "alg" Header Parameter
> value is conveyed.

There are some inconsistencies in the Docker issues that I've
arbitrated:

* [1] has 'signature', but [2] has 'signatures'.  I expect this was
  just a typo in [1], since having an array of signatures is mentioned
  multiple times in [2], and nobody suggests having only a single
  signature.  (Sephen confirmed this [4]).

* [2] has 'fsLayers' holding 'blobSum's in the signable manifest, but
  'blobSums' holding 'blobSum's in the signed manifest.  I expect they
  meant 'fsLayers' in both cases, because 'blobSums' is too generic,
  and [1] mentions 'fsLayers'.

I've left the other manifest fields ('architecture', 'history',
'schemaVersion', ...) unspecified, since that's all independent of the
registry API.

[1]: https://github.com/docker/docker/issues/9015
[2]: https://github.com/docker/docker/issues/8093
[3]: http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-7.2
[4]: https://github.com/wking/docker/commit/f083eb10e95d85a4d040da9a8731753e256e263c#commitcomment-8922939
registry.json: Update error codes (e.g. INVALID_DIGEST -> DIGEST_INVALID)

Catch up after [1]:

On Wed, Dec 10, 2014 at 03:48:34PM -0800, Stephen Day wrote:
> Changes:
>
> - Updated error codes based on feedback and implementation
>   discoveries
> - Added full table of all api error codes, their descriptions and
>   encountered statuses

Which added the following to the #9015 summary:

> The error codes encountered via the API are enumerated in the
> following table:

which I've rendered as a list, because the table was too wide to fit
here.

> code: UNKNOWN
> message: unknown error
> description: Generic error returned when the error does not have an API classification.
> HTTP status codes: Any
>
> code: DIGEST_INVALID
> message: provided digest did not match uploaded content
> description: When a blob is uploaded, the registry will check that
>   the content matches the digest provided by the client. The error
>   may include a detail structure with the key "digest", including
>   the invalid digest string. This error may also be returned when a
>   manifest includes an invalid layer digest.
> HTTP status codes: 400, 404
>
> code: SIZE_INVALID
> message: provided length did not match content length
> description: When a layer is uploaded, the provided size will be
>   checked against the uploaded content. If they do not match, this
>   error will be returned.
> HTTP status codes: 400
>
> code: NAME_INVALID
> message: manifest name did not match URI
> description: During a manifest upload, if the name in the manifest
>   does not match the uri name, this error will be returned.
> HTTP status codes: 400, 404
>
> code: TAG_INVALID
> message: manifest tag did not match URI
> description: During a manifest upload, if the tag in the manifest
>   does not match the uri tag, this error will be returned.
> HTTP status codes: 400, 404
>
> code: NAME_UNKNOWN
> message: repository name not known to registry
> description: This is returned if the name used during an operation
>   is unknown to the registry.
> HTTP status codes: 404
>
> code: MANIFEST_UNKNOWN
> message: manifest unknown
> description: This error is returned when the manifest, identified by
>   name and tag is unknown to the repository.
> HTTP status codes: 404
>
> code: MANIFEST_INVALID
> message: manifest invalid
> description: During upload, manifests undergo several checks
>   ensuring validity. If those checks fail, this error may be
>   returned, unless a more specific error is included. The detail
>   will contain information the failed validation.
> HTTP status codes: 400
>
> code: MANIFEST_UNVERIFIED
> message: manifest failed signature verification
> description: During manifest upload, if the manifest fails signature
>   verification, this error will be returned.
> HTTP status codes: 400
>
> code: BLOB_UNKNOWN
> message: blob unknown to registry
> description: This error may be returned when a blob is unknown to
>   the registry in a specified repository. This can be returned with
>   a standard get or if a manifest references an unknown layer during
>   upload.
> HTTP status codes: 400, 404
>
> code: BLOB_UPLOAD_UNKNOWN
> message: blob upload unknown to registry
> description: If a blob upload has been cancelled or was never
>   started, this error code may be returned.
> HTTP status codes: 404
>
> While the client can take action on certain error codes, the
> registry may add new error codes over time. All client
> implementations should treat unknown error codes as UNKNOWN,
> allowing future error codes to be added without breaking API
> compatibility. For the purposes of the specification error codes
> will only be added and never removed.

Almost everything has an obvious analog in the new list, but
UNTRUSTED_SIGNATURE is gone (rolled into MANIFEST_UNVERIFIED until we
have a better feel for the trust implementation [2]).

[1]: https://github.com/docker/docker/issues/9015#issuecomment-66546536
[2]: https://github.com/docker/docker/issues/9015#issuecomment-66548515