Merge "Extend container interface with mounts get log opts"
This commit is contained in:
commit
8b19ced1b8
@ -123,7 +123,7 @@ func (options *BootstrapContainerOptions) GetContainerStatus() (container.Status
|
||||
var exitCode int
|
||||
exitCode = state.ExitCode
|
||||
if exitCode > 0 {
|
||||
reader, err := options.Container.GetContainerLogs()
|
||||
reader, err := options.Container.GetContainerLogs(container.GetLogOptions{Stderr: true, Follow: true})
|
||||
if err != nil {
|
||||
log.Printf("Error while trying to retrieve the container logs")
|
||||
return BootNullString, err
|
||||
@ -197,7 +197,7 @@ func (options *BootstrapContainerOptions) CreateBootstrapContainer() error {
|
||||
fmt.Sprintf("%s=%s", envBootstrapVolume, containerVolMount),
|
||||
}
|
||||
|
||||
err := options.Container.RunCommand(container.RunCommandOptions{EnvVars: envVars, VolumeMounts: vols})
|
||||
err := options.Container.RunCommand(container.RunCommandOptions{EnvVars: envVars, Binds: vols})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ func (opts BootstrapIsoOptions) CreateBootstrapIso() error {
|
||||
fmt.Sprintf("NO_PROXY=%s", os.Getenv("NO_PROXY")),
|
||||
}
|
||||
|
||||
err = opts.Builder.RunCommand(container.RunCommandOptions{EnvVars: envVars, VolumeMounts: vols})
|
||||
err = opts.Builder.RunCommand(container.RunCommandOptions{EnvVars: envVars, Binds: vols})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -143,7 +143,7 @@ func (opts BootstrapIsoOptions) CreateBootstrapIso() error {
|
||||
|
||||
if log.DebugEnabled() {
|
||||
var cLogs io.ReadCloser
|
||||
cLogs, err = opts.Builder.GetContainerLogs()
|
||||
cLogs, err = opts.Builder.GetContainerLogs(container.GetLogOptions{Stderr: true, Follow: true})
|
||||
if err != nil {
|
||||
log.Printf("failed to read container logs %s", err)
|
||||
} else {
|
||||
|
@ -19,6 +19,11 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
// ContainerDriverDocker indicates that docker driver should be used in container constructor
|
||||
ContainerDriverDocker = "docker"
|
||||
)
|
||||
|
||||
// Status type provides container status
|
||||
type Status string
|
||||
|
||||
@ -36,7 +41,7 @@ type State struct {
|
||||
type Container interface {
|
||||
ImagePull() error
|
||||
RunCommand(RunCommandOptions) error
|
||||
GetContainerLogs() (io.ReadCloser, error)
|
||||
GetContainerLogs(GetLogOptions) (io.ReadCloser, error)
|
||||
InspectContainer() (State, error)
|
||||
WaitUntilFinished() error
|
||||
RmContainer() error
|
||||
@ -45,13 +50,31 @@ type Container interface {
|
||||
|
||||
// RunCommandOptions options for RunCommand
|
||||
type RunCommandOptions struct {
|
||||
Privileged bool
|
||||
Privileged bool
|
||||
HostNewtork bool
|
||||
|
||||
Cmd []string
|
||||
EnvVars []string
|
||||
VolumeMounts []string
|
||||
Cmd []string
|
||||
EnvVars []string
|
||||
Binds []string
|
||||
|
||||
Input io.Reader
|
||||
Mounts []Mount
|
||||
Input io.Reader
|
||||
}
|
||||
|
||||
// Mount describes mount settings
|
||||
type Mount struct {
|
||||
ReadOnly bool
|
||||
Type string
|
||||
Dst string
|
||||
Src string
|
||||
}
|
||||
|
||||
// GetLogOptions options for getting logs
|
||||
// If both Stderr and Stdout are specified the logs will contain both stderr and stdout
|
||||
type GetLogOptions struct {
|
||||
Stderr bool
|
||||
Stdout bool
|
||||
Follow bool
|
||||
}
|
||||
|
||||
// NewContainer returns instance of Container interface implemented by particular driver
|
||||
@ -63,7 +86,7 @@ func NewContainer(ctx context.Context, driver string, url string) (Container, er
|
||||
switch driver {
|
||||
case "":
|
||||
return nil, ErrNoContainerDriver{}
|
||||
case "docker":
|
||||
case ContainerDriverDocker:
|
||||
cli, err := NewDockerClient(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/client"
|
||||
|
||||
@ -174,18 +175,36 @@ func (c *DockerContainer) getConfig(opts RunCommandOptions) (container.Config, c
|
||||
if err != nil {
|
||||
return container.Config{}, container.HostConfig{}, err
|
||||
}
|
||||
|
||||
mounts := []mount.Mount{}
|
||||
for _, mnt := range opts.Mounts {
|
||||
mounts = append(mounts, mount.Mount{
|
||||
Type: mount.Type(mnt.Type),
|
||||
Source: mnt.Src,
|
||||
Target: mnt.Dst,
|
||||
ReadOnly: mnt.ReadOnly,
|
||||
})
|
||||
}
|
||||
|
||||
cCfg := container.Config{
|
||||
Image: c.imageURL,
|
||||
Cmd: cmd,
|
||||
AttachStdin: true,
|
||||
OpenStdin: true,
|
||||
Env: opts.EnvVars,
|
||||
Tty: true,
|
||||
Image: c.imageURL,
|
||||
Cmd: cmd,
|
||||
|
||||
AttachStdin: true,
|
||||
StdinOnce: true,
|
||||
OpenStdin: true,
|
||||
AttachStderr: true,
|
||||
AttachStdout: true,
|
||||
Env: opts.EnvVars,
|
||||
}
|
||||
hCfg := container.HostConfig{
|
||||
Binds: opts.VolumeMounts,
|
||||
Binds: opts.Binds,
|
||||
Mounts: mounts,
|
||||
Privileged: opts.Privileged,
|
||||
}
|
||||
if opts.HostNewtork {
|
||||
hCfg.NetworkMode = "host"
|
||||
}
|
||||
return cCfg, hCfg, nil
|
||||
}
|
||||
|
||||
@ -268,6 +287,8 @@ func (c *DockerContainer) RunCommand(opts RunCommandOptions) (err error) {
|
||||
if attachErr != nil {
|
||||
return attachErr
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
if _, err = io.Copy(conn.Conn, opts.Input); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -282,8 +303,12 @@ func (c *DockerContainer) RunCommand(opts RunCommandOptions) (err error) {
|
||||
}
|
||||
|
||||
// GetContainerLogs returns logs from the container as io.ReadCloser
|
||||
func (c *DockerContainer) GetContainerLogs() (io.ReadCloser, error) {
|
||||
return c.dockerClient.ContainerLogs(c.ctx, c.id, types.ContainerLogsOptions{ShowStdout: true, Follow: true})
|
||||
func (c *DockerContainer) GetContainerLogs(opts GetLogOptions) (io.ReadCloser, error) {
|
||||
return c.dockerClient.ContainerLogs(c.ctx, c.id, types.ContainerLogsOptions{
|
||||
ShowStderr: opts.Stderr,
|
||||
Follow: opts.Follow,
|
||||
ShowStdout: opts.Stdout,
|
||||
})
|
||||
}
|
||||
|
||||
// RmContainer kills and removes a container from the docker host.
|
||||
|
@ -286,6 +286,7 @@ func TestRunCommand(t *testing.T) {
|
||||
cmd []string
|
||||
containerInput io.Reader
|
||||
volumeMounts []string
|
||||
mounts []Mount
|
||||
debug bool
|
||||
mockDockerClient mockDockerClient
|
||||
expectedRunErr error
|
||||
@ -329,7 +330,15 @@ func TestRunCommand(t *testing.T) {
|
||||
return conn, nil
|
||||
},
|
||||
},
|
||||
expectedRunErr: nil,
|
||||
expectedRunErr: nil,
|
||||
mounts: []Mount{
|
||||
{
|
||||
ReadOnly: true,
|
||||
Type: "bind",
|
||||
Dst: "/dev/vda0",
|
||||
Src: "/dev/vd3",
|
||||
},
|
||||
},
|
||||
expectedWaitErr: nil,
|
||||
assertF: func(t *testing.T) {},
|
||||
},
|
||||
@ -422,9 +431,10 @@ func TestRunCommand(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
cnt := getDockerContainerMock(tt.mockDockerClient)
|
||||
actualErr := cnt.RunCommand(RunCommandOptions{
|
||||
Input: tt.containerInput,
|
||||
Cmd: tt.cmd,
|
||||
VolumeMounts: tt.volumeMounts,
|
||||
Input: tt.containerInput,
|
||||
Cmd: tt.cmd,
|
||||
Binds: tt.volumeMounts,
|
||||
Mounts: tt.mounts,
|
||||
})
|
||||
assert.Equal(t, tt.expectedRunErr, actualErr)
|
||||
actualErr = cnt.WaitUntilFinished()
|
||||
@ -468,12 +478,12 @@ func TestRunCommandOutput(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
cnt := getDockerContainerMock(tt.mockDockerClient)
|
||||
actualErr := cnt.RunCommand(RunCommandOptions{
|
||||
Input: tt.containerInput,
|
||||
Cmd: tt.cmd,
|
||||
VolumeMounts: tt.volumeMounts,
|
||||
Input: tt.containerInput,
|
||||
Cmd: tt.cmd,
|
||||
Binds: tt.volumeMounts,
|
||||
})
|
||||
assert.Equal(t, tt.expectedErr, actualErr)
|
||||
actualRes, actualErr := cnt.GetContainerLogs()
|
||||
actualRes, actualErr := cnt.GetContainerLogs(GetLogOptions{Stdout: true, Follow: true})
|
||||
require.NoError(t, actualErr)
|
||||
|
||||
var actualResBytes []byte
|
||||
|
@ -42,7 +42,7 @@ func (mc *MockContainer) RunCommand(container.RunCommandOptions) error {
|
||||
}
|
||||
|
||||
// GetContainerLogs Container interface implementation for unit test purposes
|
||||
func (mc *MockContainer) GetContainerLogs() (io.ReadCloser, error) {
|
||||
func (mc *MockContainer) GetContainerLogs(container.GetLogOptions) (io.ReadCloser, error) {
|
||||
return mc.MockGetContainerLogs()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user