This commit is contained in:
Denis Makogon
2018-01-23 23:15:11 +02:00
committed by Reed Allman
parent 5fc01d6974
commit a70c038760
496 changed files with 7703 additions and 5030 deletions

245
Gopkg.lock generated
View File

@@ -4,7 +4,10 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/Azure/go-ansiterm" name = "github.com/Azure/go-ansiterm"
packages = [".","winterm"] packages = [
".",
"winterm"
]
revision = "d6e3b3328b783f23731bc4d058875b0371ff8109" revision = "d6e3b3328b783f23731bc4d058875b0371ff8109"
[[projects]] [[projects]]
@@ -51,9 +54,37 @@
[[projects]] [[projects]]
name = "github.com/aws/aws-sdk-go" name = "github.com/aws/aws-sdk-go"
packages = ["aws","aws/awserr","aws/awsutil","aws/client","aws/client/metadata","aws/corehandlers","aws/credentials","aws/credentials/ec2rolecreds","aws/credentials/endpointcreds","aws/credentials/stscreds","aws/defaults","aws/ec2metadata","aws/endpoints","aws/request","aws/session","aws/signer/v4","internal/shareddefaults","private/protocol","private/protocol/query","private/protocol/query/queryutil","private/protocol/rest","private/protocol/restxml","private/protocol/xml/xmlutil","service/s3","service/s3/s3iface","service/s3/s3manager","service/sts"] packages = [
revision = "9ed0c8de252f04ac45a65358377103d5a1aa2d92" "aws",
version = "v1.12.66" "aws/awserr",
"aws/awsutil",
"aws/client",
"aws/client/metadata",
"aws/corehandlers",
"aws/credentials",
"aws/credentials/ec2rolecreds",
"aws/credentials/endpointcreds",
"aws/credentials/stscreds",
"aws/defaults",
"aws/ec2metadata",
"aws/endpoints",
"aws/request",
"aws/session",
"aws/signer/v4",
"internal/shareddefaults",
"private/protocol",
"private/protocol/query",
"private/protocol/query/queryutil",
"private/protocol/rest",
"private/protocol/restxml",
"private/protocol/xml/xmlutil",
"service/s3",
"service/s3/s3iface",
"service/s3/s3manager",
"service/sts"
]
revision = "decd990ddc5dcdf2f73309cbcab90d06b996ca28"
version = "v1.12.67"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -80,13 +111,55 @@
[[projects]] [[projects]]
name = "github.com/docker/distribution" name = "github.com/docker/distribution"
packages = [".","digestset","manifest","manifest/schema1","manifest/schema2","reference","registry/api/errcode","registry/api/v2","registry/client","registry/client/auth","registry/client/auth/challenge","registry/client/transport","registry/storage/cache","registry/storage/cache/memory"] packages = [
".",
"digestset",
"manifest",
"manifest/schema1",
"manifest/schema2",
"reference",
"registry/api/errcode",
"registry/api/v2",
"registry/client",
"registry/client/auth",
"registry/client/auth/challenge",
"registry/client/transport",
"registry/storage/cache",
"registry/storage/cache/memory"
]
revision = "bc3c7b0525e59d3ecfab3e1568350895fd4a462f" revision = "bc3c7b0525e59d3ecfab3e1568350895fd4a462f"
[[projects]] [[projects]]
branch = "master"
name = "github.com/docker/docker" name = "github.com/docker/docker"
packages = ["api/types","api/types/blkiodev","api/types/container","api/types/filters","api/types/mount","api/types/network","api/types/registry","api/types/strslice","api/types/swarm","api/types/swarm/runtime","api/types/versions","opts","pkg/archive","pkg/fileutils","pkg/homedir","pkg/idtools","pkg/ioutils","pkg/jsonmessage","pkg/longpath","pkg/mount","pkg/pools","pkg/stdcopy","pkg/system","pkg/term","pkg/term/windows"] packages = [
revision = "fe8aac6f5ae413a967adb0adad0b54abdfb825c4" "api/types",
"api/types/blkiodev",
"api/types/container",
"api/types/filters",
"api/types/mount",
"api/types/network",
"api/types/registry",
"api/types/strslice",
"api/types/swarm",
"api/types/swarm/runtime",
"api/types/versions",
"opts",
"pkg/archive",
"pkg/fileutils",
"pkg/homedir",
"pkg/idtools",
"pkg/ioutils",
"pkg/jsonmessage",
"pkg/longpath",
"pkg/mount",
"pkg/pools",
"pkg/stdcopy",
"pkg/system",
"pkg/term",
"pkg/term/windows"
]
revision = "99cfb5f31ad82238573de3475bf5bb0435ac1ebc"
[[projects]] [[projects]]
name = "github.com/docker/go-connections" name = "github.com/docker/go-connections"
@@ -132,7 +205,14 @@
[[projects]] [[projects]]
name = "github.com/fnproject/fn_go" name = "github.com/fnproject/fn_go"
packages = ["client","client/apps","client/call","client/operations","client/routes","models"] packages = [
"client",
"client/apps",
"client/call",
"client/operations",
"client/routes",
"models"
]
revision = "847fec724330b2741336431502db292fc5a45211" revision = "847fec724330b2741336431502db292fc5a45211"
version = "0.2.3" version = "0.2.3"
@@ -143,7 +223,10 @@
[[projects]] [[projects]]
name = "github.com/garyburd/redigo" name = "github.com/garyburd/redigo"
packages = ["internal","redis"] packages = [
"internal",
"redis"
]
revision = "d1ed5c67e5794de818ea85e6b522fda02623a484" revision = "d1ed5c67e5794de818ea85e6b522fda02623a484"
version = "v1.4.0" version = "v1.4.0"
@@ -161,7 +244,11 @@
[[projects]] [[projects]]
name = "github.com/gin-gonic/gin" name = "github.com/gin-gonic/gin"
packages = [".","binding","render"] packages = [
".",
"binding",
"render"
]
revision = "d459835d2b077e44f7c9b453505ee29881d5d12d" revision = "d459835d2b077e44f7c9b453505ee29881d5d12d"
version = "v1.2" version = "v1.2"
@@ -210,8 +297,17 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/go-openapi/runtime" name = "github.com/go-openapi/runtime"
packages = [".","client","logger","middleware","middleware/denco","middleware/header","middleware/untyped","security"] packages = [
revision = "a76104f379d3c5041f2a56e69db3ad8404ce4826" ".",
"client",
"logger",
"middleware",
"middleware/denco",
"middleware/header",
"middleware/untyped",
"security"
]
revision = "be1313bd8283bc82b48033942f0f3730eaef2d90"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -252,7 +348,7 @@
branch = "master" branch = "master"
name = "github.com/golang/protobuf" name = "github.com/golang/protobuf"
packages = ["proto"] packages = ["proto"]
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845" revision = "c65a0412e71e8b9b3bfd22925720d23c0f054237"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -286,7 +382,10 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/jmoiron/sqlx" name = "github.com/jmoiron/sqlx"
packages = [".","reflectx"] packages = [
".",
"reflectx"
]
revision = "de8647470aafe4854c976707c431dbe1eb2822c6" revision = "de8647470aafe4854c976707c431dbe1eb2822c6"
[[projects]] [[projects]]
@@ -298,18 +397,29 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/lib/pq" name = "github.com/lib/pq"
packages = [".","oid"] packages = [
revision = "27ea5d92de30060e7121ddd543fe14e9a327e0cc" ".",
"oid"
]
revision = "61fe37aa2ee24fabcdbe5c4ac1d4ac566f88f345"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/mailru/easyjson" name = "github.com/mailru/easyjson"
packages = ["buffer","jlexer","jwriter"] packages = [
"buffer",
"jlexer",
"jwriter"
]
revision = "32fa128f234d041f196a9f3e0fea5ac9772c08e1" revision = "32fa128f234d041f196a9f3e0fea5ac9772c08e1"
[[projects]] [[projects]]
name = "github.com/mattes/migrate" name = "github.com/mattes/migrate"
packages = [".","database","source"] packages = [
".",
"database",
"source"
]
revision = "035c07716cd373d88456ec4d701402df52584cb4" revision = "035c07716cd373d88456ec4d701402df52584cb4"
version = "v3.0.1" version = "v3.0.1"
@@ -345,13 +455,19 @@
[[projects]] [[projects]]
name = "github.com/opencontainers/image-spec" name = "github.com/opencontainers/image-spec"
packages = ["specs-go","specs-go/v1"] packages = [
"specs-go",
"specs-go/v1"
]
revision = "d60099175f88c47cd379c4738d158884749ed235" revision = "d60099175f88c47cd379c4738d158884749ed235"
version = "v1.0.1" version = "v1.0.1"
[[projects]] [[projects]]
name = "github.com/opencontainers/runc" name = "github.com/opencontainers/runc"
packages = ["libcontainer/system","libcontainer/user"] packages = [
"libcontainer/system",
"libcontainer/user"
]
revision = "baf6536d6259209c3edfa2b22237af82942d3dfa" revision = "baf6536d6259209c3edfa2b22237af82942d3dfa"
version = "v0.1.1" version = "v0.1.1"
@@ -363,13 +479,24 @@
[[projects]] [[projects]]
name = "github.com/opentracing/opentracing-go" name = "github.com/opentracing/opentracing-go"
packages = [".","ext","log"] packages = [
".",
"ext",
"log"
]
revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38" revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
version = "v1.0.2" version = "v1.0.2"
[[projects]] [[projects]]
name = "github.com/openzipkin/zipkin-go-opentracing" name = "github.com/openzipkin/zipkin-go-opentracing"
packages = [".","flag","thrift/gen-go/scribe","thrift/gen-go/zipkincore","types","wire"] packages = [
".",
"flag",
"thrift/gen-go/scribe",
"thrift/gen-go/zipkincore",
"types",
"wire"
]
revision = "45e90b00710a4c34a1a7d8a78d90f9b010b0bd4d" revision = "45e90b00710a4c34a1a7d8a78d90f9b010b0bd4d"
version = "v0.3.2" version = "v0.3.2"
@@ -405,7 +532,10 @@
[[projects]] [[projects]]
name = "github.com/prometheus/client_golang" name = "github.com/prometheus/client_golang"
packages = ["prometheus","prometheus/promhttp"] packages = [
"prometheus",
"prometheus/promhttp"
]
revision = "c5b7fccd204277076155f10851dad72b76a49317" revision = "c5b7fccd204277076155f10851dad72b76a49317"
version = "v0.8.0" version = "v0.8.0"
@@ -418,14 +548,23 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/prometheus/common" name = "github.com/prometheus/common"
packages = ["expfmt","internal/bitbucket.org/ww/goautoneg","model"] packages = [
"expfmt",
"internal/bitbucket.org/ww/goautoneg",
"model"
]
revision = "89604d197083d4781071d3c65855d24ecfb0a563" revision = "89604d197083d4781071d3c65855d24ecfb0a563"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/prometheus/procfs" name = "github.com/prometheus/procfs"
packages = [".","xfs"] packages = [
revision = "b15cd069a83443be3154b719d0cc9fe8117f09fb" ".",
"internal/util",
"nfsd",
"xfs"
]
revision = "85fadb6e89903ef7cca6f6a804474cd5ea85b6e1"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -435,12 +574,22 @@
[[projects]] [[projects]]
name = "github.com/rdallman/migrate" name = "github.com/rdallman/migrate"
packages = [".","database/mysql","database/postgres","database/sqlite3","source","source/go-bindata"] packages = [
".",
"database/mysql",
"database/postgres",
"database/sqlite3",
"source",
"source/go-bindata"
]
revision = "bc72eeb997c7334cb5f05f5aefd2d70bc34d71ef" revision = "bc72eeb997c7334cb5f05f5aefd2d70bc34d71ef"
[[projects]] [[projects]]
name = "github.com/sirupsen/logrus" name = "github.com/sirupsen/logrus"
packages = [".","hooks/syslog"] packages = [
".",
"hooks/syslog"
]
revision = "89742aefa4b206dcf400792f3bd35b542998eb3b" revision = "89742aefa4b206dcf400792f3bd35b542998eb3b"
[[projects]] [[projects]]
@@ -453,24 +602,47 @@
branch = "master" branch = "master"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
packages = ["ssh/terminal"] packages = ["ssh/terminal"]
revision = "a6600008915114d9c087fad9f03d75087b1a74df" revision = "3d37316aaa6bd9929127ac9a527abf408178ea7b"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/net" name = "golang.org/x/net"
packages = ["context","context/ctxhttp","idna"] packages = [
"context",
"context/ctxhttp",
"idna"
]
revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec" revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/sys" name = "golang.org/x/sys"
packages = ["unix","windows"] packages = [
revision = "2c42eef0765b9837fbdab12011af7830f55f88f0" "unix",
"windows"
]
revision = "af50095a40f9041b3b38960738837185c26e9419"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/text" name = "golang.org/x/text"
packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable","width"] packages = [
"collate",
"collate/build",
"internal/colltab",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"language",
"secure/bidirule",
"transform",
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable",
"width"
]
revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3" revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3"
[[projects]] [[projects]]
@@ -482,7 +654,10 @@
[[projects]] [[projects]]
branch = "v2" branch = "v2"
name = "gopkg.in/mgo.v2" name = "gopkg.in/mgo.v2"
packages = ["bson","internal/json"] packages = [
"bson",
"internal/json"
]
revision = "3f83fa5005286a7fe593b055f0d7771a7dce4655" revision = "3f83fa5005286a7fe593b055f0d7771a7dce4655"
[[projects]] [[projects]]
@@ -494,6 +669,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "3f78f93ac5508cf8125bb9acba9c83f70b76b11e1977b98f54999d90f3dccee9" inputs-digest = "556d3a6039ee958f59418b978bbb50d2733c1069bdcb67c931ffa0ab09195097"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@@ -25,14 +25,6 @@ ignored = ["github.com/fnproject/fn/cli"]
name = "github.com/boltdb/bolt" name = "github.com/boltdb/bolt"
revision = "fa5367d20c994db73282594be0146ab221657943" revision = "fa5367d20c994db73282594be0146ab221657943"
[[constraint]]
name = "github.com/coreos/go-semver"
version = "^0.2.0"
[[constraint]]
branch = "master"
name = "github.com/dchest/siphash"
[[constraint]] [[constraint]]
name = "github.com/fnproject/fn_go" name = "github.com/fnproject/fn_go"
version = "0.2.0" version = "0.2.0"
@@ -65,14 +57,6 @@ ignored = ["github.com/fnproject/fn/cli"]
name = "github.com/sirupsen/logrus" name = "github.com/sirupsen/logrus"
revision = "89742aefa4b206dcf400792f3bd35b542998eb3b" revision = "89742aefa4b206dcf400792f3bd35b542998eb3b"
[[constraint]]
name = "github.com/docker/docker"
revision = "cdf870bd0b5fa678b10ef2708cca7ad776b4913c"
[[constraint]]
name = "github.com/docker/cli"
revision = "139fcd3ee95f37f3ac17b1200fb0a63908cb6781"
[[constraint]] [[constraint]]
name = "github.com/docker/distribution" name = "github.com/docker/distribution"
revision = "bc3c7b0525e59d3ecfab3e1568350895fd4a462f" revision = "bc3c7b0525e59d3ecfab3e1568350895fd4a462f"
@@ -85,22 +69,6 @@ ignored = ["github.com/fnproject/fn/cli"]
name = "github.com/go-sql-driver/mysql" name = "github.com/go-sql-driver/mysql"
revision = "21d7e97c9f760ca685a01ecea202e1c84276daa1" revision = "21d7e97c9f760ca685a01ecea202e1c84276daa1"
[[constraint]]
name = "github.com/opencontainers/go-digest"
revision = "279bed98673dd5bef374d3b6e4b09e2af76183bf"
[[constraint]]
name = "github.com/opencontainers/runc"
revision = "ae2948042b08ad3d6d13cd09f40a50ffff4fc688"
[[constraint]]
name = "github.com/Azure/go-ansiterm"
revision = "19f72df4d05d31cbe1c56bfc8045c96babff6c7e"
[[constraint]]
name = "github.com/prometheus/common"
revision = "2f17f4a9d485bf34b4bfaccc273805040e4f86c8"
[[constraint]] [[constraint]]
name = "github.com/aws/aws-sdk-go" name = "github.com/aws/aws-sdk-go"
version = "~1.12.59" version = "~1.12.59"

View File

@@ -1,3 +1,10 @@
Release v1.12.67 (2018-01-22)
===
### Service Client Updates
* `service/budgets`: Updates service API and documentation
* Add additional costTypes: IncludeDiscount, UseAmortized, to support finer control for different charges included in a cost budget.
Release v1.12.66 (2018-01-19) Release v1.12.66 (2018-01-19)
=== ===

View File

@@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // SDKVersion is the version of this SDK
const SDKVersion = "1.12.66" const SDKVersion = "1.12.67"

View File

