Docker testing: handle licensing, different images per node (#20347)
This commit is contained in:
parent
d3722a33c8
commit
ad18fc6398
|
@ -213,6 +213,8 @@ jobs:
|
|||
- id: run-go-tests
|
||||
name: Run Go tests
|
||||
timeout-minutes: ${{ fromJSON(env.TIMEOUT_IN_MINUTES) }}
|
||||
env:
|
||||
COMMIT_SHA: ${{ github.sha }}
|
||||
run: |
|
||||
set -exo pipefail
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ const (
|
|||
GenerateRecovery
|
||||
)
|
||||
|
||||
const VAULT_LICENSE_CI_ENV = "VAULT_LICENSE_CI"
|
||||
|
||||
// GenerateRoot generates a root token on the target cluster.
|
||||
func GenerateRoot(t testing.T, cluster *vault.TestCluster, kind GenerateRootKind) string {
|
||||
t.Helper()
|
||||
|
|
|
@ -74,6 +74,7 @@ type DockerCluster struct {
|
|||
dockerAPI *docker.Client
|
||||
ID string
|
||||
Logger log.Logger
|
||||
builtTags map[string]struct{}
|
||||
}
|
||||
|
||||
func (dc *DockerCluster) NamedLogger(s string) log.Logger {
|
||||
|
@ -429,45 +430,12 @@ func NewDockerCluster(ctx context.Context, opts *DockerClusterOptions) (*DockerC
|
|||
opts.Logger = log.NewNullLogger()
|
||||
}
|
||||
|
||||
if opts.VaultBinary != "" {
|
||||
f, err := os.Open(opts.VaultBinary)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bCtx := dockhelper.NewBuildContext()
|
||||
bCtx["vault"] = &dockhelper.FileContents{
|
||||
Data: data,
|
||||
Mode: 0o755,
|
||||
}
|
||||
|
||||
containerFile := fmt.Sprintf(`
|
||||
FROM %s:%s
|
||||
COPY vault /bin/vault
|
||||
`, opts.ImageRepo, opts.ImageTag)
|
||||
|
||||
// TODO would be nice to use current SHA as tag
|
||||
newTag := opts.ImageTag + "-testing"
|
||||
_, err = dockhelper.BuildImage(ctx, api, containerFile, bCtx,
|
||||
dockhelper.BuildRemove(true), dockhelper.BuildForceRemove(true),
|
||||
dockhelper.BuildPullParent(true),
|
||||
dockhelper.BuildTags([]string{opts.ImageRepo + ":" + newTag}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newOpts := *opts
|
||||
newOpts.ImageTag = newTag
|
||||
opts = &newOpts
|
||||
}
|
||||
|
||||
dc := &DockerCluster{
|
||||
dockerAPI: api,
|
||||
RaftStorage: true,
|
||||
ClusterName: opts.ClusterName,
|
||||
Logger: opts.Logger,
|
||||
builtTags: map[string]struct{}{},
|
||||
}
|
||||
|
||||
if err := dc.setupDockerCluster(ctx, opts); err != nil {
|
||||
|
@ -501,6 +469,8 @@ type DockerClusterNode struct {
|
|||
RealAPIAddr string
|
||||
ContainerNetworkName string
|
||||
ContainerIPAddress string
|
||||
ImageRepo string
|
||||
ImageTag string
|
||||
}
|
||||
|
||||
func (n *DockerClusterNode) TLSConfig() *tls.Config {
|
||||
|
@ -661,15 +631,6 @@ func (n *DockerClusterNode) start(ctx context.Context, caDir string, opts *Docke
|
|||
caDir: "/usr/local/share/ca-certificates/",
|
||||
}
|
||||
|
||||
repo := opts.ImageRepo
|
||||
if repo == "" {
|
||||
repo = "vault"
|
||||
}
|
||||
tag := opts.ImageTag
|
||||
if tag == "" {
|
||||
tag = "latest"
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
var seenLogs uberAtomic.Bool
|
||||
|
@ -687,8 +648,8 @@ func (n *DockerClusterNode) start(ctx context.Context, caDir string, opts *Docke
|
|||
testcluster.JSONLogNoTimestamp(n.Logger, s)
|
||||
}}
|
||||
r, err := dockhelper.NewServiceRunner(dockhelper.RunOptions{
|
||||
ImageRepo: repo,
|
||||
ImageTag: tag,
|
||||
ImageRepo: n.ImageRepo,
|
||||
ImageTag: n.ImageTag,
|
||||
// We don't need to run update-ca-certificates in the container, because
|
||||
// we're providing the CA in the raft join call, and otherwise Vault
|
||||
// servers don't talk to one another on the API port.
|
||||
|
@ -698,6 +659,7 @@ func (n *DockerClusterNode) start(ctx context.Context, caDir string, opts *Docke
|
|||
// anyway, and because it prevents us using external plugins.
|
||||
"SKIP_SETCAP=true",
|
||||
"VAULT_LOG_FORMAT=json",
|
||||
"VAULT_LICENSE=" + opts.VaultLicense,
|
||||
},
|
||||
Ports: []string{"8200/tcp", "8201/tcp"},
|
||||
ContainerName: n.Name(),
|
||||
|
@ -893,6 +855,10 @@ func (dc *DockerCluster) AddNode(ctx context.Context, opts *DockerClusterOptions
|
|||
}
|
||||
|
||||
func (dc *DockerCluster) addNode(ctx context.Context, opts *DockerClusterOptions) error {
|
||||
tag, err := dc.setupImage(ctx, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i := len(dc.ClusterNodes)
|
||||
nodeID := fmt.Sprintf("core-%d", i)
|
||||
node := &DockerClusterNode{
|
||||
|
@ -901,6 +867,8 @@ func (dc *DockerCluster) addNode(ctx context.Context, opts *DockerClusterOptions
|
|||
Cluster: dc,
|
||||
WorkDir: filepath.Join(dc.tmpDir, nodeID),
|
||||
Logger: dc.Logger.Named(nodeID),
|
||||
ImageRepo: opts.ImageRepo,
|
||||
ImageTag: tag,
|
||||
}
|
||||
dc.ClusterNodes = append(dc.ClusterNodes, node)
|
||||
if err := os.MkdirAll(node.WorkDir, 0o755); err != nil {
|
||||
|
@ -947,6 +915,58 @@ func (dc *DockerCluster) joinNode(ctx context.Context, nodeIdx int, leaderIdx in
|
|||
return testcluster.UnsealNode(ctx, dc, nodeIdx)
|
||||
}
|
||||
|
||||
func (dc *DockerCluster) setupImage(ctx context.Context, opts *DockerClusterOptions) (string, error) {
|
||||
if opts == nil {
|
||||
opts = &DockerClusterOptions{}
|
||||
}
|
||||
sourceTag := opts.ImageTag
|
||||
if sourceTag == "" {
|
||||
sourceTag = "latest"
|
||||
}
|
||||
|
||||
if opts.VaultBinary == "" {
|
||||
return sourceTag, nil
|
||||
}
|
||||
|
||||
suffix := "testing"
|
||||
if sha := os.Getenv("COMMIT_SHA"); sha != "" {
|
||||
suffix = sha
|
||||
}
|
||||
tag := sourceTag + "-" + suffix
|
||||
if _, ok := dc.builtTags[tag]; ok {
|
||||
return tag, nil
|
||||
}
|
||||
|
||||
f, err := os.Open(opts.VaultBinary)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
bCtx := dockhelper.NewBuildContext()
|
||||
bCtx["vault"] = &dockhelper.FileContents{
|
||||
Data: data,
|
||||
Mode: 0o755,
|
||||
}
|
||||
|
||||
containerFile := fmt.Sprintf(`
|
||||
FROM %s:%s
|
||||
COPY vault /bin/vault
|
||||
`, opts.ImageRepo, sourceTag)
|
||||
|
||||
_, err = dockhelper.BuildImage(ctx, dc.dockerAPI, containerFile, bCtx,
|
||||
dockhelper.BuildRemove(true), dockhelper.BuildForceRemove(true),
|
||||
dockhelper.BuildPullParent(true),
|
||||
dockhelper.BuildTags([]string{opts.ImageRepo + ":" + tag}))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
dc.builtTags[tag] = struct{}{}
|
||||
return tag, nil
|
||||
}
|
||||
|
||||
/* Notes on testing the non-bridge network case:
|
||||
- you need the test itself to be running in a container so that it can use
|
||||
the network; create the network using
|
||||
|
|
|
@ -60,7 +60,7 @@ func NewTestExecDevCluster(t *testing.T, opts *ExecDevClusterOptions) *ExecDevCl
|
|||
opts.Logger = logging.NewVaultLogger(log.Trace).Named(t.Name()) // .Named("container")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
dc, err := NewExecDevCluster(ctx, opts)
|
||||
|
@ -146,6 +146,7 @@ func (dc *ExecDevCluster) setupExecDevCluster(ctx context.Context, opts *ExecDev
|
|||
}
|
||||
cmd := exec.CommandContext(execCtx, bin, args...)
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, "VAULT_LICENSE="+opts.VaultLicense)
|
||||
cmd.Env = append(cmd.Env, "VAULT_LOG_FORMAT=json")
|
||||
cmd.Env = append(cmd.Env, "VAULT_DEV_TEMP_DIR="+dc.tmpDir)
|
||||
if opts.Logger != nil {
|
||||
|
|
|
@ -94,4 +94,5 @@ type ClusterOptions struct {
|
|||
TmpDir string
|
||||
Logger hclog.Logger
|
||||
VaultNodeConfig *VaultNodeConfig
|
||||
VaultLicense string
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/helper/testhelpers"
|
||||
vaulthttp "github.com/hashicorp/vault/http"
|
||||
"github.com/hashicorp/vault/internalshared/configutil"
|
||||
"github.com/hashicorp/vault/sdk/helper/testcluster"
|
||||
|
@ -50,7 +51,8 @@ func TestSysPprof_Exec(t *testing.T) {
|
|||
}
|
||||
cluster := testcluster.NewTestExecDevCluster(t, &testcluster.ExecDevClusterOptions{
|
||||
ClusterOptions: testcluster.ClusterOptions{
|
||||
NumCores: 1,
|
||||
NumCores: 1,
|
||||
VaultLicense: os.Getenv(testhelpers.VAULT_LICENSE_CI_ENV),
|
||||
},
|
||||
BinaryPath: binary,
|
||||
BaseListenAddress: "127.0.0.1:8208",
|
||||
|
@ -246,6 +248,7 @@ func TestSysPprof_Standby_Exec(t *testing.T) {
|
|||
VaultNodeConfig: &testcluster.VaultNodeConfig{
|
||||
DisablePerformanceStandby: true,
|
||||
},
|
||||
VaultLicense: os.Getenv(testhelpers.VAULT_LICENSE_CI_ENV),
|
||||
},
|
||||
BinaryPath: binary,
|
||||
BaseListenAddress: "127.0.0.1:8210",
|
||||
|
|
|
@ -468,6 +468,7 @@ func TestRaft_Configuration_Docker(t *testing.T) {
|
|||
// "performance_multiplier": "1",
|
||||
//},
|
||||
},
|
||||
VaultLicense: os.Getenv(testhelpers.VAULT_LICENSE_CI_ENV),
|
||||
},
|
||||
}
|
||||
cluster := docker.NewTestDockerCluster(t, opts)
|
||||
|
|
Loading…
Reference in New Issue