зеркало из https://github.com/microsoft/docker.git
Remove RunCommandPipelineWithOutput
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Родитель
9db68f4dea
Коммит
e885af2a6b
|
@ -229,3 +229,11 @@ func WithStdout(writer io.Writer) func(*icmd.Cmd) func() {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithStdin sets the standard input reader for the command
|
||||
func WithStdin(stdin io.Reader) func(*icmd.Cmd) func() {
|
||||
return func(cmd *icmd.Cmd) func() {
|
||||
cmd.Stdin = stdin
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,18 +14,20 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/request"
|
||||
"github.com/docker/docker/opts"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/testutil"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/go-check/check"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type testingT interface {
|
||||
|
@ -570,20 +572,13 @@ func (d *Daemon) WaitRun(contID string) error {
|
|||
return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...)
|
||||
}
|
||||
|
||||
// GetBaseDeviceSize returns the base device size of the daemon
|
||||
func (d *Daemon) GetBaseDeviceSize(c *check.C) int64 {
|
||||
infoCmdOutput, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
exec.Command(d.dockerBinary, "-H", d.Sock(), "info"),
|
||||
exec.Command("grep", "Base Device Size"),
|
||||
)
|
||||
c.Assert(err, checker.IsNil)
|
||||
basesizeSlice := strings.Split(infoCmdOutput, ":")
|
||||
basesize := strings.Trim(basesizeSlice[1], " ")
|
||||
basesize = strings.Trim(basesize, "\n")[:len(basesize)-3]
|
||||
basesizeFloat, err := strconv.ParseFloat(strings.Trim(basesize, " "), 64)
|
||||
c.Assert(err, checker.IsNil)
|
||||
basesizeBytes := int64(basesizeFloat) * (1024 * 1024 * 1024)
|
||||
return basesizeBytes
|
||||
// Info returns the info struct for this daemon
|
||||
func (d *Daemon) Info(t require.TestingT) types.Info {
|
||||
apiclient, err := request.NewClientForHost(d.Sock())
|
||||
require.NoError(t, err)
|
||||
info, err := apiclient.Info(context.Background())
|
||||
require.NoError(t, err)
|
||||
return info
|
||||
}
|
||||
|
||||
// Cmd executes a docker CLI command against this daemon.
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/pkg/testutil"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
@ -548,7 +547,7 @@ func (s *DockerSuite) TestCpToStdout(c *check.C) {
|
|||
// failed to set up container
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, "0")
|
||||
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "cp", containerID+":/test", "-"),
|
||||
exec.Command("tar", "-vtf", "-"))
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithInvalidBasesize(c *check.C) {
|
|||
testRequires(c, Devicemapper)
|
||||
s.d.Start(c)
|
||||
|
||||
oldBasesizeBytes := s.d.GetBaseDeviceSize(c)
|
||||
oldBasesizeBytes := getBaseDeviceSize(c, s.d)
|
||||
var newBasesizeBytes int64 = 1073741824 //1GB in bytes
|
||||
|
||||
if newBasesizeBytes < oldBasesizeBytes {
|
||||
|
@ -221,7 +221,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithIncreasedBasesize(c *check.C) {
|
|||
testRequires(c, Devicemapper)
|
||||
s.d.Start(c)
|
||||
|
||||
oldBasesizeBytes := s.d.GetBaseDeviceSize(c)
|
||||
oldBasesizeBytes := getBaseDeviceSize(c, s.d)
|
||||
|
||||
var newBasesizeBytes int64 = 53687091200 //50GB in bytes
|
||||
|
||||
|
@ -232,13 +232,31 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithIncreasedBasesize(c *check.C) {
|
|||
err := s.d.RestartWithError("--storage-opt", fmt.Sprintf("dm.basesize=%d", newBasesizeBytes))
|
||||
c.Assert(err, check.IsNil, check.Commentf("we should have been able to start the daemon with increased base device size: %v", err))
|
||||
|
||||
basesizeAfterRestart := s.d.GetBaseDeviceSize(c)
|
||||
basesizeAfterRestart := getBaseDeviceSize(c, s.d)
|
||||
newBasesize, err := convertBasesize(newBasesizeBytes)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Error in converting base device size: %v", err))
|
||||
c.Assert(newBasesize, check.Equals, basesizeAfterRestart, check.Commentf("Basesize passed is not equal to Basesize set"))
|
||||
s.d.Stop(c)
|
||||
}
|
||||
|
||||
func getBaseDeviceSize(c *check.C, d *daemon.Daemon) int64 {
|
||||
info := d.Info(c)
|
||||
for _, statusLine := range info.DriverStatus {
|
||||
key, value := statusLine[0], statusLine[1]
|
||||
if key == "Base Device Size" {
|
||||
return parseDeviceSize(c, value)
|
||||
}
|
||||
}
|
||||
c.Fatal("failed to parse Base Device Size from info")
|
||||
return int64(0)
|
||||
}
|
||||
|
||||
func parseDeviceSize(c *check.C, raw string) int64 {
|
||||
size, err := units.RAMInBytes(strings.TrimSpace(raw))
|
||||
c.Assert(err, check.IsNil)
|
||||
return size
|
||||
}
|
||||
|
||||
func convertBasesize(basesizeBytes int64) (int64, error) {
|
||||
basesize := units.HumanSize(float64(basesizeBytes))
|
||||
basesize = strings.Trim(basesize, " ")[:len(basesize)-3]
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/docker/docker/integration-cli/cli"
|
||||
"github.com/docker/docker/integration-cli/cli/build"
|
||||
"github.com/docker/docker/integration-cli/request"
|
||||
"github.com/docker/docker/pkg/testutil"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
@ -230,7 +229,7 @@ func (s *DockerSuite) TestEventsImageImport(c *check.C) {
|
|||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
since := daemonUnixTime(c)
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "export", cleanedContainerID),
|
||||
exec.Command(dockerBinary, "import", "-"),
|
||||
)
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli"
|
||||
"github.com/docker/docker/pkg/testutil"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
@ -21,7 +20,7 @@ func (s *DockerSuite) TestImportDisplay(c *check.C) {
|
|||
out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
|
||||
cleanedContainerID := strings.TrimSpace(out)
|
||||
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "export", cleanedContainerID),
|
||||
exec.Command(dockerBinary, "import", "-"),
|
||||
)
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli/build"
|
||||
"github.com/docker/docker/pkg/testutil"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/go-check/check"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
|
@ -34,7 +33,7 @@ func (s *DockerSuite) TestSaveXzAndLoadRepoStdout(c *check.C) {
|
|||
|
||||
dockerCmd(c, "inspect", repoName)
|
||||
|
||||
repoTarball, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
repoTarball, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command("xz", "-c"),
|
||||
exec.Command("gzip", "-c"))
|
||||
|
@ -63,7 +62,7 @@ func (s *DockerSuite) TestSaveXzGzAndLoadRepoStdout(c *check.C) {
|
|||
|
||||
dockerCmd(c, "inspect", repoName)
|
||||
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command("xz", "-c"),
|
||||
exec.Command("gzip", "-c"))
|
||||
|
@ -90,7 +89,7 @@ func (s *DockerSuite) TestSaveSingleTag(c *check.C) {
|
|||
out, _ := dockerCmd(c, "images", "-q", "--no-trunc", repoName)
|
||||
cleanedImageID := strings.TrimSpace(out)
|
||||
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", fmt.Sprintf("%v:latest", repoName)),
|
||||
exec.Command("tar", "t"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("(^repositories$|%v)", cleanedImageID)))
|
||||
|
@ -109,7 +108,7 @@ func (s *DockerSuite) TestSaveCheckTimes(c *check.C) {
|
|||
c.Assert(err, checker.IsNil, check.Commentf("failed to marshal from %q: err %v", repoName, err))
|
||||
c.Assert(len(data), checker.Not(checker.Equals), 0, check.Commentf("failed to marshal the data from %q", repoName))
|
||||
tarTvTimeFormat := "2006-01-02 15:04"
|
||||
out, _, err = testutil.RunCommandPipelineWithOutput(
|
||||
out, err = RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command("tar", "tv"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("%s %s", data[0].Created.Format(tarTvTimeFormat), digest.Digest(data[0].ID).Hex())))
|
||||
|
@ -167,7 +166,7 @@ func (s *DockerSuite) TestSaveAndLoadRepoFlags(c *check.C) {
|
|||
|
||||
before, _ := dockerCmd(c, "inspect", repoName)
|
||||
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName),
|
||||
exec.Command(dockerBinary, "load"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
|
||||
|
@ -196,7 +195,7 @@ func (s *DockerSuite) TestSaveMultipleNames(c *check.C) {
|
|||
// Make two images
|
||||
dockerCmd(c, "tag", "emptyfs:latest", fmt.Sprintf("%v-two:latest", repoName))
|
||||
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", fmt.Sprintf("%v-one", repoName), fmt.Sprintf("%v-two:latest", repoName)),
|
||||
exec.Command("tar", "xO", "repositories"),
|
||||
exec.Command("grep", "-q", "-E", "(-one|-two)"),
|
||||
|
@ -228,7 +227,7 @@ func (s *DockerSuite) TestSaveRepoWithMultipleImages(c *check.C) {
|
|||
deleteImages(repoName)
|
||||
|
||||
// create the archive
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", repoName, "busybox:latest"),
|
||||
exec.Command("tar", "t"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save multiple images: %s, %v", out, err))
|
||||
|
@ -272,7 +271,7 @@ func (s *DockerSuite) TestSaveDirectoryPermissions(c *check.C) {
|
|||
RUN adduser -D user && mkdir -p /opt/a/b && chown -R user:user /opt/a
|
||||
RUN touch /opt/a/b/c && chown user:user /opt/a/b/c`))
|
||||
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", name),
|
||||
exec.Command("tar", "-xf", "-", "-C", extractionDirectory),
|
||||
)
|
||||
|
@ -384,7 +383,7 @@ func (s *DockerSuite) TestSaveLoadNoTag(c *check.C) {
|
|||
id := inspectField(c, name, "Id")
|
||||
|
||||
// Test to make sure that save w/o name just shows imageID during load
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err := RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", id),
|
||||
exec.Command(dockerBinary, "load"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
|
||||
|
@ -395,7 +394,7 @@ func (s *DockerSuite) TestSaveLoadNoTag(c *check.C) {
|
|||
c.Assert(out, checker.Contains, id)
|
||||
|
||||
// Test to make sure that save by name shows that name during load
|
||||
out, _, err = testutil.RunCommandPipelineWithOutput(
|
||||
out, err = RunCommandPipelineWithOutput(
|
||||
exec.Command(dockerBinary, "save", name),
|
||||
exec.Command(dockerBinary, "load"))
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -23,7 +22,6 @@ import (
|
|||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/pkg/testutil"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/docker/docker/pkg/testutil/tempfile"
|
||||
"github.com/docker/libnetwork/driverapi"
|
||||
|
@ -467,14 +465,17 @@ func (s *DockerSwarmSuite) TestSwarmIngressNetwork(c *check.C) {
|
|||
d := s.AddDaemon(c, true, true)
|
||||
|
||||
// Ingress network can be removed
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
exec.Command("echo", "Y"),
|
||||
exec.Command("docker", "-H", d.Sock(), "network", "rm", "ingress"),
|
||||
)
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
removeNetwork := func(name string) *icmd.Result {
|
||||
return cli.Docker(
|
||||
cli.Args("-H", d.Sock(), "network", "rm", name),
|
||||
cli.WithStdin(strings.NewReader("Y")))
|
||||
}
|
||||
|
||||
result := removeNetwork("ingress")
|
||||
result.Assert(c, icmd.Success)
|
||||
|
||||
// And recreated
|
||||
out, err = d.Cmd("network", "create", "-d", "overlay", "--ingress", "new-ingress")
|
||||
out, err := d.Cmd("network", "create", "-d", "overlay", "--ingress", "new-ingress")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
// But only one is allowed
|
||||
|
@ -485,21 +486,19 @@ func (s *DockerSwarmSuite) TestSwarmIngressNetwork(c *check.C) {
|
|||
// It cannot be removed if it is being used
|
||||
out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "srv1", "-p", "9000:8000", "busybox", "top")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
out, _, err = testutil.RunCommandPipelineWithOutput(
|
||||
exec.Command("echo", "Y"),
|
||||
exec.Command("docker", "-H", d.Sock(), "network", "rm", "new-ingress"),
|
||||
)
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Contains, "ingress network cannot be removed because service")
|
||||
|
||||
result = removeNetwork("new-ingress")
|
||||
result.Assert(c, icmd.Expected{
|
||||
ExitCode: 1,
|
||||
Err: "ingress network cannot be removed because service",
|
||||
})
|
||||
|
||||
// But it can be removed once no more services depend on it
|
||||
out, err = d.Cmd("service", "update", "--publish-rm", "9000:8000", "srv1")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
out, _, err = testutil.RunCommandPipelineWithOutput(
|
||||
exec.Command("echo", "Y"),
|
||||
exec.Command("docker", "-H", d.Sock(), "network", "rm", "new-ingress"),
|
||||
)
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
||||
result = removeNetwork("new-ingress")
|
||||
result.Assert(c, icmd.Success)
|
||||
|
||||
// A service which needs the ingress network cannot be created if no ingress is present
|
||||
out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "srv2", "-p", "500:500", "busybox", "top")
|
||||
|
@ -520,15 +519,14 @@ func (s *DockerSwarmSuite) TestSwarmCreateServiceWithNoIngressNetwork(c *check.C
|
|||
d := s.AddDaemon(c, true, true)
|
||||
|
||||
// Remove ingress network
|
||||
out, _, err := testutil.RunCommandPipelineWithOutput(
|
||||
exec.Command("echo", "Y"),
|
||||
exec.Command("docker", "-H", d.Sock(), "network", "rm", "ingress"),
|
||||
)
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
result := cli.Docker(
|
||||
cli.Args("-H", d.Sock(), "network", "rm", "ingress"),
|
||||
cli.WithStdin(strings.NewReader("Y")))
|
||||
result.Assert(c, icmd.Success)
|
||||
|
||||
// Create a overlay network and launch a service on it
|
||||
// Make sure nothing panics because ingress network is missing
|
||||
out, err = d.Cmd("network", "create", "-d", "overlay", "another-network")
|
||||
out, err := d.Cmd("network", "create", "-d", "overlay", "another-network")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "srv4", "--network", "another-network", "busybox", "top")
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/docker/docker/pkg/testutil"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
|
@ -62,15 +61,15 @@ func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) {
|
|||
c.Assert(err, checker.IsNil, check.Commentf("Could not inspect running container: out: %q", pid))
|
||||
// check the uid and gid maps for the PID to ensure root is remapped
|
||||
// (cmd = cat /proc/<pid>/uid_map | grep -E '0\s+9999\s+1')
|
||||
out, rc1, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err = RunCommandPipelineWithOutput(
|
||||
exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/uid_map"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", uid)))
|
||||
c.Assert(rc1, checker.Equals, 0, check.Commentf("Didn't match uid_map: output: %s", out))
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
out, rc2, err := testutil.RunCommandPipelineWithOutput(
|
||||
out, err = RunCommandPipelineWithOutput(
|
||||
exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/gid_map"),
|
||||
exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", gid)))
|
||||
c.Assert(rc2, checker.Equals, 0, check.Commentf("Didn't match gid_map: output: %s", out))
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
// check that the touched file is owned by remapped uid:gid
|
||||
stat, err := system.Stat(filepath.Join(tmpDir, "testfile"))
|
||||
|
|
|
@ -165,7 +165,11 @@ func NewHTTPClient(host string) (*http.Client, error) {
|
|||
|
||||
// NewClient returns a new Docker API client
|
||||
func NewClient() (dclient.APIClient, error) {
|
||||
host := DaemonHost()
|
||||
return NewClientForHost(DaemonHost())
|
||||
}
|
||||
|
||||
// NewClientForHost returns a Docker API client for the host
|
||||
func NewClientForHost(host string) (dclient.APIClient, error) {
|
||||
httpClient, err := NewHTTPClient(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) {
|
||||
|
@ -64,3 +65,50 @@ func RandomTmpDirPath(s string, platform string) string {
|
|||
}
|
||||
return filepath.ToSlash(path) // Using /
|
||||
}
|
||||
|
||||
// RunCommandPipelineWithOutput runs the array of commands with the output
|
||||
// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
|
||||
// It returns the final output, the exitCode different from 0 and the error
|
||||
// if something bad happened.
|
||||
// Deprecated: use icmd instead
|
||||
func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, err error) {
|
||||
if len(cmds) < 2 {
|
||||
return "", errors.New("pipeline does not have multiple cmds")
|
||||
}
|
||||
|
||||
// connect stdin of each cmd to stdout pipe of previous cmd
|
||||
for i, cmd := range cmds {
|
||||
if i > 0 {
|
||||
prevCmd := cmds[i-1]
|
||||
cmd.Stdin, err = prevCmd.StdoutPipe()
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start all cmds except the last
|
||||
for _, cmd := range cmds[:len(cmds)-1] {
|
||||
if err = cmd.Start(); err != nil {
|
||||
return "", fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
|
||||
}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
var pipeErrMsgs []string
|
||||
// wait all cmds except the last to release their resources
|
||||
for _, cmd := range cmds[:len(cmds)-1] {
|
||||
if pipeErr := cmd.Wait(); pipeErr != nil {
|
||||
pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
|
||||
}
|
||||
}
|
||||
if len(pipeErrMsgs) > 0 && err == nil {
|
||||
err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
|
||||
}
|
||||
}()
|
||||
|
||||
// wait on last cmd
|
||||
out, err := cmds[len(cmds)-1].CombinedOutput()
|
||||
return string(out), err
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
package testutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/system"
|
||||
)
|
||||
|
||||
func runCommandWithOutput(cmd *exec.Cmd) (output string, exitCode int, err error) {
|
||||
out, err := cmd.CombinedOutput()
|
||||
exitCode = system.ProcessExitCode(err)
|
||||
output = string(out)
|
||||
return
|
||||
}
|
||||
|
||||
// RunCommandPipelineWithOutput runs the array of commands with the output
|
||||
// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
|
||||
// It returns the final output, the exitCode different from 0 and the error
|
||||
// if something bad happened.
|
||||
func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, exitCode int, err error) {
|
||||
if len(cmds) < 2 {
|
||||
return "", 0, errors.New("pipeline does not have multiple cmds")
|
||||
}
|
||||
|
||||
// connect stdin of each cmd to stdout pipe of previous cmd
|
||||
for i, cmd := range cmds {
|
||||
if i > 0 {
|
||||
prevCmd := cmds[i-1]
|
||||
cmd.Stdin, err = prevCmd.StdoutPipe()
|
||||
|
||||
if err != nil {
|
||||
return "", 0, fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start all cmds except the last
|
||||
for _, cmd := range cmds[:len(cmds)-1] {
|
||||
if err = cmd.Start(); err != nil {
|
||||
return "", 0, fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
|
||||
}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
var pipeErrMsgs []string
|
||||
// wait all cmds except the last to release their resources
|
||||
for _, cmd := range cmds[:len(cmds)-1] {
|
||||
if pipeErr := cmd.Wait(); pipeErr != nil {
|
||||
pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
|
||||
}
|
||||
}
|
||||
if len(pipeErrMsgs) > 0 && err == nil {
|
||||
err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
|
||||
}
|
||||
}()
|
||||
|
||||
// wait on last cmd
|
||||
return runCommandWithOutput(cmds[len(cmds)-1])
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
package testutil
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRunCommandPipelineWithOutputWithNotEnoughCmds(t *testing.T) {
|
||||
_, _, err := RunCommandPipelineWithOutput(exec.Command("ls"))
|
||||
expectedError := "pipeline does not have multiple cmds"
|
||||
if err == nil || err.Error() != expectedError {
|
||||
t.Fatalf("Expected an error with %s, got err:%s", expectedError, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunCommandPipelineWithOutputErrors(t *testing.T) {
|
||||
p := "$PATH"
|
||||
if runtime.GOOS == "windows" {
|
||||
p = "%PATH%"
|
||||
}
|
||||
cmd1 := exec.Command("ls")
|
||||
cmd1.Stdout = os.Stdout
|
||||
cmd2 := exec.Command("anything really")
|
||||
_, _, err := RunCommandPipelineWithOutput(cmd1, cmd2)
|
||||
if err == nil || err.Error() != "cannot set stdout pipe for anything really: exec: Stdout already set" {
|
||||
t.Fatalf("Expected an error, got %v", err)
|
||||
}
|
||||
|
||||
cmdWithError := exec.Command("doesnotexists")
|
||||
cmdCat := exec.Command("cat")
|
||||
_, _, err = RunCommandPipelineWithOutput(cmdWithError, cmdCat)
|
||||
if err == nil || err.Error() != `starting doesnotexists failed with error: exec: "doesnotexists": executable file not found in `+p {
|
||||
t.Fatalf("Expected an error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunCommandPipelineWithOutput(t *testing.T) {
|
||||
//TODO: Should run on Solaris
|
||||
if runtime.GOOS == "solaris" {
|
||||
t.Skip()
|
||||
}
|
||||
cmds := []*exec.Cmd{
|
||||
// Print 2 characters
|
||||
exec.Command("echo", "-n", "11"),
|
||||
// Count the number or char from stdin (previous command)
|
||||
exec.Command("wc", "-m"),
|
||||
}
|
||||
out, exitCode, err := RunCommandPipelineWithOutput(cmds...)
|
||||
expectedOutput := "2\n"
|
||||
if out != expectedOutput || exitCode != 0 || err != nil {
|
||||
t.Fatalf("Expected %s for commands %v, got out:%s, exitCode:%d, err:%v", expectedOutput, cmds, out, exitCode, err)
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче