Bug#768071: unblock: docker.io/1.3.1~dfsg1-1
retitle 768071 unblock: docker.io/1.3.1~dfsg1-2
thanks
per paultag's instructions (updated debdiff is attached)
♥,
- Tianon
4096R / B42F 6819 007F 00F8 8E36 4FD4 036A 9C25 BF35 7DD4
diff -Nru docker.io-1.3.0~dfsg1/CHANGELOG.md docker.io-1.3.1~dfsg1/CHANGELOG.md
--- docker.io-1.3.0~dfsg1/CHANGELOG.md 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/CHANGELOG.md 2014-10-30 13:44:46.000000000 +0000
@@ -1,5 +1,23 @@
# Changelog
+## 1.3.1 (2014-10-28)
+
+#### Security
+* Prevent fallback to SSL protocols < TLS 1.0 for client, daemon and registry
++ Secure HTTPS connection to registries with certificate verification and without HTTP fallback unless `--insecure-registry` is specified
+
+#### Runtime
+- Fix issue where volumes would not be shared
+
+#### Client
+- Fix issue with `--iptables=false` not automatically setting `--ip-masq=false`
+- Fix docker run output to non-TTY stdout
+
+#### Builder
+- Fix escaping `$` for environment variables
+- Fix issue with lowercase `onbuild` Dockerfile instruction
+- Restrict envrionment variable expansion to `ENV`, `ADD`, `COPY`, `WORKDIR`, `EXPOSE`, `VOLUME` and `USER`
+
## 1.3.0 (2014-10-14)
#### Notable features since 1.2.0
diff -Nru docker.io-1.3.0~dfsg1/VERSION docker.io-1.3.1~dfsg1/VERSION
--- docker.io-1.3.0~dfsg1/VERSION 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/VERSION 2014-10-30 13:44:46.000000000 +0000
@@ -1 +1 @@
-1.3.0
+1.3.1
diff -Nru docker.io-1.3.0~dfsg1/api/client/commands.go docker.io-1.3.1~dfsg1/api/client/commands.go
--- docker.io-1.3.0~dfsg1/api/client/commands.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/api/client/commands.go 2014-10-30 13:44:46.000000000 +0000
@@ -1986,6 +1986,10 @@
}
func (cli *DockerCli) pullImage(image string) error {
+ return cli.pullImageCustomOut(image, cli.out)
+}
+
+func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error {
v := url.Values{}
repos, tag := parsers.ParseRepositoryTag(image)
// pull only the image tagged 'latest' if no tag was specified
@@ -2014,7 +2018,7 @@
registryAuthHeader := []string{
base64.URLEncoding.EncodeToString(buf),
}
- if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, cli.out, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil {
+ if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, out, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil {
return err
}
return nil
@@ -2081,7 +2085,8 @@
if statusCode == 404 {
fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", config.Image)
- if err = cli.pullImage(config.Image); err != nil {
+ // we don't want to write to stdout anything apart from container.ID
+ if err = cli.pullImageCustomOut(config.Image, cli.err); err != nil {
return nil, err
}
// Retry
diff -Nru docker.io-1.3.0~dfsg1/api/server/server.go docker.io-1.3.1~dfsg1/api/server/server.go
--- docker.io-1.3.0~dfsg1/api/server/server.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/api/server/server.go 2014-10-30 13:44:46.000000000 +0000
@@ -1439,6 +1439,8 @@
tlsConfig := &tls.Config{
NextProtos: []string{"http/1.1"},
Certificates: []tls.Certificate{cert},
+ // Avoid fallback on insecure SSL protocols
+ MinVersion: tls.VersionTLS10,
}
if job.GetenvBool("TlsVerify") {
certPool := x509.NewCertPool()
diff -Nru docker.io-1.3.0~dfsg1/builder/dispatchers.go docker.io-1.3.1~dfsg1/builder/dispatchers.go
--- docker.io-1.3.0~dfsg1/builder/dispatchers.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/builder/dispatchers.go 2014-10-30 13:44:46.000000000 +0000
@@ -11,6 +11,7 @@
"fmt"
"io/ioutil"
"path/filepath"
+ "regexp"
"strings"
"github.com/docker/docker/nat"
@@ -129,7 +130,7 @@
return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", triggerInstruction)
}
- original = strings.TrimSpace(strings.TrimLeft(original, "ONBUILD"))
+ original = regexp.MustCompile(`(?i)^\s*ONBUILD\s*`).ReplaceAllString(original, "")
b.Config.OnBuild = append(b.Config.OnBuild, original)
return b.commit("", b.Config.Cmd, fmt.Sprintf("ONBUILD %s", original))
@@ -194,7 +195,7 @@
defer func(cmd []string) { b.Config.Cmd = cmd }(cmd)
- log.Debugf("Command to be executed: %v", b.Config.Cmd)
+ log.Debugf("[BUILDER] Command to be executed: %v", b.Config.Cmd)
hit, err := b.probeCache()
if err != nil {
@@ -233,7 +234,7 @@
func cmd(b *Builder, args []string, attributes map[string]bool, original string) error {
b.Config.Cmd = handleJsonArgs(args, attributes)
- if !attributes["json"] && len(b.Config.Entrypoint) == 0 {
+ if !attributes["json"] {
b.Config.Cmd = append([]string{"/bin/sh", "-c"}, b.Config.Cmd...)
}
@@ -260,14 +261,14 @@
parsed := handleJsonArgs(args, attributes)
switch {
- case len(parsed) == 0:
- // ENTYRPOINT []
- b.Config.Entrypoint = nil
case attributes["json"]:
// ENTRYPOINT ["echo", "hi"]
b.Config.Entrypoint = parsed
+ case len(parsed) == 0:
+ // ENTRYPOINT []
+ b.Config.Entrypoint = nil
default:
- // ENTYRPOINT echo hi
+ // ENTRYPOINT echo hi
b.Config.Entrypoint = []string{"/bin/sh", "-c", parsed[0]}
}
diff -Nru docker.io-1.3.0~dfsg1/builder/evaluator.go docker.io-1.3.1~dfsg1/builder/evaluator.go
--- docker.io-1.3.0~dfsg1/builder/evaluator.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/builder/evaluator.go 2014-10-30 13:44:46.000000000 +0000
@@ -41,6 +41,17 @@
ErrDockerfileEmpty = errors.New("Dockerfile cannot be empty")
)
+// Environment variable interpolation will happen on these statements only.
+var replaceEnvAllowed = map[string]struct{}{
+ "env": {},
+ "add": {},
+ "copy": {},
+ "workdir": {},
+ "expose": {},
+ "volume": {},
+ "user": {},
+}
+
var evaluateTable map[string]func(*Builder, []string, map[string]bool, string) error
func init() {
@@ -149,7 +160,7 @@
b.dockerfile = ast
// some initializations that would not have been supplied by the caller.
- b.Config = &runconfig.Config{Entrypoint: []string{}, Cmd: nil}
+ b.Config = &runconfig.Config{}
b.TmpContainers = map[string]struct{}{}
for i, n := range b.dockerfile.Children {
@@ -196,13 +207,18 @@
if cmd == "onbuild" {
ast = ast.Next.Children[0]
- strs = append(strs, b.replaceEnv(ast.Value))
+ strs = append(strs, ast.Value)
msg += " " + ast.Value
}
for ast.Next != nil {
ast = ast.Next
- strs = append(strs, b.replaceEnv(ast.Value))
+ var str string
+ str = ast.Value
+ if _, ok := replaceEnvAllowed[cmd]; ok {
+ str = b.replaceEnv(ast.Value)
+ }
+ strs = append(strs, str)
msg += " " + ast.Value
}
diff -Nru docker.io-1.3.0~dfsg1/builder/parser/parser.go docker.io-1.3.1~dfsg1/builder/parser/parser.go
--- docker.io-1.3.0~dfsg1/builder/parser/parser.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/builder/parser/parser.go 2014-10-30 13:44:46.000000000 +0000
@@ -87,10 +87,11 @@
if sexp.Value != "" || sexp.Next != nil || sexp.Children != nil {
node.Next = sexp
- node.Attributes = attrs
- node.Original = line
}
+ node.Attributes = attrs
+ node.Original = line
+
return "", node, nil
}
diff -Nru docker.io-1.3.0~dfsg1/builder/support.go docker.io-1.3.1~dfsg1/builder/support.go
--- docker.io-1.3.0~dfsg1/builder/support.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/builder/support.go 2014-10-30 13:44:46.000000000 +0000
@@ -10,13 +10,26 @@
// `\$` - match literal $
// `[[:alnum:]_]+` - match things like `$SOME_VAR`
// `{[[:alnum:]_]+}` - match things like `${SOME_VAR}`
- tokenEnvInterpolation = regexp.MustCompile(`(\\\\+|[^\\]|\b|\A)\$([[:alnum:]_]+|{[[:alnum:]_]+})`)
+ tokenEnvInterpolation = regexp.MustCompile(`(\\|\\\\+|[^\\]|\b|\A)\$([[:alnum:]_]+|{[[:alnum:]_]+})`)
// this intentionally punts on more exotic interpolations like ${SOME_VAR%suffix} and lets the shell handle those directly
)
// handle environment replacement. Used in dispatcher.
func (b *Builder) replaceEnv(str string) string {
for _, match := range tokenEnvInterpolation.FindAllString(str, -1) {
+ idx := strings.Index(match, "\\$")
+ if idx != -1 {
+ if idx+2 >= len(match) {
+ str = strings.Replace(str, match, "\\$", -1)
+ continue
+ }
+
+ prefix := match[:idx]
+ stripped := match[idx+2:]
+ str = strings.Replace(str, match, prefix+"$"+stripped, -1)
+ continue
+ }
+
match = match[strings.Index(match, "$"):]
matchKey := strings.Trim(match, "${}")
diff -Nru docker.io-1.3.0~dfsg1/builtins/builtins.go docker.io-1.3.1~dfsg1/builtins/builtins.go
--- docker.io-1.3.0~dfsg1/builtins/builtins.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/builtins/builtins.go 2014-10-30 13:44:46.000000000 +0000
@@ -10,7 +10,6 @@
"github.com/docker/docker/engine"
"github.com/docker/docker/events"
"github.com/docker/docker/pkg/parsers/kernel"
- "github.com/docker/docker/registry"
)
func Register(eng *engine.Engine) error {
@@ -26,7 +25,8 @@
if err := eng.Register("version", dockerVersion); err != nil {
return err
}
- return registry.NewService().Install(eng)
+
+ return nil
}
// remote: a RESTful api for cross-docker communication
diff -Nru docker.io-1.3.0~dfsg1/daemon/config.go docker.io-1.3.1~dfsg1/daemon/config.go
--- docker.io-1.3.0~dfsg1/daemon/config.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/daemon/config.go 2014-10-30 13:44:46.000000000 +0000
@@ -31,6 +31,7 @@
BridgeIface string
BridgeIP string
FixedCIDR string
+ InsecureRegistries []string
InterContainerCommunication bool
GraphDriver string
GraphOptions []string
@@ -55,6 +56,7 @@
flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
flag.StringVar(&config.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs (ex: 10.20.0.0/16)\nthis subnet must be nested in the bridge subnet (which is defined by -b or --bip)")
+ opts.ListVar(&config.InsecureRegistries, []string{"-insecure-registry"}, "Enable insecure communication with specified registries (no certificate verification for HTTPS and enable HTTP fallback)")
flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Force the Docker runtime to use a specific storage driver")
flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Force the Docker runtime to use a specific exec driver")
diff -Nru docker.io-1.3.0~dfsg1/daemon/daemon.go docker.io-1.3.1~dfsg1/daemon/daemon.go
--- docker.io-1.3.0~dfsg1/daemon/daemon.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/daemon/daemon.go 2014-10-30 13:44:46.000000000 +0000
@@ -731,7 +731,7 @@
return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
}
if !config.EnableIptables && config.EnableIpMasq {
- return nil, fmt.Errorf("You specified --iptables=false with --ipmasq=true. IP masquerading uses iptables to function. Please set --ipmasq to false or --iptables to true.")
+ config.EnableIpMasq = false
}
config.DisableNetwork = config.BridgeIface == disableNetworkBridge
@@ -831,7 +831,7 @@
}
log.Debugf("Creating repository list")
- repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, config.Mirrors)
+ repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, config.Mirrors, config.InsecureRegistries)
if err != nil {
return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
}
diff -Nru docker.io-1.3.0~dfsg1/daemon/volumes.go docker.io-1.3.1~dfsg1/daemon/volumes.go
--- docker.io-1.3.0~dfsg1/daemon/volumes.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/daemon/volumes.go 2014-10-30 13:44:46.000000000 +0000
@@ -133,6 +133,7 @@
// Get the rest of the volumes
for path := range container.Config.Volumes {
// Check if this is already added as a bind-mount
+ path = filepath.Clean(path)
if _, exists := mounts[path]; exists {
continue
}
@@ -182,6 +183,8 @@
return "", "", false, fmt.Errorf("cannot bind mount volume: %s volume paths must be absolute.", path)
}
+ path = filepath.Clean(path)
+ mountToPath = filepath.Clean(mountToPath)
return path, mountToPath, writable, nil
}
diff -Nru docker.io-1.3.0~dfsg1/debian/changelog docker.io-1.3.1~dfsg1/debian/changelog
--- docker.io-1.3.0~dfsg1/debian/changelog 2014-10-17 06:56:10.000000000 +0000
+++ docker.io-1.3.1~dfsg1/debian/changelog 2014-11-07 20:11:37.000000000 +0000
@@ -1,3 +1,19 @@
+docker.io (1.3.1~dfsg1-2) unstable; urgency=medium
+
+ * Remove deprecated /usr/bin/docker.io symlink
+ - added as a temporary shim in 1.0.0~dfsg1-1 (13 Jun 2014)
+ - unused by package-installed files in 1.2.0~dfsg1-1 (13 Sep 2014)
+
+ -- Tianon Gravi <admwiggin@gmail.com> Fri, 07 Nov 2014 13:11:34 -0700
+
+docker.io (1.3.1~dfsg1-1) unstable; urgency=high
+
+ * Update to 1.3.1 upstream release
+ - fix for CVE-2014-5277
+ - https://groups.google.com/d/topic/docker-user/oYm0i3xShJU/discussion
+
+ -- Tianon Gravi <admwiggin@gmail.com> Mon, 03 Nov 2014 08:26:29 -0700
+
docker.io (1.3.0~dfsg1-1) unstable; urgency=medium
* Updated to 1.3.0 upstream release.
diff -Nru docker.io-1.3.0~dfsg1/debian/rules docker.io-1.3.1~dfsg1/debian/rules
--- docker.io-1.3.0~dfsg1/debian/rules 2014-10-17 06:36:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/debian/rules 2014-11-07 20:11:30.000000000 +0000
@@ -54,8 +54,6 @@
# install docker binary
mkdir -p debian/docker.io/usr/bin
mv bundles/${DOCKER_VERSION}/dynbinary/docker-${DOCKER_VERSION} debian/docker.io/usr/bin/docker
- # install docker.io symlink for easier transition
- ln -s docker debian/docker.io/usr/bin/docker.io
# install dockerinit binary
mkdir -p debian/docker.io/${INITDIR}
diff -Nru docker.io-1.3.0~dfsg1/debian/upstream-version-gitcommits docker.io-1.3.1~dfsg1/debian/upstream-version-gitcommits
--- docker.io-1.3.0~dfsg1/debian/upstream-version-gitcommits 2014-10-17 06:34:38.000000000 +0000
+++ docker.io-1.3.1~dfsg1/debian/upstream-version-gitcommits 2014-10-31 21:26:53.000000000 +0000
@@ -33,3 +33,4 @@
1.1.2: d84a070
1.2.0: fa7b24f
1.3.0: c78088f
+1.3.1: 4e9bbfa
diff -Nru docker.io-1.3.0~dfsg1/docker/daemon.go docker.io-1.3.1~dfsg1/docker/daemon.go
--- docker.io-1.3.0~dfsg1/docker/daemon.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/docker/daemon.go 2014-10-30 13:44:46.000000000 +0000
@@ -14,6 +14,7 @@
"github.com/docker/docker/engine"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/signal"
+ "github.com/docker/docker/registry"
)
const CanDaemon = true
@@ -33,11 +34,17 @@
}
eng := engine.New()
signal.Trap(eng.Shutdown)
+
// Load builtins
if err := builtins.Register(eng); err != nil {
log.Fatal(err)
}
+ // load registry service
+ if err := registry.NewService(daemonCfg.InsecureRegistries).Install(eng); err != nil {
+ log.Fatal(err)
+ }
+
// load the daemon in the background so we can immediately start
// the http api so that connections don't fail while the daemon
// is booting
diff -Nru docker.io-1.3.0~dfsg1/docker/docker.go docker.io-1.3.1~dfsg1/docker/docker.go
--- docker.io-1.3.0~dfsg1/docker/docker.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/docker/docker.go 2014-10-30 13:44:46.000000000 +0000
@@ -93,6 +93,8 @@
}
tlsConfig.Certificates = []tls.Certificate{cert}
}
+ // Avoid fallback to SSL protocols < TLS1.0
+ tlsConfig.MinVersion = tls.VersionTLS10
}
if *flTls || *flTlsVerify {
diff -Nru docker.io-1.3.0~dfsg1/docs/mkdocs.yml docker.io-1.3.1~dfsg1/docs/mkdocs.yml
--- docker.io-1.3.0~dfsg1/docs/mkdocs.yml 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/docs/mkdocs.yml 2014-10-30 13:44:46.000000000 +0000
@@ -26,6 +26,7 @@
# Introduction:
- ['index.md', 'About', 'Docker']
+- ['release-notes.md', 'About', 'Release Notes']
- ['introduction/index.md', '**HIDDEN**']
- ['introduction/understanding-docker.md', 'About', 'Understanding Docker']
diff -Nru docker.io-1.3.0~dfsg1/graph/pull.go docker.io-1.3.1~dfsg1/graph/pull.go
--- docker.io-1.3.0~dfsg1/graph/pull.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/graph/pull.go 2014-10-30 13:44:46.000000000 +0000
@@ -113,7 +113,9 @@
return job.Error(err)
}
- endpoint, err := registry.NewEndpoint(hostname)
+ secure := registry.IsSecure(hostname, s.insecureRegistries)
+
+ endpoint, err := registry.NewEndpoint(hostname, secure)
if err != nil {
return job.Error(err)
}
diff -Nru docker.io-1.3.0~dfsg1/graph/push.go docker.io-1.3.1~dfsg1/graph/push.go
--- docker.io-1.3.0~dfsg1/graph/push.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/graph/push.go 2014-10-30 13:44:46.000000000 +0000
@@ -214,7 +214,9 @@
return job.Error(err)
}
- endpoint, err := registry.NewEndpoint(hostname)
+ secure := registry.IsSecure(hostname, s.insecureRegistries)
+
+ endpoint, err := registry.NewEndpoint(hostname, secure)
if err != nil {
return job.Error(err)
}
diff -Nru docker.io-1.3.0~dfsg1/graph/tags.go docker.io-1.3.1~dfsg1/graph/tags.go
--- docker.io-1.3.0~dfsg1/graph/tags.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/graph/tags.go 2014-10-30 13:44:46.000000000 +0000
@@ -23,10 +23,11 @@
)
type TagStore struct {
- path string
- graph *Graph
- mirrors []string
- Repositories map[string]Repository
+ path string
+ graph *Graph
+ mirrors []string
+ insecureRegistries []string
+ Repositories map[string]Repository
sync.Mutex
// FIXME: move push/pull-related fields
// to a helper type
@@ -54,18 +55,20 @@
return true
}
-func NewTagStore(path string, graph *Graph, mirrors []string) (*TagStore, error) {
+func NewTagStore(path string, graph *Graph, mirrors []string, insecureRegistries []string) (*TagStore, error) {
abspath, err := filepath.Abs(path)
if err != nil {
return nil, err
}
+
store := &TagStore{
- path: abspath,
- graph: graph,
- mirrors: mirrors,
- Repositories: make(map[string]Repository),
- pullingPool: make(map[string]chan struct{}),
- pushingPool: make(map[string]chan struct{}),
+ path: abspath,
+ graph: graph,
+ mirrors: mirrors,
+ insecureRegistries: insecureRegistries,
+ Repositories: make(map[string]Repository),
+ pullingPool: make(map[string]chan struct{}),
+ pushingPool: make(map[string]chan struct{}),
}
// Load the json file if it exists, otherwise create it.
if err := store.reload(); os.IsNotExist(err) {
diff -Nru docker.io-1.3.0~dfsg1/graph/tags_unit_test.go docker.io-1.3.1~dfsg1/graph/tags_unit_test.go
--- docker.io-1.3.0~dfsg1/graph/tags_unit_test.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/graph/tags_unit_test.go 2014-10-30 13:44:46.000000000 +0000
@@ -53,7 +53,7 @@
if err != nil {
t.Fatal(err)
}
- store, err := NewTagStore(path.Join(root, "tags"), graph, nil)
+ store, err := NewTagStore(path.Join(root, "tags"), graph, nil, nil)
if err != nil {
t.Fatal(err)
}
diff -Nru docker.io-1.3.0~dfsg1/hack/release.sh docker.io-1.3.1~dfsg1/hack/release.sh
--- docker.io-1.3.0~dfsg1/hack/release.sh 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/hack/release.sh 2014-10-30 13:44:46.000000000 +0000
@@ -270,7 +270,7 @@
done
# Upload keys
- s3cmd sync /.gnupg/ s3://$BUCKET/ubuntu/.gnupg/
+ s3cmd sync $HOME/.gnupg/ s3://$BUCKET/ubuntu/.gnupg/
gpg --armor --export releasedocker > bundles/$VERSION/ubuntu/gpg
s3cmd --acl-public put bundles/$VERSION/ubuntu/gpg s3://$BUCKET/gpg
@@ -355,8 +355,8 @@
setup_gpg() {
# Make sure that we have our keys
- mkdir -p /.gnupg/
- s3cmd sync s3://$BUCKET/ubuntu/.gnupg/ /.gnupg/ || true
+ mkdir -p $HOME/.gnupg/
+ s3cmd sync s3://$BUCKET/ubuntu/.gnupg/ $HOME/.gnupg/ || true
gpg --list-keys releasedocker >/dev/null || {
gpg --gen-key --batch <<EOF
Key-Type: RSA
diff -Nru docker.io-1.3.0~dfsg1/integration-cli/docker_cli_build_test.go docker.io-1.3.1~dfsg1/integration-cli/docker_cli_build_test.go
--- docker.io-1.3.0~dfsg1/integration-cli/docker_cli_build_test.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/integration-cli/docker_cli_build_test.go 2014-10-30 13:44:46.000000000 +0000
@@ -2,6 +2,7 @@
import (
"archive/tar"
+ "encoding/json"
"fmt"
"io/ioutil"
"os"
@@ -15,6 +16,396 @@
"github.com/docker/docker/pkg/archive"
)
+func TestBuildShCmdJSONEntrypoint(t *testing.T) {
+ name := "testbuildshcmdjsonentrypoint"
+ defer deleteImages(name)
+
+ _, err := buildImage(
+ name,
+ `
+ FROM busybox
+ ENTRYPOINT ["/bin/echo"]
+ CMD echo test
+ `,
+ true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ out, _, err := runCommandWithOutput(
+ exec.Command(
+ dockerBinary,
+ "run",
+ name))
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if strings.TrimSpace(out) != "/bin/sh -c echo test" {
+ t.Fatal("CMD did not contain /bin/sh -c")
+ }
+
+ logDone("build - CMD should always contain /bin/sh -c when specified without JSON")
+}
+
+func TestBuildEnvironmentReplacementUser(t *testing.T) {
+ name := "testbuildenvironmentreplacement"
+ defer deleteImages(name)
+
+ _, err := buildImage(name, `
+ FROM scratch
+ ENV user foo
+ USER ${user}
+ `, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ res, err := inspectFieldJSON(name, "Config.User")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if res != `"foo"` {
+ t.Fatal("User foo from environment not in Config.User on image")
+ }
+
+ logDone("build - user environment replacement")
+}
+
+func TestBuildEnvironmentReplacementVolume(t *testing.T) {
+ name := "testbuildenvironmentreplacement"
+ defer deleteImages(name)
+
+ _, err := buildImage(name, `
+ FROM scratch
+ ENV volume /quux
+ VOLUME ${volume}
+ `, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ res, err := inspectFieldJSON(name, "Config.Volumes")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var volumes map[string]interface{}
+
+ if err := json.Unmarshal([]byte(res), &volumes); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, ok := volumes["/quux"]; !ok {
+ t.Fatal("Volume /quux from environment not in Config.Volumes on image")
+ }
+
+ logDone("build - volume environment replacement")
+}
+
+func TestBuildEnvironmentReplacementExpose(t *testing.T) {
+ name := "testbuildenvironmentreplacement"
+ defer deleteImages(name)
+
+ _, err := buildImage(name, `
+ FROM scratch
+ ENV port 80
+ EXPOSE ${port}
+ `, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ res, err := inspectFieldJSON(name, "Config.ExposedPorts")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var exposedPorts map[string]interface{}
+
+ if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, ok := exposedPorts["80/tcp"]; !ok {
+ t.Fatal("Exposed port 80 from environment not in Config.ExposedPorts on image")
+ }
+
+ logDone("build - expose environment replacement")
+}
+
+func TestBuildEnvironmentReplacementWorkdir(t *testing.T) {
+ name := "testbuildenvironmentreplacement"
+ defer deleteImages(name)
+
+ _, err := buildImage(name, `
+ FROM busybox
+ ENV MYWORKDIR /work
+ RUN mkdir ${MYWORKDIR}
+ WORKDIR ${MYWORKDIR}
+ `, true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ logDone("build - workdir environment replacement")
+}
+
+func TestBuildEnvironmentReplacementAddCopy(t *testing.T) {
+ name := "testbuildenvironmentreplacement"
+ defer deleteImages(name)
+
+ ctx, err := fakeContext(`
+ FROM scratch
+ ENV baz foo
+ ENV quux bar
+ ENV dot .
+
+ ADD ${baz} ${dot}
+ COPY ${quux} ${dot}
+ `,
+ map[string]string{
+ "foo": "test1",
+ "bar": "test2",
+ })
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := buildImageFromContext(name, ctx, true); err != nil {
+ t.Fatal(err)
+ }
+
+ logDone("build - add/copy environment replacement")
+}
+
+func TestBuildEnvironmentReplacementEnv(t *testing.T) {
+ name := "testbuildenvironmentreplacement"
+
+ defer deleteImages(name)
+
+ _, err := buildImage(name,
+ `
+ FROM scratch
+ ENV foo foo
+ ENV bar ${foo}
+ `, true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ res, err := inspectFieldJSON(name, "Config.Env")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ envResult := []string{}
+
+ if err = unmarshalJSON([]byte(res), &envResult); err != nil {
+ t.Fatal(err)
+ }
+
+ found := false
+
+ for _, env := range envResult {
+ parts := strings.SplitN(env, "=", 2)
+ if parts[0] == "bar" {
+ found = true
+ if parts[1] != "foo" {
+ t.Fatal("Could not find replaced var for env `bar`: got %q instead of `foo`", parts[1])
+ }
+ }
+ }
+
+ if !found {
+ t.Fatal("Never found the `bar` env variable")
+ }
+
+ logDone("build - env environment replacement")
+}
+
+func TestBuildHandleEscapes(t *testing.T) {
+ name := "testbuildhandleescapes"
+
+ defer deleteImages(name)
+
+ _, err := buildImage(name,
+ `
+ FROM scratch
+ ENV FOO bar
+ VOLUME ${FOO}
+ `, true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var result map[string]map[string]struct{}
+
+ res, err := inspectFieldJSON(name, "Config.Volumes")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if err = unmarshalJSON([]byte(res), &result); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, ok := result["bar"]; !ok {
+ t.Fatal("Could not find volume bar set from env foo in volumes table")
+ }
+
+ _, err = buildImage(name,
+ `
+ FROM scratch
+ ENV FOO bar
+ VOLUME \${FOO}
+ `, true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ res, err = inspectFieldJSON(name, "Config.Volumes")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if err = unmarshalJSON([]byte(res), &result); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, ok := result["${FOO}"]; !ok {
+ t.Fatal("Could not find volume ${FOO} set from env foo in volumes table")
+ }
+
+ // this test in particular provides *7* backslashes and expects 6 to come back.
+ // Like above, the first escape is swallowed and the rest are treated as
+ // literals, this one is just less obvious because of all the character noise.
+
+ _, err = buildImage(name,
+ `
+ FROM scratch
+ ENV FOO bar
+ VOLUME \\\\\\\${FOO}
+ `, true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ res, err = inspectFieldJSON(name, "Config.Volumes")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if err = unmarshalJSON([]byte(res), &result); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, ok := result[`\\\\\\${FOO}`]; !ok {
+ t.Fatal(`Could not find volume \\\\\\${FOO} set from env foo in volumes table`)
+ }
+
+ logDone("build - handle escapes")
+}
+
+func TestBuildOnBuildLowercase(t *testing.T) {
+ name := "testbuildonbuildlowercase"
+ name2 := "testbuildonbuildlowercase2"
+
+ defer deleteImages(name, name2)
+
+ _, err := buildImage(name,
+ `
+ FROM busybox
+ onbuild run echo quux
+ `, true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ _, out, err := buildImageWithOut(name2, fmt.Sprintf(`
+ FROM %s
+ `, name), true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if !strings.Contains(out, "quux") {
+ t.Fatalf("Did not receive the expected echo text, got %s", out)
+ }
+
+ if strings.Contains(out, "ONBUILD ONBUILD") {
+ t.Fatalf("Got an ONBUILD ONBUILD error with no error: got %s", out)
+ }
+
+ logDone("build - handle case-insensitive onbuild statement")
+}
+
+func TestBuildEnvEscapes(t *testing.T) {
+ name := "testbuildenvescapes"
+ defer deleteAllContainers()
+ defer deleteImages(name)
+ _, err := buildImage(name,
+ `
+ FROM busybox
+ ENV TEST foo
+ CMD echo \$
+ `,
+ true)
+
+ out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name))
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if strings.TrimSpace(out) != "$" {
+ t.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
+ }
+
+ logDone("build - env should handle \\$ properly")
+}
+
+func TestBuildEnvOverwrite(t *testing.T) {
+ name := "testbuildenvoverwrite"
+ defer deleteAllContainers()
+ defer deleteImages(name)
+
+ _, err := buildImage(name,
+ `
+ FROM busybox
+ ENV TEST foo
+ CMD echo ${TEST}
+ `,
+ true)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-e", "TEST=bar", "-t", name))
+
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if strings.TrimSpace(out) != "bar" {
+ t.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
+ }
+
+ logDone("build - env should overwrite builder ENV during run")
+}
+
func TestBuildOnBuildForbiddenMaintainerInSourceImage(t *testing.T) {
name := "testbuildonbuildforbiddenmaintainerinsourceimage"
defer deleteImages(name)
@@ -1272,6 +1663,49 @@
logDone("build - expose")
}
+func TestBuildEmptyEntrypointInheritance(t *testing.T) {
+ name := "testbuildentrypointinheritance"
+ name2 := "testbuildentrypointinheritance2"
+ defer deleteImages(name, name2)
+
+ _, err := buildImage(name,
+ `FROM busybox
+ ENTRYPOINT ["/bin/echo"]`,
+ true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ res, err := inspectField(name, "Config.Entrypoint")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ expected := "[/bin/echo]"
+ if res != expected {
+ t.Fatalf("Entrypoint %s, expected %s", res, expected)
+ }
+
+ _, err = buildImage(name2,
+ fmt.Sprintf(`FROM %s
+ ENTRYPOINT []`, name),
+ true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ res, err = inspectField(name2, "Config.Entrypoint")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ expected = "[]"
+
+ if res != expected {
+ t.Fatalf("Entrypoint %s, expected %s", res, expected)
+ }
+
+ logDone("build - empty entrypoint inheritance")
+}
+
func TestBuildEmptyEntrypoint(t *testing.T) {
name := "testbuildentrypoint"
defer deleteImages(name)
@@ -2328,6 +2762,7 @@
name := "testbuildenvusage"
defer deleteImages(name)
dockerfile := `FROM busybox
+ENV HOME /root
ENV PATH $HOME/bin:$PATH
ENV PATH /tmp:$PATH
RUN [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
diff -Nru docker.io-1.3.0~dfsg1/integration-cli/docker_cli_daemon_test.go docker.io-1.3.1~dfsg1/integration-cli/docker_cli_daemon_test.go
--- docker.io-1.3.0~dfsg1/integration-cli/docker_cli_daemon_test.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/integration-cli/docker_cli_daemon_test.go 2014-10-30 13:44:46.000000000 +0000
@@ -82,3 +82,13 @@
logDone("daemon - volume refs are restored")
}
+
+func TestDaemonStartIptablesFalse(t *testing.T) {
+ d := NewDaemon(t)
+ if err := d.Start("--iptables=false"); err != nil {
+ t.Fatalf("we should have been able to start the daemon with passing iptables=false: %v", err)
+ }
+ d.Stop()
+
+ logDone("daemon - started daemon with iptables=false")
+}
diff -Nru docker.io-1.3.0~dfsg1/integration-cli/docker_cli_run_test.go docker.io-1.3.1~dfsg1/integration-cli/docker_cli_run_test.go
--- docker.io-1.3.0~dfsg1/integration-cli/docker_cli_run_test.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/integration-cli/docker_cli_run_test.go 2014-10-30 13:44:46.000000000 +0000
@@ -2,6 +2,7 @@
import (
"bufio"
+ "bytes"
"fmt"
"io/ioutil"
"net"
@@ -2374,3 +2375,68 @@
logDone("run - volumes not recreated on start")
}
+
+func TestRunNoOutputFromPullInStdout(t *testing.T) {
+ defer deleteAllContainers()
+ // just run with unknown image
+ cmd := exec.Command(dockerBinary, "run", "asdfsg")
+ stdout := bytes.NewBuffer(nil)
+ cmd.Stdout = stdout
+ if err := cmd.Run(); err == nil {
+ t.Fatal("Run with unknown image should fail")
+ }
+ if stdout.Len() != 0 {
+ t.Fatalf("Stdout contains output from pull: %s", stdout)
+ }
+ logDone("run - no output from pull in stdout")
+}
+
+func TestRunVolumesCleanPaths(t *testing.T) {
+ defer deleteAllContainers()
+
+ if _, err := buildImage("run_volumes_clean_paths",
+ `FROM busybox
+ VOLUME /foo/`,
+ true); err != nil {
+ t.Fatal(err)
+ }
+ defer deleteImages("run_volumes_clean_paths")
+
+ cmd := exec.Command(dockerBinary, "run", "-v", "/foo", "-v", "/bar/", "--name", "dark_helmet", "run_volumes_clean_paths")
+ if out, _, err := runCommandWithOutput(cmd); err != nil {
+ t.Fatal(err, out)
+ }
+
+ out, err := inspectFieldMap("dark_helmet", "Volumes", "/foo/")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if out != "<no value>" {
+ t.Fatalf("Found unexpected volume entry for '/foo/' in volumes\n%q", out)
+ }
+
+ out, err = inspectFieldMap("dark_helmet", "Volumes", "/foo")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !strings.Contains(out, volumesStoragePath) {
+ t.Fatalf("Volume was not defined for /foo\n%q", out)
+ }
+
+ out, err = inspectFieldMap("dark_helmet", "Volumes", "/bar/")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if out != "<no value>" {
+ t.Fatalf("Found unexpected volume entry for '/bar/' in volumes\n%q", out)
+ }
+ out, err = inspectFieldMap("dark_helmet", "Volumes", "/bar")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !strings.Contains(out, volumesStoragePath) {
+ t.Fatalf("Volume was not defined for /bar\n%q", out)
+ }
+
+ logDone("run - volume paths are cleaned")
+}
diff -Nru docker.io-1.3.0~dfsg1/integration-cli/docker_test_vars.go docker.io-1.3.1~dfsg1/integration-cli/docker_test_vars.go
--- docker.io-1.3.0~dfsg1/integration-cli/docker_test_vars.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/integration-cli/docker_test_vars.go 2014-10-30 13:44:46.000000000 +0000
@@ -16,8 +16,10 @@
// the private registry to use for tests
privateRegistryURL = "127.0.0.1:5000"
- execDriverPath = "/var/lib/docker/execdriver/native"
- volumesConfigPath = "/var/lib/docker/volumes"
+ dockerBasePath = "/var/lib/docker"
+ execDriverPath = dockerBasePath + "/execdriver/native"
+ volumesConfigPath = dockerBasePath + "/volumes"
+ volumesStoragePath = dockerBasePath + "/vfs/dir"
workingDirectory string
)
diff -Nru docker.io-1.3.0~dfsg1/integration-cli/docker_utils.go docker.io-1.3.1~dfsg1/integration-cli/docker_utils.go
--- docker.io-1.3.0~dfsg1/integration-cli/docker_utils.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/integration-cli/docker_utils.go 2014-10-30 13:44:46.000000000 +0000
@@ -507,6 +507,16 @@
return strings.TrimSpace(out), nil
}
+func inspectFieldMap(name, path, field string) (string, error) {
+ format := fmt.Sprintf("{{index .%s %q}}", path, field)
+ inspectCmd := exec.Command(dockerBinary, "inspect", "-f", format, name)
+ out, exitCode, err := runCommandWithOutput(inspectCmd)
+ if err != nil || exitCode != 0 {
+ return "", fmt.Errorf("failed to inspect %s: %s", name, out)
+ }
+ return strings.TrimSpace(out), nil
+}
+
func getIDByName(name string) (string, error) {
return inspectField(name, "Id")
}
diff -Nru docker.io-1.3.0~dfsg1/registry/endpoint.go docker.io-1.3.1~dfsg1/registry/endpoint.go
--- docker.io-1.3.0~dfsg1/registry/endpoint.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/registry/endpoint.go 2014-10-30 13:44:46.000000000 +0000
@@ -2,7 +2,6 @@
import (
"encoding/json"
- "errors"
"fmt"
"io/ioutil"
"net/http"
@@ -34,9 +33,9 @@
return hostname, DefaultAPIVersion
}
-func NewEndpoint(hostname string) (*Endpoint, error) {
+func NewEndpoint(hostname string, secure bool) (*Endpoint, error) {
var (
- endpoint Endpoint
+ endpoint = Endpoint{secure: secure}
trimmedHostname string
err error
)
@@ -49,14 +48,27 @@
return nil, err
}
+ // Try HTTPS ping to registry
endpoint.URL.Scheme = "https"
if _, err := endpoint.Ping(); err != nil {
- log.Debugf("Registry %s does not work (%s), falling back to http", endpoint, err)
- // TODO: Check if http fallback is enabled
+
+ //TODO: triggering highland build can be done there without "failing"
+
+ if secure {
+ // If registry is secure and HTTPS failed, show user the error and tell them about `--insecure-registry`
+ // in case that's what they need. DO NOT accept unknown CA certificates, and DO NOT fallback to HTTP.
+ return nil, fmt.Errorf("Invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host)
+ }
+
+ // If registry is insecure and HTTPS failed, fallback to HTTP.
+ log.Debugf("Error from registry %q marked as insecure: %v. Insecurely falling back to HTTP", endpoint, err)
endpoint.URL.Scheme = "http"
- if _, err = endpoint.Ping(); err != nil {
- return nil, errors.New("Invalid Registry endpoint: " + err.Error())
+ _, err2 := endpoint.Ping()
+ if err2 == nil {
+ return &endpoint, nil
}
+
+ return nil, fmt.Errorf("Invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2)
}
return &endpoint, nil
@@ -65,6 +77,7 @@
type Endpoint struct {
URL *url.URL
Version APIVersion
+ secure bool
}
// Get the formated URL for the root of this registry Endpoint
@@ -88,7 +101,7 @@
return RegistryInfo{Standalone: false}, err
}
- resp, _, err := doRequest(req, nil, ConnectTimeout)
+ resp, _, err := doRequest(req, nil, ConnectTimeout, e.secure)
if err != nil {
return RegistryInfo{Standalone: false}, err
}
@@ -127,3 +140,19 @@
log.Debugf("RegistryInfo.Standalone: %t", info.Standalone)
return info, nil
}
+
+// IsSecure returns false if the provided hostname is part of the list of insecure registries.
+// Insecure registries accept HTTP and/or accept HTTPS with certificates from unknown CAs.
+func IsSecure(hostname string, insecureRegistries []string) bool {
+ if hostname == IndexServerAddress() {
+ return true
+ }
+
+ for _, h := range insecureRegistries {
+ if hostname == h {
+ return false
+ }
+ }
+
+ return true
+}
diff -Nru docker.io-1.3.0~dfsg1/registry/registry.go docker.io-1.3.1~dfsg1/registry/registry.go
--- docker.io-1.3.0~dfsg1/registry/registry.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/registry/registry.go 2014-10-30 13:44:46.000000000 +0000
@@ -14,6 +14,7 @@
"strings"
"time"
+ "github.com/docker/docker/pkg/log"
"github.com/docker/docker/utils"
)
@@ -35,13 +36,21 @@
ConnectTimeout
)
-func newClient(jar http.CookieJar, roots *x509.CertPool, cert *tls.Certificate, timeout TimeoutType) *http.Client {
- tlsConfig := tls.Config{RootCAs: roots}
+func newClient(jar http.CookieJar, roots *x509.CertPool, cert *tls.Certificate, timeout TimeoutType, secure bool) *http.Client {
+ tlsConfig := tls.Config{
+ RootCAs: roots,
+ // Avoid fallback to SSL protocols < TLS1.0
+ MinVersion: tls.VersionTLS10,
+ }
if cert != nil {
tlsConfig.Certificates = append(tlsConfig.Certificates, *cert)
}
+ if !secure {
+ tlsConfig.InsecureSkipVerify = true
+ }
+
httpTransport := &http.Transport{
DisableKeepAlives: true,
Proxy: http.ProxyFromEnvironment,
@@ -78,69 +87,76 @@
}
}
-func doRequest(req *http.Request, jar http.CookieJar, timeout TimeoutType) (*http.Response, *http.Client, error) {
- hasFile := func(files []os.FileInfo, name string) bool {
- for _, f := range files {
- if f.Name() == name {
- return true
- }
- }
- return false
- }
-
- hostDir := path.Join("/etc/docker/certs.d", req.URL.Host)
- fs, err := ioutil.ReadDir(hostDir)
- if err != nil && !os.IsNotExist(err) {
- return nil, nil, err
- }
-
+func doRequest(req *http.Request, jar http.CookieJar, timeout TimeoutType, secure bool) (*http.Response, *http.Client, error) {
var (
pool *x509.CertPool
certs []*tls.Certificate
)
- for _, f := range fs {
- if strings.HasSuffix(f.Name(), ".crt") {
- if pool == nil {
- pool = x509.NewCertPool()
- }
- data, err := ioutil.ReadFile(path.Join(hostDir, f.Name()))
- if err != nil {
- return nil, nil, err
- }
- pool.AppendCertsFromPEM(data)
+ if secure && req.URL.Scheme == "https" {
+ hasFile := func(files []os.FileInfo, name string) bool {
+ for _, f := range files {
+ if f.Name() == name {
+ return true
+ }
+ }
+ return false
}
- if strings.HasSuffix(f.Name(), ".cert") {
- certName := f.Name()
- keyName := certName[:len(certName)-5] + ".key"
- if !hasFile(fs, keyName) {
- return nil, nil, fmt.Errorf("Missing key %s for certificate %s", keyName, certName)
- }
- cert, err := tls.LoadX509KeyPair(path.Join(hostDir, certName), path.Join(hostDir, keyName))
- if err != nil {
- return nil, nil, err
- }
- certs = append(certs, &cert)
+
+ hostDir := path.Join("/etc/docker/certs.d", req.URL.Host)
+ log.Debugf("hostDir: %s", hostDir)
+ fs, err := ioutil.ReadDir(hostDir)
+ if err != nil && !os.IsNotExist(err) {
+ return nil, nil, err
}
- if strings.HasSuffix(f.Name(), ".key") {
- keyName := f.Name()
- certName := keyName[:len(keyName)-4] + ".cert"
- if !hasFile(fs, certName) {
- return nil, nil, fmt.Errorf("Missing certificate %s for key %s", certName, keyName)
+
+ for _, f := range fs {
+ if strings.HasSuffix(f.Name(), ".crt") {
+ if pool == nil {
+ pool = x509.NewCertPool()
+ }
+ log.Debugf("crt: %s", hostDir+"/"+f.Name())
+ data, err := ioutil.ReadFile(path.Join(hostDir, f.Name()))
+ if err != nil {
+ return nil, nil, err
+ }
+ pool.AppendCertsFromPEM(data)
+ }
+ if strings.HasSuffix(f.Name(), ".cert") {
+ certName := f.Name()
+ keyName := certName[:len(certName)-5] + ".key"
+ log.Debugf("cert: %s", hostDir+"/"+f.Name())
+ if !hasFile(fs, keyName) {
+ return nil, nil, fmt.Errorf("Missing key %s for certificate %s", keyName, certName)
+ }
+ cert, err := tls.LoadX509KeyPair(path.Join(hostDir, certName), path.Join(hostDir, keyName))
+ if err != nil {
+ return nil, nil, err
+ }
+ certs = append(certs, &cert)
+ }
+ if strings.HasSuffix(f.Name(), ".key") {
+ keyName := f.Name()
+ certName := keyName[:len(keyName)-4] + ".cert"
+ log.Debugf("key: %s", hostDir+"/"+f.Name())
+ if !hasFile(fs, certName) {
+ return nil, nil, fmt.Errorf("Missing certificate %s for key %s", certName, keyName)
+ }
}
}
}
if len(certs) == 0 {
- client := newClient(jar, pool, nil, timeout)
+ client := newClient(jar, pool, nil, timeout, secure)
res, err := client.Do(req)
if err != nil {
return nil, nil, err
}
return res, client, nil
}
+
for i, cert := range certs {
- client := newClient(jar, pool, cert, timeout)
+ client := newClient(jar, pool, cert, timeout, secure)
res, err := client.Do(req)
// If this is the last cert, otherwise, continue to next cert if 403 or 5xx
if i == len(certs)-1 || err == nil && res.StatusCode != 403 && res.StatusCode < 500 {
diff -Nru docker.io-1.3.0~dfsg1/registry/registry_test.go docker.io-1.3.1~dfsg1/registry/registry_test.go
--- docker.io-1.3.0~dfsg1/registry/registry_test.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/registry/registry_test.go 2014-10-30 13:44:46.000000000 +0000
@@ -18,7 +18,7 @@
func spawnTestRegistrySession(t *testing.T) *Session {
authConfig := &AuthConfig{}
- endpoint, err := NewEndpoint(makeURL("/v1/"))
+ endpoint, err := NewEndpoint(makeURL("/v1/"), false)
if err != nil {
t.Fatal(err)
}
@@ -30,7 +30,7 @@
}
func TestPingRegistryEndpoint(t *testing.T) {
- ep, err := NewEndpoint(makeURL("/v1/"))
+ ep, err := NewEndpoint(makeURL("/v1/"), false)
if err != nil {
t.Fatal(err)
}
diff -Nru docker.io-1.3.0~dfsg1/registry/service.go docker.io-1.3.1~dfsg1/registry/service.go
--- docker.io-1.3.0~dfsg1/registry/service.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/registry/service.go 2014-10-30 13:44:46.000000000 +0000
@@ -13,12 +13,15 @@
// 'pull': Download images from any registry (TODO)
// 'push': Upload images to any registry (TODO)
type Service struct {
+ insecureRegistries []string
}
// NewService returns a new instance of Service ready to be
// installed no an engine.
-func NewService() *Service {
- return &Service{}
+func NewService(insecureRegistries []string) *Service {
+ return &Service{
+ insecureRegistries: insecureRegistries,
+ }
}
// Install installs registry capabilities to eng.
@@ -32,15 +35,12 @@
// and returns OK if authentication was sucessful.
// It can be used to verify the validity of a client's credentials.
func (s *Service) Auth(job *engine.Job) engine.Status {
- var (
- err error
- authConfig = &AuthConfig{}
- )
+ var authConfig = new(AuthConfig)
job.GetenvJson("authConfig", authConfig)
- // TODO: this is only done here because auth and registry need to be merged into one pkg
+
if addr := authConfig.ServerAddress; addr != "" && addr != IndexServerAddress() {
- endpoint, err := NewEndpoint(addr)
+ endpoint, err := NewEndpoint(addr, IsSecure(addr, s.insecureRegistries))
if err != nil {
return job.Error(err)
}
@@ -49,11 +49,13 @@
}
authConfig.ServerAddress = endpoint.String()
}
+
status, err := Login(authConfig, HTTPRequestFactory(nil))
if err != nil {
return job.Error(err)
}
job.Printf("%s\n", status)
+
return engine.StatusOK
}
@@ -89,7 +91,10 @@
if err != nil {
return job.Error(err)
}
- endpoint, err := NewEndpoint(hostname)
+
+ secure := IsSecure(hostname, s.insecureRegistries)
+
+ endpoint, err := NewEndpoint(hostname, secure)
if err != nil {
return job.Error(err)
}
diff -Nru docker.io-1.3.0~dfsg1/registry/session.go docker.io-1.3.1~dfsg1/registry/session.go
--- docker.io-1.3.0~dfsg1/registry/session.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/registry/session.go 2014-10-30 13:44:46.000000000 +0000
@@ -64,7 +64,7 @@
}
func (r *Session) doRequest(req *http.Request) (*http.Response, *http.Client, error) {
- return doRequest(req, r.jar, r.timeout)
+ return doRequest(req, r.jar, r.timeout, r.indexEndpoint.secure)
}
// Retrieve the history of a given image from the Registry.
diff -Nru docker.io-1.3.0~dfsg1/runconfig/merge.go docker.io-1.3.1~dfsg1/runconfig/merge.go
--- docker.io-1.3.0~dfsg1/runconfig/merge.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/runconfig/merge.go 2014-10-30 13:44:46.000000000 +0000
@@ -88,7 +88,10 @@
if len(userConf.Cmd) == 0 {
userConf.Cmd = imageConf.Cmd
}
- userConf.Entrypoint = imageConf.Entrypoint
+
+ if userConf.Entrypoint == nil {
+ userConf.Entrypoint = imageConf.Entrypoint
+ }
}
if userConf.WorkingDir == "" {
userConf.WorkingDir = imageConf.WorkingDir
diff -Nru docker.io-1.3.0~dfsg1/volumes/repository.go docker.io-1.3.1~dfsg1/volumes/repository.go
--- docker.io-1.3.0~dfsg1/volumes/repository.go 2014-10-15 19:15:24.000000000 +0000
+++ docker.io-1.3.1~dfsg1/volumes/repository.go 2014-10-30 13:44:46.000000000 +0000
@@ -55,6 +55,7 @@
return nil, err
}
}
+ path = filepath.Clean(path)
path, err = filepath.EvalSymlinks(path)
if err != nil {
@@ -126,7 +127,7 @@
if err != nil {
return nil
}
- return r.volumes[path]
+ return r.volumes[filepath.Clean(path)]
}
func (r *Repository) Add(volume *Volume) error {
@@ -160,7 +161,7 @@
if err != nil {
return err
}
- volume := r.get(path)
+ volume := r.get(filepath.Clean(path))
if volume == nil {
return fmt.Errorf("Volume %s does not exist", path)
}
Reply to: