Merge "Fix docker stdin write."
This commit is contained in:
commit
359c362861
6
go.mod
6
go.mod
@ -10,7 +10,7 @@ require (
|
||||
github.com/ahmetb/dlog v0.0.0-20170105205344-4fb5f8204f26
|
||||
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
|
||||
github.com/containerd/containerd v1.4.1 // indirect
|
||||
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce
|
||||
github.com/docker/docker v20.10.5+incompatible
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
|
||||
@ -26,8 +26,9 @@ require (
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
|
||||
github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
@ -35,6 +36,7 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
|
||||
gotest.tools/v3 v3.0.3 // indirect
|
||||
k8s.io/api v0.17.9
|
||||
k8s.io/apiextensions-apiserver v0.17.9
|
||||
k8s.io/apimachinery v0.17.9
|
||||
|
13
go.sum
13
go.sum
@ -131,6 +131,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@ -142,8 +144,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce h1:KXS1Jg+ddGcWA8e1N7cupxaHHZhit5rB9tfDU+mfjyY=
|
||||
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.5+incompatible h1:o5WL5onN4awYGwrW7+oTn5x9AF2prw7V0Ox8ZEkoCdg=
|
||||
github.com/docker/docker v20.10.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
@ -501,6 +503,8 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -827,6 +831,7 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -867,6 +872,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@ -957,6 +963,9 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@ -167,10 +167,19 @@ func (c *clientV1Alpha1) runAirship() error {
|
||||
c.conf.Spec.Airship.Cmd)
|
||||
|
||||
// write logs asynchronously while waiting for for container to finish
|
||||
go writeLogs(cont)
|
||||
cErr := make(chan error, 1)
|
||||
go func() {
|
||||
cErr <- writeLogs(cont)
|
||||
}()
|
||||
|
||||
err = cont.WaitUntilFinished()
|
||||
if err != nil {
|
||||
<-cErr
|
||||
return err
|
||||
}
|
||||
|
||||
// check writeLogs error after container is done waiting
|
||||
if err = <-cErr; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -224,20 +233,17 @@ func (c *clientV1Alpha1) runKRM() error {
|
||||
return fns.Execute()
|
||||
}
|
||||
|
||||
func writeLogs(cont Container) {
|
||||
func writeLogs(cont Container) error {
|
||||
stderr, err := cont.GetContainerLogs(GetLogOptions{
|
||||
Stderr: true,
|
||||
Follow: true})
|
||||
if err != nil {
|
||||
log.Fatalf("received an error trying to attach to container to retrieve logs %e", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer stderr.Close()
|
||||
parsedStdErr := dlog.NewReader(stderr)
|
||||
_, err = io.Copy(log.Writer(), parsedStdErr)
|
||||
if err != nil {
|
||||
log.Fatalf("received an error while copying logs from container %e", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// writeSink output to directory on filesystem sink
|
||||
|
@ -17,6 +17,7 @@ package container
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
@ -135,6 +136,52 @@ func TestGenericContainer(t *testing.T) {
|
||||
}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error airship container writeLogs",
|
||||
expectedErr: "container logs error",
|
||||
containerAPI: &v1alpha1.GenericContainer{
|
||||
Spec: v1alpha1.GenericContainerSpec{
|
||||
Type: v1alpha1.GenericContainerTypeAirship,
|
||||
Image: "some image",
|
||||
StorageMounts: []v1alpha1.StorageMount{
|
||||
{
|
||||
MountType: "bind",
|
||||
Src: "test",
|
||||
DstPath: "/mount",
|
||||
},
|
||||
{
|
||||
MountType: "bind",
|
||||
Src: "~/test",
|
||||
DstPath: "/mnt",
|
||||
},
|
||||
},
|
||||
},
|
||||
Config: `kind: ConfigMap`,
|
||||
},
|
||||
execFunc: func(ctx context.Context, driver, url string) (Container, error) {
|
||||
return getDockerContainerMock(mockDockerClient{
|
||||
containerAttach: func() (types.HijackedResponse, error) {
|
||||
conn := types.HijackedResponse{
|
||||
Conn: mockConn{WData: make([]byte, len([]byte("foo: bar")))},
|
||||
}
|
||||
return conn, nil
|
||||
},
|
||||
imageList: func() ([]types.ImageSummary, error) {
|
||||
return []types.ImageSummary{{ID: "imgid"}}, nil
|
||||
},
|
||||
imageInspectWithRaw: func() (types.ImageInspect, []byte, error) {
|
||||
return types.ImageInspect{
|
||||
Config: &container.Config{
|
||||
Cmd: []string{"testCmd"},
|
||||
},
|
||||
}, nil, nil
|
||||
},
|
||||
containerLogs: func() (io.ReadCloser, error) {
|
||||
return nil, fmt.Errorf("container logs error")
|
||||
},
|
||||
}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "basic success airship container",
|
||||
containerAPI: &v1alpha1.GenericContainer{
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/client"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
)
|
||||
@ -57,6 +58,7 @@ type DockerClient interface {
|
||||
*container.Config,
|
||||
*container.HostConfig,
|
||||
*network.NetworkingConfig,
|
||||
*specs.Platform,
|
||||
string,
|
||||
) (container.ContainerCreateCreatedBody, error)
|
||||
// ContainerAttach attaches a connection to a container in the server.
|
||||
@ -271,6 +273,7 @@ func (c *DockerContainer) RunCommand(opts RunCommandOptions) (err error) {
|
||||
&containerConfig,
|
||||
&hostConfig,
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
@ -284,14 +287,28 @@ func (c *DockerContainer) RunCommand(opts RunCommandOptions) (err error) {
|
||||
Stream: true,
|
||||
Stdin: true,
|
||||
})
|
||||
|
||||
if attachErr != nil {
|
||||
return attachErr
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
if _, err = io.Copy(conn.Conn, opts.Input); err != nil {
|
||||
// This code is smiplified version of docker cli code
|
||||
cErr := make(chan error, 1)
|
||||
|
||||
// Write to stdin asynchronously
|
||||
go func() {
|
||||
_, copyErr := io.Copy(conn.Conn, opts.Input)
|
||||
cErr <- copyErr
|
||||
}()
|
||||
|
||||
if err = c.dockerClient.ContainerStart(c.ctx, c.id, types.ContainerStartOptions{}); err != nil {
|
||||
<-cErr
|
||||
return err
|
||||
}
|
||||
// lock until error is returned from the write channel
|
||||
return <-cErr
|
||||
}
|
||||
|
||||
if err = c.dockerClient.ContainerStart(c.ctx, c.id, types.ContainerStartOptions{}); err != nil {
|
||||
|
@ -15,6 +15,7 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -30,6 +31,7 @@ import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
type mockConn struct {
|
||||
@ -77,6 +79,7 @@ func (mdc *mockDockerClient) ContainerCreate(
|
||||
*container.Config,
|
||||
*container.HostConfig,
|
||||
*network.NetworkingConfig,
|
||||
*specs.Platform,
|
||||
string,
|
||||
) (container.ContainerCreateCreatedBody, error) {
|
||||
return container.ContainerCreateCreatedBody{ID: "testID"}, nil
|
||||
@ -370,6 +373,34 @@ func TestRunCommand(t *testing.T) {
|
||||
expectedWaitErr: nil,
|
||||
assertF: func(t *testing.T) {},
|
||||
},
|
||||
{
|
||||
// pass empty buffer to make sure we cover error when input isn't nil
|
||||
containerInput: bytes.NewBuffer([]byte{}),
|
||||
volumeMounts: nil,
|
||||
debug: false,
|
||||
mockDockerClient: mockDockerClient{
|
||||
containerStart: func() error {
|
||||
return containerStartError
|
||||
},
|
||||
imageList: func() ([]types.ImageSummary, error) {
|
||||
return []types.ImageSummary{{ID: "imgid"}}, nil
|
||||
},
|
||||
imageInspectWithRaw: func() (types.ImageInspect, []byte, error) {
|
||||
return types.ImageInspect{
|
||||
Config: &container.Config{},
|
||||
}, nil, nil
|
||||
},
|
||||
containerAttach: func() (types.HijackedResponse, error) {
|
||||
conn := types.HijackedResponse{
|
||||
Conn: mockConn{WData: make([]byte, len([]byte("testInput")))},
|
||||
}
|
||||
return conn, nil
|
||||
},
|
||||
},
|
||||
expectedRunErr: containerStartError,
|
||||
expectedWaitErr: nil,
|
||||
assertF: func(t *testing.T) {},
|
||||
},
|
||||
{
|
||||
cmd: []string{"testCmd"},
|
||||
containerInput: nil,
|
||||
|
Loading…
Reference in New Issue
Block a user