mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Big dependency update, all lowercase sirupsen's for all dependencies.
This commit is contained in:
3
vendor/github.com/opencontainers/image-spec/.gitignore
generated
vendored
Normal file
3
vendor/github.com/opencontainers/image-spec/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/oci-validate-examples
|
||||
output
|
||||
header.html
|
||||
14
vendor/github.com/opencontainers/image-spec/.header
generated
vendored
Normal file
14
vendor/github.com/opencontainers/image-spec/.header
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
27
vendor/github.com/opencontainers/image-spec/.pullapprove.yml
generated
vendored
Normal file
27
vendor/github.com/opencontainers/image-spec/.pullapprove.yml
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
version: 2
|
||||
|
||||
requirements:
|
||||
signed_off_by:
|
||||
required: true
|
||||
|
||||
group_defaults:
|
||||
required: 2
|
||||
approve_by_comment:
|
||||
enabled: true
|
||||
approve_regex: '^(Approved|lgtm|LGTM|:shipit:|:star:|:\+1:|:ship:)'
|
||||
reject_regex: ^Rejected
|
||||
reset_on_push:
|
||||
enabled: true
|
||||
author_approval:
|
||||
ignored: true
|
||||
always_pending:
|
||||
title_regex: ^WIP
|
||||
explanation: 'Work in progress...'
|
||||
conditions:
|
||||
branches:
|
||||
- master
|
||||
|
||||
groups:
|
||||
image-spec:
|
||||
teams:
|
||||
- image-spec-maintainers
|
||||
16
vendor/github.com/opencontainers/image-spec/.tool/check-license
generated
vendored
Executable file
16
vendor/github.com/opencontainers/image-spec/.tool/check-license
generated
vendored
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
ret=0
|
||||
|
||||
for file in $(find . -type f -iname '*.go' ! -path './vendor/*'); do
|
||||
if ! head -n3 "${file}" | grep -Eq "(Copyright|generated|GENERATED)"; then
|
||||
echo "${file}:missing license header"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $ret
|
||||
54
vendor/github.com/opencontainers/image-spec/.tool/genheader.go
generated
vendored
Normal file
54
vendor/github.com/opencontainers/image-spec/.tool/genheader.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2017 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
specs "github.com/opencontainers/image-spec/specs-go"
|
||||
)
|
||||
|
||||
var headerTemplate = template.Must(template.New("gen").Parse(`<title>image-spec {{.Version}}</title>
|
||||
<base href="https://raw.githubusercontent.com/opencontainers/image-spec/{{.Branch}}/">`))
|
||||
|
||||
type Obj struct {
|
||||
Version string
|
||||
Branch string
|
||||
}
|
||||
|
||||
func main() {
|
||||
obj := Obj{
|
||||
Version: specs.Version,
|
||||
Branch: specs.Version,
|
||||
}
|
||||
if strings.HasSuffix(specs.Version, "-dev") {
|
||||
cmd := exec.Command("git", "log", "-1", `--pretty=%H`, "HEAD")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
obj.Branch = strings.Trim(out.String(), " \n\r")
|
||||
}
|
||||
headerTemplate.Execute(os.Stdout, obj)
|
||||
}
|
||||
24
vendor/github.com/opencontainers/image-spec/.tool/lint
generated
vendored
Executable file
24
vendor/github.com/opencontainers/image-spec/.tool/lint
generated
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
if [ ! $(command -v gometalinter) ]; then
|
||||
go get -u github.com/alecthomas/gometalinter
|
||||
gometalinter --install
|
||||
fi
|
||||
|
||||
for d in $(find . -type d -not -iwholename '*.git*' -a -not -iname '.tool' -a -not -iwholename '*vendor*'); do
|
||||
gometalinter \
|
||||
--exclude='error return value not checked.*(Close|Log|Print).*\(errcheck\)$' \
|
||||
--exclude='.*_test\.go:.*error return value not checked.*\(errcheck\)$' \
|
||||
--exclude='duplicate of.*_test.go.*\(dupl\)$' \
|
||||
--exclude='schema/fs.go' \
|
||||
--disable=aligncheck \
|
||||
--disable=gotype \
|
||||
--disable=gas \
|
||||
--cyclo-over=35 \
|
||||
--tests \
|
||||
--deadline=60s "${d}"
|
||||
done
|
||||
28
vendor/github.com/opencontainers/image-spec/.travis.yml
generated
vendored
Normal file
28
vendor/github.com/opencontainers/image-spec/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.7
|
||||
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_script:
|
||||
- export PATH=$HOME/gopath/bin:$PATH
|
||||
|
||||
before_install:
|
||||
- docker pull vbatts/pandoc
|
||||
- make install.tools
|
||||
- go get -u github.com/alecthomas/gometalinter
|
||||
- gometalinter --install
|
||||
- go get -t -d ./...
|
||||
|
||||
install: true
|
||||
|
||||
script:
|
||||
- env | grep TRAVIS_
|
||||
- make .gitvalidation
|
||||
- make lint
|
||||
- make check-license
|
||||
- make test
|
||||
- make docs
|
||||
70
vendor/github.com/opencontainers/image-spec/GOVERNANCE.md
generated
vendored
Normal file
70
vendor/github.com/opencontainers/image-spec/GOVERNANCE.md
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# Project governance
|
||||
|
||||
The [OCI charter][charter] §5.b.viii tasks an OCI Project's maintainers (listed in the repository's MAINTAINERS file and sometimes referred to as "the TDC", [§5.e][charter]) with:
|
||||
|
||||
> Creating, maintaining and enforcing governance guidelines for the TDC, approved by the maintainers, and which shall be posted visibly for the TDC.
|
||||
|
||||
This section describes generic rules and procedures for fulfilling that mandate.
|
||||
|
||||
## Proposing a motion
|
||||
|
||||
A maintainer SHOULD propose a motion on the dev@opencontainers.org mailing list (except [security issues](#security-issues)) with another maintainer as a co-sponsor.
|
||||
|
||||
## Voting
|
||||
|
||||
Voting on a proposed motion SHOULD happen on the dev@opencontainers.org mailing list (except [security issues](#security-issues)) with maintainers posting LGTM or REJECT.
|
||||
Maintainers MAY also explicitly not vote by posting ABSTAIN (which is useful to revert a previous vote).
|
||||
Maintainers MAY post multiple times (e.g. as they revise their position based on feedback), but only their final post counts in the tally.
|
||||
A proposed motion is adopted if two-thirds of votes cast, a quorum having voted, are in favor of the release.
|
||||
|
||||
Voting SHOULD remain open for a week to collect feedback from the wider community and allow the maintainers to digest the proposed motion.
|
||||
Under exceptional conditions (e.g. non-major security fix releases) proposals which reach quorum with unanimous support MAY be adopted earlier.
|
||||
|
||||
A maintainer MAY choose to reply with REJECT.
|
||||
A maintainer posting a REJECT MUST include a list of concerns or links to written documentation for those concerns (e.g. GitHub issues or mailing-list threads).
|
||||
The maintainers SHOULD try to resolve the concerns and wait for the rejecting maintainer to change their opinion to LGTM.
|
||||
However, a motion MAY be adopted with REJECTs, as outlined in the previous paragraphs.
|
||||
|
||||
## Quorum
|
||||
|
||||
A quorum is established when at least two-thirds of maintainers have voted.
|
||||
|
||||
For projects that are not specifications, a [motion to release](#release-approval) MAY be adopted if the tally is at least three LGTMs and no REJECTs, even if three votes does not meet the usual two-thirds quorum.
|
||||
|
||||
## Security issues
|
||||
|
||||
Motions with sensitive security implications MUST be proposed on the security@opencontainers.org mailing list instead of dev@opencontainers.org, but should otherwise follow the standard [proposal](#proposing-a-motion) process.
|
||||
The security@opencontainers.org mailing list includes all members of the TOB.
|
||||
The TOB will contact the project maintainers and provide a channel for discussing and voting on the motion, but voting will otherwise follow the standard [voting](#voting) and [quorum](#quorum) rules.
|
||||
The TOB and project maintainers will work together to notify affected parties before making an adopted motion public.
|
||||
|
||||
## Amendments
|
||||
|
||||
The [project governance](#project-governance) rules and procedures MAY be amended or replaced using the procedures themselves.
|
||||
The MAINTAINERS of this project governance document is the total set of MAINTAINERS from all Open Containers projects (runC, runtime-spec, and image-spec).
|
||||
|
||||
## Subject templates
|
||||
|
||||
Maintainers are busy and get lots of email.
|
||||
To make project proposals recognizable, proposed motions SHOULD use the following subject templates.
|
||||
|
||||
### Proposing a motion
|
||||
|
||||
> [{project} VOTE]: {motion description} (closes {end of voting window})
|
||||
|
||||
For example:
|
||||
|
||||
> [runtime-spec VOTE]: Tag 0647920 as 1.0.0-rc (closes 2016-06-03 20:00 UTC)
|
||||
|
||||
### Tallying results
|
||||
|
||||
After voting closes, a maintainer SHOULD post a tally to the motion thread with a subject template like:
|
||||
|
||||
> [{project} {status}]: {motion description} (+{LGTMs} -{REJECTs} #{ABSTAINs})
|
||||
|
||||
Where `{status}` is either `adopted` or `rejected`.
|
||||
For example:
|
||||
|
||||
> [runtime-spec adopted]: Tag 0647920 as 1.0.0-rc (+6 -0 #3)
|
||||
|
||||
[charter]: https://www.opencontainers.org/about/governance
|
||||
104
vendor/github.com/opencontainers/image-spec/HACKING.md
generated
vendored
Normal file
104
vendor/github.com/opencontainers/image-spec/HACKING.md
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
# Hacking Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide contains instructions for building artifacts contained in this repository.
|
||||
|
||||
### Go
|
||||
|
||||
This spec includes several Go packages, and a command line tool considered to be a reference implementation of the OCI image specification.
|
||||
|
||||
Prerequisites:
|
||||
* Go - current release only, earlier releases are not supported
|
||||
* make
|
||||
|
||||
The following make targets are relevant for any work involving the Go packages.
|
||||
|
||||
### Linting
|
||||
|
||||
The included Go source code is being examined for any linting violations not included in the standard Go compiler. Linting is done using [gometalinter](https://github.com/alecthomas/gometalinter).
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make lint
|
||||
```
|
||||
|
||||
### Tests
|
||||
|
||||
This target executes all Go based tests.
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make test
|
||||
$ make validate-examples
|
||||
```
|
||||
|
||||
### Virtual schema http/FileSystem
|
||||
|
||||
The `schema` validator uses a virtual [http/FileSystem](https://golang.org/pkg/net/http/#FileSystem) to load the JSON schema files for validating OCI images and/or manifests.
|
||||
The virtual filesystem is generated using the `esc` tool and compiled into consumers of the `schema` package so the JSON schema files don't have to be distributed along with and consumer binaries.
|
||||
|
||||
Whenever changes are being done in any of the `schema/*.json` files, one must refresh the generated virtual filesystem.
|
||||
Otherwise schema changes will not be visible inside `schema` consumers.
|
||||
|
||||
Prerequisites:
|
||||
* [esc](https://github.com/mjibson/esc)
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make schema-fs
|
||||
```
|
||||
|
||||
### JSON schema formatting
|
||||
|
||||
This target auto-formats all JSON files in the `schema` directory using the `jq` tool.
|
||||
|
||||
Prerequisites:
|
||||
* [jq](https://stedolan.github.io/jq/) >=1.5
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make fmt
|
||||
```
|
||||
|
||||
### OCI image specification PDF/HTML documentation files
|
||||
|
||||
This target generates a PDF/HTML version of the OCI image specification.
|
||||
|
||||
Prerequisites:
|
||||
* [Docker](https://www.docker.com/)
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make docs
|
||||
```
|
||||
|
||||
### License header check
|
||||
|
||||
This target checks if the source code includes necessary headers.
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make check-license
|
||||
```
|
||||
|
||||
### Clean build artifacts
|
||||
|
||||
This target cleans all generated/compiled artifacts.
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make clean
|
||||
```
|
||||
|
||||
### Create PNG images from dot files
|
||||
|
||||
This target generates PNG image files from DOT source files in the `img` directory.
|
||||
|
||||
Prerequisites:
|
||||
* [graphviz](http://www.graphviz.org/)
|
||||
|
||||
Invocation:
|
||||
```
|
||||
$ make img/media-types.png
|
||||
```
|
||||
191
vendor/github.com/opencontainers/image-spec/LICENSE
generated
vendored
Normal file
191
vendor/github.com/opencontainers/image-spec/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2016 The Linux Foundation.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
7
vendor/github.com/opencontainers/image-spec/MAINTAINERS
generated
vendored
Normal file
7
vendor/github.com/opencontainers/image-spec/MAINTAINERS
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
Brandon Philips <brandon.philips@coreos.com> (@philips)
|
||||
Brendan Burns <bburns@microsoft.com> (@brendandburns)
|
||||
Jason Bouzane <jbouzane@google.com> (@jbouzane)
|
||||
John Starks <jostarks@microsoft.com> (@jstarks)
|
||||
Jonathan Boulle <jon.boulle@coreos.com> (@jonboulle)
|
||||
Stephen Day <stephen.day@docker.com> (@stevvooe)
|
||||
Vincent Batts <vbatts@redhat.com> (@vbatts)
|
||||
146
vendor/github.com/opencontainers/image-spec/Makefile
generated
vendored
Normal file
146
vendor/github.com/opencontainers/image-spec/Makefile
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
GO15VENDOREXPERIMENT=1
|
||||
export GO15VENDOREXPERIMENT
|
||||
|
||||
DOCKER ?= $(shell command -v docker 2>/dev/null)
|
||||
PANDOC ?= $(shell command -v pandoc 2>/dev/null)
|
||||
|
||||
ifeq "$(strip $(PANDOC))" ''
|
||||
ifneq "$(strip $(DOCKER))" ''
|
||||
PANDOC = $(DOCKER) run \
|
||||
-it \
|
||||
--rm \
|
||||
-v $(shell pwd)/:/input/:ro \
|
||||
-v $(shell pwd)/$(OUTPUT_DIRNAME)/:/$(OUTPUT_DIRNAME)/ \
|
||||
-u $(shell id -u) \
|
||||
--workdir /input \
|
||||
docker.io/vbatts/pandoc:1.17.0.3-2.fc25.x86_64
|
||||
PANDOC_SRC := /input/
|
||||
PANDOC_DST := /
|
||||
endif
|
||||
endif
|
||||
|
||||
# These docs are in an order that determines how they show up in the PDF/HTML docs.
|
||||
DOC_FILES := \
|
||||
spec.md \
|
||||
media-types.md \
|
||||
descriptor.md \
|
||||
image-layout.md \
|
||||
manifest.md \
|
||||
image-index.md \
|
||||
layer.md \
|
||||
config.md \
|
||||
annotations.md \
|
||||
conversion.md \
|
||||
considerations.md \
|
||||
implementations.md
|
||||
|
||||
FIGURE_FILES := \
|
||||
img/media-types.png
|
||||
|
||||
OUTPUT_DIRNAME ?= output/
|
||||
DOC_FILENAME ?= oci-image-spec
|
||||
|
||||
EPOCH_TEST_COMMIT ?= v0.2.0
|
||||
|
||||
TOOLS := esc gitvalidation glide glide-vc
|
||||
|
||||
default: check-license lint test
|
||||
|
||||
help:
|
||||
@echo "Usage: make <target>"
|
||||
@echo
|
||||
@echo " * 'docs' - produce document in the $(OUTPUT_DIRNAME) directory"
|
||||
@echo " * 'fmt' - format the json with indentation"
|
||||
@echo " * 'validate-examples' - validate the examples in the specification markdown files"
|
||||
@echo " * 'schema-fs' - regenerate the virtual schema http/FileSystem"
|
||||
@echo " * 'check-license' - check license headers in source files"
|
||||
@echo " * 'lint' - Execute the source code linter"
|
||||
@echo " * 'test' - Execute the unit tests"
|
||||
@echo " * 'img/*.png' - Generate PNG from dot file"
|
||||
|
||||
fmt:
|
||||
for i in schema/*.json ; do jq --indent 2 -M . "$${i}" > xx && cat xx > "$${i}" && rm xx ; done
|
||||
|
||||
docs: $(OUTPUT_DIRNAME)/$(DOC_FILENAME).pdf $(OUTPUT_DIRNAME)/$(DOC_FILENAME).html
|
||||
|
||||
ifeq "$(strip $(PANDOC))" ''
|
||||
$(OUTPUT_DIRNAME)/$(DOC_FILENAME).pdf: $(DOC_FILES) $(FIGURE_FILES)
|
||||
$(error cannot build $@ without either pandoc or docker)
|
||||
else
|
||||
$(OUTPUT_DIRNAME)/$(DOC_FILENAME).pdf: $(DOC_FILES) $(FIGURE_FILES)
|
||||
@mkdir -p $(OUTPUT_DIRNAME)/ && \
|
||||
$(PANDOC) -f markdown_github -t latex --latex-engine=xelatex -o $(PANDOC_DST)$@ $(patsubst %,$(PANDOC_SRC)%,$(DOC_FILES))
|
||||
ls -sh $(realpath $@)
|
||||
|
||||
$(OUTPUT_DIRNAME)/$(DOC_FILENAME).html: header.html $(DOC_FILES) $(FIGURE_FILES)
|
||||
@mkdir -p $(OUTPUT_DIRNAME)/ && \
|
||||
cp -ap img/ $(shell pwd)/$(OUTPUT_DIRNAME)/&& \
|
||||
$(PANDOC) -f markdown_github -t html5 -H $(PANDOC_SRC)header.html --standalone -o $(PANDOC_DST)$@ $(patsubst %,$(PANDOC_SRC)%,$(DOC_FILES))
|
||||
ls -sh $(realpath $@)
|
||||
endif
|
||||
|
||||
header.html: .tool/genheader.go specs-go/version.go
|
||||
go run .tool/genheader.go > $@
|
||||
|
||||
validate-examples: schema/fs.go
|
||||
go test -run TestValidate ./schema
|
||||
|
||||
schema/fs.go: $(wildcard schema/*.json) schema/gen.go
|
||||
cd schema && printf "%s\n\n%s\n" "$$(cat ../.header)" "$$(go generate)" > fs.go
|
||||
|
||||
schema-fs: schema/fs.go
|
||||
@echo "generating schema fs"
|
||||
|
||||
check-license:
|
||||
@echo "checking license headers"
|
||||
@./.tool/check-license
|
||||
|
||||
lint:
|
||||
@echo "checking lint"
|
||||
@./.tool/lint
|
||||
|
||||
test: schema/fs.go
|
||||
go test -race -cover $(shell go list ./... | grep -v /vendor/)
|
||||
|
||||
img/%.png: img/%.dot
|
||||
dot -Tpng $^ > $@
|
||||
|
||||
|
||||
# When this is running in travis, it will only check the travis commit range
|
||||
.gitvalidation:
|
||||
@which git-validation > /dev/null 2>/dev/null || (echo "ERROR: git-validation not found. Consider 'make install.tools' target" && false)
|
||||
ifdef TRAVIS_COMMIT_RANGE
|
||||
git-validation -q -run DCO,short-subject,dangling-whitespace
|
||||
else
|
||||
git-validation -v -run DCO,short-subject,dangling-whitespace -range $(EPOCH_TEST_COMMIT)..HEAD
|
||||
endif
|
||||
|
||||
install.tools: $(TOOLS:%=.install.%)
|
||||
|
||||
.install.esc:
|
||||
go get -u github.com/mjibson/esc
|
||||
|
||||
.install.gitvalidation:
|
||||
go get -u github.com/vbatts/git-validation
|
||||
|
||||
.install.glide:
|
||||
go get -u github.com/Masterminds/glide
|
||||
|
||||
.install.glide-vc:
|
||||
go get -u github.com/sgotti/glide-vc
|
||||
|
||||
clean:
|
||||
rm -rf *~ $(OUTPUT_DIRNAME) header.html
|
||||
|
||||
.PHONY: \
|
||||
$(TOOLS:%=.install.%) \
|
||||
validate-examples \
|
||||
check-license \
|
||||
clean \
|
||||
lint \
|
||||
install.tools \
|
||||
docs \
|
||||
test \
|
||||
.gitvalidation \
|
||||
schema/fs.go \
|
||||
schema-fs
|
||||
167
vendor/github.com/opencontainers/image-spec/README.md
generated
vendored
Normal file
167
vendor/github.com/opencontainers/image-spec/README.md
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
# OCI Image Format Specification
|
||||
<div>
|
||||
<a href="https://travis-ci.org/opencontainers/image-spec">
|
||||
<img src="https://travis-ci.org/opencontainers/image-spec.svg?branch=master"></img>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
The OCI Image Format project creates and maintains the software shipping container image format spec (OCI Image Format).
|
||||
|
||||
**[The specification can be found here](spec.md).**
|
||||
|
||||
This repository also provides [Go types](specs-go), [intra-blob validation tooling, and JSON Schema](schema).
|
||||
The Go types and validation should be compatible with the current Go release; earlier Go releases are not supported.
|
||||
|
||||
Additional documentation about how this group operates:
|
||||
|
||||
- [Code of Conduct](https://github.com/opencontainers/tob/blob/d2f9d68c1332870e40693fe077d311e0742bc73d/code-of-conduct.md)
|
||||
- [Roadmap](#roadmap)
|
||||
- [Releases](RELEASES.md)
|
||||
- [Project Documentation](project.md)
|
||||
|
||||
The _optional_ and _base_ layers of all OCI projects are tracked in the [OCI Scope Table](https://www.opencontainers.org/about/oci-scope-table).
|
||||
|
||||
## Running an OCI Image
|
||||
|
||||
The OCI Image Format partner project is the [OCI Runtime Spec project](https://github.com/opencontainers/runtime-spec).
|
||||
The Runtime Specification outlines how to run a "[filesystem bundle](https://github.com/opencontainers/runtime-spec/blob/master/bundle.md)" that is unpacked on disk.
|
||||
At a high-level an OCI implementation would download an OCI Image then unpack that image into an OCI Runtime filesystem bundle.
|
||||
At this point the OCI Runtime Bundle would be run by an OCI Runtime.
|
||||
|
||||
This entire workflow supports the UX that users have come to expect from container engines like Docker and rkt: primarily, the ability to run an image with no additional arguments:
|
||||
|
||||
* docker run example.com/org/app:v1.0.0
|
||||
* rkt run example.com/org/app,version=v1.0.0
|
||||
|
||||
To support this UX the OCI Image Format contains sufficient information to launch the application on the target platform (e.g. command, arguments, environment variables, etc).
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: Why doesn't this project mention distribution?**
|
||||
|
||||
A: Distribution, for example using HTTP as both Docker v2.2 and AppC do today, is currently out of scope on the [OCI Scope Table](https://www.opencontainers.org/about/oci-scope-table).
|
||||
There has been [some discussion on the TOB mailing list](https://groups.google.com/a/opencontainers.org/d/msg/tob/A3JnmI-D-6Y/tLuptPDHAgAJ) to make distribution an optional layer, but this topic is a work in progress.
|
||||
|
||||
**Q: What happens to AppC or Docker Image Formats?**
|
||||
|
||||
A: Existing formats can continue to be a proving ground for technologies, as needed.
|
||||
The OCI Image Format project strives to provide a dependable open specification that can be shared between different tools and be evolved for years or decades of compatibility; as the deb and rpm format have.
|
||||
|
||||
Find more [FAQ on the OCI site](https://www.opencontainers.org/faq).
|
||||
|
||||
## Roadmap
|
||||
|
||||
The [GitHub milestones](https://github.com/opencontainers/image-spec/milestones) lay out the path to the future improvements.
|
||||
|
||||
# Contributing
|
||||
|
||||
Development happens on GitHub for the spec.
|
||||
Issues are used for bugs and actionable items and longer discussions can happen on the [mailing list](#mailing-list).
|
||||
|
||||
The specification and code is licensed under the Apache 2.0 license found in the `LICENSE` file of this repository.
|
||||
|
||||
## Discuss your design
|
||||
|
||||
The project welcomes submissions, but please let everyone know what you are working on.
|
||||
|
||||
Before undertaking a nontrivial change to this specification, send mail to the [mailing list](#mailing-list) to discuss what you plan to do.
|
||||
This gives everyone a chance to validate the design, helps prevent duplication of effort, and ensures that the idea fits.
|
||||
It also guarantees that the design is sound before code is written; a GitHub pull-request is not the place for high-level discussions.
|
||||
|
||||
Typos and grammatical errors can go straight to a pull-request.
|
||||
When in doubt, start on the [mailing-list](#mailing-list).
|
||||
|
||||
## Weekly Call
|
||||
|
||||
The contributors and maintainers of all OCI projects have a weekly meeting Wednesdays at 2:00 PM (USA Pacific).
|
||||
Everyone is welcome to participate via [UberConference web][UberConference] or audio-only: +1-415-968-0849 (no PIN needed).
|
||||
An initial agenda will be posted to the [mailing list](#mailing-list) earlier in the week, and everyone is welcome to propose additional topics or suggest other agenda alterations there.
|
||||
Minutes are posted to the [mailing list](#mailing-list) and minutes from past calls are archived [here][minutes].
|
||||
|
||||
## Mailing List
|
||||
|
||||
You can subscribe and join the mailing list on [Google Groups](https://groups.google.com/a/opencontainers.org/forum/#!forum/dev).
|
||||
|
||||
## IRC
|
||||
|
||||
OCI discussion happens on #opencontainers on Freenode ([logs][irc-logs]).
|
||||
|
||||
## Markdown style
|
||||
|
||||
To keep consistency throughout the Markdown files in the Open Container spec all files should be formatted one sentence per line.
|
||||
This fixes two things: it makes diffing easier with git and it resolves fights about line wrapping length.
|
||||
For example, this paragraph will span three lines in the Markdown source.
|
||||
|
||||
## Git commit
|
||||
|
||||
### Sign your work
|
||||
|
||||
The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch.
|
||||
The rules are pretty simple: if you can certify the below (from [developercertificate.org](http://developercertificate.org/)):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
then you just add a line to every git commit message:
|
||||
|
||||
Signed-off-by: Joe Smith <joe@gmail.com>
|
||||
|
||||
using your real name (sorry, no pseudonyms or anonymous contributions.)
|
||||
|
||||
You can add the sign off when creating the git commit via `git commit -s`.
|
||||
|
||||
### Commit Style
|
||||
|
||||
Simple house-keeping for clean git history.
|
||||
Read more on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) or the Discussion section of [`git-commit(1)`](http://git-scm.com/docs/git-commit).
|
||||
|
||||
1. Separate the subject from body with a blank line
|
||||
2. Limit the subject line to 50 characters
|
||||
3. Capitalize the subject line
|
||||
4. Do not end the subject line with a period
|
||||
5. Use the imperative mood in the subject line
|
||||
6. Wrap the body at 72 characters
|
||||
7. Use the body to explain what and why vs. how
|
||||
* If there was important/useful/essential conversation or information, copy or include a reference
|
||||
8. When possible, one keyword to scope the change in the subject (i.e. "README: ...", "runtime: ...")
|
||||
|
||||
|
||||
[UberConference]: https://www.uberconference.com/opencontainers
|
||||
[irc-logs]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/
|
||||
[minutes]: http://ircbot.wl.linuxfoundation.org/meetings/opencontainers/
|
||||
51
vendor/github.com/opencontainers/image-spec/RELEASES.md
generated
vendored
Normal file
51
vendor/github.com/opencontainers/image-spec/RELEASES.md
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# Releases
|
||||
|
||||
The release process hopes to encourage early, consistent consensus-building during project development.
|
||||
The mechanisms used are regular community communication on the mailing list about progress, scheduled meetings for issue resolution and release triage, and regularly paced and communicated releases.
|
||||
Releases are proposed and adopted or rejected using the usual [project governance](GOVERNANCE.md) rules and procedures.
|
||||
|
||||
An anti-pattern that we want to avoid is heavy development or discussions "late cycle" around major releases.
|
||||
We want to build a community that is involved and communicates consistently through all releases instead of relying on "silent periods" as a judge of stability.
|
||||
|
||||
## Parallel releases
|
||||
|
||||
A single project MAY consider several motions to release in parallel.
|
||||
However each motion to release after the initial 0.1.0 MUST be based on a previous release that has already landed.
|
||||
|
||||
For example, runtime-spec maintainers may propose a v1.0.0-rc2 on the 1st of the month and a v0.9.1 bugfix on the 2nd of the month.
|
||||
They may not propose a v1.0.0-rc3 until the v1.0.0-rc2 is accepted (on the 7th if the vote initiated on the 1st passes).
|
||||
|
||||
## Specifications
|
||||
|
||||
The OCI maintains three categories of projects: specifications, applications, and conformance-testing tools.
|
||||
However, specification releases have special restrictions in the [OCI charter][charter]:
|
||||
|
||||
* They are the target of backwards compatibility (§7.g), and
|
||||
* They are subject to the OFWa patent grant (§8.d and e).
|
||||
|
||||
To avoid unfortunate side effects (onerous backwards compatibity requirements or Member resignations), the following additional procedures apply to specification releases:
|
||||
|
||||
### Planning a release
|
||||
|
||||
Every OCI specification project SHOULD hold meetings that involve maintainers reviewing pull requests, debating outstanding issues, and planning releases.
|
||||
This meeting MUST be advertised on the project README and MAY happen on a phone call, video conference, or on IRC.
|
||||
Maintainers MUST send updates to the dev@opencontainers.org with results of these meetings.
|
||||
|
||||
Before the specification reaches v1.0.0, the meetings SHOULD be weekly.
|
||||
Once a specification has reached v1.0.0, the maintainers may alter the cadence, but a meeting MUST be held within four weeks of the previous meeting.
|
||||
|
||||
The release plans, corresponding milestones and estimated due dates MUST be published on GitHub (e.g. https://github.com/opencontainers/runtime-spec/milestones).
|
||||
GitHub milestones and issues are only used for community organization and all releases MUST follow the [project governance](GOVERNANCE.md) rules and procedures.
|
||||
|
||||
### Timelines
|
||||
|
||||
Specifications have a variety of different timelines in their lifecycle.
|
||||
|
||||
* Pre-v1.0.0 specifications SHOULD release on a monthly cadence to garner feedback.
|
||||
* Major specification releases MUST release at least three release candidates spaced a minimum of one week apart.
|
||||
This means a major release like a v1.0.0 or v2.0.0 release will take 1 month at minimum: one week for rc1, one week for rc2, one week for rc3, and one week for the major release itself.
|
||||
Maintainers SHOULD strive to make zero breaking changes during this cycle of release candidates and SHOULD restart the three-candidate count when a breaking change is introduced.
|
||||
For example if a breaking change is introduced in v1.0.0-rc2 then the series would end with v1.0.0-rc4 and v1.0.0.
|
||||
- Minor and patch releases SHOULD be made on an as-needed basis.
|
||||
|
||||
[charter]: https://www.opencontainers.org/about/governance
|
||||
67
vendor/github.com/opencontainers/image-spec/annotations.md
generated
vendored
Normal file
67
vendor/github.com/opencontainers/image-spec/annotations.md
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# Annotations
|
||||
Several components of the specification, like [Image Manifests](manifest.md) and [Descriptors](descriptor.md), feature an optional annotations property, whose format is common and defined in this section.
|
||||
|
||||
This property contains arbitrary metadata.
|
||||
|
||||
## Rules
|
||||
|
||||
* Annotations MUST be a key-value map where both the key and value MUST be strings.
|
||||
* While the value MUST be present, it MAY be an empty string.
|
||||
* Keys MUST be unique within this map, and best practice is to namespace the keys.
|
||||
* Keys SHOULD be named using a reverse domain notation - e.g. `com.example.myKey`.
|
||||
* The prefix `org.opencontainers` is reserved for keys defined in Open Container Initiative (OCI) specifications and MUST NOT be used by other specifications and extensions.
|
||||
* Keys using the `org.opencontainers.image` namespace are reserved for use in the OCI Image Specification and MUST NOT be used by other specifications and extensions, including other OCI specifications.
|
||||
* If there are no annotations then this property MUST either be absent or be an empty map.
|
||||
* Consumers MUST NOT generate an error if they encounter an unknown annotation key.
|
||||
|
||||
## Pre-Defined Annotation Keys
|
||||
|
||||
This specification defines the following annotation keys, intended for but not limited to [image index](image-index.md) and image [manifest](manifest.md) authors:
|
||||
* **org.opencontainers.image.created** date and time on which the image was built (string, date-time as defined by [RFC 3339](https://tools.ietf.org/html/rfc3339#section-5.6)).
|
||||
* **org.opencontainers.image.authors** contact details of the people or organization responsible for the image (freeform string)
|
||||
* **org.opencontainers.image.url** URL to find more information on the image (string)
|
||||
* **org.opencontainers.image.documentation** URL to get documentation on the image (string)
|
||||
* **org.opencontainers.image.source** URL to get source code for building the image (string)
|
||||
* **org.opencontainers.image.version** version of the packaged software
|
||||
* The version MAY match a label or tag in the source code repository
|
||||
* version MAY be [Semantic versioning-compatible](http://semver.org/)
|
||||
* **org.opencontainers.image.revision** Source control revision identifier for the packaged software.
|
||||
* **org.opencontainers.image.vendor** Name of the distributing entity, organization or individual.
|
||||
* **org.opencontainers.image.licenses** License(s) under which contained software is distributed as an [SPDX License Expression][spdx-license-expression].
|
||||
* **org.opencontainers.image.ref.name** Name of the reference for a target (string).
|
||||
* SHOULD only be considered valid when on descriptors on `index.json` within [image layout](image-layout.md).
|
||||
* Character set of the value SHOULD conform to alphanum of `A-Za-z0-9` and separator set of `-._:@/+`
|
||||
* The reference must match the following [grammar](considerations.md#ebnf):
|
||||
```
|
||||
ref ::= component ("/" component)*
|
||||
component ::= alphanum (separator alphanum)*
|
||||
alphanum ::= [A-Za-z0-9]+
|
||||
separator ::= [-._:@+] | "--"
|
||||
```
|
||||
* **org.opencontainers.image.title** Human-readable title of the image (string)
|
||||
* **org.opencontainers.image.description** Human-readable description of the software packaged in the image (string)
|
||||
|
||||
## Back-compatibility with Label Schema
|
||||
|
||||
[Label Schema](https://label-schema.org) defined a number of conventional labels for container images, and these are now superceded by annotations with keys starting **org.opencontainers.image**.
|
||||
|
||||
While users are encouraged to use the **org.opencontainers.image** keys, tools MAY choose to support compatible annotations using the **org.label-schema** prefix as follows.
|
||||
|
||||
| `org.opencontainers.image` prefix | `org.label-schema prefix` | Compatibility notes |
|
||||
|---------------------------|-------------------------|---------------------|
|
||||
| `created` | `build-date` | Compatible |
|
||||
| `url` | `url` | Compatible |
|
||||
| `source` | `vcs-url` | Compatible |
|
||||
| `version` | `version` | Compatible |
|
||||
| `revision` | `vcs-ref` | Compatible |
|
||||
| `vendor` | `vendor` | Compatible |
|
||||
| `title` | `name` | Compatible |
|
||||
| `description` | `description` | Compatible |
|
||||
| `documentation` | `usage` | Value is compatible if the documentation is located by a URL |
|
||||
| `authors` | | No equivalent in Label Schema |
|
||||
| `licenses` | | No equivalent in Label Schema |
|
||||
| `ref.name` | | No equivalent in Label Schema |
|
||||
| | `schema-version`| No equivalent in the OCI Image Spec |
|
||||
| | `docker.*`, `rkt.*` | No equivalent in the OCI Image Spec |
|
||||
|
||||
[spdx-license-expression]: https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60
|
||||
274
vendor/github.com/opencontainers/image-spec/config.md
generated
vendored
Normal file
274
vendor/github.com/opencontainers/image-spec/config.md
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
# OCI Image Configuration
|
||||
|
||||
An OCI *Image* is an ordered collection of root filesystem changes and the corresponding execution parameters for use within a container runtime.
|
||||
This specification outlines the JSON format describing images for use with a container runtime and execution tool and its relationship to filesystem changesets, described in [Layers](layer.md).
|
||||
|
||||
This section defines the `application/vnd.oci.image.config.v1+json` [media type](media-types.md).
|
||||
|
||||
## Terminology
|
||||
|
||||
This specification uses the following terms:
|
||||
|
||||
### [Layer](layer.md)
|
||||
|
||||
* Image filesystems are composed of *layers*.
|
||||
* Each layer represents a set of filesystem changes in a tar-based [layer format](layer.md), recording files to be added, changed, or deleted relative to its parent layer.
|
||||
* Layers do not have configuration metadata such as environment variables or default arguments - these are properties of the image as a whole rather than any particular layer.
|
||||
* Using a layer-based or union filesystem such as AUFS, or by computing the diff from filesystem snapshots, the filesystem changeset can be used to present a series of image layers as if they were one cohesive filesystem.
|
||||
|
||||
### Image JSON
|
||||
|
||||
* Each image has an associated JSON structure which describes some basic information about the image such as date created, author, as well as execution/runtime configuration like its entrypoint, default arguments, networking, and volumes.
|
||||
* The JSON structure also references a cryptographic hash of each layer used by the image, and provides history information for those layers.
|
||||
* This JSON is considered to be immutable, because changing it would change the computed [ImageID](#imageid).
|
||||
* Changing it means creating a new derived image, instead of changing the existing image.
|
||||
|
||||
### Layer DiffID
|
||||
|
||||
A layer DiffID is the digest over the layer's uncompressed tar archive and serialized in the descriptor digest format, e.g., `sha256:a9561eb1b190625c9adb5a9513e72c4dedafc1cb2d4c5236c9a6957ec7dfd5a9`.
|
||||
Layers SHOULD be packed and unpacked reproducibly to avoid changing the layer DiffID, for example by using [tar-split][] to save the tar headers.
|
||||
|
||||
NOTE: Do not confuse DiffIDs with [layer digests](manifest.md#image-manifest-property-descriptions), often referenced in the manifest, which are digests over compressed or uncompressed content.
|
||||
|
||||
### Layer ChainID
|
||||
|
||||
For convenience, it is sometimes useful to refer to a stack of layers with a single identifier.
|
||||
While a layer's `DiffID` identifies a single changeset, the `ChainID` identifies the subsequent application of those changesets.
|
||||
This ensures that we have handles referring to both the layer itself, as well as the result of the application of a series of changesets.
|
||||
Use in combination with `rootfs.diff_ids` while applying layers to a root filesystem to uniquely and safely identify the result.
|
||||
|
||||
#### Definition
|
||||
|
||||
The `ChainID` of an applied set of layers is defined with the following recursion:
|
||||
|
||||
```
|
||||
ChainID(L₀) = DiffID(L₀)
|
||||
ChainID(L₀|...|Lₙ₋₁|Lₙ) = Digest(ChainID(L₀|...|Lₙ₋₁) + " " + DiffID(Lₙ))
|
||||
```
|
||||
|
||||
For this, we define the binary `|` operation to be the result of applying the right operand to the left operand.
|
||||
For example, given base layer `A` and a changeset `B`, we refer to the result of applying `B` to `A` as `A|B`.
|
||||
|
||||
Above, we define the `ChainID` for a single layer (`L₀`) as equivalent to the `DiffID` for that layer.
|
||||
Otherwise, the `ChainID` for a set of applied layers (`L₀|...|Lₙ₋₁|Lₙ`) is defined as the recursion `Digest(ChainID(L₀|...|Lₙ₋₁) + " " + DiffID(Lₙ))`.
|
||||
|
||||
#### Explanation
|
||||
|
||||
Let's say we have layers A, B, C, ordered from bottom to top, where A is the base and C is the top.
|
||||
Defining `|` as a binary application operator, the root filesystem may be `A|B|C`.
|
||||
While it is implied that `C` is only useful when applied to `A|B`, the identifier `C` is insufficient to identify this result, as we'd have the equality `C = A|B|C`, which isn't true.
|
||||
|
||||
The main issue is when we have two definitions of `C`, `C = C` and `C = A|B|C`.
|
||||
If this is true (with some handwaving), `C = x|C` where `x = any application`.
|
||||
This means that if an attacker can define `x`, relying on `C` provides no guarantee that the layers were applied in any order.
|
||||
|
||||
The `ChainID` addresses this problem by being defined as a compound hash.
|
||||
__We differentiate the changeset `C`, from the order-dependent application `A|B|C` by saying that the resulting rootfs is identified by ChainID(A|B|C), which can be calculated by `ImageConfig.rootfs`.__
|
||||
|
||||
Let's expand the definition of `ChainID(A|B|C)` to explore its internal structure:
|
||||
|
||||
```
|
||||
ChainID(A) = DiffID(A)
|
||||
ChainID(A|B) = Digest(ChainID(A) + " " + DiffID(B))
|
||||
ChainID(A|B|C) = Digest(ChainID(A|B) + " " + DiffID(C))
|
||||
```
|
||||
|
||||
We can replace each definition and reduce to a single equality:
|
||||
|
||||
```
|
||||
ChainID(A|B|C) = Digest(Digest(DiffID(A) + " " + DiffID(B)) + " " + DiffID(C))
|
||||
```
|
||||
|
||||
Hopefully, the above is illustrative of the _actual_ contents of the `ChainID`.
|
||||
Most importantly, we can easily see that `ChainID(C) != ChainID(A|B|C)`, otherwise, `ChainID(C) = DiffID(C)`, which is the base case, could not be true.
|
||||
|
||||
### ImageID
|
||||
|
||||
Each image's ID is given by the SHA256 hash of its [configuration JSON](#image-json).
|
||||
It is represented as a hexadecimal encoding of 256 bits, e.g., `sha256:a9561eb1b190625c9adb5a9513e72c4dedafc1cb2d4c5236c9a6957ec7dfd5a9`.
|
||||
Since the [configuration JSON](#image-json) that gets hashed references hashes of each layer in the image, this formulation of the ImageID makes images content-addressable.
|
||||
|
||||
## Properties
|
||||
|
||||
Note: Any OPTIONAL field MAY also be set to null, which is equivalent to being absent.
|
||||
|
||||
- **created** *string*, OPTIONAL
|
||||
|
||||
An combined date and time at which the image was created, formatted as defined by [RFC 3339, section 5.6][rfc3339-s5.6].
|
||||
|
||||
- **author** *string*, OPTIONAL
|
||||
|
||||
Gives the name and/or email address of the person or entity which created and is responsible for maintaining the image.
|
||||
|
||||
- **architecture** *string*, REQUIRED
|
||||
|
||||
The CPU architecture which the binaries in this image are built to run on.
|
||||
Configurations SHOULD use, and implementations SHOULD understand, values listed in the Go Language document for [`GOARCH`][go-environment].
|
||||
|
||||
- **os** *string*, REQUIRED
|
||||
|
||||
The name of the operating system which the image is built to run on.
|
||||
Configurations SHOULD use, and implementations SHOULD understand, values listed in the Go Language document for [`GOOS`][go-environment].
|
||||
|
||||
- **config** *object*, OPTIONAL
|
||||
|
||||
The execution parameters which SHOULD be used as a base when running a container using the image.
|
||||
This field can be `null`, in which case any execution parameters should be specified at creation of the container.
|
||||
|
||||
- **User** *string*, OPTIONAL
|
||||
|
||||
The username or UID which is a platform-specific structure that allows specific control over which user the process run as.
|
||||
This acts as a default value to use when the value is not specified when creating a container.
|
||||
For Linux based systems, all of the following are valid: `user`, `uid`, `user:group`, `uid:gid`, `uid:group`, `user:gid`.
|
||||
If `group`/`gid` is not specified, the default group and supplementary groups of the given `user`/`uid` in `/etc/passwd` from the container are applied.
|
||||
|
||||
- **ExposedPorts** *object*, OPTIONAL
|
||||
|
||||
A set of ports to expose from a container running this image.
|
||||
Its keys can be in the format of:
|
||||
`port/tcp`, `port/udp`, `port` with the default protocol being `tcp` if not specified.
|
||||
These values act as defaults and are merged with any specified when creating a container.
|
||||
**NOTE:** This JSON structure value is unusual because it is a direct JSON serialization of the Go type `map[string]struct{}` and is represented in JSON as an object mapping its keys to an empty object.
|
||||
|
||||
- **Env** *array of strings*, OPTIONAL
|
||||
|
||||
Entries are in the format of `VARNAME=VARVALUE`.
|
||||
These values act as defaults and are merged with any specified when creating a container.
|
||||
|
||||
- **Entrypoint** *array of strings*, OPTIONAL
|
||||
|
||||
A list of arguments to use as the command to execute when the container starts.
|
||||
These values act as defaults and may be replaced by an entrypoint specified when creating a container.
|
||||
|
||||
- **Cmd** *array of strings*, OPTIONAL
|
||||
|
||||
Default arguments to the entrypoint of the container.
|
||||
These values act as defaults and may be replaced by any specified when creating a container.
|
||||
If an `Entrypoint` value is not specified, then the first entry of the `Cmd` array SHOULD be interpreted as the executable to run.
|
||||
|
||||
- **Volumes** *object*, OPTIONAL
|
||||
|
||||
A set of directories describing where the process is likely write data specific to a container instance.
|
||||
**NOTE:** This JSON structure value is unusual because it is a direct JSON serialization of the Go type `map[string]struct{}` and is represented in JSON as an object mapping its keys to an empty object.
|
||||
|
||||
- **WorkingDir** *string*, OPTIONAL
|
||||
|
||||
Sets the current working directory of the entrypoint process in the container.
|
||||
This value acts as a default and may be replaced by a working directory specified when creating a container.
|
||||
|
||||
- **Labels** *object*, OPTIONAL
|
||||
|
||||
The field contains arbitrary metadata for the container.
|
||||
This property MUST use the [annotation rules](annotations.md#rules).
|
||||
|
||||
- **StopSignal** *string*, OPTIONAL
|
||||
|
||||
The field contains the system call signal that will be sent to the container to exit. The signal can be a signal name in the format `SIGNAME`, for instance `SIGKILL` or `SIGRTMIN+3`.
|
||||
|
||||
- **rootfs** *object*, REQUIRED
|
||||
|
||||
The rootfs key references the layer content addresses used by the image.
|
||||
This makes the image config hash depend on the filesystem hash.
|
||||
|
||||
- **type** *string*, REQUIRED
|
||||
|
||||
MUST be set to `layers`.
|
||||
Implementations MUST generate an error if they encounter a unknown value while verifying or unpacking an image.
|
||||
|
||||
- **diff_ids** *array of strings*, REQUIRED
|
||||
|
||||
An array of layer content hashes (`DiffIDs`), in order from first to last.
|
||||
|
||||
- **history** *array of objects*, OPTIONAL
|
||||
|
||||
Describes the history of each layer.
|
||||
The array is ordered from first to last.
|
||||
The object has the following fields:
|
||||
|
||||
- **created** *string*, OPTIONAL
|
||||
|
||||
A combined date and time at which the layer was created, formatted as defined by [RFC 3339, section 5.6][rfc3339-s5.6].
|
||||
|
||||
- **author** *string*, OPTIONAL
|
||||
|
||||
The author of the build point.
|
||||
|
||||
- **created_by** *string*, OPTIONAL
|
||||
|
||||
The command which created the layer.
|
||||
|
||||
- **comment** *string*, OPTIONAL
|
||||
|
||||
A custom message set when creating the layer.
|
||||
|
||||
- **empty_layer** *boolean*, OPTIONAL
|
||||
|
||||
This field is used to mark if the history item created a filesystem diff.
|
||||
It is set to true if this history item doesn't correspond to an actual layer in the rootfs section (for example, Dockerfile's [ENV](https://docs.docker.com/engine/reference/builder/#/env) command results in no change to the filesystem).
|
||||
|
||||
Any extra fields in the Image JSON struct are considered implementation specific and MUST be ignored by any implementations which are unable to interpret them.
|
||||
|
||||
Whitespace is OPTIONAL and implementations MAY have compact JSON with no whitespace.
|
||||
|
||||
## Example
|
||||
|
||||
Here is an example image configuration JSON document:
|
||||
|
||||
```json,title=Image%20JSON&mediatype=application/vnd.oci.image.config.v1%2Bjson
|
||||
{
|
||||
"created": "2015-10-31T22:22:56.015925234Z",
|
||||
"author": "Alyssa P. Hacker <alyspdev@example.com>",
|
||||
"architecture": "amd64",
|
||||
"os": "linux",
|
||||
"config": {
|
||||
"User": "alice",
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {}
|
||||
},
|
||||
"Env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"FOO=oci_is_a",
|
||||
"BAR=well_written_spec"
|
||||
],
|
||||
"Entrypoint": [
|
||||
"/bin/my-app-binary"
|
||||
],
|
||||
"Cmd": [
|
||||
"--foreground",
|
||||
"--config",
|
||||
"/etc/my-app.d/default.cfg"
|
||||
],
|
||||
"Volumes": {
|
||||
"/var/job-result-data": {},
|
||||
"/var/log/my-app-logs": {}
|
||||
},
|
||||
"WorkingDir": "/home/alice",
|
||||
"Labels": {
|
||||
"com.example.project.git.url": "https://example.com/project.git",
|
||||
"com.example.project.git.commit": "45a939b2999782a3f005621a8d0f29aa387e1d6b"
|
||||
}
|
||||
},
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1",
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"created": "2015-10-31T22:22:54.690851953Z",
|
||||
"created_by": "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5374fb4eef1e281fe3f282c65fb853ee171c5 in /"
|
||||
},
|
||||
{
|
||||
"created": "2015-10-31T22:22:55.613815829Z",
|
||||
"created_by": "/bin/sh -c #(nop) CMD [\"sh\"]",
|
||||
"empty_layer": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
[rfc3339-s5.6]: https://tools.ietf.org/html/rfc3339#section-5.6
|
||||
[go-environment]: https://golang.org/doc/install/source#environment
|
||||
[tar-split]: https://github.com/vbatts/tar-split
|
||||
137
vendor/github.com/opencontainers/image-spec/considerations.md
generated
vendored
Normal file
137
vendor/github.com/opencontainers/image-spec/considerations.md
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
# Extensibility
|
||||
|
||||
Implementations that are reading/processing [manifests](manifest.md) or [image indexes](image-index.md) MUST NOT generate an error if they encounter an unknown property.
|
||||
Instead they MUST ignore unknown properties.
|
||||
|
||||
# Canonicalization
|
||||
|
||||
* OCI Images are [content-addressable](https://en.wikipedia.org/wiki/Content-addressable_storage). See [descriptors](descriptor.md) for more.
|
||||
* One benefit of content-addressable storage is easy deduplication.
|
||||
* Many images might depend on a particular [layer](layer.md), but there will only be one blob in the [store](image-layout.md).
|
||||
* With a different serialization, that same semantic layer would have a different hash, and if both versions of the layer are referenced there will be two blobs with the same semantic content.
|
||||
* To allow efficient storage, implementations serializing content for blobs SHOULD use a canonical serialization.
|
||||
* This increases the chance that different implementations can push the same semantic content to the store without creating redundant blobs.
|
||||
|
||||
## JSON
|
||||
|
||||
[JSON][] content SHOULD be serialized as [canonical JSON][canonical-json].
|
||||
Of the [OCI Image Format Specification media types](media-types.md), all the types ending in `+json` contain JSON content.
|
||||
Implementations:
|
||||
|
||||
* [Go][]: [github.com/docker/go][], which claims to implement [canonical JSON][canonical-json] except for Unicode normalization.
|
||||
|
||||
[canonical-json]: http://wiki.laptop.org/go/Canonical_JSON
|
||||
[github.com/docker/go]: https://github.com/docker/go/
|
||||
[Go]: https://golang.org/
|
||||
[JSON]: http://json.org/
|
||||
|
||||
# EBNF
|
||||
|
||||
For field formats described in this specification, we use a limited subset of [Extended Backus-Naur Form][ebnf], similar to that used by the [XML specification][xmlebnf].
|
||||
Grammars present in the OCI specification are regular and can be converted to a single regular expressions.
|
||||
However, regular expressions are avoided to limit abiguity between regular expression syntax.
|
||||
By defining a subset of EBNF used here, the possibility of variation, misunderstanding or ambiguities from linking to a larger specification can be avoided.
|
||||
|
||||
Grammars are made up of rules in the following form:
|
||||
|
||||
```
|
||||
symbol ::= expression
|
||||
```
|
||||
|
||||
We can say we have the production identified by symbol if the input is matched by the expression.
|
||||
Whitespace is completely ignored in rule definitions.
|
||||
|
||||
## Expressions
|
||||
|
||||
The simplest expression is the literal, surrounded by quotes:
|
||||
|
||||
```
|
||||
literal ::= "matchthis"
|
||||
```
|
||||
|
||||
The above expression defines a symbol, "literal", that matches the exact input of "matchthis".
|
||||
Character classes are delineated by brackets (`[]`), describing either a set, range or multiple range of characters:
|
||||
|
||||
```
|
||||
set := [abc]
|
||||
range := [A-Z]
|
||||
```
|
||||
|
||||
The above symbol "set" would match one character of either "a", "b" or "c".
|
||||
The symbol "range" would match any character, "A" to "Z", inclusive.
|
||||
Currently, only matching for 7-bit ascii literals and character classes is defined, as that is all that is required by this specification.
|
||||
Multiple character ranges and explicit characters can be specified in a single character classes, as follows:
|
||||
|
||||
```
|
||||
multipleranges := [a-zA-Z=-]
|
||||
```
|
||||
|
||||
The above matches the characters in the range `A` to `Z`, `a` to `z` and the individual characters `-` and `=`.
|
||||
|
||||
Expressions can be made up of one or more expressions, such that one must be followed by the other.
|
||||
This is known as an implicit concatenation operator.
|
||||
For example, to satisfy the following rule, both `A` and `B` must be matched to satisfy the rule:
|
||||
|
||||
```
|
||||
symbol ::= A B
|
||||
```
|
||||
|
||||
Each expression must be matched once and only once, `A` followed by `B`.
|
||||
To support the description of repetition and optional match criteria, the postfix operators `*` and `+` are defined.
|
||||
`*` indicates that the preceeding expression can be matched zero or more times.
|
||||
`+` indicates that the preceeding expression must be matched one or more times.
|
||||
These appear in the following form:
|
||||
|
||||
```
|
||||
zeroormore ::= expression*
|
||||
oneormore ::= expression+
|
||||
```
|
||||
|
||||
Parentheses are used to group expressions into a larger expression:
|
||||
|
||||
```
|
||||
group ::= (A B)
|
||||
```
|
||||
|
||||
Like simpler expressions above, operators can be applied to groups, as well.
|
||||
To allow for alternates, we also define the infix operator `|`.
|
||||
|
||||
```
|
||||
oneof ::= A | B
|
||||
```
|
||||
|
||||
The above indicates that the expression should match one of the expressions, `A` or `B`.
|
||||
|
||||
## Precedence
|
||||
|
||||
The operator precedence is in the following order:
|
||||
|
||||
- Terminals (literals and character classes)
|
||||
- Grouping `()`
|
||||
- Unary operators `+*`
|
||||
- Concatenation
|
||||
- Alternates `|`
|
||||
|
||||
The precedence can be better described using grouping to show equivalents.
|
||||
Concatenation has higher precedence than alernates, such `A B | C D` is equivalent to `(A B) | (C D)`.
|
||||
Unary operators have higher precedence than alternates and concatenation, such that `A+ | B+` is equivalent to `(A+) | (B+)`.
|
||||
|
||||
## Examples
|
||||
|
||||
The following combines the previous definitions to match a simple, relative path name, describing the individual components:
|
||||
|
||||
```
|
||||
path ::= component ("/" component)*
|
||||
component ::= [a-z]+
|
||||
```
|
||||
|
||||
The production "component" is one or more lowercase letters.
|
||||
A "path" is then at least one component, possibly followed by zero or more slash-component pairs.
|
||||
The above can be converted into the following regular expression:
|
||||
|
||||
```
|
||||
[a-z]+(?:/[a-z]+)*
|
||||
```
|
||||
|
||||
[ebnf]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form
|
||||
[xmlebnf]: https://www.w3.org/TR/REC-xml/#sec-notation
|
||||
120
vendor/github.com/opencontainers/image-spec/conversion.md
generated
vendored
Normal file
120
vendor/github.com/opencontainers/image-spec/conversion.md
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
# Conversion to OCI Runtime Configuration
|
||||
|
||||
When extracting an OCI Image into an [OCI Runtime bundle][oci-runtime-bundle], two orthogonal components of the extraction are relevant:
|
||||
|
||||
1. Extraction of the root filesystem from the set of [filesystem layers](layer.md).
|
||||
2. Conversion of the [image configuration blob](config.md) to an [OCI Runtime configuration blob][oci-runtime-config].
|
||||
|
||||
This section defines how to convert an `application/vnd.oci.image.config.v1+json` blob to an [OCI runtime configuration blob][oci-runtime-config] (the latter component of extraction).
|
||||
The former component of extraction is defined [elsewhere](layer.md) and is orthogonal to configuration of a runtime bundle.
|
||||
The values of runtime configuration properties not specified by this document are implementation-defined.
|
||||
|
||||
A converter MUST rely on the OCI image configuration to build the OCI runtime configuration as described by this document; this will create the "default generated runtime configuration".
|
||||
|
||||
The "default generated runtime configuration" MAY be overridden or combined with externally provided inputs from the caller.
|
||||
In addition, a converter MAY have its own implementation-defined defaults and extensions which MAY be combined with the "default generated runtime configuration".
|
||||
The restrictions in this document refer only to combining implementation-defined defaults with the "default generated runtime configuration".
|
||||
Externally provided inputs are considered to be a modification of the `application/vnd.oci.image.config.v1+json` used as a source, and such modifications have no restrictions.
|
||||
|
||||
For example, externally provided inputs MAY cause an environment variable to be added, removed or changed.
|
||||
However an implementation-defined default SHOULD NOT result in an environment variable being removed or changed.
|
||||
|
||||
[oci-runtime-bundle]: https://github.com/opencontainers/runtime-spec/blob/v1.0.0/bundle.md
|
||||
[oci-runtime-config]: https://github.com/opencontainers/runtime-spec/blob/v1.0.0/config.md
|
||||
|
||||
## Verbatim Fields
|
||||
|
||||
Certain image configuration fields have an identical counterpart in the runtime configuration.
|
||||
Some of these are purely annotation-based fields, and have been extracted into a [separate subsection](#annotation-fields).
|
||||
A compliant configuration converter MUST extract the following fields verbatim to the corresponding field in the generated runtime configuration:
|
||||
|
||||
| Image Field | Runtime Field | Notes |
|
||||
| ------------------- | --------------- | ----- |
|
||||
| `Config.WorkingDir` | `process.cwd` | |
|
||||
| `Config.Env` | `process.env` | 1 |
|
||||
| `Config.Entrypoint` | `process.args` | 2 |
|
||||
| `Config.Cmd` | `process.args` | 2 |
|
||||
|
||||
1. The converter MAY add additional entries to `process.env` but it SHOULD NOT add entries that have variable names present in `Config.Env`.
|
||||
2. If both `Config.Entrypoint` and `Config.Cmd` are specified, the converter MUST append the value of `Config.Cmd` to the value of `Config.Entrypoint` and set `process.args` to that combined value.
|
||||
|
||||
### Annotation Fields
|
||||
|
||||
These fields all affect the `annotations` of the runtime configuration, and are thus subject to [precedence](#annotations).
|
||||
|
||||
| Image Field | Runtime Field | Notes |
|
||||
| ------------------- | --------------- | ----- |
|
||||
| `author` | `annotations` | 1,2 |
|
||||
| `created` | `annotations` | 1,3 |
|
||||
| `Config.Labels` | `annotations` | |
|
||||
| `Config.StopSignal` | `annotations` | 1,4 |
|
||||
|
||||
1. If a user has explicitly specified this annotation with `Config.Labels`, then the value specified in this field takes lower [precedence](#annotations) and the converter MUST instead use the value from `Config.Labels`.
|
||||
2. The value of this field MUST be set as the value of `org.opencontainers.image.author` in `annotations`.
|
||||
3. The value of this field MUST be set as the value of `org.opencontainers.image.created` in `annotations`.
|
||||
4. The value of this field MUST be set as the value of `org.opencontainers.image.stopSignal` in `annotations`.
|
||||
|
||||
## Parsed Fields
|
||||
|
||||
Certain image configuration fields have a counterpart that must first be translated.
|
||||
A compliant configuration converter SHOULD parse all of these fields and set the corresponding fields in the generated runtime configuration:
|
||||
|
||||
| Image Field | Runtime Field |
|
||||
| ------------------- | --------------- |
|
||||
| `Config.User` | `process.user.*` |
|
||||
|
||||
The method of parsing the above image fields are described in the following sections.
|
||||
|
||||
### `Config.User`
|
||||
|
||||
If the values of [`user` or `group`](config.md#properties) in `Config.User` are numeric (`uid` or `gid`) then the values MUST be copied verbatim to `process.user.uid` and `process.user.gid` respectively.
|
||||
If the values of [`user` or `group`](config.md#properties) in `Config.User` are not numeric (`user` or `group`) then a converter SHOULD resolve the user information using a method appropriate for the container's context.
|
||||
For Unix-like systems, this MAY involve resolution through NSS or parsing `/etc/passwd` from the extracted container's root filesystem to determine the values of `process.user.uid` and `process.user.gid`.
|
||||
|
||||
In addition, a converter SHOULD set the value of `process.user.additionalGids` to a value corresponding to the user in the container's context described by `Config.User`.
|
||||
For Unix-like systems, this MAY involve resolution through NSS or parsing `/etc/group` and determining the group memberships of the user specified in `process.user.uid`.
|
||||
If the value of [`user`](config.md#properties) in `Config.User` is numeric, the converter SHOULD NOT modify `process.user.additionalGids`.
|
||||
|
||||
If `Config.User` is not defined, the converted `process.user` value is implementation-defined.
|
||||
If `Config.User` does not correspond to a user in the container's context, the converter MUST return an error.
|
||||
|
||||
## Optional Fields
|
||||
|
||||
Certain image configuration fields are not applicable to all conversion use cases, and thus are optional for configuration converters to implement.
|
||||
A compliant configuration converter SHOULD provide a way for users to extract these fields into the generated runtime configuration:
|
||||
|
||||
| Image Field | Runtime Field | Notes |
|
||||
| --------------------- | ------------------ | ----- |
|
||||
| `Config.ExposedPorts` | `annotations` | 1 |
|
||||
| `Config.Volumes` | `mounts` | 2 |
|
||||
|
||||
1. The runtime configuration does not have a corresponding field for this image field.
|
||||
However, converters SHOULD set the [`org.opencontainers.image.exposedPorts` annotation](#config.exposedports).
|
||||
2. Implementations SHOULD provide mounts for these locations such that application data is not written to the container's root filesystem.
|
||||
If a converter implements conversion for this field using mountpoints, it SHOULD set the `destination` of the mountpoint to the value specified in `Config.Volumes`.
|
||||
An implementation MAY seed the contents of the mount with data in the image at the same location.
|
||||
If a _new_ image is created from a container based on the image described by this configuration, data in these paths SHOULD NOT be included in the _new_ image.
|
||||
The other `mounts` fields are platform and context dependent, and thus are implementation-defined.
|
||||
Note that the implementation of `Config.Volumes` need not use mountpoints, as it is effectively a mask of the filesystem.
|
||||
|
||||
### `Config.ExposedPorts`
|
||||
|
||||
The OCI runtime configuration does not provide a way of expressing the concept of "container exposed ports".
|
||||
However, converters SHOULD set the **org.opencontainers.image.exposedPorts** annotation, unless doing so will [cause a conflict](#annotations).
|
||||
|
||||
**org.opencontainers.image.exposedPorts** is the list of values that correspond to the [keys defined for `Config.ExposedPorts`](config.md) (string, comma-separated values).
|
||||
|
||||
## Annotations
|
||||
|
||||
There are three ways of annotating an OCI image in this specification:
|
||||
|
||||
1. `Config.Labels` in the [configuration](config.md) of the image.
|
||||
2. `annotations` in the [manifest](manifest.md) of the image.
|
||||
3. `annotations` in the [image index](image-index.md) of the image.
|
||||
|
||||
In addition, there are also implicit annotations that are defined by this section which are determined from the values of the image configuration.
|
||||
A converter SHOULD NOT attempt to extract annotations from [manifests](manifest.md) or [image indices](image-index.md).
|
||||
If there is a conflict (same key but different value) between an implicit annotation (or annotation in [manifests](manifest.md) or [image indices](image-index.md)) and an explicitly specified annotation in `Config.Labels`, the value specified in `Config.Labels` MUST take precedence.
|
||||
|
||||
A converter MAY add annotations which have keys not specified in the image.
|
||||
A converter MUST NOT modify the values of annotations specified in the image.
|
||||
185
vendor/github.com/opencontainers/image-spec/descriptor.md
generated
vendored
Normal file
185
vendor/github.com/opencontainers/image-spec/descriptor.md
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
# OCI Content Descriptors
|
||||
|
||||
* An OCI image consists of several different components, arranged in a [Merkle Directed Acyclic Graph (DAG)](https://en.wikipedia.org/wiki/Merkle_tree).
|
||||
* References between components in the graph are expressed through _Content Descriptors_.
|
||||
* A Content Descriptor (or simply _Descriptor_) describes the disposition of the targeted content.
|
||||
* A Content Descriptor includes the type of the content, a content identifier (_digest_), and the byte-size of the raw content.
|
||||
* Descriptors SHOULD be embedded in other formats to securely reference external content.
|
||||
* Other formats SHOULD use descriptors to securely reference external content.
|
||||
|
||||
This section defines the `application/vnd.oci.descriptor.v1+json` [media type](media-types.md).
|
||||
|
||||
## Properties
|
||||
|
||||
A descriptor consists of a set of properties encapsulated in key-value fields.
|
||||
|
||||
The following fields contain the primary properties that constitute a Descriptor:
|
||||
|
||||
- **`mediaType`** *string*
|
||||
|
||||
This REQUIRED property contains the media type of the referenced content.
|
||||
Values MUST comply with [RFC 6838][rfc6838], including the [naming requirements in its section 4.2][rfc6838-s4.2].
|
||||
|
||||
The OCI image specification defines [several of its own MIME types](media-types.md) for resources defined in the specification.
|
||||
|
||||
- **`digest`** *string*
|
||||
|
||||
This REQUIRED property is the _digest_ of the targeted content, conforming to the requirements outlined in [Digests and Verification](#digests-and-verification).
|
||||
Retrieved content SHOULD be verified against this digest when consumed via untrusted sources.
|
||||
|
||||
- **`size`** *int64*
|
||||
|
||||
This REQUIRED property specifies the size, in bytes, of the raw content.
|
||||
This property exists so that a client will have an expected size for the content before processing.
|
||||
If the length of the retrieved content does not match the specified length, the content SHOULD NOT be trusted.
|
||||
|
||||
- **`urls`** *array of strings*
|
||||
|
||||
This OPTIONAL property specifies a list of URIs from which this object MAY be downloaded.
|
||||
Each entry MUST conform to [RFC 3986][rfc3986].
|
||||
Entries SHOULD use the `http` and `https` schemes, as defined in [RFC 7230][rfc7230-s2.7].
|
||||
|
||||
- **`annotations`** *string-string map*
|
||||
|
||||
This OPTIONAL property contains arbitrary metadata for this descriptor.
|
||||
This OPTIONAL property MUST use the [annotation rules](annotations.md#rules).
|
||||
|
||||
Descriptors pointing to [`application/vnd.oci.image.manifest.v1+json`](manifest.md) SHOULD include the extended field `platform`, see [Image Index Property Descriptions](image-index.md#image-index-property-descriptions) for details.
|
||||
|
||||
### Reserved
|
||||
|
||||
The following field keys are reserved and MUST NOT be used by other specifications.
|
||||
|
||||
- **`data`** *string*
|
||||
|
||||
This key is RESERVED for future versions of the specification.
|
||||
|
||||
All other fields may be included in other OCI specifications.
|
||||
Extended _Descriptor_ field additions proposed in other OCI specifications SHOULD first be considered for addition into this specification.
|
||||
|
||||
## Digests
|
||||
|
||||
The _digest_ property of a Descriptor acts as a content identifier, enabling [content addressability](http://en.wikipedia.org/wiki/Content-addressable_storage).
|
||||
It uniquely identifies content by taking a [collision-resistant hash](https://en.wikipedia.org/wiki/Cryptographic_hash_function) of the bytes.
|
||||
If the _digest_ can be communicated in a secure manner, one can verify content from an insecure source by recalculating the digest independently, ensuring the content has not been modified.
|
||||
|
||||
The value of the `digest` property is a string consisting of an _algorithm_ portion and an _encoded_ portion.
|
||||
The _algorithm_ specifies the cryptographic hash function and encoding used for the digest; the _encoded_ portion contains the encoded result of the hash function.
|
||||
|
||||
A digest string MUST match the following [grammar](considerations.md#ebnf):
|
||||
|
||||
```
|
||||
digest ::= algorithm ":" encoded
|
||||
algorithm ::= algorithm-component (algorithm-separator algorithm-component)*
|
||||
algorithm-component ::= [a-z0-9]+
|
||||
algorithm-separator ::= [+._-]
|
||||
encoded ::= [a-zA-Z0-9=_-]+
|
||||
```
|
||||
|
||||
Note that _algorithm_ MAY impose algorithm-specific restriction on the grammar of the _encoded_ portion.
|
||||
See also [Registered Algorithms](#registered-algorithms).
|
||||
|
||||
Some example digest strings include the following:
|
||||
|
||||
digest | algorithm | Registered |
|
||||
--------------------------------------------------------------------------|---------------------|------------|
|
||||
`sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b` | [SHA-256](#sha-256) | Yes |
|
||||
`sha512:401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b372742...` | [SHA-512](#sha-512) | Yes |
|
||||
`multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8` | Multihash | No |
|
||||
`sha256+b64u:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564` | SHA-256 with urlsafe base64 | No |
|
||||
|
||||
Please see [Registered Algorithms](#registered-algorithms) for a list of registered algorithms.
|
||||
|
||||
Implementations SHOULD allow digests with unrecognized algorithms to pass validation if they comply with the above grammar.
|
||||
While `sha256` will only use hex encoded digests, separators in _algorithm_ and alphanumerics in _encoded_ are included to allow for extensions.
|
||||
As an example, we can parameterize the encoding and algorithm as `multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8`, which would be considered valid but unregistered by this specification.
|
||||
|
||||
### Verification
|
||||
|
||||
Before consuming content targeted by a descriptor from untrusted sources, the byte content SHOULD be verified against the digest string.
|
||||
Before calculating the digest, the size of the content SHOULD be verified to reduce hash collision space.
|
||||
Heavy processing before calculating a hash SHOULD be avoided.
|
||||
Implementations MAY employ [canonicalization](canonicalization.md#canonicalization) of the underlying content to ensure stable content identifiers.
|
||||
|
||||
### Digest calculations
|
||||
|
||||
A _digest_ is calculated by the following pseudo-code, where `H` is the selected hash algorithm, identified by string `<alg>`:
|
||||
```
|
||||
let ID(C) = Descriptor.digest
|
||||
let C = <bytes>
|
||||
let D = '<alg>:' + Encode(H(C))
|
||||
let verified = ID(C) == D
|
||||
```
|
||||
Above, we define the content identifier as `ID(C)`, extracted from the `Descriptor.digest` field.
|
||||
Content `C` is a string of bytes.
|
||||
Function `H` returns the hash of `C` in bytes and is passed to function `Encode` and prefixed with the algorithm to obtain the digest.
|
||||
The result `verified` is true if `ID(C)` is equal to `D`, confirming that `C` is the content identified by `D`.
|
||||
After verification, the following is true:
|
||||
|
||||
```
|
||||
D == ID(C) == '<alg>:' + Encode(H(C))
|
||||
```
|
||||
|
||||
The _digest_ is confirmed as the content identifier by independently calculating the _digest_.
|
||||
|
||||
### Registered algorithms
|
||||
|
||||
While the _algorithm_ component of the digest string allows the use of a variety of cryptographic algorithms, compliant implementations SHOULD use [SHA-256](#sha-256).
|
||||
|
||||
The following algorithm identifiers are currently defined by this specification:
|
||||
|
||||
| algorithm identifier | algorithm |
|
||||
|----------------------|---------------------|
|
||||
| `sha256` | [SHA-256](#sha-256) |
|
||||
| `sha512` | [SHA-512](#sha-512) |
|
||||
|
||||
If a useful algorithm is not included in the above table, it SHOULD be submitted to this specification for registration.
|
||||
|
||||
#### SHA-256
|
||||
|
||||
[SHA-256][rfc4634-s4.1] is a collision-resistant hash function, chosen for ubiquity, reasonable size and secure characteristics.
|
||||
Implementations MUST implement SHA-256 digest verification for use in descriptors.
|
||||
|
||||
When the _algorithm identifier_ is `sha256`, the _encoded_ portion MUST match `/[a-f0-9]{64}/`.
|
||||
Note that `[A-F]` MUST NOT be used here.
|
||||
|
||||
#### SHA-512
|
||||
|
||||
[SHA-512][rfc4634-s4.2] is a collision-resistant hash function which [may be more perfomant][sha256-vs-sha512] than [SHA-256](#sha-256) on some CPUs.
|
||||
Implementations MAY implement SHA-512 digest verification for use in descriptors.
|
||||
|
||||
When the _algorithm identifier_ is `sha512`, the _encoded_ portion MUST match `/[a-f0-9]{128}/`.
|
||||
Note that `[A-F]` MUST NOT be used here.
|
||||
|
||||
## Examples
|
||||
|
||||
The following example describes a [_Manifest_](manifest.md#image-manifest) with a content identifier of "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270" and a size of 7682 bytes:
|
||||
|
||||
```json,title=Content%20Descriptor&mediatype=application/vnd.oci.descriptor.v1%2Bjson
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
```
|
||||
|
||||
In the following example, the descriptor indicates that the referenced manifest is retrievable from a particular URL:
|
||||
|
||||
```json,title=Content%20Descriptor&mediatype=application/vnd.oci.descriptor.v1%2Bjson
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"urls": [
|
||||
"https://example.com/example-manifest"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
[rfc3986]: https://tools.ietf.org/html/rfc3986
|
||||
[rfc4634-s4.1]: https://tools.ietf.org/html/rfc4634#section-4.1
|
||||
[rfc4634-s4.2]: https://tools.ietf.org/html/rfc4634#section-4.2
|
||||
[rfc6838]: https://tools.ietf.org/html/rfc6838
|
||||
[rfc6838-s4.2]: https://tools.ietf.org/html/rfc6838#section-4.2
|
||||
[rfc7230-s2.7]: https://tools.ietf.org/html/rfc7230#section-2.7
|
||||
[sha256-vs-sha512]: https://groups.google.com/a/opencontainers.org/forum/#!topic/dev/hsMw7cAwrZE
|
||||
67
vendor/github.com/opencontainers/image-spec/identity/chainid.go
generated
vendored
Normal file
67
vendor/github.com/opencontainers/image-spec/identity/chainid.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package identity provides implementations of subtle calculations pertaining
|
||||
// to image and layer identity. The primary item present here is the ChainID
|
||||
// calculation used in identifying the result of subsequent layer applications.
|
||||
//
|
||||
// Helpers are also provided here to ease transition to the
|
||||
// github.com/opencontainers/go-digest package, but that package may be used
|
||||
// directly.
|
||||
package identity
|
||||
|
||||
import "github.com/opencontainers/go-digest"
|
||||
|
||||
// ChainID takes a slice of digests and returns the ChainID corresponding to
|
||||
// the last entry. Typically, these are a list of layer DiffIDs, with the
|
||||
// result providing the ChainID identifying the result of sequential
|
||||
// application of the preceding layers.
|
||||
func ChainID(dgsts []digest.Digest) digest.Digest {
|
||||
chainIDs := make([]digest.Digest, len(dgsts))
|
||||
copy(chainIDs, dgsts)
|
||||
ChainIDs(chainIDs)
|
||||
|
||||
if len(chainIDs) == 0 {
|
||||
return ""
|
||||
}
|
||||
return chainIDs[len(chainIDs)-1]
|
||||
}
|
||||
|
||||
// ChainIDs calculates the recursively applied chain id for each identifier in
|
||||
// the slice. The result is written direcly back into the slice such that the
|
||||
// ChainID for each item will be in the respective position.
|
||||
//
|
||||
// By definition of ChainID, the zeroth element will always be the same before
|
||||
// and after the call.
|
||||
//
|
||||
// As an example, given the chain of ids `[A, B, C]`, the result `[A,
|
||||
// ChainID(A|B), ChainID(A|B|C)]` will be written back to the slice.
|
||||
//
|
||||
// The input is provided as a return value for convenience.
|
||||
//
|
||||
// Typically, these are a list of layer DiffIDs, with the
|
||||
// result providing the ChainID for each the result of each layer application
|
||||
// sequentially.
|
||||
func ChainIDs(dgsts []digest.Digest) []digest.Digest {
|
||||
if len(dgsts) < 2 {
|
||||
return dgsts
|
||||
}
|
||||
|
||||
parent := digest.FromBytes([]byte(dgsts[0] + " " + dgsts[1]))
|
||||
next := dgsts[1:]
|
||||
next[0] = parent
|
||||
ChainIDs(next)
|
||||
|
||||
return dgsts
|
||||
}
|
||||
95
vendor/github.com/opencontainers/image-spec/identity/chainid_test.go
generated
vendored
Normal file
95
vendor/github.com/opencontainers/image-spec/identity/chainid_test.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
_ "crypto/sha256" // required to install sha256 digest support
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
func TestChainID(t *testing.T) {
|
||||
// To provide a good testing base, we define the individual links in a
|
||||
// chain recursively, illustrating the calculations for each chain.
|
||||
//
|
||||
// Note that we use invalid digests for the unmodified identifiers here to
|
||||
// make the computation more readable.
|
||||
chainDigestAB := digest.FromString("sha256:a" + " " + "sha256:b") // chain for A|B
|
||||
chainDigestABC := digest.FromString(chainDigestAB.String() + " " + "sha256:c") // chain for A|B|C
|
||||
|
||||
for _, testcase := range []struct {
|
||||
Name string
|
||||
Digests []digest.Digest
|
||||
Expected []digest.Digest
|
||||
}{
|
||||
{
|
||||
Name: "nil",
|
||||
},
|
||||
{
|
||||
Name: "empty",
|
||||
Digests: []digest.Digest{},
|
||||
Expected: []digest.Digest{},
|
||||
},
|
||||
{
|
||||
Name: "identity",
|
||||
Digests: []digest.Digest{"sha256:a"},
|
||||
Expected: []digest.Digest{"sha256:a"},
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
Digests: []digest.Digest{"sha256:a", "sha256:b"},
|
||||
Expected: []digest.Digest{"sha256:a", chainDigestAB},
|
||||
},
|
||||
{
|
||||
Name: "three",
|
||||
Digests: []digest.Digest{"sha256:a", "sha256:b", "sha256:c"},
|
||||
Expected: []digest.Digest{"sha256:a", chainDigestAB, chainDigestABC},
|
||||
},
|
||||
} {
|
||||
t.Run(testcase.Name, func(t *testing.T) {
|
||||
t.Log("before", testcase.Digests)
|
||||
|
||||
var ids []digest.Digest
|
||||
|
||||
if testcase.Digests != nil {
|
||||
ids = make([]digest.Digest, len(testcase.Digests))
|
||||
copy(ids, testcase.Digests)
|
||||
}
|
||||
|
||||
ids = ChainIDs(ids)
|
||||
t.Log("after", ids)
|
||||
if !reflect.DeepEqual(ids, testcase.Expected) {
|
||||
t.Errorf("unexpected chain: %v != %v", ids, testcase.Expected)
|
||||
}
|
||||
|
||||
if len(testcase.Digests) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Make sure parent stays stable
|
||||
if ids[0] != testcase.Digests[0] {
|
||||
t.Errorf("parent changed: %v != %v", ids[0], testcase.Digests[0])
|
||||
}
|
||||
|
||||
// make sure that the ChainID function takes the last element
|
||||
id := ChainID(testcase.Digests)
|
||||
if id != ids[len(ids)-1] {
|
||||
t.Errorf("incorrect chain id returned from ChainID: %v != %v", id, ids[len(ids)-1])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
40
vendor/github.com/opencontainers/image-spec/identity/helpers.go
generated
vendored
Normal file
40
vendor/github.com/opencontainers/image-spec/identity/helpers.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
_ "crypto/sha256" // side-effect to install impls, sha256
|
||||
_ "crypto/sha512" // side-effect to install impls, sha384/sh512
|
||||
|
||||
"io"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// FromReader consumes the content of rd until io.EOF, returning canonical
|
||||
// digest.
|
||||
func FromReader(rd io.Reader) (digest.Digest, error) {
|
||||
return digest.Canonical.FromReader(rd)
|
||||
}
|
||||
|
||||
// FromBytes digests the input and returns a Digest.
|
||||
func FromBytes(p []byte) digest.Digest {
|
||||
return digest.Canonical.FromBytes(p)
|
||||
}
|
||||
|
||||
// FromString digests the input and returns a Digest.
|
||||
func FromString(s string) digest.Digest {
|
||||
return digest.Canonical.FromString(s)
|
||||
}
|
||||
127
vendor/github.com/opencontainers/image-spec/image-index.md
generated
vendored
Normal file
127
vendor/github.com/opencontainers/image-spec/image-index.md
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
# OCI Image Index Specification
|
||||
|
||||
The image index is a higher-level manifest which points to specific [image manifests](manifest.md), ideal for one or more platforms.
|
||||
While the use of an image index is OPTIONAL for image providers, image consumers SHOULD be prepared to process them.
|
||||
|
||||
This section defines the `application/vnd.oci.image.index.v1+json` [media type](media-types.md).
|
||||
For the media type(s) that this document is compatible with, see the [matrix][matrix].
|
||||
|
||||
## *Image Index* Property Descriptions
|
||||
|
||||
- **`schemaVersion`** *int*
|
||||
|
||||
This REQUIRED property specifies the image manifest schema version.
|
||||
For this version of the specification, this MUST be `2` to ensure backward compatibility with older versions of Docker.
|
||||
The value of this field will not change.
|
||||
This field MAY be removed in a future version of the specification.
|
||||
|
||||
- **`mediaType`** *string*
|
||||
|
||||
This property is *reserved* for use, to [maintain compatibility][matrix].
|
||||
When used, this field contains the media type of this document, which differs from the [descriptor](descriptor.md#properties) use of `mediaType`.
|
||||
|
||||
- **`manifests`** *array of objects*
|
||||
|
||||
This REQUIRED property contains a list of [manifests](manifest.md) for specific platforms.
|
||||
While this property MUST be present, the size of the array MAY be zero.
|
||||
|
||||
Each object in `manifests` includes a set of [descriptor properties](descriptor.md#properties) with the following additional properties and restrictions:
|
||||
|
||||
- **`mediaType`** *string*
|
||||
|
||||
This [descriptor property](descriptor.md#properties) has additional restrictions for `manifests`.
|
||||
Implementations MUST support at least the following media types:
|
||||
|
||||
- [`application/vnd.oci.image.manifest.v1+json`](manifest.md)
|
||||
|
||||
Image indexes concerned with portability SHOULD use one of the above media types.
|
||||
Future versions of the spec MAY use a different mediatype (i.e. a new versioned format).
|
||||
An encountered `mediaType` that is unknown SHOULD be safely ignored.
|
||||
|
||||
- **`platform`** *object*
|
||||
|
||||
This OPTIONAL property describes the minimum runtime requirements of the image.
|
||||
This property SHOULD be present if its target is platform-specific.
|
||||
|
||||
- **`architecture`** *string*
|
||||
|
||||
This REQUIRED property specifies the CPU architecture.
|
||||
Image indexes SHOULD use, and implementations SHOULD understand, values listed in the Go Language document for [`GOARCH`][go-environment2].
|
||||
|
||||
- **`os`** *string*
|
||||
|
||||
This REQUIRED property specifies the operating system.
|
||||
Image indexes SHOULD use, and implementations SHOULD understand, values listed in the Go Language document for [`GOOS`][go-environment2].
|
||||
|
||||
- **`os.version`** *string*
|
||||
|
||||
This OPTIONAL property specifies the version of the operating system targeted by the referenced blob.
|
||||
Implementations MAY refuse to use manifests where `os.version` is not known to work with the host OS version.
|
||||
Valid values are implementation-defined. e.g. `10.0.14393.1066` on `windows`.
|
||||
|
||||
- **`os.features`** *array of strings*
|
||||
|
||||
This OPTIONAL property specifies an array of strings, each specifying a mandatory OS feature.
|
||||
When `os` is `windows`, image indexes SHOULD use, and implementations SHOULD understand the following values:
|
||||
- `win32k`: image requires `win32k.sys` on the host (Note: `win32k.sys` is missing on Nano Server)
|
||||
When `os` is not `windows`, values are implementation-defined and SHOULD be submitted to this specification for standardization.
|
||||
|
||||
- **`variant`** *string*
|
||||
|
||||
This OPTIONAL property specifies the variant of the CPU.
|
||||
Image indexes SHOULD use, and implementations SHOULD understand, values listed in the following table.
|
||||
When the variant of the CPU is not listed in the table, values are implementation-defined and SHOULD be submitted to this specification for standardization.
|
||||
|
||||
| ISA/ABI | `architecture` | `variant` |
|
||||
|-----------------|----------------|-------------|
|
||||
| ARM 32-bit, v6 | `arm` | `v6` |
|
||||
| ARM 32-bit, v7 | `arm` | `v7` |
|
||||
| ARM 32-bit, v8 | `arm` | `v8` |
|
||||
| ARM 64-bit, v8 | `arm64` | `v8` |
|
||||
|
||||
- **`features`** *array of strings*
|
||||
|
||||
This property is RESERVED for future versions of the specification.
|
||||
|
||||
- **`annotations`** *string-string map*
|
||||
|
||||
This OPTIONAL property contains arbitrary metadata for the image index.
|
||||
This OPTIONAL property MUST use the [annotation rules](annotations.md#rules).
|
||||
|
||||
See [Pre-Defined Annotation Keys](annotations.md#pre-defined-annotation-keys).
|
||||
|
||||
## Example Image Index
|
||||
|
||||
*Example showing a simple image index pointing to image manifests for two platforms:*
|
||||
```json,title=Image%20Index&mediatype=application/vnd.oci.image.index.v1%2Bjson
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7143,
|
||||
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"com.example.key1": "value1",
|
||||
"com.example.key2": "value2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[go-environment2]: https://golang.org/doc/install/source#environment
|
||||
[matrix]: media-types.md#compatibility-matrix
|
||||
205
vendor/github.com/opencontainers/image-spec/image-layout.md
generated
vendored
Normal file
205
vendor/github.com/opencontainers/image-spec/image-layout.md
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
## OCI Image Layout Specification
|
||||
|
||||
* The OCI Image Layout is a slash separated layout of OCI content-addressable blobs and [location-addressable](https://en.wikipedia.org/wiki/Content-addressable_storage#Content-addressed_vs._location-addressed) references (refs).
|
||||
* This layout MAY be used in a variety of different transport mechanisms: archive formats (e.g. tar, zip), shared filesystem environments (e.g. nfs), or networked file fetching (e.g. http, ftp, rsync).
|
||||
|
||||
Given an image layout and a ref, a tool can create an [OCI Runtime Specification bundle](https://github.com/opencontainers/runtime-spec/blob/v1.0.0/bundle.md) by:
|
||||
|
||||
* Following the ref to find a [manifest](manifest.md#image-manifest), possibly via an [image index](image-index.md)
|
||||
* [Applying the filesystem layers](layer.md#applying) in the specified order
|
||||
* Converting the [image configuration](config.md) into an [OCI Runtime Specification `config.json`](https://github.com/opencontainers/runtime-spec/blob/v1.0.0/config.md)
|
||||
|
||||
# Content
|
||||
|
||||
The image layout is as follows:
|
||||
|
||||
- `blobs` directory
|
||||
- Contains content-addressable blobs
|
||||
- A blob has no schema and SHOULD be considered opaque
|
||||
- Directory MUST exist and MAY be empty
|
||||
- See [blobs](#blobs) section
|
||||
- `oci-layout` file
|
||||
- It MUST exist
|
||||
- It MUST be a JSON object
|
||||
- It MUST contain an `imageLayoutVersion` field
|
||||
- See [oci-layout file](#oci-layout-file) section
|
||||
- It MAY include additional fields
|
||||
- `index.json` file
|
||||
- It MUST exist
|
||||
- It MUST be an [image index](image-index.md) JSON object.
|
||||
- See [index.json](#indexjson-file) section
|
||||
|
||||
## Example Layout
|
||||
|
||||
This is an example image layout:
|
||||
|
||||
```
|
||||
$ cd example.com/app/
|
||||
$ find . -type f
|
||||
./index.json
|
||||
./oci-layout
|
||||
./blobs/sha256/3588d02542238316759cbf24502f4344ffcc8a60c803870022f335d1390c13b4
|
||||
./blobs/sha256/4b0bc1c4050b03c95ef2a8e36e25feac42fd31283e8c30b3ee5df6b043155d3c
|
||||
./blobs/sha256/7968321274dc6b6171697c33df7815310468e694ac5be0ec03ff053bb135e768
|
||||
```
|
||||
|
||||
Blobs are named by their contents:
|
||||
|
||||
```
|
||||
$ shasum -a 256 ./blobs/sha256/afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51
|
||||
afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51 ./blobs/sha256/afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51
|
||||
```
|
||||
|
||||
## Blobs
|
||||
|
||||
* Object names in the `blobs` subdirectories are composed of a directory for each hash algorithm, the children of which will contain the actual content.
|
||||
* The content of `blobs/<alg>/<encoded>` MUST match the digest `<alg>:<encoded>` (referenced per [descriptor](descriptor.md#digests-and-verification)). For example, the content of `blobs/sha256/da39a3ee5e6b4b0d3255bfef95601890afd80709` MUST match the digest `sha256:da39a3ee5e6b4b0d3255bfef95601890afd80709`.
|
||||
* The character set of the entry name for `<alg>` and `<encoded>` MUST match the respective grammar elements described in [descriptor](descriptor.md#digests-and-verification).
|
||||
* The blobs directory MAY contain blobs which are not referenced by any of the [refs](#indexjson-file).
|
||||
* The blobs directory MAY be missing referenced blobs, in which case the missing blobs SHOULD be fulfilled by an external blob store.
|
||||
|
||||
### Example Blobs
|
||||
|
||||
```
|
||||
$ cat ./blobs/sha256/9b97579de92b1c195b85bb42a11011378ee549b02d7fe9c17bf2a6b35d5cb079 | jq
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7143,
|
||||
"digest": "sha256:afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
...
|
||||
```
|
||||
|
||||
```
|
||||
$ cat ./blobs/sha256/afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51 | jq
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 7023,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 32654,
|
||||
"digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0"
|
||||
},
|
||||
...
|
||||
```
|
||||
|
||||
```
|
||||
$ cat ./blobs/sha256/5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270 | jq
|
||||
{
|
||||
"architecture": "amd64",
|
||||
"author": "Alyssa P. Hacker <alyspdev@example.com>",
|
||||
"config": {
|
||||
"Hostname": "8dfe43d80430",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
],
|
||||
"Cmd": null,
|
||||
"Image": "sha256:6986ae504bbf843512d680cc959484452034965db15f75ee8bdd1b107f61500b",
|
||||
...
|
||||
```
|
||||
|
||||
```
|
||||
$ cat ./blobs/sha256/9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0
|
||||
[gzipped tar stream]
|
||||
```
|
||||
|
||||
## oci-layout file
|
||||
|
||||
This JSON object serves as a marker for the base of an Open Container Image Layout and to provide the version of the image-layout in use.
|
||||
The `imageLayoutVersion` value will align with the OCI Image Specification version at the time changes to the layout are made, and will pin a given version until changes to the image layout are required.
|
||||
This section defines the `application/vnd.oci.layout.header.v1+json` [media type](media-types.md).
|
||||
|
||||
### oci-layout Example
|
||||
|
||||
```json,title=OCI%20Layout&mediatype=application/vnd.oci.layout.header.v1%2Bjson
|
||||
{
|
||||
"imageLayoutVersion": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
## index.json file
|
||||
|
||||
This REQUIRED file is the entry point for references and descriptors of the image-layout.
|
||||
The [image index](image-index.md) is a multi-descriptor entry point.
|
||||
|
||||
This index provides an established path (`/index.json`) to have an entry point for an image-layout and to discover auxiliary descriptors.
|
||||
|
||||
* No semantic restriction is given for the "org.opencontainers.image.ref.name" annotation of descriptors.
|
||||
* In general the `mediaType` of each [descriptor][descriptors] object in the `manifests` field will be either `application/vnd.oci.image.index.v1+json` or `application/vnd.oci.image.manifest.v1+json`.
|
||||
* Future versions of the spec MAY use a different mediatype (i.e. a new versioned format).
|
||||
* An encountered `mediaType` that is unknown SHOULD be safely ignored.
|
||||
|
||||
|
||||
**Implementor's Note:**
|
||||
A common use case of descriptors with a "org.opencontainers.image.ref.name" annotation is representing a "tag" for a container image.
|
||||
For example, an image may have a tag for different versions or builds of the software.
|
||||
In the wild you often see "tags" like "v1.0.0-vendor.0", "2.0.0-debug", etc.
|
||||
Those tags will often be represented in an image-layout repository with matching "org.opencontainers.image.ref.name" annotations like "v1.0.0-vendor.0", "2.0.0-debug", etc.
|
||||
|
||||
|
||||
### Index Example
|
||||
|
||||
```json,title=Image%20Index&mediatype=application/vnd.oci.image.index.v1%2Bjson
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.index.v1+json",
|
||||
"size": 7143,
|
||||
"digest": "sha256:0228f90e926ba6b96e4f39cf294b2586d38fbb5a1e385c05cd1ee40ea54fe7fd",
|
||||
"annotations": {
|
||||
"org.opencontainers.image.ref.name": "stable-release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7143,
|
||||
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
},
|
||||
"annotations": {
|
||||
"org.opencontainers.image.ref.name": "v1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/xml",
|
||||
"size": 7143,
|
||||
"digest": "sha256:b3d63d132d21c3ff4c35a061adf23cf43da8ae054247e32faa95494d904a007e",
|
||||
"annotations": {
|
||||
"org.freedesktop.specifications.metainfo.version": "1.0",
|
||||
"org.freedesktop.specifications.metainfo.type": "AppStream"
|
||||
}
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"com.example.index.revision": "r124356"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This illustrates an index that provides two named manifest references and an auxiliary mediatype for this image layout.
|
||||
|
||||
|
||||
[descriptors]: ./descriptor.md
|
||||
BIN
vendor/github.com/opencontainers/image-spec/img/build-diagram.png
generated
vendored
Normal file
BIN
vendor/github.com/opencontainers/image-spec/img/build-diagram.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
12
vendor/github.com/opencontainers/image-spec/img/media-types.dot
generated
vendored
Normal file
12
vendor/github.com/opencontainers/image-spec/img/media-types.dot
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
digraph G {
|
||||
{
|
||||
imageIndex [shape=note, label="Image Index\n<<optional>>\napplication/vnd.oci.image.index.v1+json"]
|
||||
manifest [shape=note, label="Image manifest\napplication/vnd.oci.image.manifest.v1+json"]
|
||||
config [shape=note, label="Image JSON\napplication/vnd.oci.image.config.v1+json"]
|
||||
layer [shape=note, label="Layer tar archive\napplication/vnd.oci.image.layer.v1.tar\napplication/vnd.oci.image.layer.v1.tar+gzip\napplication/vnd.oci.image.layer.nondistributable.v1.tar\napplication/vnd.oci.image.layer.nondistributable.v1.tar+gzip"]
|
||||
}
|
||||
|
||||
imageIndex -> manifest [label="1..*"]
|
||||
manifest -> config [label="1..1"]
|
||||
manifest -> layer [label="1..*"]
|
||||
}
|
||||
BIN
vendor/github.com/opencontainers/image-spec/img/media-types.png
generated
vendored
Normal file
BIN
vendor/github.com/opencontainers/image-spec/img/media-types.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
BIN
vendor/github.com/opencontainers/image-spec/img/run-diagram.png
generated
vendored
Normal file
BIN
vendor/github.com/opencontainers/image-spec/img/run-diagram.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
21
vendor/github.com/opencontainers/image-spec/implementations.md
generated
vendored
Normal file
21
vendor/github.com/opencontainers/image-spec/implementations.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# OCI Image Implementations
|
||||
|
||||
Projects or Companies currently adopting the OCI Image Specification
|
||||
|
||||
* [projectatomic/skopeo](https://github.com/projectatomic/skopeo)
|
||||
* [Amazon Elastic Container Registry (ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-manifest-formats.html) ([announcement](https://aws.amazon.com/about-aws/whats-new/2017/01/amazon-ecr-supports-docker-image-manifest-v2-schema-2/))
|
||||
* [openSUSE/umoci](https://github.com/openSUSE/umoci)
|
||||
* [cloudfoundry/grootfs](https://github.com/cloudfoundry/grootfs) ([source](https://github.com/cloudfoundry/grootfs/blob/c3da26e1e463b51be1add289032f3dca6698b335/fetcher/remote/docker_src.go))
|
||||
* [Mesos plans](https://issues.apache.org/jira/browse/MESOS-5011) ([design doc](https://docs.google.com/document/d/1Pus7D-inIBoLSIPyu3rl_apxvUhtp3rp0_b0Ttr2Xww/edit#heading=h.hrvk2wboog4p))
|
||||
* [Docker](https://github.com/docker)
|
||||
- [docker/containerd](https://github.com/docker/containerd)
|
||||
- [docker/docker (`docker save/load` WIP)](https://github.com/docker/docker/pull/26369)
|
||||
- [docker/distribution (registry PR)](https://github.com/docker/distribution/pull/2076)
|
||||
* [Containers](https://github.com/containers/)
|
||||
- [containers/build](https://github.com/containers/build)
|
||||
- [containers/image](https://github.com/containers/image)
|
||||
* [coreos/rkt](https://github.com/coreos/rkt)
|
||||
* [box-builder/box](https://github.com/box-builder/box)
|
||||
|
||||
|
||||
_(to add your project please open a [pull-request](https://github.com/opencontainers/image-spec/pulls))_
|
||||
333
vendor/github.com/opencontainers/image-spec/layer.md
generated
vendored
Normal file
333
vendor/github.com/opencontainers/image-spec/layer.md
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
# Image Layer Filesystem Changeset
|
||||
|
||||
This document describes how to serialize a filesystem and filesystem changes like removed files into a blob called a layer.
|
||||
One or more layers are applied on top of each other to create a complete filesystem.
|
||||
This document will use a concrete example to illustrate how to create and consume these filesystem layers.
|
||||
|
||||
This section defines the `application/vnd.oci.image.layer.v1.tar`, `application/vnd.oci.image.layer.v1.tar+gzip`, `application/vnd.oci.image.layer.nondistributable.v1.tar`, and `application/vnd.oci.image.layer.nondistributable.v1.tar+gzip` [media types](media-types.md).
|
||||
|
||||
## `+gzip` Media Types
|
||||
|
||||
* The media type `application/vnd.oci.image.layer.v1.tar+gzip` represents an `application/vnd.oci.image.layer.v1.tar` payload which has been compressed with [gzip][rfc1952_2].
|
||||
* The media type `application/vnd.oci.image.layer.nondistributable.v1.tar+gzip` represents an `application/vnd.oci.image.layer.nondistributable.v1.tar` payload which has been compressed with [gzip][rfc1952_2].
|
||||
|
||||
## Distributable Format
|
||||
|
||||
* Layer Changesets for the [media type](media-types.md) `application/vnd.oci.image.layer.v1.tar` MUST be packaged in [tar archive][tar-archive].
|
||||
* Layer Changesets for the [media type](media-types.md) `application/vnd.oci.image.layer.v1.tar` MUST NOT include duplicate entries for file paths in the resulting [tar archive][tar-archive].
|
||||
|
||||
## Change Types
|
||||
|
||||
Types of changes that can occur in a changeset are:
|
||||
|
||||
* Additions
|
||||
* Modifications
|
||||
* Removals
|
||||
|
||||
Additions and Modifications are represented the same in the changeset tar archive.
|
||||
|
||||
Removals are represented using "[whiteout](#whiteouts)" file entries (See [Representing Changes](#representing-changes)).
|
||||
|
||||
### File Types
|
||||
|
||||
Throughout this document section, the use of word "files" or "entries" includes the following, where supported:
|
||||
|
||||
* regular files
|
||||
* directories
|
||||
* sockets
|
||||
* symbolic links
|
||||
* block devices
|
||||
* character devices
|
||||
* FIFOs
|
||||
|
||||
### File Attributes
|
||||
|
||||
Where supported, MUST include file attributes for Additions and Modifications include:
|
||||
|
||||
* Modification Time (`mtime`)
|
||||
* User ID (`uid`)
|
||||
* User Name (`uname`) *secondary to `uid`*
|
||||
* Group ID (`gid `)
|
||||
* Group Name (`gname`) *secondary to `gid`*
|
||||
* Mode (`mode`)
|
||||
* Extended Attributes (`xattrs`)
|
||||
* Symlink reference (`linkname` + symbolic link type)
|
||||
* [Hardlink](#hardlinks) reference (`linkname`)
|
||||
|
||||
[Sparse files](https://en.wikipedia.org/wiki/Sparse_file) SHOULD NOT be used because they lack consistent support across tar implementations.
|
||||
|
||||
#### Hardlinks
|
||||
|
||||
* Hardlinks are a [POSIX concept](http://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html) for having one or more directory entries for the same file on the same device.
|
||||
* Not all filesystems support hardlinks (e.g. [FAT](https://en.wikipedia.org/wiki/File_Allocation_Table)).
|
||||
* Hardlinks are possible with all [file types](#file-types) except `directories`.
|
||||
* Non-directory files are considered "hardlinked" when their link count is greater than 1.
|
||||
* Hardlinked files are on a same device (i.e. comparing Major:Minor pair) and have the same inode.
|
||||
* The corresponding files that share the link with the > 1 linkcount may be outside the directory that the changeset is being produced from, in which case the `linkname` is not recorded in the changeset.
|
||||
* Hardlinks are stored in a tar archive with type of a `1` char, per the [GNU Basic Tar Format][gnu-tar-standard] and [libarchive tar(5)][libarchive-tar].
|
||||
* While approaches to deriving new or changed hardlinks may vary, a possible approach is:
|
||||
|
||||
```
|
||||
SET LinkMap to map[< Major:Minor String >]map[< inode integer >]< path string >
|
||||
SET LinkNames to map[< src path string >]< dest path string >
|
||||
FOR each path in root path
|
||||
IF path type is directory
|
||||
CONTINUE
|
||||
ENDIF
|
||||
SET filestat to stat(path)
|
||||
IF filestat num of links == 1
|
||||
CONTINUE
|
||||
ENDIF
|
||||
IF LinkMap[filestat device][filestat inode] is not empty
|
||||
SET LinkNames[path] to LinkMap[filestat device][filestat inode]
|
||||
ELSE
|
||||
SET LinkMap[filestat device][filestat inode] to path
|
||||
ENDIF
|
||||
END FOR
|
||||
```
|
||||
|
||||
With this approach, the link map and links names of a directory could be compared against that of another directory to derive additions and changes to hardlinks.
|
||||
|
||||
#### Platform-specific attributes
|
||||
|
||||
Implementations on Windows MUST support these additional attributes, encoded in [PAX vendor
|
||||
extensions](https://github.com/libarchive/libarchive/wiki/ManPageTar5#pax-interchange-format) as follows:
|
||||
|
||||
* [Windows file attributes](https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx) (`MSWINDOWS.fileattr`)
|
||||
* [Security descriptor](https://msdn.microsoft.com/en-us/library/cc230366.aspx) (`MSWINDOWS.rawsd`): base64-encoded self-relative binary security descriptor
|
||||
* Mount points (`MSWINDOWS.mountpoint`): if present on a directory symbolic link, then the link should be created as a [directory junction](https://en.wikipedia.org/wiki/NTFS_junction_point)
|
||||
* Creation time (`LIBARCHIVE.creationtime`)
|
||||
|
||||
## Creating
|
||||
|
||||
### Initial Root Filesystem
|
||||
|
||||
The initial root filesystem is the base or parent layer.
|
||||
|
||||
For this example, an image root filesystem has an initial state as an empty directory.
|
||||
The name of the directory is not relevant to the layer itself, only for the purpose of producing comparisons.
|
||||
|
||||
Here is an initial empty directory structure for a changeset, with a unique directory name `rootfs-c9d-v1`.
|
||||
|
||||
```
|
||||
rootfs-c9d-v1/
|
||||
```
|
||||
|
||||
### Populate Initial Filesystem
|
||||
|
||||
Files and directories are then created:
|
||||
|
||||
```
|
||||
rootfs-c9d-v1/
|
||||
etc/
|
||||
my-app-config
|
||||
bin/
|
||||
my-app-binary
|
||||
my-app-tools
|
||||
```
|
||||
|
||||
The `rootfs-c9d-v1` directory is then created as a plain [tar archive][tar-archive] with relative path to `rootfs-c9d-v1`.
|
||||
Entries for the following files:
|
||||
|
||||
```
|
||||
./
|
||||
./etc/
|
||||
./etc/my-app-config
|
||||
./bin/
|
||||
./bin/my-app-binary
|
||||
./bin/my-app-tools
|
||||
```
|
||||
|
||||
### Populate a Comparison Filesystem
|
||||
|
||||
Create a new directory and initialize it with a copy or snapshot of the prior root filesystem.
|
||||
Example commands that can preserve [file attributes](#file-attributes) to make this copy are:
|
||||
* [cp(1)](http://linux.die.net/man/1/cp): `cp -a rootfs-c9d-v1/ rootfs-c9d-v1.s1/`
|
||||
* [rsync(1)](http://linux.die.net/man/1/rsync): `rsync -aHAX rootfs-c9d-v1/ rootfs-c9d-v1.s1/`
|
||||
* [tar(1)](http://linux.die.net/man/1/tar): `mkdir rootfs-c9d-v1.s1 && tar --acls --xattrs -C rootfs-c9d-v1/ -c . | tar -C rootfs-c9d-v1.s1/ --acls --xattrs -x` (including `--selinux` where supported)
|
||||
|
||||
Any [changes](#change-types) to the snapshot MUST NOT change or affect the directory it was copied from.
|
||||
|
||||
For example `rootfs-c9d-v1.s1` is an identical snapshot of `rootfs-c9d-v1`.
|
||||
In this way `rootfs-c9d-v1.s1` is prepared for updates and alterations.
|
||||
|
||||
**Implementor's Note**: *a copy-on-write or union filesystem can efficiently make directory snapshots*
|
||||
|
||||
Initial layout of the snapshot:
|
||||
|
||||
```
|
||||
rootfs-c9d-v1.s1/
|
||||
etc/
|
||||
my-app-config
|
||||
bin/
|
||||
my-app-binary
|
||||
my-app-tools
|
||||
```
|
||||
|
||||
See [Change Types](#change-types) for more details on changes.
|
||||
|
||||
For example, add a directory at `/etc/my-app.d` containing a default config file, removing the existing config file.
|
||||
Also a change (in attribute or file content) to `./bin/my-app-tools` binary to handle the config layout change.
|
||||
|
||||
Following these changes, the representation of the `rootfs-c9d-v1.s1` directory:
|
||||
|
||||
```
|
||||
rootfs-c9d-v1.s1/
|
||||
etc/
|
||||
my-app.d/
|
||||
default.cfg
|
||||
bin/
|
||||
my-app-binary
|
||||
my-app-tools
|
||||
```
|
||||
|
||||
### Determining Changes
|
||||
|
||||
When two directories are compared, the relative root is the top-level directory.
|
||||
The directories are compared, looking for files that have been [added, modified, or removed](#change-types).
|
||||
|
||||
For this example, `rootfs-c9d-v1/` and `rootfs-c9d-v1.s1/` are recursively compared, each as relative root path.
|
||||
|
||||
The following changeset is found:
|
||||
|
||||
```
|
||||
Added: /etc/my-app.d/
|
||||
Added: /etc/my-app.d/default.cfg
|
||||
Modified: /bin/my-app-tools
|
||||
Deleted: /etc/my-app-config
|
||||
```
|
||||
|
||||
This reflects the removal of `/etc/my-app-config` and creation of a file and directory at `/etc/my-app.d/default.cfg`.
|
||||
`/bin/my-app-tools` has also been replaced with an updated version.
|
||||
|
||||
### Representing Changes
|
||||
|
||||
A [tar archive][tar-archive] is then created which contains *only* this changeset:
|
||||
|
||||
- Added and modified files and directories in their entirety
|
||||
- Deleted files or directories marked with a [whiteout file](#whiteouts)
|
||||
|
||||
The resulting tar archive for `rootfs-c9d-v1.s1` has the following entries:
|
||||
|
||||
```
|
||||
./etc/my-app.d/
|
||||
./etc/my-app.d/default.cfg
|
||||
./bin/my-app-tools
|
||||
./etc/.wh.my-app-config
|
||||
```
|
||||
|
||||
To signify that the resource `./etc/my-app-config` MUST be removed when the changeset is applied, the basename of the entry is prefixed with `.wh.`.
|
||||
|
||||
## Applying Changesets
|
||||
|
||||
* Layer Changesets of [media type](media-types.md) `application/vnd.oci.image.layer.v1.tar` are _applied_, rather than simply extracted as tar archives.
|
||||
* Applying a layer changeset requires special consideration for the [whiteout](#whiteouts) files.
|
||||
* In the absence of any [whiteout](#whiteouts) files in a layer changeset, the archive is extracted like a regular tar archive.
|
||||
|
||||
### Changeset over existing files
|
||||
|
||||
This section specifies applying an entry from a layer changeset if the target path already exists.
|
||||
|
||||
If the entry and the existing path are both directories, then the existing path's attributes MUST be replaced by those of the entry in the changeset.
|
||||
In all other cases, the implementation MUST do the semantic equivalent of the following:
|
||||
- removing the file path (e.g. [`unlink(2)`](http://linux.die.net/man/2/unlink) on Linux systems)
|
||||
- recreating the file path, based on the contents and attributes of the changeset entry
|
||||
|
||||
## Whiteouts
|
||||
|
||||
* A whiteout file is an empty file with a special filename that signifies a path should be deleted.
|
||||
* A whiteout filename consists of the prefix `.wh.` plus the basename of the path to be deleted.
|
||||
* As files prefixed with `.wh.` are special whiteout markers, it is not possible to create a filesystem which has a file or directory with a name beginning with `.wh.`.
|
||||
* Once a whiteout is applied, the whiteout itself MUST also be hidden.
|
||||
* Whiteout files MUST only apply to resources in lower/parent layers.
|
||||
* Files that are present in the same layer as a whiteout file can only be hidden by whiteout files in subsequent layers.
|
||||
|
||||
The following is a base layer with several resources:
|
||||
|
||||
```
|
||||
a/
|
||||
a/b/
|
||||
a/b/c/
|
||||
a/b/c/bar
|
||||
```
|
||||
|
||||
When the next layer is created, the original `a/b` directory is deleted and recreated with `a/b/c/foo`:
|
||||
|
||||
```
|
||||
a/
|
||||
a/.wh..wh..opq
|
||||
a/b/
|
||||
a/b/c/
|
||||
a/b/c/foo
|
||||
```
|
||||
|
||||
When processing the second layer, `a/.wh..wh..opq` is applied first, before creating the new version of `a/b`, regardless of the ordering in which the whiteout file was encountered.
|
||||
For example, the following layer is equivalent to the layer above:
|
||||
|
||||
```
|
||||
a/
|
||||
a/b/
|
||||
a/b/c/
|
||||
a/b/c/foo
|
||||
a/.wh..wh..opq
|
||||
```
|
||||
|
||||
Implementations SHOULD generate layers such that the whiteout files appear before sibling directory entries.
|
||||
|
||||
### Opaque Whiteout
|
||||
|
||||
* In addition to expressing that a single entry should be removed from a lower layer, layers may remove all of the children using an opaque whiteout entry.
|
||||
* An opaque whiteout entry is a file with the name `.wh..wh..opq` indicating that all siblings are hidden in the lower layer.
|
||||
|
||||
Let's take the following base layer as an example:
|
||||
|
||||
```
|
||||
etc/
|
||||
my-app-config
|
||||
bin/
|
||||
my-app-binary
|
||||
my-app-tools
|
||||
tools/
|
||||
my-app-tool-one
|
||||
```
|
||||
|
||||
If all children of `bin/` are removed, the next layer would have the following:
|
||||
|
||||
```
|
||||
bin/
|
||||
.wh..wh..opq
|
||||
```
|
||||
|
||||
This is called _opaque whiteout_ format.
|
||||
An _opaque whiteout_ file hides _all_ children of the `bin/` including sub-directories and all descendants.
|
||||
Using _explicit whiteout_ files, this would be equivalent to the following:
|
||||
|
||||
```
|
||||
bin/
|
||||
.wh.my-app-binary
|
||||
.wh.my-app-tools
|
||||
.wh.tools
|
||||
```
|
||||
|
||||
In this case, a unique whiteout file is generated for each entry.
|
||||
If there were more children of `bin/` in the base layer, there would be an entry for each.
|
||||
Note that this opaque file will apply to _all_ children, including sub-directories, other resources and all descendants.
|
||||
|
||||
Implementations SHOULD generate layers using _explicit whiteout_ files, but MUST accept both.
|
||||
|
||||
Any given image is likely to be composed of several of these Image Filesystem Changeset tar archives.
|
||||
|
||||
# Non-Distributable Layers
|
||||
|
||||
Due to legal requirements, certain layers may not be regularly distributable.
|
||||
Such "non-distributable" layers are typically downloaded directly from a distributor but never uploaded.
|
||||
|
||||
Non-distributable layers SHOULD be tagged with an alternative mediatype of `application/vnd.oci.image.layer.nondistributable.v1.tar`.
|
||||
Implementations SHOULD NOT upload layers tagged with this media type; however, such a media type SHOULD NOT affect whether an implementation downloads the layer.
|
||||
|
||||
[Descriptors](descriptor.md) referencing non-distributable layers MAY include `urls` for downloading these layers directly; however, the presence of the `urls` field SHOULD NOT be used to determine whether or not a layer is non-distributable.
|
||||
|
||||
[libarchive-tar]: https://github.com/libarchive/libarchive/wiki/ManPageTar5#POSIX_ustar_Archives
|
||||
[gnu-tar-standard]: http://www.gnu.org/software/tar/manual/html_node/Standard.html
|
||||
[rfc1952_2]: https://tools.ietf.org/html/rfc1952
|
||||
[tar-archive]: https://en.wikipedia.org/wiki/Tar_(computing)
|
||||
106
vendor/github.com/opencontainers/image-spec/manifest.md
generated
vendored
Normal file
106
vendor/github.com/opencontainers/image-spec/manifest.md
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
# OCI Image Manifest Specification
|
||||
|
||||
There are three main goals of the Image Manifest Specification.
|
||||
The first goal is content-addressable images, by supporting an image model where the image's configuration can be hashed to generate a unique ID for the image and its components.
|
||||
The second goal is to allow multi-architecture images, through a "fat manifest" which references image manifests for platform-specific versions of an image.
|
||||
In OCI, this is codified in an [image index](image-index.md).
|
||||
The third goal is to be [translatable](conversion.md) to the [OCI Runtime Specification](https://github.com/opencontainers/runtime-spec).
|
||||
|
||||
This section defines the `application/vnd.oci.image.manifest.v1+json` [media type](media-types.md).
|
||||
For the media type(s) that this is compatible with see the [matrix](media-types.md#compatibility-matrix).
|
||||
|
||||
# Image Manifest
|
||||
|
||||
Unlike the [image index](image-index.md), which contains information about a set of images that can span a variety of architectures and operating systems, an image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system.
|
||||
|
||||
## *Image Manifest* Property Descriptions
|
||||
|
||||
- **`schemaVersion`** *int*
|
||||
|
||||
This REQUIRED property specifies the image manifest schema version.
|
||||
For this version of the specification, this MUST be `2` to ensure backward compatibility with older versions of Docker. The value of this field will not change. This field MAY be removed in a future version of the specification.
|
||||
|
||||
- **`mediaType`** *string*
|
||||
|
||||
This property is *reserved* for use, to [maintain compatibility](media-types.md#compatibility-matrix).
|
||||
When used, this field contains the media type of this document, which differs from the [descriptor](descriptor.md#properties) use of `mediaType`.
|
||||
|
||||
- **`config`** *[descriptor](descriptor.md)*
|
||||
|
||||
This REQUIRED property references a configuration object for a container, by digest.
|
||||
Beyond the [descriptor requirements](descriptor.md#properties), the value has the following additional restrictions:
|
||||
|
||||
- **`mediaType`** *string*
|
||||
|
||||
This [descriptor property](descriptor.md#properties) has additional restrictions for `config`.
|
||||
Implementations MUST support at least the following media types:
|
||||
|
||||
- [`application/vnd.oci.image.config.v1+json`](config.md)
|
||||
|
||||
Manifests concerned with portability SHOULD use one of the above media types.
|
||||
|
||||
- **`layers`** *array of objects*
|
||||
|
||||
Each item in the array MUST be a [descriptor](descriptor.md).
|
||||
The array MUST have the base layer at index 0.
|
||||
Subsequent layers MUST then follow in stack order (i.e. from `layers[0]` to `layers[len(layers)-1]`).
|
||||
The final filesystem layout MUST match the result of [applying](layer.md#applying-changesets) the layers to an empty directory.
|
||||
The [ownership, mode, and other attributes](layer.md#file-attributes) of the initial empty directory are unspecified.
|
||||
|
||||
Beyond the [descriptor requirements](descriptor.md#properties), the value has the following additional restrictions:
|
||||
|
||||
- **`mediaType`** *string*
|
||||
|
||||
This [descriptor property](descriptor.md#properties) has additional restrictions for `layers[]`.
|
||||
Implementations MUST support at least the following media types:
|
||||
|
||||
- [`application/vnd.oci.image.layer.v1.tar`](layer.md)
|
||||
- [`application/vnd.oci.image.layer.v1.tar+gzip`](layer.md#gzip-media-types)
|
||||
- [`application/vnd.oci.image.layer.nondistributable.v1.tar`](layer.md#non-distributable-layers)
|
||||
- [`application/vnd.oci.image.layer.nondistributable.v1.tar+gzip`](layer.md#gzip-media-types)
|
||||
|
||||
Manifests concerned with portability SHOULD use one of the above media types.
|
||||
|
||||
Entries in this field will frequently use the `+gzip` types.
|
||||
|
||||
- **`annotations`** *string-string map*
|
||||
|
||||
This OPTIONAL property contains arbitrary metadata for the image manifest.
|
||||
This OPTIONAL property MUST use the [annotation rules](annotations.md#rules).
|
||||
|
||||
See [Pre-Defined Annotation Keys](annotations.md#pre-defined-annotation-keys).
|
||||
|
||||
## Example Image Manifest
|
||||
|
||||
*Example showing an image manifest:*
|
||||
```json,title=Manifest&mediatype=application/vnd.oci.image.manifest.v1%2Bjson
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 7023,
|
||||
"digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 32654,
|
||||
"digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 16724,
|
||||
"digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 73109,
|
||||
"digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736"
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"com.example.key1": "value1",
|
||||
"com.example.key2": "value2"
|
||||
}
|
||||
}
|
||||
```
|
||||
68
vendor/github.com/opencontainers/image-spec/media-types.md
generated
vendored
Normal file
68
vendor/github.com/opencontainers/image-spec/media-types.md
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# OCI Image Media Types
|
||||
|
||||
The following media types identify the formats described here and their referenced resources:
|
||||
|
||||
- `application/vnd.oci.descriptor.v1+json`: [Content Descriptor](descriptor.md)
|
||||
- `application/vnd.oci.layout.header.v1+json`: [OCI Layout](image-layout.md#oci-layout-file)
|
||||
- `application/vnd.oci.image.index.v1+json`: [Image Index](image-index.md)
|
||||
- `application/vnd.oci.image.manifest.v1+json`: [Image manifest](manifest.md#image-manifest)
|
||||
- `application/vnd.oci.image.config.v1+json`: [Image config](config.md)
|
||||
- `application/vnd.oci.image.layer.v1.tar`: ["Layer", as a tar archive](layer.md)
|
||||
- `application/vnd.oci.image.layer.v1.tar+gzip`: ["Layer", as a tar archive](layer.md#gzip-media-types) compressed with [gzip][rfc1952]
|
||||
- `application/vnd.oci.image.layer.nondistributable.v1.tar`: ["Layer", as a tar archive with distribution restrictions](layer.md#non-distributable-layers)
|
||||
- `application/vnd.oci.image.layer.nondistributable.v1.tar+gzip`: ["Layer", as a tar archive with distribution restrictions](layer.md#gzip-media-types) compressed with [gzip][rfc1952]
|
||||
|
||||
## Media Type Conflicts
|
||||
|
||||
[Blob](image-layout.md) retrieval methods MAY return media type metadata.
|
||||
For example, a HTTP response might return a manifest with the Content-Type header set to `application/vnd.oci.image.manifest.v1+json`.
|
||||
Implementations MAY also have expectations for the blob's media type and digest (e.g. from a [descriptor](descriptor.md) referencing the blob).
|
||||
|
||||
* Implementations that do not have an expected media type for the blob SHOULD respect the returned media type.
|
||||
* Implementations that have an expected media type which matches the returned media type SHOULD respect the matched media type.
|
||||
* Implementations that have an expected media type which does not match the returned media type SHOULD:
|
||||
* Respect the expected media type if the blob matches the expected digest.
|
||||
Implementations MAY warn about the media type mismatch.
|
||||
* Return an error if the blob does not match the expected digest (as [recommended for descriptors](descriptor.md#properties)).
|
||||
* Return an error if they do not have an expected digest.
|
||||
|
||||
## Compatibility Matrix
|
||||
|
||||
The OCI Image Specification strives to be backwards and forwards compatible when possible.
|
||||
Breaking compatibility with existing systems creates a burden on users whether they are build systems, distribution systems, container engines, etc.
|
||||
This section shows where the OCI Image Specification is compatible with formats external to the OCI Image and different versions of this specification.
|
||||
|
||||
### application/vnd.oci.image.index.v1+json
|
||||
|
||||
**Similar/related schema**
|
||||
|
||||
- [application/vnd.docker.distribution.manifest.list.v2+json](https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md#manifest-list) - mediaType is different
|
||||
|
||||
### application/vnd.oci.image.manifest.v1+json
|
||||
|
||||
**Similar/related schema**
|
||||
|
||||
- [application/vnd.docker.distribution.manifest.v2+json](https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md#image-manifest-field-descriptions)
|
||||
|
||||
### application/vnd.oci.image.layer.v1.tar+gzip
|
||||
|
||||
**Interchangeable and fully compatible mime-types**
|
||||
|
||||
- [application/vnd.docker.image.rootfs.diff.tar.gzip](https://github.com/docker/docker/blob/master/image/spec/v1.md#creating-an-image-filesystem-changeset)
|
||||
|
||||
### application/vnd.oci.image.config.v1+json
|
||||
|
||||
**Similar/related schema**
|
||||
|
||||
- [application/vnd.docker.container.image.v1+json](https://github.com/docker/docker/blob/master/image/spec/v1.md#image-json-description)
|
||||
|
||||
## Relations
|
||||
|
||||
The following figure shows how the above media types reference each other:
|
||||
|
||||

|
||||
|
||||
[Descriptors](descriptor.md) are used for all references.
|
||||
The image-index being a "fat manifest" references a list of image manifests per target platform. An image manifest references exactly one target configuration and possibly many layers.
|
||||
|
||||
[rfc1952]: https://tools.ietf.org/html/rfc1952
|
||||
7
vendor/github.com/opencontainers/image-spec/project.md
generated
vendored
Normal file
7
vendor/github.com/opencontainers/image-spec/project.md
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Project docs
|
||||
|
||||
## Release Process
|
||||
|
||||
* `git tag` the prior commit (preferably signed tag)
|
||||
* Make a release on [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec/releases) for the version. Attach the produced docs.
|
||||
|
||||
223
vendor/github.com/opencontainers/image-spec/schema/backwards_compatibility_test.go
generated
vendored
Normal file
223
vendor/github.com/opencontainers/image-spec/schema/backwards_compatibility_test.go
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
_ "crypto/sha256"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
var compatMap = map[string]string{
|
||||
"application/vnd.docker.distribution.manifest.list.v2+json": v1.MediaTypeImageIndex,
|
||||
"application/vnd.docker.distribution.manifest.v2+json": v1.MediaTypeImageManifest,
|
||||
"application/vnd.docker.image.rootfs.diff.tar.gzip": v1.MediaTypeImageLayerGzip,
|
||||
"application/vnd.docker.container.image.v1+json": v1.MediaTypeImageConfig,
|
||||
}
|
||||
|
||||
// convertFormats converts Docker v2.2 image format JSON documents to OCI
|
||||
// format by simply replacing instances of the strings found in the compatMap
|
||||
// found in the input string.
|
||||
func convertFormats(input string) string {
|
||||
out := input
|
||||
for k, v := range compatMap {
|
||||
out = strings.Replace(out, k, v, -1)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func TestBackwardsCompatibilityImageIndex(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
imageIndex string
|
||||
digest digest.Digest
|
||||
fail bool
|
||||
}{
|
||||
{
|
||||
digest: "sha256:4ffd0883f25635999f04ea543240a27c9a4341979ff7d46a9774f71512eebb1f",
|
||||
imageIndex: `{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 2094,
|
||||
"digest": "sha256:7820f9a86d4ad15a2c4f0c0e5479298df2aa7c2f6871288e2ef8546f3e7b6783",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 1922,
|
||||
"digest": "sha256:ae1b0e06e8ade3a11267564a26e750585ba2259c0ecab59ab165ad1af41d1bdd",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 2084,
|
||||
"digest": "sha256:e4c0df75810b953d6717b8f8f28298d73870e8aa2a0d5e77b8391f16fdfbbbe2",
|
||||
"platform": {
|
||||
"architecture": "s390x",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 2084,
|
||||
"digest": "sha256:07ebe243465ef4a667b78154ae6c3ea46fdb1582936aac3ac899ea311a701b40",
|
||||
"platform": {
|
||||
"architecture": "arm",
|
||||
"os": "linux",
|
||||
"variant": "v7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"size": 2090,
|
||||
"digest": "sha256:fb2fc0707b86dafa9959fe3d29e66af8787aee4d9a23581714be65db4265ad8a",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"os": "linux",
|
||||
"variant": "v8"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`,
|
||||
fail: false,
|
||||
},
|
||||
} {
|
||||
got := digest.FromString(tt.imageIndex)
|
||||
if tt.digest != got {
|
||||
t.Errorf("test %d: expected digest %s but got %s", i, tt.digest, got)
|
||||
}
|
||||
|
||||
imageIndex := convertFormats(tt.imageIndex)
|
||||
r := strings.NewReader(imageIndex)
|
||||
err := schema.ValidatorMediaTypeImageIndex.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackwardsCompatibilityManifest(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
manifest string
|
||||
digest digest.Digest
|
||||
fail bool
|
||||
}{
|
||||
// manifest pulled from docker hub using hash value
|
||||
//
|
||||
// curl -L -H "Authorization: Bearer ..." -H \
|
||||
// "Accept: application/vnd.docker.distribution.manifest.v2+json" \
|
||||
// https://registry-1.docker.io/v2/library/docker/manifests/sha256:888206c77cd2811ec47e752ba291e5b7734e3ef137dfd222daadaca39a9f17bc
|
||||
{
|
||||
digest: "sha256:888206c77cd2811ec47e752ba291e5b7734e3ef137dfd222daadaca39a9f17bc",
|
||||
manifest: `{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"config": {
|
||||
"mediaType": "application/octet-stream",
|
||||
"size": 3210,
|
||||
"digest": "sha256:5359a4f250650c20227055957e353e8f8a74152f35fe36f00b6b1f9fc19c8861"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 2310272,
|
||||
"digest": "sha256:fae91920dcd4542f97c9350b3157139a5d901362c2abec284de5ebd1b45b4957"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 913022,
|
||||
"digest": "sha256:f384f6ab36adad485192f09379c0b58dc612a3cde82c551e082a7c29a87c95da"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 9861668,
|
||||
"digest": "sha256:ed0d2dd5e1a0e5e650a330a864c8a122e9aa91fa6ba9ac6f0bd1882e59df55e7"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 465,
|
||||
"digest": "sha256:ec4d00b58417c45f7ddcfde7bcad8c9d62a7d6d5d17cdc1f7d79bcb2e22c1491"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
fail: false,
|
||||
},
|
||||
} {
|
||||
got := digest.FromString(tt.manifest)
|
||||
if tt.digest != got {
|
||||
t.Errorf("test %d: expected digest %s but got %s", i, tt.digest, got)
|
||||
}
|
||||
|
||||
manifest := convertFormats(tt.manifest)
|
||||
r := strings.NewReader(manifest)
|
||||
err := schema.ValidatorMediaTypeManifest.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackwardsCompatibilityConfig(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
config string
|
||||
digest digest.Digest
|
||||
fail bool
|
||||
}{
|
||||
// config pulled from docker hub blob store
|
||||
//
|
||||
// $ TOKEN=$(curl https://auth.docker.io/token\?service\=registry.docker.io\&scope\=repository:library/docker:pull | jq -r .token)
|
||||
// $ CONFIG_DIGEST=$(curl -H "Authorization: Bearer ${TOKEN}" -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' https://index.docker.io/v2/library/docker/manifests/1.12.1 | jq -r .config.digest)
|
||||
// $ curl -LH "Authorization: Bearer ${TOKEN}" https://index.docker.io/v2/library/docker/blobs/${CONFIG_DIGEST}
|
||||
{
|
||||
digest: "sha256:a059ea7356d5b5a9e0f6352bfa463e7bd4721c2ade3ef168603826e0de6fe54b",
|
||||
config: `{"architecture":"amd64","config":{"Hostname":"09713501c176","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","DOCKER_BUCKET=get.docker.com","DOCKER_VERSION=1.12.1","DOCKER_SHA256=05ceec7fd937e1416e5dce12b0b6e1c655907d349d52574319a1e875077ccb79"],"Cmd":["sh"],"Image":"sha256:32e2e3ccf2a4fbaa75b078bf539cd5ea2e374a4242665a5ec3f3c01e7a3eefb8","Volumes":null,"WorkingDir":"","Entrypoint":["docker-entrypoint.sh"],"OnBuild":[],"Labels":{}},"container":"15a30be053fb3069a7879b4ea537e84689d8e8e8ba94dc4dd499271506803ba1","container_config":{"Hostname":"09713501c176","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","DOCKER_BUCKET=get.docker.com","DOCKER_VERSION=1.12.1","DOCKER_SHA256=05ceec7fd937e1416e5dce12b0b6e1c655907d349d52574319a1e875077ccb79"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"sh\"]"],"Image":"sha256:32e2e3ccf2a4fbaa75b078bf539cd5ea2e374a4242665a5ec3f3c01e7a3eefb8","Volumes":null,"WorkingDir":"","Entrypoint":["docker-entrypoint.sh"],"OnBuild":[],"Labels":{}},"created":"2016-10-10T23:04:00.821781828Z","docker_version":"1.12.1","history":[{"created":"2016-09-23T16:29:57.276868291Z","created_by":"/bin/sh -c #(nop) ADD file:d6ee3ba7a4d59b161917082cc7242c660c61bb3f3cc1549c7e2dfff2b0de7104 in / "},{"created":"2016-09-23T16:36:54.024611637Z","created_by":"/bin/sh -c apk add --no-cache \t\tca-certificates \t\tcurl \t\topenssl"},{"created":"2016-09-23T16:36:54.365914519Z","created_by":"/bin/sh -c #(nop) ENV DOCKER_BUCKET=get.docker.com","empty_layer":true},{"created":"2016-09-23T16:36:54.662005049Z","created_by":"/bin/sh -c #(nop) ENV DOCKER_VERSION=1.12.1","empty_layer":true},{"created":"2016-09-23T16:36:54.946033025Z","created_by":"/bin/sh -c #(nop) ENV DOCKER_SHA256=05ceec7fd937e1416e5dce12b0b6e1c655907d349d52574319a1e875077ccb79","empty_layer":true},{"created":"2016-09-23T16:36:58.535084011Z","created_by":"/bin/sh -c set -x \t\u0026\u0026 curl -fSL \"https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz\" -o docker.tgz \t\u0026\u0026 echo \"${DOCKER_SHA256} *docker.tgz\" | sha256sum -c - \t\u0026\u0026 tar -xzvf docker.tgz \t\u0026\u0026 mv docker/* /usr/local/bin/ \t\u0026\u0026 rmdir docker \t\u0026\u0026 rm docker.tgz \t\u0026\u0026 docker -v"},{"created":"2016-10-10T23:04:00.334158993Z","created_by":"/bin/sh -c #(nop) COPY file:399605dc1850a60a586b5494ab538bad495fd6f94eabca0c5f8a26468ce6030f in /usr/local/bin/ "},{"created":"2016-10-10T23:04:00.577900192Z","created_by":"/bin/sh -c #(nop) ENTRYPOINT [\"docker-entrypoint.sh\"]","empty_layer":true},{"created":"2016-10-10T23:04:00.821781828Z","created_by":"/bin/sh -c #(nop) CMD [\"sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:9007f5987db353ec398a223bc5a135c5a9601798ba20a1abba537ea2f8ac765f","sha256:1b06990ff0df8dad281fad7e6e4c5e91f32f8f8c095d6c74cf1e90a6f4407e28","sha256:9d12251ce74aac7619a83641ab72431a8d82e58bcd8a262c2bb0cdb280f1f3b5","sha256:17a7f292c2427adfc75c3a789bab8efec925dc38c5437bf83d2f528013ab80e2"]}}`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// fedora:23 from docker hub
|
||||
// both Entrypoint and Cmd can be nullable
|
||||
digest: "sha256:a20665eb1fe2912accb3d5dadaed360430df0d1aa46874875886947d61d3d4ee",
|
||||
config: `{"architecture":"amd64","author":"Patrick Uiterwijk \u003cpatrick@puiterwijk.org\u003e","config":{"Hostname":"8dfe43d80430","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":null,"Image":"sha256:6986ae504bbf843512d680cc959484452034965db15f75ee8bdd1b107f61500b","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"container":"6249cd2c4b1d6b1bf05903364cbcb95781508994d6407c1564d494e748ea1b41","container_config":{"Hostname":"8dfe43d80430","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ADD file:293a6e463aa402bb8f80eb5cfc937f375cedc6843abaeb9eccfe3923bb3fc80b in /"],"Image":"sha256:6986ae504bbf843512d680cc959484452034965db15f75ee8bdd1b107f61500b","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2016-06-10T18:44:31.784795904Z","docker_version":"1.10.3","history":[{"created":"2016-06-10T18:44:03.360264073Z","author":"Patrick Uiterwijk \u003cpatrick@puiterwijk.org\u003e","created_by":"/bin/sh -c #(nop) MAINTAINER Patrick Uiterwijk \u003cpatrick@puiterwijk.org\u003e","empty_layer":true},{"created":"2016-06-10T18:44:31.784795904Z","author":"Patrick Uiterwijk \u003cpatrick@puiterwijk.org\u003e","created_by":"/bin/sh -c #(nop) ADD file:293a6e463aa402bb8f80eb5cfc937f375cedc6843abaeb9eccfe3923bb3fc80b in /"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:d43f38155a799dc53d8fbb9f3bc11f51805f4027cd5c3d10b9823201cd5b9400"]}}`,
|
||||
fail: false,
|
||||
},
|
||||
} {
|
||||
got := digest.FromString(tt.config)
|
||||
if tt.digest != got {
|
||||
t.Errorf("test %d: expected digest %s but got %s", i, tt.digest, got)
|
||||
}
|
||||
|
||||
config := convertFormats(tt.config)
|
||||
r := strings.NewReader(config)
|
||||
err := schema.ValidatorMediaTypeImageConfig.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
140
vendor/github.com/opencontainers/image-spec/schema/config-schema.json
generated
vendored
Normal file
140
vendor/github.com/opencontainers/image-spec/schema/config-schema.json
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"description": "OpenContainer Config Specification",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "https://opencontainers.org/schema/image/config",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"author": {
|
||||
"type": "string"
|
||||
},
|
||||
"architecture": {
|
||||
"type": "string"
|
||||
},
|
||||
"os": {
|
||||
"type": "string"
|
||||
},
|
||||
"config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"User": {
|
||||
"type": "string"
|
||||
},
|
||||
"ExposedPorts": {
|
||||
"$ref": "defs.json#/definitions/mapStringObject"
|
||||
},
|
||||
"Env": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"Entrypoint": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Cmd": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Volumes": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "defs.json#/definitions/mapStringObject"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"WorkingDir": {
|
||||
"type": "string"
|
||||
},
|
||||
"Labels": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "defs.json#/definitions/mapStringString"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"StopSignal": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rootfs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"diff_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"layers"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"diff_ids",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"history": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"author": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_by": {
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"empty_layer": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"architecture",
|
||||
"os",
|
||||
"rootfs"
|
||||
]
|
||||
}
|
||||
242
vendor/github.com/opencontainers/image-spec/schema/config_test.go
generated
vendored
Normal file
242
vendor/github.com/opencontainers/image-spec/schema/config_test.go
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
)
|
||||
|
||||
func TestConfig(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
config string
|
||||
fail bool
|
||||
}{
|
||||
// expected failure: field "os" has numeric value, must be string
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"architecture": "amd64",
|
||||
"os": 123,
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: field "config.User" has numeric value, must be string
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"created": "2015-10-31T22:22:56.015925234Z",
|
||||
"author": "Alyssa P. Hacker <alyspdev@example.com>",
|
||||
"architecture": "amd64",
|
||||
"os": "linux",
|
||||
"config": {
|
||||
"User": 1234
|
||||
},
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failue: history has string value, must be an array
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"history": "should be an array",
|
||||
"architecture": "amd64",
|
||||
"os": 123,
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: Env has numeric value, must be a string
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"architecture": "amd64",
|
||||
"os": 123,
|
||||
"config": {
|
||||
"Env": [
|
||||
7353
|
||||
]
|
||||
},
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: config.Volumes has string array, must be an object (string set)
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"architecture": "amd64",
|
||||
"os": 123,
|
||||
"config": {
|
||||
"Volumes": [
|
||||
"/var/job-result-data",
|
||||
"/var/log/my-app-logs"
|
||||
]
|
||||
},
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failue: invalid JSON
|
||||
{
|
||||
config: `invalid JSON`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// valid config with optional fields
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"created": "2015-10-31T22:22:56.015925234Z",
|
||||
"author": "Alyssa P. Hacker <alyspdev@example.com>",
|
||||
"architecture": "amd64",
|
||||
"os": "linux",
|
||||
"config": {
|
||||
"User": "1:1",
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {}
|
||||
},
|
||||
"Env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"FOO=docker_is_a_really",
|
||||
"BAR=great_tool_you_know"
|
||||
],
|
||||
"Entrypoint": [
|
||||
"/bin/sh"
|
||||
],
|
||||
"Cmd": [
|
||||
"--foreground",
|
||||
"--config",
|
||||
"/etc/my-app.d/default.cfg"
|
||||
],
|
||||
"Volumes": {
|
||||
"/var/job-result-data": {},
|
||||
"/var/log/my-app-logs": {}
|
||||
},
|
||||
"StopSignal": "SIGKILL",
|
||||
"WorkingDir": "/home/alice",
|
||||
"Labels": {
|
||||
"com.example.project.git.url": "https://example.com/project.git",
|
||||
"com.example.project.git.commit": "45a939b2999782a3f005621a8d0f29aa387e1d6b"
|
||||
}
|
||||
},
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827",
|
||||
"sha256:2b689805fbd00b2db1df73fae47562faac1a626d5f61744bfe29946ecff5d73d"
|
||||
],
|
||||
"type": "layers"
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"created": "2015-10-31T22:22:54.690851953Z",
|
||||
"created_by": "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5374fb4eef1e281fe3f282c65fb853ee171c5 in /"
|
||||
},
|
||||
{
|
||||
"created": "2015-10-31T22:22:55.613815829Z",
|
||||
"created_by": "/bin/sh -c #(nop) CMD [\"sh\"]",
|
||||
"empty_layer": true
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// valid config with only required fields
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"architecture": "amd64",
|
||||
"os": "linux",
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
// expected failure: Env is invalid
|
||||
{
|
||||
config: `
|
||||
{
|
||||
"architecture": "amd64",
|
||||
"os": "linux",
|
||||
"config": {
|
||||
"Env": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
],
|
||||
"type": "layers"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
} {
|
||||
r := strings.NewReader(tt.config)
|
||||
err := schema.ValidatorMediaTypeImageConfig.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
33
vendor/github.com/opencontainers/image-spec/schema/content-descriptor.json
generated
vendored
Normal file
33
vendor/github.com/opencontainers/image-spec/schema/content-descriptor.json
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"description": "OpenContainer Content Descriptor Specification",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "https://opencontainers.org/schema/descriptor",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mediaType": {
|
||||
"description": "the mediatype of the referenced object",
|
||||
"$ref": "defs-descriptor.json#/definitions/mediaType"
|
||||
},
|
||||
"size": {
|
||||
"description": "the size in bytes of the referenced object",
|
||||
"$ref": "defs.json#/definitions/int64"
|
||||
},
|
||||
"digest": {
|
||||
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
|
||||
"$ref": "defs-descriptor.json#/definitions/digest"
|
||||
},
|
||||
"urls": {
|
||||
"description": "a list of urls from which this object may be downloaded",
|
||||
"$ref": "defs-descriptor.json#/definitions/urls"
|
||||
},
|
||||
"annotations": {
|
||||
"id": "https://opencontainers.org/schema/image/descriptor/annotations",
|
||||
"$ref": "defs-descriptor.json#/definitions/annotations"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mediaType",
|
||||
"size",
|
||||
"digest"
|
||||
]
|
||||
}
|
||||
27
vendor/github.com/opencontainers/image-spec/schema/defs-descriptor.json
generated
vendored
Normal file
27
vendor/github.com/opencontainers/image-spec/schema/defs-descriptor.json
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"description": "Definitions particular to OpenContainer Descriptor Specification",
|
||||
"definitions": {
|
||||
"mediaType": {
|
||||
"id": "https://opencontainers.org/schema/image/descriptor/mediaType",
|
||||
"type": "string",
|
||||
"pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}$"
|
||||
},
|
||||
"digest": {
|
||||
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
|
||||
"type": "string",
|
||||
"pattern": "^[a-z0-9]+(?:[+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$"
|
||||
},
|
||||
"urls": {
|
||||
"description": "a list of urls from which this object may be downloaded",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
}
|
||||
},
|
||||
"annotations": {
|
||||
"id": "https://opencontainers.org/schema/image/descriptor/annotations",
|
||||
"$ref": "defs.json#/definitions/mapStringString"
|
||||
}
|
||||
}
|
||||
}
|
||||
91
vendor/github.com/opencontainers/image-spec/schema/defs.json
generated
vendored
Normal file
91
vendor/github.com/opencontainers/image-spec/schema/defs.json
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"description": "Definitions used throughout the OpenContainer Specification",
|
||||
"definitions": {
|
||||
"int8": {
|
||||
"type": "integer",
|
||||
"minimum": -128,
|
||||
"maximum": 127
|
||||
},
|
||||
"int16": {
|
||||
"type": "integer",
|
||||
"minimum": -32768,
|
||||
"maximum": 32767
|
||||
},
|
||||
"int32": {
|
||||
"type": "integer",
|
||||
"minimum": -2147483648,
|
||||
"maximum": 2147483647
|
||||
},
|
||||
"int64": {
|
||||
"type": "integer",
|
||||
"minimum": -9223372036854776000,
|
||||
"maximum": 9223372036854776000
|
||||
},
|
||||
"uint8": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"uint16": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 65535
|
||||
},
|
||||
"uint32": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"uint64": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 18446744073709552000
|
||||
},
|
||||
"uint16Pointer": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/uint16"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"uint64Pointer": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/uint64"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stringPointer": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mapStringString": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
".{1,}": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mapStringObject": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
".{1,}": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
303
vendor/github.com/opencontainers/image-spec/schema/descriptor_test.go
generated
vendored
Normal file
303
vendor/github.com/opencontainers/image-spec/schema/descriptor_test.go
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
)
|
||||
|
||||
func TestDescriptor(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
descriptor string
|
||||
fail bool
|
||||
}{
|
||||
// valid descriptor
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// expected failure: mediaType missing
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: mediaType does not match pattern (no subtype)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: mediaType does not match pattern (invalid first type character)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": ".foo/bar",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: mediaType does not match pattern (invalid first subtype character)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "foo/.bar",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected success: mediaType has type and subtype as long as possible
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// expected success: mediaType does not match pattern (type too long)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678/bar",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected success: mediaType does not match pattern (subtype too long)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "foo/12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: size missing
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: size is a string, expected integer
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": "7682",
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: digest missing
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: digest does not match pattern (no algorithm)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": ":5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: digest does not match pattern (no hash)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: digest does not match pattern (invalid aglorithm characters)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "SHA256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: digest does not match pattern (characters needs to be lower for sha256)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5B0BCABD1ED22E9FB1310CF6C2DEC7CDEF19F0AD69EFA1F392E94A4333501270"
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected success: valid URL entry
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"urls": [
|
||||
"https://example.com/foo"
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// expected failure: urls does not match format (invalide url characters)
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"urls": [
|
||||
"value"
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
descriptor: `{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
descriptor: `{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
descriptor: `{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
descriptor: `
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256.foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
descriptor: `{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
// fail: repeated separators in algorithm
|
||||
descriptor: `{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+foo+-b:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
}`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
descriptor: `{
|
||||
"digest": "sha256+b64u:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
|
||||
"size": 1000000,
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json"
|
||||
}`,
|
||||
},
|
||||
{
|
||||
// test for those who cannot use modulo arithmetic to recover padding.
|
||||
descriptor: `{
|
||||
"digest": "sha256+b64u.unknownlength:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564=",
|
||||
"size": 1000000,
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json"
|
||||
}`,
|
||||
},
|
||||
} {
|
||||
r := strings.NewReader(tt.descriptor)
|
||||
err := schema.ValidatorMediaTypeDescriptor.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
16
vendor/github.com/opencontainers/image-spec/schema/doc.go
generated
vendored
Normal file
16
vendor/github.com/opencontainers/image-spec/schema/doc.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package schema defines the OCI image media types, schema definitions and validation functions.
|
||||
package schema
|
||||
44
vendor/github.com/opencontainers/image-spec/schema/error.go
generated
vendored
Normal file
44
vendor/github.com/opencontainers/image-spec/schema/error.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"go4.org/errorutil"
|
||||
)
|
||||
|
||||
// A SyntaxError is a description of a JSON syntax error
|
||||
// including line, column and offset in the JSON file.
|
||||
type SyntaxError struct {
|
||||
msg string
|
||||
Line, Col int
|
||||
Offset int64
|
||||
}
|
||||
|
||||
func (e *SyntaxError) Error() string { return e.msg }
|
||||
|
||||
// WrapSyntaxError checks whether the given error is a *json.SyntaxError
|
||||
// and converts it into a *schema.SyntaxError containing line/col information using the given reader.
|
||||
// If the given error is not a *json.SyntaxError it is returned unchanged.
|
||||
func WrapSyntaxError(r io.Reader, err error) error {
|
||||
if serr, ok := err.(*json.SyntaxError); ok {
|
||||
line, col, _ := errorutil.HighlightBytePosition(r, serr.Offset)
|
||||
return &SyntaxError{serr.Error(), line, col, serr.Offset}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
321
vendor/github.com/opencontainers/image-spec/schema/fs.go
generated
vendored
Normal file
321
vendor/github.com/opencontainers/image-spec/schema/fs.go
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/base64"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type _escLocalFS struct{}
|
||||
|
||||
var _escLocal _escLocalFS
|
||||
|
||||
type _escStaticFS struct{}
|
||||
|
||||
var _escStatic _escStaticFS
|
||||
|
||||
type _escDirectory struct {
|
||||
fs http.FileSystem
|
||||
name string
|
||||
}
|
||||
|
||||
type _escFile struct {
|
||||
compressed string
|
||||
size int64
|
||||
modtime int64
|
||||
local string
|
||||
isDir bool
|
||||
|
||||
once sync.Once
|
||||
data []byte
|
||||
name string
|
||||
}
|
||||
|
||||
func (_escLocalFS) Open(name string) (http.File, error) {
|
||||
f, present := _escData[path.Clean(name)]
|
||||
if !present {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return os.Open(f.local)
|
||||
}
|
||||
|
||||
func (_escStaticFS) prepare(name string) (*_escFile, error) {
|
||||
f, present := _escData[path.Clean(name)]
|
||||
if !present {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
var err error
|
||||
f.once.Do(func() {
|
||||
f.name = path.Base(name)
|
||||
if f.size == 0 {
|
||||
return
|
||||
}
|
||||
var gr *gzip.Reader
|
||||
b64 := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(f.compressed))
|
||||
gr, err = gzip.NewReader(b64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
f.data, err = ioutil.ReadAll(gr)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (fs _escStaticFS) Open(name string) (http.File, error) {
|
||||
f, err := fs.prepare(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f.File()
|
||||
}
|
||||
|
||||
func (dir _escDirectory) Open(name string) (http.File, error) {
|
||||
return dir.fs.Open(dir.name + name)
|
||||
}
|
||||
|
||||
func (f *_escFile) File() (http.File, error) {
|
||||
type httpFile struct {
|
||||
*bytes.Reader
|
||||
*_escFile
|
||||
}
|
||||
return &httpFile{
|
||||
Reader: bytes.NewReader(f.data),
|
||||
_escFile: f,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *_escFile) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *_escFile) Readdir(count int) ([]os.FileInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *_escFile) Stat() (os.FileInfo, error) {
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (f *_escFile) Name() string {
|
||||
return f.name
|
||||
}
|
||||
|
||||
func (f *_escFile) Size() int64 {
|
||||
return f.size
|
||||
}
|
||||
|
||||
func (f *_escFile) Mode() os.FileMode {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (f *_escFile) ModTime() time.Time {
|
||||
return time.Unix(f.modtime, 0)
|
||||
}
|
||||
|
||||
func (f *_escFile) IsDir() bool {
|
||||
return f.isDir
|
||||
}
|
||||
|
||||
func (f *_escFile) Sys() interface{} {
|
||||
return f
|
||||
}
|
||||
|
||||
// _escFS returns a http.Filesystem for the embedded assets. If useLocal is true,
|
||||
// the filesystem's contents are instead used.
|
||||
func _escFS(useLocal bool) http.FileSystem {
|
||||
if useLocal {
|
||||
return _escLocal
|
||||
}
|
||||
return _escStatic
|
||||
}
|
||||
|
||||
// _escDir returns a http.Filesystem for the embedded assets on a given prefix dir.
|
||||
// If useLocal is true, the filesystem's contents are instead used.
|
||||
func _escDir(useLocal bool, name string) http.FileSystem {
|
||||
if useLocal {
|
||||
return _escDirectory{fs: _escLocal, name: name}
|
||||
}
|
||||
return _escDirectory{fs: _escStatic, name: name}
|
||||
}
|
||||
|
||||
// _escFSByte returns the named file from the embedded assets. If useLocal is
|
||||
// true, the filesystem's contents are instead used.
|
||||
func _escFSByte(useLocal bool, name string) ([]byte, error) {
|
||||
if useLocal {
|
||||
f, err := _escLocal.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b, err := ioutil.ReadAll(f)
|
||||
f.Close()
|
||||
return b, err
|
||||
}
|
||||
f, err := _escStatic.prepare(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f.data, nil
|
||||
}
|
||||
|
||||
// _escFSMustByte is the same as _escFSByte, but panics if name is not present.
|
||||
func _escFSMustByte(useLocal bool, name string) []byte {
|
||||
b, err := _escFSByte(useLocal, name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// _escFSString is the string version of _escFSByte.
|
||||
func _escFSString(useLocal bool, name string) (string, error) {
|
||||
b, err := _escFSByte(useLocal, name)
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
// _escFSMustString is the string version of _escFSMustByte.
|
||||
func _escFSMustString(useLocal bool, name string) string {
|
||||
return string(_escFSMustByte(useLocal, name))
|
||||
}
|
||||
|
||||
var _escData = map[string]*_escFile{
|
||||
|
||||
"/config-schema.json": {
|
||||
local: "config-schema.json",
|
||||
size: 2771,
|
||||
modtime: 1498025574,
|
||||
compressed: `
|
||||
H4sIAAAJbogA/+RWQW/bPAy9+1cYbo9t/R2+U67dbgMyINh2KIZAsemEnSVqFD3MGPLfB8vJZtmym3XI
|
||||
aScDFB/f4xMl60eSplkJrmC0gmSyVZqtLZhHMqLQAKePZCrcpxsLBVZYKJ9118FuXXEArTrIQcSu8vzZ
|
||||
kbnvow/E+7xkVcn9f//nfeymx2F5hrhVnpMFU5zZnIf12TlqtYe88Pw9UloLHZZ2z1BIH7NMFlgQXLZK
|
||||
u3bSNCsYlED5KzCAOmE0fTkfr4i1km6lVAL3ghoyv3bsUzLVyIF4oVSYzcUBBQppGC7FkLs08+RFJHvg
|
||||
iI9HXPHxDw44iMwwDlh9ztvvlhyU74nFjfG3DJU3ECr30I3ATV5ChQa7UXG5VnbjK697jfH65tucLMWs
|
||||
2uxuuIQCeixjoZE0Pc6QCreW0MiYmwysu56eAoKQblHigswXpIZyR5IXVZimrsNKwzqfoxY86vKf7f0j
|
||||
1Y2GyThf2P9rp/7aXX0i/oJm/wZfdc7fqR3U17ZkE9n4a1qyEbIb3BtVX2xJMvyer18mkip6WV96/ZZY
|
||||
VVssJwZf/6475S91H9CCafRkx7NatcAuizuejFgzhq8Nsv8PP0U8GKtLhhXPnh/QCXEbMz00K2LU3PbM
|
||||
b1D07fCyW0vviMlWxN4UcYpZ/Enjdtf+RQ3SGiZ/vj8oANpKu/UTMV9kR1SDMjPzGZ6y5MQwnZvwWfX7
|
||||
2RSey6SbnWPyMwAA//9KY9sL0woAAA==
|
||||
`,
|
||||
},
|
||||
|
||||
"/content-descriptor.json": {
|
||||
local: "content-descriptor.json",
|
||||
size: 1085,
|
||||
modtime: 1498025574,
|
||||
compressed: `
|
||||
H4sIAAAJbogA/5yTwW7UMBCG73mKUVqpl27NoeIQVb3AnQPcEAevPY6nbGwznlW1oL47mniXJoAo3Vsy
|
||||
+r+Zz8n4RwfQe6yOqQjl1A/QfyiY3uUklhIy6BMmgffHUGb4WNBRIGdn4lpbXFYXcbKKR5EyGPNQc9q0
|
||||
6k3m0Xi2QTZvbk2rXTSO/AmpgzG5YHKnyXXGWtr4X9MbJ4eCSubtAzpptcK5IAth7QfQgwH0E3qyn1q4
|
||||
lf48r0SEOadNIQfQAmNAxuTQw2LGjF8yBuU8hrp5FrvRE18Yj4ESae9qnqfP7FNr0Vf6/pKPRoASbA+C
|
||||
9ZVOfxGhJG9v1xKeRqzygobjQ5E8si2RHLiI7mvdT9DYk1ZzuVZdfS1WBDnB1Z3djZlJ4nQ/3OmP9ejv
|
||||
r875jkfXlf+ed/Uf9hZ21BQ1CIHzBI+RXASJVI/OMNkDbBF8fky7bD36c+xmk5WbTSnLfDtWiv+77DTZ
|
||||
ERcrb5b9zhBc4s2zO7r2jN/2xKhin3+/McttXS9NB/Cle+p+BgAA///HjexwPQQAAA==
|
||||
`,
|
||||
},
|
||||
|
||||
"/defs-descriptor.json": {
|
||||
local: "defs-descriptor.json",
|
||||
size: 922,
|
||||
modtime: 1498025574,
|
||||
compressed: `
|
||||
H4sIAAAJbogA/6STX2/TMBTF3/spLl7FgDZN4QFp0Ria2DsP42lTV93ZN/Ed8R/ZrqYy9bsjJ1naFYFA
|
||||
PCSyj67Pub8b52kCIBRFGdgndlZUIK6oZst5F8FjSCw3LQZIDr56sl+cTciWAlwNx1yAa0+Sa5bYecx7
|
||||
09FFVJBzAIQhxfht62mUAASrnKpT8rEqS+fJyueMuHChKaPUZLBkgw2Vakwt927zZ6/Ue4uYAttmr3tM
|
||||
iUKHd3d7Wdxg8WNZnK32y1cn09fF3XoxWz0t5+8/fNyVf1c2FV3Erk8SihuK6ZDuaLhJE8iw9ck1Ab1m
|
||||
CVKT/B43Bvqz4GrIRe7+gWSaA9tuOwDA6Tm2jQuctLmozvOoFKmL03+cwMA1e/O5up0t1sVqVN6+q/L6
|
||||
srhZFmef1sVqdkS4CW38Ax9Cyz1ELoQ6OAOPmqWGpDkOVGBwC/cEyj3a1qEi9Wv/GAJu9zInMoe5vycF
|
||||
ELULBvNXEJvAYtB3LzDQWpfw5fX8n7t46Dc2PQ1UZz9FdVw8RGdPyoPfojTor7ve+/cw50l+dpOfAQAA
|
||||
//8aH/C2mgMAAA==
|
||||
`,
|
||||
},
|
||||
|
||||
"/defs.json": {
|
||||
local: "defs.json",
|
||||
size: 1670,
|
||||
modtime: 1498025574,
|
||||
compressed: `
|
||||
H4sIAAAJbogA/7STza6bMBCF9zzFyO2S9oJtbGDb7hMpy6oLSiaJq2AjY6RWEe9e8RNChFuJKneRgGc8
|
||||
3zmeMbcAgByxKa2qnTKa5EC+4klp1a8aaBs8grtY054vpnXgLgi7GvUXo12hNFo41FiqkyqLoTwceTOA
|
||||
5NBLABClXTqvAIj7XWOvprTDM9qhckhUSquqrUgOn2KaPsLFrykcUzkEu3Amx2IrmlEpfPA+vsIzuhVP
|
||||
Yy55ygT3aczJlZDgW4UyShmTNGIiTbiUIooij6Jn15N0+x/T8enQJFlxN8/GBxZJwtbozXPxoTnNeCYk
|
||||
zdb8zePw8eOUcyE5jySTUZYk1Nf8WOxNz7VLQaNxdyI5fJsCMKeG9EeLfZZ8eFt8cG9Ty+eNXeivvp9G
|
||||
t9frYvf09t3Ti1c6FPy1DhtnlT5vd3jXGOtf66kq6sOAHf99V8n8+Imle9ykunAOrd5bU6N1CptFEQD5
|
||||
fIvD7in0ryMEy+fK1G6UfmdTE+tvpoL+1wV/AgAA//96IpqyhgYAAA==
|
||||
`,
|
||||
},
|
||||
|
||||
"/image-index-schema.json": {
|
||||
local: "image-index-schema.json",
|
||||
size: 2993,
|
||||
modtime: 1498025574,
|
||||
compressed: `
|
||||
H4sIAAAJbogA/6yWv27bMBDGdz/FQQmQJYmKIuhgBFnaJVOHBl2KDAx5ki61SPVIJ3ELv3tBMrIlUXZt
|
||||
1Zt95H33+07892cGkCm0kqlxZHQ2h+xrg/qz0U6QRob7WpQI91rhG3xrUFJBUoSplz733MoKa+HzKuea
|
||||
eZ4/W6OvYvTacJkrFoW7+nCTx9hZzCPVpth5npsGtWxL2pAWZ+fky+fky8dEt2rQp5qnZ5Quxho2DbIj
|
||||
tNkcvCWALOZ/R7bRVgynbh8qslAQLhTYaA8tuAohVIZQGaIYvEQ1EBaEBtIOS+SAEJQneMr7mBup1mVS
|
||||
oyZN9bLO5vBxGxNvbSyE1nEkq4WmAq2zXfutsmAWqw67w7o772g7bbEv7+01W+jxr/Y+wvhrSYy+1o9N
|
||||
1MOjIvHg0y67YUu/BxFFJVqXbUKPHfGRhZHI9wfSBeLXQpjtPYApwuJgLJBRS1SQWAoi54yFz1ZY2Cu1
|
||||
6cm13x1nucKCNPkKNt+SdBTWqelDOP1EIA1PK4d2EusIIGn36WY33Hv/D8GTvGqcKVk0FUmQFcqfdllD
|
||||
VGhxI+Olt+H/NsI5ZA0Xt2JRGiZX1XfzW78WFaq7i+l9H66boa8lL4arJnUlYEER3U+Hgk0NrxXJCpw/
|
||||
V6IXqMUKnhCUedULIxSq6dSBaidzsxCuMFyn3Mdt5o3OgHPnNoY9WzmMCZYVOZRuyTjIA8hMz1NvD8Pe
|
||||
fZxqp+OT3ed7oTvtsI5Jl9lgwnrM5inxjD0N1PVLckueAm4jexrIAoX/Dqdu4VZ3D2b/suyWTa7Ng00C
|
||||
rP9p+0UwCZ0erof0cLbrX//IEFobFx50I6fdcV3dHlx5V3XyWdcVmY15aX+te8+ecUeTXmdjNv7HgAcN
|
||||
mOlZmY29BDtPuBnA42w9+xsAAP//IKe/nbELAAA=
|
||||
`,
|
||||
},
|
||||
|
||||
"/image-layout-schema.json": {
|
||||
local: "image-layout-schema.json",
|
||||
size: 439,
|
||||
modtime: 1498025574,
|
||||
compressed: `
|
||||
H4sIAAAJbogA/2yPQUvEMBCF7/0VQ/Sg4DYVPOW6pwVhD4IX8VDTaTvLNonJVFik/12SaRXRU5g38+W9
|
||||
91kBqA6TjRSYvFMG1DGg23vHLTmMcJjaAeGxvfiZ4cmOOLXqLlPXSQYDamQORutT8m4nau3joLvY9rxr
|
||||
HrRoV8JRtyHJaO0DOruZpYLJtaZsrM/FWEi+BMysfzuhXbUQfcDIhEkZyG2yQyYl8TPGJLVk97fth1yA
|
||||
74FHhOP+8LvyDbmy8JZ2EgZ6OuNtsS8fbrESR3LDj45unpSBl3UGUPd1UzdqnV/Lu1QAS2kS8X2miN03
|
||||
8l+PKnNL9RUAAP//k31n5bcBAAA=
|
||||
`,
|
||||
},
|
||||
|
||||
"/image-manifest-schema.json": {
|
||||
local: "image-manifest-schema.json",
|
||||
size: 921,
|
||||
modtime: 1498025574,
|
||||
compressed: `
|
||||
H4sIAAAJbogA/5ySMW8iMRCF+/0VI0MJ+O501bZXUZxSJEoTpXB2x7uDWNsZmygo4r9HtnHAkCKifTvv
|
||||
zTdv/dEAiB59x+QCWSNaEHcOzT9rgiKDDOtJDQj/lSGNPsC9w440dSpNL6J97rsRJxWtYwiulXLjrVlm
|
||||
dWV5kD0rHZa//sqszbKP+mLxrZTWoenKVp9seVpSJJDTkSB7w95hdNuXDXZHzbF1yIHQixbiYQAiRzwi
|
||||
+3xclq9vfhjJgybc9uDzheghjAhpOZTlkPPgLQeC8qAMkAk4ICeKFH7bZbKG/Uort16tmcjQtJtEC39O
|
||||
mnovWpIO+YvorNE0nDcwZ9QxNqKhCcvSiOVV/H+ism/VHtmf2wuVYlb7imkdcIqjv099HJVi/ul2gENF
|
||||
oYyxIb28CuXGus/TFpet9Kj9JdRM9qjJULJU9qawJlLB+Lojxoj19N07rP9JXXED8Nwcms8AAAD//7u3
|
||||
Dj+ZAwAA
|
||||
`,
|
||||
},
|
||||
|
||||
"/": {
|
||||
isDir: true,
|
||||
local: "/",
|
||||
},
|
||||
}
|
||||
21
vendor/github.com/opencontainers/image-spec/schema/gen.go
generated
vendored
Normal file
21
vendor/github.com/opencontainers/image-spec/schema/gen.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema
|
||||
|
||||
// Generates an embbedded http.FileSystem for all schema files
|
||||
// using esc (https://github.com/mjibson/esc).
|
||||
|
||||
// This should generally be invoked with `make schema-fs`
|
||||
//go:generate esc -private -pkg=schema -include=.*\.json$ .
|
||||
89
vendor/github.com/opencontainers/image-spec/schema/image-index-schema.json
generated
vendored
Normal file
89
vendor/github.com/opencontainers/image-spec/schema/image-index-schema.json
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"description": "OpenContainer Image Index Specification",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "https://opencontainers.org/schema/image/index",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"schemaVersion": {
|
||||
"description": "This field specifies the image index schema version as an integer",
|
||||
"id": "https://opencontainers.org/schema/image/index/schemaVersion",
|
||||
"type": "integer",
|
||||
"minimum": 2,
|
||||
"maximum": 2
|
||||
},
|
||||
"manifests": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"id": "https://opencontainers.org/schema/image/manifestDescriptor",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"mediaType",
|
||||
"size",
|
||||
"digest"
|
||||
],
|
||||
"properties": {
|
||||
"mediaType": {
|
||||
"description": "the mediatype of the referenced object",
|
||||
"$ref": "defs-descriptor.json#/definitions/mediaType"
|
||||
},
|
||||
"size": {
|
||||
"description": "the size in bytes of the referenced object",
|
||||
"$ref": "defs.json#/definitions/int64"
|
||||
},
|
||||
"digest": {
|
||||
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
|
||||
"$ref": "defs-descriptor.json#/definitions/digest"
|
||||
},
|
||||
"urls": {
|
||||
"description": "a list of urls from which this object may be downloaded",
|
||||
"$ref": "defs-descriptor.json#/definitions/urls"
|
||||
},
|
||||
"platform": {
|
||||
"id": "https://opencontainers.org/schema/image/platform",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"architecture",
|
||||
"os"
|
||||
],
|
||||
"properties": {
|
||||
"architecture": {
|
||||
"id": "https://opencontainers.org/schema/image/platform/architecture",
|
||||
"type": "string"
|
||||
},
|
||||
"os": {
|
||||
"id": "https://opencontainers.org/schema/image/platform/os",
|
||||
"type": "string"
|
||||
},
|
||||
"os.version": {
|
||||
"id": "https://opencontainers.org/schema/image/platform/os.version",
|
||||
"type": "string"
|
||||
},
|
||||
"os.features": {
|
||||
"id": "https://opencontainers.org/schema/image/platform/os.features",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"variant": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"annotations": {
|
||||
"id": "https://opencontainers.org/schema/image/descriptor/annotations",
|
||||
"$ref": "defs-descriptor.json#/definitions/annotations"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"annotations": {
|
||||
"id": "https://opencontainers.org/schema/image/index/annotations",
|
||||
"$ref": "defs-descriptor.json#/definitions/annotations"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"schemaVersion",
|
||||
"manifests"
|
||||
]
|
||||
}
|
||||
18
vendor/github.com/opencontainers/image-spec/schema/image-layout-schema.json
generated
vendored
Normal file
18
vendor/github.com/opencontainers/image-spec/schema/image-layout-schema.json
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"description": "OpenContainer Image Layout Schema",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "https://opencontainers.org/schema/image/layout",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"imageLayoutVersion": {
|
||||
"description": "version of the OCI Image Layout (in the oci-layout file)",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"1.0.0"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageLayoutVersion"
|
||||
]
|
||||
}
|
||||
34
vendor/github.com/opencontainers/image-spec/schema/image-manifest-schema.json
generated
vendored
Normal file
34
vendor/github.com/opencontainers/image-spec/schema/image-manifest-schema.json
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"description": "OpenContainer Image Manifest Specification",
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "https://opencontainers.org/schema/image/manifest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"schemaVersion": {
|
||||
"description": "This field specifies the image manifest schema version as an integer",
|
||||
"id": "https://opencontainers.org/schema/image/manifest/schemaVersion",
|
||||
"type": "integer",
|
||||
"minimum": 2,
|
||||
"maximum": 2
|
||||
},
|
||||
"config": {
|
||||
"$ref": "content-descriptor.json"
|
||||
},
|
||||
"layers": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "content-descriptor.json"
|
||||
}
|
||||
},
|
||||
"annotations": {
|
||||
"id": "https://opencontainers.org/schema/image/manifest/annotations",
|
||||
"$ref": "defs-descriptor.json#/definitions/annotations"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"schemaVersion",
|
||||
"config",
|
||||
"layers"
|
||||
]
|
||||
}
|
||||
232
vendor/github.com/opencontainers/image-spec/schema/imageindex_test.go
generated
vendored
Normal file
232
vendor/github.com/opencontainers/image-spec/schema/imageindex_test.go
generated
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
)
|
||||
|
||||
func TestImageIndex(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
imageIndex string
|
||||
fail bool
|
||||
}{
|
||||
// expected failure: mediaType does not match pattern
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "invalid",
|
||||
"size": 7143,
|
||||
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: manifest.size is string, expected integer
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": "7682",
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: manifest.digest is missing, expected required
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: in the optional field platform platform.architecture is missing, expected required
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"platform": {
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: invalid referenced manifest media type
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "invalid",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: empty referenced manifest media type
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// valid image index, with optional fields
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7143,
|
||||
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7682,
|
||||
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"com.example.key1": "value1",
|
||||
"com.example.key2": "value2"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// valid image index, with required fields only
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 7143,
|
||||
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// valid image index, with customized media type of referenced manifest
|
||||
{
|
||||
imageIndex: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/customized.manifest+json",
|
||||
"size": 7143,
|
||||
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
|
||||
"platform": {
|
||||
"architecture": "ppc64le",
|
||||
"os": "linux"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
} {
|
||||
r := strings.NewReader(tt.imageIndex)
|
||||
err := schema.ValidatorMediaTypeImageIndex.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
56
vendor/github.com/opencontainers/image-spec/schema/imagelayout_test.go
generated
vendored
Normal file
56
vendor/github.com/opencontainers/image-spec/schema/imagelayout_test.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
)
|
||||
|
||||
func TestImageLayout(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
imageLayout string
|
||||
fail bool
|
||||
}{
|
||||
// expected faulure: imageLayoutVersion does not match pattern
|
||||
{
|
||||
imageLayout: `
|
||||
{
|
||||
"imageLayoutVersion": 1.0.0
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// validate layout
|
||||
{
|
||||
imageLayout: `
|
||||
{
|
||||
"imageLayoutVersion": "1.0.0"
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
} {
|
||||
r := strings.NewReader(tt.imageLayout)
|
||||
err := schema.ValidatorMediaTypeLayoutHeader.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
239
vendor/github.com/opencontainers/image-spec/schema/manifest_test.go
generated
vendored
Normal file
239
vendor/github.com/opencontainers/image-spec/schema/manifest_test.go
generated
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
)
|
||||
|
||||
func TestManifest(t *testing.T) {
|
||||
for i, tt := range []struct {
|
||||
manifest string
|
||||
fail bool
|
||||
}{
|
||||
// expected failure: mediaType does not match pattern
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "invalid",
|
||||
"size": 1470,
|
||||
"digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 148,
|
||||
"digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: config.size is a string, expected integer
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": "1470",
|
||||
"digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 148,
|
||||
"digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected failure: layers.size is string, expected integer
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": "675598",
|
||||
"digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// valid manifest with optional fields
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 675598,
|
||||
"digest": "sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 156,
|
||||
"digest": "sha256:2b689805fbd00b2db1df73fae47562faac1a626d5f61744bfe29946ecff5d73d"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 148,
|
||||
"digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"key1": "value1",
|
||||
"key2": "value2"
|
||||
}
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// valid manifest with only required fields
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 675598,
|
||||
"digest": "sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 156,
|
||||
"digest": "sha256:2b689805fbd00b2db1df73fae47562faac1a626d5f61744bfe29946ecff5d73d"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
|
||||
"size": 148,
|
||||
"digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: false,
|
||||
},
|
||||
|
||||
// expected failure: empty layer, expected at least one
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": []
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
|
||||
// expected pass: test bounds of algorithm field in digest.
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256.foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
},
|
||||
|
||||
// expected failure: push bounds of algorithm field in digest too far.
|
||||
{
|
||||
manifest: `
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"config": {
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.config.v1+json",
|
||||
"size": 1470,
|
||||
"digest": "sha256+foo+-b:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
|
||||
}
|
||||
]
|
||||
}
|
||||
`,
|
||||
fail: true,
|
||||
},
|
||||
} {
|
||||
r := strings.NewReader(tt.manifest)
|
||||
err := schema.ValidatorMediaTypeManifest.Validate(r)
|
||||
|
||||
if got := err != nil; tt.fail != got {
|
||||
t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
52
vendor/github.com/opencontainers/image-spec/schema/schema.go
generated
vendored
Normal file
52
vendor/github.com/opencontainers/image-spec/schema/schema.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// Media types for the OCI image formats
|
||||
const (
|
||||
ValidatorMediaTypeDescriptor Validator = v1.MediaTypeDescriptor
|
||||
ValidatorMediaTypeLayoutHeader Validator = v1.MediaTypeLayoutHeader
|
||||
ValidatorMediaTypeManifest Validator = v1.MediaTypeImageManifest
|
||||
ValidatorMediaTypeImageIndex Validator = v1.MediaTypeImageIndex
|
||||
ValidatorMediaTypeImageConfig Validator = v1.MediaTypeImageConfig
|
||||
ValidatorMediaTypeImageLayer unimplemented = v1.MediaTypeImageLayer
|
||||
)
|
||||
|
||||
var (
|
||||
// fs stores the embedded http.FileSystem
|
||||
// having the OCI JSON schema files in root "/".
|
||||
fs = _escFS(false)
|
||||
|
||||
// specs maps OCI schema media types to schema files.
|
||||
specs = map[Validator]string{
|
||||
ValidatorMediaTypeDescriptor: "content-descriptor.json",
|
||||
ValidatorMediaTypeLayoutHeader: "image-layout-schema.json",
|
||||
ValidatorMediaTypeManifest: "image-manifest-schema.json",
|
||||
ValidatorMediaTypeImageIndex: "image-index-schema.json",
|
||||
ValidatorMediaTypeImageConfig: "config-schema.json",
|
||||
}
|
||||
)
|
||||
|
||||
// FileSystem returns an in-memory filesystem including the schema files.
|
||||
// The schema files are located at the root directory.
|
||||
func FileSystem() http.FileSystem {
|
||||
return fs
|
||||
}
|
||||
191
vendor/github.com/opencontainers/image-spec/schema/spec_test.go
generated
vendored
Normal file
191
vendor/github.com/opencontainers/image-spec/schema/spec_test.go
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/russross/blackfriday"
|
||||
)
|
||||
|
||||
var (
|
||||
errFormatInvalid = errors.New("format: invalid")
|
||||
)
|
||||
|
||||
func TestValidateDescriptor(t *testing.T) {
|
||||
validate(t, "../descriptor.md")
|
||||
}
|
||||
|
||||
func TestValidateManifest(t *testing.T) {
|
||||
validate(t, "../manifest.md")
|
||||
}
|
||||
|
||||
func TestValidateImageIndex(t *testing.T) {
|
||||
validate(t, "../image-index.md")
|
||||
}
|
||||
|
||||
func TestValidateImageLayout(t *testing.T) {
|
||||
validate(t, "../image-layout.md")
|
||||
}
|
||||
|
||||
func TestValidateConfig(t *testing.T) {
|
||||
validate(t, "../config.md")
|
||||
}
|
||||
|
||||
// TODO(sur): include examples from all specification files
|
||||
func validate(t *testing.T, name string) {
|
||||
m, err := os.Open(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer m.Close()
|
||||
|
||||
examples, err := extractExamples(m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, example := range examples {
|
||||
if example.Err == errFormatInvalid && example.Mediatype == "" { // ignore
|
||||
continue
|
||||
}
|
||||
|
||||
if example.Err != nil {
|
||||
printFields(t, "error", example.Mediatype, example.Title, example.Err)
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
err = schema.Validator(example.Mediatype).Validate(strings.NewReader(example.Body))
|
||||
if err == nil {
|
||||
printFields(t, "ok", example.Mediatype, example.Title)
|
||||
t.Log(example.Body, "---")
|
||||
continue
|
||||
}
|
||||
|
||||
var errs []error
|
||||
if verr, ok := errors.Cause(err).(schema.ValidationError); ok {
|
||||
errs = verr.Errs
|
||||
} else {
|
||||
printFields(t, "error", example.Mediatype, example.Title, err)
|
||||
t.Error(err)
|
||||
t.Log(example.Body, "---")
|
||||
continue
|
||||
}
|
||||
|
||||
for _, err := range errs {
|
||||
// TOOD(stevvooe): This is nearly useless without file, line no.
|
||||
printFields(t, "invalid", example.Mediatype, example.Title)
|
||||
t.Error(err)
|
||||
fmt.Println(example.Body, "---")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// renderer allows one to incercept fenced blocks in markdown documents.
|
||||
type renderer struct {
|
||||
blackfriday.Renderer
|
||||
fn func(text []byte, lang string)
|
||||
}
|
||||
|
||||
func (r *renderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
|
||||
r.fn(text, lang)
|
||||
r.Renderer.BlockCode(out, text, lang)
|
||||
}
|
||||
|
||||
type example struct {
|
||||
Lang string // gets raw "lang" field
|
||||
Title string
|
||||
Mediatype string
|
||||
Body string
|
||||
Err error
|
||||
|
||||
// TODO(stevvooe): Figure out how to keep track of revision, file, line so
|
||||
// that we can trace back verification output.
|
||||
}
|
||||
|
||||
// parseExample treats the field as a syntax,attribute tuple separated by a comma.
|
||||
// Attributes are encoded as a url values.
|
||||
//
|
||||
// An example of this is `json,title=Foo%20Bar&mediatype=application/json. We
|
||||
// get that the "lang" is json, the title is "Foo Bar" and the mediatype is
|
||||
// "application/json".
|
||||
//
|
||||
// This preserves syntax highlighting and lets us tag examples with further
|
||||
// metadata.
|
||||
func parseExample(lang, body string) (e example) {
|
||||
e.Lang = lang
|
||||
e.Body = body
|
||||
|
||||
parts := strings.SplitN(lang, ",", 2)
|
||||
if len(parts) < 2 {
|
||||
e.Err = errFormatInvalid
|
||||
return
|
||||
}
|
||||
|
||||
m, err := url.ParseQuery(parts[1])
|
||||
if err != nil {
|
||||
e.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
e.Mediatype = m.Get("mediatype")
|
||||
e.Title = m.Get("title")
|
||||
return
|
||||
}
|
||||
|
||||
func extractExamples(rd io.Reader) ([]example, error) {
|
||||
p, err := ioutil.ReadAll(rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var examples []example
|
||||
renderer := &renderer{
|
||||
Renderer: blackfriday.HtmlRenderer(0, "test test", ""),
|
||||
fn: func(text []byte, lang string) {
|
||||
examples = append(examples, parseExample(lang, string(text)))
|
||||
},
|
||||
}
|
||||
|
||||
// just pass over the markdown and ignore the rendered result. We just want
|
||||
// the side-effect of calling back for each code block.
|
||||
// TODO(stevvooe): Consider just parsing these with a scanner. It will be
|
||||
// faster and we can retain file, line no.
|
||||
blackfriday.MarkdownOptions(p, renderer, blackfriday.Options{
|
||||
Extensions: blackfriday.EXTENSION_FENCED_CODE,
|
||||
})
|
||||
|
||||
return examples, nil
|
||||
}
|
||||
|
||||
// printFields prints each value tab separated.
|
||||
func printFields(t *testing.T, vs ...interface{}) {
|
||||
var ss []string
|
||||
for _, f := range vs {
|
||||
ss = append(ss, fmt.Sprint(f))
|
||||
}
|
||||
t.Log(strings.Join(ss, "\t"))
|
||||
}
|
||||
224
vendor/github.com/opencontainers/image-spec/schema/validator.go
generated
vendored
Normal file
224
vendor/github.com/opencontainers/image-spec/schema/validator.go
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
)
|
||||
|
||||
// Validator wraps a media type string identifier
|
||||
// and implements validation against a JSON schema.
|
||||
type Validator string
|
||||
|
||||
type validateFunc func(r io.Reader) error
|
||||
|
||||
var mapValidate = map[Validator]validateFunc{
|
||||
ValidatorMediaTypeImageConfig: validateConfig,
|
||||
ValidatorMediaTypeDescriptor: validateDescriptor,
|
||||
ValidatorMediaTypeImageIndex: validateIndex,
|
||||
ValidatorMediaTypeManifest: validateManifest,
|
||||
}
|
||||
|
||||
// ValidationError contains all the errors that happened during validation.
|
||||
type ValidationError struct {
|
||||
Errs []error
|
||||
}
|
||||
|
||||
func (e ValidationError) Error() string {
|
||||
return fmt.Sprintf("%v", e.Errs)
|
||||
}
|
||||
|
||||
// Validate validates the given reader against the schema of the wrapped media type.
|
||||
func (v Validator) Validate(src io.Reader) error {
|
||||
buf, err := ioutil.ReadAll(src)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to read the document file")
|
||||
}
|
||||
|
||||
if f, ok := mapValidate[v]; ok {
|
||||
if f == nil {
|
||||
return fmt.Errorf("internal error: mapValidate[%q] is nil", v)
|
||||
}
|
||||
err = f(bytes.NewReader(buf))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
sl := gojsonschema.NewReferenceLoaderFileSystem("file:///"+specs[v], fs)
|
||||
ml := gojsonschema.NewStringLoader(string(buf))
|
||||
|
||||
result, err := gojsonschema.Validate(sl, ml)
|
||||
if err != nil {
|
||||
return errors.Wrapf(
|
||||
WrapSyntaxError(bytes.NewReader(buf), err),
|
||||
"schema %s: unable to validate", v)
|
||||
}
|
||||
|
||||
if result.Valid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
errs := make([]error, 0, len(result.Errors()))
|
||||
for _, desc := range result.Errors() {
|
||||
errs = append(errs, fmt.Errorf("%s", desc))
|
||||
}
|
||||
|
||||
return ValidationError{
|
||||
Errs: errs,
|
||||
}
|
||||
}
|
||||
|
||||
type unimplemented string
|
||||
|
||||
func (v unimplemented) Validate(src io.Reader) error {
|
||||
return fmt.Errorf("%s: unimplemented", v)
|
||||
}
|
||||
|
||||
func validateManifest(r io.Reader) error {
|
||||
header := v1.Manifest{}
|
||||
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error reading the io stream")
|
||||
}
|
||||
|
||||
err = json.Unmarshal(buf, &header)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manifest format mismatch")
|
||||
}
|
||||
|
||||
if header.Config.MediaType != string(v1.MediaTypeImageConfig) {
|
||||
fmt.Printf("warning: config %s has an unknown media type: %s\n", header.Config.Digest, header.Config.MediaType)
|
||||
}
|
||||
|
||||
for _, layer := range header.Layers {
|
||||
if layer.MediaType != string(v1.MediaTypeImageLayer) &&
|
||||
layer.MediaType != string(v1.MediaTypeImageLayerGzip) &&
|
||||
layer.MediaType != string(v1.MediaTypeImageLayerNonDistributable) &&
|
||||
layer.MediaType != string(v1.MediaTypeImageLayerNonDistributableGzip) {
|
||||
fmt.Printf("warning: layer %s has an unknown media type: %s\n", layer.Digest, layer.MediaType)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDescriptor(r io.Reader) error {
|
||||
header := v1.Descriptor{}
|
||||
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error reading the io stream")
|
||||
}
|
||||
|
||||
err = json.Unmarshal(buf, &header)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "descriptor format mismatch")
|
||||
}
|
||||
|
||||
err = header.Digest.Validate()
|
||||
if err == digest.ErrDigestUnsupported {
|
||||
// we ignore unsupported algorithms
|
||||
fmt.Printf("warning: unsupported digest: %q: %v\n", header.Digest, err)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func validateIndex(r io.Reader) error {
|
||||
header := v1.Index{}
|
||||
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error reading the io stream")
|
||||
}
|
||||
|
||||
err = json.Unmarshal(buf, &header)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manifestlist format mismatch")
|
||||
}
|
||||
|
||||
for _, manifest := range header.Manifests {
|
||||
if manifest.MediaType != string(v1.MediaTypeImageManifest) {
|
||||
fmt.Printf("warning: manifest %s has an unknown media type: %s\n", manifest.Digest, manifest.MediaType)
|
||||
}
|
||||
if manifest.Platform != nil {
|
||||
checkPlatform(manifest.Platform.OS, manifest.Platform.Architecture)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateConfig(r io.Reader) error {
|
||||
header := v1.Image{}
|
||||
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error reading the io stream")
|
||||
}
|
||||
|
||||
err = json.Unmarshal(buf, &header)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "config format mismatch")
|
||||
}
|
||||
|
||||
checkPlatform(header.OS, header.Architecture)
|
||||
|
||||
envRegexp := regexp.MustCompile(`^[^=]+=.*$`)
|
||||
for _, e := range header.Config.Env {
|
||||
if !envRegexp.MatchString(e) {
|
||||
return errors.Errorf("unexpected env: %q", e)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkPlatform(OS string, Architecture string) {
|
||||
validCombins := map[string][]string{
|
||||
"android": {"arm"},
|
||||
"darwin": {"386", "amd64", "arm", "arm64"},
|
||||
"dragonfly": {"amd64"},
|
||||
"freebsd": {"386", "amd64", "arm"},
|
||||
"linux": {"386", "amd64", "arm", "arm64", "ppc64", "ppc64le", "mips64", "mips64le", "s390x"},
|
||||
"netbsd": {"386", "amd64", "arm"},
|
||||
"openbsd": {"386", "amd64", "arm"},
|
||||
"plan9": {"386", "amd64"},
|
||||
"solaris": {"amd64"},
|
||||
"windows": {"386", "amd64"}}
|
||||
for os, archs := range validCombins {
|
||||
if os == OS {
|
||||
for _, arch := range archs {
|
||||
if arch == Architecture {
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Printf("warning: combination of %q and %q is invalid.", OS, Architecture)
|
||||
}
|
||||
}
|
||||
fmt.Printf("warning: operating system %q of the bundle is not supported yet.", OS)
|
||||
}
|
||||
69
vendor/github.com/opencontainers/image-spec/spec.md
generated
vendored
Normal file
69
vendor/github.com/opencontainers/image-spec/spec.md
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
# Open Container Initiative
|
||||
## Image Format Specification
|
||||
|
||||
This specification defines an OCI Image, consisting of a [manifest](manifest.md), an [image index](image-index.md) (optional), a set of [filesystem layers](layer.md), and a [configuration](config.md).
|
||||
|
||||
The goal of this specification is to enable the creation of interoperable tools for building, transporting, and preparing a container image to run.
|
||||
|
||||
### Table of Contents
|
||||
|
||||
- [Introduction](spec.md)
|
||||
- [Notational Conventions](#notational-conventions)
|
||||
- [Overview](#overview)
|
||||
- [Understanding the Specification](#understanding-the-specification)
|
||||
- [Media Types](media-types.md)
|
||||
- [Content Descriptors](descriptor.md)
|
||||
- [Image Layout](image-layout.md)
|
||||
- [Image Manifest](manifest.md)
|
||||
- [Image Index](image-index.md)
|
||||
- [Filesystem Layers](layer.md)
|
||||
- [Image Configuration](config.md)
|
||||
- [Annotations](annotations.md)
|
||||
- [Conversion](conversion.md)
|
||||
- [Considerations](considerations.md)
|
||||
- [Extensibility](considerations.md#extensibility)
|
||||
- [Canonicalization](considerations.md#canonicalization)
|
||||
|
||||
## Notational Conventions
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in [RFC 2119](http://tools.ietf.org/html/rfc2119) (Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997).
|
||||
|
||||
The key words "unspecified", "undefined", and "implementation-defined" are to be interpreted as described in the [rationale for the C99 standard][c99-unspecified].
|
||||
|
||||
An implementation is not compliant if it fails to satisfy one or more of the MUST, MUST NOT, REQUIRED, SHALL, or SHALL NOT requirements for the protocols it implements.
|
||||
An implementation is compliant if it satisfies all the MUST, MUST NOT, REQUIRED, SHALL, and SHALL NOT requirements for the protocols it implements.
|
||||
|
||||
## Overview
|
||||
|
||||
At a high level the image manifest contains metadata about the contents and dependencies of the image including the content-addressable identity of one or more [filesystem layer changeset](layer.md) archives that will be unpacked to make up the final runnable filesystem.
|
||||
The image configuration includes information such as application arguments, environments, etc.
|
||||
The image index is a higher-level manifest which points to a list of manifests and descriptors.
|
||||
Typically, these manifests may provide different implementations of the image, possibly varying by platform or other attributes.
|
||||
|
||||

|
||||
|
||||
Once built the OCI Image can then be discovered by name, downloaded, verified by hash, trusted through a signature, and unpacked into an [OCI Runtime Bundle](https://github.com/opencontainers/runtime-spec/blob/master/bundle.md).
|
||||
|
||||

|
||||
|
||||
### Understanding the Specification
|
||||
|
||||
The [OCI Image Media Types](media-types.md) document is a starting point to understanding the overall structure of the specification.
|
||||
|
||||
The high-level components of the spec include:
|
||||
|
||||
* [Image Manifest](manifest.md) - a document describing the components that make up a container image
|
||||
* [Image Index](image-index.md) - an annotated index of image manifests
|
||||
* [Image Layout](image-layout.md) - a filesystem layout representing the contents of an image
|
||||
* [Filesystem Layer](layer.md) - a changeset that describes a container's filesystem
|
||||
* [Image Configuration](config.md) - a document determining layer ordering and configuration of the image suitable for translation into a [runtime bundle][runtime-spec]
|
||||
* [Conversion](conversion.md) - a document describing how this translation should occur
|
||||
* [Descriptor](descriptor.md) - a reference that describes the type, metadata and content address of referenced content
|
||||
|
||||
Future versions of this specification may include the following OPTIONAL features:
|
||||
|
||||
* Signatures that are based on signing image content address
|
||||
* Naming that is federated based on DNS and can be delegated
|
||||
|
||||
[c99-unspecified]: http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf#page=18
|
||||
[runtime-spec]: https://github.com/opencontainers/runtime-spec
|
||||
56
vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go
generated
vendored
Normal file
56
vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
const (
|
||||
// AnnotationCreated is the annotation key for the date and time on which the image was built (date-time string as defined by RFC 3339).
|
||||
AnnotationCreated = "org.opencontainers.image.created"
|
||||
|
||||
// AnnotationAuthors is the annotation key for the contact details of the people or organization responsible for the image (freeform string).
|
||||
AnnotationAuthors = "org.opencontainers.image.authors"
|
||||
|
||||
// AnnotationURL is the annotation key for the URL to find more information on the image.
|
||||
AnnotationURL = "org.opencontainers.image.url"
|
||||
|
||||
// AnnotationDocumentation is the annotation key for the URL to get documentation on the image.
|
||||
AnnotationDocumentation = "org.opencontainers.image.documentation"
|
||||
|
||||
// AnnotationSource is the annotation key for the URL to get source code for building the image.
|
||||
AnnotationSource = "org.opencontainers.image.source"
|
||||
|
||||
// AnnotationVersion is the annotation key for the version of the packaged software.
|
||||
// The version MAY match a label or tag in the source code repository.
|
||||
// The version MAY be Semantic versioning-compatible.
|
||||
AnnotationVersion = "org.opencontainers.image.version"
|
||||
|
||||
// AnnotationRevision is the annotation key for the source control revision identifier for the packaged software.
|
||||
AnnotationRevision = "org.opencontainers.image.revision"
|
||||
|
||||
// AnnotationVendor is the annotation key for the name of the distributing entity, organization or individual.
|
||||
AnnotationVendor = "org.opencontainers.image.vendor"
|
||||
|
||||
// AnnotationLicenses is the annotation key for the license(s) under which contained software is distributed as an SPDX License Expression.
|
||||
AnnotationLicenses = "org.opencontainers.image.licenses"
|
||||
|
||||
// AnnotationRefName is the annotation key for the name of the reference for a target.
|
||||
// SHOULD only be considered valid when on descriptors on `index.json` within image layout.
|
||||
AnnotationRefName = "org.opencontainers.image.ref.name"
|
||||
|
||||
// AnnotationTitle is the annotation key for the human-readable title of the image.
|
||||
AnnotationTitle = "org.opencontainers.image.title"
|
||||
|
||||
// AnnotationDescription is the annotation key for the human-readable description of the software packaged in the image.
|
||||
AnnotationDescription = "org.opencontainers.image.description"
|
||||
)
|
||||
103
vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go
generated
vendored
Normal file
103
vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// ImageConfig defines the execution parameters which should be used as a base when running a container using an image.
|
||||
type ImageConfig struct {
|
||||
// User defines the username or UID which the process in the container should run as.
|
||||
User string `json:"User,omitempty"`
|
||||
|
||||
// ExposedPorts a set of ports to expose from a container running this image.
|
||||
ExposedPorts map[string]struct{} `json:"ExposedPorts,omitempty"`
|
||||
|
||||
// Env is a list of environment variables to be used in a container.
|
||||
Env []string `json:"Env,omitempty"`
|
||||
|
||||
// Entrypoint defines a list of arguments to use as the command to execute when the container starts.
|
||||
Entrypoint []string `json:"Entrypoint,omitempty"`
|
||||
|
||||
// Cmd defines the default arguments to the entrypoint of the container.
|
||||
Cmd []string `json:"Cmd,omitempty"`
|
||||
|
||||
// Volumes is a set of directories describing where the process is likely write data specific to a container instance.
|
||||
Volumes map[string]struct{} `json:"Volumes,omitempty"`
|
||||
|
||||
// WorkingDir sets the current working directory of the entrypoint process in the container.
|
||||
WorkingDir string `json:"WorkingDir,omitempty"`
|
||||
|
||||
// Labels contains arbitrary metadata for the container.
|
||||
Labels map[string]string `json:"Labels,omitempty"`
|
||||
|
||||
// StopSignal contains the system call signal that will be sent to the container to exit.
|
||||
StopSignal string `json:"StopSignal,omitempty"`
|
||||
}
|
||||
|
||||
// RootFS describes a layer content addresses
|
||||
type RootFS struct {
|
||||
// Type is the type of the rootfs.
|
||||
Type string `json:"type"`
|
||||
|
||||
// DiffIDs is an array of layer content hashes (DiffIDs), in order from bottom-most to top-most.
|
||||
DiffIDs []digest.Digest `json:"diff_ids"`
|
||||
}
|
||||
|
||||
// History describes the history of a layer.
|
||||
type History struct {
|
||||
// Created is the combined date and time at which the layer was created, formatted as defined by RFC 3339, section 5.6.
|
||||
Created *time.Time `json:"created,omitempty"`
|
||||
|
||||
// CreatedBy is the command which created the layer.
|
||||
CreatedBy string `json:"created_by,omitempty"`
|
||||
|
||||
// Author is the author of the build point.
|
||||
Author string `json:"author,omitempty"`
|
||||
|
||||
// Comment is a custom message set when creating the layer.
|
||||
Comment string `json:"comment,omitempty"`
|
||||
|
||||
// EmptyLayer is used to mark if the history item created a filesystem diff.
|
||||
EmptyLayer bool `json:"empty_layer,omitempty"`
|
||||
}
|
||||
|
||||
// Image is the JSON structure which describes some basic information about the image.
|
||||
// This provides the `application/vnd.oci.image.config.v1+json` mediatype when marshalled to JSON.
|
||||
type Image struct {
|
||||
// Created is the combined date and time at which the image was created, formatted as defined by RFC 3339, section 5.6.
|
||||
Created *time.Time `json:"created,omitempty"`
|
||||
|
||||
// Author defines the name and/or email address of the person or entity which created and is responsible for maintaining the image.
|
||||
Author string `json:"author,omitempty"`
|
||||
|
||||
// Architecture is the CPU architecture which the binaries in this image are built to run on.
|
||||
Architecture string `json:"architecture"`
|
||||
|
||||
// OS is the name of the operating system which the image is built to run on.
|
||||
OS string `json:"os"`
|
||||
|
||||
// Config defines the execution parameters which should be used as a base when running a container using the image.
|
||||
Config ImageConfig `json:"config,omitempty"`
|
||||
|
||||
// RootFS references the layer content addresses used by the image.
|
||||
RootFS RootFS `json:"rootfs"`
|
||||
|
||||
// History describes the history of each layer.
|
||||
History []History `json:"history,omitempty"`
|
||||
}
|
||||
64
vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go
generated
vendored
Normal file
64
vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
import digest "github.com/opencontainers/go-digest"
|
||||
|
||||
// Descriptor describes the disposition of targeted content.
|
||||
// This structure provides `application/vnd.oci.descriptor.v1+json` mediatype
|
||||
// when marshalled to JSON.
|
||||
type Descriptor struct {
|
||||
// MediaType is the media type of the object this schema refers to.
|
||||
MediaType string `json:"mediaType,omitempty"`
|
||||
|
||||
// Digest is the digest of the targeted content.
|
||||
Digest digest.Digest `json:"digest"`
|
||||
|
||||
// Size specifies the size in bytes of the blob.
|
||||
Size int64 `json:"size"`
|
||||
|
||||
// URLs specifies a list of URLs from which this object MAY be downloaded
|
||||
URLs []string `json:"urls,omitempty"`
|
||||
|
||||
// Annotations contains arbitrary metadata relating to the targeted content.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// Platform describes the platform which the image in the manifest runs on.
|
||||
//
|
||||
// This should only be used when referring to a manifest.
|
||||
Platform *Platform `json:"platform,omitempty"`
|
||||
}
|
||||
|
||||
// Platform describes the platform which the image in the manifest runs on.
|
||||
type Platform struct {
|
||||
// Architecture field specifies the CPU architecture, for example
|
||||
// `amd64` or `ppc64`.
|
||||
Architecture string `json:"architecture"`
|
||||
|
||||
// OS specifies the operating system, for example `linux` or `windows`.
|
||||
OS string `json:"os"`
|
||||
|
||||
// OSVersion is an optional field specifying the operating system
|
||||
// version, for example on Windows `10.0.14393.1066`.
|
||||
OSVersion string `json:"os.version,omitempty"`
|
||||
|
||||
// OSFeatures is an optional field specifying an array of strings,
|
||||
// each listing a required OS feature (for example on Windows `win32k`).
|
||||
OSFeatures []string `json:"os.features,omitempty"`
|
||||
|
||||
// Variant is an optional field specifying a variant of the CPU, for
|
||||
// example `v7` to specify ARMv7 when architecture is `arm`.
|
||||
Variant string `json:"variant,omitempty"`
|
||||
}
|
||||
29
vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
generated
vendored
Normal file
29
vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
import "github.com/opencontainers/image-spec/specs-go"
|
||||
|
||||
// Index references manifests for various platforms.
|
||||
// This structure provides `application/vnd.oci.image.index.v1+json` mediatype when marshalled to JSON.
|
||||
type Index struct {
|
||||
specs.Versioned
|
||||
|
||||
// Manifests references platform specific manifests.
|
||||
Manifests []Descriptor `json:"manifests"`
|
||||
|
||||
// Annotations contains arbitrary metadata for the image index.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
28
vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go
generated
vendored
Normal file
28
vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
const (
|
||||
// ImageLayoutFile is the file name of oci image layout file
|
||||
ImageLayoutFile = "oci-layout"
|
||||
// ImageLayoutVersion is the version of ImageLayout
|
||||
ImageLayoutVersion = "1.0.0"
|
||||
)
|
||||
|
||||
// ImageLayout is the structure in the "oci-layout" file, found in the root
|
||||
// of an OCI Image-layout directory.
|
||||
type ImageLayout struct {
|
||||
Version string `json:"imageLayoutVersion"`
|
||||
}
|
||||
32
vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
generated
vendored
Normal file
32
vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
import "github.com/opencontainers/image-spec/specs-go"
|
||||
|
||||
// Manifest provides `application/vnd.oci.image.manifest.v1+json` mediatype structure when marshalled to JSON.
|
||||
type Manifest struct {
|
||||
specs.Versioned
|
||||
|
||||
// Config references a configuration object for a container, by digest.
|
||||
// The referenced configuration object is a JSON blob that the runtime uses to set up the container.
|
||||
Config Descriptor `json:"config"`
|
||||
|
||||
// Layers is an indexed list of layers referenced by the manifest.
|
||||
Layers []Descriptor `json:"layers"`
|
||||
|
||||
// Annotations contains arbitrary metadata for the image manifest.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
48
vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go
generated
vendored
Normal file
48
vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
const (
|
||||
// MediaTypeDescriptor specifies the media type for a content descriptor.
|
||||
MediaTypeDescriptor = "application/vnd.oci.descriptor.v1+json"
|
||||
|
||||
// MediaTypeLayoutHeader specifies the media type for the oci-layout.
|
||||
MediaTypeLayoutHeader = "application/vnd.oci.layout.header.v1+json"
|
||||
|
||||
// MediaTypeImageManifest specifies the media type for an image manifest.
|
||||
MediaTypeImageManifest = "application/vnd.oci.image.manifest.v1+json"
|
||||
|
||||
// MediaTypeImageIndex specifies the media type for an image index.
|
||||
MediaTypeImageIndex = "application/vnd.oci.image.index.v1+json"
|
||||
|
||||
// MediaTypeImageLayer is the media type used for layers referenced by the manifest.
|
||||
MediaTypeImageLayer = "application/vnd.oci.image.layer.v1.tar"
|
||||
|
||||
// MediaTypeImageLayerGzip is the media type used for gzipped layers
|
||||
// referenced by the manifest.
|
||||
MediaTypeImageLayerGzip = "application/vnd.oci.image.layer.v1.tar+gzip"
|
||||
|
||||
// MediaTypeImageLayerNonDistributable is the media type for layers referenced by
|
||||
// the manifest but with distribution restrictions.
|
||||
MediaTypeImageLayerNonDistributable = "application/vnd.oci.image.layer.nondistributable.v1.tar"
|
||||
|
||||
// MediaTypeImageLayerNonDistributableGzip is the media type for
|
||||
// gzipped layers referenced by the manifest but with distribution
|
||||
// restrictions.
|
||||
MediaTypeImageLayerNonDistributableGzip = "application/vnd.oci.image.layer.nondistributable.v1.tar+gzip"
|
||||
|
||||
// MediaTypeImageConfig specifies the media type for the image configuration.
|
||||
MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json"
|
||||
)
|
||||
32
vendor/github.com/opencontainers/image-spec/specs-go/version.go
generated
vendored
Normal file
32
vendor/github.com/opencontainers/image-spec/specs-go/version.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package specs
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
// VersionMajor is for an API incompatible changes
|
||||
VersionMajor = 1
|
||||
// VersionMinor is for functionality in a backwards-compatible manner
|
||||
VersionMinor = 0
|
||||
// VersionPatch is for backwards-compatible bug fixes
|
||||
VersionPatch = 0
|
||||
|
||||
// VersionDev indicates development branch. Releases will be empty string.
|
||||
VersionDev = "-dev"
|
||||
)
|
||||
|
||||
// Version is the specification version that the package types support.
|
||||
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
|
||||
23
vendor/github.com/opencontainers/image-spec/specs-go/versioned.go
generated
vendored
Normal file
23
vendor/github.com/opencontainers/image-spec/specs-go/versioned.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2016 The Linux Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package specs
|
||||
|
||||
// Versioned provides a struct with the manifest schemaVersion and mediaType.
|
||||
// Incoming content with unknown schema version can be decoded against this
|
||||
// struct to check the version.
|
||||
type Versioned struct {
|
||||
// SchemaVersion is the image manifest schema that this image follows
|
||||
SchemaVersion int `json:"schemaVersion"`
|
||||
}
|
||||
4
vendor/github.com/opencontainers/runc/.travis.yml
generated
vendored
4
vendor/github.com/opencontainers/runc/.travis.yml
generated
vendored
@@ -8,6 +8,8 @@ matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
go_import_path: github.com/opencontainers/runc
|
||||
|
||||
# `make ci` uses Docker.
|
||||
sudo: required
|
||||
services:
|
||||
@@ -28,4 +30,4 @@ before_install:
|
||||
script:
|
||||
- git-validation -run DCO,short-subject -v
|
||||
- make BUILDTAGS="${BUILDTAGS}"
|
||||
- make BUILDTAGS="${BUILDTAGS}" clean validate test
|
||||
- make BUILDTAGS="${BUILDTAGS}" clean ci
|
||||
|
||||
13
vendor/github.com/opencontainers/runc/Dockerfile
generated
vendored
13
vendor/github.com/opencontainers/runc/Dockerfile
generated
vendored
@@ -40,22 +40,13 @@ RUN cd /tmp \
|
||||
&& rm -rf /tmp/bats
|
||||
|
||||
# install criu
|
||||
ENV CRIU_VERSION 2.12
|
||||
ENV CRIU_VERSION 3ca8e575b49763030d3ddfec4af190a4c9f9deef
|
||||
RUN mkdir -p /usr/src/criu \
|
||||
&& curl -sSL https://github.com/xemul/criu/archive/v${CRIU_VERSION}.tar.gz | tar -v -C /usr/src/criu/ -xz --strip-components=1 \
|
||||
&& curl -sSL https://github.com/xemul/criu/archive/${CRIU_VERSION}.tar.gz | tar -v -C /usr/src/criu/ -xz --strip-components=1 \
|
||||
&& cd /usr/src/criu \
|
||||
&& make install-criu \
|
||||
&& rm -rf /usr/src/criu
|
||||
|
||||
# install shfmt
|
||||
RUN mkdir -p /go/src/github.com/mvdan \
|
||||
&& cd /go/src/github.com/mvdan \
|
||||
&& git clone https://github.com/mvdan/sh \
|
||||
&& cd sh \
|
||||
&& git checkout -f v0.4.0 \
|
||||
&& go install ./cmd/shfmt \
|
||||
&& rm -rf /go/src/github.com/mvdan
|
||||
|
||||
# setup a playground for us to spawn containers in
|
||||
ENV ROOTFS /busybox
|
||||
RUN mkdir -p ${ROOTFS} \
|
||||
|
||||
1
vendor/github.com/opencontainers/runc/MAINTAINERS
generated
vendored
1
vendor/github.com/opencontainers/runc/MAINTAINERS
generated
vendored
@@ -3,6 +3,5 @@ Rohit Jnagal <jnagal@google.com> (@rjnagal)
|
||||
Victor Marmol <vmarmol@google.com> (@vmarmol)
|
||||
Mrunal Patel <mpatel@redhat.com> (@mrunalp)
|
||||
Daniel, Dao Quang Minh <dqminh89@gmail.com> (@dqminh)
|
||||
Andrey Vagin <avagin@virtuozzo.com> (@avagin)
|
||||
Qiang Huang <h.huangqiang@huawei.com> (@hqhq)
|
||||
Aleksa Sarai <asarai@suse.de> (@cyphar)
|
||||
|
||||
47
vendor/github.com/opencontainers/runc/Makefile
generated
vendored
47
vendor/github.com/opencontainers/runc/Makefile
generated
vendored
@@ -2,6 +2,8 @@
|
||||
localtest localunittest localintegration \
|
||||
test unittest integration
|
||||
|
||||
GO := go
|
||||
|
||||
SOURCES := $(shell find . 2>&1 | grep -E '.*\.(c|h|go)$$')
|
||||
PREFIX := $(DESTDIR)/usr/local
|
||||
BINDIR := $(PREFIX)/sbin
|
||||
@@ -27,50 +29,28 @@ SHELL := $(shell command -v bash 2>/dev/null)
|
||||
.DEFAULT: runc
|
||||
|
||||
runc: $(SOURCES)
|
||||
go build -i $(EXTRA_FLAGS) -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -tags "$(BUILDTAGS)" -o runc .
|
||||
$(GO) build -buildmode=pie $(EXTRA_FLAGS) -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -tags "$(BUILDTAGS)" -o runc .
|
||||
|
||||
all: runc recvtty
|
||||
|
||||
recvtty: contrib/cmd/recvtty/recvtty
|
||||
|
||||
contrib/cmd/recvtty/recvtty: $(SOURCES)
|
||||
go build -i $(EXTRA_FLAGS) -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
$(GO) build -buildmode=pie $(EXTRA_FLAGS) -ldflags "-X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -tags "$(BUILDTAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
static: $(SOURCES)
|
||||
CGO_ENABLED=1 go build -i $(EXTRA_FLAGS) -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -o runc .
|
||||
CGO_ENABLED=1 go build -i $(EXTRA_FLAGS) -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
CGO_ENABLED=1 $(GO) build $(EXTRA_FLAGS) -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -o runc .
|
||||
CGO_ENABLED=1 $(GO) build $(EXTRA_FLAGS) -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION} $(EXTRA_LDFLAGS)" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
|
||||
|
||||
release:
|
||||
@flag_list=(seccomp selinux apparmor static); \
|
||||
unset expression; \
|
||||
for flag in "$${flag_list[@]}"; do \
|
||||
expression+="' '{'',$${flag}}"; \
|
||||
done; \
|
||||
eval profile_list=("$$expression"); \
|
||||
for profile in "$${profile_list[@]}"; do \
|
||||
output=${RELEASE_DIR}/runc; \
|
||||
for flag in $$profile; do \
|
||||
output+=."$$flag"; \
|
||||
done; \
|
||||
tags="$$profile"; \
|
||||
ldflags="-X main.gitCommit=${COMMIT} -X main.version=${VERSION}"; \
|
||||
CGO_ENABLED=; \
|
||||
[[ "$$profile" =~ static ]] && { \
|
||||
tags="$${tags/static/static_build}"; \
|
||||
tags+=" cgo"; \
|
||||
ldflags+=" -w -extldflags -static"; \
|
||||
CGO_ENABLED=1; \
|
||||
}; \
|
||||
echo "Building target: $$output"; \
|
||||
go build -i $(EXTRA_FLAGS) -ldflags "$$ldflags $(EXTRA_LDFLAGS)" -tags "$$tags" -o "$$output" .; \
|
||||
done
|
||||
script/release.sh -r release/$(VERSION) -v $(VERSION)
|
||||
|
||||
dbuild: runcimage
|
||||
docker run --rm -v $(CURDIR):/go/src/$(PROJECT) --privileged $(RUNC_IMAGE) make clean all
|
||||
|
||||
lint:
|
||||
go vet $(allpackages)
|
||||
go fmt $(allpackages)
|
||||
$(GO) vet $(allpackages)
|
||||
$(GO) fmt $(allpackages)
|
||||
|
||||
man:
|
||||
man/md2man-all.sh
|
||||
@@ -88,7 +68,7 @@ unittest: runcimage
|
||||
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localunittest
|
||||
|
||||
localunittest: all
|
||||
go test -timeout 3m -tags "$(BUILDTAGS)" ${TESTFLAGS} -v $(allpackages)
|
||||
$(GO) test -timeout 3m -tags "$(BUILDTAGS)" ${TESTFLAGS} -v $(allpackages)
|
||||
|
||||
integration: runcimage
|
||||
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localintegration
|
||||
@@ -133,11 +113,10 @@ clean:
|
||||
|
||||
validate:
|
||||
script/validate-gofmt
|
||||
script/validate-shfmt
|
||||
go vet $(allpackages)
|
||||
$(GO) vet $(allpackages)
|
||||
|
||||
ci: validate localtest
|
||||
ci: validate test release
|
||||
|
||||
# memoize allpackages, so that it's executed only once and only if used
|
||||
_allpackages = $(shell go list ./... | grep -v vendor)
|
||||
_allpackages = $(shell $(GO) list ./... | grep -v vendor)
|
||||
allpackages = $(if $(__allpackages),,$(eval __allpackages := $$(_allpackages)))$(__allpackages)
|
||||
|
||||
34
vendor/github.com/opencontainers/runc/README.md
generated
vendored
34
vendor/github.com/opencontainers/runc/README.md
generated
vendored
@@ -145,11 +145,33 @@ Your process field in the `config.json` should look like this below with `"termi
|
||||
"TERM=xterm"
|
||||
],
|
||||
"cwd": "/",
|
||||
"capabilities": [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"capabilities": {
|
||||
"bounding": [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"effective": [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"inheritable": [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"permitted": [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"ambient": [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
]
|
||||
},
|
||||
"rlimits": [
|
||||
{
|
||||
"type": "RLIMIT_NOFILE",
|
||||
@@ -161,7 +183,7 @@ Your process field in the `config.json` should look like this below with `"termi
|
||||
},
|
||||
```
|
||||
|
||||
Now we can go though the lifecycle operations in your shell.
|
||||
Now we can go through the lifecycle operations in your shell.
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
2
vendor/github.com/opencontainers/runc/VERSION
generated
vendored
2
vendor/github.com/opencontainers/runc/VERSION
generated
vendored
@@ -1 +1 @@
|
||||
1.0.0-rc3
|
||||
1.0.0-rc4+dev
|
||||
|
||||
1
vendor/github.com/opencontainers/runc/checkpoint.go
generated
vendored
1
vendor/github.com/opencontainers/runc/checkpoint.go
generated
vendored
@@ -35,6 +35,7 @@ checkpointed.`,
|
||||
cli.BoolFlag{Name: "pre-dump", Usage: "dump container's memory information only, leave the container running after this"},
|
||||
cli.StringFlag{Name: "manage-cgroups-mode", Value: "", Usage: "cgroups mode: 'soft' (default), 'full' and 'strict'"},
|
||||
cli.StringSliceFlag{Name: "empty-ns", Usage: "create a namespace, but don't restore its properties"},
|
||||
cli.BoolFlag{Name: "auto-dedup", Usage: "enable auto deduplication of memory images"},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
if err := checkArgs(context, 1, exactArgs); err != nil {
|
||||
|
||||
4
vendor/github.com/opencontainers/runc/contrib/cmd/recvtty/recvtty.go
generated
vendored
4
vendor/github.com/opencontainers/runc/contrib/cmd/recvtty/recvtty.go
generated
vendored
@@ -24,6 +24,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runc/libcontainer/utils"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -100,6 +101,9 @@ func handleSingle(path string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = libcontainer.SaneTerminal(master); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy from our stdio to the master fd.
|
||||
quitChan := make(chan struct{})
|
||||
|
||||
3
vendor/github.com/opencontainers/runc/events.go
generated
vendored
3
vendor/github.com/opencontainers/runc/events.go
generated
vendored
@@ -9,9 +9,10 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
|
||||
98
vendor/github.com/opencontainers/runc/libcontainer/README.md
generated
vendored
98
vendor/github.com/opencontainers/runc/libcontainer/README.md
generated
vendored
@@ -59,22 +59,88 @@ struct describing how the container is to be created. A sample would look simila
|
||||
defaultMountFlags := unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV
|
||||
config := &configs.Config{
|
||||
Rootfs: "/your/path/to/rootfs",
|
||||
Capabilities: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Capabilities: &configs.Capabilities{
|
||||
Bounding: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Effective: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Inheritable: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Permitted: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
Ambient: []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_FSETID",
|
||||
"CAP_FOWNER",
|
||||
"CAP_MKNOD",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_KILL",
|
||||
"CAP_AUDIT_WRITE",
|
||||
},
|
||||
},
|
||||
Namespaces: configs.Namespaces([]configs.Namespace{
|
||||
{Type: configs.NEWNS},
|
||||
{Type: configs.NEWUTS},
|
||||
|
||||
44
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
generated
vendored
44
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go
generated
vendored
@@ -73,14 +73,14 @@ func EnableKernelMemoryAccounting(path string) error {
|
||||
// until a limit is set on the cgroup and limit cannot be set once the
|
||||
// cgroup has children, or if there are already tasks in the cgroup.
|
||||
for _, i := range []int64{1, -1} {
|
||||
if err := setKernelMemory(path, uint64(i)); err != nil {
|
||||
if err := setKernelMemory(path, i); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setKernelMemory(path string, kernelMemoryLimit uint64) error {
|
||||
func setKernelMemory(path string, kernelMemoryLimit int64) error {
|
||||
if path == "" {
|
||||
return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit)
|
||||
}
|
||||
@@ -88,7 +88,7 @@ func setKernelMemory(path string, kernelMemoryLimit uint64) error {
|
||||
// kernel memory is not enabled on the system so we should do nothing
|
||||
return nil
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatUint(kernelMemoryLimit, 10)), 0700); err != nil {
|
||||
if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil {
|
||||
// Check if the error number returned by the syscall is "EBUSY"
|
||||
// The EBUSY signal is returned on attempts to write to the
|
||||
// memory.kmem.limit_in_bytes file if the cgroup has children or
|
||||
@@ -106,14 +106,12 @@ func setKernelMemory(path string, kernelMemoryLimit uint64) error {
|
||||
}
|
||||
|
||||
func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error {
|
||||
ulimited := -1
|
||||
|
||||
// If the memory update is set to uint64(-1) we should also
|
||||
// set swap to uint64(-1), it means unlimited memory.
|
||||
if cgroup.Resources.Memory == uint64(ulimited) {
|
||||
// Only set swap if it's enbled in kernel
|
||||
// If the memory update is set to -1 we should also
|
||||
// set swap to -1, it means unlimited memory.
|
||||
if cgroup.Resources.Memory == -1 {
|
||||
// Only set swap if it's enabled in kernel
|
||||
if cgroups.PathExists(filepath.Join(path, cgroupMemorySwapLimit)) {
|
||||
cgroup.Resources.MemorySwap = uint64(ulimited)
|
||||
cgroup.Resources.MemorySwap = -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,29 +126,29 @@ func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error {
|
||||
// When update memory limit, we should adapt the write sequence
|
||||
// for memory and swap memory, so it won't fail because the new
|
||||
// value and the old value don't fit kernel's validation.
|
||||
if cgroup.Resources.MemorySwap == uint64(ulimited) || memoryUsage.Limit < cgroup.Resources.MemorySwap {
|
||||
if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatUint(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
if cgroup.Resources.MemorySwap == -1 || memoryUsage.Limit < uint64(cgroup.Resources.MemorySwap) {
|
||||
if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeFile(path, cgroupMemoryLimit, strconv.FormatUint(cgroup.Resources.Memory, 10)); err != nil {
|
||||
if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := writeFile(path, cgroupMemoryLimit, strconv.FormatUint(cgroup.Resources.Memory, 10)); err != nil {
|
||||
if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatUint(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if cgroup.Resources.Memory != 0 {
|
||||
if err := writeFile(path, cgroupMemoryLimit, strconv.FormatUint(cgroup.Resources.Memory, 10)); err != nil {
|
||||
if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if cgroup.Resources.MemorySwap != 0 {
|
||||
if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatUint(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -171,13 +169,13 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
|
||||
}
|
||||
|
||||
if cgroup.Resources.MemoryReservation != 0 {
|
||||
if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatUint(cgroup.Resources.MemoryReservation, 10)); err != nil {
|
||||
if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(cgroup.Resources.MemoryReservation, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if cgroup.Resources.KernelMemoryTCP != 0 {
|
||||
if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatUint(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
|
||||
if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -245,6 +243,14 @@ func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
|
||||
}
|
||||
stats.MemoryStats.KernelTCPUsage = kernelTCPUsage
|
||||
|
||||
useHierarchy := strings.Join([]string{"memory", "use_hierarchy"}, ".")
|
||||
value, err := getCgroupParamUint(path, useHierarchy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value == 1 {
|
||||
stats.MemoryStats.UseHierarchy = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go
generated
vendored
12
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go
generated
vendored
@@ -12,10 +12,11 @@ import (
|
||||
const (
|
||||
memoryStatContents = `cache 512
|
||||
rss 1024`
|
||||
memoryUsageContents = "2048\n"
|
||||
memoryMaxUsageContents = "4096\n"
|
||||
memoryFailcnt = "100\n"
|
||||
memoryLimitContents = "8192\n"
|
||||
memoryUsageContents = "2048\n"
|
||||
memoryMaxUsageContents = "4096\n"
|
||||
memoryFailcnt = "100\n"
|
||||
memoryLimitContents = "8192\n"
|
||||
memoryUseHierarchyContents = "1\n"
|
||||
)
|
||||
|
||||
func TestMemorySetMemory(t *testing.T) {
|
||||
@@ -273,6 +274,7 @@ func TestMemoryStats(t *testing.T) {
|
||||
"memory.kmem.max_usage_in_bytes": memoryMaxUsageContents,
|
||||
"memory.kmem.failcnt": memoryFailcnt,
|
||||
"memory.kmem.limit_in_bytes": memoryLimitContents,
|
||||
"memory.use_hierarchy": memoryUseHierarchyContents,
|
||||
})
|
||||
|
||||
memory := &MemoryGroup{}
|
||||
@@ -281,7 +283,7 @@ func TestMemoryStats(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expectedStats := cgroups.MemoryStats{Cache: 512, Usage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, SwapUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, KernelUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, Stats: map[string]uint64{"cache": 512, "rss": 1024}}
|
||||
expectedStats := cgroups.MemoryStats{Cache: 512, Usage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, SwapUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, KernelUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, Stats: map[string]uint64{"cache": 512, "rss": 1024}, UseHierarchy: true}
|
||||
expectMemoryStatEquals(t, expectedStats, actualStats.MemoryStats)
|
||||
}
|
||||
|
||||
|
||||
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/stats_util_test.go
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/stats_util_test.go
generated
vendored
@@ -6,8 +6,9 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func blkioStatEntryEquals(expected, actual []cgroups.BlkioStatEntry) error {
|
||||
@@ -84,6 +85,11 @@ func expectMemoryStatEquals(t *testing.T, expected, actual cgroups.MemoryStats)
|
||||
expectMemoryDataEquals(t, expected.SwapUsage, actual.SwapUsage)
|
||||
expectMemoryDataEquals(t, expected.KernelUsage, actual.KernelUsage)
|
||||
|
||||
if expected.UseHierarchy != actual.UseHierarchy {
|
||||
logrus.Printf("Expected memory use hiearchy %v, but found %v\n", expected.UseHierarchy, actual.UseHierarchy)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
for key, expValue := range expected.Stats {
|
||||
actValue, ok := actual.Stats[key]
|
||||
if !ok {
|
||||
|
||||
2
vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
generated
vendored
@@ -51,6 +51,8 @@ type MemoryStats struct {
|
||||
KernelUsage MemoryData `json:"kernel_usage,omitempty"`
|
||||
// usage of kernel TCP memory
|
||||
KernelTCPUsage MemoryData `json:"kernel_tcp_usage,omitempty"`
|
||||
// if true, memory usage is accounted for throughout a hierarchy of cgroups.
|
||||
UseHierarchy bool `json:"use_hierarchy"`
|
||||
|
||||
Stats map[string]uint64 `json:"stats,omitempty"`
|
||||
}
|
||||
|
||||
2
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
generated
vendored
@@ -353,7 +353,6 @@ func joinCgroups(c *configs.Cgroup, pid int) error {
|
||||
switch name {
|
||||
case "name=systemd":
|
||||
// let systemd handle this
|
||||
break
|
||||
case "cpuset":
|
||||
path, err := getSubsystemPath(c, name)
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
@@ -363,7 +362,6 @@ func joinCgroups(c *configs.Cgroup, pid int) error {
|
||||
if err := s.ApplyDir(path, c, pid); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
default:
|
||||
_, err := join(c, name, pid)
|
||||
if err != nil {
|
||||
|
||||
10
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go
generated
vendored
10
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go
generated
vendored
@@ -43,19 +43,19 @@ type Resources struct {
|
||||
Devices []*Device `json:"devices"`
|
||||
|
||||
// Memory limit (in bytes)
|
||||
Memory uint64 `json:"memory"`
|
||||
Memory int64 `json:"memory"`
|
||||
|
||||
// Memory reservation or soft_limit (in bytes)
|
||||
MemoryReservation uint64 `json:"memory_reservation"`
|
||||
MemoryReservation int64 `json:"memory_reservation"`
|
||||
|
||||
// Total memory usage (memory + swap); set `-1` to enable unlimited swap
|
||||
MemorySwap uint64 `json:"memory_swap"`
|
||||
MemorySwap int64 `json:"memory_swap"`
|
||||
|
||||
// Kernel memory limit (in bytes)
|
||||
KernelMemory uint64 `json:"kernel_memory"`
|
||||
KernelMemory int64 `json:"kernel_memory"`
|
||||
|
||||
// Kernel memory limit for TCP use (in bytes)
|
||||
KernelMemoryTCP uint64 `json:"kernel_memory_tcp"`
|
||||
KernelMemoryTCP int64 `json:"kernel_memory_tcp"`
|
||||
|
||||
// CPU shares (relative weight vs. other containers)
|
||||
CpuShares uint64 `json:"cpu_shares"`
|
||||
|
||||
3
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
3
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
@@ -7,8 +7,9 @@ import (
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Rlimit struct {
|
||||
|
||||
3
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
generated
vendored
3
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
generated
vendored
@@ -79,9 +79,6 @@ type Namespace struct {
|
||||
}
|
||||
|
||||
func (n *Namespace) GetPath(pid int) string {
|
||||
if n.Path != "" {
|
||||
return n.Path
|
||||
}
|
||||
return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type))
|
||||
}
|
||||
|
||||
|
||||
19
vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
generated
vendored
19
vendor/github.com/opencontainers/runc/libcontainer/console_linux.go
generated
vendored
@@ -21,9 +21,6 @@ func newConsole() (Console, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := saneTerminal(master); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
console, err := ptsname(master)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -126,30 +123,28 @@ func unlockpt(f *os.File) error {
|
||||
|
||||
// ptsname retrieves the name of the first available pts for the given master.
|
||||
func ptsname(f *os.File) (string, error) {
|
||||
var n int32
|
||||
if err := ioctl(f.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
|
||||
n, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("/dev/pts/%d", n), nil
|
||||
}
|
||||
|
||||
// saneTerminal sets the necessary tty_ioctl(4)s to ensure that a pty pair
|
||||
// SaneTerminal sets the necessary tty_ioctl(4)s to ensure that a pty pair
|
||||
// created by us acts normally. In particular, a not-very-well-known default of
|
||||
// Linux unix98 ptys is that they have +onlcr by default. While this isn't a
|
||||
// problem for terminal emulators, because we relay data from the terminal we
|
||||
// also relay that funky line discipline.
|
||||
func saneTerminal(terminal *os.File) error {
|
||||
// Go doesn't have a wrapper for any of the termios ioctls.
|
||||
var termios unix.Termios
|
||||
|
||||
if err := ioctl(terminal.Fd(), unix.TCGETS, uintptr(unsafe.Pointer(&termios))); err != nil {
|
||||
func SaneTerminal(terminal *os.File) error {
|
||||
termios, err := unix.IoctlGetTermios(int(terminal.Fd()), unix.TCGETS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ioctl(tty, tcgets): %s", err.Error())
|
||||
}
|
||||
|
||||
// Set -onlcr so we don't have to deal with \r.
|
||||
termios.Oflag &^= unix.ONLCR
|
||||
|
||||
if err := ioctl(terminal.Fd(), unix.TCSETS, uintptr(unsafe.Pointer(&termios))); err != nil {
|
||||
if err := unix.IoctlSetTermios(int(terminal.Fd()), unix.TCSETS, termios); err != nil {
|
||||
return fmt.Errorf("ioctl(tty, tcsets): %s", err.Error())
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/opencontainers/runc/libcontainer/container.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/container.go
generated
vendored
@@ -54,7 +54,7 @@ type BaseState struct {
|
||||
InitProcessPid int `json:"init_process_pid"`
|
||||
|
||||
// InitProcessStartTime is the init process start time in clock cycles since boot time.
|
||||
InitProcessStartTime string `json:"init_process_start"`
|
||||
InitProcessStartTime uint64 `json:"init_process_start"`
|
||||
|
||||
// Created is the unix timestamp for the creation time of the container in UTC
|
||||
Created time.Time `json:"created"`
|
||||
|
||||
212
vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
generated
vendored
212
vendor/github.com/opencontainers/runc/libcontainer/container_linux.go
generated
vendored
@@ -18,17 +18,17 @@ import (
|
||||
"syscall" // only for SysProcAttr and Signal
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/criurpc"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
"github.com/opencontainers/runc/libcontainer/utils"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/syndtr/gocapability/capability"
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const stdioFdCount = 3
|
||||
@@ -40,7 +40,7 @@ type linuxContainer struct {
|
||||
cgroupManager cgroups.Manager
|
||||
initArgs []string
|
||||
initProcess parentProcess
|
||||
initProcessStartTime string
|
||||
initProcessStartTime uint64
|
||||
criuPath string
|
||||
m sync.Mutex
|
||||
criuVersion int
|
||||
@@ -186,8 +186,17 @@ func (c *linuxContainer) Set(config configs.Config) error {
|
||||
if status == Stopped {
|
||||
return newGenericError(fmt.Errorf("container not running"), ContainerNotRunning)
|
||||
}
|
||||
if err := c.cgroupManager.Set(&config); err != nil {
|
||||
// Set configs back
|
||||
if err2 := c.cgroupManager.Set(c.config); err2 != nil {
|
||||
logrus.Warnf("Setting back cgroup configs failed due to error: %v, your state.json and actual configs might be inconsistent.", err2)
|
||||
}
|
||||
return err
|
||||
}
|
||||
// After config setting succeed, update config and states
|
||||
c.config = &config
|
||||
return c.cgroupManager.Set(c.config)
|
||||
_, err = c.updateState(nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *linuxContainer) Start(process *Process) error {
|
||||
@@ -546,7 +555,8 @@ func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.
|
||||
var t criurpc.CriuReqType
|
||||
t = criurpc.CriuReqType_FEATURE_CHECK
|
||||
|
||||
if err := c.checkCriuVersion("1.8"); err != nil {
|
||||
// criu 1.8 => 10800
|
||||
if err := c.checkCriuVersion(10800); err != nil {
|
||||
// Feature checking was introduced with CRIU 1.8.
|
||||
// Ignore the feature check if an older CRIU version is used
|
||||
// and just act as before.
|
||||
@@ -589,19 +599,12 @@ func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkCriuVersion checks Criu version greater than or equal to minVersion
|
||||
func (c *linuxContainer) checkCriuVersion(minVersion string) error {
|
||||
var x, y, z, versionReq int
|
||||
func parseCriuVersion(path string) (int, error) {
|
||||
var x, y, z int
|
||||
|
||||
_, err := fmt.Sscanf(minVersion, "%d.%d.%d\n", &x, &y, &z) // 1.5.2
|
||||
out, err := exec.Command(path, "-V").Output()
|
||||
if err != nil {
|
||||
_, err = fmt.Sscanf(minVersion, "Version: %d.%d\n", &x, &y) // 1.6
|
||||
}
|
||||
versionReq = x*10000 + y*100 + z
|
||||
|
||||
out, err := exec.Command(c.criuPath, "-V").Output()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to execute CRIU command: %s", c.criuPath)
|
||||
return 0, fmt.Errorf("Unable to execute CRIU command: %s", path)
|
||||
}
|
||||
|
||||
x = 0
|
||||
@@ -613,7 +616,7 @@ func (c *linuxContainer) checkCriuVersion(minVersion string) error {
|
||||
if sp := strings.Index(string(out), "GitID"); sp > 0 {
|
||||
version = string(out)[sp:ep]
|
||||
} else {
|
||||
return fmt.Errorf("Unable to parse the CRIU version: %s", c.criuPath)
|
||||
return 0, fmt.Errorf("Unable to parse the CRIU version: %s", path)
|
||||
}
|
||||
|
||||
n, err := fmt.Sscanf(string(version), "GitID: v%d.%d.%d", &x, &y, &z) // 1.5.2
|
||||
@@ -624,7 +627,7 @@ func (c *linuxContainer) checkCriuVersion(minVersion string) error {
|
||||
z++
|
||||
}
|
||||
if n < 2 || err != nil {
|
||||
return fmt.Errorf("Unable to parse the CRIU version: %s %d %s", version, n, err)
|
||||
return 0, fmt.Errorf("Unable to parse the CRIU version: %s %d %s", version, n, err)
|
||||
}
|
||||
} else {
|
||||
// criu release version format
|
||||
@@ -633,19 +636,81 @@ func (c *linuxContainer) checkCriuVersion(minVersion string) error {
|
||||
n, err = fmt.Sscanf(string(out), "Version: %d.%d\n", &x, &y) // 1.6
|
||||
}
|
||||
if n < 2 || err != nil {
|
||||
return fmt.Errorf("Unable to parse the CRIU version: %s %d %s", out, n, err)
|
||||
return 0, fmt.Errorf("Unable to parse the CRIU version: %s %d %s", out, n, err)
|
||||
}
|
||||
}
|
||||
|
||||
c.criuVersion = x*10000 + y*100 + z
|
||||
return x*10000 + y*100 + z, nil
|
||||
}
|
||||
|
||||
if c.criuVersion < versionReq {
|
||||
return fmt.Errorf("CRIU version %d must be %d or higher", c.criuVersion, versionReq)
|
||||
func compareCriuVersion(criuVersion int, minVersion int) error {
|
||||
// simple function to perform the actual version compare
|
||||
if criuVersion < minVersion {
|
||||
return fmt.Errorf("CRIU version %d must be %d or higher", criuVersion, minVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is used to store the result of criu version RPC
|
||||
var criuVersionRPC *criurpc.CriuVersion
|
||||
|
||||
// checkCriuVersion checks Criu version greater than or equal to minVersion
|
||||
func (c *linuxContainer) checkCriuVersion(minVersion int) error {
|
||||
|
||||
// If the version of criu has already been determined there is no need
|
||||
// to ask criu for the version again. Use the value from c.criuVersion.
|
||||
if c.criuVersion != 0 {
|
||||
return compareCriuVersion(c.criuVersion, minVersion)
|
||||
}
|
||||
|
||||
// First try if this version of CRIU support the version RPC.
|
||||
// The CRIU version RPC was introduced with CRIU 3.0.
|
||||
|
||||
// First, reset the variable for the RPC answer to nil
|
||||
criuVersionRPC = nil
|
||||
|
||||
var t criurpc.CriuReqType
|
||||
t = criurpc.CriuReqType_VERSION
|
||||
req := &criurpc.CriuReq{
|
||||
Type: &t,
|
||||
}
|
||||
|
||||
err := c.criuSwrk(nil, req, nil, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("CRIU version check failed: %s", err)
|
||||
}
|
||||
|
||||
if criuVersionRPC != nil {
|
||||
logrus.Debugf("CRIU version: %s", criuVersionRPC)
|
||||
// major and minor are always set
|
||||
c.criuVersion = int(*criuVersionRPC.Major) * 10000
|
||||
c.criuVersion += int(*criuVersionRPC.Minor) * 100
|
||||
if criuVersionRPC.Sublevel != nil {
|
||||
c.criuVersion += int(*criuVersionRPC.Sublevel)
|
||||
}
|
||||
if criuVersionRPC.Gitid != nil {
|
||||
// runc's convention is that a CRIU git release is
|
||||
// always the same as increasing the minor by 1
|
||||
c.criuVersion -= (c.criuVersion % 100)
|
||||
c.criuVersion += 100
|
||||
}
|
||||
return compareCriuVersion(c.criuVersion, minVersion)
|
||||
}
|
||||
|
||||
// This is CRIU without the version RPC and therefore
|
||||
// older than 3.0. Parsing the output is required.
|
||||
|
||||
// This can be remove once runc does not work with criu older than 3.0
|
||||
|
||||
c.criuVersion, err = parseCriuVersion(c.criuPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return compareCriuVersion(c.criuVersion, minVersion)
|
||||
}
|
||||
|
||||
const descriptorsFilename = "descriptors.json"
|
||||
|
||||
func (c *linuxContainer) addCriuDumpMount(req *criurpc.CriuReq, m *configs.Mount) {
|
||||
@@ -695,7 +760,8 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
return fmt.Errorf("cannot checkpoint a rootless container")
|
||||
}
|
||||
|
||||
if err := c.checkCriuVersion("1.5.2"); err != nil {
|
||||
// criu 1.5.2 => 10502
|
||||
if err := c.checkCriuVersion(10502); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -745,6 +811,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
FileLocks: proto.Bool(criuOpts.FileLocks),
|
||||
EmptyNs: proto.Uint32(criuOpts.EmptyNs),
|
||||
OrphanPtsMaster: proto.Bool(true),
|
||||
AutoDedup: proto.Bool(criuOpts.AutoDedup),
|
||||
}
|
||||
|
||||
fcg := c.cgroupManager.GetPaths()["freezer"]
|
||||
@@ -768,7 +835,8 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
|
||||
// append optional manage cgroups mode
|
||||
if criuOpts.ManageCgroupsMode != 0 {
|
||||
if err := c.checkCriuVersion("1.7"); err != nil {
|
||||
// criu 1.7 => 10700
|
||||
if err := c.checkCriuVersion(10700); err != nil {
|
||||
return err
|
||||
}
|
||||
mode := criurpc.CriuCgMode(criuOpts.ManageCgroupsMode)
|
||||
@@ -800,7 +868,6 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
switch m.Device {
|
||||
case "bind":
|
||||
c.addCriuDumpMount(req, m)
|
||||
break
|
||||
case "cgroup":
|
||||
binds, err := getCgroupMounts(m)
|
||||
if err != nil {
|
||||
@@ -809,7 +876,6 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
for _, b := range binds {
|
||||
c.addCriuDumpMount(req, b)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,9 +928,8 @@ func (c *linuxContainer) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts
|
||||
veth.IfOut = proto.String(iface.HostInterfaceName)
|
||||
veth.IfIn = proto.String(iface.Name)
|
||||
req.Opts.Veths = append(req.Opts.Veths, veth)
|
||||
break
|
||||
case "loopback":
|
||||
break
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
for _, i := range criuOpts.VethPairs {
|
||||
@@ -885,7 +950,8 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
return fmt.Errorf("cannot restore a rootless container")
|
||||
}
|
||||
|
||||
if err := c.checkCriuVersion("1.5.2"); err != nil {
|
||||
// criu 1.5.2 => 10502
|
||||
if err := c.checkCriuVersion(10502); err != nil {
|
||||
return err
|
||||
}
|
||||
if criuOpts.WorkDirectory == "" {
|
||||
@@ -947,6 +1013,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
FileLocks: proto.Bool(criuOpts.FileLocks),
|
||||
EmptyNs: proto.Uint32(criuOpts.EmptyNs),
|
||||
OrphanPtsMaster: proto.Bool(true),
|
||||
AutoDedup: proto.Bool(criuOpts.AutoDedup),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -954,7 +1021,6 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
switch m.Device {
|
||||
case "bind":
|
||||
c.addCriuRestoreMount(req, m)
|
||||
break
|
||||
case "cgroup":
|
||||
binds, err := getCgroupMounts(m)
|
||||
if err != nil {
|
||||
@@ -963,7 +1029,6 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
for _, b := range binds {
|
||||
c.addCriuRestoreMount(req, b)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,7 +1048,8 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
|
||||
// append optional manage cgroups mode
|
||||
if criuOpts.ManageCgroupsMode != 0 {
|
||||
if err := c.checkCriuVersion("1.7"); err != nil {
|
||||
// criu 1.7 => 10700
|
||||
if err := c.checkCriuVersion(10700); err != nil {
|
||||
return err
|
||||
}
|
||||
mode := criurpc.CriuCgMode(criuOpts.ManageCgroupsMode)
|
||||
@@ -1045,7 +1111,14 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
||||
return err
|
||||
}
|
||||
|
||||
logPath := filepath.Join(opts.WorkDirectory, req.GetOpts().GetLogFile())
|
||||
var logPath string
|
||||
if opts != nil {
|
||||
logPath = filepath.Join(opts.WorkDirectory, req.GetOpts().GetLogFile())
|
||||
} else {
|
||||
// For the VERSION RPC 'opts' is set to 'nil' and therefore
|
||||
// opts.WorkDirectory does not exist. Set logPath to "".
|
||||
logPath = ""
|
||||
}
|
||||
criuClient := os.NewFile(uintptr(fds[0]), "criu-transport-client")
|
||||
criuClientFileCon, err := net.FileConn(criuClient)
|
||||
criuClient.Close()
|
||||
@@ -1060,7 +1133,11 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
||||
defer criuServer.Close()
|
||||
|
||||
args := []string{"swrk", "3"}
|
||||
logrus.Debugf("Using CRIU %d at: %s", c.criuVersion, c.criuPath)
|
||||
if c.criuVersion != 0 {
|
||||
// If the CRIU Version is still '0' then this is probably
|
||||
// the initial CRIU run to detect the version. Skip it.
|
||||
logrus.Debugf("Using CRIU %d at: %s", c.criuVersion, c.criuPath)
|
||||
}
|
||||
logrus.Debugf("Using CRIU with following args: %s", args)
|
||||
cmd := exec.Command(c.criuPath, args...)
|
||||
if process != nil {
|
||||
@@ -1101,8 +1178,11 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
||||
logrus.Debugf("Using CRIU in %s mode", req.GetType().String())
|
||||
// In the case of criurpc.CriuReqType_FEATURE_CHECK req.GetOpts()
|
||||
// should be empty. For older CRIU versions it still will be
|
||||
// available but empty.
|
||||
if req.GetType() != criurpc.CriuReqType_FEATURE_CHECK {
|
||||
// available but empty. criurpc.CriuReqType_VERSION actually
|
||||
// has no req.GetOpts().
|
||||
if !(req.GetType() == criurpc.CriuReqType_FEATURE_CHECK ||
|
||||
req.GetType() == criurpc.CriuReqType_VERSION) {
|
||||
|
||||
val := reflect.ValueOf(req.GetOpts())
|
||||
v := reflect.Indirect(val)
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
@@ -1145,15 +1225,23 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
|
||||
}
|
||||
if !resp.GetSuccess() {
|
||||
typeString := req.GetType().String()
|
||||
if typeString == "VERSION" {
|
||||
// If the VERSION RPC fails this probably means that the CRIU
|
||||
// version is too old for this RPC. Just return 'nil'.
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("criu failed: type %s errno %d\nlog file: %s", typeString, resp.GetCrErrno(), logPath)
|
||||
}
|
||||
|
||||
t := resp.GetType()
|
||||
switch {
|
||||
case t == criurpc.CriuReqType_VERSION:
|
||||
logrus.Debugf("CRIU version: %s", resp)
|
||||
criuVersionRPC = resp.GetVersion()
|
||||
break
|
||||
case t == criurpc.CriuReqType_FEATURE_CHECK:
|
||||
logrus.Debugf("Feature check says: %s", resp)
|
||||
criuFeatures = resp.GetFeatures()
|
||||
break
|
||||
case t == criurpc.CriuReqType_NOTIFY:
|
||||
if err := c.criuNotifications(resp, process, opts, extFds, oob[:oobn]); err != nil {
|
||||
return err
|
||||
@@ -1290,11 +1378,14 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
|
||||
}
|
||||
}
|
||||
case notify.GetScript() == "orphan-pts-master":
|
||||
scm, err := syscall.ParseSocketControlMessage(oob)
|
||||
scm, err := unix.ParseSocketControlMessage(oob)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fds, err := unix.ParseUnixRights(&scm[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fds, err := syscall.ParseUnixRights(&scm[0])
|
||||
|
||||
master := os.NewFile(uintptr(fds[0]), "orphan-pts-master")
|
||||
defer master.Close()
|
||||
@@ -1308,7 +1399,9 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
|
||||
}
|
||||
|
||||
func (c *linuxContainer) updateState(process parentProcess) (*State, error) {
|
||||
c.initProcess = process
|
||||
if process != nil {
|
||||
c.initProcess = process
|
||||
}
|
||||
state, err := c.currentState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1365,40 +1458,17 @@ func (c *linuxContainer) refreshState() error {
|
||||
return c.state.transition(&stoppedState{c: c})
|
||||
}
|
||||
|
||||
// doesInitProcessExist checks if the init process is still the same process
|
||||
// as the initial one, it could happen that the original process has exited
|
||||
// and a new process has been created with the same pid, in this case, the
|
||||
// container would already be stopped.
|
||||
func (c *linuxContainer) doesInitProcessExist(initPid int) (bool, error) {
|
||||
startTime, err := system.GetProcessStartTime(initPid)
|
||||
if err != nil {
|
||||
return false, newSystemErrorWithCausef(err, "getting init process %d start time", initPid)
|
||||
}
|
||||
if c.initProcessStartTime != startTime {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (c *linuxContainer) runType() (Status, error) {
|
||||
if c.initProcess == nil {
|
||||
return Stopped, nil
|
||||
}
|
||||
pid := c.initProcess.pid()
|
||||
// return Running if the init process is alive
|
||||
if err := unix.Kill(pid, 0); err != nil {
|
||||
if err == unix.ESRCH {
|
||||
// It means the process does not exist anymore, could happen when the
|
||||
// process exited just when we call the function, we should not return
|
||||
// error in this case.
|
||||
return Stopped, nil
|
||||
}
|
||||
return Stopped, newSystemErrorWithCausef(err, "sending signal 0 to pid %d", pid)
|
||||
stat, err := system.Stat(pid)
|
||||
if err != nil {
|
||||
return Stopped, nil
|
||||
}
|
||||
// check if the process is still the original init process.
|
||||
exist, err := c.doesInitProcessExist(pid)
|
||||
if !exist || err != nil {
|
||||
return Stopped, err
|
||||
if stat.StartTime != c.initProcessStartTime || stat.State == system.Zombie || stat.State == system.Dead {
|
||||
return Stopped, nil
|
||||
}
|
||||
// We'll create exec fifo and blocking on it after container is created,
|
||||
// and delete it after start container.
|
||||
@@ -1427,7 +1497,7 @@ func (c *linuxContainer) isPaused() (bool, error) {
|
||||
|
||||
func (c *linuxContainer) currentState() (*State, error) {
|
||||
var (
|
||||
startTime string
|
||||
startTime uint64
|
||||
externalDescriptors []string
|
||||
pid = -1
|
||||
)
|
||||
|
||||
75
vendor/github.com/opencontainers/runc/libcontainer/container_linux_test.go
generated
vendored
75
vendor/github.com/opencontainers/runc/libcontainer/container_linux_test.go
generated
vendored
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
)
|
||||
|
||||
type mockCgroupManager struct {
|
||||
@@ -52,7 +53,7 @@ func (m *mockCgroupManager) Freeze(state configs.FreezerState) error {
|
||||
|
||||
type mockProcess struct {
|
||||
_pid int
|
||||
started string
|
||||
started uint64
|
||||
}
|
||||
|
||||
func (m *mockProcess) terminate() error {
|
||||
@@ -63,7 +64,7 @@ func (m *mockProcess) pid() int {
|
||||
return m._pid
|
||||
}
|
||||
|
||||
func (m *mockProcess) startTime() (string, error) {
|
||||
func (m *mockProcess) startTime() (uint64, error) {
|
||||
return m.started, nil
|
||||
}
|
||||
|
||||
@@ -134,7 +135,7 @@ func TestGetContainerState(t *testing.T) {
|
||||
var (
|
||||
pid = os.Getpid()
|
||||
expectedMemoryPath = "/sys/fs/cgroup/memory/myid"
|
||||
expectedNetworkPath = "/networks/fd"
|
||||
expectedNetworkPath = fmt.Sprintf("/proc/%d/ns/net", pid)
|
||||
)
|
||||
container := &linuxContainer{
|
||||
id: "myid",
|
||||
@@ -150,7 +151,7 @@ func TestGetContainerState(t *testing.T) {
|
||||
},
|
||||
initProcess: &mockProcess{
|
||||
_pid: pid,
|
||||
started: "010",
|
||||
started: 10,
|
||||
},
|
||||
cgroupManager: &mockCgroupManager{
|
||||
pids: []int{1, 2, 3},
|
||||
@@ -174,8 +175,8 @@ func TestGetContainerState(t *testing.T) {
|
||||
if state.InitProcessPid != pid {
|
||||
t.Fatalf("expected pid %d but received %d", pid, state.InitProcessPid)
|
||||
}
|
||||
if state.InitProcessStartTime != "010" {
|
||||
t.Fatalf("expected process start time 010 but received %s", state.InitProcessStartTime)
|
||||
if state.InitProcessStartTime != 10 {
|
||||
t.Fatalf("expected process start time 10 but received %d", state.InitProcessStartTime)
|
||||
}
|
||||
paths := state.CgroupPaths
|
||||
if paths == nil {
|
||||
@@ -216,3 +217,65 @@ func TestGetContainerState(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetContainerStateAfterUpdate(t *testing.T) {
|
||||
var (
|
||||
pid = os.Getpid()
|
||||
)
|
||||
stat, err := system.Stat(pid)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
container := &linuxContainer{
|
||||
id: "myid",
|
||||
config: &configs.Config{
|
||||
Namespaces: []configs.Namespace{
|
||||
{Type: configs.NEWPID},
|
||||
{Type: configs.NEWNS},
|
||||
{Type: configs.NEWNET},
|
||||
{Type: configs.NEWUTS},
|
||||
{Type: configs.NEWIPC},
|
||||
},
|
||||
Cgroups: &configs.Cgroup{
|
||||
Resources: &configs.Resources{
|
||||
Memory: 1024,
|
||||
},
|
||||
},
|
||||
},
|
||||
initProcess: &mockProcess{
|
||||
_pid: pid,
|
||||
started: stat.StartTime,
|
||||
},
|
||||
cgroupManager: &mockCgroupManager{},
|
||||
}
|
||||
container.state = &createdState{c: container}
|
||||
state, err := container.State()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if state.InitProcessPid != pid {
|
||||
t.Fatalf("expected pid %d but received %d", pid, state.InitProcessPid)
|
||||
}
|
||||
if state.InitProcessStartTime != stat.StartTime {
|
||||
t.Fatalf("expected process start time %d but received %d", stat.StartTime, state.InitProcessStartTime)
|
||||
}
|
||||
if state.Config.Cgroups.Resources.Memory != 1024 {
|
||||
t.Fatalf("expected Memory to be 1024 but received %q", state.Config.Cgroups.Memory)
|
||||
}
|
||||
|
||||
// Set initProcessStartTime so we fake to be running
|
||||
container.initProcessStartTime = state.InitProcessStartTime
|
||||
container.state = &runningState{c: container}
|
||||
newConfig := container.Config()
|
||||
newConfig.Cgroups.Resources.Memory = 2048
|
||||
if err := container.Set(newConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
state, err = container.State()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if state.Config.Cgroups.Resources.Memory != 2048 {
|
||||
t.Fatalf("expected Memory to be 2048 but received %q", state.Config.Cgroups.Memory)
|
||||
}
|
||||
}
|
||||
|
||||
1
vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go
generated
vendored
1
vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go
generated
vendored
@@ -34,4 +34,5 @@ type CriuOpts struct {
|
||||
VethPairs []VethPairName // pass the veth to criu when restore
|
||||
ManageCgroupsMode cgMode // dump or restore cgroup mode
|
||||
EmptyNs uint32 // don't c/r properties for namespace from this mask
|
||||
AutoDedup bool // auto deduplication for incremental dumps
|
||||
}
|
||||
|
||||
399
vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.pb.go
generated
vendored
399
vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.pb.go
generated
vendored
@@ -23,6 +23,7 @@ It has these top-level messages:
|
||||
CriuFeatures
|
||||
CriuReq
|
||||
CriuResp
|
||||
CriuVersion
|
||||
*/
|
||||
package criurpc
|
||||
|
||||
@@ -103,19 +104,21 @@ const (
|
||||
CriuReqType_CPUINFO_DUMP CriuReqType = 7
|
||||
CriuReqType_CPUINFO_CHECK CriuReqType = 8
|
||||
CriuReqType_FEATURE_CHECK CriuReqType = 9
|
||||
CriuReqType_VERSION CriuReqType = 10
|
||||
)
|
||||
|
||||
var CriuReqType_name = map[int32]string{
|
||||
0: "EMPTY",
|
||||
1: "DUMP",
|
||||
2: "RESTORE",
|
||||
3: "CHECK",
|
||||
4: "PRE_DUMP",
|
||||
5: "PAGE_SERVER",
|
||||
6: "NOTIFY",
|
||||
7: "CPUINFO_DUMP",
|
||||
8: "CPUINFO_CHECK",
|
||||
9: "FEATURE_CHECK",
|
||||
0: "EMPTY",
|
||||
1: "DUMP",
|
||||
2: "RESTORE",
|
||||
3: "CHECK",
|
||||
4: "PRE_DUMP",
|
||||
5: "PAGE_SERVER",
|
||||
6: "NOTIFY",
|
||||
7: "CPUINFO_DUMP",
|
||||
8: "CPUINFO_CHECK",
|
||||
9: "FEATURE_CHECK",
|
||||
10: "VERSION",
|
||||
}
|
||||
var CriuReqType_value = map[string]int32{
|
||||
"EMPTY": 0,
|
||||
@@ -128,6 +131,7 @@ var CriuReqType_value = map[string]int32{
|
||||
"CPUINFO_DUMP": 7,
|
||||
"CPUINFO_CHECK": 8,
|
||||
"FEATURE_CHECK": 9,
|
||||
"VERSION": 10,
|
||||
}
|
||||
|
||||
func (x CriuReqType) Enum() *CriuReqType {
|
||||
@@ -190,8 +194,8 @@ func (m *CriuPageServerInfo) GetFd() int32 {
|
||||
}
|
||||
|
||||
type CriuVethPair struct {
|
||||
IfIn *string `protobuf:"bytes,1,req,name=if_in" json:"if_in,omitempty"`
|
||||
IfOut *string `protobuf:"bytes,2,req,name=if_out" json:"if_out,omitempty"`
|
||||
IfIn *string `protobuf:"bytes,1,req,name=if_in,json=ifIn" json:"if_in,omitempty"`
|
||||
IfOut *string `protobuf:"bytes,2,req,name=if_out,json=ifOut" json:"if_out,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
@@ -241,8 +245,8 @@ func (m *ExtMountMap) GetVal() string {
|
||||
|
||||
type JoinNamespace struct {
|
||||
Ns *string `protobuf:"bytes,1,req,name=ns" json:"ns,omitempty"`
|
||||
NsFile *string `protobuf:"bytes,2,req,name=ns_file" json:"ns_file,omitempty"`
|
||||
ExtraOpt *string `protobuf:"bytes,3,opt,name=extra_opt" json:"extra_opt,omitempty"`
|
||||
NsFile *string `protobuf:"bytes,2,req,name=ns_file,json=nsFile" json:"ns_file,omitempty"`
|
||||
ExtraOpt *string `protobuf:"bytes,3,opt,name=extra_opt,json=extraOpt" json:"extra_opt,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
@@ -340,55 +344,55 @@ func (m *UnixSk) GetInode() uint32 {
|
||||
}
|
||||
|
||||
type CriuOpts struct {
|
||||
ImagesDirFd *int32 `protobuf:"varint,1,req,name=images_dir_fd" json:"images_dir_fd,omitempty"`
|
||||
ImagesDirFd *int32 `protobuf:"varint,1,req,name=images_dir_fd,json=imagesDirFd" json:"images_dir_fd,omitempty"`
|
||||
Pid *int32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"`
|
||||
LeaveRunning *bool `protobuf:"varint,3,opt,name=leave_running" json:"leave_running,omitempty"`
|
||||
ExtUnixSk *bool `protobuf:"varint,4,opt,name=ext_unix_sk" json:"ext_unix_sk,omitempty"`
|
||||
TcpEstablished *bool `protobuf:"varint,5,opt,name=tcp_established" json:"tcp_established,omitempty"`
|
||||
EvasiveDevices *bool `protobuf:"varint,6,opt,name=evasive_devices" json:"evasive_devices,omitempty"`
|
||||
ShellJob *bool `protobuf:"varint,7,opt,name=shell_job" json:"shell_job,omitempty"`
|
||||
FileLocks *bool `protobuf:"varint,8,opt,name=file_locks" json:"file_locks,omitempty"`
|
||||
LogLevel *int32 `protobuf:"varint,9,opt,name=log_level,def=2" json:"log_level,omitempty"`
|
||||
LogFile *string `protobuf:"bytes,10,opt,name=log_file" json:"log_file,omitempty"`
|
||||
LeaveRunning *bool `protobuf:"varint,3,opt,name=leave_running,json=leaveRunning" json:"leave_running,omitempty"`
|
||||
ExtUnixSk *bool `protobuf:"varint,4,opt,name=ext_unix_sk,json=extUnixSk" json:"ext_unix_sk,omitempty"`
|
||||
TcpEstablished *bool `protobuf:"varint,5,opt,name=tcp_established,json=tcpEstablished" json:"tcp_established,omitempty"`
|
||||
EvasiveDevices *bool `protobuf:"varint,6,opt,name=evasive_devices,json=evasiveDevices" json:"evasive_devices,omitempty"`
|
||||
ShellJob *bool `protobuf:"varint,7,opt,name=shell_job,json=shellJob" json:"shell_job,omitempty"`
|
||||
FileLocks *bool `protobuf:"varint,8,opt,name=file_locks,json=fileLocks" json:"file_locks,omitempty"`
|
||||
LogLevel *int32 `protobuf:"varint,9,opt,name=log_level,json=logLevel,def=2" json:"log_level,omitempty"`
|
||||
LogFile *string `protobuf:"bytes,10,opt,name=log_file,json=logFile" json:"log_file,omitempty"`
|
||||
Ps *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"`
|
||||
NotifyScripts *bool `protobuf:"varint,12,opt,name=notify_scripts" json:"notify_scripts,omitempty"`
|
||||
NotifyScripts *bool `protobuf:"varint,12,opt,name=notify_scripts,json=notifyScripts" json:"notify_scripts,omitempty"`
|
||||
Root *string `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"`
|
||||
ParentImg *string `protobuf:"bytes,14,opt,name=parent_img" json:"parent_img,omitempty"`
|
||||
TrackMem *bool `protobuf:"varint,15,opt,name=track_mem" json:"track_mem,omitempty"`
|
||||
AutoDedup *bool `protobuf:"varint,16,opt,name=auto_dedup" json:"auto_dedup,omitempty"`
|
||||
WorkDirFd *int32 `protobuf:"varint,17,opt,name=work_dir_fd" json:"work_dir_fd,omitempty"`
|
||||
LinkRemap *bool `protobuf:"varint,18,opt,name=link_remap" json:"link_remap,omitempty"`
|
||||
ParentImg *string `protobuf:"bytes,14,opt,name=parent_img,json=parentImg" json:"parent_img,omitempty"`
|
||||
TrackMem *bool `protobuf:"varint,15,opt,name=track_mem,json=trackMem" json:"track_mem,omitempty"`
|
||||
AutoDedup *bool `protobuf:"varint,16,opt,name=auto_dedup,json=autoDedup" json:"auto_dedup,omitempty"`
|
||||
WorkDirFd *int32 `protobuf:"varint,17,opt,name=work_dir_fd,json=workDirFd" json:"work_dir_fd,omitempty"`
|
||||
LinkRemap *bool `protobuf:"varint,18,opt,name=link_remap,json=linkRemap" json:"link_remap,omitempty"`
|
||||
Veths []*CriuVethPair `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"`
|
||||
CpuCap *uint32 `protobuf:"varint,20,opt,name=cpu_cap,def=4294967295" json:"cpu_cap,omitempty"`
|
||||
ForceIrmap *bool `protobuf:"varint,21,opt,name=force_irmap" json:"force_irmap,omitempty"`
|
||||
ExecCmd []string `protobuf:"bytes,22,rep,name=exec_cmd" json:"exec_cmd,omitempty"`
|
||||
ExtMnt []*ExtMountMap `protobuf:"bytes,23,rep,name=ext_mnt" json:"ext_mnt,omitempty"`
|
||||
ManageCgroups *bool `protobuf:"varint,24,opt,name=manage_cgroups" json:"manage_cgroups,omitempty"`
|
||||
CgRoot []*CgroupRoot `protobuf:"bytes,25,rep,name=cg_root" json:"cg_root,omitempty"`
|
||||
RstSibling *bool `protobuf:"varint,26,opt,name=rst_sibling" json:"rst_sibling,omitempty"`
|
||||
InheritFd []*InheritFd `protobuf:"bytes,27,rep,name=inherit_fd" json:"inherit_fd,omitempty"`
|
||||
AutoExtMnt *bool `protobuf:"varint,28,opt,name=auto_ext_mnt" json:"auto_ext_mnt,omitempty"`
|
||||
ExtSharing *bool `protobuf:"varint,29,opt,name=ext_sharing" json:"ext_sharing,omitempty"`
|
||||
ExtMasters *bool `protobuf:"varint,30,opt,name=ext_masters" json:"ext_masters,omitempty"`
|
||||
SkipMnt []string `protobuf:"bytes,31,rep,name=skip_mnt" json:"skip_mnt,omitempty"`
|
||||
EnableFs []string `protobuf:"bytes,32,rep,name=enable_fs" json:"enable_fs,omitempty"`
|
||||
UnixSkIno []*UnixSk `protobuf:"bytes,33,rep,name=unix_sk_ino" json:"unix_sk_ino,omitempty"`
|
||||
ManageCgroupsMode *CriuCgMode `protobuf:"varint,34,opt,name=manage_cgroups_mode,enum=CriuCgMode" json:"manage_cgroups_mode,omitempty"`
|
||||
GhostLimit *uint32 `protobuf:"varint,35,opt,name=ghost_limit,def=1048576" json:"ghost_limit,omitempty"`
|
||||
IrmapScanPaths []string `protobuf:"bytes,36,rep,name=irmap_scan_paths" json:"irmap_scan_paths,omitempty"`
|
||||
CpuCap *uint32 `protobuf:"varint,20,opt,name=cpu_cap,json=cpuCap,def=4294967295" json:"cpu_cap,omitempty"`
|
||||
ForceIrmap *bool `protobuf:"varint,21,opt,name=force_irmap,json=forceIrmap" json:"force_irmap,omitempty"`
|
||||
ExecCmd []string `protobuf:"bytes,22,rep,name=exec_cmd,json=execCmd" json:"exec_cmd,omitempty"`
|
||||
ExtMnt []*ExtMountMap `protobuf:"bytes,23,rep,name=ext_mnt,json=extMnt" json:"ext_mnt,omitempty"`
|
||||
ManageCgroups *bool `protobuf:"varint,24,opt,name=manage_cgroups,json=manageCgroups" json:"manage_cgroups,omitempty"`
|
||||
CgRoot []*CgroupRoot `protobuf:"bytes,25,rep,name=cg_root,json=cgRoot" json:"cg_root,omitempty"`
|
||||
RstSibling *bool `protobuf:"varint,26,opt,name=rst_sibling,json=rstSibling" json:"rst_sibling,omitempty"`
|
||||
InheritFd []*InheritFd `protobuf:"bytes,27,rep,name=inherit_fd,json=inheritFd" json:"inherit_fd,omitempty"`
|
||||
AutoExtMnt *bool `protobuf:"varint,28,opt,name=auto_ext_mnt,json=autoExtMnt" json:"auto_ext_mnt,omitempty"`
|
||||
ExtSharing *bool `protobuf:"varint,29,opt,name=ext_sharing,json=extSharing" json:"ext_sharing,omitempty"`
|
||||
ExtMasters *bool `protobuf:"varint,30,opt,name=ext_masters,json=extMasters" json:"ext_masters,omitempty"`
|
||||
SkipMnt []string `protobuf:"bytes,31,rep,name=skip_mnt,json=skipMnt" json:"skip_mnt,omitempty"`
|
||||
EnableFs []string `protobuf:"bytes,32,rep,name=enable_fs,json=enableFs" json:"enable_fs,omitempty"`
|
||||
UnixSkIno []*UnixSk `protobuf:"bytes,33,rep,name=unix_sk_ino,json=unixSkIno" json:"unix_sk_ino,omitempty"`
|
||||
ManageCgroupsMode *CriuCgMode `protobuf:"varint,34,opt,name=manage_cgroups_mode,json=manageCgroupsMode,enum=CriuCgMode" json:"manage_cgroups_mode,omitempty"`
|
||||
GhostLimit *uint32 `protobuf:"varint,35,opt,name=ghost_limit,json=ghostLimit,def=1048576" json:"ghost_limit,omitempty"`
|
||||
IrmapScanPaths []string `protobuf:"bytes,36,rep,name=irmap_scan_paths,json=irmapScanPaths" json:"irmap_scan_paths,omitempty"`
|
||||
External []string `protobuf:"bytes,37,rep,name=external" json:"external,omitempty"`
|
||||
EmptyNs *uint32 `protobuf:"varint,38,opt,name=empty_ns" json:"empty_ns,omitempty"`
|
||||
JoinNs []*JoinNamespace `protobuf:"bytes,39,rep,name=join_ns" json:"join_ns,omitempty"`
|
||||
CgroupProps *string `protobuf:"bytes,41,opt,name=cgroup_props" json:"cgroup_props,omitempty"`
|
||||
CgroupPropsFile *string `protobuf:"bytes,42,opt,name=cgroup_props_file" json:"cgroup_props_file,omitempty"`
|
||||
CgroupDumpController []string `protobuf:"bytes,43,rep,name=cgroup_dump_controller" json:"cgroup_dump_controller,omitempty"`
|
||||
FreezeCgroup *string `protobuf:"bytes,44,opt,name=freeze_cgroup" json:"freeze_cgroup,omitempty"`
|
||||
EmptyNs *uint32 `protobuf:"varint,38,opt,name=empty_ns,json=emptyNs" json:"empty_ns,omitempty"`
|
||||
JoinNs []*JoinNamespace `protobuf:"bytes,39,rep,name=join_ns,json=joinNs" json:"join_ns,omitempty"`
|
||||
CgroupProps *string `protobuf:"bytes,41,opt,name=cgroup_props,json=cgroupProps" json:"cgroup_props,omitempty"`
|
||||
CgroupPropsFile *string `protobuf:"bytes,42,opt,name=cgroup_props_file,json=cgroupPropsFile" json:"cgroup_props_file,omitempty"`
|
||||
CgroupDumpController []string `protobuf:"bytes,43,rep,name=cgroup_dump_controller,json=cgroupDumpController" json:"cgroup_dump_controller,omitempty"`
|
||||
FreezeCgroup *string `protobuf:"bytes,44,opt,name=freeze_cgroup,json=freezeCgroup" json:"freeze_cgroup,omitempty"`
|
||||
Timeout *uint32 `protobuf:"varint,45,opt,name=timeout" json:"timeout,omitempty"`
|
||||
TcpSkipInFlight *bool `protobuf:"varint,46,opt,name=tcp_skip_in_flight" json:"tcp_skip_in_flight,omitempty"`
|
||||
WeakSysctls *bool `protobuf:"varint,47,opt,name=weak_sysctls" json:"weak_sysctls,omitempty"`
|
||||
LazyPages *bool `protobuf:"varint,48,opt,name=lazy_pages" json:"lazy_pages,omitempty"`
|
||||
StatusFd *int32 `protobuf:"varint,49,opt,name=status_fd" json:"status_fd,omitempty"`
|
||||
OrphanPtsMaster *bool `protobuf:"varint,50,opt,name=orphan_pts_master" json:"orphan_pts_master,omitempty"`
|
||||
TcpSkipInFlight *bool `protobuf:"varint,46,opt,name=tcp_skip_in_flight,json=tcpSkipInFlight" json:"tcp_skip_in_flight,omitempty"`
|
||||
WeakSysctls *bool `protobuf:"varint,47,opt,name=weak_sysctls,json=weakSysctls" json:"weak_sysctls,omitempty"`
|
||||
LazyPages *bool `protobuf:"varint,48,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"`
|
||||
StatusFd *int32 `protobuf:"varint,49,opt,name=status_fd,json=statusFd" json:"status_fd,omitempty"`
|
||||
OrphanPtsMaster *bool `protobuf:"varint,50,opt,name=orphan_pts_master,json=orphanPtsMaster" json:"orphan_pts_master,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
@@ -807,7 +811,8 @@ func (m *CriuNotify) GetPid() int32 {
|
||||
// List of features which can queried via
|
||||
// CRIU_REQ_TYPE__FEATURE_CHECK
|
||||
type CriuFeatures struct {
|
||||
MemTrack *bool `protobuf:"varint,1,opt,name=mem_track" json:"mem_track,omitempty"`
|
||||
MemTrack *bool `protobuf:"varint,1,opt,name=mem_track,json=memTrack" json:"mem_track,omitempty"`
|
||||
LazyPages *bool `protobuf:"varint,2,opt,name=lazy_pages,json=lazyPages" json:"lazy_pages,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
@@ -823,15 +828,22 @@ func (m *CriuFeatures) GetMemTrack() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *CriuFeatures) GetLazyPages() bool {
|
||||
if m != nil && m.LazyPages != nil {
|
||||
return *m.LazyPages
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type CriuReq struct {
|
||||
Type *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"`
|
||||
Opts *CriuOpts `protobuf:"bytes,2,opt,name=opts" json:"opts,omitempty"`
|
||||
NotifySuccess *bool `protobuf:"varint,3,opt,name=notify_success" json:"notify_success,omitempty"`
|
||||
NotifySuccess *bool `protobuf:"varint,3,opt,name=notify_success,json=notifySuccess" json:"notify_success,omitempty"`
|
||||
//
|
||||
// When set service won't close the connection but
|
||||
// will wait for more req-s to appear. Works not
|
||||
// for all request types.
|
||||
KeepOpen *bool `protobuf:"varint,4,opt,name=keep_open" json:"keep_open,omitempty"`
|
||||
KeepOpen *bool `protobuf:"varint,4,opt,name=keep_open,json=keepOpen" json:"keep_open,omitempty"`
|
||||
//
|
||||
// 'features' can be used to query which features
|
||||
// are supported by the installed criu/kernel
|
||||
@@ -887,9 +899,10 @@ type CriuResp struct {
|
||||
Restore *CriuRestoreResp `protobuf:"bytes,4,opt,name=restore" json:"restore,omitempty"`
|
||||
Notify *CriuNotify `protobuf:"bytes,5,opt,name=notify" json:"notify,omitempty"`
|
||||
Ps *CriuPageServerInfo `protobuf:"bytes,6,opt,name=ps" json:"ps,omitempty"`
|
||||
CrErrno *int32 `protobuf:"varint,7,opt,name=cr_errno" json:"cr_errno,omitempty"`
|
||||
CrErrno *int32 `protobuf:"varint,7,opt,name=cr_errno,json=crErrno" json:"cr_errno,omitempty"`
|
||||
Features *CriuFeatures `protobuf:"bytes,8,opt,name=features" json:"features,omitempty"`
|
||||
CrErrmsg *string `protobuf:"bytes,9,opt,name=cr_errmsg" json:"cr_errmsg,omitempty"`
|
||||
CrErrmsg *string `protobuf:"bytes,9,opt,name=cr_errmsg,json=crErrmsg" json:"cr_errmsg,omitempty"`
|
||||
Version *CriuVersion `protobuf:"bytes,10,opt,name=version" json:"version,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
@@ -961,6 +974,71 @@ func (m *CriuResp) GetCrErrmsg() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CriuResp) GetVersion() *CriuVersion {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Answer for criu_req_type.VERSION requests
|
||||
type CriuVersion struct {
|
||||
Major *int32 `protobuf:"varint,1,req,name=major" json:"major,omitempty"`
|
||||
Minor *int32 `protobuf:"varint,2,req,name=minor" json:"minor,omitempty"`
|
||||
Gitid *string `protobuf:"bytes,3,opt,name=gitid" json:"gitid,omitempty"`
|
||||
Sublevel *int32 `protobuf:"varint,4,opt,name=sublevel" json:"sublevel,omitempty"`
|
||||
Extra *int32 `protobuf:"varint,5,opt,name=extra" json:"extra,omitempty"`
|
||||
Name *string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CriuVersion) Reset() { *m = CriuVersion{} }
|
||||
func (m *CriuVersion) String() string { return proto.CompactTextString(m) }
|
||||
func (*CriuVersion) ProtoMessage() {}
|
||||
func (*CriuVersion) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
|
||||
|
||||
func (m *CriuVersion) GetMajor() int32 {
|
||||
if m != nil && m.Major != nil {
|
||||
return *m.Major
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CriuVersion) GetMinor() int32 {
|
||||
if m != nil && m.Minor != nil {
|
||||
return *m.Minor
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CriuVersion) GetGitid() string {
|
||||
if m != nil && m.Gitid != nil {
|
||||
return *m.Gitid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CriuVersion) GetSublevel() int32 {
|
||||
if m != nil && m.Sublevel != nil {
|
||||
return *m.Sublevel
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CriuVersion) GetExtra() int32 {
|
||||
if m != nil && m.Extra != nil {
|
||||
return *m.Extra
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CriuVersion) GetName() string {
|
||||
if m != nil && m.Name != nil {
|
||||
return *m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*CriuPageServerInfo)(nil), "criu_page_server_info")
|
||||
proto.RegisterType((*CriuVethPair)(nil), "criu_veth_pair")
|
||||
@@ -976,6 +1054,7 @@ func init() {
|
||||
proto.RegisterType((*CriuFeatures)(nil), "criu_features")
|
||||
proto.RegisterType((*CriuReq)(nil), "criu_req")
|
||||
proto.RegisterType((*CriuResp)(nil), "criu_resp")
|
||||
proto.RegisterType((*CriuVersion)(nil), "criu_version")
|
||||
proto.RegisterEnum("CriuCgMode", CriuCgMode_name, CriuCgMode_value)
|
||||
proto.RegisterEnum("CriuReqType", CriuReqType_name, CriuReqType_value)
|
||||
}
|
||||
@@ -983,87 +1062,117 @@ func init() {
|
||||
func init() { proto.RegisterFile("criurpc.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 1297 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x56, 0xdb, 0x77, 0xd3, 0xc6,
|
||||
0x13, 0xfe, 0xc5, 0x71, 0x7c, 0x59, 0x5f, 0x22, 0x04, 0x84, 0xe5, 0x9e, 0x9f, 0x28, 0x6d, 0x49,
|
||||
0x5b, 0x03, 0x3e, 0x5c, 0x0a, 0x4f, 0xe5, 0x04, 0x87, 0xe6, 0x14, 0x62, 0x1f, 0xc7, 0xe9, 0x39,
|
||||
0x3c, 0xed, 0x11, 0xd2, 0xda, 0x5e, 0x2c, 0x69, 0xd5, 0xdd, 0x95, 0x21, 0xfc, 0x03, 0x7d, 0xec,
|
||||
0x63, 0x1f, 0xfb, 0xaf, 0x76, 0x76, 0x24, 0x05, 0x41, 0x39, 0xbc, 0x80, 0x35, 0x9a, 0xcb, 0x37,
|
||||
0xdf, 0xcc, 0x7c, 0x0a, 0xe9, 0x05, 0x4a, 0x64, 0x2a, 0x0d, 0x06, 0xa9, 0x92, 0x46, 0x7a, 0x63,
|
||||
0x72, 0xd1, 0x1a, 0x58, 0xea, 0x2f, 0x38, 0xd3, 0x5c, 0xad, 0xb9, 0x62, 0x22, 0x99, 0x4b, 0x77,
|
||||
0x9b, 0x34, 0xfd, 0x30, 0x54, 0x5c, 0x6b, 0xba, 0xb1, 0xbb, 0xf1, 0x7d, 0xdb, 0xed, 0x92, 0x7a,
|
||||
0x2a, 0x95, 0xa1, 0x35, 0x78, 0xda, 0x72, 0x3b, 0x64, 0x33, 0x15, 0x21, 0xdd, 0xc4, 0x07, 0x42,
|
||||
0x6a, 0xf3, 0x90, 0xd6, 0xed, 0x6f, 0xef, 0x2e, 0xe9, 0x63, 0xc2, 0x35, 0x37, 0x4b, 0xc8, 0x2a,
|
||||
0x94, 0xdb, 0x23, 0x5b, 0x62, 0x0e, 0x49, 0x21, 0x4f, 0x0d, 0xf2, 0xf4, 0x49, 0x03, 0x1e, 0x65,
|
||||
0x66, 0x33, 0xc1, 0xb3, 0x77, 0x87, 0xf4, 0xf8, 0x7b, 0xc3, 0x62, 0x99, 0x25, 0xf0, 0xaf, 0x9f,
|
||||
0xda, 0xd4, 0x2b, 0x7e, 0x5a, 0x78, 0xc3, 0xc3, 0xda, 0x8f, 0x0a, 0xd7, 0x5f, 0x48, 0xff, 0xad,
|
||||
0x14, 0x09, 0x4b, 0xfc, 0x98, 0xeb, 0xd4, 0x0f, 0xb8, 0xad, 0x9c, 0xe8, 0xc2, 0x15, 0x10, 0x27,
|
||||
0x9a, 0xcd, 0x45, 0xc4, 0x73, 0x77, 0xf7, 0x1c, 0x69, 0x43, 0x66, 0xe5, 0x33, 0x99, 0x1a, 0x44,
|
||||
0xda, 0xf6, 0x6e, 0x13, 0x22, 0x92, 0x25, 0x57, 0xc2, 0xb0, 0x79, 0xf8, 0x69, 0xa5, 0xbc, 0x09,
|
||||
0x1b, 0xb9, 0x05, 0x98, 0x3a, 0xc1, 0x42, 0xc9, 0x2c, 0x65, 0x4a, 0x4a, 0x63, 0x5b, 0x0f, 0x8c,
|
||||
0x8a, 0x2a, 0x44, 0xf8, 0x66, 0x59, 0x60, 0xa2, 0xa4, 0x99, 0x25, 0xe2, 0x3d, 0xd3, 0x2b, 0x6c,
|
||||
0x34, 0x91, 0x21, 0xc7, 0x84, 0x3d, 0xef, 0xef, 0x36, 0x69, 0x23, 0x15, 0x50, 0x5e, 0xbb, 0x17,
|
||||
0x49, 0x4f, 0xc4, 0x40, 0xb2, 0x66, 0xa1, 0x50, 0x50, 0x1c, 0x9d, 0xce, 0x78, 0xcc, 0x49, 0x05,
|
||||
0x9f, 0x88, 0xfb, 0x6b, 0xce, 0x54, 0x96, 0x24, 0x22, 0x59, 0x20, 0xe8, 0x96, 0x7b, 0x9e, 0x74,
|
||||
0x2c, 0x43, 0x45, 0x19, 0xe4, 0xb9, 0xe5, 0x5e, 0x22, 0xdb, 0x26, 0x48, 0x19, 0xd7, 0xc6, 0x7f,
|
||||
0x13, 0x09, 0xbd, 0xe4, 0x21, 0xdd, 0x2a, 0x5f, 0xf0, 0xb5, 0xaf, 0x05, 0xa4, 0x09, 0xf9, 0x5a,
|
||||
0x04, 0x5c, 0xd3, 0x06, 0xbe, 0x00, 0x3a, 0xc0, 0x2d, 0x8a, 0xd8, 0x5b, 0xf9, 0x86, 0x36, 0xd1,
|
||||
0x04, 0x4d, 0x5b, 0xbe, 0x58, 0x24, 0x83, 0x95, 0xa6, 0x2d, 0xb4, 0x5d, 0x20, 0xed, 0x48, 0x2e,
|
||||
0x58, 0xc4, 0xd7, 0x3c, 0xa2, 0x6d, 0x8b, 0xeb, 0xe9, 0xc6, 0xd0, 0x75, 0x48, 0xcb, 0x5a, 0x91,
|
||||
0x5d, 0x82, 0x34, 0x78, 0xa4, 0x96, 0x6a, 0xda, 0x81, 0xdf, 0x9d, 0xe1, 0xce, 0xe0, 0xcb, 0x4b,
|
||||
0xb4, 0x43, 0xfa, 0x89, 0x34, 0x62, 0x7e, 0xca, 0x34, 0x38, 0x00, 0x0d, 0xb4, 0x8b, 0x35, 0x80,
|
||||
0x42, 0x4b, 0x2c, 0xed, 0x61, 0x26, 0x40, 0x91, 0xfa, 0x8a, 0xc3, 0xf8, 0x45, 0xbc, 0xa0, 0x7d,
|
||||
0xb4, 0x01, 0x58, 0x98, 0x5c, 0xb0, 0x62, 0x31, 0x8f, 0xe9, 0x76, 0x09, 0xd6, 0xcf, 0x8c, 0x84,
|
||||
0xae, 0xc2, 0x2c, 0xa5, 0x4e, 0x49, 0xcd, 0x3b, 0xa9, 0x56, 0x25, 0xa7, 0xe7, 0x90, 0x46, 0x70,
|
||||
0x8c, 0x44, 0xb2, 0x62, 0x8a, 0xc3, 0x3a, 0x51, 0x17, 0x1d, 0x6f, 0x90, 0x2d, 0xbb, 0x91, 0x9a,
|
||||
0x9e, 0xdf, 0xdd, 0x04, 0xc0, 0xdb, 0x83, 0xcf, 0x96, 0xf4, 0x2a, 0x69, 0x06, 0x69, 0xc6, 0x02,
|
||||
0x08, 0xb8, 0x00, 0x01, 0xbd, 0xa7, 0xe4, 0xc1, 0xf0, 0xc9, 0x83, 0x27, 0x8f, 0x1e, 0x0f, 0x9f,
|
||||
0x3c, 0xb4, 0x55, 0xe6, 0x52, 0x05, 0x9c, 0x09, 0x65, 0x33, 0x5e, 0xc4, 0x8c, 0xc0, 0x08, 0x7f,
|
||||
0xcf, 0x03, 0x16, 0xc4, 0x21, 0xdd, 0x81, 0xa4, 0x6d, 0xf7, 0x26, 0x69, 0xe2, 0x26, 0x27, 0x86,
|
||||
0x5e, 0xc2, 0x2a, 0xfd, 0xc1, 0xa7, 0x9b, 0x0d, 0x74, 0xc4, 0x7e, 0x62, 0x49, 0xca, 0xb7, 0x4b,
|
||||
0x53, 0x8a, 0xa9, 0xae, 0x43, 0xf1, 0x05, 0xae, 0x1a, 0xbd, 0x8c, 0x81, 0xdd, 0x41, 0x75, 0xfd,
|
||||
0xa0, 0xbc, 0xd2, 0x86, 0x69, 0x01, 0x83, 0x86, 0xa5, 0xb8, 0x82, 0x31, 0x37, 0xab, 0x9b, 0x4c,
|
||||
0xaf, 0x62, 0x58, 0x67, 0x50, 0x59, 0xee, 0x0b, 0xa4, 0x8b, 0x74, 0x95, 0x90, 0xae, 0x55, 0x77,
|
||||
0x49, 0x2f, 0x7d, 0x65, 0x73, 0x5d, 0xaf, 0x1a, 0x63, 0x5f, 0x1b, 0xae, 0x34, 0xbd, 0x51, 0xf6,
|
||||
0xa7, 0x57, 0x22, 0xc5, 0xd8, 0x9b, 0xd8, 0x9f, 0xbd, 0xa7, 0x04, 0xb6, 0x8d, 0xb3, 0xb9, 0xa6,
|
||||
0xbb, 0x68, 0xba, 0x4e, 0x3a, 0xc5, 0x5a, 0xc2, 0xc0, 0x25, 0xfd, 0x3f, 0xc2, 0x68, 0x0d, 0xca,
|
||||
0x8b, 0xd8, 0x23, 0xe7, 0x3f, 0x6d, 0x18, 0xc8, 0x80, 0xfb, 0xf0, 0xa0, 0x40, 0x7f, 0xd8, 0xcb,
|
||||
0x67, 0x00, 0x9d, 0x5b, 0xa3, 0x7b, 0x8d, 0x74, 0x16, 0x4b, 0x09, 0x7d, 0x46, 0x22, 0x16, 0x86,
|
||||
0xde, 0xc2, 0x29, 0x34, 0xef, 0xdf, 0x7b, 0xf0, 0xf3, 0xc3, 0xc7, 0x8f, 0x5c, 0x4a, 0x1c, 0x24,
|
||||
0x1f, 0x16, 0xc9, 0x4f, 0x98, 0xbd, 0x3f, 0x4d, 0xbf, 0x41, 0x08, 0x38, 0x07, 0xc0, 0x9d, 0x80,
|
||||
0x4c, 0xdc, 0x3e, 0xb3, 0xc4, 0xa9, 0x39, 0x65, 0x20, 0x0d, 0xdf, 0xda, 0x34, 0xee, 0x2e, 0x69,
|
||||
0xe6, 0xc2, 0xa1, 0xe9, 0x77, 0xc5, 0xfc, 0x3f, 0x13, 0x12, 0x60, 0xab, 0xa0, 0x1c, 0x74, 0x11,
|
||||
0x06, 0x73, 0x07, 0xb7, 0xf0, 0x32, 0x39, 0x57, 0xb5, 0xe6, 0xeb, 0xbf, 0x87, 0xaf, 0x6e, 0x90,
|
||||
0x9d, 0xe2, 0x55, 0x98, 0xc5, 0x29, 0x0b, 0x64, 0x62, 0x94, 0x8c, 0x22, 0xae, 0xe8, 0x0f, 0x08,
|
||||
0x02, 0x6e, 0x79, 0xae, 0x38, 0xff, 0x50, 0xb6, 0x4e, 0x7f, 0xc4, 0x30, 0x10, 0x29, 0x23, 0x62,
|
||||
0x6e, 0xe5, 0xef, 0x27, 0x84, 0x76, 0x85, 0xb8, 0xf6, 0x8e, 0x91, 0x6a, 0x40, 0x34, 0x8f, 0xc4,
|
||||
0x62, 0x69, 0xe8, 0xa0, 0x38, 0xc5, 0xee, 0x3b, 0xee, 0xaf, 0x98, 0x3e, 0xd5, 0x81, 0x89, 0x34,
|
||||
0xbd, 0x5b, 0xde, 0x41, 0xe4, 0x7f, 0x38, 0xc5, 0x6b, 0xd3, 0xf4, 0xde, 0xd9, 0x6d, 0x1b, 0xdf,
|
||||
0x64, 0xda, 0x2e, 0xc3, 0x7d, 0xbc, 0x02, 0xc0, 0x2e, 0x55, 0xba, 0xb4, 0x6c, 0x19, 0x5d, 0xcc,
|
||||
0x96, 0x0e, 0xad, 0xb7, 0xe7, 0x15, 0x1a, 0x8d, 0xc8, 0x41, 0xe2, 0x53, 0x4b, 0x19, 0xfc, 0x6f,
|
||||
0xa4, 0xe2, 0x21, 0xaa, 0x5c, 0xcb, 0xdb, 0x85, 0xd6, 0xad, 0x4f, 0x61, 0xce, 0xdd, 0x0a, 0xb5,
|
||||
0x42, 0xe9, 0xf2, 0xf6, 0x40, 0x24, 0xad, 0x47, 0x7e, 0xe1, 0x56, 0xd7, 0xf3, 0x23, 0x2f, 0x64,
|
||||
0xb2, 0xaa, 0x6c, 0x50, 0x11, 0xbf, 0x3b, 0x6c, 0xce, 0x01, 0x24, 0xa4, 0xb2, 0x80, 0xe1, 0xb2,
|
||||
0x19, 0xde, 0x78, 0x51, 0xf1, 0xaf, 0x0d, 0xd2, 0x2a, 0x4a, 0xfe, 0x01, 0xdb, 0x50, 0x37, 0xa7,
|
||||
0x69, 0x2e, 0xa5, 0x7d, 0x38, 0xa4, 0xf2, 0x05, 0xb3, 0x56, 0xd8, 0x86, 0xba, 0x15, 0x55, 0x4c,
|
||||
0xde, 0x19, 0x92, 0xc1, 0x47, 0x99, 0xad, 0x28, 0x4e, 0x16, 0x04, 0xf6, 0xeb, 0xb5, 0x59, 0x12,
|
||||
0xb4, 0xe2, 0x3c, 0x05, 0x27, 0x9e, 0x14, 0x0a, 0xba, 0x4b, 0x5a, 0x25, 0x1c, 0x94, 0xce, 0x4e,
|
||||
0x59, 0xa6, 0xb4, 0x7a, 0x7f, 0xd6, 0x0a, 0x05, 0xc7, 0xe6, 0xbf, 0x0e, 0x09, 0x06, 0x5b, 0x56,
|
||||
0xb4, 0x1f, 0x06, 0x7b, 0xd4, 0x75, 0xcb, 0x2f, 0xd6, 0x3f, 0x13, 0x9c, 0x8f, 0x8c, 0xdf, 0x22,
|
||||
0xcd, 0x82, 0x5a, 0x84, 0xd3, 0x19, 0xba, 0x83, 0xff, 0xf2, 0x7d, 0x8d, 0x34, 0xf2, 0x6e, 0x0a,
|
||||
0x80, 0xdd, 0x41, 0x95, 0xf1, 0x5c, 0x81, 0x1b, 0x5f, 0x55, 0x60, 0xc7, 0x72, 0xca, 0xb8, 0x52,
|
||||
0x70, 0x9d, 0x4d, 0xdc, 0x8b, 0x6a, 0xdb, 0xad, 0x2f, 0xb5, 0x6d, 0xb9, 0xca, 0x63, 0x62, 0xbd,
|
||||
0xc0, 0x2f, 0x40, 0x7b, 0x8f, 0xc1, 0x79, 0x54, 0x8f, 0x95, 0x90, 0xc6, 0xe1, 0x8b, 0xa3, 0xf1,
|
||||
0x74, 0xe4, 0xfc, 0x0f, 0x06, 0xdd, 0xdc, 0x7f, 0xc1, 0x8e, 0xc6, 0x47, 0x23, 0x67, 0xc3, 0x6d,
|
||||
0x93, 0xad, 0xc9, 0x74, 0x3c, 0x39, 0x76, 0x6a, 0x6e, 0x8b, 0xd4, 0x8f, 0xc7, 0x07, 0x33, 0x67,
|
||||
0xd3, 0xfe, 0x3a, 0x38, 0x79, 0xf9, 0xd2, 0xa9, 0xdb, 0xb8, 0xe3, 0xd9, 0xf4, 0x70, 0x7f, 0xe6,
|
||||
0xd8, 0x4f, 0x5f, 0xf3, 0xf9, 0xe8, 0xe0, 0xd9, 0xc9, 0xcb, 0x99, 0xd3, 0xd8, 0xfb, 0x67, 0xa3,
|
||||
0xd8, 0x90, 0x33, 0x42, 0x21, 0xd3, 0xe8, 0xd5, 0x64, 0xf6, 0x1a, 0x2a, 0x40, 0xfc, 0xf3, 0x93,
|
||||
0x57, 0x13, 0x48, 0x0f, 0x31, 0xd3, 0xd1, 0xf1, 0xcc, 0x16, 0xae, 0x59, 0x8f, 0xfd, 0x5f, 0x47,
|
||||
0xfb, 0xbf, 0x41, 0x85, 0x2e, 0x69, 0x4d, 0xa6, 0x23, 0x86, 0x5e, 0x75, 0x98, 0x45, 0x67, 0xf2,
|
||||
0xec, 0xc5, 0x88, 0x1d, 0x8f, 0xa6, 0xbf, 0x8f, 0xa6, 0x8e, 0xfd, 0x03, 0xa5, 0x71, 0x34, 0x9e,
|
||||
0x1d, 0x1e, 0xbc, 0x76, 0x1a, 0xc0, 0x48, 0x77, 0x7f, 0x72, 0x72, 0x78, 0x74, 0x30, 0xce, 0xdd,
|
||||
0x9b, 0xd0, 0x6f, 0xaf, 0xb4, 0xe4, 0xf9, 0xec, 0xba, 0xf4, 0x0e, 0x46, 0xcf, 0x66, 0x27, 0x90,
|
||||
0x33, 0x37, 0xb5, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xed, 0xcb, 0xc7, 0x95, 0x39, 0x09, 0x00,
|
||||
0x00,
|
||||
// 1781 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xdd, 0x72, 0x5b, 0xb7,
|
||||
0x11, 0x0e, 0x29, 0xfe, 0x1c, 0x82, 0x3f, 0xa6, 0x10, 0xdb, 0x81, 0x93, 0xda, 0x62, 0xe8, 0x28,
|
||||
0x51, 0x15, 0x97, 0x4d, 0x58, 0x3b, 0xae, 0x33, 0xed, 0x85, 0x47, 0x22, 0x5d, 0x36, 0x92, 0xc8,
|
||||
0x01, 0x25, 0xcf, 0xe4, 0x0a, 0x73, 0x74, 0x0e, 0x48, 0xc1, 0x3c, 0x7f, 0x05, 0x40, 0x45, 0xf2,
|
||||
0x83, 0xf4, 0x29, 0xfa, 0x0c, 0x7d, 0x84, 0xbe, 0x4e, 0x6f, 0x3b, 0xbb, 0x00, 0x65, 0x29, 0xc9,
|
||||
0xb4, 0xbd, 0xc3, 0x7e, 0x58, 0x00, 0xbb, 0xfb, 0xed, 0x0f, 0x48, 0x3b, 0xd2, 0x6a, 0xad, 0x8b,
|
||||
0x68, 0x50, 0xe8, 0xdc, 0xe6, 0xfd, 0x25, 0x79, 0x00, 0x80, 0x28, 0xc2, 0xa5, 0x14, 0x46, 0xea,
|
||||
0x4b, 0xa9, 0x85, 0xca, 0x16, 0x39, 0x65, 0xa4, 0x1e, 0xc6, 0xb1, 0x96, 0xc6, 0xb0, 0x52, 0xaf,
|
||||
0xb4, 0xd7, 0xe0, 0x1b, 0x91, 0x52, 0x52, 0x29, 0x72, 0x6d, 0x59, 0xb9, 0x57, 0xda, 0xab, 0x72,
|
||||
0x5c, 0xd3, 0x2e, 0xd9, 0x2a, 0x54, 0xcc, 0xb6, 0x10, 0x82, 0x25, 0xed, 0x90, 0xf2, 0x22, 0x66,
|
||||
0x15, 0x04, 0xca, 0x8b, 0xb8, 0xff, 0x27, 0xd2, 0xc1, 0x87, 0x2e, 0xa5, 0xbd, 0x10, 0x45, 0xa8,
|
||||
0x34, 0xfd, 0x98, 0x54, 0xd5, 0x42, 0xa8, 0x8c, 0x95, 0x7a, 0xe5, 0xbd, 0x06, 0xaf, 0xa8, 0xc5,
|
||||
0x24, 0xa3, 0x0f, 0x48, 0x4d, 0x2d, 0x44, 0xbe, 0x86, 0xeb, 0x01, 0xad, 0xaa, 0xc5, 0x74, 0x6d,
|
||||
0xfb, 0x7f, 0x20, 0x6d, 0x79, 0x65, 0x45, 0x9a, 0xaf, 0x33, 0x2b, 0xd2, 0xb0, 0x80, 0x07, 0x57,
|
||||
0xf2, 0xda, 0x1f, 0x85, 0x25, 0x20, 0x97, 0x61, 0xe2, 0x8f, 0xc1, 0xb2, 0xff, 0x96, 0x74, 0xde,
|
||||
0xe5, 0x2a, 0x13, 0x59, 0x98, 0x4a, 0x53, 0x84, 0x91, 0x04, 0xa3, 0x32, 0xe3, 0x0f, 0x95, 0x33,
|
||||
0x43, 0x3f, 0x21, 0xf5, 0xcc, 0x88, 0x85, 0x4a, 0xa4, 0x3f, 0x57, 0xcb, 0xcc, 0x58, 0x25, 0x92,
|
||||
0x7e, 0x46, 0x1a, 0xf2, 0xca, 0xea, 0x50, 0xe4, 0x85, 0x45, 0xaf, 0x1a, 0x3c, 0x40, 0x60, 0x5a,
|
||||
0xd8, 0xfe, 0x80, 0x10, 0x95, 0x5d, 0x48, 0xad, 0xac, 0x58, 0xc4, 0xbf, 0x62, 0x89, 0x73, 0x1d,
|
||||
0x2e, 0x74, 0xae, 0xbf, 0x20, 0xcd, 0x68, 0xa9, 0xf3, 0x75, 0x21, 0x74, 0x9e, 0x5b, 0x88, 0x5f,
|
||||
0x64, 0x75, 0xe2, 0xc3, 0x8a, 0x6b, 0x8c, 0x69, 0x68, 0x2f, 0xbc, 0x15, 0xb8, 0xee, 0xef, 0x90,
|
||||
0xfa, 0x3a, 0x53, 0x57, 0xc2, 0xac, 0xe8, 0x7d, 0x52, 0x55, 0x59, 0x1e, 0x4b, 0x7c, 0xa5, 0xcd,
|
||||
0x9d, 0xd0, 0xff, 0x57, 0x9b, 0x34, 0x30, 0xa6, 0x79, 0x61, 0x0d, 0xed, 0x93, 0xb6, 0x4a, 0xc3,
|
||||
0xa5, 0x34, 0x22, 0x56, 0x5a, 0x2c, 0x62, 0xd4, 0xad, 0xf2, 0xa6, 0x03, 0x0f, 0x95, 0x1e, 0xc7,
|
||||
0x1b, 0x9a, 0xca, 0x1f, 0x68, 0x7a, 0x4a, 0xda, 0x89, 0x0c, 0x2f, 0xa5, 0xd0, 0xeb, 0x2c, 0x53,
|
||||
0xd9, 0x12, 0x9d, 0x0d, 0x78, 0x0b, 0x41, 0xee, 0x30, 0xfa, 0x84, 0x34, 0x21, 0xfa, 0xde, 0x1a,
|
||||
0x24, 0x35, 0xe0, 0x10, 0xa0, 0xb3, 0x4c, 0x5d, 0xcd, 0x57, 0xf4, 0x2b, 0x72, 0xcf, 0x46, 0x85,
|
||||
0x90, 0xc6, 0x86, 0xe7, 0x89, 0x32, 0x17, 0x32, 0x66, 0x55, 0xd4, 0xe9, 0xd8, 0xa8, 0x18, 0x7d,
|
||||
0x40, 0x41, 0x51, 0x5e, 0x86, 0x46, 0x5d, 0x4a, 0x11, 0xcb, 0x4b, 0x15, 0x49, 0xc3, 0x6a, 0x4e,
|
||||
0xd1, 0xc3, 0x87, 0x0e, 0x85, 0xf8, 0x9b, 0x0b, 0x99, 0x24, 0xe2, 0x5d, 0x7e, 0xce, 0xea, 0xa8,
|
||||
0x12, 0x20, 0xf0, 0xd7, 0xfc, 0x9c, 0x3e, 0x26, 0x04, 0x28, 0x13, 0x49, 0x1e, 0xad, 0x0c, 0x0b,
|
||||
0x9c, 0x35, 0x80, 0x1c, 0x01, 0x40, 0x9f, 0x90, 0x46, 0x92, 0x2f, 0x45, 0x22, 0x2f, 0x65, 0xc2,
|
||||
0x1a, 0xe0, 0xea, 0xf7, 0xa5, 0x21, 0x0f, 0x92, 0x7c, 0x79, 0x04, 0x10, 0x7d, 0x44, 0x60, 0xed,
|
||||
0x58, 0x27, 0x2e, 0xb5, 0x93, 0x7c, 0x89, 0xb4, 0x7f, 0x49, 0xca, 0x85, 0x61, 0xcd, 0x5e, 0x69,
|
||||
0xaf, 0x39, 0x7c, 0x38, 0xf8, 0xd5, 0xc2, 0xe0, 0xe5, 0xc2, 0xd0, 0x5d, 0xd2, 0xc9, 0x72, 0xab,
|
||||
0x16, 0xd7, 0xc2, 0x44, 0x5a, 0x15, 0xd6, 0xb0, 0x16, 0x5a, 0xd1, 0x76, 0xe8, 0xdc, 0x81, 0xc0,
|
||||
0x2a, 0x30, 0xce, 0xda, 0x8e, 0x69, 0x64, 0xff, 0x31, 0x21, 0x45, 0xa8, 0x65, 0x66, 0x85, 0x4a,
|
||||
0x97, 0xac, 0x83, 0x3b, 0x0d, 0x87, 0x4c, 0xd2, 0x25, 0x38, 0x6e, 0x75, 0x18, 0xad, 0x44, 0x2a,
|
||||
0x53, 0x76, 0xcf, 0x39, 0x8e, 0xc0, 0xb1, 0x4c, 0xe1, 0x6c, 0xb8, 0xb6, 0xb9, 0x88, 0x65, 0xbc,
|
||||
0x2e, 0x58, 0xd7, 0x39, 0x0e, 0xc8, 0x21, 0x00, 0x40, 0xd3, 0x4f, 0xb9, 0x5e, 0x6d, 0xf8, 0xdf,
|
||||
0x46, 0x96, 0x1b, 0x00, 0x39, 0xf6, 0x1f, 0x13, 0x92, 0xa8, 0x6c, 0x25, 0xb4, 0x4c, 0xc3, 0x82,
|
||||
0x51, 0x77, 0x1c, 0x10, 0x0e, 0x00, 0xdd, 0x25, 0x55, 0x28, 0x4e, 0xc3, 0x3e, 0xee, 0x6d, 0xed,
|
||||
0x35, 0x87, 0xf7, 0x06, 0x77, 0xeb, 0x95, 0xbb, 0x5d, 0xfa, 0x94, 0xd4, 0xa3, 0x62, 0x2d, 0xa2,
|
||||
0xb0, 0x60, 0xf7, 0x7b, 0xa5, 0xbd, 0xf6, 0xf7, 0xe4, 0xf9, 0xf0, 0xd5, 0xf3, 0x57, 0xdf, 0xbd,
|
||||
0x1c, 0xbe, 0x7a, 0xc1, 0x6b, 0x51, 0xb1, 0x3e, 0x08, 0x0b, 0xba, 0x43, 0x9a, 0x8b, 0x5c, 0x47,
|
||||
0x52, 0x28, 0x0d, 0x6f, 0x3d, 0xc0, 0xb7, 0x08, 0x42, 0x13, 0x40, 0x80, 0x04, 0x79, 0x25, 0x23,
|
||||
0x11, 0xa5, 0x31, 0x7b, 0xd8, 0xdb, 0x02, 0x12, 0x40, 0x3e, 0x48, 0x21, 0x49, 0xea, 0x58, 0xeb,
|
||||
0x99, 0x65, 0x9f, 0xa0, 0x25, 0x9d, 0xc1, 0x9d, 0xda, 0xe7, 0x35, 0x79, 0x65, 0x8f, 0x33, 0x0b,
|
||||
0x2c, 0xa4, 0x61, 0x06, 0xfc, 0xb8, 0xf2, 0x32, 0x8c, 0x39, 0x16, 0x1c, 0x7a, 0xe0, 0x40, 0xba,
|
||||
0x4b, 0xea, 0xd1, 0x12, 0x4b, 0x8f, 0x3d, 0xc2, 0xfb, 0x5a, 0x83, 0x5b, 0xe5, 0xc8, 0x6b, 0xd1,
|
||||
0x92, 0x03, 0x31, 0x3b, 0xa4, 0xa9, 0x8d, 0x15, 0x46, 0x9d, 0x27, 0x50, 0x07, 0x9f, 0x3a, 0x93,
|
||||
0xb5, 0xb1, 0x73, 0x87, 0xd0, 0xfd, 0xdb, 0x65, 0xcf, 0x3e, 0xc3, 0xab, 0x9a, 0x83, 0x0f, 0x10,
|
||||
0x6f, 0xf8, 0xf5, 0x38, 0xa6, 0x3d, 0xd2, 0x42, 0xa6, 0x36, 0x8e, 0xfc, 0xc6, 0xdd, 0x06, 0xd8,
|
||||
0xc8, 0x19, 0xbf, 0xe3, 0x6a, 0xca, 0x5c, 0x84, 0x1a, 0x9e, 0x7b, 0xec, 0x14, 0xe4, 0x95, 0x9d,
|
||||
0x3b, 0x64, 0xa3, 0x90, 0x86, 0xc6, 0x4a, 0x6d, 0xd8, 0x93, 0x1b, 0x85, 0x63, 0x87, 0x40, 0x08,
|
||||
0xcd, 0x4a, 0x15, 0x78, 0xff, 0x8e, 0x0b, 0x21, 0xc8, 0x70, 0x39, 0xb4, 0xaf, 0x2c, 0x3c, 0x4f,
|
||||
0xa4, 0x58, 0x18, 0xd6, 0xc3, 0xbd, 0xc0, 0x01, 0x63, 0x43, 0xf7, 0x48, 0xd3, 0x57, 0xb2, 0x50,
|
||||
0x59, 0xce, 0x3e, 0x47, 0x47, 0x82, 0x81, 0xc7, 0x78, 0x63, 0x8d, 0x45, 0x3d, 0xc9, 0x72, 0xfa,
|
||||
0x67, 0xf2, 0xf1, 0xdd, 0x00, 0x8b, 0x14, 0x9a, 0x50, 0xbf, 0x57, 0xda, 0xeb, 0x0c, 0xdb, 0x2e,
|
||||
0x3f, 0xa2, 0x25, 0x82, 0x7c, 0xfb, 0x4e, 0xd0, 0x8f, 0xf3, 0x58, 0xc2, 0x43, 0xcb, 0x8b, 0xdc,
|
||||
0x58, 0x91, 0xa8, 0x54, 0x59, 0xf6, 0x14, 0xb3, 0xa5, 0xfe, 0xed, 0x37, 0xcf, 0xff, 0xf8, 0xe2,
|
||||
0xe5, 0x77, 0x9c, 0xe0, 0xde, 0x11, 0x6c, 0xd1, 0x3d, 0xd2, 0xc5, 0x44, 0x11, 0x26, 0x0a, 0x33,
|
||||
0x01, 0xdd, 0xcf, 0xb0, 0x2f, 0xd0, 0xec, 0x0e, 0xe2, 0xf3, 0x28, 0xcc, 0x66, 0x80, 0xd2, 0x4f,
|
||||
0x21, 0x6f, 0xac, 0xd4, 0x59, 0x98, 0xb0, 0x5d, 0xef, 0x98, 0x97, 0x31, 0xa7, 0xd2, 0xc2, 0x5e,
|
||||
0x8b, 0xcc, 0xb0, 0x2f, 0xe1, 0x31, 0x5e, 0x47, 0xf9, 0x04, 0x7c, 0xae, 0xbb, 0x51, 0x60, 0xd8,
|
||||
0x57, 0x3e, 0xbb, 0xef, 0x8e, 0x06, 0x5e, 0x03, 0xf9, 0xc4, 0xd0, 0xcf, 0x49, 0xcb, 0x67, 0x47,
|
||||
0xa1, 0xf3, 0xc2, 0xb0, 0xdf, 0x62, 0x85, 0xfa, 0x06, 0x3e, 0x03, 0x88, 0xee, 0x93, 0xed, 0xdb,
|
||||
0x2a, 0xae, 0x93, 0xec, 0xa3, 0xde, 0xbd, 0x5b, 0x7a, 0xd8, 0x51, 0x9e, 0x93, 0x87, 0x5e, 0x37,
|
||||
0x5e, 0xa7, 0x85, 0x88, 0xf2, 0xcc, 0xea, 0x3c, 0x49, 0xa4, 0x66, 0x5f, 0xa3, 0xf5, 0xf7, 0xdd,
|
||||
0xee, 0xe1, 0x3a, 0x2d, 0x0e, 0x6e, 0xf6, 0xa0, 0x2b, 0x2f, 0xb4, 0x94, 0xef, 0x37, 0x81, 0x67,
|
||||
0xcf, 0xf0, 0xf6, 0x96, 0x03, 0x5d, 0x8c, 0x61, 0x42, 0x5b, 0x95, 0x4a, 0x98, 0x95, 0xbf, 0x73,
|
||||
0xde, 0x7a, 0x91, 0x7e, 0x4d, 0x28, 0xf4, 0x63, 0xcc, 0x0e, 0x95, 0x89, 0x45, 0xa2, 0x96, 0x17,
|
||||
0x96, 0x0d, 0x30, 0x83, 0xa0, 0x53, 0xcf, 0x57, 0xaa, 0x98, 0x64, 0x63, 0x84, 0xc1, 0xe1, 0x9f,
|
||||
0x64, 0xb8, 0x12, 0xe6, 0xda, 0x44, 0x36, 0x31, 0xec, 0xf7, 0xa8, 0xd6, 0x04, 0x6c, 0xee, 0x20,
|
||||
0x6c, 0x1c, 0xe1, 0xfb, 0x6b, 0xec, 0x85, 0x86, 0x7d, 0xe3, 0x1b, 0x47, 0xf8, 0xfe, 0x7a, 0x06,
|
||||
0x00, 0x36, 0x6b, 0x1b, 0xda, 0xb5, 0x81, 0xba, 0xf8, 0x16, 0xbb, 0x4e, 0xe0, 0x80, 0x71, 0x0c,
|
||||
0xc1, 0xca, 0x75, 0x71, 0x01, 0xb4, 0x5a, 0xe3, 0xb3, 0x99, 0x0d, 0x9d, 0x29, 0x6e, 0x63, 0x66,
|
||||
0x8d, 0x4b, 0xe9, 0xfe, 0x33, 0xff, 0x47, 0xc0, 0x50, 0x69, 0x69, 0x0a, 0xa0, 0x5b, 0x4b, 0x63,
|
||||
0x73, 0x2d, 0x63, 0x9c, 0x97, 0x01, 0xbf, 0x91, 0xfb, 0xbb, 0x64, 0x1b, 0xb5, 0x3d, 0xe0, 0x0e,
|
||||
0xf8, 0x09, 0xe7, 0x66, 0x1f, 0x2c, 0xfb, 0x2f, 0x49, 0x13, 0xd5, 0x5c, 0x6b, 0xa6, 0x0f, 0x49,
|
||||
0xcd, 0xf5, 0x6c, 0x3f, 0x7f, 0xbd, 0xf4, 0xcb, 0xd1, 0xd8, 0xff, 0xc1, 0xfd, 0x95, 0xc4, 0x42,
|
||||
0x86, 0x76, 0xad, 0x9d, 0x9f, 0xa9, 0x4c, 0x05, 0xb6, 0xe3, 0x8d, 0x35, 0xa9, 0x4c, 0x4f, 0x41,
|
||||
0xfe, 0x59, 0x8c, 0xca, 0x3f, 0x8b, 0x51, 0xff, 0x9f, 0x25, 0x12, 0x78, 0x6b, 0xff, 0x46, 0xfb,
|
||||
0xa4, 0x62, 0xaf, 0x0b, 0x37, 0xcd, 0x3b, 0xc3, 0xce, 0x60, 0xb3, 0x21, 0x00, 0xe5, 0xb8, 0x47,
|
||||
0x9f, 0x90, 0x0a, 0x8c, 0x75, 0xbc, 0xa9, 0x39, 0x24, 0x83, 0x9b, 0x41, 0xcf, 0x11, 0xbf, 0x3d,
|
||||
0x82, 0xd6, 0x51, 0x04, 0xdf, 0xb4, 0xad, 0x3b, 0x23, 0xc8, 0x81, 0x60, 0xf3, 0x4a, 0xca, 0x42,
|
||||
0xe4, 0x85, 0xcc, 0xfc, 0xe0, 0x0e, 0x00, 0x98, 0x16, 0x32, 0xa3, 0xfb, 0x24, 0xd8, 0x38, 0x87,
|
||||
0x03, 0xbb, 0xb9, 0xb1, 0x65, 0x83, 0xf2, 0x9b, 0xfd, 0xfe, 0xbf, 0xcb, 0xfe, 0xb3, 0x81, 0x61,
|
||||
0xfe, 0x7f, 0x3c, 0x60, 0xa4, 0xbe, 0x31, 0x0d, 0xbe, 0x35, 0x01, 0xdf, 0x88, 0xf4, 0x29, 0xa9,
|
||||
0x00, 0xc5, 0x68, 0xf1, 0xcd, 0xa0, 0xb9, 0x21, 0x9d, 0xe3, 0x26, 0x7d, 0x46, 0xea, 0x9e, 0x59,
|
||||
0xb4, 0xbb, 0x39, 0xa4, 0x83, 0x5f, 0xd0, 0xcd, 0x37, 0x2a, 0xf4, 0x0b, 0x52, 0x73, 0x8e, 0x7b,
|
||||
0x47, 0x5a, 0x83, 0x5b, 0xa4, 0x73, 0xbf, 0xe7, 0xe7, 0x7b, 0xed, 0x7f, 0xce, 0xf7, 0x47, 0x40,
|
||||
0x96, 0x90, 0x5a, 0x67, 0x39, 0xfe, 0x3e, 0xaa, 0xbc, 0x1e, 0xe9, 0x11, 0x88, 0x77, 0x62, 0x16,
|
||||
0xfc, 0xf7, 0x98, 0x41, 0xf0, 0xdd, 0x35, 0xa9, 0x59, 0xe2, 0x4f, 0xa4, 0xc1, 0x03, 0xbc, 0x27,
|
||||
0x35, 0x4b, 0x18, 0x73, 0x97, 0x52, 0x1b, 0x95, 0x67, 0xf8, 0x0b, 0x69, 0x6e, 0x1a, 0xaa, 0x07,
|
||||
0xf9, 0x66, 0xb7, 0xff, 0xf7, 0x12, 0x69, 0xdd, 0xde, 0x81, 0xdf, 0x60, 0x1a, 0xbe, 0xcb, 0xb5,
|
||||
0xcf, 0x72, 0x27, 0x20, 0xaa, 0xb2, 0x5c, 0xfb, 0x8f, 0xa7, 0x13, 0x00, 0x5d, 0x2a, 0xeb, 0xbf,
|
||||
0xe6, 0x0d, 0xee, 0x04, 0x28, 0x2b, 0xb3, 0x3e, 0x77, 0x3f, 0xa4, 0x8a, 0x2f, 0x58, 0x2f, 0xc3,
|
||||
0x09, 0xfc, 0xe9, 0x62, 0x20, 0xab, 0xdc, 0x09, 0xf0, 0x95, 0x81, 0x5e, 0x89, 0xb1, 0x6b, 0x70,
|
||||
0x5c, 0xef, 0x0b, 0x6f, 0x97, 0x1f, 0x01, 0x94, 0x90, 0xda, 0xe4, 0xcd, 0xc9, 0x94, 0x8f, 0xba,
|
||||
0x1f, 0xd1, 0x26, 0xa9, 0x1f, 0xbc, 0x11, 0x27, 0xd3, 0x93, 0x51, 0xb7, 0x44, 0x1b, 0xa4, 0x3a,
|
||||
0xe3, 0xd3, 0xd9, 0xbc, 0x5b, 0xa6, 0x01, 0xa9, 0xcc, 0xa7, 0xe3, 0xd3, 0xee, 0x16, 0xac, 0xc6,
|
||||
0x67, 0x47, 0x47, 0xdd, 0x0a, 0x9c, 0x9b, 0x9f, 0xf2, 0xc9, 0xc1, 0x69, 0xb7, 0x0a, 0xe7, 0x0e,
|
||||
0x47, 0xe3, 0xd7, 0x67, 0x47, 0xa7, 0xdd, 0xda, 0xfe, 0x3f, 0x4a, 0xbe, 0x04, 0x37, 0x99, 0x05,
|
||||
0x37, 0x8d, 0x8e, 0x67, 0xa7, 0x3f, 0x76, 0x3f, 0x82, 0xf3, 0x87, 0x67, 0xc7, 0xb3, 0x6e, 0x09,
|
||||
0xce, 0xf0, 0xd1, 0xfc, 0x14, 0x1e, 0x2e, 0x83, 0xc6, 0xc1, 0x5f, 0x46, 0x07, 0x3f, 0x74, 0xb7,
|
||||
0x68, 0x8b, 0x04, 0x33, 0x3e, 0x12, 0xa8, 0x55, 0xa1, 0xf7, 0x48, 0x73, 0xf6, 0xfa, 0xcd, 0x48,
|
||||
0xcc, 0x47, 0xfc, 0xed, 0x88, 0x77, 0xab, 0xf0, 0xec, 0xc9, 0xf4, 0x74, 0x32, 0xfe, 0xb1, 0x5b,
|
||||
0xa3, 0x5d, 0xd2, 0x3a, 0x98, 0x9d, 0x4d, 0x4e, 0xc6, 0x53, 0xa7, 0x5e, 0xa7, 0xdb, 0xa4, 0xbd,
|
||||
0x41, 0xdc, 0x7d, 0x01, 0x40, 0xe3, 0xd1, 0xeb, 0xd3, 0x33, 0x3e, 0xf2, 0x50, 0x03, 0x9e, 0x7e,
|
||||
0x3b, 0xe2, 0xf3, 0xc9, 0xf4, 0xa4, 0x4b, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x2a, 0xaf,
|
||||
0x49, 0x5b, 0x0d, 0x00, 0x00,
|
||||
}
|
||||
|
||||
14
vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.proto
generated
vendored
14
vendor/github.com/opencontainers/runc/libcontainer/criurpc/criurpc.proto
generated
vendored
@@ -140,6 +140,8 @@ enum criu_req_type {
|
||||
CPUINFO_CHECK = 8;
|
||||
|
||||
FEATURE_CHECK = 9;
|
||||
|
||||
VERSION = 10;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -148,6 +150,7 @@ enum criu_req_type {
|
||||
*/
|
||||
message criu_features {
|
||||
optional bool mem_track = 1;
|
||||
optional bool lazy_pages = 2;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -192,4 +195,15 @@ message criu_resp {
|
||||
optional int32 cr_errno = 7;
|
||||
optional criu_features features = 8;
|
||||
optional string cr_errmsg = 9;
|
||||
optional criu_version version = 10;
|
||||
}
|
||||
|
||||
/* Answer for criu_req_type.VERSION requests */
|
||||
message criu_version {
|
||||
required int32 major = 1;
|
||||
required int32 minor = 2;
|
||||
optional string gitid = 3;
|
||||
optional int32 sublevel = 4;
|
||||
optional int32 extra = 5;
|
||||
optional string name = 6;
|
||||
}
|
||||
|
||||
44
vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
generated
vendored
44
vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
generated
vendored
@@ -2,11 +2,9 @@ package devices
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall" //only for Stat_t
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
|
||||
@@ -19,45 +17,45 @@ var (
|
||||
|
||||
// Testing dependencies
|
||||
var (
|
||||
osLstat = os.Lstat
|
||||
unixLstat = unix.Lstat
|
||||
ioutilReadDir = ioutil.ReadDir
|
||||
)
|
||||
|
||||
// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
|
||||
func DeviceFromPath(path, permissions string) (*configs.Device, error) {
|
||||
fileInfo, err := osLstat(path)
|
||||
var stat unix.Stat_t
|
||||
err := unixLstat(path, &stat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
devType rune
|
||||
mode = fileInfo.Mode()
|
||||
fileModePermissionBits = os.FileMode.Perm(mode)
|
||||
devNumber = int(stat.Rdev)
|
||||
major = Major(devNumber)
|
||||
)
|
||||
if major == 0 {
|
||||
return nil, ErrNotADevice
|
||||
}
|
||||
|
||||
var (
|
||||
devType rune
|
||||
mode = stat.Mode
|
||||
)
|
||||
switch {
|
||||
case mode&os.ModeDevice == 0:
|
||||
return nil, ErrNotADevice
|
||||
case mode&os.ModeCharDevice != 0:
|
||||
fileModePermissionBits |= unix.S_IFCHR
|
||||
devType = 'c'
|
||||
default:
|
||||
fileModePermissionBits |= unix.S_IFBLK
|
||||
case mode&unix.S_IFBLK == unix.S_IFBLK:
|
||||
devType = 'b'
|
||||
case mode&unix.S_IFCHR == unix.S_IFCHR:
|
||||
devType = 'c'
|
||||
}
|
||||
stat_t, ok := fileInfo.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot determine the device number for device %s", path)
|
||||
}
|
||||
devNumber := int(stat_t.Rdev)
|
||||
return &configs.Device{
|
||||
Type: devType,
|
||||
Path: path,
|
||||
Major: Major(devNumber),
|
||||
Major: major,
|
||||
Minor: Minor(devNumber),
|
||||
Permissions: permissions,
|
||||
FileMode: fileModePermissionBits,
|
||||
Uid: stat_t.Uid,
|
||||
Gid: stat_t.Gid,
|
||||
FileMode: os.FileMode(mode),
|
||||
Uid: stat.Uid,
|
||||
Gid: stat.Gid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
8
vendor/github.com/opencontainers/runc/libcontainer/devices/devices_test.go
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/devices/devices_test.go
generated
vendored
@@ -6,14 +6,16 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestDeviceFromPathLstatFailure(t *testing.T) {
|
||||
testError := errors.New("test error")
|
||||
|
||||
// Override os.Lstat to inject error.
|
||||
osLstat = func(path string) (os.FileInfo, error) {
|
||||
return nil, testError
|
||||
// Override unix.Lstat to inject error.
|
||||
unixLstat = func(path string, stat *unix.Stat_t) error {
|
||||
return testError
|
||||
}
|
||||
|
||||
_, err := DeviceFromPath("", "")
|
||||
|
||||
10
vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
generated
vendored
10
vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go
generated
vendored
@@ -162,14 +162,6 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
|
||||
if err := l.Validator.Validate(config); err != nil {
|
||||
return nil, newGenericError(err, ConfigInvalid)
|
||||
}
|
||||
uid, err := config.HostRootUID()
|
||||
if err != nil {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
gid, err := config.HostRootGID()
|
||||
if err != nil {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
containerRoot := filepath.Join(l.Root, id)
|
||||
if _, err := os.Stat(containerRoot); err == nil {
|
||||
return nil, newGenericError(fmt.Errorf("container with id exists: %v", id), IdInUse)
|
||||
@@ -179,7 +171,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
|
||||
if err := os.MkdirAll(containerRoot, 0711); err != nil {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
if err := os.Chown(containerRoot, uid, gid); err != nil {
|
||||
if err := os.Chown(containerRoot, unix.Geteuid(), unix.Getegid()); err != nil {
|
||||
return nil, newGenericError(err, SystemError)
|
||||
}
|
||||
if config.Rootless {
|
||||
|
||||
7
vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
generated
vendored
7
vendor/github.com/opencontainers/runc/libcontainer/init_linux.go
generated
vendored
@@ -12,14 +12,14 @@ import (
|
||||
"syscall" // only for Errno
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
"github.com/opencontainers/runc/libcontainer/user"
|
||||
"github.com/opencontainers/runc/libcontainer/utils"
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vishvananda/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -31,7 +31,8 @@ const (
|
||||
)
|
||||
|
||||
type pid struct {
|
||||
Pid int `json:"pid"`
|
||||
Pid int `json:"pid"`
|
||||
PidFirstChild int `json:"pid_first"`
|
||||
}
|
||||
|
||||
// network is an internal struct used to setup container networks.
|
||||
|
||||
2
vendor/github.com/opencontainers/runc/libcontainer/integration/checkpoint_test.go
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/integration/checkpoint_test.go
generated
vendored
@@ -180,7 +180,7 @@ func testCheckpoint(t *testing.T, userns bool) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if state != libcontainer.Running {
|
||||
if state != libcontainer.Stopped {
|
||||
t.Fatal("Unexpected state checkpoint: ", state)
|
||||
}
|
||||
|
||||
|
||||
6
vendor/github.com/opencontainers/runc/libcontainer/integration/exec_test.go
generated
vendored
6
vendor/github.com/opencontainers/runc/libcontainer/integration/exec_test.go
generated
vendored
@@ -807,7 +807,13 @@ func TestPassExtraFiles(t *testing.T) {
|
||||
|
||||
var stdout bytes.Buffer
|
||||
pipeout1, pipein1, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pipeout2, pipein2, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
process := libcontainer.Process{
|
||||
Cwd: "/",
|
||||
Args: []string{"sh", "-c", "cd /proc/$$/fd; echo -n *; echo -n 1 >3; echo -n 2 >4"},
|
||||
|
||||
9
vendor/github.com/opencontainers/runc/libcontainer/integration/execin_test.go
generated
vendored
9
vendor/github.com/opencontainers/runc/libcontainer/integration/execin_test.go
generated
vendored
@@ -234,7 +234,7 @@ func TestExecInError(t *testing.T) {
|
||||
Cwd: "/",
|
||||
Args: []string{"unexistent"},
|
||||
Env: standardEnvironment,
|
||||
Stdout: &out,
|
||||
Stderr: &out,
|
||||
}
|
||||
err = container.Run(unexistent)
|
||||
if err == nil {
|
||||
@@ -300,6 +300,7 @@ func TestExecInTTY(t *testing.T) {
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
libcontainer.SaneTerminal(f)
|
||||
dc <- &cdata{
|
||||
c: libcontainer.ConsoleFromFile(f),
|
||||
}
|
||||
@@ -430,7 +431,13 @@ func TestExecinPassExtraFiles(t *testing.T) {
|
||||
|
||||
var stdout bytes.Buffer
|
||||
pipeout1, pipein1, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pipeout2, pipein2, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
inprocess := &libcontainer.Process{
|
||||
Cwd: "/",
|
||||
Args: []string{"sh", "-c", "cd /proc/$$/fd; echo -n *; echo -n 1 >3; echo -n 2 >4"},
|
||||
|
||||
3
vendor/github.com/opencontainers/runc/libcontainer/integration/init_test.go
generated
vendored
3
vendor/github.com/opencontainers/runc/libcontainer/integration/init_test.go
generated
vendored
@@ -5,10 +5,11 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
|
||||
_ "github.com/opencontainers/runc/libcontainer/nsenter"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// init runs the libcontainer initialization code because of the busybox style needs
|
||||
|
||||
29
vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
generated
vendored
29
vendor/github.com/opencontainers/runc/libcontainer/keys/keyctl.go
generated
vendored
@@ -6,31 +6,16 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const KEYCTL_JOIN_SESSION_KEYRING = 1
|
||||
const KEYCTL_SETPERM = 5
|
||||
const KEYCTL_DESCRIBE = 6
|
||||
|
||||
type KeySerial uint32
|
||||
|
||||
func JoinSessionKeyring(name string) (KeySerial, error) {
|
||||
var _name *byte
|
||||
var err error
|
||||
|
||||
if len(name) > 0 {
|
||||
_name, err = unix.BytePtrFromString(name)
|
||||
if err != nil {
|
||||
return KeySerial(0), err
|
||||
}
|
||||
}
|
||||
|
||||
sessKeyId, _, errn := unix.Syscall(unix.SYS_KEYCTL, KEYCTL_JOIN_SESSION_KEYRING, uintptr(unsafe.Pointer(_name)), 0)
|
||||
if errn != 0 {
|
||||
return 0, fmt.Errorf("could not create session key: %v", errn)
|
||||
sessKeyId, err := unix.KeyctlJoinSessionKeyring(name)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not create session key: %v", err)
|
||||
}
|
||||
return KeySerial(sessKeyId), nil
|
||||
}
|
||||
@@ -39,10 +24,8 @@ func JoinSessionKeyring(name string) (KeySerial, error) {
|
||||
// anding the bits with the given mask (clearing permissions) and setting
|
||||
// additional permission bits
|
||||
func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
|
||||
dest := make([]byte, 1024)
|
||||
destBytes := unsafe.Pointer(&dest[0])
|
||||
|
||||
if _, _, err := unix.Syscall6(unix.SYS_KEYCTL, uintptr(KEYCTL_DESCRIBE), uintptr(ringId), uintptr(destBytes), uintptr(len(dest)), 0, 0); err != 0 {
|
||||
dest, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(ringId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -59,7 +42,7 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
|
||||
|
||||
perm := (uint32(perm64) & mask) | setbits
|
||||
|
||||
if _, _, err := unix.Syscall(unix.SYS_KEYCTL, uintptr(KEYCTL_SETPERM), uintptr(ringId), uintptr(perm)); err != 0 {
|
||||
if err := unix.KeyctlSetperm(int(ringId), perm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
10
vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go
generated
vendored
10
vendor/github.com/opencontainers/runc/libcontainer/notify_linux.go
generated
vendored
@@ -26,13 +26,13 @@ func registerMemoryEvent(cgDir string, evName string, arg string) (<-chan struct
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fd, _, syserr := unix.RawSyscall(unix.SYS_EVENTFD2, 0, unix.FD_CLOEXEC, 0)
|
||||
if syserr != 0 {
|
||||
fd, err := unix.Eventfd(0, unix.EFD_CLOEXEC)
|
||||
if err != nil {
|
||||
evFile.Close()
|
||||
return nil, syserr
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eventfd := os.NewFile(fd, "eventfd")
|
||||
eventfd := os.NewFile(uintptr(fd), "eventfd")
|
||||
|
||||
eventControlPath := filepath.Join(cgDir, "cgroup.event_control")
|
||||
data := fmt.Sprintf("%d %d %s", eventfd.Fd(), evFile.Fd(), arg)
|
||||
@@ -44,9 +44,9 @@ func registerMemoryEvent(cgDir string, evName string, arg string) (<-chan struct
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
defer func() {
|
||||
close(ch)
|
||||
eventfd.Close()
|
||||
evFile.Close()
|
||||
close(ch)
|
||||
}()
|
||||
buf := make([]byte, 8)
|
||||
for {
|
||||
|
||||
9
vendor/github.com/opencontainers/runc/libcontainer/notify_linux_test.go
generated
vendored
9
vendor/github.com/opencontainers/runc/libcontainer/notify_linux_test.go
generated
vendored
@@ -53,17 +53,13 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ
|
||||
t.Fatalf("invalid control data %q: %s", data, err)
|
||||
}
|
||||
|
||||
// re-open the eventfd
|
||||
// dup the eventfd
|
||||
efd, err := unix.Dup(eventFd)
|
||||
if err != nil {
|
||||
t.Fatal("unable to reopen eventfd:", err)
|
||||
t.Fatal("unable to dup eventfd:", err)
|
||||
}
|
||||
defer unix.Close(efd)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("unable to dup event fd:", err)
|
||||
}
|
||||
|
||||
buf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(buf, 1)
|
||||
|
||||
@@ -93,6 +89,7 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ
|
||||
t.Fatal("expected no notification to be triggered")
|
||||
}
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Fatal("channel not closed after 100ms")
|
||||
}
|
||||
|
||||
if _, _, err := unix.Syscall(unix.SYS_FCNTL, uintptr(evFd), unix.F_GETFD, 0); err != unix.EBADF {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user