@@ -283,7 +283,9 @@
"IncludeUpfront":{"shape":"NullableBoolean"}, "IncludeUpfront":{"shape":"NullableBoolean"},
"IncludeRecurring":{"shape":"NullableBoolean"}, "IncludeRecurring":{"shape":"NullableBoolean"},
"IncludeOtherSubscription":{"shape":"NullableBoolean"}, "IncludeOtherSubscription":{"shape":"NullableBoolean"},
"IncludeSupport":{"shape":"NullableBoolean"} "IncludeSupport":{"shape":"NullableBoolean"},
"IncludeDiscount":{"shape":"NullableBoolean"},
"UseAmortized":{"shape":"NullableBoolean"}
} }
}, },
"CreateBudgetRequest":{ "CreateBudgetRequest":{

View File

@@ -321,7 +321,9 @@
"CostTypes$IncludeUpfront": "A boolean value whether to include upfront costs in the cost budget.", "CostTypes$IncludeUpfront": "A boolean value whether to include upfront costs in the cost budget.",
"CostTypes$IncludeRecurring": "A boolean value whether to include recurring costs in the cost budget.", "CostTypes$IncludeRecurring": "A boolean value whether to include recurring costs in the cost budget.",
"CostTypes$IncludeOtherSubscription": "A boolean value whether to include other subscription costs in the cost budget.", "CostTypes$IncludeOtherSubscription": "A boolean value whether to include other subscription costs in the cost budget.",
"CostTypes$IncludeSupport": "A boolean value whether to include support costs in the cost budget." "CostTypes$IncludeSupport": "A boolean value whether to include support costs in the cost budget.",
"CostTypes$IncludeDiscount": "A boolean value whether to include discounts in the cost budget.",
"CostTypes$UseAmortized": "A boolean value whether to include amortized costs in the cost budget."
} }
}, },
"NumericValue": { "NumericValue": {

View File

@@ -1357,6 +1357,9 @@ type CostTypes struct {
// A boolean value whether to include credits in the cost budget. // A boolean value whether to include credits in the cost budget.
IncludeCredit *bool `type:"boolean"` IncludeCredit *bool `type:"boolean"`
// A boolean value whether to include discounts in the cost budget.
IncludeDiscount *bool `type:"boolean"`
// A boolean value whether to include other subscription costs in the cost budget. // A boolean value whether to include other subscription costs in the cost budget.
IncludeOtherSubscription *bool `type:"boolean"` IncludeOtherSubscription *bool `type:"boolean"`
@@ -1378,6 +1381,9 @@ type CostTypes struct {
// A boolean value whether to include upfront costs in the cost budget. // A boolean value whether to include upfront costs in the cost budget.
IncludeUpfront *bool `type:"boolean"` IncludeUpfront *bool `type:"boolean"`
// A boolean value whether to include amortized costs in the cost budget.
UseAmortized *bool `type:"boolean"`
// A boolean value whether to use blended costs in the cost budget. // A boolean value whether to use blended costs in the cost budget.
UseBlended *bool `type:"boolean"` UseBlended *bool `type:"boolean"`
} }
@@ -1398,6 +1404,12 @@ func (s *CostTypes) SetIncludeCredit(v bool) *CostTypes {
return s return s
} }
// SetIncludeDiscount sets the IncludeDiscount field's value.
func (s *CostTypes) SetIncludeDiscount(v bool) *CostTypes {
s.IncludeDiscount = &v
return s
}
// SetIncludeOtherSubscription sets the IncludeOtherSubscription field's value. // SetIncludeOtherSubscription sets the IncludeOtherSubscription field's value.
func (s *CostTypes) SetIncludeOtherSubscription(v bool) *CostTypes { func (s *CostTypes) SetIncludeOtherSubscription(v bool) *CostTypes {
s.IncludeOtherSubscription = &v s.IncludeOtherSubscription = &v
@@ -1440,6 +1452,12 @@ func (s *CostTypes) SetIncludeUpfront(v bool) *CostTypes {
return s return s
} }
// SetUseAmortized sets the UseAmortized field's value.
func (s *CostTypes) SetUseAmortized(v bool) *CostTypes {
s.UseAmortized = &v
return s
}
// SetUseBlended sets the UseBlended field's value. // SetUseBlended sets the UseBlended field's value.
func (s *CostTypes) SetUseBlended(v bool) *CostTypes { func (s *CostTypes) SetUseBlended(v bool) *CostTypes {
s.UseBlended = &v s.UseBlended = &v

View File

@@ -63,9 +63,12 @@ func (strat HeaderV2SaveStrategy) Save(env Envelope, req *request.Request) error
input.Metadata[http.CanonicalHeaderKey(matDescHeader)] = &env.MatDesc input.Metadata[http.CanonicalHeaderKey(matDescHeader)] = &env.MatDesc
input.Metadata[http.CanonicalHeaderKey(wrapAlgorithmHeader)] = &env.WrapAlg input.Metadata[http.CanonicalHeaderKey(wrapAlgorithmHeader)] = &env.WrapAlg
input.Metadata[http.CanonicalHeaderKey(cekAlgorithmHeader)] = &env.CEKAlg input.Metadata[http.CanonicalHeaderKey(cekAlgorithmHeader)] = &env.CEKAlg
input.Metadata[http.CanonicalHeaderKey(tagLengthHeader)] = &env.TagLen
input.Metadata[http.CanonicalHeaderKey(unencryptedMD5Header)] = &env.UnencryptedMD5 input.Metadata[http.CanonicalHeaderKey(unencryptedMD5Header)] = &env.UnencryptedMD5
input.Metadata[http.CanonicalHeaderKey(unencryptedContentLengthHeader)] = &env.UnencryptedContentLen input.Metadata[http.CanonicalHeaderKey(unencryptedContentLengthHeader)] = &env.UnencryptedContentLen
if len(env.TagLen) > 0 {
input.Metadata[http.CanonicalHeaderKey(tagLengthHeader)] = &env.TagLen
}
return nil return nil
} }

View File

@@ -11,38 +11,67 @@ import (
) )
func TestHeaderV2SaveStrategy(t *testing.T) { func TestHeaderV2SaveStrategy(t *testing.T) {
env := s3crypto.Envelope{ cases := []struct {
CipherKey: "Foo", env s3crypto.Envelope
IV: "Bar", expected map[string]*string
MatDesc: "{}", }{
WrapAlg: s3crypto.KMSWrap, {
CEKAlg: s3crypto.AESGCMNoPadding, s3crypto.Envelope{
TagLen: "128", CipherKey: "Foo",
UnencryptedMD5: "hello", IV: "Bar",
UnencryptedContentLen: "0", MatDesc: "{}",
} WrapAlg: s3crypto.KMSWrap,
params := &s3.PutObjectInput{} CEKAlg: s3crypto.AESGCMNoPadding,
req := &request.Request{ TagLen: "128",
Params: params, UnencryptedMD5: "hello",
} UnencryptedContentLen: "0",
strat := s3crypto.HeaderV2SaveStrategy{} },
err := strat.Save(env, req) map[string]*string{
if err != nil { "X-Amz-Key-V2": aws.String("Foo"),
t.Errorf("expected no error, but received %v", err) "X-Amz-Iv": aws.String("Bar"),
"X-Amz-Matdesc": aws.String("{}"),
"X-Amz-Wrap-Alg": aws.String(s3crypto.KMSWrap),
"X-Amz-Cek-Alg": aws.String(s3crypto.AESGCMNoPadding),
"X-Amz-Tag-Len": aws.String("128"),
"X-Amz-Unencrypted-Content-Md5": aws.String("hello"),
"X-Amz-Unencrypted-Content-Length": aws.String("0"),
},
},
{
s3crypto.Envelope{
CipherKey: "Foo",
IV: "Bar",
MatDesc: "{}",
WrapAlg: s3crypto.KMSWrap,
CEKAlg: s3crypto.AESGCMNoPadding,
UnencryptedMD5: "hello",
UnencryptedContentLen: "0",
},
map[string]*string{
"X-Amz-Key-V2": aws.String("Foo"),
"X-Amz-Iv": aws.String("Bar"),
"X-Amz-Matdesc": aws.String("{}"),
"X-Amz-Wrap-Alg": aws.String(s3crypto.KMSWrap),
"X-Amz-Cek-Alg": aws.String(s3crypto.AESGCMNoPadding),
"X-Amz-Unencrypted-Content-Md5": aws.String("hello"),
"X-Amz-Unencrypted-Content-Length": aws.String("0"),
},
},
} }
expected := map[string]*string{ for _, c := range cases {
"X-Amz-Key-V2": aws.String("Foo"), params := &s3.PutObjectInput{}
"X-Amz-Iv": aws.String("Bar"), req := &request.Request{
"X-Amz-Matdesc": aws.String("{}"), Params: params,
"X-Amz-Wrap-Alg": aws.String(s3crypto.KMSWrap), }
"X-Amz-Cek-Alg": aws.String(s3crypto.AESGCMNoPadding), strat := s3crypto.HeaderV2SaveStrategy{}
"X-Amz-Tag-Len": aws.String("128"), err := strat.Save(c.env, req)
"X-Amz-Unencrypted-Content-Md5": aws.String("hello"), if err != nil {
"X-Amz-Unencrypted-Content-Length": aws.String("0"), t.Errorf("expected no error, but received %v", err)
} }
if !reflect.DeepEqual(expected, params.Metadata) { if !reflect.DeepEqual(c.expected, params.Metadata) {
t.Errorf("expected %v, but received %v", expected, params.Metadata) t.Errorf("expected %v, but received %v", c.expected, params.Metadata)
}
} }
} }

17
vendor/github.com/docker/docker/.DEREK.yml generated vendored Normal file
View File

@@ -0,0 +1,17 @@
curators:
- aboch
- alexellis
- andrewhsu
- anonymuse
- chanwit
- ehazlett
- fntlnz
- gianarb
- mgoelzer
- programmerq
- rheinwein
- ripcurld0
- thajeztah
features:
- comments

View File

@@ -6,323 +6,70 @@
# #
# For explanation on this file format: man git-shortlog # For explanation on this file format: man git-shortlog
Patrick Stapleton <github@gdi2290.com> <21551195@zju.edu.cn> <hsinko@users.noreply.github.com>
Shishir Mahajan <shishir.mahajan@redhat.com> <smahajan@redhat.com>
Erwin van der Koogh <info@erronis.nl>
Ahmed Kamal <email.ahmedkamal@googlemail.com>
Alessandro Boch <aboch@tetrationanalytics.com> <aboch@docker.com>
Tejesh Mehta <tejesh.mehta@gmail.com> <tj@init.me>
Cristian Staretu <cristian.staretu@gmail.com>
Cristian Staretu <cristian.staretu@gmail.com> <unclejacksons@gmail.com>
Cristian Staretu <cristian.staretu@gmail.com> <unclejack@users.noreply.github.com>
Marcus Linke <marcus.linke@gmx.de>
Aleksandrs Fadins <aleks@s-ko.net>
Christopher Latham <sudosurootdev@gmail.com>
Hu Keping <hukeping@huawei.com>
Wayne Chang <wayne@neverfear.org>
Chen Chao <cc272309126@gmail.com>
Daehyeok Mun <daehyeok@gmail.com>
<daehyeok@gmail.com> <daehyeok@daehyeokui-MacBook-Air.local>
<jt@yadutaf.fr> <admin@jtlebi.fr>
<jeff@docker.com> <jefferya@programmerq.net>
<charles.hooper@dotcloud.com> <chooper@plumata.com>
<daniel.mizyrycki@dotcloud.com> <daniel@dotcloud.com>
<daniel.mizyrycki@dotcloud.com> <mzdaniel@glidelink.net>
Guillaume J. Charmes <guillaume.charmes@docker.com> <charmes.guillaume@gmail.com>
<guillaume.charmes@docker.com> <guillaume@dotcloud.com>
<guillaume.charmes@docker.com> <guillaume@docker.com>
<guillaume.charmes@docker.com> <guillaume.charmes@dotcloud.com>
<guillaume.charmes@docker.com> <guillaume@charmes.net>
<kencochrane@gmail.com> <KenCochrane@gmail.com>
Thatcher Peskens <thatcher@docker.com>
Thatcher Peskens <thatcher@docker.com> <thatcher@dotcloud.com>
Thatcher Peskens <thatcher@docker.com> dhrp <thatcher@gmx.net>
Jérôme Petazzoni <jerome.petazzoni@docker.com> <jerome.petazzoni@dotcloud.com>
Jérôme Petazzoni <jerome.petazzoni@docker.com> <jp@enix.org>
Jérôme Petazzoni <jerome.petazzoni@docker.com> <jerome.petazzoni@gmail.com>
Joffrey F <joffrey@docker.com>
Joffrey F <joffrey@docker.com> <joffrey@dotcloud.com>
Joffrey F <joffrey@docker.com> <f.joffrey@gmail.com>
Kir Kolyshkin <kolyshkin@gmail.com> <kir@openvz.org>
Kir Kolyshkin <kolyshkin@gmail.com>
Lorenzo Fontana <lo@linux.com> <fontanalorenzo@me.com>
<mr.wrfly@gmail.com> <wrfly@users.noreply.github.com> <mr.wrfly@gmail.com> <wrfly@users.noreply.github.com>
Tim Terhorst <mynamewastaken+git@gmail.com>
Andy Smith <github@anarkystic.com>
<kalessin@kalessin.fr> <louis@dotcloud.com>
<victor.vieux@docker.com> <victor.vieux@dotcloud.com>
<victor.vieux@docker.com> <victor@dotcloud.com>
<victor.vieux@docker.com> <dev@vvieux.com>
<victor.vieux@docker.com> <victor@docker.com>
<victor.vieux@docker.com> <vieux@docker.com>
<victor.vieux@docker.com> <victorvieux@gmail.com>
<dominik@honnef.co> <dominikh@fork-bomb.org>
<ehanchrow@ine.com> <eric.hanchrow@gmail.com>
Walter Stanish <walter@pratyeka.org>
<daniel@gasienica.ch> <dgasienica@zynga.com>
Roberto Hashioka <roberto_hashioka@hotmail.com>
Konstantin Pelykh <kpelykh@zettaset.com>
David Sissitka <me@dsissitka.com>
Nolan Darilek <nolan@thewordnerd.info>
<mastahyeti@gmail.com> <mastahyeti@users.noreply.github.com>
Benoit Chesneau <bchesneau@gmail.com>
Jordan Arentsen <blissdev@gmail.com>
Daniel Garcia <daniel@danielgarcia.info>
Miguel Angel Fernández <elmendalerenda@gmail.com>
Bhiraj Butala <abhiraj.butala@gmail.com>
Faiz Khan <faizkhan00@gmail.com>
Victor Lyuboslavsky <victor@victoreda.com>
Jean-Baptiste Barth <jeanbaptiste.barth@gmail.com>
Matthew Mueller <mattmuelle@gmail.com>
<mosoni@ebay.com> <mohitsoni1989@gmail.com>
Shih-Yuan Lee <fourdollars@gmail.com>
Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com> root <root@vagrant-ubuntu-12.10.vagrantup.com>
Jean-Baptiste Dalido <jeanbaptiste@appgratis.com>
<proppy@google.com> <proppy@aminche.com>
<michael@docker.com> <michael@crosbymichael.com>
<michael@docker.com> <crosby.michael@gmail.com>
<michael@docker.com> <crosbymichael@gmail.com>
<github@developersupport.net> <github@metaliveblog.com>
<brandon@ifup.org> <brandon@ifup.co>
<dano@spotify.com> <daniel.norberg@gmail.com>
<danny@codeaholics.org> <Danny.Yates@mailonline.co.uk>
<gurjeet@singh.im> <singh.gurjeet@gmail.com>
<shawn@churchofgit.com> <shawnlandden@gmail.com>
<sjoerd-github@linuxonly.nl> <sjoerd@byte.nl>
<solomon@docker.com> <solomon.hykes@dotcloud.com>
<solomon@docker.com> <solomon@dotcloud.com>
<solomon@docker.com> <s@docker.com>
Sven Dowideit <SvenDowideit@home.org.au>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@fosiki.com>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@docker.com>
Sven Dowideit <SvenDowideit@home.org.au> <¨SvenDowideit@home.org.au¨>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@home.org.au>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@users.noreply.github.com>
Sven Dowideit <SvenDowideit@home.org.au> <sven@t440s.home.gateway>
<info@fortinux.com> <fortinux@users.noreply.github.com>
Akihiro Matsushima <amatsusbit@gmail.com> <amatsus@users.noreply.github.com>
<alexl@redhat.com> <alexander.larsson@gmail.com>
Alexander Morozov <lk4d4@docker.com> <lk4d4math@gmail.com>
Alexander Morozov <lk4d4@docker.com>
<git.nivoc@neverbox.com> <kuehnle@online.de>
O.S. Tezer <ostezer@gmail.com>
<ostezer@gmail.com> <ostezer@users.noreply.github.com>
Roberto G. Hashioka <roberto.hashioka@docker.com> <roberto_hashioka@hotmail.com>
<justin.p.simonelis@gmail.com> <justin.simonelis@PTS-JSIMON2.toronto.exclamation.com>
<taim@bosboot.org> <maztaim@users.noreply.github.com>
<viktor.vojnovski@amadeus.com> <vojnovski@gmail.com>
<vbatts@redhat.com> <vbatts@hashbangbash.com>
<altsysrq@gmail.com> <iamironbob@gmail.com>
Sridhar Ratnakumar <sridharr@activestate.com>
Sridhar Ratnakumar <sridharr@activestate.com> <github@srid.name>
Liang-Chi Hsieh <viirya@gmail.com>
Aaron L. Xu <liker.xu@foxmail.com> Aaron L. Xu <liker.xu@foxmail.com>
Abhinandan Prativadi <abhi@docker.com>
Adrien Gallouët <adrien@gallouet.fr> <angt@users.noreply.github.com>
Ahmed Kamal <email.ahmedkamal@googlemail.com>
Ahmet Alp Balkan <ahmetb@microsoft.com> <ahmetalpbalkan@gmail.com>
AJ Bowen <aj@gandi.net>
AJ Bowen <aj@gandi.net> <amy@gandi.net>
Akihiro Matsushima <amatsusbit@gmail.com> <amatsus@users.noreply.github.com>
Akihiro Suda <suda.akihiro@lab.ntt.co.jp> <suda.kyoto@gmail.com>
Aleksa Sarai <asarai@suse.de> Aleksa Sarai <asarai@suse.de>
Aleksa Sarai <asarai@suse.de> <asarai@suse.com> Aleksa Sarai <asarai@suse.de> <asarai@suse.com>
Aleksa Sarai <asarai@suse.de> <cyphar@cyphar.com> Aleksa Sarai <asarai@suse.de> <cyphar@cyphar.com>
Will Weaver <monkey@buildingbananas.com> Aleksandrs Fadins <aleks@s-ko.net>
Timothy Hobbs <timothyhobbs@seznam.cz> Alessandro Boch <aboch@tetrationanalytics.com> <aboch@docker.com>
Nathan LeClaire <nathan.leclaire@docker.com> <nathan.leclaire@gmail.com> Alex Chen <alexchenunix@gmail.com> <root@localhost.localdomain>
Nathan LeClaire <nathan.leclaire@docker.com> <nathanleclaire@gmail.com> Alex Ellis <alexellis2@gmail.com>
<github@hollensbe.org> <erik+github@hollensbe.org> Alexander Larsson <alexl@redhat.com> <alexander.larsson@gmail.com>
<github@albersweb.de> <albers@users.noreply.github.com> Alexander Morozov <lk4d4@docker.com>
<lsm5@fedoraproject.org> <lsm5@redhat.com> Alexander Morozov <lk4d4@docker.com> <lk4d4math@gmail.com>
<marc@marc-abramowitz.com> <msabramo@gmail.com> Alexandre Beslic <alexandre.beslic@gmail.com> <abronan@docker.com>
Matthew Heon <mheon@redhat.com> <mheon@mheonlaptop.redhat.com> Alicia Lauerman <alicia@eta.im> <allydevour@me.com>
<bernat@luffy.cx> <vincent@bernat.im>
<bernat@luffy.cx> <Vincent.Bernat@exoscale.ch>
<p@pwaller.net> <peter@scraperwiki.com>
<andrew.weiss@outlook.com> <andrew.weiss@microsoft.com>
Francisco Carriedo <fcarriedo@gmail.com>
<julienbordellier@gmail.com> <git@julienbordellier.com>
<ahmetb@microsoft.com> <ahmetalpbalkan@gmail.com>
<arnaud.porterie@docker.com> <icecrime@gmail.com>
<baloo@gandi.net> <superbaloo+registrations.github@superbaloo.net>
Brian Goff <cpuguy83@gmail.com>
<cpuguy83@gmail.com> <bgoff@cpuguy83-mbp.home>
Erica Windisch <erica@windisch.us> <ewindisch@docker.com>
Erica Windisch <erica@windisch.us> <eric@windisch.us>
<frank.rosquin+github@gmail.com> <frank.rosquin@gmail.com>
Hollie Teal <hollie@docker.com>
<hollie@docker.com> <hollie.teal@docker.com>
<hollie@docker.com> <hollietealok@users.noreply.github.com>
<huu@prismskylabs.com> <whoshuu@gmail.com>
Jessica Frazelle <jessfraz@google.com>
Jessica Frazelle <jessfraz@google.com> <me@jessfraz.com>
Jessica Frazelle <jessfraz@google.com> <jess@mesosphere.com>
Jessica Frazelle <jessfraz@google.com> <jfrazelle@users.noreply.github.com>
Jessica Frazelle <jessfraz@google.com> <acidburn@docker.com>
Jessica Frazelle <jessfraz@google.com> <acidburn@google.com>
Jessica Frazelle <jessfraz@google.com> <jess@docker.com>
Jessica Frazelle <jessfraz@google.com> <princess@docker.com>
<konrad.wilhelm.kleine@gmail.com> <kwk@users.noreply.github.com>
<tintypemolly@gmail.com> <tintypemolly@Ohui-MacBook-Pro.local>
<estesp@linux.vnet.ibm.com> <estesp@gmail.com>
Sebastiaan van Stijn <github@gone.nl> <thaJeztah@users.noreply.github.com>
Sebastiaan van Stijn <github@gone.nl> <sebastiaan@ws-key-sebas3.dpi1.dpi>
Thomas LEVEIL <thomasleveil@gmail.com> Thomas LÉVEIL <thomasleveil@users.noreply.github.com>
<oi@truffles.me.uk> <timruffles@googlemail.com>
<Vincent.Bernat@exoscale.ch> <bernat@luffy.cx>
Antonio Murdaca <antonio.murdaca@gmail.com> <amurdaca@redhat.com>
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@redhat.com>
Antonio Murdaca <antonio.murdaca@gmail.com> <me@runcom.ninja>
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@linux.com>
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@users.noreply.github.com>
Darren Shepherd <darren.s.shepherd@gmail.com> <darren@rancher.com>
Deshi Xiao <dxiao@redhat.com> <dsxiao@dataman-inc.com>
Deshi Xiao <dxiao@redhat.com> <xiaods@gmail.com>
Doug Davis <dug@us.ibm.com> <duglin@users.noreply.github.com>
Giampaolo Mancini <giampaolo@trampolineup.com>
Hakan Özler <hakan.ozler@kodcu.com>
K. Heller <pestophagous@gmail.com> <pestophagous@users.noreply.github.com>
Jacob Atzen <jacob@jacobatzen.dk> <jatzen@gmail.com>
Jeff Nickoloff <jeff.nickoloff@gmail.com> <jeff@allingeek.com>
Jérôme Petazzoni <jerome.petazzoni@docker.com> <jerome.petazzoni@dotcloud.com>
John Harris <john@johnharris.io>
John Howard (VM) <John.Howard@microsoft.com> <jhowardmsft@users.noreply.github.com>
John Howard (VM) <John.Howard@microsoft.com>
John Howard (VM) <John.Howard@microsoft.com> <john.howard@microsoft.com>
John Howard (VM) <John.Howard@microsoft.com> <jhoward@microsoft.com>
John Howard (VM) <John.Howard@microsoft.com> <jhoward@ntdev.microsoft.com>
Kevin Feyrer <kevin.feyrer@btinternet.com> <kevinfeyrer@users.noreply.github.com>
Liao Qingwei <liaoqingwei@huawei.com>
Luke Marsden <me@lukemarsden.net> <luke@digital-crocus.com>
Madhan Raj Mookkandy <MadhanRaj.Mookkandy@microsoft.com> <madhanm@microsoft.com>
Madhu Venugopal <madhu@socketplane.io> <madhu@docker.com>
Mageee <fangpuyi@foxmail.com> <21521230.zju.edu.cn>
Mansi Nahar <mmn4185@rit.edu> <mansinahar@users.noreply.github.com>
Mansi Nahar <mmn4185@rit.edu> <mansi.nahar@macbookpro-mansinahar.local>
Markus Kortlang <hyp3rdino@googlemail.com> <markus.kortlang@lhsystems.com>
Mary Anthony <mary.anthony@docker.com> <mary@docker.com>
Mary Anthony <mary.anthony@docker.com> moxiegirl <mary@docker.com>
Mary Anthony <mary.anthony@docker.com> <moxieandmore@gmail.com>
Matt Schurenko <matt.schurenko@gmail.com>
Matt Williams <mattyw@me.com> <gh@mattyw.net>
Matt Williams <mattyw@me.com>
Michael Spetsiotis <michael_spets@hotmail.com>
Nik Nyby <nikolas@gnu.org> <nnyby@columbia.edu>
Ouyang Liduo <oyld0210@163.com>
Paul Liljenberg <liljenberg.paul@gmail.com> <letters@paulnotcom.se>
Pawel Konczalski <mail@konczalski.de>
Philip Alexander Etling <paetling@gmail.com>
Peter Jaffe <pjaffe@nevo.com>
AJ Bowen <aj@gandi.net> soulshake <amy@gandi.net>
AJ Bowen <aj@gandi.net> soulshake <aj@gandi.net>
Tibor Vass <teabee89@gmail.com> <tibor@docker.com>
Tibor Vass <teabee89@gmail.com> <tiborvass@users.noreply.github.com>
Vincent Bernat <bernat@luffy.cx> <Vincent.Bernat@exoscale.ch>
Yestin Sun <sunyi0804@gmail.com> <yestin.sun@polyera.com>
bin liu <liubin0329@users.noreply.github.com> <liubin0329@gmail.com>
John Howard (VM) <John.Howard@microsoft.com> jhowardmsft <jhoward@microsoft.com>
Ankush Agarwal <ankushagarwal11@gmail.com> <ankushagarwal@users.noreply.github.com>
Tangi COLIN <tangicolin@gmail.com> tangicolin <tangicolin@gmail.com>
Allen Sun <allensun.shl@alibaba-inc.com> <allen.sun@daocloud.io> Allen Sun <allensun.shl@alibaba-inc.com> <allen.sun@daocloud.io>
Allen Sun <allensun.shl@alibaba-inc.com> <shlallen1990@gmail.com> Allen Sun <allensun.shl@alibaba-inc.com> <shlallen1990@gmail.com>
Adrien Gallouët <adrien@gallouet.fr> <angt@users.noreply.github.com> Andrew Weiss <andrew.weiss@docker.com> <andrew.weiss@microsoft.com>
<aanm90@gmail.com> <martins@noironetworks.com> Andrew Weiss <andrew.weiss@docker.com> <andrew.weiss@outlook.com>
André Martins <aanm90@gmail.com> <martins@noironetworks.com>
Andy Rothfusz <github@developersupport.net> <github@metaliveblog.com>
Andy Smith <github@anarkystic.com>
Ankush Agarwal <ankushagarwal11@gmail.com> <ankushagarwal@users.noreply.github.com>
Antonio Murdaca <antonio.murdaca@gmail.com> <amurdaca@redhat.com>
Antonio Murdaca <antonio.murdaca@gmail.com> <me@runcom.ninja>
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@linux.com>
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@redhat.com>
Antonio Murdaca <antonio.murdaca@gmail.com> <runcom@users.noreply.github.com>
Anuj Bahuguna <anujbahuguna.dev@gmail.com> Anuj Bahuguna <anujbahuguna.dev@gmail.com>
Anuj Bahuguna <anujbahuguna.dev@gmail.com> <abahuguna@fiberlink.com>
Anusha Ragunathan <anusha.ragunathan@docker.com> <anusha@docker.com> Anusha Ragunathan <anusha.ragunathan@docker.com> <anusha@docker.com>
Avi Miller <avi.miller@oracle.com> <avi.miller@gmail.com>
Brent Salisbury <brent.salisbury@docker.com> <brent@docker.com>
Chander G <chandergovind@gmail.com>
Chun Chen <ramichen@tencent.com> <chenchun.feed@gmail.com>
Ying Li <cyli@twistedmatrix.com>
Daehyeok Mun <daehyeok@gmail.com> <daehyeok@daehyeok-ui-MacBook-Air.local>
<dqminh@cloudflare.com> <dqminh89@gmail.com>
Daniel, Dao Quang Minh <dqminh@cloudflare.com>
Daniel Nephin <dnephin@docker.com> <dnephin@gmail.com>
Dave Tucker <dt@docker.com> <dave@dtucker.co.uk>
Doug Tangren <d.tangren@gmail.com>
Euan Kemp <euan.kemp@coreos.com> <euank@amazon.com>
Frederick F. Kautz IV <fkautz@redhat.com> <fkautz@alumni.cmu.edu>
Fengtu Wang <wangfengtu@huawei.com> <wangfengtu@huawei.com>
Ben Golub <ben.golub@dotcloud.com>
Harold Cooper <hrldcpr@gmail.com>
hsinko <21551195@zju.edu.cn> <hsinko@users.noreply.github.com>
Josh Hawn <josh.hawn@docker.com> <jlhawn@berkeley.edu>
Justin Cormack <justin.cormack@docker.com>
<justin.cormack@docker.com> <justin.cormack@unikernel.com>
<justin.cormack@docker.com> <justin@specialbusservice.com>
Kamil Domański <kamil@domanski.co>
Lei Jitang <leijitang@huawei.com>
<leijitang@huawei.com> <leijitang@gmail.com>
Linus Heckemann <lheckemann@twig-world.com>
<lheckemann@twig-world.com> <anonymouse2048@gmail.com>
Lynda O'Leary <lyndaoleary29@gmail.com>
<lyndaoleary29@gmail.com> <lyndaoleary@hotmail.com>
Marianna Tessel <mtesselh@gmail.com>
Michael Huettermann <michael@huettermann.net>
Moysés Borges <moysesb@gmail.com>
<moysesb@gmail.com> <moyses.furtado@wplex.com.br>
Nigel Poulton <nigelpoulton@hotmail.com>
Qiang Huang <h.huangqiang@huawei.com>
<h.huangqiang@huawei.com> <qhuang@10.0.2.15>
Boaz Shuster <ripcurld.github@gmail.com>
Shuwei Hao <haosw@cn.ibm.com>
<haosw@cn.ibm.com> <haoshuwei24@gmail.com>
Soshi Katsuta <soshi.katsuta@gmail.com>
<soshi.katsuta@gmail.com> <katsuta_soshi@cyberagent.co.jp>
Stefan Berger <stefanb@linux.vnet.ibm.com>
<stefanb@linux.vnet.ibm.com> <stefanb@us.ibm.com>
Stefan J. Wernli <swernli@microsoft.com> <swernli@ntdev.microsoft.com>
Stephen Day <stephen.day@docker.com>
<stephen.day@docker.com> <stevvooe@users.noreply.github.com>
Toli Kuznets <toli@docker.com>
Tristan Carel <tristan@cogniteev.com>
<tristan@cogniteev.com> <tristan.carel@gmail.com>
<vincent.demeester@docker.com> <vincent@sbr.pm>
<vincent.demeester@docker.com> <vincent+github@demeester.fr>
Vincent Demeester <vincent.demeester@docker.com> <vincent@demeester.fr>
Vishnu Kannan <vishnuk@google.com>
xlgao-zju <xlgao@zju.edu.cn> xlgao <xlgao@zju.edu.cn>
Yu Changchun <yuchangchun1@huawei.com> y00277921 <yuchangchun1@huawei.com>
Yu Changchun <yuchangchun1@huawei.com>
<zij@case.edu> <zjaffee@us.ibm.com>
<anujbahuguna.dev@gmail.com> <abahuguna@fiberlink.com>
<eungjun.yi@navercorp.com> <semtlenori@gmail.com>
<haosw@cn.ibm.com> <haoshuwei1989@163.com>
Hao Shu Wei <haosw@cn.ibm.com>
<matt.bentley@docker.com> <mbentley@mbentley.net>
<MihaiBorob@gmail.com> <MihaiBorobocea@gmail.com>
<redmond.martin@gmail.com> <xgithub@redmond5.com>
<redmond.martin@gmail.com> <martin@tinychat.com>
<srbrahma@us.ibm.com> <sbrahma@us.ibm.com>
<suda.akihiro@lab.ntt.co.jp> <suda.kyoto@gmail.com>
<thomas@gazagnaire.org> <thomas@gazagnaire.com>
Shengbo Song <thomassong@tencent.com> mYmNeo <mymneo@163.com>
Shengbo Song <thomassong@tencent.com>
<sylvain@ascribe.io> <sylvain.bellemare@ezeep.com>
Sylvain Bellemare <sylvain@ascribe.io>
<alexandre.beslic@gmail.com> <abronan@docker.com>
<bilal.amarni@gmail.com> <bamarni@users.noreply.github.com>
<misty@docker.com> <misty@apache.org>
Arnaud Porterie <arnaud.porterie@docker.com> Arnaud Porterie <arnaud.porterie@docker.com>
<cpuguy83@gmail.com> <bgoff@cpuguy83-mbp.local> Arnaud Porterie <arnaud.porterie@docker.com> <icecrime@gmail.com>
David M. Karr <davidmichaelkarr@gmail.com> Arthur Gautier <baloo@gandi.net> <superbaloo+registrations.github@superbaloo.net>
<diogo@docker.com> <diogo.monica@gmail.com> Avi Miller <avi.miller@oracle.com> <avi.miller@gmail.com>
<horwitz@addthis.com> <horwitzja@gmail.com>
<kherner@progress.com> <chosenken@gmail.com>
Kenfe-Mickaël Laventure <mickael.laventure@gmail.com>
<mauricio@medallia.com> <mauriciogaravaglia@gmail.com>
<dhenderson@gmail.com> <Dave.Henderson@ca.ibm.com>
<wkq5325@gmail.com> <wkqwu@cn.ibm.com>
<mike.goelzer@docker.com> <mgoelzer@docker.com>
<nicholasjamesrusso@gmail.com> <nicholasrusso@icloud.com>
Runshen Zhu <runshen.zhu@gmail.com>
Tom Barlow <tomwbarlow@gmail.com>
Tom Sweeney <tsweeney@redhat.com>
Xianlu Bird <xianlubird@gmail.com>
Dan Feldman <danf@jfrog.com>
Harry Zhang <harryz@hyper.sh> <resouer@gmail.com>
Harry Zhang <harryz@hyper.sh> <harryzhang@zju.edu.cn>
Harry Zhang <harryz@hyper.sh> <resouer@163.com>
Harry Zhang <resouer@163.com>
Alex Chen <alexchenunix@gmail.com> alexchen <root@localhost.localdomain>
Alex Ellis <alexellis2@gmail.com>
Alicia Lauerman <alicia@eta.im> <allydevour@me.com>
Ben Bonnefoy <frenchben@docker.com> Ben Bonnefoy <frenchben@docker.com>
Ben Golub <ben.golub@dotcloud.com>
Ben Toews <mastahyeti@gmail.com> <mastahyeti@users.noreply.github.com>
Benoit Chesneau <bchesneau@gmail.com>
Bhiraj Butala <abhiraj.butala@gmail.com>
Bhumika Bayani <bhumikabayani@gmail.com> Bhumika Bayani <bhumikabayani@gmail.com>
Bilal Amarni <bilal.amarni@gmail.com> <bamarni@users.noreply.github.com>
Bin Liu <liubin0329@gmail.com>
Bin Liu <liubin0329@gmail.com> <liubin0329@users.noreply.github.com>
Bingshen Wang <bingshen.wbs@alibaba-inc.com> Bingshen Wang <bingshen.wbs@alibaba-inc.com>
Boaz Shuster <ripcurld.github@gmail.com>
Brandon Philips <brandon.philips@coreos.com> <brandon@ifup.co>
Brandon Philips <brandon.philips@coreos.com> <brandon@ifup.org>
Brent Salisbury <brent.salisbury@docker.com> <brent@docker.com>
Brian Goff <cpuguy83@gmail.com>
Brian Goff <cpuguy83@gmail.com> <bgoff@cpuguy83-mbp.home>
Brian Goff <cpuguy83@gmail.com> <bgoff@cpuguy83-mbp.local>
Chander Govindarajan <chandergovind@gmail.com>
Chao Wang <wangchao.fnst@cn.fujitsu.com> <chaowang@localhost.localdomain>
Charles Hooper <charles.hooper@dotcloud.com> <chooper@plumata.com>
Chen Chao <cc272309126@gmail.com>
Chen Chuanliang <chen.chuanliang@zte.com.cn> Chen Chuanliang <chen.chuanliang@zte.com.cn>
Chen Mingjie <chenmingjie0828@163.com> Chen Mingjie <chenmingjie0828@163.com>
Chen Qiu <cheney-90@hotmail.com> Chen Qiu <cheney-90@hotmail.com>
@@ -330,93 +77,365 @@ Chen Qiu <cheney-90@hotmail.com> <21321229@zju.edu.cn>
Chris Dias <cdias@microsoft.com> Chris Dias <cdias@microsoft.com>
Chris McKinnel <chris.mckinnel@tangentlabs.co.uk> Chris McKinnel <chris.mckinnel@tangentlabs.co.uk>
Christopher Biscardi <biscarch@sketcht.com> Christopher Biscardi <biscarch@sketcht.com>
Christopher Latham <sudosurootdev@gmail.com>
Chun Chen <ramichen@tencent.com> <chenchun.feed@gmail.com>
Corbin Coleman <corbin.coleman@docker.com>
Cristian Staretu <cristian.staretu@gmail.com>
Cristian Staretu <cristian.staretu@gmail.com> <unclejack@users.noreply.github.com>
Cristian Staretu <cristian.staretu@gmail.com> <unclejacksons@gmail.com>
CUI Wei <ghostplant@qq.com> cuiwei13 <cuiwei13@pku.edu.cn> CUI Wei <ghostplant@qq.com> cuiwei13 <cuiwei13@pku.edu.cn>
Daehyeok Mun <daehyeok@gmail.com>
Daehyeok Mun <daehyeok@gmail.com> <daehyeok@daehyeok-ui-MacBook-Air.local>
Daehyeok Mun <daehyeok@gmail.com> <daehyeok@daehyeokui-MacBook-Air.local>
Dan Feldman <danf@jfrog.com>
Daniel Dao <dqminh@cloudflare.com>
Daniel Dao <dqminh@cloudflare.com> <dqminh89@gmail.com>
Daniel Garcia <daniel@danielgarcia.info>
Daniel Gasienica <daniel@gasienica.ch> <dgasienica@zynga.com>
Daniel Grunwell <mwgrunny@gmail.com> Daniel Grunwell <mwgrunny@gmail.com>
Daniel J Walsh <dwalsh@redhat.com> Daniel J Walsh <dwalsh@redhat.com>
Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com> <daniel@dotcloud.com>
Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com> <mzdaniel@glidelink.net>
Daniel Mizyrycki <daniel.mizyrycki@dotcloud.com> <root@vagrant-ubuntu-12.10.vagrantup.com>
Daniel Nephin <dnephin@docker.com> <dnephin@gmail.com>
Daniel Norberg <dano@spotify.com> <daniel.norberg@gmail.com>
Danny Yates <danny@codeaholics.org> <Danny.Yates@mailonline.co.uk>
Darren Shepherd <darren.s.shepherd@gmail.com> <darren@rancher.com>
Dattatraya Kumbhar <dattatraya.kumbhar@gslab.com> Dattatraya Kumbhar <dattatraya.kumbhar@gslab.com>
Dave Henderson <dhenderson@gmail.com> <Dave.Henderson@ca.ibm.com>
Dave Tucker <dt@docker.com> <dave@dtucker.co.uk>
David M. Karr <davidmichaelkarr@gmail.com>
David Sheets <dsheets@docker.com> <sheets@alum.mit.edu> David Sheets <dsheets@docker.com> <sheets@alum.mit.edu>
David Sissitka <me@dsissitka.com>
Deshi Xiao <dxiao@redhat.com> <dsxiao@dataman-inc.com>
Deshi Xiao <dxiao@redhat.com> <xiaods@gmail.com>
Diego Siqueira <dieg0@live.com> Diego Siqueira <dieg0@live.com>
Elan Ruusamäe <glen@pld-linux.org> <glen@delfi.ee> Diogo Monica <diogo@docker.com> <diogo.monica@gmail.com>
Dominik Honnef <dominik@honnef.co> <dominikh@fork-bomb.org>
Doug Davis <dug@us.ibm.com> <duglin@users.noreply.github.com>
Doug Tangren <d.tangren@gmail.com>
Elan Ruusamäe <glen@pld-linux.org> Elan Ruusamäe <glen@pld-linux.org>
Elan Ruusamäe <glen@pld-linux.org> <glen@delfi.ee>
Eric G. Noriega <enoriega@vizuri.com> <egnoriega@users.noreply.github.com> Eric G. Noriega <enoriega@vizuri.com> <egnoriega@users.noreply.github.com>
Eric Hanchrow <ehanchrow@ine.com> <eric.hanchrow@gmail.com>
Erica Windisch <erica@windisch.us> <eric@windisch.us>
Erica Windisch <erica@windisch.us> <ewindisch@docker.com>
Erik Hollensbe <github@hollensbe.org> <erik+github@hollensbe.org>
Erwin van der Koogh <info@erronis.nl>
Euan Kemp <euan.kemp@coreos.com> <euank@amazon.com>
Eugen Krizo <eugen.krizo@gmail.com> Eugen Krizo <eugen.krizo@gmail.com>
Evgeny Shmarnev <shmarnev@gmail.com>
Evelyn Xu <evelynhsu21@gmail.com> Evelyn Xu <evelynhsu21@gmail.com>
Evgeny Shmarnev <shmarnev@gmail.com>
Faiz Khan <faizkhan00@gmail.com>
Felix Ruess <felix.ruess@gmail.com> <felix.ruess@roboception.de> Felix Ruess <felix.ruess@gmail.com> <felix.ruess@roboception.de>
Feng Yan <fy2462@gmail.com>
Fengtu Wang <wangfengtu@huawei.com> <wangfengtu@huawei.com>
Francisco Carriedo <fcarriedo@gmail.com>
Frank Rosquin <frank.rosquin+github@gmail.com> <frank.rosquin@gmail.com>
Frederick F. Kautz IV <fkautz@redhat.com> <fkautz@alumni.cmu.edu>
Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com> Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
Gang Qiao <qiaohai8866@gmail.com> <1373319223@qq.com> Gang Qiao <qiaohai8866@gmail.com> <1373319223@qq.com>
George Kontridze <george@bugsnag.com> George Kontridze <george@bugsnag.com>
Gerwim Feiken <g.feiken@tfe.nl> <gerwim@gmail.com>
Giampaolo Mancini <giampaolo@trampolineup.com>
Gopikannan Venugopalsamy <gopikannan.venugopalsamy@gmail.com> Gopikannan Venugopalsamy <gopikannan.venugopalsamy@gmail.com>
Gou Rao <gou@portworx.com> <gourao@users.noreply.github.com> Gou Rao <gou@portworx.com> <gourao@users.noreply.github.com>
Greg Stephens <greg@udon.org> Greg Stephens <greg@udon.org>
Guillaume J. Charmes <guillaume.charmes@docker.com> <charmes.guillaume@gmail.com>
Guillaume J. Charmes <guillaume.charmes@docker.com> <guillaume.charmes@dotcloud.com>
Guillaume J. Charmes <guillaume.charmes@docker.com> <guillaume@charmes.net>
Guillaume J. Charmes <guillaume.charmes@docker.com> <guillaume@docker.com>
Guillaume J. Charmes <guillaume.charmes@docker.com> <guillaume@dotcloud.com>
Gurjeet Singh <gurjeet@singh.im> <singh.gurjeet@gmail.com>
Gustav Sinder <gustav.sinder@gmail.com> Gustav Sinder <gustav.sinder@gmail.com>
Hakan Özler <hakan.ozler@kodcu.com>
Hao Shu Wei <haosw@cn.ibm.com>
Hao Shu Wei <haosw@cn.ibm.com> <haoshuwei1989@163.com>
Harald Albers <github@albersweb.de> <albers@users.noreply.github.com>
Harold Cooper <hrldcpr@gmail.com>
Harry Zhang <harryz@hyper.sh> <harryzhang@zju.edu.cn>
Harry Zhang <harryz@hyper.sh> <resouer@163.com>
Harry Zhang <harryz@hyper.sh> <resouer@gmail.com>
Harry Zhang <resouer@163.com>
Harshal Patil <harshal.patil@in.ibm.com> <harche@users.noreply.github.com> Harshal Patil <harshal.patil@in.ibm.com> <harche@users.noreply.github.com>
Helen Xie <chenjg@harmonycloud.cn> Helen Xie <chenjg@harmonycloud.cn>
Hyzhou Zhy <hyzhou.zhy@alibaba-inc.com> <1187766782@qq.com> Hollie Teal <hollie@docker.com>
Hollie Teal <hollie@docker.com> <hollie.teal@docker.com>
Hollie Teal <hollie@docker.com> <hollietealok@users.noreply.github.com>
Hu Keping <hukeping@huawei.com>
Huu Nguyen <huu@prismskylabs.com> <whoshuu@gmail.com>
Hyzhou Zhy <hyzhou.zhy@alibaba-inc.com> Hyzhou Zhy <hyzhou.zhy@alibaba-inc.com>
Hyzhou Zhy <hyzhou.zhy@alibaba-inc.com> <1187766782@qq.com>
Jack Laxson <jackjrabbit@gmail.com>
Jacob Atzen <jacob@jacobatzen.dk> <jatzen@gmail.com>
Jacob Tomlinson <jacob@tom.linson.uk> <jacobtomlinson@users.noreply.github.com> Jacob Tomlinson <jacob@tom.linson.uk> <jacobtomlinson@users.noreply.github.com>
Jean-Baptiste Barth <jeanbaptiste.barth@gmail.com>
Jean-Baptiste Dalido <jeanbaptiste@appgratis.com>
Jean-Tiare Le Bigot <jt@yadutaf.fr> <admin@jtlebi.fr>
Jeff Anderson <jeff@docker.com> <jefferya@programmerq.net>
Jeff Nickoloff <jeff.nickoloff@gmail.com> <jeff@allingeek.com>
Jeroen Franse <jeroenfranse@gmail.com>
Jessica Frazelle <jessfraz@google.com>
Jessica Frazelle <jessfraz@google.com> <acidburn@docker.com>
Jessica Frazelle <jessfraz@google.com> <acidburn@google.com>
Jessica Frazelle <jessfraz@google.com> <jess@docker.com>
Jessica Frazelle <jessfraz@google.com> <jess@mesosphere.com>
Jessica Frazelle <jessfraz@google.com> <jfrazelle@users.noreply.github.com>
Jessica Frazelle <jessfraz@google.com> <me@jessfraz.com>
Jessica Frazelle <jessfraz@google.com> <princess@docker.com>
Jim Galasyn <jim.galasyn@docker.com>
Jiuyue Ma <majiuyue@huawei.com> Jiuyue Ma <majiuyue@huawei.com>
Joffrey F <joffrey@docker.com>
Joffrey F <joffrey@docker.com> <f.joffrey@gmail.com>
Joffrey F <joffrey@docker.com> <joffrey@dotcloud.com>
Johan Euphrosine <proppy@google.com> <proppy@aminche.com>
John Harris <john@johnharris.io>
John Howard (VM) <John.Howard@microsoft.com>
John Howard (VM) <John.Howard@microsoft.com> <jhoward@microsoft.com>
John Howard (VM) <John.Howard@microsoft.com> <jhoward@ntdev.microsoft.com>
John Howard (VM) <John.Howard@microsoft.com> <jhowardmsft@users.noreply.github.com>
John Howard (VM) <John.Howard@microsoft.com> <john.howard@microsoft.com>
John Stephens <johnstep@docker.com> <johnstep@users.noreply.github.com> John Stephens <johnstep@docker.com> <johnstep@users.noreply.github.com>
Jordan Arentsen <blissdev@gmail.com>
Jordan Jennings <jjn2009@gmail.com> <jjn2009@users.noreply.github.com>
Jorit Kleine-Möllhoff <joppich@bricknet.de> <joppich@users.noreply.github.com>
Jose Diaz-Gonzalez <jose@seatgeek.com> <josegonzalez@users.noreply.github.com> Jose Diaz-Gonzalez <jose@seatgeek.com> <josegonzalez@users.noreply.github.com>
Josh Eveleth <joshe@opendns.com> <jeveleth@users.noreply.github.com> Josh Eveleth <joshe@opendns.com> <jeveleth@users.noreply.github.com>
Josh Hawn <josh.hawn@docker.com> <jlhawn@berkeley.edu>
Josh Horwitz <horwitz@addthis.com> <horwitzja@gmail.com>
Josh Soref <jsoref@gmail.com> <jsoref@users.noreply.github.com> Josh Soref <jsoref@gmail.com> <jsoref@users.noreply.github.com>
Josh Wilson <josh.wilson@fivestars.com> <jcwilson@users.noreply.github.com> Josh Wilson <josh.wilson@fivestars.com> <jcwilson@users.noreply.github.com>
Jim Galasyn <jim.galasyn@docker.com> Joyce Jang <mail@joycejang.com>
Julien Bordellier <julienbordellier@gmail.com> <git@julienbordellier.com>
Julien Bordellier <julienbordellier@gmail.com> <me@julienbordellier.com>
Justin Cormack <justin.cormack@docker.com>
Justin Cormack <justin.cormack@docker.com> <justin.cormack@unikernel.com>
Justin Cormack <justin.cormack@docker.com> <justin@specialbusservice.com>
Justin Simonelis <justin.p.simonelis@gmail.com> <justin.simonelis@PTS-JSIMON2.toronto.exclamation.com>
Jérôme Petazzoni <jerome.petazzoni@docker.com> <jerome.petazzoni@dotcloud.com>
Jérôme Petazzoni <jerome.petazzoni@docker.com> <jerome.petazzoni@gmail.com>
Jérôme Petazzoni <jerome.petazzoni@docker.com> <jp@enix.org>
K. Heller <pestophagous@gmail.com> <pestophagous@users.noreply.github.com>
Kai Qiang Wu (Kennan) <wkq5325@gmail.com>
Kai Qiang Wu (Kennan) <wkq5325@gmail.com> <wkqwu@cn.ibm.com>
Kamil Domański <kamil@domanski.co>
Kamjar Gerami <kami.gerami@gmail.com>
Ken Cochrane <kencochrane@gmail.com> <KenCochrane@gmail.com>
Ken Herner <kherner@progress.com> <chosenken@gmail.com>
Kenfe-Mickaël Laventure <mickael.laventure@gmail.com>
Kevin Feyrer <kevin.feyrer@btinternet.com> <kevinfeyrer@users.noreply.github.com>
Kevin Kern <kaiwentan@harmonycloud.cn> Kevin Kern <kaiwentan@harmonycloud.cn>
Kir Kolyshkin <kolyshkin@gmail.com>
Kir Kolyshkin <kolyshkin@gmail.com> <kir@openvz.org>
Konrad Kleine <konrad.wilhelm.kleine@gmail.com> <kwk@users.noreply.github.com>
Konstantin Gribov <grossws@gmail.com> Konstantin Gribov <grossws@gmail.com>
Konstantin Pelykh <kpelykh@zettaset.com>
Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp> <kunal.kushwaha@gmail.com> Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp> <kunal.kushwaha@gmail.com>
Lajos Papp <lajos.papp@sequenceiq.com> <lalyos@yahoo.com> Lajos Papp <lajos.papp@sequenceiq.com> <lalyos@yahoo.com>
Lei Jitang <leijitang@huawei.com>
Lei Jitang <leijitang@huawei.com> <leijitang@gmail.com>
Liang Mingqiang <mqliang.zju@gmail.com> Liang Mingqiang <mqliang.zju@gmail.com>
Liang-Chi Hsieh <viirya@gmail.com>
Liao Qingwei <liaoqingwei@huawei.com>
Linus Heckemann <lheckemann@twig-world.com>
Linus Heckemann <lheckemann@twig-world.com> <anonymouse2048@gmail.com>
Lokesh Mandvekar <lsm5@fedoraproject.org> <lsm5@redhat.com>
Lorenzo Fontana <lo@linux.com> <fontanalorenzo@me.com>
Louis Opter <kalessin@kalessin.fr>
Louis Opter <kalessin@kalessin.fr> <louis@dotcloud.com>
Luke Marsden <me@lukemarsden.net> <luke@digital-crocus.com>
Lyn <energylyn@zju.edu.cn> Lyn <energylyn@zju.edu.cn>
Markan Patel <mpatel678@gmail.com> Lynda O'Leary <lyndaoleary29@gmail.com>
Matthew Mosesohn <raytrac3r@gmail.com> Lynda O'Leary <lyndaoleary29@gmail.com> <lyndaoleary@hotmail.com>
Michael Käufl <docker@c.michael-kaeufl.de> <michael-k@users.noreply.github.com>
Michal Minář <miminar@redhat.com>
Michael Hudson-Doyle <michael.hudson@canonical.com> <michael.hudson@linaro.org>
Mike Casas <mkcsas0@gmail.com> <mikecasas@users.noreply.github.com>
Milind Chawre <milindchawre@gmail.com>
Ma Müller <mueller-ma@users.noreply.github.com> Ma Müller <mueller-ma@users.noreply.github.com>
Madhan Raj Mookkandy <MadhanRaj.Mookkandy@microsoft.com> <madhanm@microsoft.com>
Madhu Venugopal <madhu@socketplane.io> <madhu@docker.com>
Mageee <fangpuyi@foxmail.com> <21521230.zju.edu.cn>
Mansi Nahar <mmn4185@rit.edu> <mansi.nahar@macbookpro-mansinahar.local>
Mansi Nahar <mmn4185@rit.edu> <mansinahar@users.noreply.github.com>
Marc Abramowitz <marc@marc-abramowitz.com> <msabramo@gmail.com>
Marcelo Horacio Fortino <info@fortinux.com> <fortinux@users.noreply.github.com>
Marcus Linke <marcus.linke@gmx.de>
Marianna Tessel <mtesselh@gmail.com>
Markan Patel <mpatel678@gmail.com>
Markus Kortlang <hyp3rdino@googlemail.com> <markus.kortlang@lhsystems.com>
Martin Redmond <redmond.martin@gmail.com> <martin@tinychat.com>
Martin Redmond <redmond.martin@gmail.com> <xgithub@redmond5.com>
Mary Anthony <mary.anthony@docker.com> <mary@docker.com>
Mary Anthony <mary.anthony@docker.com> <moxieandmore@gmail.com>
Mary Anthony <mary.anthony@docker.com> moxiegirl <mary@docker.com>
Matt Bentley <matt.bentley@docker.com> <mbentley@mbentley.net>
Matt Schurenko <matt.schurenko@gmail.com>
Matt Williams <mattyw@me.com>
Matt Williams <mattyw@me.com> <gh@mattyw.net>
Matthew Heon <mheon@redhat.com> <mheon@mheonlaptop.redhat.com>
Matthew Mosesohn <raytrac3r@gmail.com>
Matthew Mueller <mattmuelle@gmail.com>
Matthias Kühnle <git.nivoc@neverbox.com> <kuehnle@online.de>
Mauricio Garavaglia <mauricio@medallia.com> <mauriciogaravaglia@gmail.com>
Michael Crosby <michael@docker.com> <crosby.michael@gmail.com>
Michael Crosby <michael@docker.com> <crosbymichael@gmail.com>
Michael Crosby <michael@docker.com> <michael@crosbymichael.com>
Michael Hudson-Doyle <michael.hudson@canonical.com> <michael.hudson@linaro.org>
Michael Huettermann <michael@huettermann.net>
Michael Käufl <docker@c.michael-kaeufl.de> <michael-k@users.noreply.github.com>
Michael Spetsiotis <michael_spets@hotmail.com>
Michal Minář <miminar@redhat.com>
Miguel Angel Fernández <elmendalerenda@gmail.com>
Mihai Borobocea <MihaiBorob@gmail.com> <MihaiBorobocea@gmail.com>
Mike Casas <mkcsas0@gmail.com> <mikecasas@users.noreply.github.com>
Mike Goelzer <mike.goelzer@docker.com> <mgoelzer@docker.com>
Milind Chawre <milindchawre@gmail.com>
Misty Stanley-Jones <misty@docker.com> <misty@apache.org>
Mohit Soni <mosoni@ebay.com> <mohitsoni1989@gmail.com>
Moorthy RS <rsmoorthy@gmail.com> <rsmoorthy@users.noreply.github.com> Moorthy RS <rsmoorthy@gmail.com> <rsmoorthy@users.noreply.github.com>
Moysés Borges <moysesb@gmail.com>
Moysés Borges <moysesb@gmail.com> <moyses.furtado@wplex.com.br>
Nace Oroz <orkica@gmail.com> Nace Oroz <orkica@gmail.com>
Nathan LeClaire <nathan.leclaire@docker.com> <nathan.leclaire@gmail.com>
Nathan LeClaire <nathan.leclaire@docker.com> <nathanleclaire@gmail.com>
Neil Horman <nhorman@tuxdriver.com> <nhorman@hmswarspite.think-freely.org> Neil Horman <nhorman@tuxdriver.com> <nhorman@hmswarspite.think-freely.org>
Nick Russo <nicholasjamesrusso@gmail.com> <nicholasrusso@icloud.com>
Nigel Poulton <nigelpoulton@hotmail.com>
Nik Nyby <nikolas@gnu.org> <nnyby@columbia.edu>
Nolan Darilek <nolan@thewordnerd.info>
O.S. Tezer <ostezer@gmail.com>
O.S. Tezer <ostezer@gmail.com> <ostezer@users.noreply.github.com>
Oh Jinkyun <tintypemolly@gmail.com> <tintypemolly@Ohui-MacBook-Pro.local>
Ouyang Liduo <oyld0210@163.com>
Patrick Stapleton <github@gdi2290.com>
Paul Liljenberg <liljenberg.paul@gmail.com> <letters@paulnotcom.se>
Pavel Tikhomirov <ptikhomirov@virtuozzo.com> <ptikhomirov@parallels.com> Pavel Tikhomirov <ptikhomirov@virtuozzo.com> <ptikhomirov@parallels.com>
Pawel Konczalski <mail@konczalski.de>
Peter Choi <phkchoi89@gmail.com> <reikani@Peters-MacBook-Pro.local> Peter Choi <phkchoi89@gmail.com> <reikani@Peters-MacBook-Pro.local>
Peter Dave Hello <hsu@peterdavehello.org> <PeterDaveHello@users.noreply.github.com> Peter Dave Hello <hsu@peterdavehello.org> <PeterDaveHello@users.noreply.github.com>
Peter Jaffe <pjaffe@nevo.com>
Peter Waller <p@pwaller.net> <peter@scraperwiki.com>
Phil Estes <estesp@linux.vnet.ibm.com> <estesp@gmail.com>
Philip Alexander Etling <paetling@gmail.com>
Philipp Gillé <philipp.gille@gmail.com> <philippgille@users.noreply.github.com> Philipp Gillé <philipp.gille@gmail.com> <philippgille@users.noreply.github.com>
Qiang Huang <h.huangqiang@huawei.com>
Qiang Huang <h.huangqiang@huawei.com> <qhuang@10.0.2.15>
Renaud Gaubert <rgaubert@nvidia.com> <renaud.gaubert@gmail.com>
Robert Terhaar <rterhaar@atlanticdynamic.com> <robbyt@users.noreply.github.com> Robert Terhaar <rterhaar@atlanticdynamic.com> <robbyt@users.noreply.github.com>
Roberto G. Hashioka <roberto.hashioka@docker.com> <roberto_hashioka@hotmail.com>
Roberto Muñoz Fernández <robertomf@gmail.com> <roberto.munoz.fernandez.contractor@bbva.com> Roberto Muñoz Fernández <robertomf@gmail.com> <roberto.munoz.fernandez.contractor@bbva.com>
Roman Dudin <katrmr@gmail.com> <decadent@users.noreply.github.com> Roman Dudin <katrmr@gmail.com> <decadent@users.noreply.github.com>
Sandeep Bansal <sabansal@microsoft.com> <msabansal@microsoft.com> Runshen Zhu <runshen.zhu@gmail.com>
Sandeep Bansal <sabansal@microsoft.com> Sandeep Bansal <sabansal@microsoft.com>
Sandeep Bansal <sabansal@microsoft.com> <msabansal@microsoft.com>
Sargun Dhillon <sargun@netflix.com> <sargun@sargun.me>
Sean Lee <seanlee@tw.ibm.com> <scaleoutsean@users.noreply.github.com> Sean Lee <seanlee@tw.ibm.com> <scaleoutsean@users.noreply.github.com>
Sebastiaan van Stijn <github@gone.nl> <sebastiaan@ws-key-sebas3.dpi1.dpi>
Sebastiaan van Stijn <github@gone.nl> <thaJeztah@users.noreply.github.com>
Shaun Kaasten <shaunk@gmail.com> Shaun Kaasten <shaunk@gmail.com>
Shawn Landden <shawn@churchofgit.com> <shawnlandden@gmail.com>
Shengbo Song <thomassong@tencent.com>
Shengbo Song <thomassong@tencent.com> <mymneo@163.com>
Shih-Yuan Lee <fourdollars@gmail.com>
Shishir Mahajan <shishir.mahajan@redhat.com> <smahajan@redhat.com>
Shukui Yang <yangshukui@huawei.com> Shukui Yang <yangshukui@huawei.com>
Shuwei Hao <haosw@cn.ibm.com>
Shuwei Hao <haosw@cn.ibm.com> <haoshuwei24@gmail.com>
Sjoerd Langkemper <sjoerd-github@linuxonly.nl> <sjoerd@byte.nl>
Solomon Hykes <solomon@docker.com> <s@docker.com>
Solomon Hykes <solomon@docker.com> <solomon.hykes@dotcloud.com>
Solomon Hykes <solomon@docker.com> <solomon@dotcloud.com>
Soshi Katsuta <soshi.katsuta@gmail.com>
Soshi Katsuta <soshi.katsuta@gmail.com> <katsuta_soshi@cyberagent.co.jp>
Sridhar Ratnakumar <sridharr@activestate.com>
Sridhar Ratnakumar <sridharr@activestate.com> <github@srid.name>
Srini Brahmaroutu <srbrahma@us.ibm.com> <sbrahma@us.ibm.com>
Srinivasan Srivatsan <srinivasan.srivatsan@hpe.com> <srinsriv@users.noreply.github.com> Srinivasan Srivatsan <srinivasan.srivatsan@hpe.com> <srinsriv@users.noreply.github.com>
Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger <stefanb@linux.vnet.ibm.com> <stefanb@us.ibm.com>
Stefan J. Wernli <swernli@microsoft.com> <swernli@ntdev.microsoft.com>
Stefan S. <tronicum@user.github.com> Stefan S. <tronicum@user.github.com>
Stephen Day <stephen.day@docker.com>
Stephen Day <stephen.day@docker.com> <stevvooe@users.noreply.github.com>
Steve Desmond <steve@vtsv.ca> <stevedesmond-ca@users.noreply.github.com> Steve Desmond <steve@vtsv.ca> <stevedesmond-ca@users.noreply.github.com>
Sun Gengze <690388648@qq.com> Sun Gengze <690388648@qq.com>
Sven Dowideit <SvenDowideit@home.org.au>
Sven Dowideit <SvenDowideit@home.org.au> <sven@t440s.home.gateway>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@docker.com>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@fosiki.com>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@home.org.au>
Sven Dowideit <SvenDowideit@home.org.au> <SvenDowideit@users.noreply.github.com>
Sven Dowideit <SvenDowideit@home.org.au> <¨SvenDowideit@home.org.au¨>
Sylvain Bellemare <sylvain@ascribe.io>
Sylvain Bellemare <sylvain@ascribe.io> <sylvain.bellemare@ezeep.com>
Tangi Colin <tangicolin@gmail.com>
Tejesh Mehta <tejesh.mehta@gmail.com> <tj@init.me>
Thatcher Peskens <thatcher@docker.com>
Thatcher Peskens <thatcher@docker.com> <thatcher@dotcloud.com>
Thatcher Peskens <thatcher@docker.com> <thatcher@gmx.net>
Thomas Gazagnaire <thomas@gazagnaire.org> <thomas@gazagnaire.com>
Thomas Léveil <thomasleveil@gmail.com>
Thomas Léveil <thomasleveil@gmail.com> <thomasleveil@users.noreply.github.com>
Tibor Vass <teabee89@gmail.com> <tibor@docker.com>
Tibor Vass <teabee89@gmail.com> <tiborvass@users.noreply.github.com>
Tim Bart <tim@fewagainstmany.com> Tim Bart <tim@fewagainstmany.com>
Tim Bosse <taim@bosboot.org> <maztaim@users.noreply.github.com>
Tim Ruffles <oi@truffles.me.uk> <timruffles@googlemail.com>
Tim Terhorst <mynamewastaken+git@gmail.com>
Tim Zju <21651152@zju.edu.cn> Tim Zju <21651152@zju.edu.cn>
Timothy Hobbs <timothyhobbs@seznam.cz>
Toli Kuznets <toli@docker.com>
Tom Barlow <tomwbarlow@gmail.com>
Tom Sweeney <tsweeney@redhat.com>
Tõnis Tiigi <tonistiigi@gmail.com> Tõnis Tiigi <tonistiigi@gmail.com>
Trishna Guha <trishnaguha17@gmail.com> Trishna Guha <trishnaguha17@gmail.com>
Wayne Song <wsong@docker.com> <wsong@users.noreply.github.com> Tristan Carel <tristan@cogniteev.com>
Tristan Carel <tristan@cogniteev.com> <tristan.carel@gmail.com>
Umesh Yadav <umesh4257@gmail.com> <dungeonmaster18@users.noreply.github.com>
Victor Lyuboslavsky <victor@victoreda.com>
Victor Vieux <victor.vieux@docker.com> <dev@vvieux.com>
Victor Vieux <victor.vieux@docker.com> <victor.vieux@dotcloud.com>
Victor Vieux <victor.vieux@docker.com> <victor@docker.com>
Victor Vieux <victor.vieux@docker.com> <victor@dotcloud.com>
Victor Vieux <victor.vieux@docker.com> <victorvieux@gmail.com>
Victor Vieux <victor.vieux@docker.com> <vieux@docker.com>
Viktor Vojnovski <viktor.vojnovski@amadeus.com> <vojnovski@gmail.com>
Vincent Batts <vbatts@redhat.com> <vbatts@hashbangbash.com>
Vincent Bernat <Vincent.Bernat@exoscale.ch> <bernat@luffy.cx>
Vincent Bernat <Vincent.Bernat@exoscale.ch> <vincent@bernat.im>
Vincent Demeester <vincent.demeester@docker.com> <vincent+github@demeester.fr>
Vincent Demeester <vincent.demeester@docker.com> <vincent@demeester.fr>
Vincent Demeester <vincent.demeester@docker.com> <vincent@sbr.pm>
Vishnu Kannan <vishnuk@google.com>
Vladimir Rutsky <altsysrq@gmail.com> <iamironbob@gmail.com>
Walter Stanish <walter@pratyeka.org>
Wang Guoliang <liangcszzu@163.com> Wang Guoliang <liangcszzu@163.com>
Wang Jie <wangjie5@chinaskycloud.com> Wang Jie <wangjie5@chinaskycloud.com>
Wang Ping <present.wp@icloud.com> Wang Ping <present.wp@icloud.com>
Wang Yuexiao <wang.yuexiao@zte.com.cn> Wang Yuexiao <wang.yuexiao@zte.com.cn>
Wayne Chang <wayne@neverfear.org>
Wayne Song <wsong@docker.com> <wsong@users.noreply.github.com>
Wei Wu <wuwei4455@gmail.com> cizixs <cizixs@163.com>
Wenjun Tang <tangwj2@lenovo.com> <dodia@163.com> Wenjun Tang <tangwj2@lenovo.com> <dodia@163.com>
Wewang Xiaorenfine <wang.xiaoren@zte.com.cn> Wewang Xiaorenfine <wang.xiaoren@zte.com.cn>
Wei Wu <wuwei4455@gmail.com> cizixs <cizixs@163.com> Will Weaver <monkey@buildingbananas.com>
Xianglin Gao <xlgao@zju.edu.cn>
Xianlu Bird <xianlubird@gmail.com>
Xiaoyu Zhang <zhang.xiaoyu33@zte.com.cn> Xiaoyu Zhang <zhang.xiaoyu33@zte.com.cn>
Xuecong Liao <satorulogic@gmail.com> Xuecong Liao <satorulogic@gmail.com>
Yamasaki Masahide <masahide.y@gmail.com> Yamasaki Masahide <masahide.y@gmail.com>
Yao Zaiyong <yaozaiyong@hotmail.com>
Yassine Tijani <yasstij11@gmail.com> Yassine Tijani <yasstij11@gmail.com>
Yazhong Liu <yorkiefixer@gmail.com>
Yestin Sun <sunyi0804@gmail.com> <yestin.sun@polyera.com>
Yi EungJun <eungjun.yi@navercorp.com> <semtlenori@gmail.com>
Ying Li <ying.li@docker.com>
Ying Li <ying.li@docker.com> <cyli@twistedmatrix.com> Ying Li <ying.li@docker.com> <cyli@twistedmatrix.com>
Yong Tang <yong.tang.github@outlook.com> <yongtang@users.noreply.github.com> Yong Tang <yong.tang.github@outlook.com> <yongtang@users.noreply.github.com>
Yosef Fertel <yfertel@gmail.com> <frosforever@users.noreply.github.com>
Yu Changchun <yuchangchun1@huawei.com>
Yu Chengxia <yuchengxia@huawei.com> Yu Chengxia <yuchengxia@huawei.com>
Yu Peng <yu.peng36@zte.com.cn> Yu Peng <yu.peng36@zte.com.cn>
Yu Peng <yu.peng36@zte.com.cn> <yupeng36@zte.com.cn> Yu Peng <yu.peng36@zte.com.cn> <yupeng36@zte.com.cn>
Yao Zaiyong <yaozaiyong@hotmail.com> Zachary Jaffee <zjaffee@us.ibm.com> <zij@case.edu>
Zachary Jaffee <zjaffee@us.ibm.com> <zjaffee@apache.org>
ZhangHang <stevezhang2014@gmail.com> ZhangHang <stevezhang2014@gmail.com>
Zhenkun Bi <bi.zhenkun@zte.com.cn> Zhenkun Bi <bi.zhenkun@zte.com.cn>
Zhu Kunjia <zhu.kunjia@zte.com.cn> Zhu Kunjia <zhu.kunjia@zte.com.cn>
Zou Yu <zouyu7@huawei.com>

View File

@@ -26,6 +26,7 @@ Adam Walz <adam@adamwalz.net>
Addam Hardy <addam.hardy@gmail.com> Addam Hardy <addam.hardy@gmail.com>
Aditi Rajagopal <arajagopal@us.ibm.com> Aditi Rajagopal <arajagopal@us.ibm.com>
Aditya <aditya@netroy.in> Aditya <aditya@netroy.in>
Adnan Khan <adnkha@amazon.com>
Adolfo Ochagavía <aochagavia92@gmail.com> Adolfo Ochagavía <aochagavia92@gmail.com>
Adria Casas <adriacasas88@gmail.com> Adria Casas <adriacasas88@gmail.com>
Adrian Moisey <adrian@changeover.za.net> Adrian Moisey <adrian@changeover.za.net>
@@ -43,6 +44,7 @@ ajneu <ajneu@users.noreply.github.com>
Akash Gupta <akagup@microsoft.com> Akash Gupta <akagup@microsoft.com>
Akihiro Matsushima <amatsusbit@gmail.com> Akihiro Matsushima <amatsusbit@gmail.com>
Akihiro Suda <suda.akihiro@lab.ntt.co.jp> Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Akim Demaille <akim.demaille@docker.com>
Akira Koyasu <mail@akirakoyasu.net> Akira Koyasu <mail@akirakoyasu.net>
Akshay Karle <akshay.a.karle@gmail.com> Akshay Karle <akshay.a.karle@gmail.com>
Al Tobey <al@ooyala.com> Al Tobey <al@ooyala.com>
@@ -105,6 +107,7 @@ Andre Dublin <81dublin@gmail.com>
Andre Granovsky <robotciti@live.com> Andre Granovsky <robotciti@live.com>
Andrea Luzzardi <aluzzardi@gmail.com> Andrea Luzzardi <aluzzardi@gmail.com>
Andrea Turli <andrea.turli@gmail.com> Andrea Turli <andrea.turli@gmail.com>
Andreas Elvers <andreas@work.de>
Andreas Köhler <andi5.py@gmx.net> Andreas Köhler <andi5.py@gmx.net>
Andreas Savvides <andreas@editd.com> Andreas Savvides <andreas@editd.com>
Andreas Tiefenthaler <at@an-ti.eu> Andreas Tiefenthaler <at@an-ti.eu>
@@ -123,8 +126,9 @@ Andrew Macpherson <hopscotch23@gmail.com>
Andrew Martin <sublimino@gmail.com> Andrew Martin <sublimino@gmail.com>
Andrew McDonnell <bugs@andrewmcdonnell.net> Andrew McDonnell <bugs@andrewmcdonnell.net>
Andrew Munsell <andrew@wizardapps.net> Andrew Munsell <andrew@wizardapps.net>
Andrew Pennebaker <andrew.pennebaker@gmail.com>
Andrew Po <absourd.noise@gmail.com> Andrew Po <absourd.noise@gmail.com>
Andrew Weiss <andrew.weiss@outlook.com> Andrew Weiss <andrew.weiss@docker.com>
Andrew Williams <williams.andrew@gmail.com> Andrew Williams <williams.andrew@gmail.com>
Andrews Medina <andrewsmedina@gmail.com> Andrews Medina <andrewsmedina@gmail.com>
Andrey Petrov <andrey.petrov@shazow.net> Andrey Petrov <andrey.petrov@shazow.net>
@@ -144,6 +148,7 @@ Anil Madhavapeddy <anil@recoil.org>
Ankush Agarwal <ankushagarwal11@gmail.com> Ankush Agarwal <ankushagarwal11@gmail.com>
Anonmily <michelle@michelleliu.io> Anonmily <michelle@michelleliu.io>
Anran Qiao <anran.qiao@daocloud.io> Anran Qiao <anran.qiao@daocloud.io>
Anshul Pundir <anshul.pundir@docker.com>
Anthon van der Neut <anthon@mnt.org> Anthon van der Neut <anthon@mnt.org>
Anthony Baire <Anthony.Baire@irisa.fr> Anthony Baire <Anthony.Baire@irisa.fr>
Anthony Bishopric <git@anthonybishopric.com> Anthony Bishopric <git@anthonybishopric.com>
@@ -167,6 +172,7 @@ Arthur Barr <arthur.barr@uk.ibm.com>
Arthur Gautier <baloo@gandi.net> Arthur Gautier <baloo@gandi.net>
Artur Meyster <arthurfbi@yahoo.com> Artur Meyster <arthurfbi@yahoo.com>
Arun Gupta <arun.gupta@gmail.com> Arun Gupta <arun.gupta@gmail.com>
Asad Saeeduddin <masaeedu@gmail.com>
Asbjørn Enge <asbjorn@hanafjedle.net> Asbjørn Enge <asbjorn@hanafjedle.net>
averagehuman <averagehuman@users.noreply.github.com> averagehuman <averagehuman@users.noreply.github.com>
Avi Das <andas222@gmail.com> Avi Das <andas222@gmail.com>
@@ -199,7 +205,7 @@ Bhiraj Butala <abhiraj.butala@gmail.com>
Bhumika Bayani <bhumikabayani@gmail.com> Bhumika Bayani <bhumikabayani@gmail.com>
Bilal Amarni <bilal.amarni@gmail.com> Bilal Amarni <bilal.amarni@gmail.com>
Bill W <SydOps@users.noreply.github.com> Bill W <SydOps@users.noreply.github.com>
bin liu <liubin0329@users.noreply.github.com> Bin Liu <liubin0329@gmail.com>
Bingshen Wang <bingshen.wbs@alibaba-inc.com> Bingshen Wang <bingshen.wbs@alibaba-inc.com>
Blake Geno <blakegeno@gmail.com> Blake Geno <blakegeno@gmail.com>
Boaz Shuster <ripcurld.github@gmail.com> Boaz Shuster <ripcurld.github@gmail.com>
@@ -213,12 +219,13 @@ boynux <boynux@gmail.com>
Bradley Cicenas <bradley.cicenas@gmail.com> Bradley Cicenas <bradley.cicenas@gmail.com>
Bradley Wright <brad@intranation.com> Bradley Wright <brad@intranation.com>
Brandon Liu <bdon@bdon.org> Brandon Liu <bdon@bdon.org>
Brandon Philips <brandon@ifup.org> Brandon Philips <brandon.philips@coreos.com>
Brandon Rhodes <brandon@rhodesmill.org> Brandon Rhodes <brandon@rhodesmill.org>
Brendan Dixon <brendand@microsoft.com> Brendan Dixon <brendand@microsoft.com>
Brent Salisbury <brent.salisbury@docker.com> Brent Salisbury <brent.salisbury@docker.com>
Brett Higgins <brhiggins@arbor.net> Brett Higgins <brhiggins@arbor.net>
Brett Kochendorfer <brett.kochendorfer@gmail.com> Brett Kochendorfer <brett.kochendorfer@gmail.com>
Brett Randall <javabrett@gmail.com>
Brian (bex) Exelbierd <bexelbie@redhat.com> Brian (bex) Exelbierd <bexelbie@redhat.com>
Brian Bland <brian.bland@docker.com> Brian Bland <brian.bland@docker.com>
Brian DeHamer <brian@dehamer.com> Brian DeHamer <brian@dehamer.com>
@@ -266,7 +273,8 @@ Cedric Davies <cedricda@microsoft.com>
Cezar Sa Espinola <cezarsa@gmail.com> Cezar Sa Espinola <cezarsa@gmail.com>
Chad Swenson <chadswen@gmail.com> Chad Swenson <chadswen@gmail.com>
Chance Zibolski <chance.zibolski@gmail.com> Chance Zibolski <chance.zibolski@gmail.com>
Chander G <chandergovind@gmail.com> Chander Govindarajan <chandergovind@gmail.com>
Chao Wang <wangchao.fnst@cn.fujitsu.com>
Charles Chan <charleswhchan@users.noreply.github.com> Charles Chan <charleswhchan@users.noreply.github.com>
Charles Hooper <charles.hooper@dotcloud.com> Charles Hooper <charles.hooper@dotcloud.com>
Charles Law <claw@conduce.com> Charles Law <claw@conduce.com>
@@ -284,6 +292,8 @@ Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
Chen Min <chenmin46@huawei.com> Chen Min <chenmin46@huawei.com>
Chen Mingjie <chenmingjie0828@163.com> Chen Mingjie <chenmingjie0828@163.com>
Chen Qiu <cheney-90@hotmail.com> Chen Qiu <cheney-90@hotmail.com>
Cheng-mean Liu <soccerl@microsoft.com>
Chetan Birajdar <birajdar.chetan@gmail.com>
Chewey <prosto-chewey@users.noreply.github.com> Chewey <prosto-chewey@users.noreply.github.com>
Chia-liang Kao <clkao@clkao.org> Chia-liang Kao <clkao@clkao.org>
chli <chli@freewheel.tv> chli <chli@freewheel.tv>
@@ -306,6 +316,7 @@ Chris Swan <chris.swan@iee.org>
Chris Wahl <github@wahlnetwork.com> Chris Wahl <github@wahlnetwork.com>
Chris Weyl <cweyl@alumni.drew.edu> Chris Weyl <cweyl@alumni.drew.edu>
Christian Berendt <berendt@b1-systems.de> Christian Berendt <berendt@b1-systems.de>
Christian Brauner <christian.brauner@ubuntu.com>
Christian Böhme <developement@boehme3d.de> Christian Böhme <developement@boehme3d.de>
Christian Persson <saser@live.se> Christian Persson <saser@live.se>
Christian Rotzoll <ch.rotzoll@gmail.com> Christian Rotzoll <ch.rotzoll@gmail.com>
@@ -333,6 +344,7 @@ Colin Walters <walters@verbum.org>
Collin Guarino <collin.guarino@gmail.com> Collin Guarino <collin.guarino@gmail.com>
Colm Hally <colmhally@gmail.com> Colm Hally <colmhally@gmail.com>
companycy <companycy@gmail.com> companycy <companycy@gmail.com>
Corbin Coleman <corbin.coleman@docker.com>
Corey Farrell <git@cfware.com> Corey Farrell <git@cfware.com>
Cory Forsyth <cory.forsyth@gmail.com> Cory Forsyth <cory.forsyth@gmail.com>
cressie176 <github@stephen-cresswell.net> cressie176 <github@stephen-cresswell.net>
@@ -363,6 +375,7 @@ Dan McPherson <dmcphers@redhat.com>
Dan Stine <sw@stinemail.com> Dan Stine <sw@stinemail.com>
Dan Williams <me@deedubs.com> Dan Williams <me@deedubs.com>
Daniel Antlinger <d.antlinger@gmx.at> Daniel Antlinger <d.antlinger@gmx.at>
Daniel Dao <dqminh@cloudflare.com>
Daniel Exner <dex@dragonslave.de> Daniel Exner <dex@dragonslave.de>
Daniel Farrell <dfarrell@redhat.com> Daniel Farrell <dfarrell@redhat.com>
Daniel Garcia <daniel@danielgarcia.info> Daniel Garcia <daniel@danielgarcia.info>
@@ -381,9 +394,9 @@ Daniel Von Fange <daniel@leancoder.com>
Daniel X Moore <yahivin@gmail.com> Daniel X Moore <yahivin@gmail.com>
Daniel YC Lin <dlin.tw@gmail.com> Daniel YC Lin <dlin.tw@gmail.com>
Daniel Zhang <jmzwcn@gmail.com> Daniel Zhang <jmzwcn@gmail.com>
Daniel, Dao Quang Minh <dqminh@cloudflare.com>
Danny Berger <dpb587@gmail.com> Danny Berger <dpb587@gmail.com>
Danny Yates <danny@codeaholics.org> Danny Yates <danny@codeaholics.org>
Danyal Khaliq <danyal.khaliq@tenpearls.com>
Darren Coxall <darren@darrencoxall.com> Darren Coxall <darren@darrencoxall.com>
Darren Shepherd <darren.s.shepherd@gmail.com> Darren Shepherd <darren.s.shepherd@gmail.com>
Darren Stahl <darst@microsoft.com> Darren Stahl <darst@microsoft.com>
@@ -431,6 +444,7 @@ Denis Defreyne <denis@soundcloud.com>
Denis Gladkikh <denis@gladkikh.email> Denis Gladkikh <denis@gladkikh.email>
Denis Ollier <larchunix@users.noreply.github.com> Denis Ollier <larchunix@users.noreply.github.com>
Dennis Chen <barracks510@gmail.com> Dennis Chen <barracks510@gmail.com>
Dennis Chen <dennis.chen@arm.com>
Dennis Docter <dennis@d23.nl> Dennis Docter <dennis@d23.nl>
Derek <crq@kernel.org> Derek <crq@kernel.org>
Derek <crquan@gmail.com> Derek <crquan@gmail.com>
@@ -516,6 +530,7 @@ Eric Paris <eparis@redhat.com>
Eric Rafaloff <erafaloff@gmail.com> Eric Rafaloff <erafaloff@gmail.com>
Eric Rosenberg <ehaydenr@users.noreply.github.com> Eric Rosenberg <ehaydenr@users.noreply.github.com>
Eric Sage <eric.david.sage@gmail.com> Eric Sage <eric.david.sage@gmail.com>
Eric Soderstrom <ericsoderstrom@gmail.com>
Eric Yang <windfarer@gmail.com> Eric Yang <windfarer@gmail.com>
Eric-Olivier Lamey <eo@lamey.me> Eric-Olivier Lamey <eo@lamey.me>
Erica Windisch <erica@windisch.us> Erica Windisch <erica@windisch.us>
@@ -567,6 +582,7 @@ Felix Hupfeld <quofelix@users.noreply.github.com>
Felix Rabe <felix@rabe.io> Felix Rabe <felix@rabe.io>
Felix Ruess <felix.ruess@gmail.com> Felix Ruess <felix.ruess@gmail.com>
Felix Schindler <fschindler@weluse.de> Felix Schindler <fschindler@weluse.de>
Feng Yan <fy2462@gmail.com>
Fengtu Wang <wangfengtu@huawei.com> Fengtu Wang <wangfengtu@huawei.com>
Ferenc Szabo <pragmaticfrank@gmail.com> Ferenc Szabo <pragmaticfrank@gmail.com>
Fernando <fermayo@gmail.com> Fernando <fermayo@gmail.com>
@@ -586,7 +602,6 @@ Florian Weingarten <flo@hackvalue.de>
Florin Asavoaie <florin.asavoaie@gmail.com> Florin Asavoaie <florin.asavoaie@gmail.com>
Florin Patan <florinpatan@gmail.com> Florin Patan <florinpatan@gmail.com>
fonglh <fonglh@gmail.com> fonglh <fonglh@gmail.com>
fortinux <info@fortinux.com>
Foysal Iqbal <foysal.iqbal.fb@gmail.com> Foysal Iqbal <foysal.iqbal.fb@gmail.com>
Francesc Campoy <campoy@google.com> Francesc Campoy <campoy@google.com>
Francis Chuang <francis.chuang@boostport.com> Francis Chuang <francis.chuang@boostport.com>
@@ -601,8 +616,7 @@ Frederick F. Kautz IV <fkautz@redhat.com>
Frederik Loeffert <frederik@zitrusmedia.de> Frederik Loeffert <frederik@zitrusmedia.de>
Frederik Nordahl Jul Sabroe <frederikns@gmail.com> Frederik Nordahl Jul Sabroe <frederikns@gmail.com>
Freek Kalter <freek@kalteronline.org> Freek Kalter <freek@kalteronline.org>
frosforever <frosforever@users.noreply.github.com> Frieder Bluemle <frieder.bluemle@gmail.com>
fy2462 <fy2462@gmail.com>
Félix Baylac-Jacqué <baylac.felix@gmail.com> Félix Baylac-Jacqué <baylac.felix@gmail.com>
Félix Cantournet <felix.cantournet@cloudwatt.com> Félix Cantournet <felix.cantournet@cloudwatt.com>
Gabe Rosenhouse <gabe@missionst.com> Gabe Rosenhouse <gabe@missionst.com>
@@ -629,7 +643,8 @@ Georgi Hristozov <georgi@forkbomb.nl>
Gereon Frey <gereon.frey@dynport.de> Gereon Frey <gereon.frey@dynport.de>
German DZ <germ@ndz.com.ar> German DZ <germ@ndz.com.ar>
Gert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl> Gert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>
Gerwim <gerwim@gmail.com> Gerwim Feiken <g.feiken@tfe.nl>
Ghislain Bourgeois <ghislain.bourgeois@gmail.com>
Giampaolo Mancini <giampaolo@trampolineup.com> Giampaolo Mancini <giampaolo@trampolineup.com>
Gianluca Borello <g.borello@gmail.com> Gianluca Borello <g.borello@gmail.com>
Gildas Cuisinier <gildas.cuisinier@gcuisinier.net> Gildas Cuisinier <gildas.cuisinier@gcuisinier.net>
@@ -673,6 +688,7 @@ Harry Zhang <harryz@hyper.sh>
Harshal Patil <harshal.patil@in.ibm.com> Harshal Patil <harshal.patil@in.ibm.com>
Harshal Patil <harshalp@linux.vnet.ibm.com> Harshal Patil <harshalp@linux.vnet.ibm.com>
He Simei <hesimei@zju.edu.cn> He Simei <hesimei@zju.edu.cn>
He Xiaoxi <tossmilestone@gmail.com>
He Xin <he_xinworld@126.com> He Xin <he_xinworld@126.com>
heartlock <21521209@zju.edu.cn> heartlock <21521209@zju.edu.cn>
Hector Castro <hectcastro@gmail.com> Hector Castro <hectcastro@gmail.com>
@@ -708,6 +724,7 @@ Iavael <iavaelooeyt@gmail.com>
Icaro Seara <icaro.seara@gmail.com> Icaro Seara <icaro.seara@gmail.com>
Ignacio Capurro <icapurrofagian@gmail.com> Ignacio Capurro <icapurrofagian@gmail.com>
Igor Dolzhikov <bluesriverz@gmail.com> Igor Dolzhikov <bluesriverz@gmail.com>
Igor Karpovich <i.karpovich@currencysolutions.com>
Iliana Weller <iweller@amazon.com> Iliana Weller <iweller@amazon.com>
Ilkka Laukkanen <ilkka@ilkka.io> Ilkka Laukkanen <ilkka@ilkka.io>
Ilya Dmitrichenko <errordeveloper@gmail.com> Ilya Dmitrichenko <errordeveloper@gmail.com>
@@ -726,9 +743,11 @@ Ivan Markin <twim@riseup.net>
J Bruni <joaohbruni@yahoo.com.br> J Bruni <joaohbruni@yahoo.com.br>
J. Nunn <jbnunn@gmail.com> J. Nunn <jbnunn@gmail.com>
Jack Danger Canty <jackdanger@squareup.com> Jack Danger Canty <jackdanger@squareup.com>
Jack Laxson <jackjrabbit@gmail.com>
Jacob Atzen <jacob@jacobatzen.dk> Jacob Atzen <jacob@jacobatzen.dk>
Jacob Edelman <edelman.jd@gmail.com> Jacob Edelman <edelman.jd@gmail.com>
Jacob Tomlinson <jacob@tom.linson.uk> Jacob Tomlinson <jacob@tom.linson.uk>
Jacob Vallejo <jakeev@amazon.com>
Jacob Wen <jian.w.wen@oracle.com> Jacob Wen <jian.w.wen@oracle.com>
Jake Champlin <jake.champlin.27@gmail.com> Jake Champlin <jake.champlin.27@gmail.com>
Jake Moshenko <jake@devtable.com> Jake Moshenko <jake@devtable.com>
@@ -785,6 +804,7 @@ Jean-Christophe Berthon <huygens@berthon.eu>
Jean-Paul Calderone <exarkun@twistedmatrix.com> Jean-Paul Calderone <exarkun@twistedmatrix.com>
Jean-Pierre Huynh <jean-pierre.huynh@ounet.fr> Jean-Pierre Huynh <jean-pierre.huynh@ounet.fr>
Jean-Tiare Le Bigot <jt@yadutaf.fr> Jean-Tiare Le Bigot <jt@yadutaf.fr>
Jeeva S. Chelladhurai <sjeeva@gmail.com>
Jeff Anderson <jeff@docker.com> Jeff Anderson <jeff@docker.com>
Jeff Johnston <jeff.johnston.mn@gmail.com> Jeff Johnston <jeff.johnston.mn@gmail.com>
Jeff Lindsay <progrium@gmail.com> Jeff Lindsay <progrium@gmail.com>
@@ -803,6 +823,7 @@ Jeremy Price <jprice.rhit@gmail.com>
Jeremy Qian <vanpire110@163.com> Jeremy Qian <vanpire110@163.com>
Jeremy Unruh <jeremybunruh@gmail.com> Jeremy Unruh <jeremybunruh@gmail.com>
Jeremy Yallop <yallop@docker.com> Jeremy Yallop <yallop@docker.com>
Jeroen Franse <jeroenfranse@gmail.com>
Jeroen Jacobs <github@jeroenj.be> Jeroen Jacobs <github@jeroenj.be>
Jesse Dearing <jesse.dearing@gmail.com> Jesse Dearing <jesse.dearing@gmail.com>
Jesse Dubay <jesse@thefortytwo.net> Jesse Dubay <jesse@thefortytwo.net>
@@ -814,6 +835,7 @@ Ji.Zhilong <zhilongji@gmail.com>
Jian Zhang <zhangjian.fnst@cn.fujitsu.com> Jian Zhang <zhangjian.fnst@cn.fujitsu.com>
jianbosun <wonderflow.sun@gmail.com> jianbosun <wonderflow.sun@gmail.com>
Jie Luo <luo612@zju.edu.cn> Jie Luo <luo612@zju.edu.cn>
Jihyun Hwang <jhhwang@telcoware.com>
Jilles Oldenbeuving <ojilles@gmail.com> Jilles Oldenbeuving <ojilles@gmail.com>
Jim Alateras <jima@comware.com.au> Jim Alateras <jima@comware.com.au>
Jim Galasyn <jim.galasyn@docker.com> Jim Galasyn <jim.galasyn@docker.com>
@@ -880,10 +902,11 @@ Jonathan Stoppani <jonathan.stoppani@divio.com>
Jonh Wendell <jonh.wendell@redhat.com> Jonh Wendell <jonh.wendell@redhat.com>
Joni Sar <yoni@cocycles.com> Joni Sar <yoni@cocycles.com>
Joost Cassee <joost@cassee.net> Joost Cassee <joost@cassee.net>
Jordan <jjn2009@users.noreply.github.com>
Jordan Arentsen <blissdev@gmail.com> Jordan Arentsen <blissdev@gmail.com>
Jordan Jennings <jjn2009@gmail.com>
Jordan Sissel <jls@semicomplete.com> Jordan Sissel <jls@semicomplete.com>
Jorge Marin <chipironcin@users.noreply.github.com> Jorge Marin <chipironcin@users.noreply.github.com>
Jorit Kleine-Möllhoff <joppich@bricknet.de>
Jose Diaz-Gonzalez <jose@seatgeek.com> Jose Diaz-Gonzalez <jose@seatgeek.com>
Joseph Anthony Pasquale Holsten <joseph@josephholsten.com> Joseph Anthony Pasquale Holsten <joseph@josephholsten.com>
Joseph Hager <ajhager@gmail.com> Joseph Hager <ajhager@gmail.com>
@@ -900,9 +923,8 @@ Josh Soref <jsoref@gmail.com>
Josh Wilson <josh.wilson@fivestars.com> Josh Wilson <josh.wilson@fivestars.com>
Josiah Kiehl <jkiehl@riotgames.com> Josiah Kiehl <jkiehl@riotgames.com>
José Tomás Albornoz <jojo@eljojo.net> José Tomás Albornoz <jojo@eljojo.net>
Joyce Jang <mail@joycejang.com>
JP <jpellerin@leapfrogonline.com> JP <jpellerin@leapfrogonline.com>
jrabbit <jackjrabbit@gmail.com>
jroenf <jeroenfranse@gmail.com>
Julian Taylor <jtaylor.debian@googlemail.com> Julian Taylor <jtaylor.debian@googlemail.com>
Julien Barbier <write0@gmail.com> Julien Barbier <write0@gmail.com>
Julien Bisconti <veggiemonk@users.noreply.github.com> Julien Bisconti <veggiemonk@users.noreply.github.com>
@@ -927,9 +949,9 @@ Jérôme Petazzoni <jerome.petazzoni@docker.com>
Jörg Thalheim <joerg@higgsboson.tk> Jörg Thalheim <joerg@higgsboson.tk>
K. Heller <pestophagous@gmail.com> K. Heller <pestophagous@gmail.com>
Kai Blin <kai@samba.org> Kai Blin <kai@samba.org>
Kai Qiang Wu(Kennan) <wkq5325@gmail.com> Kai Qiang Wu (Kennan) <wkq5325@gmail.com>
Kamil Domański <kamil@domanski.co> Kamil Domański <kamil@domanski.co>
kamjar gerami <kami.gerami@gmail.com> Kamjar Gerami <kami.gerami@gmail.com>
Kanstantsin Shautsou <kanstantsin.sha@gmail.com> Kanstantsin Shautsou <kanstantsin.sha@gmail.com>
Kara Alexandra <kalexandra@us.ibm.com> Kara Alexandra <kalexandra@us.ibm.com>
Karan Lyons <karan@karanlyons.com> Karan Lyons <karan@karanlyons.com>
@@ -938,6 +960,7 @@ kargakis <kargakis@users.noreply.github.com>
Karl Grzeszczak <karlgrz@gmail.com> Karl Grzeszczak <karlgrz@gmail.com>
Karol Duleba <mr.fuxi@gmail.com> Karol Duleba <mr.fuxi@gmail.com>
Karthik Nayak <Karthik.188@gmail.com> Karthik Nayak <Karthik.188@gmail.com>
Kate Heddleston <kate.heddleston@gmail.com>
Katie McLaughlin <katie@glasnt.com> Katie McLaughlin <katie@glasnt.com>
Kato Kazuyoshi <kato.kazuyoshi@gmail.com> Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
Katrina Owen <katrina.owen@gmail.com> Katrina Owen <katrina.owen@gmail.com>
@@ -1025,6 +1048,7 @@ Levi Gross <levi@levigross.com>
Lewis Daly <lewisdaly@me.com> Lewis Daly <lewisdaly@me.com>
Lewis Marshall <lewis@lmars.net> Lewis Marshall <lewis@lmars.net>
Lewis Peckover <lew+github@lew.io> Lewis Peckover <lew+github@lew.io>
Li Yi <denverdino@gmail.com>
Liam Macgillavry <liam@kumina.nl> Liam Macgillavry <liam@kumina.nl>
Liana Lo <liana.lixia@gmail.com> Liana Lo <liana.lixia@gmail.com>
Liang Mingqiang <mqliang.zju@gmail.com> Liang Mingqiang <mqliang.zju@gmail.com>
@@ -1056,6 +1080,7 @@ Luca Orlandi <luca.orlandi@gmail.com>
Luca-Bogdan Grigorescu <Luca-Bogdan Grigorescu> Luca-Bogdan Grigorescu <Luca-Bogdan Grigorescu>
Lucas Chan <lucas-github@lucaschan.com> Lucas Chan <lucas-github@lucaschan.com>
Lucas Chi <lucas@teacherspayteachers.com> Lucas Chi <lucas@teacherspayteachers.com>
Lucas Molas <lmolas@fundacionsadosky.org.ar>
Luciano Mores <leslau@gmail.com> Luciano Mores <leslau@gmail.com>
Luis Martínez de Bartolomé Izquierdo <lmartinez@biicode.com> Luis Martínez de Bartolomé Izquierdo <lmartinez@biicode.com>
Luiz Svoboda <luizek@gmail.com> Luiz Svoboda <luizek@gmail.com>
@@ -1087,11 +1112,13 @@ Marc Abramowitz <marc@marc-abramowitz.com>
Marc Kuo <kuomarc2@gmail.com> Marc Kuo <kuomarc2@gmail.com>
Marc Tamsky <mtamsky@gmail.com> Marc Tamsky <mtamsky@gmail.com>
Marcel Edmund Franke <marcel.edmund.franke@gmail.com> Marcel Edmund Franke <marcel.edmund.franke@gmail.com>
Marcelo Horacio Fortino <info@fortinux.com>
Marcelo Salazar <chelosalazar@gmail.com> Marcelo Salazar <chelosalazar@gmail.com>
Marco Hennings <marco.hennings@freiheit.com> Marco Hennings <marco.hennings@freiheit.com>
Marcus Cobden <mcobden@cisco.com> Marcus Cobden <mcobden@cisco.com>
Marcus Farkas <toothlessgear@finitebox.com> Marcus Farkas <toothlessgear@finitebox.com>
Marcus Linke <marcus.linke@gmx.de> Marcus Linke <marcus.linke@gmx.de>
Marcus Martins <marcus@docker.com>
Marcus Ramberg <marcus@nordaaker.com> Marcus Ramberg <marcus@nordaaker.com>
Marek Goldmann <marek.goldmann@gmail.com> Marek Goldmann <marek.goldmann@gmail.com>
Marian Marinov <mm@yuhu.biz> Marian Marinov <mm@yuhu.biz>
@@ -1204,6 +1231,7 @@ Mike Chelen <michael.chelen@gmail.com>
Mike Danese <mikedanese@google.com> Mike Danese <mikedanese@google.com>
Mike Dillon <mike@embody.org> Mike Dillon <mike@embody.org>
Mike Dougherty <mike.dougherty@docker.com> Mike Dougherty <mike.dougherty@docker.com>
Mike Estes <mike.estes@logos.com>
Mike Gaffney <mike@uberu.com> Mike Gaffney <mike@uberu.com>
Mike Goelzer <mike.goelzer@docker.com> Mike Goelzer <mike.goelzer@docker.com>
Mike Leone <mleone896@gmail.com> Mike Leone <mleone896@gmail.com>
@@ -1219,6 +1247,7 @@ mingqing <limingqing@cyou-inc.com>
Mingzhen Feng <fmzhen@zju.edu.cn> Mingzhen Feng <fmzhen@zju.edu.cn>
Misty Stanley-Jones <misty@docker.com> Misty Stanley-Jones <misty@docker.com>
Mitch Capper <mitch.capper@gmail.com> Mitch Capper <mitch.capper@gmail.com>
Mizuki Urushida <z11111001011@gmail.com>
mlarcher <github@ringabell.org> mlarcher <github@ringabell.org>
Mohammad Banikazemi <mb@us.ibm.com> Mohammad Banikazemi <mb@us.ibm.com>
Mohammed Aaqib Ansari <maaquib@gmail.com> Mohammed Aaqib Ansari <maaquib@gmail.com>
@@ -1262,20 +1291,21 @@ Neyazul Haque <nuhaque@gmail.com>
Nghia Tran <nghia@google.com> Nghia Tran <nghia@google.com>
Niall O'Higgins <niallo@unworkable.org> Niall O'Higgins <niallo@unworkable.org>
Nicholas E. Rabenau <nerab@gmx.at> Nicholas E. Rabenau <nerab@gmx.at>
nick <nicholasjamesrusso@gmail.com>
Nick DeCoursin <n.decoursin@foodpanda.com> Nick DeCoursin <n.decoursin@foodpanda.com>
Nick Irvine <nfirvine@nfirvine.com> Nick Irvine <nfirvine@nfirvine.com>
Nick Parker <nikaios@gmail.com> Nick Parker <nikaios@gmail.com>
Nick Payne <nick@kurai.co.uk> Nick Payne <nick@kurai.co.uk>
Nick Russo <nicholasjamesrusso@gmail.com>
Nick Stenning <nick.stenning@digital.cabinet-office.gov.uk> Nick Stenning <nick.stenning@digital.cabinet-office.gov.uk>
Nick Stinemates <nick@stinemates.org> Nick Stinemates <nick@stinemates.org>
NickrenREN <yuquan.ren@easystack.cn> NickrenREN <yuquan.ren@easystack.cn>
Nicola Kabar <nicolaka@gmail.com> Nicola Kabar <nicolaka@gmail.com>
Nicolas Borboën <ponsfrilus@users.noreply.github.com> Nicolas Borboën <ponsfrilus@users.noreply.github.com>
Nicolas De loof <nicolas.deloof@gmail.com> Nicolas De Loof <nicolas.deloof@gmail.com>
Nicolas Dudebout <nicolas.dudebout@gatech.edu> Nicolas Dudebout <nicolas.dudebout@gatech.edu>
Nicolas Goy <kuon@goyman.com> Nicolas Goy <kuon@goyman.com>
Nicolas Kaiser <nikai@nikai.net> Nicolas Kaiser <nikai@nikai.net>
Nicolas Sterchele <sterchele.nicolas@gmail.com>
Nicolás Hock Isaza <nhocki@gmail.com> Nicolás Hock Isaza <nhocki@gmail.com>
Nigel Poulton <nigelpoulton@hotmail.com> Nigel Poulton <nigelpoulton@hotmail.com>
Nik Nyby <nikolas@gnu.org> Nik Nyby <nikolas@gnu.org>
@@ -1391,7 +1421,6 @@ Prayag Verma <prayag.verma@gmail.com>
Przemek Hejman <przemyslaw.hejman@gmail.com> Przemek Hejman <przemyslaw.hejman@gmail.com>
Pure White <daniel48@126.com> Pure White <daniel48@126.com>
pysqz <randomq@126.com> pysqz <randomq@126.com>
qhuang <h.huangqiang@huawei.com>
Qiang Huang <h.huangqiang@huawei.com> Qiang Huang <h.huangqiang@huawei.com>
Qinglan Peng <qinglanpeng@zju.edu.cn> Qinglan Peng <qinglanpeng@zju.edu.cn>
qudongfang <qudongfang@gmail.com> qudongfang <qudongfang@gmail.com>
@@ -1422,6 +1451,7 @@ Remy Suen <remy.suen@gmail.com>
Renato Riccieri Santos Zannon <renato.riccieri@gmail.com> Renato Riccieri Santos Zannon <renato.riccieri@gmail.com>
Renaud Gaubert <rgaubert@nvidia.com> Renaud Gaubert <rgaubert@nvidia.com>
Rhys Hiltner <rhys@twitch.tv> Rhys Hiltner <rhys@twitch.tv>
Ri Xu <xuri.me@gmail.com>
Ricardo N Feliciano <FelicianoTech@gmail.com> Ricardo N Feliciano <FelicianoTech@gmail.com>
Rich Moyse <rich@moyse.us> Rich Moyse <rich@moyse.us>
Rich Seymour <rseymour@gmail.com> Rich Seymour <rseymour@gmail.com>
@@ -1493,6 +1523,7 @@ Ryan Liu <ryanlyy@me.com>
Ryan McLaughlin <rmclaughlin@insidesales.com> Ryan McLaughlin <rmclaughlin@insidesales.com>
Ryan O'Donnell <odonnellryanc@gmail.com> Ryan O'Donnell <odonnellryanc@gmail.com>
Ryan Seto <ryanseto@yak.net> Ryan Seto <ryanseto@yak.net>
Ryan Simmen <ryan.simmen@gmail.com>
Ryan Thomas <rthomas@atlassian.com> Ryan Thomas <rthomas@atlassian.com>
Ryan Trauntvein <rtrauntvein@novacoast.com> Ryan Trauntvein <rtrauntvein@novacoast.com>
Ryan Wallner <ryan.wallner@clusterhq.com> Ryan Wallner <ryan.wallner@clusterhq.com>
@@ -1526,6 +1557,7 @@ Sankar சங்கர் <sankar.curiosity@gmail.com>
Sanket Saurav <sanketsaurav@gmail.com> Sanket Saurav <sanketsaurav@gmail.com>
Santhosh Manohar <santhosh@docker.com> Santhosh Manohar <santhosh@docker.com>
sapphiredev <se.imas.kr@gmail.com> sapphiredev <se.imas.kr@gmail.com>
Sargun Dhillon <sargun@netflix.com>
Sascha Andres <sascha.andres@outlook.com> Sascha Andres <sascha.andres@outlook.com>
Satnam Singh <satnam@raintown.org> Satnam Singh <satnam@raintown.org>
Satoshi Amemiya <satoshi_amemiya@voyagegroup.com> Satoshi Amemiya <satoshi_amemiya@voyagegroup.com>
@@ -1569,6 +1601,7 @@ Shengbo Song <thomassong@tencent.com>
Shev Yan <yandong_8212@163.com> Shev Yan <yandong_8212@163.com>
Shih-Yuan Lee <fourdollars@gmail.com> Shih-Yuan Lee <fourdollars@gmail.com>
Shijiang Wei <mountkin@gmail.com> Shijiang Wei <mountkin@gmail.com>
Shijun Qin <qinshijun16@mails.ucas.ac.cn>
Shishir Mahajan <shishir.mahajan@redhat.com> Shishir Mahajan <shishir.mahajan@redhat.com>
Shoubhik Bose <sbose78@gmail.com> Shoubhik Bose <sbose78@gmail.com>
Shourya Sarcar <shourya.sarcar@gmail.com> Shourya Sarcar <shourya.sarcar@gmail.com>
@@ -1641,7 +1674,7 @@ Tabakhase <mail@tabakhase.com>
Tadej Janež <tadej.j@nez.si> Tadej Janež <tadej.j@nez.si>
TAGOMORI Satoshi <tagomoris@gmail.com> TAGOMORI Satoshi <tagomoris@gmail.com>
tang0th <tang0th@gmx.com> tang0th <tang0th@gmx.com>
Tangi COLIN <tangicolin@gmail.com> Tangi Colin <tangicolin@gmail.com>
Tatsuki Sugiura <sugi@nemui.org> Tatsuki Sugiura <sugi@nemui.org>
Tatsushi Inagaki <e29253@jp.ibm.com> Tatsushi Inagaki <e29253@jp.ibm.com>
Taylor Jones <monitorjbl@gmail.com> Taylor Jones <monitorjbl@gmail.com>
@@ -1662,7 +1695,7 @@ Thomas Gazagnaire <thomas@gazagnaire.org>
Thomas Grainger <tagrain@gmail.com> Thomas Grainger <tagrain@gmail.com>
Thomas Hansen <thomas.hansen@gmail.com> Thomas Hansen <thomas.hansen@gmail.com>
Thomas Leonard <thomas.leonard@docker.com> Thomas Leonard <thomas.leonard@docker.com>
Thomas LEVEIL <thomasleveil@gmail.com> Thomas Léveil <thomasleveil@gmail.com>
Thomas Orozco <thomas@orozco.fr> Thomas Orozco <thomas@orozco.fr>
Thomas Riccardi <riccardi@systran.fr> Thomas Riccardi <riccardi@systran.fr>
Thomas Schroeter <thomas@cliqz.com> Thomas Schroeter <thomas@cliqz.com>
@@ -1744,6 +1777,7 @@ Tyler Brock <tyler.brock@gmail.com>
Tzu-Jung Lee <roylee17@gmail.com> Tzu-Jung Lee <roylee17@gmail.com>
uhayate <uhayate.gong@daocloud.io> uhayate <uhayate.gong@daocloud.io>
Ulysse Carion <ulyssecarion@gmail.com> Ulysse Carion <ulyssecarion@gmail.com>
Umesh Yadav <umesh4257@gmail.com>
Utz Bacher <utz.bacher@de.ibm.com> Utz Bacher <utz.bacher@de.ibm.com>
vagrant <vagrant@ubuntu-14.04-amd64-vbox> vagrant <vagrant@ubuntu-14.04-amd64-vbox>
Vaidas Jablonskis <jablonskis@gmail.com> Vaidas Jablonskis <jablonskis@gmail.com>
@@ -1763,7 +1797,6 @@ Viktor Stanchev <me@viktorstanchev.com>
Viktor Vojnovski <viktor.vojnovski@amadeus.com> Viktor Vojnovski <viktor.vojnovski@amadeus.com>
VinayRaghavanKS <raghavan.vinay@gmail.com> VinayRaghavanKS <raghavan.vinay@gmail.com>
Vincent Batts <vbatts@redhat.com> Vincent Batts <vbatts@redhat.com>
Vincent Bernat <bernat@luffy.cx>
Vincent Bernat <Vincent.Bernat@exoscale.ch> Vincent Bernat <Vincent.Bernat@exoscale.ch>
Vincent Demeester <vincent.demeester@docker.com> Vincent Demeester <vincent.demeester@docker.com>
Vincent Giersch <vincent.giersch@ovh.net> Vincent Giersch <vincent.giersch@ovh.net>
@@ -1837,7 +1870,6 @@ xiekeyang <xiekeyang@huawei.com>
Xinbo Weng <xihuanbo_0521@zju.edu.cn> Xinbo Weng <xihuanbo_0521@zju.edu.cn>
Xinzi Zhou <imdreamrunner@gmail.com> Xinzi Zhou <imdreamrunner@gmail.com>
Xiuming Chen <cc@cxm.cc> Xiuming Chen <cc@cxm.cc>
xlgao-zju <xlgao@zju.edu.cn>
Xuecong Liao <satorulogic@gmail.com> Xuecong Liao <satorulogic@gmail.com>
xuzhaokui <cynicholas@gmail.com> xuzhaokui <cynicholas@gmail.com>
Yahya <ya7yaz@gmail.com> Yahya <ya7yaz@gmail.com>
@@ -1851,6 +1883,7 @@ Yanqiang Miao <miao.yanqiang@zte.com.cn>
Yao Zaiyong <yaozaiyong@hotmail.com> Yao Zaiyong <yaozaiyong@hotmail.com>
Yassine Tijani <yasstij11@gmail.com> Yassine Tijani <yasstij11@gmail.com>
Yasunori Mahata <nori@mahata.net> Yasunori Mahata <nori@mahata.net>
Yazhong Liu <yorkiefixer@gmail.com>
Yestin Sun <sunyi0804@gmail.com> Yestin Sun <sunyi0804@gmail.com>
Yi EungJun <eungjun.yi@navercorp.com> Yi EungJun <eungjun.yi@navercorp.com>
Yibai Zhang <xm1994@gmail.com> Yibai Zhang <xm1994@gmail.com>
@@ -1859,7 +1892,7 @@ Ying Li <ying.li@docker.com>
Yohei Ueda <yohei@jp.ibm.com> Yohei Ueda <yohei@jp.ibm.com>
Yong Tang <yong.tang.github@outlook.com> Yong Tang <yong.tang.github@outlook.com>
Yongzhi Pan <panyongzhi@gmail.com> Yongzhi Pan <panyongzhi@gmail.com>
yorkie <yorkiefixer@gmail.com> Yosef Fertel <yfertel@gmail.com>
You-Sheng Yang (楊有勝) <vicamo@gmail.com> You-Sheng Yang (楊有勝) <vicamo@gmail.com>
Youcef YEKHLEF <yyekhlef@gmail.com> Youcef YEKHLEF <yyekhlef@gmail.com>
Yu Changchun <yuchangchun1@huawei.com> Yu Changchun <yuchangchun1@huawei.com>
@@ -1871,10 +1904,10 @@ Yuanhong Peng <pengyuanhong@huawei.com>
Yuhao Fang <fangyuhao@gmail.com> Yuhao Fang <fangyuhao@gmail.com>
Yunxiang Huang <hyxqshk@vip.qq.com> Yunxiang Huang <hyxqshk@vip.qq.com>
Yurii Rashkovskii <yrashk@gmail.com> Yurii Rashkovskii <yrashk@gmail.com>
yuzou <zouyu7@huawei.com> Yves Junqueira <yves.junqueira@gmail.com>
Zac Dover <zdover@redhat.com> Zac Dover <zdover@redhat.com>
Zach Borboa <zachborboa@gmail.com> Zach Borboa <zachborboa@gmail.com>
Zachary Jaffee <zij@case.edu> Zachary Jaffee <zjaffee@us.ibm.com>
Zain Memon <zain@inzain.net> Zain Memon <zain@inzain.net>
Zaiste! <oh@zaiste.net> Zaiste! <oh@zaiste.net>
Zane DeGraffenried <zane.deg@gmail.com> Zane DeGraffenried <zane.deg@gmail.com>
@@ -1898,6 +1931,7 @@ Ziming Dong <bnudzm@foxmail.com>
ZJUshuaizhou <21551191@zju.edu.cn> ZJUshuaizhou <21551191@zju.edu.cn>
zmarouf <zeid.marouf@gmail.com> zmarouf <zeid.marouf@gmail.com>
Zoltan Tombol <zoltan.tombol@gmail.com> Zoltan Tombol <zoltan.tombol@gmail.com>
Zou Yu <zouyu7@huawei.com>
zqh <zqhxuyuan@gmail.com> zqh <zqhxuyuan@gmail.com>
Zuhayr Elahi <elahi.zuhayr@gmail.com> Zuhayr Elahi <elahi.zuhayr@gmail.com>
Zunayed Ali <zunayed@gmail.com> Zunayed Ali <zunayed@gmail.com>
@@ -1907,3 +1941,4 @@ Zunayed Ali <zunayed@gmail.com>
尹吉峰 <jifeng.yin@gmail.com> 尹吉峰 <jifeng.yin@gmail.com>
徐俊杰 <paco.xu@daocloud.io> 徐俊杰 <paco.xu@daocloud.io>
搏通 <yufeng.pyf@alibaba-inc.com> 搏通 <yufeng.pyf@alibaba-inc.com>
黄艳红00139573 <huang.yanhong@zte.com.cn>

View File

@@ -303,14 +303,43 @@ commit automatically with `git commit -s`.
### How can I become a maintainer? ### How can I become a maintainer?
The procedures for adding new maintainers are explained in the The procedures for adding new maintainers are explained in the
global [MAINTAINERS](https://github.com/docker/opensource/blob/master/MAINTAINERS) [/project/GOVERNANCE.md](/project/GOVERNANCE.md)
file in the [https://github.com/docker/opensource/](https://github.com/docker/opensource/) file in this repository.
repository.
Don't forget: being a maintainer is a time investment. Make sure you Don't forget: being a maintainer is a time investment. Make sure you
will have time to make yourself available. You don't have to be a will have time to make yourself available. You don't have to be a
maintainer to make a difference on the project! maintainer to make a difference on the project!
### Manage issues and pull requests using the Derek bot
If you want to help label, assign, close or reopen issues or pull requests
without commit rights, ask a maintainer to add your Github handle to the
`.DEREK.yml` file. [Derek](https://github.com/alexellis/derek) is a bot that extends
Github's user permissions to help non-committers to manage issues and pull requests simply by commenting.
For example:
* Labels
```
Derek add label: kind/question
Derek remove label: status/claimed
```
* Assign work
```
Derek assign: username
Derek unassign: me
```
* Manage issues and PRs
```
Derek close
Derek reopen
```
## Moby community guidelines ## Moby community guidelines
We want to keep the Moby community awesome, growing and collaborative. We need We want to keep the Moby community awesome, growing and collaborative. We need
@@ -341,6 +370,11 @@ guidelines for the community as a whole:
used to ping maintainers to review a pull request, a proposal or an used to ping maintainers to review a pull request, a proposal or an
issue. issue.
The open source governance for this repository is handled via the [Moby Technical Steering Committee (TSC)](https://github.com/moby/tsc)
charter. For any concerns with the community process regarding technical contributions,
please contact the TSC. More information on project governance is available in
our [project/GOVERNANCE.md](/project/GOVERNANCE.md) document.
### Guideline violations — 3 strikes method ### Guideline violations — 3 strikes method
The point of this section is not to find opportunities to punish people, but we The point of this section is not to find opportunities to punish people, but we

View File

@@ -52,6 +52,7 @@ RUN apt-get update && apt-get install -y \
libapparmor-dev \ libapparmor-dev \
libcap-dev \ libcap-dev \
libdevmapper-dev \ libdevmapper-dev \
libnet-dev \
libnl-3-dev \ libnl-3-dev \
libprotobuf-c0-dev \ libprotobuf-c0-dev \
libprotobuf-dev \ libprotobuf-dev \
@@ -61,6 +62,7 @@ RUN apt-get update && apt-get install -y \
libudev-dev \ libudev-dev \
mercurial \ mercurial \
net-tools \ net-tools \
pigz \
pkg-config \ pkg-config \
protobuf-compiler \ protobuf-compiler \
protobuf-c-compiler \ protobuf-c-compiler \
@@ -86,7 +88,7 @@ RUN apt-get update && apt-get install -y \
# will need updating, to avoid errors. Ping #docker-maintainers on IRC # will need updating, to avoid errors. Ping #docker-maintainers on IRC
# with a heads-up. # with a heads-up.
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \ RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
| tar -xzC /usr/local | tar -xzC /usr/local
@@ -94,11 +96,9 @@ ENV PATH /go/bin:/usr/local/go/bin:$PATH
ENV GOPATH /go ENV GOPATH /go
# Install CRIU for checkpoint/restore support # Install CRIU for checkpoint/restore support
ENV CRIU_VERSION 2.12.1 ENV CRIU_VERSION 3.6
# Install dependancy packages specific to criu RUN mkdir -p /usr/src/criu \
RUN apt-get install libnet-dev -y && \ && curl -sSL https://github.com/checkpoint-restore/criu/archive/v${CRIU_VERSION}.tar.gz | tar -C /usr/src/criu/ -xz --strip-components=1 \
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 \
&& cd /usr/src/criu \ && cd /usr/src/criu \
&& make \ && make \
&& make install-criu && make install-criu
@@ -168,11 +168,12 @@ RUN echo "source $PWD/hack/make/.integration-test-helpers" >> /etc/bash.bashrc
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling # Get useful and necessary Hub images so we can "docker load" locally instead of pulling
COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/
# TODO: when issue #35963 fixed, we can upgrade the busybox to multi-arch
RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
buildpack-deps:jessie@sha256:85b379ec16065e4fe4127eb1c5fb1bcc03c559bd36dbb2e22ff496de55925fa6 \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
busybox:latest@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f \ busybox:latest@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f \
debian:jessie@sha256:72f784399fd2719b4cb4e16ef8e369a39dc67f53d978cd3e2e7bf4e502c7b793 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
hello-world:latest@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7 hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
# See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list)
# Install tomlv, vndr, runc, containerd, tini, docker-proxy dockercli # Install tomlv, vndr, runc, containerd, tini, docker-proxy dockercli
@@ -190,7 +191,7 @@ RUN ln -s /usr/local/completion/bash/docker /etc/bash_completion.d/docker
ENTRYPOINT ["hack/dind"] ENTRYPOINT ["hack/dind"]
# Options for hack/validate/gometalinter # Options for hack/validate/gometalinter
ENV GOMETALINTER_OPTS="--deadline 2m" ENV GOMETALINTER_OPTS="--deadline=2m"
# Upload docker source # Upload docker source
COPY . /go/src/github.com/docker/docker COPY . /go/src/github.com/docker/docker

View File

@@ -15,7 +15,7 @@
# the case. Therefore, you don't have to disable it anymore. # the case. Therefore, you don't have to disable it anymore.
# #
FROM arm64v8/debian:stretch FROM debian:stretch
# allow replacing httpredir or deb mirror # allow replacing httpredir or deb mirror
ARG APT_MIRROR=deb.debian.org ARG APT_MIRROR=deb.debian.org
@@ -52,6 +52,7 @@ RUN apt-get update && apt-get install -y \
libudev-dev \ libudev-dev \
mercurial \ mercurial \
net-tools \ net-tools \
pigz \
pkg-config \ pkg-config \
protobuf-compiler \ protobuf-compiler \
protobuf-c-compiler \ protobuf-c-compiler \
@@ -73,7 +74,7 @@ RUN apt-get update && apt-get install -y \
# Install Go # Install Go
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" \ RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" \
| tar -xzC /usr/local | tar -xzC /usr/local
@@ -142,10 +143,10 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling # Get useful and necessary Hub images so we can "docker load" locally instead of pulling
COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/
RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
aarch64/buildpack-deps:jessie@sha256:107f4a96837ed89c493fc205cd28508ed0b6b680b4bf3e514e9f0fa0f6667b77 \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
aarch64/busybox:latest@sha256:5a06b8b2fdf22dd1f4085c6c3efd23ee99af01b2d668d286bc4be6d8baa10efb \ busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \
aarch64/debian:jessie@sha256:e6f90b568631705bd5cb27490977378ba762792b38d47c91c4da7a539f63079a \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
aarch64/hello-world:latest@sha256:bd1722550b97668b23ede297abf824d4855f4d9f600dab7b4db1a963dae7ec9e hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
# See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list)
# Install tomlv, vndr, runc, containerd, tini, docker-proxy # Install tomlv, vndr, runc, containerd, tini, docker-proxy
@@ -159,7 +160,7 @@ ENV PATH=/usr/local/cli:$PATH
ENTRYPOINT ["hack/dind"] ENTRYPOINT ["hack/dind"]
# Options for hack/validate/gometalinter # Options for hack/validate/gometalinter
ENV GOMETALINTER_OPTS="--deadline 4m -j2" ENV GOMETALINTER_OPTS="--deadline=4m -j2"
# Upload docker source # Upload docker source
COPY . /go/src/github.com/docker/docker COPY . /go/src/github.com/docker/docker

View File

@@ -45,6 +45,7 @@ RUN apt-get update && apt-get install -y \
libtool \ libtool \
libudev-dev \ libudev-dev \
mercurial \ mercurial \
pigz \
pkg-config \ pkg-config \
python-backports.ssl-match-hostname \ python-backports.ssl-match-hostname \
python-dev \ python-dev \
@@ -63,7 +64,7 @@ RUN apt-get update && apt-get install -y \
# Install Go # Install Go
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" \ RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-armv6l.tar.gz" \
| tar -xzC /usr/local | tar -xzC /usr/local
ENV PATH /go/bin:/usr/local/go/bin:$PATH ENV PATH /go/bin:/usr/local/go/bin:$PATH
@@ -131,10 +132,10 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling # Get useful and necessary Hub images so we can "docker load" locally instead of pulling
COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/
RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
armhf/buildpack-deps:jessie@sha256:eb2dad77ef53e88d94c3c83862d315c806ea1ca49b6e74f4db362381365ce489 \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
armhf/busybox:latest@sha256:016a1e149d2acc2a3789a160dfa60ce870794eea27ad5e96f7a101970e5e1689 \ busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \
armhf/debian:jessie@sha256:ac59fa18b28d0ef751eabb5ba4c4b5a9063f99398bae2f70495aa8ed6139b577 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
armhf/hello-world:latest@sha256:9701edc932223a66e49dd6c894a11db8c2cf4eccd1414f1ec105a623bf16b426 hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
# See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list)
# Install tomlv, vndr, runc, containerd, tini, docker-proxy # Install tomlv, vndr, runc, containerd, tini, docker-proxy
@@ -147,7 +148,7 @@ ENV PATH=/usr/local/cli:$PATH
ENTRYPOINT ["hack/dind"] ENTRYPOINT ["hack/dind"]
# Options for hack/validate/gometalinter # Options for hack/validate/gometalinter
ENV GOMETALINTER_OPTS="--deadline 10m -j2" ENV GOMETALINTER_OPTS="--deadline=10m -j2"
# Upload docker source # Upload docker source
COPY . /go/src/github.com/docker/docker COPY . /go/src/github.com/docker/docker

View File

@@ -1,5 +1,5 @@
## Step 1: Build tests ## Step 1: Build tests
FROM golang:1.8.5-alpine3.6 as builder FROM golang:1.9.2-alpine3.6 as builder
RUN apk add --update \ RUN apk add --update \
bash \ bash \
@@ -16,10 +16,10 @@ WORKDIR /go/src/github.com/docker/docker/
# Generate frozen images # Generate frozen images
COPY contrib/download-frozen-image-v2.sh contrib/download-frozen-image-v2.sh COPY contrib/download-frozen-image-v2.sh contrib/download-frozen-image-v2.sh
RUN contrib/download-frozen-image-v2.sh /output/docker-frozen-images \ RUN contrib/download-frozen-image-v2.sh /output/docker-frozen-images \
buildpack-deps:jessie@sha256:85b379ec16065e4fe4127eb1c5fb1bcc03c559bd36dbb2e22ff496de55925fa6 \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
busybox:latest@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f \ busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \
debian:jessie@sha256:72f784399fd2719b4cb4e16ef8e369a39dc67f53d978cd3e2e7bf4e502c7b793 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
hello-world:latest@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7 hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
# Download Docker CLI binary # Download Docker CLI binary
COPY hack/dockerfile hack/dockerfile COPY hack/dockerfile hack/dockerfile
@@ -47,6 +47,7 @@ RUN apk add --update \
g++ \ g++ \
git \ git \
iptables \ iptables \
pigz \
tar \ tar \
xz \ xz \
&& rm -rf /var/cache/apk/* && rm -rf /var/cache/apk/*

View File

@@ -46,6 +46,7 @@ RUN apt-get update && apt-get install -y \
libtool \ libtool \
libudev-dev \ libudev-dev \
mercurial \ mercurial \
pigz \
pkg-config \ pkg-config \
python-backports.ssl-match-hostname \ python-backports.ssl-match-hostname \
python-dev \ python-dev \
@@ -64,7 +65,7 @@ RUN apt-get update && apt-get install -y \
# Install Go # Install Go
# NOTE: official ppc64le go binaries weren't available until go 1.6.4 and 1.7.4 # NOTE: official ppc64le go binaries weren't available until go 1.6.4 and 1.7.4
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" \ RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-ppc64le.tar.gz" \
| tar -xzC /usr/local | tar -xzC /usr/local
@@ -129,10 +130,10 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling # Get useful and necessary Hub images so we can "docker load" locally instead of pulling
COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/
RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
ppc64le/buildpack-deps:jessie@sha256:1a2f2d2cc8738f14b336aeffc3503b5c9dedf9e1f26c7313cb4999534ad4716f \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
ppc64le/busybox:latest@sha256:54f34c83adfab20cf0e630d879e210f07b0062cd6caaf16346a61396d50e7584 \ busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \
ppc64le/debian:jessie@sha256:ea8c5b105e3790f075145b40e4be1e4488c9f33f55e6cc45182047b80a68f892 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
ppc64le/hello-world:latest@sha256:7d57adf137665f748956c86089320710b66d08584db3500ed98f4bb3da637c2d hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
# See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list)
# Install tomlv, vndr, runc, containerd, tini, docker-proxy # Install tomlv, vndr, runc, containerd, tini, docker-proxy

View File

@@ -42,6 +42,7 @@ RUN apt-get update && apt-get install -y \
libtool \ libtool \
libudev-dev \ libudev-dev \
mercurial \ mercurial \
pigz \
pkg-config \ pkg-config \
python-backports.ssl-match-hostname \ python-backports.ssl-match-hostname \
python-dev \ python-dev \
@@ -58,7 +59,7 @@ RUN apt-get update && apt-get install -y \
--no-install-recommends --no-install-recommends
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" \ RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" \
| tar -xzC /usr/local | tar -xzC /usr/local
@@ -123,10 +124,10 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling # Get useful and necessary Hub images so we can "docker load" locally instead of pulling
COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/
RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
s390x/buildpack-deps:jessie@sha256:552dec28146e4d2591fc0309aebdbac9e4fb1f335d90c70a14bbf72fb8bb1be5 \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
s390x/busybox:latest@sha256:e32f40c39ca596a4317392bd32809bb188c4ae5864ea827c3219c75c50069964 \ busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \
s390x/debian:jessie@sha256:6994e3ffa5a1dabea09d536f350b3ed2715292cb469417c42a82b70fcbff7d32 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
s390x/hello-world:latest@sha256:602db500fee63934292260e65c0c528128ad1c1c7c6497f95bbbac7d4d5312f1 hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
# See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list)
# Install tomlv, vndr, runc, containerd, tini, docker-proxy # Install tomlv, vndr, runc, containerd, tini, docker-proxy

View File

@@ -27,6 +27,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \ ca-certificates \
e2fsprogs \ e2fsprogs \
iptables \ iptables \
pkg-config \
pigz \
procps \ procps \
xfsprogs \ xfsprogs \
xz-utils \ xz-utils \
@@ -40,7 +42,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# will need updating, to avoid errors. Ping #docker-maintainers on IRC # will need updating, to avoid errors. Ping #docker-maintainers on IRC
# with a heads-up. # with a heads-up.
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \ RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
| tar -xzC /usr/local | tar -xzC /usr/local
ENV PATH /go/bin:/usr/local/go/bin:$PATH ENV PATH /go/bin:/usr/local/go/bin:$PATH

View File

@@ -161,7 +161,7 @@ SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPref
# Environment variable notes: # Environment variable notes:
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux. # - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
# - FROM_DOCKERFILE is used for detection of building within a container. # - FROM_DOCKERFILE is used for detection of building within a container.
ENV GO_VERSION=1.8.5 ` ENV GO_VERSION=1.9.2 `
GIT_VERSION=2.11.1 ` GIT_VERSION=2.11.1 `
GOPATH=C:\go ` GOPATH=C:\go `
FROM_DOCKERFILE=1 FROM_DOCKERFILE=1

View File

@@ -1,12 +1,14 @@
# Moby maintainers file # Moby maintainers file
# #
# This file describes who runs the docker/docker project and how. # This file describes the maintainer groups within the moby/moby project.
# This is a living document - if you see something out of date or missing, speak up! # More detail on Moby project governance is available in the
# project/GOVERNANCE.md file found in this repository.
# #
# It is structured to be consumable by both humans and programs. # It is structured to be consumable by both humans and programs.
# To extract its contents programmatically, use any TOML-compliant # To extract its contents programmatically, use any TOML-compliant
# parser. # parser.
# #
# TODO(estesp): This file should not necessarily depend on docker/opensource
# This file is compiled into the MAINTAINERS file in docker/opensource. # This file is compiled into the MAINTAINERS file in docker/opensource.
# #
[Org] [Org]
@@ -368,7 +370,7 @@
[people.mlaventure] [people.mlaventure]
Name = "Kenfe-Mickaël Laventure" Name = "Kenfe-Mickaël Laventure"
Email = "mickael.laventure@docker.com" Email = "mickael.laventure@gmail.com"
GitHub = "mlaventure" GitHub = "mlaventure"
[people.moxiegirl] [people.moxiegirl]
@@ -465,4 +467,3 @@
Name = "Yong Tang" Name = "Yong Tang"
Email = "yong.tang.github@outlook.com" Email = "yong.tang.github@outlook.com"
GitHub = "yongtang" GitHub = "yongtang"

View File

@@ -53,7 +53,8 @@ DOCKER_ENVS := \
-e http_proxy \ -e http_proxy \
-e https_proxy \ -e https_proxy \
-e no_proxy \ -e no_proxy \
-e VERSION -e VERSION \
-e PLATFORM
# note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds # note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds
# to allow `make BIND_DIR=. shell` or `make BIND_DIR= test` # to allow `make BIND_DIR=. shell` or `make BIND_DIR= test`

View File

@@ -3,7 +3,7 @@ package api
// Common constants for daemon and client. // Common constants for daemon and client.
const ( const (
// DefaultVersion of Current REST API // DefaultVersion of Current REST API
DefaultVersion string = "1.35" DefaultVersion string = "1.36"
// NoBaseImageSpecifier is the symbol used by the FROM // NoBaseImageSpecifier is the symbol used by the FROM
// command to specify that no base image is to be used. // command to specify that no base image is to be used.

View File

@@ -17,7 +17,7 @@ import (
// ImageComponent provides an interface for working with images // ImageComponent provides an interface for working with images
type ImageComponent interface { type ImageComponent interface {
SquashImage(from string, to string) (string, error) SquashImage(from string, to string) (string, error)
TagImageWithReference(image.ID, string, reference.Named) error TagImageWithReference(image.ID, reference.Named) error
} }
// Builder defines interface for running a build // Builder defines interface for running a build

View File

@@ -3,11 +3,9 @@ package build
import ( import (
"fmt" "fmt"
"io" "io"
"runtime"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/pkg/system"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -35,12 +33,7 @@ func NewTagger(backend ImageComponent, stdout io.Writer, names []string) (*Tagge
// TagImages creates image tags for the imageID // TagImages creates image tags for the imageID
func (bt *Tagger) TagImages(imageID image.ID) error { func (bt *Tagger) TagImages(imageID image.ID) error {
for _, rt := range bt.repoAndTags { for _, rt := range bt.repoAndTags {
// TODO @jhowardmsft LCOW support. Will need revisiting. if err := bt.imageComponent.TagImageWithReference(imageID, rt); err != nil {
platform := runtime.GOOS
if system.LCOWSupported() {
platform = "linux"
}
if err := bt.imageComponent.TagImageWithReference(imageID, platform, rt); err != nil {
return err return err
} }
fmt.Fprintf(bt.stdout, "Successfully tagged %s\n", reference.FamiliarString(rt)) fmt.Fprintf(bt.stdout, "Successfully tagged %s\n", reference.FamiliarString(rt))

View File

@@ -4,9 +4,9 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/docker/docker/api/errdefs"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"google.golang.org/grpc" "google.golang.org/grpc"
@@ -35,7 +35,7 @@ func GetHTTPErrorStatusCode(err error) int {
statusCode = http.StatusNotFound statusCode = http.StatusNotFound
case errdefs.IsInvalidParameter(err): case errdefs.IsInvalidParameter(err):
statusCode = http.StatusBadRequest statusCode = http.StatusBadRequest
case errdefs.IsConflict(err): case errdefs.IsConflict(err) || errdefs.IsAlreadyExists(err):
statusCode = http.StatusConflict statusCode = http.StatusConflict
case errdefs.IsUnauthorized(err): case errdefs.IsUnauthorized(err):
statusCode = http.StatusUnauthorized statusCode = http.StatusUnauthorized
@@ -47,7 +47,7 @@ func GetHTTPErrorStatusCode(err error) int {
statusCode = http.StatusNotModified statusCode = http.StatusNotModified
case errdefs.IsNotImplemented(err): case errdefs.IsNotImplemented(err):
statusCode = http.StatusNotImplemented statusCode = http.StatusNotImplemented
case errdefs.IsSystem(err) || errdefs.IsUnknown(err): case errdefs.IsSystem(err) || errdefs.IsUnknown(err) || errdefs.IsDataLoss(err) || errdefs.IsDeadline(err) || errdefs.IsCancelled(err):
statusCode = http.StatusInternalServerError statusCode = http.StatusInternalServerError
default: default:
statusCode = statusCodeFromGRPCError(err) statusCode = statusCodeFromGRPCError(err)

View File

@@ -6,13 +6,16 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
type contextKey string
// APIVersionKey is the client's requested API version. // APIVersionKey is the client's requested API version.
const APIVersionKey = "api-version" const APIVersionKey contextKey = "api-version"
// APIFunc is an adapter to allow the use of ordinary functions as Docker API endpoints. // APIFunc is an adapter to allow the use of ordinary functions as Docker API endpoints.
// Any function that has the appropriate signature can be registered as an API endpoint (e.g. getVersion). // Any function that has the appropriate signature can be registered as an API endpoint (e.g. getVersion).
@@ -43,20 +46,6 @@ func CloseStreams(streams ...interface{}) {
} }
} }
type validationError struct {
cause error
}
func (e validationError) Error() string {
return e.cause.Error()
}
func (e validationError) Cause() error {
return e.cause
}
func (e validationError) InvalidParameter() {}
// CheckForJSON makes sure that the request's Content-Type is application/json. // CheckForJSON makes sure that the request's Content-Type is application/json.
func CheckForJSON(r *http.Request) error { func CheckForJSON(r *http.Request) error {
ct := r.Header.Get("Content-Type") ct := r.Header.Get("Content-Type")
@@ -72,7 +61,7 @@ func CheckForJSON(r *http.Request) error {
if matchesContentType(ct, "application/json") { if matchesContentType(ct, "application/json") {
return nil return nil
} }
return validationError{errors.Errorf("Content-Type specified (%s) must be 'application/json'", ct)} return errdefs.InvalidParameter(errors.Errorf("Content-Type specified (%s) must be 'application/json'", ct))
} }
// ParseForm ensures the request form is parsed even with invalid content types. // ParseForm ensures the request form is parsed even with invalid content types.
@@ -82,7 +71,7 @@ func ParseForm(r *http.Request) error {
return nil return nil
} }
if err := r.ParseForm(); err != nil && !strings.HasPrefix(err.Error(), "mime:") { if err := r.ParseForm(); err != nil && !strings.HasPrefix(err.Error(), "mime:") {
return validationError{err} return errdefs.InvalidParameter(err)
} }
return nil return nil
} }

View File

@@ -5,6 +5,7 @@ import (
"net/http" "net/http"
"runtime" "runtime"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@@ -57,8 +58,7 @@ func (v VersionMiddleware) WrapHandler(handler func(ctx context.Context, w http.
if versions.GreaterThan(apiVersion, v.defaultVersion) { if versions.GreaterThan(apiVersion, v.defaultVersion) {
return versionUnsupportedError{version: apiVersion, maxVersion: v.defaultVersion} return versionUnsupportedError{version: apiVersion, maxVersion: v.defaultVersion}
} }
// nolint: golint ctx = context.WithValue(ctx, httputils.APIVersionKey, apiVersion)
ctx = context.WithValue(ctx, "api-version", apiVersion)
return handler(ctx, w, r, vars) return handler(ctx, w, r, vars)
} }

View File

@@ -4,7 +4,6 @@ import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"runtime" "runtime"
"strings"
"testing" "testing"
"github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/server/httputils"
@@ -12,37 +11,16 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
) )
func TestVersionMiddleware(t *testing.T) { func TestVersionMiddlewareVersion(t *testing.T) {
defaultVersion := "1.10.0"
minVersion := "1.2.0"
expectedVersion := defaultVersion
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if httputils.VersionFromContext(ctx) == "" { v := httputils.VersionFromContext(ctx)
t.Fatal("Expected version, got empty string") assert.Equal(t, expectedVersion, v)
}
return nil return nil
} }
defaultVersion := "1.10.0"
minVersion := "1.2.0"
m := NewVersionMiddleware(defaultVersion, defaultVersion, minVersion)
h := m.WrapHandler(handler)
req, _ := http.NewRequest("GET", "/containers/json", nil)
resp := httptest.NewRecorder()
ctx := context.Background()
if err := h(ctx, resp, req, map[string]string{}); err != nil {
t.Fatal(err)
}
}
func TestVersionMiddlewareVersionTooOld(t *testing.T) {
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if httputils.VersionFromContext(ctx) == "" {
t.Fatal("Expected version, got empty string")
}
return nil
}
defaultVersion := "1.10.0"
minVersion := "1.2.0"
m := NewVersionMiddleware(defaultVersion, defaultVersion, minVersion) m := NewVersionMiddleware(defaultVersion, defaultVersion, minVersion)
h := m.WrapHandler(handler) h := m.WrapHandler(handler)
@@ -50,44 +28,45 @@ func TestVersionMiddlewareVersionTooOld(t *testing.T) {
resp := httptest.NewRecorder() resp := httptest.NewRecorder()
ctx := context.Background() ctx := context.Background()
vars := map[string]string{"version": "0.1"} tests := []struct {
err := h(ctx, resp, req, vars) reqVersion string
expectedVersion string
if !strings.Contains(err.Error(), "client version 0.1 is too old. Minimum supported API version is 1.2.0") { errString string
t.Fatalf("Expected too old client error, got %v", err) }{
{
expectedVersion: "1.10.0",
},
{
reqVersion: "1.9.0",
expectedVersion: "1.9.0",
},
{
reqVersion: "0.1",
errString: "client version 0.1 is too old. Minimum supported API version is 1.2.0, please upgrade your client to a newer version",
},
{
reqVersion: "9999.9999",
errString: "client version 9999.9999 is too new. Maximum supported API version is 1.10.0",
},
} }
}
func TestVersionMiddlewareVersionTooNew(t *testing.T) { for _, test := range tests {
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { expectedVersion = test.expectedVersion
if httputils.VersionFromContext(ctx) == "" {
t.Fatal("Expected version, got empty string") err := h(ctx, resp, req, map[string]string{"version": test.reqVersion})
if test.errString != "" {
assert.EqualError(t, err, test.errString)
} else {
assert.NoError(t, err)
} }
return nil
}
defaultVersion := "1.10.0"
minVersion := "1.2.0"
m := NewVersionMiddleware(defaultVersion, defaultVersion, minVersion)
h := m.WrapHandler(handler)
req, _ := http.NewRequest("GET", "/containers/json", nil)
resp := httptest.NewRecorder()
ctx := context.Background()
vars := map[string]string{"version": "9999.9999"}
err := h(ctx, resp, req, vars)
if !strings.Contains(err.Error(), "client version 9999.9999 is too new. Maximum supported API version is 1.10.0") {
t.Fatalf("Expected too new client error, got %v", err)
} }
} }
func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) { func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) {
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if httputils.VersionFromContext(ctx) == "" { v := httputils.VersionFromContext(ctx)
t.Fatal("Expected version, got empty string") assert.NotEmpty(t, v)
}
return nil return nil
} }
@@ -102,8 +81,8 @@ func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) {
vars := map[string]string{"version": "0.1"} vars := map[string]string{"version": "0.1"}
err := h(ctx, resp, req, vars) err := h(ctx, resp, req, vars)
assert.Error(t, err) assert.Error(t, err)
hdr := resp.Result().Header hdr := resp.Result().Header
assert.Contains(t, hdr.Get("Server"), "Docker/"+defaultVersion) assert.Contains(t, hdr.Get("Server"), "Docker/"+defaultVersion)
assert.Contains(t, hdr.Get("Server"), runtime.GOOS) assert.Contains(t, hdr.Get("Server"), runtime.GOOS)

View File

@@ -18,6 +18,7 @@ import (
"github.com/docker/docker/api/types/backend" "github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/streamformatter"
@@ -83,7 +84,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui
} }
p := system.ParsePlatform(apiPlatform) p := system.ParsePlatform(apiPlatform)
if err := system.ValidatePlatform(p); err != nil { if err := system.ValidatePlatform(p); err != nil {
return nil, validationError{fmt.Errorf("invalid platform: %s", err)} return nil, errdefs.InvalidParameter(errors.Errorf("invalid platform: %s", err))
} }
options.Platform = p.OS options.Platform = p.OS
} }
@@ -104,14 +105,14 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui
} }
if runtime.GOOS != "windows" && options.SecurityOpt != nil { if runtime.GOOS != "windows" && options.SecurityOpt != nil {
return nil, validationError{fmt.Errorf("The daemon on this platform does not support setting security options on build")} return nil, errdefs.InvalidParameter(errors.New("The daemon on this platform does not support setting security options on build"))
} }
var buildUlimits = []*units.Ulimit{} var buildUlimits = []*units.Ulimit{}
ulimitsJSON := r.FormValue("ulimits") ulimitsJSON := r.FormValue("ulimits")
if ulimitsJSON != "" { if ulimitsJSON != "" {
if err := json.Unmarshal([]byte(ulimitsJSON), &buildUlimits); err != nil { if err := json.Unmarshal([]byte(ulimitsJSON), &buildUlimits); err != nil {
return nil, errors.Wrap(validationError{err}, "error reading ulimit settings") return nil, errors.Wrap(errdefs.InvalidParameter(err), "error reading ulimit settings")
} }
options.Ulimits = buildUlimits options.Ulimits = buildUlimits
} }
@@ -132,7 +133,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui
if buildArgsJSON != "" { if buildArgsJSON != "" {
var buildArgs = map[string]*string{} var buildArgs = map[string]*string{}
if err := json.Unmarshal([]byte(buildArgsJSON), &buildArgs); err != nil { if err := json.Unmarshal([]byte(buildArgsJSON), &buildArgs); err != nil {
return nil, errors.Wrap(validationError{err}, "error reading build args") return nil, errors.Wrap(errdefs.InvalidParameter(err), "error reading build args")
} }
options.BuildArgs = buildArgs options.BuildArgs = buildArgs
} }
@@ -141,7 +142,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui
if labelsJSON != "" { if labelsJSON != "" {
var labels = map[string]string{} var labels = map[string]string{}
if err := json.Unmarshal([]byte(labelsJSON), &labels); err != nil { if err := json.Unmarshal([]byte(labelsJSON), &labels); err != nil {
return nil, errors.Wrap(validationError{err}, "error reading labels") return nil, errors.Wrap(errdefs.InvalidParameter(err), "error reading labels")
} }
options.Labels = labels options.Labels = labels
} }
@@ -167,16 +168,6 @@ func (br *buildRouter) postPrune(ctx context.Context, w http.ResponseWriter, r *
return httputils.WriteJSON(w, http.StatusOK, report) return httputils.WriteJSON(w, http.StatusOK, report)
} }
type validationError struct {
cause error
}
func (e validationError) Error() string {
return e.cause.Error()
}
func (e validationError) InvalidParameter() {}
func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var ( var (
notVerboseBuffer = bytes.NewBuffer(nil) notVerboseBuffer = bytes.NewBuffer(nil)
@@ -210,7 +201,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
buildOptions.AuthConfigs = getAuthConfigs(r.Header) buildOptions.AuthConfigs = getAuthConfigs(r.Header)
if buildOptions.Squash && !br.daemon.HasExperimental() { if buildOptions.Squash && !br.daemon.HasExperimental() {
return validationError{errors.New("squash is only supported with experimental mode")} return errdefs.InvalidParameter(errors.New("squash is only supported with experimental mode"))
} }
out := io.Writer(output) out := io.Writer(output)

View File

@@ -5,20 +5,6 @@ import (
"github.com/docker/docker/api/server/router" "github.com/docker/docker/api/server/router"
) )
type validationError struct {
cause error
}
func (e validationError) Error() string {
return e.cause.Error()
}
func (e validationError) Cause() error {
return e.cause
}
func (e validationError) InvalidParameter() {}
// containerRouter is a router to talk with the container controller // containerRouter is a router to talk with the container controller
type containerRouter struct { type containerRouter struct {
backend Backend backend Backend

View File

@@ -8,7 +8,6 @@ import (
"strconv" "strconv"
"syscall" "syscall"
"github.com/docker/docker/api/errdefs"
"github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend" "github.com/docker/docker/api/types/backend"
@@ -16,6 +15,7 @@ import (
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
containerpkg "github.com/docker/docker/container" containerpkg "github.com/docker/docker/container"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -88,7 +88,7 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response
// with the appropriate status code. // with the appropriate status code.
stdout, stderr := httputils.BoolValue(r, "stdout"), httputils.BoolValue(r, "stderr") stdout, stderr := httputils.BoolValue(r, "stdout"), httputils.BoolValue(r, "stderr")
if !(stdout || stderr) { if !(stdout || stderr) {
return validationError{errors.New("Bad parameters: you must choose at least one stream")} return errdefs.InvalidParameter(errors.New("Bad parameters: you must choose at least one stream"))
} }
containerName := vars["name"] containerName := vars["name"]
@@ -203,7 +203,7 @@ func (s *containerRouter) postContainersKill(ctx context.Context, w http.Respons
if sigStr := r.Form.Get("signal"); sigStr != "" { if sigStr := r.Form.Get("signal"); sigStr != "" {
var err error var err error
if sig, err = signal.ParseSignal(sigStr); err != nil { if sig, err = signal.ParseSignal(sigStr); err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
} }
@@ -468,11 +468,11 @@ func (s *containerRouter) postContainersResize(ctx context.Context, w http.Respo
height, err := strconv.Atoi(r.Form.Get("h")) height, err := strconv.Atoi(r.Form.Get("h"))
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
width, err := strconv.Atoi(r.Form.Get("w")) width, err := strconv.Atoi(r.Form.Get("w"))
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
return s.backend.ContainerResize(vars["name"], height, width) return s.backend.ContainerResize(vars["name"], height, width)
@@ -490,7 +490,7 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo
hijacker, ok := w.(http.Hijacker) hijacker, ok := w.(http.Hijacker)
if !ok { if !ok {
return validationError{errors.Errorf("error attaching to container %s, hijack connection missing", containerName)} return errdefs.InvalidParameter(errors.Errorf("error attaching to container %s, hijack connection missing", containerName))
} }
setupStreams := func() (io.ReadCloser, io.Writer, io.Writer, error) { setupStreams := func() (io.ReadCloser, io.Writer, io.Writer, error) {
@@ -593,7 +593,11 @@ func (s *containerRouter) wsContainersAttach(ctx context.Context, w http.Respons
close(done) close(done)
select { select {
case <-started: case <-started:
logrus.Errorf("Error attaching websocket: %s", err) if err != nil {
logrus.Errorf("Error attaching websocket: %s", err)
} else {
logrus.Debug("websocket connection was closed by client")
}
return nil return nil
default: default:
} }
@@ -607,7 +611,7 @@ func (s *containerRouter) postContainersPrune(ctx context.Context, w http.Respon
pruneFilters, err := filters.FromJSON(r.Form.Get("filters")) pruneFilters, err := filters.FromJSON(r.Form.Get("filters"))
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
pruneReport, err := s.backend.ContainersPrune(ctx, pruneFilters) pruneReport, err := s.backend.ContainersPrune(ctx, pruneFilters)

View File

@@ -10,6 +10,7 @@ import (
"github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/stdcopy"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
@@ -137,11 +138,11 @@ func (s *containerRouter) postContainerExecResize(ctx context.Context, w http.Re
} }
height, err := strconv.Atoi(r.Form.Get("h")) height, err := strconv.Atoi(r.Form.Get("h"))
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
width, err := strconv.Atoi(r.Form.Get("w")) width, err := strconv.Atoi(r.Form.Get("w"))
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
return s.backend.ContainerExecResize(vars["name"], height, width) return s.backend.ContainerExecResize(vars["name"], height, width)

View File

@@ -13,9 +13,9 @@ import (
"github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend" "github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/system"
@@ -46,9 +46,6 @@ func (s *imageRouter) postCommit(ctx context.Context, w http.ResponseWriter, r *
if err != nil && err != io.EOF { //Do not fail if body is empty. if err != nil && err != io.EOF { //Do not fail if body is empty.
return err return err
} }
if c == nil {
c = &container.Config{}
}
commitCfg := &backend.ContainerCommitConfig{ commitCfg := &backend.ContainerCommitConfig{
ContainerCommitConfig: types.ContainerCommitConfig{ ContainerCommitConfig: types.ContainerCommitConfig{
@@ -148,20 +145,6 @@ func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrite
return nil return nil
} }
type validationError struct {
cause error
}
func (e validationError) Error() string {
return e.cause.Error()
}
func (e validationError) Cause() error {
return e.cause
}
func (validationError) InvalidParameter() {}
func (s *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (s *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
metaHeaders := map[string][]string{} metaHeaders := map[string][]string{}
for k, v := range r.Header { for k, v := range r.Header {
@@ -185,7 +168,7 @@ func (s *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter,
} else { } else {
// the old format is supported for compatibility if there was no authConfig header // the old format is supported for compatibility if there was no authConfig header
if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil { if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
return errors.Wrap(validationError{err}, "Bad parameters and missing X-Registry-Auth") return errors.Wrap(errdefs.InvalidParameter(err), "Bad parameters and missing X-Registry-Auth")
} }
} }

View File

@@ -17,6 +17,6 @@ type Backend interface {
CreateNetwork(nc types.NetworkCreateRequest) (*types.NetworkCreateResponse, error) CreateNetwork(nc types.NetworkCreateRequest) (*types.NetworkCreateResponse, error)
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
DisconnectContainerFromNetwork(containerName string, networkName string, force bool) error DisconnectContainerFromNetwork(containerName string, networkName string, force bool) error
DeleteNetwork(name string) error DeleteNetwork(networkID string) error
NetworksPrune(ctx context.Context, pruneFilters filters.Args) (*types.NetworksPruneReport, error) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (*types.NetworksPruneReport, error)
} }

View File

@@ -13,6 +13,7 @@ import (
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/libnetwork" "github.com/docker/libnetwork"
netconst "github.com/docker/libnetwork/datastore" netconst "github.com/docker/libnetwork/datastore"
"github.com/docker/libnetwork/networkdb" "github.com/docker/libnetwork/networkdb"
@@ -100,22 +101,8 @@ func (e ambigousResultsError) Error() string {
func (ambigousResultsError) InvalidParameter() {} func (ambigousResultsError) InvalidParameter() {}
type conflictError struct {
cause error
}
func (e conflictError) Error() string {
return e.cause.Error()
}
func (e conflictError) Cause() error {
return e.cause
}
func (e conflictError) Conflict() {}
func nameConflict(name string) error { func nameConflict(name string) error {
return conflictError{libnetwork.NetworkNameError(name)} return errdefs.Conflict(libnetwork.NetworkNameError(name))
} }
func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -288,7 +275,12 @@ func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseW
return err return err
} }
return n.backend.ConnectContainerToNetwork(connect.Container, vars["id"], connect.EndpointConfig) // Always make sure there is no ambiguity with respect to the network ID/name
nw, err := n.backend.FindNetwork(vars["id"])
if err != nil {
return err
}
return n.backend.ConnectContainerToNetwork(connect.Container, nw.ID(), connect.EndpointConfig)
} }
func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -312,15 +304,19 @@ func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter
if err := httputils.ParseForm(r); err != nil { if err := httputils.ParseForm(r); err != nil {
return err return err
} }
if _, err := n.cluster.GetNetwork(vars["id"]); err == nil {
if err = n.cluster.RemoveNetwork(vars["id"]); err != nil { nw, err := n.findUniqueNetwork(vars["id"])
if err != nil {
return err
}
if nw.Scope == "swarm" {
if err = n.cluster.RemoveNetwork(nw.ID); err != nil {
return err
}
} else {
if err := n.backend.DeleteNetwork(nw.ID); err != nil {
return err return err
} }
w.WriteHeader(http.StatusNoContent)
return nil
}
if err := n.backend.DeleteNetwork(vars["id"]); err != nil {
return err
} }
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
return nil return nil
@@ -518,3 +514,79 @@ func (n *networkRouter) postNetworksPrune(ctx context.Context, w http.ResponseWr
} }
return httputils.WriteJSON(w, http.StatusOK, pruneReport) return httputils.WriteJSON(w, http.StatusOK, pruneReport)
} }
// findUniqueNetwork will search network across different scopes (both local and swarm).
// NOTE: This findUniqueNetwork is different from FindNetwork in the daemon.
// In case multiple networks have duplicate names, return error.
// First find based on full ID, return immediately once one is found.
// If a network appears both in swarm and local, assume it is in local first
// For full name and partial ID, save the result first, and process later
// in case multiple records was found based on the same term
// TODO (yongtang): should we wrap with version here for backward compatibility?
func (n *networkRouter) findUniqueNetwork(term string) (types.NetworkResource, error) {
listByFullName := map[string]types.NetworkResource{}
listByPartialID := map[string]types.NetworkResource{}
nw := n.backend.GetNetworks()
for _, network := range nw {
if network.ID() == term {
return *n.buildDetailedNetworkResources(network, false), nil
}
if network.Name() == term && !network.Info().Ingress() {
// No need to check the ID collision here as we are still in
// local scope and the network ID is unique in this scope.
listByFullName[network.ID()] = *n.buildDetailedNetworkResources(network, false)
}
if strings.HasPrefix(network.ID(), term) {
// No need to check the ID collision here as we are still in
// local scope and the network ID is unique in this scope.
listByPartialID[network.ID()] = *n.buildDetailedNetworkResources(network, false)
}
}
nr, _ := n.cluster.GetNetworks()
for _, network := range nr {
if network.ID == term {
return network, nil
}
if network.Name == term {
// Check the ID collision as we are in swarm scope here, and
// the map (of the listByFullName) may have already had a
// network with the same ID (from local scope previously)
if _, ok := listByFullName[network.ID]; !ok {
listByFullName[network.ID] = network
}
}
if strings.HasPrefix(network.ID, term) {
// Check the ID collision as we are in swarm scope here, and
// the map (of the listByPartialID) may have already had a
// network with the same ID (from local scope previously)
if _, ok := listByPartialID[network.ID]; !ok {
listByPartialID[network.ID] = network
}
}
}
// Find based on full name, returns true only if no duplicates
if len(listByFullName) == 1 {
for _, v := range listByFullName {
return v, nil
}
}
if len(listByFullName) > 1 {
return types.NetworkResource{}, errdefs.InvalidParameter(errors.Errorf("network %s is ambiguous (%d matches found based on name)", term, len(listByFullName)))
}
// Find based on partial ID, returns true only if no duplicates
if len(listByPartialID) == 1 {
for _, v := range listByPartialID {
return v, nil
}
}
if len(listByPartialID) > 1 {
return types.NetworkResource{}, errdefs.InvalidParameter(errors.Errorf("network %s is ambiguous (%d matches found based on ID prefix)", term, len(listByPartialID)))
}
return types.NetworkResource{}, errdefs.NotFound(libnetwork.ErrNoSuchNetwork(term))
}

View File

@@ -3,27 +3,14 @@ package session
import ( import (
"net/http" "net/http"
"github.com/docker/docker/errdefs"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
type invalidRequest struct {
cause error
}
func (e invalidRequest) Error() string {
return e.cause.Error()
}
func (e invalidRequest) Cause() error {
return e.cause
}
func (e invalidRequest) InvalidParameter() {}
func (sr *sessionRouter) startSession(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (sr *sessionRouter) startSession(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
err := sr.backend.HandleHTTPRequest(ctx, w, r) err := sr.backend.HandleHTTPRequest(ctx, w, r)
if err != nil { if err != nil {
return invalidRequest{err} return errdefs.InvalidParameter(err)
} }
return nil return nil
} }

View File

@@ -12,6 +12,7 @@ import (
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
types "github.com/docker/docker/api/types/swarm" types "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
@@ -57,20 +58,6 @@ func (sr *swarmRouter) inspectCluster(ctx context.Context, w http.ResponseWriter
return httputils.WriteJSON(w, http.StatusOK, swarm) return httputils.WriteJSON(w, http.StatusOK, swarm)
} }
type invalidRequestError struct {
err error
}
func (e invalidRequestError) Error() string {
return e.err.Error()
}
func (e invalidRequestError) Cause() error {
return e.err
}
func (e invalidRequestError) InvalidParameter() {}
func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var swarm types.Spec var swarm types.Spec
if err := json.NewDecoder(r.Body).Decode(&swarm); err != nil { if err := json.NewDecoder(r.Body).Decode(&swarm); err != nil {
@@ -81,7 +68,7 @@ func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter,
version, err := strconv.ParseUint(rawVersion, 10, 64) version, err := strconv.ParseUint(rawVersion, 10, 64)
if err != nil { if err != nil {
err := fmt.Errorf("invalid swarm version '%s': %v", rawVersion, err) err := fmt.Errorf("invalid swarm version '%s': %v", rawVersion, err)
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
var flags types.UpdateFlags var flags types.UpdateFlags
@@ -90,7 +77,7 @@ func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter,
rot, err := strconv.ParseBool(value) rot, err := strconv.ParseBool(value)
if err != nil { if err != nil {
err := fmt.Errorf("invalid value for rotateWorkerToken: %s", value) err := fmt.Errorf("invalid value for rotateWorkerToken: %s", value)
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
flags.RotateWorkerToken = rot flags.RotateWorkerToken = rot
@@ -100,7 +87,7 @@ func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter,
rot, err := strconv.ParseBool(value) rot, err := strconv.ParseBool(value)
if err != nil { if err != nil {
err := fmt.Errorf("invalid value for rotateManagerToken: %s", value) err := fmt.Errorf("invalid value for rotateManagerToken: %s", value)
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
flags.RotateManagerToken = rot flags.RotateManagerToken = rot
@@ -109,7 +96,7 @@ func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter,
if value := r.URL.Query().Get("rotateManagerUnlockKey"); value != "" { if value := r.URL.Query().Get("rotateManagerUnlockKey"); value != "" {
rot, err := strconv.ParseBool(value) rot, err := strconv.ParseBool(value)
if err != nil { if err != nil {
return invalidRequestError{fmt.Errorf("invalid value for rotateManagerUnlockKey: %s", value)} return errdefs.InvalidParameter(fmt.Errorf("invalid value for rotateManagerUnlockKey: %s", value))
} }
flags.RotateManagerUnlockKey = rot flags.RotateManagerUnlockKey = rot
@@ -153,7 +140,7 @@ func (sr *swarmRouter) getServices(ctx context.Context, w http.ResponseWriter, r
} }
filter, err := filters.FromJSON(r.Form.Get("filters")) filter, err := filters.FromJSON(r.Form.Get("filters"))
if err != nil { if err != nil {
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
services, err := sr.backend.GetServices(basictypes.ServiceListOptions{Filters: filter}) services, err := sr.backend.GetServices(basictypes.ServiceListOptions{Filters: filter})
@@ -172,7 +159,7 @@ func (sr *swarmRouter) getService(ctx context.Context, w http.ResponseWriter, r
insertDefaults, err = strconv.ParseBool(value) insertDefaults, err = strconv.ParseBool(value)
if err != nil { if err != nil {
err := fmt.Errorf("invalid value for insertDefaults: %s", value) err := fmt.Errorf("invalid value for insertDefaults: %s", value)
return errors.Wrapf(invalidRequestError{err}, "invalid value for insertDefaults: %s", value) return errors.Wrapf(errdefs.InvalidParameter(err), "invalid value for insertDefaults: %s", value)
} }
} }
@@ -218,7 +205,7 @@ func (sr *swarmRouter) updateService(ctx context.Context, w http.ResponseWriter,
version, err := strconv.ParseUint(rawVersion, 10, 64) version, err := strconv.ParseUint(rawVersion, 10, 64)
if err != nil { if err != nil {
err := fmt.Errorf("invalid service version '%s': %v", rawVersion, err) err := fmt.Errorf("invalid service version '%s': %v", rawVersion, err)
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
var flags basictypes.ServiceUpdateOptions var flags basictypes.ServiceUpdateOptions
@@ -311,7 +298,7 @@ func (sr *swarmRouter) updateNode(ctx context.Context, w http.ResponseWriter, r
version, err := strconv.ParseUint(rawVersion, 10, 64) version, err := strconv.ParseUint(rawVersion, 10, 64)
if err != nil { if err != nil {
err := fmt.Errorf("invalid node version '%s': %v", rawVersion, err) err := fmt.Errorf("invalid node version '%s': %v", rawVersion, err)
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
if err := sr.backend.UpdateNode(vars["id"], version, node); err != nil { if err := sr.backend.UpdateNode(vars["id"], version, node); err != nil {
@@ -417,13 +404,13 @@ func (sr *swarmRouter) getSecret(ctx context.Context, w http.ResponseWriter, r *
func (sr *swarmRouter) updateSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (sr *swarmRouter) updateSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var secret types.SecretSpec var secret types.SecretSpec
if err := json.NewDecoder(r.Body).Decode(&secret); err != nil { if err := json.NewDecoder(r.Body).Decode(&secret); err != nil {
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
rawVersion := r.URL.Query().Get("version") rawVersion := r.URL.Query().Get("version")
version, err := strconv.ParseUint(rawVersion, 10, 64) version, err := strconv.ParseUint(rawVersion, 10, 64)
if err != nil { if err != nil {
return invalidRequestError{fmt.Errorf("invalid secret version")} return errdefs.InvalidParameter(fmt.Errorf("invalid secret version"))
} }
id := vars["id"] id := vars["id"]
@@ -484,13 +471,13 @@ func (sr *swarmRouter) getConfig(ctx context.Context, w http.ResponseWriter, r *
func (sr *swarmRouter) updateConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (sr *swarmRouter) updateConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var config types.ConfigSpec var config types.ConfigSpec
if err := json.NewDecoder(r.Body).Decode(&config); err != nil { if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
return invalidRequestError{err} return errdefs.InvalidParameter(err)
} }
rawVersion := r.URL.Query().Get("version") rawVersion := r.URL.Query().Get("version")
version, err := strconv.ParseUint(rawVersion, 10, 64) version, err := strconv.ParseUint(rawVersion, 10, 64)
if err != nil { if err != nil {
return invalidRequestError{fmt.Errorf("invalid config version")} return errdefs.InvalidParameter(fmt.Errorf("invalid config version"))
} }
id := vars["id"] id := vars["id"]

View File

@@ -6,7 +6,6 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/docker/docker/api"
"github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
@@ -65,7 +64,6 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
func (s *systemRouter) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func (s *systemRouter) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
info := s.backend.SystemVersion() info := s.backend.SystemVersion()
info.APIVersion = api.DefaultVersion
return httputils.WriteJSON(w, http.StatusOK, info) return httputils.WriteJSON(w, http.StatusOK, info)
} }

View File

@@ -2,11 +2,14 @@ package volume
import ( import (
"encoding/json" "encoding/json"
"errors"
"io"
"net/http" "net/http"
"github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
volumetypes "github.com/docker/docker/api/types/volume" volumetypes "github.com/docker/docker/api/types/volume"
"github.com/docker/docker/errdefs"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@@ -45,6 +48,9 @@ func (v *volumeRouter) postVolumesCreate(ctx context.Context, w http.ResponseWri
var req volumetypes.VolumesCreateBody var req volumetypes.VolumesCreateBody
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return err return err
} }

View File

@@ -19,10 +19,10 @@ produces:
consumes: consumes:
- "application/json" - "application/json"
- "text/plain" - "text/plain"
basePath: "/v1.35" basePath: "/v1.36"
info: info:
title: "Docker Engine API" title: "Docker Engine API"
version: "1.35" version: "1.36"
x-logo: x-logo:
url: "https://docs.docker.com/images/logo-docker-main.png" url: "https://docs.docker.com/images/logo-docker-main.png"
description: | description: |
@@ -49,8 +49,8 @@ info:
the URL is not supported by the daemon, a HTTP `400 Bad Request` error message the URL is not supported by the daemon, a HTTP `400 Bad Request` error message
is returned. is returned.
If you omit the version-prefix, the current version of the API (v1.35) is used. If you omit the version-prefix, the current version of the API (v1.36) is used.
For example, calling `/info` is the same as calling `/v1.35/info`. Using the For example, calling `/info` is the same as calling `/v1.36/info`. Using the
API without a version-prefix is deprecated and will be removed in a future release. API without a version-prefix is deprecated and will be removed in a future release.
Engine releases in the near future should support this version of the API, Engine releases in the near future should support this version of the API,
@@ -254,6 +254,7 @@ definitions:
properties: properties:
Propagation: Propagation:
description: "A propagation mode with the value `[r]private`, `[r]shared`, or `[r]slave`." description: "A propagation mode with the value `[r]private`, `[r]shared`, or `[r]slave`."
type: "string"
enum: enum:
- "private" - "private"
- "rprivate" - "rprivate"
@@ -332,6 +333,7 @@ definitions:
Memory: Memory:
description: "Memory limit in bytes." description: "Memory limit in bytes."
type: "integer" type: "integer"
format: "int64"
default: 0 default: 0
# Applicable to UNIX platforms # Applicable to UNIX platforms
CgroupParent: CgroupParent:
@@ -606,17 +608,7 @@ definitions:
description: "Network mode to use for this container. Supported standard values are: `bridge`, `host`, `none`, and `container:<name|id>`. Any other value is taken description: "Network mode to use for this container. Supported standard values are: `bridge`, `host`, `none`, and `container:<name|id>`. Any other value is taken
as a custom network's name to which this container should connect to." as a custom network's name to which this container should connect to."
PortBindings: PortBindings:
type: "object" $ref: "#/definitions/PortMap"
description: "A map of exposed container ports and the host port they should map to."
additionalProperties:
type: "object"
properties:
HostIp:
type: "string"
description: "The host IP address"
HostPort:
type: "string"
description: "The host port number, as a string"
RestartPolicy: RestartPolicy:
$ref: "#/definitions/RestartPolicy" $ref: "#/definitions/RestartPolicy"
AutoRemove: AutoRemove:
@@ -832,9 +824,7 @@ definitions:
type: "string" type: "string"
Cmd: Cmd:
description: "Command to run specified as a string or an array of strings." description: "Command to run specified as a string or an array of strings."
type: type: "array"
- "array"
- "string"
items: items:
type: "string" type: "string"
Healthcheck: Healthcheck:
@@ -862,9 +852,7 @@ definitions:
The entry point for the container as a string or an array of strings. The entry point for the container as a string or an array of strings.
If the array consists of exactly one empty string (`[""]`) then the entry point is reset to system default (i.e., the entry point used by docker when there is no `ENTRYPOINT` instruction in the `Dockerfile`). If the array consists of exactly one empty string (`[""]`) then the entry point is reset to system default (i.e., the entry point used by docker when there is no `ENTRYPOINT` instruction in the `Dockerfile`).
type: type: "array"
- "array"
- "string"
items: items:
type: "string" type: "string"
NetworkDisabled: NetworkDisabled:
@@ -1508,10 +1496,23 @@ definitions:
type: "string" type: "string"
progressDetail: progressDetail:
$ref: "#/definitions/ProgressDetail" $ref: "#/definitions/ProgressDetail"
aux:
$ref: "#/definitions/ImageID"
ImageID:
type: "object"
description: "Image ID or Digest"
properties:
ID:
type: "string"
example:
ID: "sha256:85f05633ddc1c50679be2b16a0479ab6f7637f8884e0cfe0f4d20e1ebb3d6e7c"
CreateImageInfo: CreateImageInfo:
type: "object" type: "object"
properties: properties:
id:
type: "string"
error: error:
type: "string" type: "string"
status: status:
@@ -1544,9 +1545,9 @@ definitions:
ProgressDetail: ProgressDetail:
type: "object" type: "object"
properties: properties:
code: current:
type: "integer" type: "integer"
message: total:
type: "integer" type: "integer"
ErrorResponse: ErrorResponse:
@@ -4501,6 +4502,8 @@ paths:
description: "Container created successfully" description: "Container created successfully"
schema: schema:
type: "object" type: "object"
title: "ContainerCreateResponse"
description: "OK response to ContainerCreate operation"
required: [Id, Warnings] required: [Id, Warnings]
properties: properties:
Id: Id:
@@ -4549,6 +4552,7 @@ paths:
description: "no error" description: "no error"
schema: schema:
type: "object" type: "object"
title: "ContainerInspectResponse"
properties: properties:
Id: Id:
description: "The ID of the container" description: "The ID of the container"
@@ -4833,6 +4837,8 @@ paths:
description: "no error" description: "no error"
schema: schema:
type: "object" type: "object"
title: "ContainerTopResponse"
description: "OK response to ContainerTop operation"
properties: properties:
Titles: Titles:
description: "The ps column titles" description: "The ps column titles"
@@ -4993,6 +4999,8 @@ paths:
items: items:
type: "object" type: "object"
x-go-name: "ContainerChangeResponseItem" x-go-name: "ContainerChangeResponseItem"
title: "ContainerChangeResponseItem"
description: "change item in response to ContainerChanges operation"
required: [Path, Kind] required: [Path, Kind]
properties: properties:
Path: Path:
@@ -5371,6 +5379,8 @@ paths:
description: "The container has been updated." description: "The container has been updated."
schema: schema:
type: "object" type: "object"
title: "ContainerUpdateResponse"
description: "OK response to ContainerUpdate operation"
properties: properties:
Warnings: Warnings:
type: "array" type: "array"
@@ -5724,6 +5734,8 @@ paths:
description: "The container has exit." description: "The container has exit."
schema: schema:
type: "object" type: "object"
title: "ContainerWaitResponse"
description: "OK response to ContainerWait operation"
required: [StatusCode] required: [StatusCode]
properties: properties:
StatusCode: StatusCode:
@@ -5969,6 +5981,7 @@ paths:
description: "No error" description: "No error"
schema: schema:
type: "object" type: "object"
title: "ContainerPruneResponse"
properties: properties:
ContainersDeleted: ContainersDeleted:
description: "Container IDs that were deleted" description: "Container IDs that were deleted"
@@ -6225,6 +6238,7 @@ paths:
description: "No error" description: "No error"
schema: schema:
type: "object" type: "object"
title: "BuildPruneResponse"
properties: properties:
SpaceReclaimed: SpaceReclaimed:
description: "Disk space reclaimed in bytes" description: "Disk space reclaimed in bytes"
@@ -6410,6 +6424,8 @@ paths:
items: items:
type: "object" type: "object"
x-go-name: HistoryResponseItem x-go-name: HistoryResponseItem
title: "HistoryResponseItem"
description: "individual image layer information in response to ImageHistory operation"
required: [Id, Created, CreatedBy, Tags, Size, Comment] required: [Id, Created, CreatedBy, Tags, Size, Comment]
properties: properties:
Id: Id:
@@ -6616,6 +6632,7 @@ paths:
type: "array" type: "array"
items: items:
type: "object" type: "object"
title: "ImageSearchResponseItem"
properties: properties:
description: description:
type: "string" type: "string"
@@ -6691,6 +6708,7 @@ paths:
description: "No error" description: "No error"
schema: schema:
type: "object" type: "object"
title: "ImagePruneResponse"
properties: properties:
ImagesDeleted: ImagesDeleted:
description: "Images that were deleted" description: "Images that were deleted"
@@ -6718,6 +6736,7 @@ paths:
description: "An identity token was generated successfully." description: "An identity token was generated successfully."
schema: schema:
type: "object" type: "object"
title: "SystemAuthResponse"
required: [Status] required: [Status]
properties: properties:
Status: Status:
@@ -6772,7 +6791,30 @@ paths:
description: "no error" description: "no error"
schema: schema:
type: "object" type: "object"
title: "SystemVersionResponse"
properties: properties:
Platform:
type: "object"
required: [Name]
properties:
Name:
type: "string"
Components:
type: "array"
items:
type: "object"
x-go-name: ComponentVersion
required: [Name, Version]
properties:
Name:
type: "string"
Version:
type: "string"
x-nullable: false
Details:
type: "object"
x-nullable: true
Version: Version:
type: "string" type: "string"
ApiVersion: ApiVersion:
@@ -6902,7 +6944,7 @@ paths:
Various objects within Docker report events when something happens to them. Various objects within Docker report events when something happens to them.
Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, and `update` Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, and `update`
Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, and `untag` Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, and `untag`
@@ -6928,6 +6970,7 @@ paths:
description: "no error" description: "no error"
schema: schema:
type: "object" type: "object"
title: "SystemEventsResponse"
properties: properties:
Type: Type:
description: "The type of object emitting the event" description: "The type of object emitting the event"
@@ -7011,6 +7054,7 @@ paths:
description: "no error" description: "no error"
schema: schema:
type: "object" type: "object"
title: "SystemDataUsageResponse"
properties: properties:
LayersSize: LayersSize:
type: "integer" type: "integer"
@@ -7268,6 +7312,9 @@ paths:
User: User:
type: "string" type: "string"
description: "The user, and optionally, group to run the exec process inside the container. Format is one of: `user`, `user:group`, `uid`, or `uid:gid`." description: "The user, and optionally, group to run the exec process inside the container. Format is one of: `user`, `user:group`, `uid`, or `uid:gid`."
WorkingDir:
type: "string"
description: "The working directory for the exec process inside the container."
example: example:
AttachStdin: false AttachStdin: false
AttachStdout: true AttachStdout: true
@@ -7366,7 +7413,12 @@ paths:
description: "No error" description: "No error"
schema: schema:
type: "object" type: "object"
title: "ExecInspectResponse"
properties: properties:
CanRemove:
type: "boolean"
DetachKeys:
type: "string"
ID: ID:
type: "string" type: "string"
Running: Running:
@@ -7432,6 +7484,7 @@ paths:
description: "Summary volume data that matches the query" description: "Summary volume data that matches the query"
schema: schema:
type: "object" type: "object"
title: "VolumeListResponse"
required: [Volumes, Warnings] required: [Volumes, Warnings]
properties: properties:
Volumes: Volumes:
@@ -7613,6 +7666,7 @@ paths:
description: "No error" description: "No error"
schema: schema:
type: "object" type: "object"
title: "VolumePruneResponse"
properties: properties:
VolumesDeleted: VolumesDeleted:
description: "Volumes that were deleted" description: "Volumes that were deleted"
@@ -7791,6 +7845,7 @@ paths:
description: "No error" description: "No error"
schema: schema:
type: "object" type: "object"
title: "NetworkCreateResponse"
properties: properties:
Id: Id:
description: "The ID of the created network." description: "The ID of the created network."
@@ -7993,6 +8048,7 @@ paths:
description: "No error" description: "No error"
schema: schema:
type: "object" type: "object"
title: "NetworkPruneResponse"
properties: properties:
NetworksDeleted: NetworksDeleted:
description: "Networks that were deleted" description: "Networks that were deleted"
@@ -8044,6 +8100,7 @@ paths:
items: items:
description: "Describes a permission the user has to accept upon installing the plugin." description: "Describes a permission the user has to accept upon installing the plugin."
type: "object" type: "object"
title: "PluginPrivilegeItem"
properties: properties:
Name: Name:
type: "string" type: "string"
@@ -8746,6 +8803,7 @@ paths:
description: "no error" description: "no error"
schema: schema:
type: "object" type: "object"
title: "UnlockKeyResponse"
properties: properties:
UnlockKey: UnlockKey:
description: "The swarm's unlock key." description: "The swarm's unlock key."
@@ -8837,6 +8895,7 @@ paths:
description: "no error" description: "no error"
schema: schema:
type: "object" type: "object"
title: "ServiceCreateResponse"
properties: properties:
ID: ID:
description: "The ID of the created service." description: "The ID of the created service."
@@ -9508,13 +9567,7 @@ paths:
201: 201:
description: "no error" description: "no error"
schema: schema:
type: "object" $ref: "#/definitions/IdResponse"
properties:
ID:
description: "The ID of the created secret."
type: "string"
example:
ID: "ktnbjxoalbkvbvedmg1urrz8h"
409: 409:
description: "name conflicts with an existing object" description: "name conflicts with an existing object"
schema: schema:
@@ -9713,13 +9766,7 @@ paths:
201: 201:
description: "no error" description: "no error"
schema: schema:
type: "object" $ref: "#/definitions/IdResponse"
properties:
ID:
description: "The ID of the created config."
type: "string"
example:
ID: "ktnbjxoalbkvbvedmg1urrz8h"
409: 409:
description: "name conflicts with an existing object" description: "name conflicts with an existing object"
schema: schema:
@@ -9865,6 +9912,7 @@ paths:
schema: schema:
type: "object" type: "object"
x-go-name: DistributionInspect x-go-name: DistributionInspect
title: "DistributionInspectResponse"
required: [Descriptor, Platforms] required: [Descriptor, Platforms]
properties: properties:
Descriptor: Descriptor:

View File

@@ -20,7 +20,7 @@ import (
{{ range .ExtraSchemas }} {{ range .ExtraSchemas }}
// {{ .Name }} {{ template "docstring" . }} // {{ .Name }} {{ comment .Description }}
// swagger:model {{ .Name }} // swagger:model {{ .Name }}
{{ template "schema" . }} {{ template "schema" . }}
{{ end }} {{ end }}

View File

@@ -50,6 +50,7 @@ type ExecConfig struct {
Detach bool // Execute in detach mode Detach bool // Execute in detach mode
DetachKeys string // Escape keys for detach DetachKeys string // Escape keys for detach
Env []string // Environment variables Env []string // Environment variables
WorkingDir string // Working directory
Cmd []string // Execution commands and args Cmd []string // Execution commands and args
} }

View File

@@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerChangeResponseItem container change response item // ContainerChangeResponseItem change item in response to ContainerChanges operation
// swagger:model ContainerChangeResponseItem // swagger:model ContainerChangeResponseItem
type ContainerChangeResponseItem struct { type ContainerChangeResponseItem struct {

View File

@@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerCreateCreatedBody container create created body // ContainerCreateCreatedBody OK response to ContainerCreate operation
// swagger:model ContainerCreateCreatedBody // swagger:model ContainerCreateCreatedBody
type ContainerCreateCreatedBody struct { type ContainerCreateCreatedBody struct {

View File

@@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerTopOKBody container top o k body // ContainerTopOKBody OK response to ContainerTop operation
// swagger:model ContainerTopOKBody // swagger:model ContainerTopOKBody
type ContainerTopOKBody struct { type ContainerTopOKBody struct {

View File

@@ -7,7 +7,7 @@ package container
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ContainerUpdateOKBody container update o k body // ContainerUpdateOKBody OK response to ContainerUpdate operation
// swagger:model ContainerUpdateOKBody // swagger:model ContainerUpdateOKBody
type ContainerUpdateOKBody struct { type ContainerUpdateOKBody struct {

View File

@@ -15,7 +15,7 @@ type ContainerWaitOKBodyError struct {
Message string `json:"Message,omitempty"` Message string `json:"Message,omitempty"`
} }
// ContainerWaitOKBody container wait o k body // ContainerWaitOKBody OK response to ContainerWait operation
// swagger:model ContainerWaitOKBody // swagger:model ContainerWaitOKBody
type ContainerWaitOKBody struct { type ContainerWaitOKBody struct {

View File

@@ -7,7 +7,7 @@ package image
// See hack/generate-swagger-api.sh // See hack/generate-swagger-api.sh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// HistoryResponseItem history response item // HistoryResponseItem individual image layer information in response to ImageHistory operation
// swagger:model HistoryResponseItem // swagger:model HistoryResponseItem
type HistoryResponseItem struct { type HistoryResponseItem struct {

View File

@@ -1,5 +1,7 @@
syntax = "proto3"; syntax = "proto3";
option go_package = "github.com/docker/docker/api/types/swarm/runtime;runtime";
// PluginSpec defines the base payload which clients can specify for creating // PluginSpec defines the base payload which clients can specify for creating
// a service with the plugin runtime. // a service with the plugin runtime.
message PluginSpec { message PluginSpec {

View File

@@ -107,9 +107,21 @@ type Ping struct {
Experimental bool Experimental bool
} }
// ComponentVersion describes the version information for a specific component.
type ComponentVersion struct {
Name string
Version string
Details map[string]string `json:",omitempty"`
}
// Version contains response of Engine API: // Version contains response of Engine API:
// GET "/version" // GET "/version"
type Version struct { type Version struct {
Platform struct{ Name string } `json:",omitempty"`
Components []ComponentVersion `json:",omitempty"`
// The following fields are deprecated, they relate to the Engine component and are kept for backwards compatibility
Version string Version string
APIVersion string `json:"ApiVersion"` APIVersion string `json:"ApiVersion"`
MinAPIVersion string `json:"MinAPIVersion,omitempty"` MinAPIVersion string `json:"MinAPIVersion,omitempty"`

View File

@@ -44,7 +44,7 @@ type Backend interface {
// ContainerCreateWorkdir creates the workdir // ContainerCreateWorkdir creates the workdir
ContainerCreateWorkdir(containerID string) error ContainerCreateWorkdir(containerID string) error
CreateImage(config []byte, parent string, platform string) (Image, error) CreateImage(config []byte, parent string) (Image, error)
ImageCacheBuilder ImageCacheBuilder
} }
@@ -79,7 +79,7 @@ type Result struct {
// ImageCacheBuilder represents a generator for stateful image cache. // ImageCacheBuilder represents a generator for stateful image cache.
type ImageCacheBuilder interface { type ImageCacheBuilder interface {
// MakeImageCache creates a stateful image cache. // MakeImageCache creates a stateful image cache.
MakeImageCache(cacheFrom []string, platform string) ImageCache MakeImageCache(cacheFrom []string) ImageCache
} }
// ImageCache abstracts an image cache. // ImageCache abstracts an image cache.
@@ -102,6 +102,6 @@ type Image interface {
type ReleaseableLayer interface { type ReleaseableLayer interface {
Release() error Release() error
Mount() (containerfs.ContainerFS, error) Mount() (containerfs.ContainerFS, error)
Commit(platform string) (ReleaseableLayer, error) Commit() (ReleaseableLayer, error)
DiffID() layer.DiffID DiffID() layer.DiffID
} }

View File

@@ -17,6 +17,7 @@ import (
"github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/builder/dockerfile/parser"
"github.com/docker/docker/builder/fscache" "github.com/docker/docker/builder/fscache"
"github.com/docker/docker/builder/remotecontext" "github.com/docker/docker/builder/remotecontext"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
@@ -122,7 +123,7 @@ func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) (
PathCache: bm.pathCache, PathCache: bm.pathCache,
IDMappings: bm.idMappings, IDMappings: bm.idMappings,
} }
return newBuilder(ctx, builderOptions, os).build(source, dockerfile) return newBuilder(ctx, builderOptions).build(source, dockerfile)
} }
func (bm *BuildManager) initializeClientSession(ctx context.Context, cancel func(), options *types.ImageBuildOptions) (builder.Source, error) { func (bm *BuildManager) initializeClientSession(ctx context.Context, cancel func(), options *types.ImageBuildOptions) (builder.Source, error) {
@@ -189,7 +190,7 @@ type Builder struct {
} }
// newBuilder creates a new Dockerfile builder from an optional dockerfile and a Options. // newBuilder creates a new Dockerfile builder from an optional dockerfile and a Options.
func newBuilder(clientCtx context.Context, options builderOptions, os string) *Builder { func newBuilder(clientCtx context.Context, options builderOptions) *Builder {
config := options.Options config := options.Options
if config == nil { if config == nil {
config = new(types.ImageBuildOptions) config = new(types.ImageBuildOptions)
@@ -206,7 +207,7 @@ func newBuilder(clientCtx context.Context, options builderOptions, os string) *B
idMappings: options.IDMappings, idMappings: options.IDMappings,
imageSources: newImageSources(clientCtx, options), imageSources: newImageSources(clientCtx, options),
pathCache: options.PathCache, pathCache: options.PathCache,
imageProber: newImageProber(options.Backend, config.CacheFrom, os, config.NoCache), imageProber: newImageProber(options.Backend, config.CacheFrom, config.NoCache),
containerManager: newContainerManager(options.Backend), containerManager: newContainerManager(options.Backend),
} }
@@ -225,7 +226,7 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil
if instructions.IsUnknownInstruction(err) { if instructions.IsUnknownInstruction(err) {
buildsFailed.WithValues(metricsUnknownInstructionError).Inc() buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
} }
return nil, validationError{err} return nil, errdefs.InvalidParameter(err)
} }
if b.options.Target != "" { if b.options.Target != "" {
targetIx, found := instructions.HasStage(stages, b.options.Target) targetIx, found := instructions.HasStage(stages, b.options.Target)
@@ -356,29 +357,27 @@ func addNodesForLabelOption(dockerfile *parser.Node, labels map[string]string) {
// coming from the query parameter of the same name. // coming from the query parameter of the same name.
// //
// TODO: Remove? // TODO: Remove?
func BuildFromConfig(config *container.Config, changes []string) (*container.Config, error) { func BuildFromConfig(config *container.Config, changes []string, os string) (*container.Config, error) {
if !system.IsOSSupported(os) {
return nil, errdefs.InvalidParameter(system.ErrNotSupportedOperatingSystem)
}
if len(changes) == 0 { if len(changes) == 0 {
return config, nil return config, nil
} }
dockerfile, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n"))) dockerfile, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
if err != nil { if err != nil {
return nil, validationError{err} return nil, errdefs.InvalidParameter(err)
}
os := runtime.GOOS
if dockerfile.OS != "" {
os = dockerfile.OS
} }
b := newBuilder(context.Background(), builderOptions{ b := newBuilder(context.Background(), builderOptions{
Options: &types.ImageBuildOptions{NoCache: true}, Options: &types.ImageBuildOptions{NoCache: true},
}, os) })
// ensure that the commands are valid // ensure that the commands are valid
for _, n := range dockerfile.AST.Children { for _, n := range dockerfile.AST.Children {
if !validCommitCommands[n.Value] { if !validCommitCommands[n.Value] {
return nil, validationError{errors.Errorf("%s is not a valid change command", n.Value)} return nil, errdefs.InvalidParameter(errors.Errorf("%s is not a valid change command", n.Value))
} }
} }
@@ -390,18 +389,20 @@ func BuildFromConfig(config *container.Config, changes []string) (*container.Con
for _, n := range dockerfile.AST.Children { for _, n := range dockerfile.AST.Children {
cmd, err := instructions.ParseCommand(n) cmd, err := instructions.ParseCommand(n)
if err != nil { if err != nil {
return nil, validationError{err} return nil, errdefs.InvalidParameter(err)
} }
commands = append(commands, cmd) commands = append(commands, cmd)
} }
dispatchRequest := newDispatchRequest(b, dockerfile.EscapeToken, nil, newBuildArgs(b.options.BuildArgs), newStagesBuildResults()) dispatchRequest := newDispatchRequest(b, dockerfile.EscapeToken, nil, newBuildArgs(b.options.BuildArgs), newStagesBuildResults())
dispatchRequest.state.runConfig = config // We make mutations to the configuration, ensure we have a copy
dispatchRequest.state.runConfig = copyRunConfig(config)
dispatchRequest.state.imageID = config.Image dispatchRequest.state.imageID = config.Image
dispatchRequest.state.operatingSystem = os
for _, cmd := range commands { for _, cmd := range commands {
err := dispatch(dispatchRequest, cmd) err := dispatch(dispatchRequest, cmd)
if err != nil { if err != nil {
return nil, validationError{err} return nil, errdefs.InvalidParameter(err)
} }
dispatchRequest.state.updateRunConfig() dispatchRequest.state.updateRunConfig()
} }

View File

@@ -28,7 +28,7 @@ func newContainerManager(docker builder.ExecBackend) *containerManager {
} }
// Create a container // Create a container
func (c *containerManager) Create(runConfig *container.Config, hostConfig *container.HostConfig, platform string) (container.ContainerCreateCreatedBody, error) { func (c *containerManager) Create(runConfig *container.Config, hostConfig *container.HostConfig) (container.ContainerCreateCreatedBody, error) {
container, err := c.backend.ContainerCreate(types.ContainerCreateConfig{ container, err := c.backend.ContainerCreate(types.ContainerCreateConfig{
Config: runConfig, Config: runConfig,
HostConfig: hostConfig, HostConfig: hostConfig,

View File

@@ -20,6 +20,7 @@ import (
"github.com/docker/docker/builder" "github.com/docker/docker/builder"
"github.com/docker/docker/builder/dockerfile/instructions" "github.com/docker/docker/builder/dockerfile/instructions"
"github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/builder/dockerfile/parser"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
@@ -155,7 +156,9 @@ func initializeStage(d dispatchRequest, cmd *instructions.Stage) error {
return err return err
} }
state := d.state state := d.state
state.beginStage(cmd.Name, image) if err := state.beginStage(cmd.Name, image); err != nil {
return err
}
if len(state.runConfig.OnBuild) > 0 { if len(state.runConfig.OnBuild) > 0 {
triggers := state.runConfig.OnBuild triggers := state.runConfig.OnBuild
state.runConfig.OnBuild = nil state.runConfig.OnBuild = nil
@@ -260,8 +263,8 @@ func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error {
func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error { func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
runConfig := d.state.runConfig runConfig := d.state.runConfig
var err error var err error
optionsOS := system.ParsePlatform(d.builder.options.Platform).OS baseImageOS := system.ParsePlatform(d.state.operatingSystem).OS
runConfig.WorkingDir, err = normalizeWorkdir(optionsOS, runConfig.WorkingDir, c.Path) runConfig.WorkingDir, err = normalizeWorkdir(baseImageOS, runConfig.WorkingDir, c.Path)
if err != nil { if err != nil {
return err return err
} }
@@ -277,7 +280,7 @@ func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
} }
comment := "WORKDIR " + runConfig.WorkingDir comment := "WORKDIR " + runConfig.WorkingDir
runConfigWithCommentCmd := copyRunConfig(runConfig, withCmdCommentString(comment, optionsOS)) runConfigWithCommentCmd := copyRunConfig(runConfig, withCmdCommentString(comment, baseImageOS))
containerID, err := d.builder.probeAndCreate(d.state, runConfigWithCommentCmd) containerID, err := d.builder.probeAndCreate(d.state, runConfigWithCommentCmd)
if err != nil || containerID == "" { if err != nil || containerID == "" {
return err return err
@@ -289,10 +292,10 @@ func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
return d.builder.commitContainer(d.state, containerID, runConfigWithCommentCmd) return d.builder.commitContainer(d.state, containerID, runConfigWithCommentCmd)
} }
func resolveCmdLine(cmd instructions.ShellDependantCmdLine, runConfig *container.Config, platform string) []string { func resolveCmdLine(cmd instructions.ShellDependantCmdLine, runConfig *container.Config, os string) []string {
result := cmd.CmdLine result := cmd.CmdLine
if cmd.PrependShell && result != nil { if cmd.PrependShell && result != nil {
result = append(getShell(runConfig, platform), result...) result = append(getShell(runConfig, os), result...)
} }
return result return result
} }
@@ -308,10 +311,11 @@ func resolveCmdLine(cmd instructions.ShellDependantCmdLine, runConfig *container
// RUN [ "echo", "hi" ] # echo hi // RUN [ "echo", "hi" ] # echo hi
// //
func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error { func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
if !system.IsOSSupported(d.state.operatingSystem) {
return system.ErrNotSupportedOperatingSystem
}
stateRunConfig := d.state.runConfig stateRunConfig := d.state.runConfig
optionsOS := system.ParsePlatform(d.builder.options.Platform).OS cmdFromArgs := resolveCmdLine(c.ShellDependantCmdLine, stateRunConfig, d.state.operatingSystem)
cmdFromArgs := resolveCmdLine(c.ShellDependantCmdLine, stateRunConfig, optionsOS)
buildArgs := d.state.buildArgs.FilterAllowed(stateRunConfig.Env) buildArgs := d.state.buildArgs.FilterAllowed(stateRunConfig.Env)
saveCmd := cmdFromArgs saveCmd := cmdFromArgs
@@ -510,7 +514,7 @@ func dispatchStopSignal(d dispatchRequest, c *instructions.StopSignalCommand) er
_, err := signal.ParseSignal(c.Signal) _, err := signal.ParseSignal(c.Signal)
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
d.state.runConfig.StopSignal = c.Signal d.state.runConfig.StopSignal = c.Signal
return d.builder.commit(d.state, fmt.Sprintf("STOPSIGNAL %v", c.Signal)) return d.builder.commit(d.state, fmt.Sprintf("STOPSIGNAL %v", c.Signal))

View File

@@ -31,7 +31,7 @@ func newBuilderWithMockBackend() *Builder {
Options: &types.ImageBuildOptions{Platform: runtime.GOOS}, Options: &types.ImageBuildOptions{Platform: runtime.GOOS},
Backend: mockBackend, Backend: mockBackend,
}), }),
imageProber: newImageProber(mockBackend, nil, runtime.GOOS, false), imageProber: newImageProber(mockBackend, nil, false),
containerManager: newContainerManager(mockBackend), containerManager: newContainerManager(mockBackend),
} }
return b return b
@@ -427,10 +427,10 @@ func TestRunWithBuildArgs(t *testing.T) {
} }
mockBackend := b.docker.(*MockBackend) mockBackend := b.docker.(*MockBackend)
mockBackend.makeImageCacheFunc = func(_ []string, _ string) builder.ImageCache { mockBackend.makeImageCacheFunc = func(_ []string) builder.ImageCache {
return imageCache return imageCache
} }
b.imageProber = newImageProber(mockBackend, nil, runtime.GOOS, false) b.imageProber = newImageProber(mockBackend, nil, false)
mockBackend.getImageFunc = func(_ string) (builder.Image, builder.ReleaseableLayer, error) { mockBackend.getImageFunc = func(_ string) (builder.Image, builder.ReleaseableLayer, error) {
return &mockImage{ return &mockImage{
id: "abcdef", id: "abcdef",

View File

@@ -1,15 +0,0 @@
package dockerfile
type validationError struct {
err error
}
func (e validationError) Error() string {
return e.err.Error()
}
func (e validationError) InvalidParameter() {}
func (e validationError) Cause() error {
return e.err
}

View File

@@ -21,12 +21,14 @@ package dockerfile
import ( import (
"reflect" "reflect"
"runtime"
"strconv" "strconv"
"strings" "strings"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder" "github.com/docker/docker/builder"
"github.com/docker/docker/builder/dockerfile/instructions" "github.com/docker/docker/builder/dockerfile/instructions"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/system"
"github.com/docker/docker/runconfig/opts" "github.com/docker/docker/runconfig/opts"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -37,7 +39,7 @@ func dispatch(d dispatchRequest, cmd instructions.Command) (err error) {
optionsOS := system.ParsePlatform(d.builder.options.Platform).OS optionsOS := system.ParsePlatform(d.builder.options.Platform).OS
err := c.CheckPlatform(optionsOS) err := c.CheckPlatform(optionsOS)
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
} }
runConfigEnv := d.state.runConfig.Env runConfigEnv := d.state.runConfig.Env
@@ -48,7 +50,7 @@ func dispatch(d dispatchRequest, cmd instructions.Command) (err error) {
return d.shlex.ProcessWord(word, envs) return d.shlex.ProcessWord(word, envs)
}) })
if err != nil { if err != nil {
return validationError{err} return errdefs.InvalidParameter(err)
} }
} }
@@ -103,13 +105,14 @@ func dispatch(d dispatchRequest, cmd instructions.Command) (err error) {
// dispatchState is a data object which is modified by dispatchers // dispatchState is a data object which is modified by dispatchers
type dispatchState struct { type dispatchState struct {
runConfig *container.Config runConfig *container.Config
maintainer string maintainer string
cmdSet bool cmdSet bool
imageID string imageID string
baseImage builder.Image baseImage builder.Image
stageName string stageName string
buildArgs *buildArgs buildArgs *buildArgs
operatingSystem string
} }
func newDispatchState(baseArgs *buildArgs) *dispatchState { func newDispatchState(baseArgs *buildArgs) *dispatchState {
@@ -209,9 +212,16 @@ func (s *dispatchState) hasFromImage() bool {
return s.imageID != "" || (s.baseImage != nil && s.baseImage.ImageID() == "") return s.imageID != "" || (s.baseImage != nil && s.baseImage.ImageID() == "")
} }
func (s *dispatchState) beginStage(stageName string, image builder.Image) { func (s *dispatchState) beginStage(stageName string, image builder.Image) error {
s.stageName = stageName s.stageName = stageName
s.imageID = image.ImageID() s.imageID = image.ImageID()
s.operatingSystem = image.OperatingSystem()
if s.operatingSystem == "" { // In case it isn't set
s.operatingSystem = runtime.GOOS
}
if !system.IsOSSupported(s.operatingSystem) {
return system.ErrNotSupportedOperatingSystem
}
if image.RunConfig() != nil { if image.RunConfig() != nil {
// copy avoids referencing the same instance when 2 stages have the same base // copy avoids referencing the same instance when 2 stages have the same base
@@ -223,12 +233,13 @@ func (s *dispatchState) beginStage(stageName string, image builder.Image) {
s.setDefaultPath() s.setDefaultPath()
s.runConfig.OpenStdin = false s.runConfig.OpenStdin = false
s.runConfig.StdinOnce = false s.runConfig.StdinOnce = false
return nil
} }
// Add the default PATH to runConfig.ENV if one exists for the operating system and there // Add the default PATH to runConfig.ENV if one exists for the operating system and there
// is no PATH set. Note that Windows containers on Windows won't have one as it's set by HCS // is no PATH set. Note that Windows containers on Windows won't have one as it's set by HCS
func (s *dispatchState) setDefaultPath() { func (s *dispatchState) setDefaultPath() {
defaultPath := system.DefaultPathEnv(s.baseImage.OperatingSystem()) defaultPath := system.DefaultPathEnv(s.operatingSystem)
if defaultPath == "" { if defaultPath == "" {
return return
} }

View File

@@ -19,13 +19,13 @@ type imageProber struct {
cacheBusted bool cacheBusted bool
} }
func newImageProber(cacheBuilder builder.ImageCacheBuilder, cacheFrom []string, platform string, noCache bool) ImageProber { func newImageProber(cacheBuilder builder.ImageCacheBuilder, cacheFrom []string, noCache bool) ImageProber {
if noCache { if noCache {
return &nopProber{} return &nopProber{}
} }
reset := func() builder.ImageCache { reset := func() builder.ImageCache {
return cacheBuilder.MakeImageCache(cacheFrom, platform) return cacheBuilder.MakeImageCache(cacheFrom)
} }
return &imageProber{cache: reset(), reset: reset} return &imageProber{cache: reset(), reset: reset}
} }

View File

@@ -11,7 +11,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"strconv" "runtime"
"strings" "strings"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@@ -23,10 +23,8 @@ import (
"github.com/docker/docker/pkg/containerfs" "github.com/docker/docker/pkg/containerfs"
"github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/system"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
lcUser "github.com/opencontainers/runc/libcontainer/user"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -124,8 +122,7 @@ func (b *Builder) commitContainer(dispatchState *dispatchState, id string, conta
} }
func (b *Builder) exportImage(state *dispatchState, imageMount *imageMount, runConfig *container.Config) error { func (b *Builder) exportImage(state *dispatchState, imageMount *imageMount, runConfig *container.Config) error {
optionsPlatform := system.ParsePlatform(b.options.Platform) newLayer, err := imageMount.Layer().Commit()
newLayer, err := imageMount.Layer().Commit(optionsPlatform.OS)
if err != nil { if err != nil {
return err return err
} }
@@ -153,7 +150,7 @@ func (b *Builder) exportImage(state *dispatchState, imageMount *imageMount, runC
return errors.Wrap(err, "failed to encode image config") return errors.Wrap(err, "failed to encode image config")
} }
exportedImage, err := b.docker.CreateImage(config, state.imageID, parentImage.OS) exportedImage, err := b.docker.CreateImage(config, state.imageID)
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to export image") return errors.Wrapf(err, "failed to export image")
} }
@@ -216,82 +213,6 @@ func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error
return b.exportImage(state, imageMount, runConfigWithCommentCmd) return b.exportImage(state, imageMount, runConfigWithCommentCmd)
} }
func parseChownFlag(chown, ctrRootPath string, idMappings *idtools.IDMappings) (idtools.IDPair, error) {
var userStr, grpStr string
parts := strings.Split(chown, ":")
if len(parts) > 2 {
return idtools.IDPair{}, errors.New("invalid chown string format: " + chown)
}
if len(parts) == 1 {
// if no group specified, use the user spec as group as well
userStr, grpStr = parts[0], parts[0]
} else {
userStr, grpStr = parts[0], parts[1]
}
passwdPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "passwd"), ctrRootPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/passwd path in container rootfs")
}
groupPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "group"), ctrRootPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/group path in container rootfs")
}
uid, err := lookupUser(userStr, passwdPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't find uid for user "+userStr)
}
gid, err := lookupGroup(grpStr, groupPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't find gid for group "+grpStr)
}
// convert as necessary because of user namespaces
chownPair, err := idMappings.ToHost(idtools.IDPair{UID: uid, GID: gid})
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "unable to convert uid/gid to host mapping")
}
return chownPair, nil
}
func lookupUser(userStr, filepath string) (int, error) {
// if the string is actually a uid integer, parse to int and return
// as we don't need to translate with the help of files
uid, err := strconv.Atoi(userStr)
if err == nil {
return uid, nil
}
users, err := lcUser.ParsePasswdFileFilter(filepath, func(u lcUser.User) bool {
return u.Name == userStr
})
if err != nil {
return 0, err
}
if len(users) == 0 {
return 0, errors.New("no such user: " + userStr)
}
return users[0].Uid, nil
}
func lookupGroup(groupStr, filepath string) (int, error) {
// if the string is actually a gid integer, parse to int and return
// as we don't need to translate with the help of files
gid, err := strconv.Atoi(groupStr)
if err == nil {
return gid, nil
}
groups, err := lcUser.ParseGroupFileFilter(filepath, func(g lcUser.Group) bool {
return g.Name == groupStr
})
if err != nil {
return 0, err
}
if len(groups) == 0 {
return 0, errors.New("no such group: " + groupStr)
}
return groups[0].Gid, nil
}
func createDestInfo(workingDir string, inst copyInstruction, imageMount *imageMount, platform string) (copyInfo, error) { func createDestInfo(workingDir string, inst copyInstruction, imageMount *imageMount, platform string) (copyInfo, error) {
// Twiddle the destination when it's a relative path - meaning, make it // Twiddle the destination when it's a relative path - meaning, make it
// relative to the WORKINGDIR // relative to the WORKINGDIR
@@ -501,15 +422,13 @@ func (b *Builder) probeAndCreate(dispatchState *dispatchState, runConfig *contai
} }
// Set a log config to override any default value set on the daemon // Set a log config to override any default value set on the daemon
hostConfig := &container.HostConfig{LogConfig: defaultLogConfig} hostConfig := &container.HostConfig{LogConfig: defaultLogConfig}
optionsPlatform := system.ParsePlatform(b.options.Platform) container, err := b.containerManager.Create(runConfig, hostConfig)
container, err := b.containerManager.Create(runConfig, hostConfig, optionsPlatform.OS)
return container.ID, err return container.ID, err
} }
func (b *Builder) create(runConfig *container.Config) (string, error) { func (b *Builder) create(runConfig *container.Config) (string, error) {
hostConfig := hostConfigFromOptions(b.options) hostConfig := hostConfigFromOptions(b.options)
optionsPlatform := system.ParsePlatform(b.options.Platform) container, err := b.containerManager.Create(runConfig, hostConfig)
container, err := b.containerManager.Create(runConfig, hostConfig, optionsPlatform.OS)
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -534,7 +453,7 @@ func hostConfigFromOptions(options *types.ImageBuildOptions) *container.HostConf
Ulimits: options.Ulimits, Ulimits: options.Ulimits,
} }
return &container.HostConfig{ hc := &container.HostConfig{
SecurityOpt: options.SecurityOpt, SecurityOpt: options.SecurityOpt,
Isolation: options.Isolation, Isolation: options.Isolation,
ShmSize: options.ShmSize, ShmSize: options.ShmSize,
@@ -544,6 +463,17 @@ func hostConfigFromOptions(options *types.ImageBuildOptions) *container.HostConf
LogConfig: defaultLogConfig, LogConfig: defaultLogConfig,
ExtraHosts: options.ExtraHosts, ExtraHosts: options.ExtraHosts,
} }
// For WCOW, the default of 20GB hard-coded in the platform
// is too small for builder scenarios where many users are
// using RUN statements to install large amounts of data.
// Use 127GB as that's the default size of a VHD in Hyper-V.
if runtime.GOOS == "windows" && options.Platform == "windows" {
hc.StorageOpt = make(map[string]string)
hc.StorageOpt["size"] = "127GB"
}
return hc
} }
// fromSlash works like filepath.FromSlash but with a given OS platform field // fromSlash works like filepath.FromSlash but with a given OS platform field

View File

@@ -0,0 +1,88 @@
package dockerfile
import (
"path/filepath"
"strconv"
"strings"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/symlink"
lcUser "github.com/opencontainers/runc/libcontainer/user"
"github.com/pkg/errors"
)
func parseChownFlag(chown, ctrRootPath string, idMappings *idtools.IDMappings) (idtools.IDPair, error) {
var userStr, grpStr string
parts := strings.Split(chown, ":")
if len(parts) > 2 {
return idtools.IDPair{}, errors.New("invalid chown string format: " + chown)
}
if len(parts) == 1 {
// if no group specified, use the user spec as group as well
userStr, grpStr = parts[0], parts[0]
} else {
userStr, grpStr = parts[0], parts[1]
}
passwdPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "passwd"), ctrRootPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/passwd path in container rootfs")
}
groupPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "group"), ctrRootPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/group path in container rootfs")
}
uid, err := lookupUser(userStr, passwdPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't find uid for user "+userStr)
}
gid, err := lookupGroup(grpStr, groupPath)
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "can't find gid for group "+grpStr)
}
// convert as necessary because of user namespaces
chownPair, err := idMappings.ToHost(idtools.IDPair{UID: uid, GID: gid})
if err != nil {
return idtools.IDPair{}, errors.Wrapf(err, "unable to convert uid/gid to host mapping")
}
return chownPair, nil
}
func lookupUser(userStr, filepath string) (int, error) {
// if the string is actually a uid integer, parse to int and return
// as we don't need to translate with the help of files
uid, err := strconv.Atoi(userStr)
if err == nil {
return uid, nil
}
users, err := lcUser.ParsePasswdFileFilter(filepath, func(u lcUser.User) bool {
return u.Name == userStr
})
if err != nil {
return 0, err
}
if len(users) == 0 {
return 0, errors.New("no such user: " + userStr)
}
return users[0].Uid, nil
}
func lookupGroup(groupStr, filepath string) (int, error) {
// if the string is actually a gid integer, parse to int and return
// as we don't need to translate with the help of files
gid, err := strconv.Atoi(groupStr)
if err == nil {
return gid, nil
}
groups, err := lcUser.ParseGroupFileFilter(filepath, func(g lcUser.Group) bool {
return g.Name == groupStr
})
if err != nil {
return 0, err
}
if len(groups) == 0 {
return 0, errors.New("no such group: " + groupStr)
}
return groups[0].Gid, nil
}

View File

@@ -0,0 +1,138 @@
package dockerfile
import (
"os"
"path/filepath"
"testing"
"github.com/docker/docker/pkg/idtools"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestChownFlagParsing(t *testing.T) {
testFiles := map[string]string{
"passwd": `root:x:0:0::/bin:/bin/false
bin:x:1:1::/bin:/bin/false
wwwwww:x:21:33::/bin:/bin/false
unicorn:x:1001:1002::/bin:/bin/false
`,
"group": `root:x:0:
bin:x:1:
wwwwww:x:33:
unicorn:x:1002:
somegrp:x:5555:
othergrp:x:6666:
`,
}
// test mappings for validating use of maps
idMaps := []idtools.IDMap{
{
ContainerID: 0,
HostID: 100000,
Size: 65536,
},
}
remapped := idtools.NewIDMappingsFromMaps(idMaps, idMaps)
unmapped := &idtools.IDMappings{}
contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test")
defer cleanup()
if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0755); err != nil {
t.Fatalf("error creating test directory: %v", err)
}
for filename, content := range testFiles {
createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0644)
}
// positive tests
for _, testcase := range []struct {
name string
chownStr string
idMapping *idtools.IDMappings
expected idtools.IDPair
}{
{
name: "UIDNoMap",
chownStr: "1",
idMapping: unmapped,
expected: idtools.IDPair{UID: 1, GID: 1},
},
{
name: "UIDGIDNoMap",
chownStr: "0:1",
idMapping: unmapped,
expected: idtools.IDPair{UID: 0, GID: 1},
},
{
name: "UIDWithMap",
chownStr: "0",
idMapping: remapped,
expected: idtools.IDPair{UID: 100000, GID: 100000},
},
{
name: "UIDGIDWithMap",
chownStr: "1:33",
idMapping: remapped,
expected: idtools.IDPair{UID: 100001, GID: 100033},
},
{
name: "UserNoMap",
chownStr: "bin:5555",
idMapping: unmapped,
expected: idtools.IDPair{UID: 1, GID: 5555},
},
{
name: "GroupWithMap",
chownStr: "0:unicorn",
idMapping: remapped,
expected: idtools.IDPair{UID: 100000, GID: 101002},
},
{
name: "UserOnlyWithMap",
chownStr: "unicorn",
idMapping: remapped,
expected: idtools.IDPair{UID: 101001, GID: 101002},
},
} {
t.Run(testcase.name, func(t *testing.T) {
idPair, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
require.NoError(t, err, "Failed to parse chown flag: %q", testcase.chownStr)
assert.Equal(t, testcase.expected, idPair, "chown flag mapping failure")
})
}
// error tests
for _, testcase := range []struct {
name string
chownStr string
idMapping *idtools.IDMappings
descr string
}{
{
name: "BadChownFlagFormat",
chownStr: "bob:1:555",
idMapping: unmapped,
descr: "invalid chown string format: bob:1:555",
},
{
name: "UserNoExist",
chownStr: "bob",
idMapping: unmapped,
descr: "can't find uid for user bob: no such user: bob",
},
{
name: "GroupNoExist",
chownStr: "root:bob",
idMapping: unmapped,
descr: "can't find gid for group bob: no such group: bob",
},
} {
t.Run(testcase.name, func(t *testing.T) {
_, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
assert.EqualError(t, err, testcase.descr, "Expected error string doesn't match")
})
}
}

View File

@@ -2,8 +2,6 @@ package dockerfile
import ( import (
"fmt" "fmt"
"os"
"path/filepath"
"runtime" "runtime"
"testing" "testing"
@@ -13,7 +11,6 @@ import (
"github.com/docker/docker/builder" "github.com/docker/docker/builder"
"github.com/docker/docker/builder/remotecontext" "github.com/docker/docker/builder/remotecontext"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -171,130 +168,3 @@ func TestDeepCopyRunConfig(t *testing.T) {
copy.Shell[0] = "sh" copy.Shell[0] = "sh"
assert.Equal(t, fullMutableRunConfig(), runConfig) assert.Equal(t, fullMutableRunConfig(), runConfig)
} }
func TestChownFlagParsing(t *testing.T) {
testFiles := map[string]string{
"passwd": `root:x:0:0::/bin:/bin/false
bin:x:1:1::/bin:/bin/false
wwwwww:x:21:33::/bin:/bin/false
unicorn:x:1001:1002::/bin:/bin/false
`,
"group": `root:x:0:
bin:x:1:
wwwwww:x:33:
unicorn:x:1002:
somegrp:x:5555:
othergrp:x:6666:
`,
}
// test mappings for validating use of maps
idMaps := []idtools.IDMap{
{
ContainerID: 0,
HostID: 100000,
Size: 65536,
},
}
remapped := idtools.NewIDMappingsFromMaps(idMaps, idMaps)
unmapped := &idtools.IDMappings{}
contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test")
defer cleanup()
if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0755); err != nil {
t.Fatalf("error creating test directory: %v", err)
}
for filename, content := range testFiles {
createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0644)
}
// positive tests
for _, testcase := range []struct {
name string
chownStr string
idMapping *idtools.IDMappings
expected idtools.IDPair
}{
{
name: "UIDNoMap",
chownStr: "1",
idMapping: unmapped,
expected: idtools.IDPair{UID: 1, GID: 1},
},
{
name: "UIDGIDNoMap",
chownStr: "0:1",
idMapping: unmapped,
expected: idtools.IDPair{UID: 0, GID: 1},
},
{
name: "UIDWithMap",
chownStr: "0",
idMapping: remapped,
expected: idtools.IDPair{UID: 100000, GID: 100000},
},
{
name: "UIDGIDWithMap",
chownStr: "1:33",
idMapping: remapped,
expected: idtools.IDPair{UID: 100001, GID: 100033},
},
{
name: "UserNoMap",
chownStr: "bin:5555",
idMapping: unmapped,
expected: idtools.IDPair{UID: 1, GID: 5555},
},
{
name: "GroupWithMap",
chownStr: "0:unicorn",
idMapping: remapped,
expected: idtools.IDPair{UID: 100000, GID: 101002},
},
{
name: "UserOnlyWithMap",
chownStr: "unicorn",
idMapping: remapped,
expected: idtools.IDPair{UID: 101001, GID: 101002},
},
} {
t.Run(testcase.name, func(t *testing.T) {
idPair, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
require.NoError(t, err, "Failed to parse chown flag: %q", testcase.chownStr)
assert.Equal(t, testcase.expected, idPair, "chown flag mapping failure")
})
}
// error tests
for _, testcase := range []struct {
name string
chownStr string
idMapping *idtools.IDMappings
descr string
}{
{
name: "BadChownFlagFormat",
chownStr: "bob:1:555",
idMapping: unmapped,
descr: "invalid chown string format: bob:1:555",
},
{
name: "UserNoExist",
chownStr: "bob",
idMapping: unmapped,
descr: "can't find uid for user bob: no such user: bob",
},
{
name: "GroupNoExist",
chownStr: "root:bob",
idMapping: unmapped,
descr: "can't find gid for group bob: no such group: bob",
},
} {
t.Run(testcase.name, func(t *testing.T) {
_, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
assert.EqualError(t, err, testcase.descr, "Expected error string doesn't match")
})
}
}

View File

@@ -0,0 +1,7 @@
package dockerfile
import "github.com/docker/docker/pkg/idtools"
func parseChownFlag(chown, ctrRootPath string, idMappings *idtools.IDMappings) (idtools.IDPair, error) {
return idMappings.RootPair(), nil
}

View File

@@ -20,7 +20,7 @@ type MockBackend struct {
containerCreateFunc func(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error) containerCreateFunc func(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
commitFunc func(string, *backend.ContainerCommitConfig) (string, error) commitFunc func(string, *backend.ContainerCommitConfig) (string, error)
getImageFunc func(string) (builder.Image, builder.ReleaseableLayer, error) getImageFunc func(string) (builder.Image, builder.ReleaseableLayer, error)
makeImageCacheFunc func(cacheFrom []string, platform string) builder.ImageCache makeImageCacheFunc func(cacheFrom []string) builder.ImageCache
} }
func (m *MockBackend) ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool, attached chan struct{}) error { func (m *MockBackend) ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool, attached chan struct{}) error {
@@ -73,14 +73,14 @@ func (m *MockBackend) GetImageAndReleasableLayer(ctx context.Context, refOrID st
return &mockImage{id: "theid"}, &mockLayer{}, nil return &mockImage{id: "theid"}, &mockLayer{}, nil
} }
func (m *MockBackend) MakeImageCache(cacheFrom []string, platform string) builder.ImageCache { func (m *MockBackend) MakeImageCache(cacheFrom []string) builder.ImageCache {
if m.makeImageCacheFunc != nil { if m.makeImageCacheFunc != nil {
return m.makeImageCacheFunc(cacheFrom, platform) return m.makeImageCacheFunc(cacheFrom)
} }
return nil return nil
} }
func (m *MockBackend) CreateImage(config []byte, parent string, platform string) (builder.Image, error) { func (m *MockBackend) CreateImage(config []byte, parent string) (builder.Image, error) {
return nil, nil return nil, nil
} }
@@ -127,7 +127,7 @@ func (l *mockLayer) Mount() (containerfs.ContainerFS, error) {
return containerfs.NewLocalContainerFS("mountPath"), nil return containerfs.NewLocalContainerFS("mountPath"), nil
} }
func (l *mockLayer) Commit(string) (builder.ReleaseableLayer, error) { func (l *mockLayer) Commit() (builder.ReleaseableLayer, error) {
return nil, nil return nil, nil
} }

View File

@@ -9,7 +9,7 @@
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
# #
# # Run the test suite: # # Run the test suite:
# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py # docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
# #
# # Publish a release: # # Publish a release:
# docker run --privileged \ # docker run --privileged \

View File

@@ -485,10 +485,7 @@ func (s *fsCacheStore) delete(id string) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.fs.Remove(src.BackendID); err != nil { return s.fs.Remove(src.BackendID)
return err
}
return nil
} }
type sourceMeta struct { type sourceMeta struct {

View File

@@ -1,75 +0,0 @@
package remotecontext
type notFoundError string
func (e notFoundError) Error() string {
return string(e)
}
func (notFoundError) NotFound() {}
type requestError string
func (e requestError) Error() string {
return string(e)
}
func (e requestError) InvalidParameter() {}
type unauthorizedError string
func (e unauthorizedError) Error() string {
return string(e)
}
func (unauthorizedError) Unauthorized() {}
type forbiddenError string
func (e forbiddenError) Error() string {
return string(e)
}
func (forbiddenError) Forbidden() {}
type dnsError struct {
cause error
}
func (e dnsError) Error() string {
return e.cause.Error()
}
func (e dnsError) NotFound() {}
func (e dnsError) Cause() error {
return e.cause
}
type systemError struct {
cause error
}
func (e systemError) Error() string {
return e.cause.Error()
}
func (e systemError) SystemError() {}
func (e systemError) Cause() error {
return e.cause
}
type unknownError struct {
cause error
}
func (e unknownError) Error() string {
return e.cause.Error()
}
func (unknownError) Unknown() {}
func (e unknownError) Cause() error {
return e.cause
}

View File

@@ -29,6 +29,10 @@ func Clone(remoteURL string) (string, error) {
return "", err return "", err
} }
return cloneGitRepo(repo)
}
func cloneGitRepo(repo gitRepo) (checkoutDir string, err error) {
fetch := fetchArgs(repo.remote, repo.ref) fetch := fetchArgs(repo.remote, repo.ref)
root, err := ioutil.TempDir("", "docker-build-git") root, err := ioutil.TempDir("", "docker-build-git")
@@ -36,6 +40,12 @@ func Clone(remoteURL string) (string, error) {
return "", err return "", err
} }
defer func() {
if err != nil {
os.RemoveAll(root)
}
}()
if out, err := gitWithinDir(root, "init"); err != nil { if out, err := gitWithinDir(root, "init"); err != nil {
return "", errors.Wrapf(err, "failed to init repo at %s: %s", root, out) return "", errors.Wrapf(err, "failed to init repo at %s: %s", root, out)
} }
@@ -50,7 +60,19 @@ func Clone(remoteURL string) (string, error) {
return "", errors.Wrapf(err, "error fetching: %s", output) return "", errors.Wrapf(err, "error fetching: %s", output)
} }
return checkoutGit(root, repo.ref, repo.subdir) checkoutDir, err = checkoutGit(root, repo.ref, repo.subdir)
if err != nil {
return "", err
}
cmd := exec.Command("git", "submodule", "update", "--init", "--recursive", "--depth=1")
cmd.Dir = root
output, err := cmd.CombinedOutput()
if err != nil {
return "", errors.Wrapf(err, "error initializing submodules: %s", output)
}
return checkoutDir, nil
} }
func parseRemoteURL(remoteURL string) (gitRepo, error) { func parseRemoteURL(remoteURL string) (gitRepo, error) {
@@ -96,7 +118,7 @@ func getRefAndSubdir(fragment string) (ref string, subdir string) {
} }
func fetchArgs(remoteURL string, ref string) []string { func fetchArgs(remoteURL string, ref string) []string {
args := []string{"fetch", "--recurse-submodules=yes"} args := []string{"fetch"}
if supportsShallowClone(remoteURL) { if supportsShallowClone(remoteURL) {
args = append(args, "--depth", "1") args = append(args, "--depth", "1")

View File

@@ -7,6 +7,7 @@ import (
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
@@ -61,7 +62,7 @@ func TestCloneArgsSmartHttp(t *testing.T) {
}) })
args := fetchArgs(serverURL.String(), "master") args := fetchArgs(serverURL.String(), "master")
exp := []string{"fetch", "--recurse-submodules=yes", "--depth", "1", "origin", "master"} exp := []string{"fetch", "--depth", "1", "origin", "master"}
assert.Equal(t, exp, args) assert.Equal(t, exp, args)
} }
@@ -77,13 +78,13 @@ func TestCloneArgsDumbHttp(t *testing.T) {
}) })
args := fetchArgs(serverURL.String(), "master") args := fetchArgs(serverURL.String(), "master")
exp := []string{"fetch", "--recurse-submodules=yes", "origin", "master"} exp := []string{"fetch", "origin", "master"}
assert.Equal(t, exp, args) assert.Equal(t, exp, args)
} }
func TestCloneArgsGit(t *testing.T) { func TestCloneArgsGit(t *testing.T) {
args := fetchArgs("git://github.com/docker/docker", "master") args := fetchArgs("git://github.com/docker/docker", "master")
exp := []string{"fetch", "--recurse-submodules=yes", "--depth", "1", "origin", "master"} exp := []string{"fetch", "--depth", "1", "origin", "master"}
assert.Equal(t, exp, args) assert.Equal(t, exp, args)
} }
@@ -165,24 +166,55 @@ func TestCheckoutGit(t *testing.T) {
_, err = gitWithinDir(gitDir, "checkout", "master") _, err = gitWithinDir(gitDir, "checkout", "master")
require.NoError(t, err) require.NoError(t, err)
// set up submodule
subrepoDir := filepath.Join(root, "subrepo")
_, err = git("init", subrepoDir)
require.NoError(t, err)
_, err = gitWithinDir(subrepoDir, "config", "user.email", "test@docker.com")
require.NoError(t, err)
_, err = gitWithinDir(subrepoDir, "config", "user.name", "Docker test")
require.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(subrepoDir, "subfile"), []byte("subcontents"), 0644)
require.NoError(t, err)
_, err = gitWithinDir(subrepoDir, "add", "-A")
require.NoError(t, err)
_, err = gitWithinDir(subrepoDir, "commit", "-am", "Subrepo initial")
require.NoError(t, err)
cmd := exec.Command("git", "submodule", "add", subrepoDir, "sub") // this command doesn't work with --work-tree
cmd.Dir = gitDir
require.NoError(t, cmd.Run())
_, err = gitWithinDir(gitDir, "add", "-A")
require.NoError(t, err)
_, err = gitWithinDir(gitDir, "commit", "-am", "With submodule")
require.NoError(t, err)
type singleCase struct { type singleCase struct {
frag string frag string
exp string exp string
fail bool fail bool
submodule bool
} }
cases := []singleCase{ cases := []singleCase{
{"", "FROM scratch", false}, {"", "FROM scratch", false, true},
{"master", "FROM scratch", false}, {"master", "FROM scratch", false, true},
{":subdir", "FROM scratch" + eol + "EXPOSE 5000", false}, {":subdir", "FROM scratch" + eol + "EXPOSE 5000", false, false},
{":nosubdir", "", true}, // missing directory error {":nosubdir", "", true, false}, // missing directory error
{":Dockerfile", "", true}, // not a directory error {":Dockerfile", "", true, false}, // not a directory error
{"master:nosubdir", "", true}, {"master:nosubdir", "", true, false},
{"master:subdir", "FROM scratch" + eol + "EXPOSE 5000", false}, {"master:subdir", "FROM scratch" + eol + "EXPOSE 5000", false, false},
{"master:../subdir", "", true}, {"master:../subdir", "", true, false},
{"test", "FROM scratch" + eol + "EXPOSE 3000", false}, {"test", "FROM scratch" + eol + "EXPOSE 3000", false, false},
{"test:", "FROM scratch" + eol + "EXPOSE 3000", false}, {"test:", "FROM scratch" + eol + "EXPOSE 3000", false, false},
{"test:subdir", "FROM busybox" + eol + "EXPOSE 5000", false}, {"test:subdir", "FROM busybox" + eol + "EXPOSE 5000", false, false},
} }
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
@@ -197,12 +229,23 @@ func TestCheckoutGit(t *testing.T) {
for _, c := range cases { for _, c := range cases {
ref, subdir := getRefAndSubdir(c.frag) ref, subdir := getRefAndSubdir(c.frag)
r, err := checkoutGit(gitDir, ref, subdir) r, err := cloneGitRepo(gitRepo{remote: gitDir, ref: ref, subdir: subdir})
if c.fail { if c.fail {
assert.Error(t, err) assert.Error(t, err)
continue continue
} }
require.NoError(t, err)
defer os.RemoveAll(r)
if c.submodule {
b, err := ioutil.ReadFile(filepath.Join(r, "sub/subfile"))
require.NoError(t, err)
assert.Equal(t, "subcontents", string(b))
} else {
_, err := os.Stat(filepath.Join(r, "sub/subfile"))
require.Error(t, err)
require.True(t, os.IsNotExist(err))
}
b, err := ioutil.ReadFile(filepath.Join(r, "Dockerfile")) b, err := ioutil.ReadFile(filepath.Join(r, "Dockerfile"))
require.NoError(t, err) require.NoError(t, err)

View File

@@ -10,6 +10,7 @@ import (
"net/url" "net/url"
"regexp" "regexp"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -26,7 +27,7 @@ var mimeRe = regexp.MustCompile(acceptableRemoteMIME)
func downloadRemote(remoteURL string) (string, io.ReadCloser, error) { func downloadRemote(remoteURL string) (string, io.ReadCloser, error) {
response, err := GetWithStatusError(remoteURL) response, err := GetWithStatusError(remoteURL)
if err != nil { if err != nil {
return "", nil, fmt.Errorf("error downloading remote context %s: %v", remoteURL, err) return "", nil, errors.Wrapf(err, "error downloading remote context %s", remoteURL)
} }
contentType, contextReader, err := inspectResponse( contentType, contextReader, err := inspectResponse(
@@ -35,7 +36,7 @@ func downloadRemote(remoteURL string) (string, io.ReadCloser, error) {
response.ContentLength) response.ContentLength)
if err != nil { if err != nil {
response.Body.Close() response.Body.Close()
return "", nil, fmt.Errorf("error detecting content type for remote %s: %v", remoteURL, err) return "", nil, errors.Wrapf(err, "error detecting content type for remote %s", remoteURL)
} }
return contentType, ioutils.NewReadCloserWrapper(contextReader, response.Body.Close), nil return contentType, ioutils.NewReadCloserWrapper(contextReader, response.Body.Close), nil
@@ -47,10 +48,10 @@ func GetWithStatusError(address string) (resp *http.Response, err error) {
if resp, err = http.Get(address); err != nil { if resp, err = http.Get(address); err != nil {
if uerr, ok := err.(*url.Error); ok { if uerr, ok := err.(*url.Error); ok {
if derr, ok := uerr.Err.(*net.DNSError); ok && !derr.IsTimeout { if derr, ok := uerr.Err.(*net.DNSError); ok && !derr.IsTimeout {
return nil, dnsError{err} return nil, errdefs.NotFound(err)
} }
} }
return nil, systemError{err} return nil, errdefs.System(err)
} }
if resp.StatusCode < 400 { if resp.StatusCode < 400 {
return resp, nil return resp, nil
@@ -59,21 +60,21 @@ func GetWithStatusError(address string) (resp *http.Response, err error) {
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close() resp.Body.Close()
if err != nil { if err != nil {
return nil, errors.Wrap(systemError{err}, msg+": error reading body") return nil, errdefs.System(errors.New(msg + ": error reading body"))
} }
msg += ": " + string(bytes.TrimSpace(body)) msg += ": " + string(bytes.TrimSpace(body))
switch resp.StatusCode { switch resp.StatusCode {
case http.StatusNotFound: case http.StatusNotFound:
return nil, notFoundError(msg) return nil, errdefs.NotFound(errors.New(msg))
case http.StatusBadRequest: case http.StatusBadRequest:
return nil, requestError(msg) return nil, errdefs.InvalidParameter(errors.New(msg))
case http.StatusUnauthorized: case http.StatusUnauthorized:
return nil, unauthorizedError(msg) return nil, errdefs.Unauthorized(errors.New(msg))
case http.StatusForbidden: case http.StatusForbidden:
return nil, forbiddenError(msg) return nil, errdefs.Forbidden(errors.New(msg))
} }
return nil, unknownError{errors.New(msg)} return nil, errdefs.Unknown(errors.New(msg))
} }
// inspectResponse looks into the http response data at r to determine whether its // inspectResponse looks into the http response data at r to determine whether its

View File

@@ -30,7 +30,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
} }
// CopyToContainer copies content into the container filesystem. // CopyToContainer copies content into the container filesystem.
// Note that `content` must be a Reader for a TAR // Note that `content` must be a Reader for a TAR archive
func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error { func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error {
query := url.Values{} query := url.Values{}
query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
@@ -59,7 +59,7 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string,
} }
// CopyFromContainer gets the content from the container and returns it as a Reader // CopyFromContainer gets the content from the container and returns it as a Reader
// to manipulate it in the host. It's up to the caller to close the reader. // for a TAR archive to manipulate it in the host. It's up to the caller to close the reader.
func (cli *Client) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { func (cli *Client) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
query := make(url.Values, 1) query := make(url.Values, 1)
query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.

View File

@@ -74,7 +74,7 @@ func (cli *Client) ContainerLogs(ctx context.Context, container string, options
resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil) resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil)
if err != nil { if err != nil {
return nil, err return nil, wrapResponseError(err, resp, "container", container)
} }
return resp.body, nil return resp.body, nil
} }

View File

@@ -18,6 +18,16 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
) )
func TestContainerLogsNotFoundError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusNotFound, "Not found")),
}
_, err := client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{})
if !IsErrNotFound(err) {
t.Fatalf("expected a not found error, got %v", err)
}
}
func TestContainerLogsError(t *testing.T) { func TestContainerLogsError(t *testing.T) {
client := &Client{ client := &Client{
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),

View File

@@ -6,11 +6,11 @@ import (
"time" "time"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network" networktypes "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
volumetypes "github.com/docker/docker/api/types/volume" volumetypes "github.com/docker/docker/api/types/volume"
@@ -43,8 +43,8 @@ type CommonAPIClient interface {
type ContainerAPIClient interface { type ContainerAPIClient interface {
ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error)
ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error) ContainerCreate(ctx context.Context, config *containertypes.Config, hostConfig *containertypes.HostConfig, networkingConfig *networktypes.NetworkingConfig, containerName string) (containertypes.ContainerCreateCreatedBody, error)
ContainerDiff(ctx context.Context, container string) ([]container.ContainerChangeResponseItem, error) ContainerDiff(ctx context.Context, container string) ([]containertypes.ContainerChangeResponseItem, error)
ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error)
ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error)
@@ -65,10 +65,10 @@ type ContainerAPIClient interface {
ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error) ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error)
ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error
ContainerStop(ctx context.Context, container string, timeout *time.Duration) error ContainerStop(ctx context.Context, container string, timeout *time.Duration) error
ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error) ContainerTop(ctx context.Context, container string, arguments []string) (containertypes.ContainerTopOKBody, error)
ContainerUnpause(ctx context.Context, container string) error ContainerUnpause(ctx context.Context, container string) error
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error) ContainerUpdate(ctx context.Context, container string, updateConfig containertypes.UpdateConfig) (containertypes.ContainerUpdateOKBody, error)
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) ContainerWait(ctx context.Context, container string, condition containertypes.WaitCondition) (<-chan containertypes.ContainerWaitOKBody, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error)
@@ -100,13 +100,13 @@ type ImageAPIClient interface {
// NetworkAPIClient defines API client methods for the networks // NetworkAPIClient defines API client methods for the networks
type NetworkAPIClient interface { type NetworkAPIClient interface {
NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error NetworkConnect(ctx context.Context, network, container string, config *networktypes.EndpointSettings) error
NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error)
NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error NetworkDisconnect(ctx context.Context, network, container string, force bool) error
NetworkInspect(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) NetworkInspect(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, error)
NetworkInspectWithRaw(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error) NetworkInspectWithRaw(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error)
NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error)
NetworkRemove(ctx context.Context, networkID string) error NetworkRemove(ctx context.Context, network string) error
NetworksPrune(ctx context.Context, pruneFilter filters.Args) (types.NetworksPruneReport, error) NetworksPrune(ctx context.Context, pruneFilter filters.Args) (types.NetworksPruneReport, error)
} }

View File

@@ -59,13 +59,15 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", config.DefaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull") flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", config.DefaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull")
flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", config.DefaultMaxConcurrentUploads, "Set the max concurrent uploads for each push") flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", config.DefaultMaxConcurrentUploads, "Set the max concurrent uploads for each push")
flags.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", defaultShutdownTimeout, "Set the default shutdown timeout") flags.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", defaultShutdownTimeout, "Set the default shutdown timeout")
flags.IntVar(&conf.NetworkDiagnosticPort, "network-diagnostic-port", 0, "TCP port number of the network diagnostic server")
flags.MarkHidden("network-diagnostic-port")
flags.StringVar(&conf.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address") flags.StringVar(&conf.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address")
flags.BoolVar(&conf.Experimental, "experimental", false, "Enable experimental features") flags.BoolVar(&conf.Experimental, "experimental", false, "Enable experimental features")
flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on") flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on")
flags.Var(opts.NewListOptsRef(&conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resource", "Advertise user-defined resource") flags.Var(opts.NewListOptsRef(&conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resources", "Advertise user-defined resource")
flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU") flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU")
@@ -90,6 +92,8 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.
flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication") flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
// TODO: Remove this flag after 3 release cycles (18.03)
flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries") flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries")
flags.MarkHidden("disable-legacy-registry")
} }
} }

View File

@@ -1,9 +0,0 @@
package main
import (
"github.com/docker/docker/daemon/config"
"github.com/spf13/pflag"
)
func attachExperimentalFlags(conf *config.Config, cmd *pflag.FlagSet) {
}

View File

@@ -1,17 +0,0 @@
package main
import (
"github.com/docker/docker/daemon/config"
"github.com/spf13/pflag"
)
// installConfigFlags adds flags to the pflag.FlagSet to configure the daemon
func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
// First handle install flags which are consistent cross-platform
installCommonConfigFlags(conf, flags)
// Then install flags common to unix platforms
installUnixConfigFlags(conf, flags)
attachExperimentalFlags(conf, flags)
}

View File

@@ -44,6 +44,4 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
flags.Var(&conf.ShmSize, "default-shm-size", "Default shm size for containers") flags.Var(&conf.ShmSize, "default-shm-size", "Default shm size for containers")
flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers") flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers")
flags.StringVar(&conf.IpcMode, "default-ipc-mode", config.DefaultIpcMode, `Default mode for containers ipc ("shareable" | "private")`) flags.StringVar(&conf.IpcMode, "default-ipc-mode", config.DefaultIpcMode, `Default mode for containers ipc ("shareable" | "private")`)
attachExperimentalFlags(conf, flags)
} }

View File

@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"time" "time"
@@ -472,8 +473,15 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
return nil, err return nil, err
} }
if !conf.V2Only { if runtime.GOOS != "windows" {
logrus.Warnf(`The "disable-legacy-registry" option is deprecated and wil be removed in Docker v17.12. Interacting with legacy (v1) registries will no longer be supported in Docker v17.12"`) if flags.Changed("disable-legacy-registry") {
// TODO: Remove this error after 3 release cycles (18.03)
return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported")
}
if !conf.V2Only {
// TODO: Remove this error after 3 release cycles (18.03)
return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported")
}
} }
if flags.Changed("graph") { if flags.Changed("graph") {

View File

@@ -1,5 +1,3 @@
// +build linux
package main package main
import systemdDaemon "github.com/coreos/go-systemd/daemon" import systemdDaemon "github.com/coreos/go-systemd/daemon"

View File

@@ -14,7 +14,6 @@ import (
"github.com/docker/docker/cmd/dockerd/hack" "github.com/docker/docker/cmd/dockerd/hack"
"github.com/docker/docker/daemon" "github.com/docker/docker/daemon"
"github.com/docker/docker/libcontainerd" "github.com/docker/docker/libcontainerd"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/libnetwork/portallocator" "github.com/docker/libnetwork/portallocator"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
@@ -38,24 +37,13 @@ func getDaemonConfDir(_ string) string {
} }
func (cli *DaemonCli) getPlatformRemoteOptions() ([]libcontainerd.RemoteOption, error) { func (cli *DaemonCli) getPlatformRemoteOptions() ([]libcontainerd.RemoteOption, error) {
// On older kernel, letting putting the containerd-shim in its own
// namespace will effectively prevent operations such as unlink, rename
// and remove on mountpoints that were present at the time the shim
// namespace was created. This would led to a famous EBUSY will trying to
// remove shm mounts.
var noNewNS bool
if !kernel.CheckKernelVersion(3, 18, 0) {
noNewNS = true
}
opts := []libcontainerd.RemoteOption{ opts := []libcontainerd.RemoteOption{
libcontainerd.WithOOMScore(cli.Config.OOMScoreAdjust), libcontainerd.WithOOMScore(cli.Config.OOMScoreAdjust),
libcontainerd.WithPlugin("linux", &linux.Config{ libcontainerd.WithPlugin("linux", &linux.Config{
Shim: daemon.DefaultShimBinary, Shim: daemon.DefaultShimBinary,
Runtime: daemon.DefaultRuntimeBinary, Runtime: daemon.DefaultRuntimeBinary,
RuntimeRoot: filepath.Join(cli.Config.Root, "runc"), RuntimeRoot: filepath.Join(cli.Config.Root, "runc"),
ShimDebug: cli.Config.Debug, ShimDebug: cli.Config.Debug,
ShimNoMountNS: noNewNS,
}), }),
} }
if cli.Config.Debug { if cli.Config.Debug {

View File

@@ -97,15 +97,3 @@ func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
assert.True(t, loadedConfig.EnableUserlandProxy) assert.True(t, loadedConfig.EnableUserlandProxy)
} }
func TestLoadDaemonConfigWithLegacyRegistryOptions(t *testing.T) {
content := `{"disable-legacy-registry": false}`
tempFile := fs.NewFile(t, "config", fs.WithContent(content))
defer tempFile.Remove()
opts := defaultOptions(tempFile.Path())
loadedConfig, err := loadDaemonCliConfig(opts)
require.NoError(t, err)
require.NotNil(t, loadedConfig)
assert.False(t, loadedConfig.V2Only)
}

View File

@@ -15,7 +15,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/containerd/containerd" "github.com/containerd/containerd/cio"
containertypes "github.com/docker/docker/api/types/container" containertypes "github.com/docker/docker/api/types/container"
mounttypes "github.com/docker/docker/api/types/mount" mounttypes "github.com/docker/docker/api/types/mount"
networktypes "github.com/docker/docker/api/types/network" networktypes "github.com/docker/docker/api/types/network"
@@ -27,7 +27,6 @@ import (
"github.com/docker/docker/daemon/network" "github.com/docker/docker/daemon/network"
"github.com/docker/docker/image" "github.com/docker/docker/image"
"github.com/docker/docker/layer" "github.com/docker/docker/layer"
"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/opts" "github.com/docker/docker/opts"
"github.com/docker/docker/pkg/containerfs" "github.com/docker/docker/pkg/containerfs"
"github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/idtools"
@@ -1004,7 +1003,7 @@ func (container *Container) CloseStreams() error {
} }
// InitializeStdio is called by libcontainerd to connect the stdio. // InitializeStdio is called by libcontainerd to connect the stdio.
func (container *Container) InitializeStdio(iop *libcontainerd.IOPipe) (containerd.IO, error) { func (container *Container) InitializeStdio(iop *cio.DirectIO) (cio.IO, error) {
if err := container.startLogging(); err != nil { if err := container.startLogging(); err != nil {
container.Reset(false) container.Reset(false)
return nil, err return nil, err
@@ -1020,17 +1019,26 @@ func (container *Container) InitializeStdio(iop *libcontainerd.IOPipe) (containe
} }
} }
return &cio{IO: iop, sc: container.StreamConfig}, nil return &rio{IO: iop, sc: container.StreamConfig}, nil
}
// MountsResourcePath returns the path where mounts are stored for the given mount
func (container *Container) MountsResourcePath(mount string) (string, error) {
return container.GetRootResourcePath(filepath.Join("mounts", mount))
} }
// SecretMountPath returns the path of the secret mount for the container // SecretMountPath returns the path of the secret mount for the container
func (container *Container) SecretMountPath() string { func (container *Container) SecretMountPath() (string, error) {
return filepath.Join(container.Root, "secrets") return container.MountsResourcePath("secrets")
} }
// SecretFilePath returns the path to the location of a secret on the host. // SecretFilePath returns the path to the location of a secret on the host.
func (container *Container) SecretFilePath(secretRef swarmtypes.SecretReference) string { func (container *Container) SecretFilePath(secretRef swarmtypes.SecretReference) (string, error) {
return filepath.Join(container.SecretMountPath(), secretRef.SecretID) secrets, err := container.SecretMountPath()
if err != nil {
return "", err
}
return filepath.Join(secrets, secretRef.SecretID), nil
} }
func getSecretTargetPath(r *swarmtypes.SecretReference) string { func getSecretTargetPath(r *swarmtypes.SecretReference) string {
@@ -1043,13 +1051,17 @@ func getSecretTargetPath(r *swarmtypes.SecretReference) string {
// ConfigsDirPath returns the path to the directory where configs are stored on // ConfigsDirPath returns the path to the directory where configs are stored on
// disk. // disk.
func (container *Container) ConfigsDirPath() string { func (container *Container) ConfigsDirPath() (string, error) {
return filepath.Join(container.Root, "configs") return container.GetRootResourcePath("configs")
} }
// ConfigFilePath returns the path to the on-disk location of a config. // ConfigFilePath returns the path to the on-disk location of a config.
func (container *Container) ConfigFilePath(configRef swarmtypes.ConfigReference) string { func (container *Container) ConfigFilePath(configRef swarmtypes.ConfigReference) (string, error) {
return filepath.Join(container.ConfigsDirPath(), configRef.ConfigID) configs, err := container.ConfigsDirPath()
if err != nil {
return "", err
}
return filepath.Join(configs, configRef.ConfigID), nil
} }
// CreateDaemonEnvironment creates a new environment variable slice for this container. // CreateDaemonEnvironment creates a new environment variable slice for this container.
@@ -1078,19 +1090,19 @@ func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string
return env return env
} }
type cio struct { type rio struct {
containerd.IO cio.IO
sc *stream.Config sc *stream.Config
} }
func (i *cio) Close() error { func (i *rio) Close() error {
i.IO.Close() i.IO.Close()
return i.sc.CloseStreams() return i.sc.CloseStreams()
} }
func (i *cio) Wait() { func (i *rio) Wait() {
i.sc.Wait() i.sc.Wait()
i.IO.Wait() i.IO.Wait()

View File

@@ -151,7 +151,7 @@ func (container *Container) CopyImagePathContent(v volume.Volume, destination st
// ShmResourcePath returns path to shm // ShmResourcePath returns path to shm
func (container *Container) ShmResourcePath() (string, error) { func (container *Container) ShmResourcePath() (string, error) {
return container.GetRootResourcePath("shm") return container.MountsResourcePath("shm")
} }
// HasMountFor checks if path is a mountpoint // HasMountFor checks if path is a mountpoint
@@ -218,49 +218,61 @@ func (container *Container) IpcMounts() []Mount {
} }
// SecretMounts returns the mounts for the secret path. // SecretMounts returns the mounts for the secret path.
func (container *Container) SecretMounts() []Mount { func (container *Container) SecretMounts() ([]Mount, error) {
var mounts []Mount var mounts []Mount
for _, r := range container.SecretReferences { for _, r := range container.SecretReferences {
if r.File == nil { if r.File == nil {
continue continue
} }
src, err := container.SecretFilePath(*r)
if err != nil {
return nil, err
}
mounts = append(mounts, Mount{ mounts = append(mounts, Mount{
Source: container.SecretFilePath(*r), Source: src,
Destination: getSecretTargetPath(r), Destination: getSecretTargetPath(r),
Writable: false, Writable: false,
}) })
} }
return mounts return mounts, nil
} }
// UnmountSecrets unmounts the local tmpfs for secrets // UnmountSecrets unmounts the local tmpfs for secrets
func (container *Container) UnmountSecrets() error { func (container *Container) UnmountSecrets() error {
if _, err := os.Stat(container.SecretMountPath()); err != nil { p, err := container.SecretMountPath()
if err != nil {
return err
}
if _, err := os.Stat(p); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil return nil
} }
return err return err
} }
return detachMounted(container.SecretMountPath()) return mount.RecursiveUnmount(p)
} }
// ConfigMounts returns the mounts for configs. // ConfigMounts returns the mounts for configs.
func (container *Container) ConfigMounts() []Mount { func (container *Container) ConfigMounts() ([]Mount, error) {
var mounts []Mount var mounts []Mount
for _, configRef := range container.ConfigReferences { for _, configRef := range container.ConfigReferences {
if configRef.File == nil { if configRef.File == nil {
continue continue
} }
src, err := container.ConfigFilePath(*configRef)
if err != nil {
return nil, err
}
mounts = append(mounts, Mount{ mounts = append(mounts, Mount{
Source: container.ConfigFilePath(*configRef), Source: src,
Destination: configRef.File.Name, Destination: configRef.File.Name,
Writable: false, Writable: false,
}) })
} }
return mounts return mounts, nil
} }
type conflictingUpdateOptions string type conflictingUpdateOptions string
@@ -332,6 +344,12 @@ func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfi
if resources.KernelMemory != 0 { if resources.KernelMemory != 0 {
cResources.KernelMemory = resources.KernelMemory cResources.KernelMemory = resources.KernelMemory
} }
if resources.CPURealtimePeriod != 0 {
cResources.CPURealtimePeriod = resources.CPURealtimePeriod
}
if resources.CPURealtimeRuntime != 0 {
cResources.CPURealtimeRuntime = resources.CPURealtimeRuntime
}
// update HostConfig of container // update HostConfig of container
if hostConfig.RestartPolicy.Name != "" { if hostConfig.RestartPolicy.Name != "" {

View File

@@ -1,5 +1,3 @@
// +build windows
package container package container
import ( import (
@@ -56,22 +54,30 @@ func (container *Container) CreateSecretSymlinks() error {
// SecretMounts returns the mount for the secret path. // SecretMounts returns the mount for the secret path.
// All secrets are stored in a single mount on Windows. Target symlinks are // All secrets are stored in a single mount on Windows. Target symlinks are
// created for each secret, pointing to the files in this mount. // created for each secret, pointing to the files in this mount.
func (container *Container) SecretMounts() []Mount { func (container *Container) SecretMounts() ([]Mount, error) {
var mounts []Mount var mounts []Mount
if len(container.SecretReferences) > 0 { if len(container.SecretReferences) > 0 {
src, err := container.SecretMountPath()
if err != nil {
return nil, err
}
mounts = append(mounts, Mount{ mounts = append(mounts, Mount{
Source: container.SecretMountPath(), Source: src,
Destination: containerInternalSecretMountPath, Destination: containerInternalSecretMountPath,
Writable: false, Writable: false,
}) })
} }
return mounts return mounts, nil
} }
// UnmountSecrets unmounts the fs for secrets // UnmountSecrets unmounts the fs for secrets
func (container *Container) UnmountSecrets() error { func (container *Container) UnmountSecrets() error {
return os.RemoveAll(container.SecretMountPath()) p, err := container.SecretMountPath()
if err != nil {
return err
}
return os.RemoveAll(p)
} }
// CreateConfigSymlinks creates symlinks to files in the config mount. // CreateConfigSymlinks creates symlinks to files in the config mount.
@@ -98,17 +104,21 @@ func (container *Container) CreateConfigSymlinks() error {
// ConfigMounts returns the mount for configs. // ConfigMounts returns the mount for configs.
// All configs are stored in a single mount on Windows. Target symlinks are // All configs are stored in a single mount on Windows. Target symlinks are
// created for each config, pointing to the files in this mount. // created for each config, pointing to the files in this mount.
func (container *Container) ConfigMounts() []Mount { func (container *Container) ConfigMounts() ([]Mount, error) {
var mounts []Mount var mounts []Mount
if len(container.ConfigReferences) > 0 { if len(container.ConfigReferences) > 0 {
src, err := container.ConfigsDirPath()
if err != nil {
return nil, err
}
mounts = append(mounts, Mount{ mounts = append(mounts, Mount{
Source: container.ConfigsDirPath(), Source: src,
Destination: containerInternalConfigsDirPath, Destination: containerInternalConfigsDirPath,
Writable: false, Writable: false,
}) })
} }
return mounts return mounts, nil
} }
// DetachAndUnmount unmounts all volumes. // DetachAndUnmount unmounts all volumes.

View File

@@ -102,15 +102,6 @@ func (s *State) String() string {
return fmt.Sprintf("Exited (%d) %s ago", s.ExitCodeValue, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt))) return fmt.Sprintf("Exited (%d) %s ago", s.ExitCodeValue, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
} }
// HealthString returns a single string to describe health status.
func (s *State) HealthString() string {
if s.Health == nil {
return types.NoHealthcheck
}
return s.Health.String()
}
// IsValidHealthString checks if the provided string is a valid container health status or not. // IsValidHealthString checks if the provided string is a valid container health status or not.
func IsValidHealthString(s string) bool { func IsValidHealthString(s string) bool {
return s == types.Starting || return s == types.Starting ||

View File

@@ -1,7 +0,0 @@
package container
// setFromExitStatus is a platform specific helper function to set the state
// based on the ExitStatus structure.
func (s *State) setFromExitStatus(exitStatus *ExitStatus) {
s.ExitCodeValue = exitStatus.ExitCode
}

View File

@@ -7,7 +7,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/docker/docker/libcontainerd" "github.com/containerd/containerd/cio"
"github.com/docker/docker/pkg/broadcaster" "github.com/docker/docker/pkg/broadcaster"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/pools" "github.com/docker/docker/pkg/pools"
@@ -114,7 +114,7 @@ func (c *Config) CloseStreams() error {
} }
// CopyToPipe connects streamconfig with a libcontainerd.IOPipe // CopyToPipe connects streamconfig with a libcontainerd.IOPipe
func (c *Config) CopyToPipe(iop *libcontainerd.IOPipe) { func (c *Config) CopyToPipe(iop *cio.DirectIO) {
copyFunc := func(w io.Writer, r io.ReadCloser) { copyFunc := func(w io.Writer, r io.ReadCloser) {
c.Add(1) c.Add(1)
go func() { go func() {

View File

@@ -14,9 +14,8 @@ import (
) )
const ( const (
memdbContainersTable = "containers" memdbContainersTable = "containers"
memdbNamesTable = "names" memdbNamesTable = "names"
memdbIDIndex = "id" memdbIDIndex = "id"
memdbContainerIDIndex = "containerid" memdbContainerIDIndex = "containerid"
) )
@@ -191,11 +190,7 @@ func (db *memDB) ReserveName(name, containerID string) error {
} }
return nil return nil
} }
return txn.Insert(memdbNamesTable, nameAssociation{name: name, containerID: containerID})
if err := txn.Insert(memdbNamesTable, nameAssociation{name: name, containerID: containerID}); err != nil {
return err
}
return nil
}) })
} }
@@ -295,6 +290,10 @@ func (v *memdbView) GetAllNames() map[string][]string {
// transform maps a (deep) copied Container object to what queries need. // transform maps a (deep) copied Container object to what queries need.
// A lock on the Container is not held because these are immutable deep copies. // A lock on the Container is not held because these are immutable deep copies.
func (v *memdbView) transform(container *Container) *Snapshot { func (v *memdbView) transform(container *Container) *Snapshot {
health := types.NoHealthcheck
if container.Health != nil {
health = container.Health.Status()
}
snapshot := &Snapshot{ snapshot := &Snapshot{
Container: types.Container{ Container: types.Container{
ID: container.ID, ID: container.ID,
@@ -313,7 +312,7 @@ func (v *memdbView) transform(container *Container) *Snapshot {
Managed: container.Managed, Managed: container.Managed,
ExposedPorts: make(nat.PortSet), ExposedPorts: make(nat.PortSet),
PortBindings: make(nat.PortSet), PortBindings: make(nat.PortSet),
Health: container.HealthString(), Health: health,
Running: container.Running, Running: container.Running,
Paused: container.Paused, Paused: container.Paused,
ExitCode: container.ExitCode(), ExitCode: container.ExitCode(),

View File

@@ -6,6 +6,7 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container" containertypes "github.com/docker/docker/api/types/container"
"github.com/pborman/uuid" "github.com/pborman/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -159,3 +160,26 @@ func TestNames(t *testing.T) {
view = db.Snapshot() view = db.Snapshot()
assert.Equal(t, map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames()) assert.Equal(t, map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames())
} }
// Test case for GitHub issue 35920
func TestViewWithHealthCheck(t *testing.T) {
var (
db, _ = NewViewDB()
one = newContainer(t)
)
one.Health = &Health{
Health: types.Health{
Status: "starting",
},
}
if err := one.CheckpointTo(db); err != nil {
t.Fatal(err)
}
s, err := db.Snapshot().Get(one.ID)
if err != nil {
t.Fatal(err)
}
if s == nil || s.Health != "starting" {
t.Fatalf("expected Health=starting. Got: %+v", s)
}
}

View File

@@ -7,7 +7,7 @@ FROM aarch64/debian:jessie
RUN echo deb http://ftp.debian.org/debian jessie-backports main > /etc/apt/sources.list.d/backports.list RUN echo deb http://ftp.debian.org/debian jessie-backports main > /etc/apt/sources.list.d/backports.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

View File

@@ -6,7 +6,7 @@ FROM aarch64/debian:stretch
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

View File

@@ -6,7 +6,7 @@ FROM aarch64/ubuntu:trusty
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

View File

@@ -6,7 +6,7 @@ FROM aarch64/ubuntu:xenial
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-dev libseccomp-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-arm64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

View File

@@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

View File

@@ -10,7 +10,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev libseccomp-dev pkg-config vim-common libsystemd-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

View File

@@ -12,7 +12,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list.d
RUN apt-get update && apt-get install -y -t wheezy-backports btrfs-tools --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y -t wheezy-backports btrfs-tools --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y apparmor bash-completion build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

View File

@@ -6,7 +6,7 @@ FROM ubuntu:trusty
RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y apparmor bash-completion btrfs-tools build-essential cmake curl ca-certificates debhelper dh-apparmor dh-systemd git libapparmor-dev libdevmapper-dev pkg-config vim-common libsystemd-journal-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.8.5 ENV GO_VERSION 1.9.2
RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local
ENV PATH $PATH:/usr/local/go/bin ENV PATH $PATH:/usr/local/go/bin

Some files were not shown because too many files have changed in this diff Show More