From 1cbc4221a383878e6b620189d1de8c29bd50dbdd Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Fri, 6 Dec 2013 21:18:42 -0800 Subject: [PATCH 01/14] vendor: add github.com/coreos/go-systemd/activation Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: e996daeed08defbab8864be1e26cd1294b12af87 Component: engine --- .../src/github.com/coreos/go-systemd/LICENSE | 191 ++++++++++++++++++ .../github.com/coreos/go-systemd/README.md | 3 + .../coreos/go-systemd/activation/files.go | 38 ++++ .../go-systemd/activation/files_test.go | 68 +++++++ 4 files changed, 300 insertions(+) create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/README.md create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE b/components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE new file mode 100644 index 0000000000..37ec93a14f --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/README.md b/components/engine/vendor/src/github.com/coreos/go-systemd/README.md new file mode 100644 index 0000000000..9b8a2f83ff --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/README.md @@ -0,0 +1,3 @@ +# go-systemd + +Go bindings to systemd socket activation, journal and D-BUS APIs. diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go new file mode 100644 index 0000000000..3f323d8201 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go @@ -0,0 +1,38 @@ +// Package activation implements primitives for systemd socket activation. +package activation + +import ( + "os" + "strconv" + "syscall" +) + +// based on: https://gist.github.com/alberts/4640792 +const ( + listenFdsStart = 3 +) + +func Files(unsetEnv bool) []*os.File { + + if unsetEnv { + // there is no way to unset env in golang os package for now + // https://code.google.com/p/go/issues/detail?id=6423 + defer os.Setenv("LISTEN_PID", "") + defer os.Setenv("LISTEN_FDS", "") + } + + pid, err := strconv.Atoi(os.Getenv("LISTEN_PID")) + if err != nil || pid != os.Getpid() { + return nil + } + nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) + if err != nil || nfds == 0 { + return nil + } + var files []*os.File + for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ { + syscall.CloseOnExec(fd) + files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd))) + } + return files +} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go new file mode 100644 index 0000000000..cee919e765 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go @@ -0,0 +1,68 @@ +package activation + +import ( + "bytes" + "io" + "os" + "os/exec" + "testing" +) + +// correctStringWritten fails the text if the correct string wasn't written +// to the other side of the pipe. +func correctStringWritten(t *testing.T, r *os.File, expected string) bool { + bytes := make([]byte, len(expected)) + io.ReadAtLeast(r, bytes, len(expected)) + + if string(bytes) != expected { + t.Fatalf("Unexpected string %s", string(bytes)) + } + + return true +} + +// TestActivation forks out a copy of activation.go example and reads back two +// strings from the pipes that are passed in. +func TestActivation(t *testing.T) { + cmd := exec.Command("go", "run", "../examples/activation/activation.go") + + r1, w1, _ := os.Pipe() + r2, w2, _ := os.Pipe() + cmd.ExtraFiles = []*os.File{ + w1, + w2, + } + + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") + + err := cmd.Run() + if err != nil { + t.Fatalf(err.Error()) + } + + correctStringWritten(t, r1, "Hello world") + correctStringWritten(t, r2, "Goodbye world") +} + +func TestActivationNoFix(t *testing.T) { + cmd := exec.Command("go", "run", "../examples/activation/activation.go") + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, "LISTEN_FDS=2") + + out, _ := cmd.CombinedOutput() + if bytes.Contains(out, []byte("No files")) == false { + t.Fatalf("Child didn't error out as expected") + } +} + +func TestActivationNoFiles(t *testing.T) { + cmd := exec.Command("go", "run", "../examples/activation/activation.go") + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, "LISTEN_FDS=0", "FIX_LISTEN_PID=1") + + out, _ := cmd.CombinedOutput() + if bytes.Contains(out, []byte("No files")) == false { + t.Fatalf("Child didn't error out as expected") + } +} From 93246312a11f630bd46d3526f60b9ace9eae95da Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Fri, 6 Dec 2013 21:19:30 -0800 Subject: [PATCH 02/14] server: add socket activation This adds the ability to socket activate docker by passing in `-H fd://*` along with examples systemd configuration files. The fastest way to test this is to run: ``` /usr/lib/systemd/systemd-activate -l 127.0.0.1:2001 /usr/bin/docker -d -H 'fd://*' docker -H tcp://127.0.0.1:2001 ps ``` Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 87fb2c973d8f9a8a1868ab0c2da504095d04715b Component: engine --- components/engine/api.go | 64 +++++++++++++++++-- .../systemd/socket-activation/docker.service | 11 ++++ .../systemd/socket-activation/docker.socket | 8 +++ components/engine/server.go | 26 ++++---- components/engine/systemd/listendfd.go | 41 ++++++++++++ components/engine/utils/utils.go | 2 + 6 files changed, 130 insertions(+), 22 deletions(-) create mode 100644 components/engine/contrib/init/systemd/socket-activation/docker.service create mode 100644 components/engine/contrib/init/systemd/socket-activation/docker.socket create mode 100644 components/engine/systemd/listendfd.go diff --git a/components/engine/api.go b/components/engine/api.go index bf9f29b57f..e522583087 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -24,6 +24,7 @@ import ( "regexp" "strconv" "strings" + "syscall" ) const ( @@ -1081,16 +1082,66 @@ func ServeRequest(srv *Server, apiversion float64, w http.ResponseWriter, req *h return nil } +// ServeFD creates an http.Server and sets it up to serve given a socket activated +// argument. +func ServeFd(addr string, handle http.Handler) error { + ls, e := systemd.ListenFD(addr) + if e != nil { + return e + } + + chErrors := make(chan error, len(ls)) + + // Since ListenFD will return one or more sockets we have + // to create a go func to spawn off multiple serves + for i, _ := range(ls) { + listener := ls[i] + go func () { + httpSrv := http.Server{Handler: handle} + chErrors <- httpSrv.Serve(listener) + }() + } + + for i := 0; i < len(ls); i += 1 { + err := <-chErrors + if err != nil { + return err + } + } + + return nil +} + +// ListenAndServe sets up the required http.Server and gets it listening for +// each addr passed in and does protocol specific checking. func ListenAndServe(proto, addr string, srv *Server, logging bool) error { r, err := createRouter(srv, logging) if err != nil { return err } - l, e := net.Listen(proto, addr) - if e != nil { - return e + + if proto == "fd" { + return ServeFd(addr, r) } + if proto == "unix" { + if err := syscall.Unlink(addr); err != nil && !os.IsNotExist(err) { + return err + } + } + + l, err := net.Listen(proto, addr) + if err != nil { + return err + } + + // Basic error and sanity checking + switch proto { + case "tcp": + if !strings.HasPrefix(addr, "127.0.0.1") { + log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\") + } + case "unix": if err := os.Chmod(addr, 0660); err != nil { return err } @@ -1110,11 +1161,10 @@ func ListenAndServe(proto, addr string, srv *Server, logging bool) error { return err } } + default: + return fmt.Errorf("Invalid protocol format.") } - httpSrv := http.Server{Addr: addr, Handler: r} - log.Printf("Listening for HTTP on %s (%s)\n", addr, proto) - // Tell the init daemon we are accepting requests - go systemd.SdNotify("READY=1") + httpSrv := http.Server{Addr: addr, Handler: r} return httpSrv.Serve(l) } diff --git a/components/engine/contrib/init/systemd/socket-activation/docker.service b/components/engine/contrib/init/systemd/socket-activation/docker.service new file mode 100644 index 0000000000..0b39c28328 --- /dev/null +++ b/components/engine/contrib/init/systemd/socket-activation/docker.service @@ -0,0 +1,11 @@ +[Unit] +Description=Docker Application Container Engine +Documentation=http://docs.docker.io +After=network.target + +[Service] +ExecStartPre=/bin/mount --make-rprivate / +ExecStart=/usr/bin/docker -d -H fd://* + +[Install] +WantedBy=multi-user.target diff --git a/components/engine/contrib/init/systemd/socket-activation/docker.socket b/components/engine/contrib/init/systemd/socket-activation/docker.socket new file mode 100644 index 0000000000..3635c89385 --- /dev/null +++ b/components/engine/contrib/init/systemd/socket-activation/docker.socket @@ -0,0 +1,8 @@ +[Unit] +Description=Docker Socket for the API + +[Socket] +ListenStream=/var/run/docker.sock + +[Install] +WantedBy=sockets.target diff --git a/components/engine/server.go b/components/engine/server.go index b4add79771..b87ec659f8 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -10,6 +10,7 @@ import ( "github.com/dotcloud/docker/pkg/cgroups" "github.com/dotcloud/docker/pkg/graphdb" "github.com/dotcloud/docker/registry" + "github.com/dotcloud/docker/systemd" "github.com/dotcloud/docker/utils" "io" "io/ioutil" @@ -114,29 +115,20 @@ func jobInitApi(job *engine.Job) engine.Status { return engine.StatusOK } +// ListenAndServe loops through all of the protocols sent in to docker and spawns +// off a go routine to setup a serving http.Server for each. func (srv *Server) ListenAndServe(job *engine.Job) engine.Status { protoAddrs := job.Args chErrors := make(chan error, len(protoAddrs)) + for _, protoAddr := range protoAddrs { protoAddrParts := strings.SplitN(protoAddr, "://", 2) - switch protoAddrParts[0] { - case "unix": - if err := syscall.Unlink(protoAddrParts[1]); err != nil && !os.IsNotExist(err) { - log.Fatal(err) - } - case "tcp": - if !strings.HasPrefix(protoAddrParts[1], "127.0.0.1") { - log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\") - } - default: - job.Errorf("Invalid protocol format.") - return engine.StatusErr - } - go func() { - // FIXME: merge Server.ListenAndServe with ListenAndServe + go func () { + log.Printf("Listening for HTTP on %s (%s)\n", protoAddrParts[0], protoAddrParts[1]) chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], srv, job.GetenvBool("Logging")) }() } + for i := 0; i < len(protoAddrs); i += 1 { err := <-chErrors if err != nil { @@ -144,6 +136,10 @@ func (srv *Server) ListenAndServe(job *engine.Job) engine.Status { return engine.StatusErr } } + + // Tell the init daemon we are accepting requests + go systemd.SdNotify("READY=1") + return engine.StatusOK } diff --git a/components/engine/systemd/listendfd.go b/components/engine/systemd/listendfd.go new file mode 100644 index 0000000000..a8fdb09ca4 --- /dev/null +++ b/components/engine/systemd/listendfd.go @@ -0,0 +1,41 @@ +package systemd + +import ( + "errors" + "fmt" + "net" + "strconv" + + "github.com/coreos/go-systemd/activation" +) + +// ListenFD returns the specified socket activated files as a slice of +// net.Listeners or all of the activated files if "*" is given. +func ListenFD(addr string) ([]net.Listener, error) { + files := activation.Files(false) + if files == nil || len(files) == 0 { + return nil, errors.New("No sockets found") + } + + fdNum, _ := strconv.Atoi(addr) + fdOffset := fdNum - 3 + if (addr != "*") && (len(files) < int(fdOffset)+1) { + return nil, errors.New("Too few socket activated files passed in") + } + + // socket activation + listeners := make([]net.Listener, len(files)) + for i, f := range files { + var err error + listeners[i], err = net.FileListener(f) + if err != nil { + return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error()) + } + } + + if addr == "*" { + return listeners, nil + } + + return []net.Listener{listeners[fdOffset]}, nil +} diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index 2a11397212..542ab49702 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -767,6 +767,8 @@ func ParseHost(defaultHost string, defaultPort int, defaultUnix, addr string) (s case strings.HasPrefix(addr, "tcp://"): proto = "tcp" addr = strings.TrimPrefix(addr, "tcp://") + case strings.HasPrefix(addr, "fd://"): + return addr, nil case addr == "": proto = "unix" addr = defaultUnix From bbf27c35bb15b3c9c20a19138afd091eed293e58 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 21 Jan 2014 12:47:27 -0800 Subject: [PATCH 03/14] fix(docs): fixup based on changes in master Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: cfeb1f0f652e11b8b6a8b4e1cbed3835fc5d9546 Component: engine --- components/engine/docker/docker.go | 2 +- components/engine/docs/sources/reference/commandline/cli.rst | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/engine/docker/docker.go b/components/engine/docker/docker.go index 5f5b3c17ce..5824c78270 100644 --- a/components/engine/docker/docker.go +++ b/components/engine/docker/docker.go @@ -43,7 +43,7 @@ func main() { flMtu = flag.Int([]string{"#mtu", "-mtu"}, docker.DefaultNetworkMtu, "Set the containers network mtu") ) flag.Var(&flDns, []string{"#dns", "-dns"}, "Force docker to use specific DNS servers") - flag.Var(&flHosts, []string{"H", "-host"}, "Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise") + flag.Var(&flHosts, []string{"H", "-host"}, "tcp://host:port, unix://path/to/socket, fd://* or fd://socketfd to use in daemon mode. Multiple sockets can be specified") flag.Parse() diff --git a/components/engine/docs/sources/reference/commandline/cli.rst b/components/engine/docs/sources/reference/commandline/cli.rst index e71b691bcc..a0b2115987 100644 --- a/components/engine/docs/sources/reference/commandline/cli.rst +++ b/components/engine/docs/sources/reference/commandline/cli.rst @@ -27,7 +27,7 @@ To list available commands, either run ``docker`` with no parameters or execute Usage of docker: -D, --debug=false: Enable debug mode - -H, --host=[]: Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise + -H, --host=[]: Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise. systemd socket activation can be used with fd://[socketfd]. --api-enable-cors=false: Enable CORS headers in the remote API -b, --bridge="": Attach containers to a pre-existing network bridge; use 'none' to disable container networking --bip="": Use this CIDR notation address for the network bridge's IP, not compatible with -b @@ -63,6 +63,8 @@ the ``-H`` flag for the client. # both are equal +To run the daemon with socket activation, use ``docker -d -H fd://*``. Individual sockets can also be specified ``docker -d -H fd://3``. + .. _cli_attach: ``attach`` From efeecbbbfbefb3285c1903ade7ff702ca858d73e Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 10 Dec 2013 17:39:20 -0800 Subject: [PATCH 04/14] docs: improve the socket activation cli docs as suggested by SvenDowideit expand the docs to have more information on socket activation. Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 4a90f00ab7ec9e534c97611dbbdc412ed5966602 Component: engine --- components/engine/docs/sources/reference/commandline/cli.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/engine/docs/sources/reference/commandline/cli.rst b/components/engine/docs/sources/reference/commandline/cli.rst index a0b2115987..a9fc9100a0 100644 --- a/components/engine/docs/sources/reference/commandline/cli.rst +++ b/components/engine/docs/sources/reference/commandline/cli.rst @@ -63,7 +63,10 @@ the ``-H`` flag for the client. # both are equal -To run the daemon with socket activation, use ``docker -d -H fd://*``. Individual sockets can also be specified ``docker -d -H fd://3``. +To run the daemon with `socket activation `, use ``docker -d -H fd://*``. +Using ``fd://*`` will work perfectly for most setups but you can also specify individual sockets too ``docker -d -H fd://3``. +If the specified socket activated files aren't found then docker will exit. +You can find examples of using socket activation with docker and systemd in the `docker source tree `. .. _cli_attach: From 5197c3fef90d32aef6880969215be3be3d893dfb Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Wed, 18 Dec 2013 10:15:31 -0800 Subject: [PATCH 05/14] fix(docs): add Systemd in front of socket activation Suggested by SvenDowideit. Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 6acc99889d97638d632a2974e04cd91ed4036c4b Component: engine --- components/engine/docs/sources/reference/commandline/cli.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/engine/docs/sources/reference/commandline/cli.rst b/components/engine/docs/sources/reference/commandline/cli.rst index a9fc9100a0..e9809156d5 100644 --- a/components/engine/docs/sources/reference/commandline/cli.rst +++ b/components/engine/docs/sources/reference/commandline/cli.rst @@ -63,10 +63,10 @@ the ``-H`` flag for the client. # both are equal -To run the daemon with `socket activation `, use ``docker -d -H fd://*``. +To run the daemon with `systemd socket activation `, use ``docker -d -H fd://*``. Using ``fd://*`` will work perfectly for most setups but you can also specify individual sockets too ``docker -d -H fd://3``. If the specified socket activated files aren't found then docker will exit. -You can find examples of using socket activation with docker and systemd in the `docker source tree `. +You can find examples of using systemd socket activation with docker and systemd in the `docker source tree `. .. _cli_attach: From 843c8c74fb965c07099eeb99431e774b6684c348 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Fri, 3 Jan 2014 18:06:34 -0800 Subject: [PATCH 06/14] Move listenfd to utility package Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 566fb31c889cfa05c617f44e6c99d44578d643a5 Component: engine --- components/engine/{ => pkg}/systemd/listendfd.go | 0 components/engine/server.go | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename components/engine/{ => pkg}/systemd/listendfd.go (100%) diff --git a/components/engine/systemd/listendfd.go b/components/engine/pkg/systemd/listendfd.go similarity index 100% rename from components/engine/systemd/listendfd.go rename to components/engine/pkg/systemd/listendfd.go diff --git a/components/engine/server.go b/components/engine/server.go index b87ec659f8..a9d4a20bfb 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -10,7 +10,7 @@ import ( "github.com/dotcloud/docker/pkg/cgroups" "github.com/dotcloud/docker/pkg/graphdb" "github.com/dotcloud/docker/registry" - "github.com/dotcloud/docker/systemd" + "github.com/dotcloud/docker/pkg/systemd" "github.com/dotcloud/docker/utils" "io" "io/ioutil" From 7f4461fb981e4989a188b2aead80a9b662a591ed Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Fri, 3 Jan 2014 18:07:43 -0800 Subject: [PATCH 07/14] Allow fd:// like unix:// and tcp:// Somthing like 20605eb310f0b57bd06eea80ec63c5022fc83bde Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 7f9d3268bf0e1d4a79d07c67e22eb14d3de96f6c Component: engine --- .../contrib/init/systemd/socket-activation/docker.service | 2 +- components/engine/docs/sources/reference/commandline/cli.rst | 4 ++-- components/engine/pkg/systemd/listendfd.go | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/components/engine/contrib/init/systemd/socket-activation/docker.service b/components/engine/contrib/init/systemd/socket-activation/docker.service index 0b39c28328..405bdf5afc 100644 --- a/components/engine/contrib/init/systemd/socket-activation/docker.service +++ b/components/engine/contrib/init/systemd/socket-activation/docker.service @@ -5,7 +5,7 @@ After=network.target [Service] ExecStartPre=/bin/mount --make-rprivate / -ExecStart=/usr/bin/docker -d -H fd://* +ExecStart=/usr/bin/docker -d -H fd:// [Install] WantedBy=multi-user.target diff --git a/components/engine/docs/sources/reference/commandline/cli.rst b/components/engine/docs/sources/reference/commandline/cli.rst index e9809156d5..739e93975d 100644 --- a/components/engine/docs/sources/reference/commandline/cli.rst +++ b/components/engine/docs/sources/reference/commandline/cli.rst @@ -63,8 +63,8 @@ the ``-H`` flag for the client. # both are equal -To run the daemon with `systemd socket activation `, use ``docker -d -H fd://*``. -Using ``fd://*`` will work perfectly for most setups but you can also specify individual sockets too ``docker -d -H fd://3``. +To run the daemon with `systemd socket activation `, use ``docker -d -H fd://``. +Using ``fd://`` will work perfectly for most setups but you can also specify individual sockets too ``docker -d -H fd://3``. If the specified socket activated files aren't found then docker will exit. You can find examples of using systemd socket activation with docker and systemd in the `docker source tree `. diff --git a/components/engine/pkg/systemd/listendfd.go b/components/engine/pkg/systemd/listendfd.go index a8fdb09ca4..08070b6ece 100644 --- a/components/engine/pkg/systemd/listendfd.go +++ b/components/engine/pkg/systemd/listendfd.go @@ -17,6 +17,11 @@ func ListenFD(addr string) ([]net.Listener, error) { return nil, errors.New("No sockets found") } + // default to all fds just like unix:// and tcp:// + if addr == "" { + addr = "*" + } + fdNum, _ := strconv.Atoi(addr) fdOffset := fdNum - 3 if (addr != "*") && (len(files) < int(fdOffset)+1) { From 599a6cd34cbeb41ad9b38f13da33dc625872922e Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 7 Jan 2014 16:10:32 -0800 Subject: [PATCH 08/14] fix(cli.rst): add missing underscores As suggested by @metalivedev Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 2fe7588af79bbc61e758ff066be1cf1c2d381f7b Component: engine --- components/engine/docs/sources/reference/commandline/cli.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/engine/docs/sources/reference/commandline/cli.rst b/components/engine/docs/sources/reference/commandline/cli.rst index 739e93975d..3d215cc0b4 100644 --- a/components/engine/docs/sources/reference/commandline/cli.rst +++ b/components/engine/docs/sources/reference/commandline/cli.rst @@ -63,10 +63,10 @@ the ``-H`` flag for the client. # both are equal -To run the daemon with `systemd socket activation `, use ``docker -d -H fd://``. +To run the daemon with `systemd socket activation `_, use ``docker -d -H fd://``. Using ``fd://`` will work perfectly for most setups but you can also specify individual sockets too ``docker -d -H fd://3``. If the specified socket activated files aren't found then docker will exit. -You can find examples of using systemd socket activation with docker and systemd in the `docker source tree `. +You can find examples of using systemd socket activation with docker and systemd in the `docker source tree `_. .. _cli_attach: From e0523eee436ad00b447512df0340b43220ffe8bf Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 14 Jan 2014 10:06:08 -0800 Subject: [PATCH 09/14] fix(contrib/init/systemd): remove mount rprivate Docker does this now via 157d99a72786c454dfaad8b0800914cc80879aa8 Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 1f44921c51883e923ed82ed4e30eca6f79702cfb Component: engine --- .../engine/contrib/init/systemd/socket-activation/docker.service | 1 - 1 file changed, 1 deletion(-) diff --git a/components/engine/contrib/init/systemd/socket-activation/docker.service b/components/engine/contrib/init/systemd/socket-activation/docker.service index 405bdf5afc..4ab92dfef8 100644 --- a/components/engine/contrib/init/systemd/socket-activation/docker.service +++ b/components/engine/contrib/init/systemd/socket-activation/docker.service @@ -4,7 +4,6 @@ Documentation=http://docs.docker.io After=network.target [Service] -ExecStartPre=/bin/mount --make-rprivate / ExecStart=/usr/bin/docker -d -H fd:// [Install] From b82cbc21447be007f383f1d251d760dc9693e0b3 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 14 Jan 2014 20:07:39 -0800 Subject: [PATCH 10/14] chore(*): go fmt I noticed that travis was failing, go fmt to make it happy. Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 1603039a7150e0510853efc9a9733ef64508dbb0 Component: engine --- components/engine/api.go | 4 ++-- components/engine/server.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/engine/api.go b/components/engine/api.go index e522583087..9c2c1fcdba 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -1094,9 +1094,9 @@ func ServeFd(addr string, handle http.Handler) error { // Since ListenFD will return one or more sockets we have // to create a go func to spawn off multiple serves - for i, _ := range(ls) { + for i, _ := range ls { listener := ls[i] - go func () { + go func() { httpSrv := http.Server{Handler: handle} chErrors <- httpSrv.Serve(listener) }() diff --git a/components/engine/server.go b/components/engine/server.go index a9d4a20bfb..14974dec73 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -9,8 +9,8 @@ import ( "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/pkg/cgroups" "github.com/dotcloud/docker/pkg/graphdb" - "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/pkg/systemd" + "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/utils" "io" "io/ioutil" @@ -123,7 +123,7 @@ func (srv *Server) ListenAndServe(job *engine.Job) engine.Status { for _, protoAddr := range protoAddrs { protoAddrParts := strings.SplitN(protoAddr, "://", 2) - go func () { + go func() { log.Printf("Listening for HTTP on %s (%s)\n", protoAddrParts[0], protoAddrParts[1]) chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], srv, job.GetenvBool("Logging")) }() From 25f4ec26df84acda238b373537a53c2d7aca0295 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Fri, 17 Jan 2014 13:18:43 -0800 Subject: [PATCH 11/14] vendor: bump github.com/coreos/go-systemd/activation tests now work in the Docker tree with `go test github.com/coreos/go-systemd/activation` Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: f82d1291cc850b39d872d022feac6b9eb7773d64 Component: engine --- .../coreos/go-systemd/activation/files.go | 4 +- .../coreos/go-systemd/activation/listeners.go | 22 ++++++ .../go-systemd/activation/listeners_test.go | 72 +++++++++++++++++++ .../examples/activation/activation.go | 44 ++++++++++++ .../examples/activation/httpserver/README.md | 1 + .../activation/httpserver/hello.service | 11 +++ .../activation/httpserver/hello.socket | 5 ++ .../activation/httpserver/httpserver.go | 29 ++++++++ .../go-systemd/examples/activation/listen.go | 50 +++++++++++++ 9 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go create mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go index 3f323d8201..d4f4cc58ea 100644 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go @@ -13,7 +13,6 @@ const ( ) func Files(unsetEnv bool) []*os.File { - if unsetEnv { // there is no way to unset env in golang os package for now // https://code.google.com/p/go/issues/detail?id=6423 @@ -25,14 +24,17 @@ func Files(unsetEnv bool) []*os.File { if err != nil || pid != os.Getpid() { return nil } + nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) if err != nil || nfds == 0 { return nil } + var files []*os.File for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ { syscall.CloseOnExec(fd) files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd))) } + return files } diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go new file mode 100644 index 0000000000..0fbd4ead6f --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go @@ -0,0 +1,22 @@ +package activation + +import ( + "fmt" + "net" +) + +// Listeners returns net.Listeners for all socket activated fds passed to this process. +func Listeners(unsetEnv bool) ([]net.Listener, error) { + files := Files(unsetEnv) + listeners := make([]net.Listener, len(files)) + + for i, f := range files { + var err error + listeners[i], err = net.FileListener(f) + if err != nil { + return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error()) + } + } + + return listeners, nil +} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go new file mode 100644 index 0000000000..6a8852184b --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go @@ -0,0 +1,72 @@ +package activation + +import ( + "io" + "net" + "os" + "os/exec" + "testing" +) + +// correctStringWritten fails the text if the correct string wasn't written +// to the other side of the pipe. +func correctStringWrittenNet(t *testing.T, r net.Conn, expected string) bool { + bytes := make([]byte, len(expected)) + io.ReadAtLeast(r, bytes, len(expected)) + + if string(bytes) != expected { + t.Fatalf("Unexpected string %s", string(bytes)) + } + + return true +} + +// TestActivation forks out a copy of activation.go example and reads back two +// strings from the pipes that are passed in. +func TestListeners(t *testing.T) { + cmd := exec.Command("go", "run", "../examples/activation/listen.go") + + l1, err := net.Listen("tcp", ":9999") + if err != nil { + t.Fatalf(err.Error()) + } + l2, err := net.Listen("tcp", ":1234") + if err != nil { + t.Fatalf(err.Error()) + } + + t1 := l1.(*net.TCPListener) + t2 := l2.(*net.TCPListener) + + f1, _ := t1.File() + f2, _ := t2.File() + + cmd.ExtraFiles = []*os.File{ + f1, + f2, + } + + r1, err := net.Dial("tcp", "127.0.0.1:9999") + if err != nil { + t.Fatalf(err.Error()) + } + r1.Write([]byte("Hi")) + + r2, err := net.Dial("tcp", "127.0.0.1:1234") + if err != nil { + t.Fatalf(err.Error()) + } + r2.Write([]byte("Hi")) + + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") + + out, err := cmd.Output() + if err != nil { + println(string(out)) + t.Fatalf(err.Error()) + } + + correctStringWrittenNet(t, r1, "Hello world") + correctStringWrittenNet(t, r2, "Goodbye world") +} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go new file mode 100644 index 0000000000..b3cf70ed84 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go @@ -0,0 +1,44 @@ +// Activation example used by the activation unit tests. +package main + +import ( + "fmt" + "os" + + "github.com/coreos/go-systemd/activation" +) + +func fixListenPid() { + if os.Getenv("FIX_LISTEN_PID") != "" { + // HACK: real systemd would set LISTEN_PID before exec'ing but + // this is too difficult in golang for the purpose of a test. + // Do not do this in real code. + os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())) + } +} + +func main() { + fixListenPid() + + files := activation.Files(false) + + if len(files) == 0 { + panic("No files") + } + + if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" { + panic("Should not unset envs") + } + + files = activation.Files(true) + + if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" { + panic("Can not unset envs") + } + + // Write out the expected strings to the two pipes + files[0].Write([]byte("Hello world")) + files[1].Write([]byte("Goodbye world")) + + return +} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md new file mode 100644 index 0000000000..91c7cbf130 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md @@ -0,0 +1 @@ +Example of using socket activation with systemd to serve a simple HTTP server on http://127.0.0.1:8076 diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service new file mode 100644 index 0000000000..c8dea0f6b3 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service @@ -0,0 +1,11 @@ +[Unit] +Description=Hello World HTTP +Requires=network.target +After=multi-user.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/httpserver + +[Install] +WantedBy=multi-user.target diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket new file mode 100644 index 0000000000..723ed7ed92 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket @@ -0,0 +1,5 @@ +[Socket] +ListenStream=127.0.0.1:8076 + +[Install] +WantedBy=sockets.target diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go new file mode 100644 index 0000000000..db12ecf612 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go @@ -0,0 +1,29 @@ +package main + +import ( + "io" + "net" + "net/http" + + "github.com/coreos/go-systemd/activation" +) + +func HelloServer(w http.ResponseWriter, req *http.Request) { + io.WriteString(w, "hello socket activated world!\n") +} + +func main() { + files := activation.Files(true) + + if len(files) != 1 { + panic("Unexpected number of socket activation fds") + } + + l, err := net.FileListener(files[0]) + if err != nil { + panic(err) + } + + http.HandleFunc("/", HelloServer) + http.Serve(l, nil) +} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go new file mode 100644 index 0000000000..5850a8b796 --- /dev/null +++ b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go @@ -0,0 +1,50 @@ +// Activation example used by the activation unit tests. +package main + +import ( + "fmt" + "os" + + "github.com/coreos/go-systemd/activation" +) + +func fixListenPid() { + if os.Getenv("FIX_LISTEN_PID") != "" { + // HACK: real systemd would set LISTEN_PID before exec'ing but + // this is too difficult in golang for the purpose of a test. + // Do not do this in real code. + os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())) + } +} + +func main() { + fixListenPid() + + listeners, _ := activation.Listeners(false) + + if len(listeners) == 0 { + panic("No listeners") + } + + if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" { + panic("Should not unset envs") + } + + listeners, err := activation.Listeners(true) + if err != nil { + panic(err) + } + + if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" { + panic("Can not unset envs") + } + + c0, _ := listeners[0].Accept() + c1, _ := listeners[1].Accept() + + // Write out the expected strings to the two pipes + c0.Write([]byte("Hello world")) + c1.Write([]byte("Goodbye world")) + + return +} From 1ce079fc3122b36d8206b5c2cd78a68b4283c1c4 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Fri, 17 Jan 2014 14:07:06 -0800 Subject: [PATCH 12/14] chore(systemd): use activation.Listeners instead of Files Use this Listeners() API that was exposed to save a few more lines of boiler plate code. Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: def09526066001eefe16dbc6475b93bc1a9af0a2 Component: engine --- components/engine/pkg/systemd/listendfd.go | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/components/engine/pkg/systemd/listendfd.go b/components/engine/pkg/systemd/listendfd.go index 08070b6ece..0fbc0a6ab6 100644 --- a/components/engine/pkg/systemd/listendfd.go +++ b/components/engine/pkg/systemd/listendfd.go @@ -2,7 +2,6 @@ package systemd import ( "errors" - "fmt" "net" "strconv" @@ -12,8 +11,13 @@ import ( // ListenFD returns the specified socket activated files as a slice of // net.Listeners or all of the activated files if "*" is given. func ListenFD(addr string) ([]net.Listener, error) { - files := activation.Files(false) - if files == nil || len(files) == 0 { + // socket activation + listeners, err := activation.Listeners(false) + if err != nil { + return nil, err + } + + if listeners == nil || len(listeners) == 0 { return nil, errors.New("No sockets found") } @@ -24,20 +28,10 @@ func ListenFD(addr string) ([]net.Listener, error) { fdNum, _ := strconv.Atoi(addr) fdOffset := fdNum - 3 - if (addr != "*") && (len(files) < int(fdOffset)+1) { + if (addr != "*") && (len(listeners) < int(fdOffset)+1) { return nil, errors.New("Too few socket activated files passed in") } - // socket activation - listeners := make([]net.Listener, len(files)) - for i, f := range files { - var err error - listeners[i], err = net.FileListener(f) - if err != nil { - return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error()) - } - } - if addr == "*" { return listeners, nil } From f715944faf9c16946feec4be361194279d76f93b Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 21 Jan 2014 12:43:57 -0800 Subject: [PATCH 13/14] chore(coreos/go-systemd): copy to github.com/dotcloud/docker/systemd/pkg/activation Via https://github.com/dotcloud/docker/pull/3105#issuecomment-32807547 Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 7839350dd582cc0f08b5e0de735d57baa08328ff Component: engine --- .../systemd}/activation/files.go | 15 ++ .../pkg/systemd/activation/listeners.go | 37 ++++ components/engine/pkg/systemd/listendfd.go | 2 +- .../src/github.com/coreos/go-systemd/LICENSE | 191 ------------------ .../github.com/coreos/go-systemd/README.md | 3 - .../go-systemd/activation/files_test.go | 68 ------- .../coreos/go-systemd/activation/listeners.go | 22 -- .../go-systemd/activation/listeners_test.go | 72 ------- .../examples/activation/activation.go | 44 ---- .../examples/activation/httpserver/README.md | 1 - .../activation/httpserver/hello.service | 11 - .../activation/httpserver/hello.socket | 5 - .../activation/httpserver/httpserver.go | 29 --- .../go-systemd/examples/activation/listen.go | 50 ----- 14 files changed, 53 insertions(+), 497 deletions(-) rename components/engine/{vendor/src/github.com/coreos/go-systemd => pkg/systemd}/activation/files.go (61%) create mode 100644 components/engine/pkg/systemd/activation/listeners.go delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/README.md delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go delete mode 100644 components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go b/components/engine/pkg/systemd/activation/files.go similarity index 61% rename from components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go rename to components/engine/pkg/systemd/activation/files.go index d4f4cc58ea..0281146310 100644 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files.go +++ b/components/engine/pkg/systemd/activation/files.go @@ -1,3 +1,18 @@ +/* +Copyright 2013 CoreOS Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ // Package activation implements primitives for systemd socket activation. package activation diff --git a/components/engine/pkg/systemd/activation/listeners.go b/components/engine/pkg/systemd/activation/listeners.go new file mode 100644 index 0000000000..3296a08361 --- /dev/null +++ b/components/engine/pkg/systemd/activation/listeners.go @@ -0,0 +1,37 @@ +/* +Copyright 2014 CoreOS Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package activation + +import ( + "fmt" + "net" +) + +// Listeners returns net.Listeners for all socket activated fds passed to this process. +func Listeners(unsetEnv bool) ([]net.Listener, error) { + files := Files(unsetEnv) + listeners := make([]net.Listener, len(files)) + + for i, f := range files { + var err error + listeners[i], err = net.FileListener(f) + if err != nil { + return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error()) + } + } + + return listeners, nil +} diff --git a/components/engine/pkg/systemd/listendfd.go b/components/engine/pkg/systemd/listendfd.go index 0fbc0a6ab6..f6044328c2 100644 --- a/components/engine/pkg/systemd/listendfd.go +++ b/components/engine/pkg/systemd/listendfd.go @@ -5,7 +5,7 @@ import ( "net" "strconv" - "github.com/coreos/go-systemd/activation" + "github.com/dotcloud/docker/pkg/systemd/activation" ) // ListenFD returns the specified socket activated files as a slice of diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE b/components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE deleted file mode 100644 index 37ec93a14f..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/README.md b/components/engine/vendor/src/github.com/coreos/go-systemd/README.md deleted file mode 100644 index 9b8a2f83ff..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# go-systemd - -Go bindings to systemd socket activation, journal and D-BUS APIs. diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go deleted file mode 100644 index cee919e765..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/files_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package activation - -import ( - "bytes" - "io" - "os" - "os/exec" - "testing" -) - -// correctStringWritten fails the text if the correct string wasn't written -// to the other side of the pipe. -func correctStringWritten(t *testing.T, r *os.File, expected string) bool { - bytes := make([]byte, len(expected)) - io.ReadAtLeast(r, bytes, len(expected)) - - if string(bytes) != expected { - t.Fatalf("Unexpected string %s", string(bytes)) - } - - return true -} - -// TestActivation forks out a copy of activation.go example and reads back two -// strings from the pipes that are passed in. -func TestActivation(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - - r1, w1, _ := os.Pipe() - r2, w2, _ := os.Pipe() - cmd.ExtraFiles = []*os.File{ - w1, - w2, - } - - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") - - err := cmd.Run() - if err != nil { - t.Fatalf(err.Error()) - } - - correctStringWritten(t, r1, "Hello world") - correctStringWritten(t, r2, "Goodbye world") -} - -func TestActivationNoFix(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2") - - out, _ := cmd.CombinedOutput() - if bytes.Contains(out, []byte("No files")) == false { - t.Fatalf("Child didn't error out as expected") - } -} - -func TestActivationNoFiles(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/activation.go") - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=0", "FIX_LISTEN_PID=1") - - out, _ := cmd.CombinedOutput() - if bytes.Contains(out, []byte("No files")) == false { - t.Fatalf("Child didn't error out as expected") - } -} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go deleted file mode 100644 index 0fbd4ead6f..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners.go +++ /dev/null @@ -1,22 +0,0 @@ -package activation - -import ( - "fmt" - "net" -) - -// Listeners returns net.Listeners for all socket activated fds passed to this process. -func Listeners(unsetEnv bool) ([]net.Listener, error) { - files := Files(unsetEnv) - listeners := make([]net.Listener, len(files)) - - for i, f := range files { - var err error - listeners[i], err = net.FileListener(f) - if err != nil { - return nil, fmt.Errorf("Error setting up FileListener for fd %d: %s", f.Fd(), err.Error()) - } - } - - return listeners, nil -} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go b/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go deleted file mode 100644 index 6a8852184b..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/activation/listeners_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package activation - -import ( - "io" - "net" - "os" - "os/exec" - "testing" -) - -// correctStringWritten fails the text if the correct string wasn't written -// to the other side of the pipe. -func correctStringWrittenNet(t *testing.T, r net.Conn, expected string) bool { - bytes := make([]byte, len(expected)) - io.ReadAtLeast(r, bytes, len(expected)) - - if string(bytes) != expected { - t.Fatalf("Unexpected string %s", string(bytes)) - } - - return true -} - -// TestActivation forks out a copy of activation.go example and reads back two -// strings from the pipes that are passed in. -func TestListeners(t *testing.T) { - cmd := exec.Command("go", "run", "../examples/activation/listen.go") - - l1, err := net.Listen("tcp", ":9999") - if err != nil { - t.Fatalf(err.Error()) - } - l2, err := net.Listen("tcp", ":1234") - if err != nil { - t.Fatalf(err.Error()) - } - - t1 := l1.(*net.TCPListener) - t2 := l2.(*net.TCPListener) - - f1, _ := t1.File() - f2, _ := t2.File() - - cmd.ExtraFiles = []*os.File{ - f1, - f2, - } - - r1, err := net.Dial("tcp", "127.0.0.1:9999") - if err != nil { - t.Fatalf(err.Error()) - } - r1.Write([]byte("Hi")) - - r2, err := net.Dial("tcp", "127.0.0.1:1234") - if err != nil { - t.Fatalf(err.Error()) - } - r2.Write([]byte("Hi")) - - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1") - - out, err := cmd.Output() - if err != nil { - println(string(out)) - t.Fatalf(err.Error()) - } - - correctStringWrittenNet(t, r1, "Hello world") - correctStringWrittenNet(t, r2, "Goodbye world") -} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go deleted file mode 100644 index b3cf70ed84..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/activation.go +++ /dev/null @@ -1,44 +0,0 @@ -// Activation example used by the activation unit tests. -package main - -import ( - "fmt" - "os" - - "github.com/coreos/go-systemd/activation" -) - -func fixListenPid() { - if os.Getenv("FIX_LISTEN_PID") != "" { - // HACK: real systemd would set LISTEN_PID before exec'ing but - // this is too difficult in golang for the purpose of a test. - // Do not do this in real code. - os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())) - } -} - -func main() { - fixListenPid() - - files := activation.Files(false) - - if len(files) == 0 { - panic("No files") - } - - if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" { - panic("Should not unset envs") - } - - files = activation.Files(true) - - if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" { - panic("Can not unset envs") - } - - // Write out the expected strings to the two pipes - files[0].Write([]byte("Hello world")) - files[1].Write([]byte("Goodbye world")) - - return -} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md deleted file mode 100644 index 91c7cbf130..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/README.md +++ /dev/null @@ -1 +0,0 @@ -Example of using socket activation with systemd to serve a simple HTTP server on http://127.0.0.1:8076 diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service deleted file mode 100644 index c8dea0f6b3..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Hello World HTTP -Requires=network.target -After=multi-user.target - -[Service] -Type=simple -ExecStart=/usr/local/bin/httpserver - -[Install] -WantedBy=multi-user.target diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket deleted file mode 100644 index 723ed7ed92..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket +++ /dev/null @@ -1,5 +0,0 @@ -[Socket] -ListenStream=127.0.0.1:8076 - -[Install] -WantedBy=sockets.target diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go deleted file mode 100644 index db12ecf612..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "io" - "net" - "net/http" - - "github.com/coreos/go-systemd/activation" -) - -func HelloServer(w http.ResponseWriter, req *http.Request) { - io.WriteString(w, "hello socket activated world!\n") -} - -func main() { - files := activation.Files(true) - - if len(files) != 1 { - panic("Unexpected number of socket activation fds") - } - - l, err := net.FileListener(files[0]) - if err != nil { - panic(err) - } - - http.HandleFunc("/", HelloServer) - http.Serve(l, nil) -} diff --git a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go b/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go deleted file mode 100644 index 5850a8b796..0000000000 --- a/components/engine/vendor/src/github.com/coreos/go-systemd/examples/activation/listen.go +++ /dev/null @@ -1,50 +0,0 @@ -// Activation example used by the activation unit tests. -package main - -import ( - "fmt" - "os" - - "github.com/coreos/go-systemd/activation" -) - -func fixListenPid() { - if os.Getenv("FIX_LISTEN_PID") != "" { - // HACK: real systemd would set LISTEN_PID before exec'ing but - // this is too difficult in golang for the purpose of a test. - // Do not do this in real code. - os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid())) - } -} - -func main() { - fixListenPid() - - listeners, _ := activation.Listeners(false) - - if len(listeners) == 0 { - panic("No listeners") - } - - if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" { - panic("Should not unset envs") - } - - listeners, err := activation.Listeners(true) - if err != nil { - panic(err) - } - - if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" { - panic("Can not unset envs") - } - - c0, _ := listeners[0].Accept() - c1, _ := listeners[1].Accept() - - // Write out the expected strings to the two pipes - c0.Write([]byte("Hello world")) - c1.Write([]byte("Goodbye world")) - - return -} From 6cb1f3415868d699c320f2d0604e02800d40c882 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 27 Jan 2014 17:09:36 -0800 Subject: [PATCH 14/14] fix(api): , _ removed to simplify code in range Docker-DCO-1.1-Signed-off-by: Brandon Philips (github: philips) Upstream-commit: 4e5859e8300e7c56f28ca07c47131d14f6cf8632 Component: engine --- components/engine/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/api.go b/components/engine/api.go index 9c2c1fcdba..85c06bb26b 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -1094,7 +1094,7 @@ func ServeFd(addr string, handle http.Handler) error { // Since ListenFD will return one or more sockets we have // to create a go func to spawn off multiple serves - for i, _ := range ls { + for i := range ls { listener := ls[i] go func() { httpSrv := http.Server{Handler: handle}