Selaa lähdekoodia

Fix spurious "bad file descriptor" errors in bashbrew by using "exec.Cmd" objects more appropriately while streaming

Tianon Gravi 9 vuotta sitten
vanhempi
sitoutus
6e93c269d5

+ 1 - 0
bashbrew/go/src/bashbrew/cmd-build.go

@@ -92,6 +92,7 @@ func cmdBuild(c *cli.Context) error {
 				if err != nil {
 					return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
 				}
+				archive.Close() // be sure this happens sooner rather than later (defer might take a while, and we want to reap zombies more aggressively)
 			} else {
 				fmt.Printf("Using %s (%s)\n", cacheTag, r.Identifier())
 			}

+ 1 - 1
bashbrew/go/src/bashbrew/docker.go

@@ -35,10 +35,10 @@ func (r Repo) DockerFrom(entry *manifest.Manifest2822Entry) (string, error) {
 	}
 
 	dockerfile, err := gitShow(commit, dockerfileFile)
-	defer dockerfile.Close()
 	if err != nil {
 		return "", err
 	}
+	defer dockerfile.Close()
 
 	from, err := dockerfileFrom(dockerfile)
 	if err != nil {

+ 2 - 11
bashbrew/go/src/bashbrew/git.go

@@ -11,6 +11,7 @@ import (
 	"strings"
 
 	"github.com/docker-library/go-dockerlibrary/manifest"
+	"github.com/docker-library/go-dockerlibrary/pkg/execpipe"
 )
 
 func gitCache() string {
@@ -52,17 +53,7 @@ func getGitCommit(commit string) (string, error) {
 }
 
 func gitStream(args ...string) (io.ReadCloser, error) {
-	cmd := gitCommand(args...)
-	out, err := cmd.StdoutPipe()
-	if err != nil {
-		return nil, err
-	}
-	if err := cmd.Start(); err != nil {
-		out.Close()
-		return nil, err
-	}
-	go cmd.Wait() // make sure we get cleaned up, eventually
-	return out, nil
+	return execpipe.Run(gitCommand(args...))
 }
 
 func gitArchive(commit string, dir string) (io.ReadCloser, error) {

+ 5 - 105
bashbrew/go/vendor/manifest

@@ -10,85 +10,14 @@
 		{
 			"importpath": "github.com/docker-library/go-dockerlibrary",
 			"repository": "https://github.com/docker-library/go-dockerlibrary",
-			"revision": "d6068c47a73468f1ca56eafc4cd5aadea3968ea8",
+			"revision": "945a488370ddcccdd3b1bcbf8cb8e2beaf0d4825",
 			"branch": "master"
 		},
 		{
-			"importpath": "github.com/docker-library/go-dockerlibrary/manifest",
-			"repository": "https://github.com/docker-library/go-dockerlibrary",
-			"revision": "7d56be63f3f8ff42ef402595615fefc34f5bc393",
-			"branch": "master",
-			"path": "/manifest"
-		},
-		{
-			"importpath": "github.com/docker-library/go-dockerlibrary/pkg/stripper",
-			"repository": "https://github.com/docker-library/go-dockerlibrary",
-			"revision": "ea2a7991ce3e7e1ba50a635040fa0ee6bb967aeb",
-			"branch": "master",
-			"path": "/pkg/stripper"
-		},
-		{
-			"importpath": "github.com/docker-library/go-dockerlibrary/pkg/templatelib",
-			"repository": "https://github.com/docker-library/go-dockerlibrary",
-			"revision": "939e8fc63d2d9960bbe2450c7fbf007fbabfe3b6",
-			"branch": "master",
-			"path": "/pkg/templatelib"
-		},
-		{
-			"importpath": "golang.org/x/crypto/cast5",
-			"repository": "https://go.googlesource.com/crypto",
-			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/cast5"
-		},
-		{
-			"importpath": "golang.org/x/crypto/openpgp",
-			"repository": "https://go.googlesource.com/crypto",
-			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/openpgp"
-		},
-		{
-			"importpath": "golang.org/x/crypto/openpgp/armor",
-			"repository": "https://go.googlesource.com/crypto",
-			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/openpgp/armor"
-		},
-		{
-			"importpath": "golang.org/x/crypto/openpgp/clearsign",
+			"importpath": "golang.org/x/crypto",
 			"repository": "https://go.googlesource.com/crypto",
 			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/openpgp/clearsign"
-		},
-		{
-			"importpath": "golang.org/x/crypto/openpgp/elgamal",
-			"repository": "https://go.googlesource.com/crypto",
-			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/openpgp/elgamal"
-		},
-		{
-			"importpath": "golang.org/x/crypto/openpgp/errors",
-			"repository": "https://go.googlesource.com/crypto",
-			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/openpgp/errors"
-		},
-		{
-			"importpath": "golang.org/x/crypto/openpgp/packet",
-			"repository": "https://go.googlesource.com/crypto",
-			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/openpgp/packet"
-		},
-		{
-			"importpath": "golang.org/x/crypto/openpgp/s2k",
-			"repository": "https://go.googlesource.com/crypto",
-			"revision": "5bcd134fee4dd1475da17714aac19c0aa0142e2f",
-			"branch": "master",
-			"path": "/openpgp/s2k"
+			"branch": "master"
 		},
 		{
 			"importpath": "gopkg.in/yaml.v2",
@@ -97,39 +26,10 @@
 			"branch": "v2"
 		},
 		{
-			"importpath": "pault.ag/go/debian/control",
-			"repository": "https://github.com/paultag/go-debian",
-			"revision": "e7a23c7df0f545cdb75afbcc6d296bb93ce2786f",
-			"branch": "master",
-			"path": "/control"
-		},
-		{
-			"importpath": "pault.ag/go/debian/dependency",
+			"importpath": "pault.ag/go/debian",
 			"repository": "https://github.com/paultag/go-debian",
 			"revision": "e7a23c7df0f545cdb75afbcc6d296bb93ce2786f",
-			"branch": "master",
-			"path": "/dependency"
-		},
-		{
-			"importpath": "pault.ag/go/debian/internal",
-			"repository": "https://github.com/paultag/go-debian",
-			"revision": "e7a23c7df0f545cdb75afbcc6d296bb93ce2786f",
-			"branch": "master",
-			"path": "/internal"
-		},
-		{
-			"importpath": "pault.ag/go/debian/transput",
-			"repository": "https://github.com/paultag/go-debian",
-			"revision": "e7a23c7df0f545cdb75afbcc6d296bb93ce2786f",
-			"branch": "master",
-			"path": "/transput"
-		},
-		{
-			"importpath": "pault.ag/go/debian/version",
-			"repository": "https://github.com/paultag/go-debian",
-			"revision": "e7a23c7df0f545cdb75afbcc6d296bb93ce2786f",
-			"branch": "master",
-			"path": "/version"
+			"branch": "master"
 		},
 		{
 			"importpath": "pault.ag/go/topsort",

+ 42 - 0
bashbrew/go/vendor/src/github.com/docker-library/go-dockerlibrary/pkg/execpipe/execpipe.go

@@ -0,0 +1,42 @@
+package execpipe
+
+import (
+	"io"
+	"os/exec"
+)
+
+// "io.ReadCloser" interface to a command's output where "Close()" is effectively "Wait()"
+type Pipe struct {
+	cmd *exec.Cmd
+	out io.ReadCloser
+}
+
+// convenience wrapper for "Run"
+func RunCommand(cmd string, args ...string) (*Pipe, error) {
+	return Run(exec.Command(cmd, args...))
+}
+
+// start "cmd", capturing stdout in a pipe (be sure to call "Close" when finished reading to reap the process)
+func Run(cmd *exec.Cmd) (*Pipe, error) {
+	pipe := &Pipe{
+		cmd: cmd,
+	}
+	if out, err := pipe.cmd.StdoutPipe(); err != nil {
+		return nil, err
+	} else {
+		pipe.out = out
+	}
+	if err := pipe.cmd.Start(); err != nil {
+		pipe.out.Close()
+		return nil, err
+	}
+	return pipe, nil
+}
+
+func (pipe *Pipe) Read(p []byte) (n int, err error) {
+	return pipe.out.Read(p)
+}
+
+func (pipe *Pipe) Close() error {
+	return pipe.cmd.Wait()
+}