vault/sdk/testing/stepwise/environments/docker/runner.go
Clint b3f0e9badf
Stepwise docker env (#9292)
* add first stepwise test env, Docker, with example transit test

* update transit stepwise test

* add other tests that use stepwise

* cleanup test, make names different than just 'transit'

* return the stderr if compile fails with error

* minor cleanups

* minor cleanups

* go mod vendor

* cleanups

* remove some extra code, and un-export some fields/methods

* update vendor

* remove reference to vault.CoreConfig, which really wasn't used anyway

* update with go mod vendor

* restore Precheck method to test cases

* clean up some networking things; create networks with UUID, clean up during teardown

* vendor stepwise

* Update sdk/testing/stepwise/environments/docker/environment.go

haha thanks :D

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>

* Update sdk/testing/stepwise/environments/docker/environment.go

Great catch, thanks

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>

* fix redundant name

* update error message in test

* Update builtin/credential/userpass/stepwise_test.go

More explicit error checking and responding

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>

* Update builtin/logical/aws/stepwise_test.go

`test` -> `testFunc`

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>

* Update builtin/logical/transit/stepwise_test.go

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>

* fix typos

* update error messages to provide clarity

* Update sdk/testing/stepwise/environments/docker/environment.go

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>

* update error handling / collection in Teardown

* panic if GenerateUUID returns an error

* Update sdk/testing/stepwise/environments/docker/environment.go

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>

* Update builtin/credential/userpass/stepwise_test.go

Co-authored-by: Calvin Leung Huang <cleung2010@gmail.com>

* Update builtin/logical/aws/stepwise_test.go

Co-authored-by: Calvin Leung Huang <cleung2010@gmail.com>

* Update builtin/logical/transit/stepwise_test.go

Co-authored-by: Calvin Leung Huang <cleung2010@gmail.com>

* Update sdk/testing/stepwise/environments/docker/environment.go

Co-authored-by: Calvin Leung Huang <cleung2010@gmail.com>

* import ordering

* standardize on dc from rc for cluster

* lowercase name

* CreateAPIClient -> NewAPIClient

* testWait -> ensure

* go mod cleanup

* cleanups

* move fields and method around

* make start and dockerclusternode private; use better random serial number

* use better random for SerialNumber

* add a timeout to the context used for terminating the docker container

* Use a constant for the Docker client version

* rearrange import statements

Co-authored-by: Michael Golowka <72365+pcman312@users.noreply.github.com>
Co-authored-by: Calvin Leung Huang <cleung2010@gmail.com>
2020-06-26 17:52:31 -05:00

114 lines
3.3 KiB
Go

package docker
import (
"context"
"fmt"
"io/ioutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/strslice"
docker "github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
)
// Runner manages the lifecycle of the Docker container
type Runner struct {
dockerAPI *docker.Client
ContainerConfig *container.Config
ContainerName string
NetName string
IP string
CopyFromTo map[string]string
}
// Start is responsible for executing the Vault container. It consists of
// pulling the specified Vault image, creating the container, and copies the
// plugin binary into the container file system before starting the container
// itself.
func (d *Runner) Start(ctx context.Context) (*types.ContainerJSON, error) {
hostConfig := &container.HostConfig{
PublishAllPorts: true,
AutoRemove: true,
}
networkingConfig := &network.NetworkingConfig{}
switch d.NetName {
case "":
case "host":
hostConfig.NetworkMode = "host"
default:
es := &network.EndpointSettings{
Aliases: []string{d.ContainerName},
}
if len(d.IP) != 0 {
es.IPAMConfig = &network.EndpointIPAMConfig{
IPv4Address: d.IP,
}
}
networkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{
d.NetName: es,
}
}
// Best-effort pull. ImageCreate here will use a matching image from the local
// Docker library, or if not found pull the matching image from docker hub. If
// not found on docker hub, returns an error. The response must be read in
// order for the local image.
resp, err := d.dockerAPI.ImageCreate(ctx, d.ContainerConfig.Image, types.ImageCreateOptions{})
if err != nil {
return nil, err
}
if resp != nil {
_, _ = ioutil.ReadAll(resp)
}
cfg := *d.ContainerConfig
hostConfig.CapAdd = strslice.StrSlice{"IPC_LOCK"}
cfg.Hostname = d.ContainerName
fullName := d.ContainerName
container, err := d.dockerAPI.ContainerCreate(ctx, &cfg, hostConfig, networkingConfig, fullName)
if err != nil {
return nil, fmt.Errorf("container create failed: %v", err)
}
// copies the plugin binary into the Docker file system. This copy is only
// allowed before the container is started
for from, to := range d.CopyFromTo {
srcInfo, err := archive.CopyInfoSourcePath(from, false)
if err != nil {
return nil, fmt.Errorf("error copying from source %q: %v", from, err)
}
srcArchive, err := archive.TarResource(srcInfo)
if err != nil {
return nil, fmt.Errorf("error creating tar from source %q: %v", from, err)
}
defer srcArchive.Close()
dstInfo := archive.CopyInfo{Path: to}
dstDir, content, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo)
if err != nil {
return nil, fmt.Errorf("error preparing copy from %q -> %q: %v", from, to, err)
}
defer content.Close()
err = d.dockerAPI.CopyToContainer(ctx, container.ID, dstDir, content, types.CopyToContainerOptions{})
if err != nil {
return nil, fmt.Errorf("error copying from %q -> %q: %v", from, to, err)
}
}
err = d.dockerAPI.ContainerStart(ctx, container.ID, types.ContainerStartOptions{})
if err != nil {
return nil, fmt.Errorf("container start failed: %v", err)
}
inspect, err := d.dockerAPI.ContainerInspect(ctx, container.ID)
if err != nil {
return nil, err
}
return &inspect, nil
}