diff --git a/testing/internal/e2e/infra/docker.go b/testing/internal/e2e/infra/docker.go index cd681dc9f..19ec22e14 100644 --- a/testing/internal/e2e/infra/docker.go +++ b/testing/internal/e2e/infra/docker.go @@ -28,11 +28,17 @@ type Container struct { // StartBoundaryDatabase spins up a postgres database in a docker container. // Returns information about the container -func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network) *Container { +func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag string) *Container { t.Log("Starting postgres database...") c, err := LoadConfig() require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: repository, + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + networkAlias := "e2epostgres" postgresDb := "e2eboundarydb" postgresUser := "e2eboundary" @@ -41,8 +47,8 @@ func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockert require.NoError(t, err) resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/library/postgres", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{"postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"}, Env: []string{ "POSTGRES_DB=" + postgresDb, @@ -77,7 +83,7 @@ func StartBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockert // InitBoundaryDatabase starts a boundary container (of the latest released version) and initializes a // postgres database (using `boundary database init`) at the specified postgres URI. // Returns information about the container -func InitBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, postgresURI string) *Container { +func InitBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, postgresURI string) *Container { t.Log("Initializing postgres database...") c, err := LoadConfig() require.NoError(t, err) @@ -85,9 +91,15 @@ func InitBoundaryDatabase(t testing.TB, pool *dockertest.Pool, network *dockerte boundaryConfigFilePath, err := filepath.Abs("testdata/boundary-config.hcl") require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: repository, + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/boundary", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{"boundary", "database", "init", "-config", "/boundary/boundary-config.hcl", "-format", "json"}, Env: []string{ "BOUNDARY_POSTGRES_URL=" + postgresURI, @@ -132,7 +144,7 @@ func GetDbInitInfoFromContainer(t testing.TB, pool *dockertest.Pool, container * // StartBoundary starts a boundary container and spins up an instance of boundary using the // specified database at postgresURI. // Returns information about the container. -func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, postgresURI string) *Container { +func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, postgresURI string) *Container { t.Log("Starting Boundary...") c, err := LoadConfig() require.NoError(t, err) @@ -140,12 +152,19 @@ func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Netw boundaryConfigFilePath, err := filepath.Abs("testdata/boundary-config.hcl") require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/boundary", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{"boundary", "server", "-config", "/boundary/boundary-config.hcl"}, Env: []string{ - "BOUNDARY_POSTGRES_URL=" + postgresURI, + fmt.Sprintf("BOUNDARY_LICENSE=%s", c.BoundaryLicense), + fmt.Sprintf("BOUNDARY_POSTGRES_URL=%s", postgresURI), "HOSTNAME=boundary", "SKIP_CHOWN=true", }, @@ -172,15 +191,21 @@ func StartBoundary(t testing.TB, pool *dockertest.Pool, network *dockertest.Netw // StartVault starts a vault container. // Returns information about the container. -func StartVault(t testing.TB, pool *dockertest.Pool, network *dockertest.Network) (*Container, string) { +func StartVault(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag string) (*Container, string) { t.Log("Starting Vault...") c, err := LoadConfig() require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + vaultToken := "boundarytok" resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/vault", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Env: []string{ "VAULT_DEV_ROOT_TOKEN_ID=" + vaultToken, }, @@ -207,14 +232,14 @@ func StartVault(t testing.TB, pool *dockertest.Pool, network *dockertest.Network // ConnectToTarget starts a boundary container and attempts to connect to the specified target. The // goal of this method is to create a session entry in the database. // Returns information about the container. -func ConnectToTarget(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, boundaryAddr string, token string, targetId string) *Container { +func ConnectToTarget(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, boundaryAddr, token, targetId string) *Container { t.Log("Connecting to target...") c, err := LoadConfig() require.NoError(t, err) resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/hashicorp/boundary", - Tag: "latest", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Cmd: []string{ "boundary", "connect", "-token", "env://E2E_AUTH_TOKEN", @@ -239,11 +264,17 @@ func ConnectToTarget(t testing.TB, pool *dockertest.Pool, network *dockertest.Ne // StartOpenSshServer starts an openssh container to serve as a target for Boundary. // Returns information about the container. -func StartOpenSshServer(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, user string, privateKeyFilePath string) *Container { +func StartOpenSshServer(t testing.TB, pool *dockertest.Pool, network *dockertest.Network, repository, tag, user, privateKeyFilePath string) *Container { t.Log("Starting openssh-server to serve as target...") c, err := LoadConfig() require.NoError(t, err) + err = pool.Client.PullImage(docker.PullImageOptions{ + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, + }, docker.AuthConfiguration{}) + require.NoError(t, err) + privateKeyRaw, err := os.ReadFile(privateKeyFilePath) require.NoError(t, err) signer, err := ssh.ParsePrivateKey(privateKeyRaw) @@ -251,7 +282,8 @@ func StartOpenSshServer(t testing.TB, pool *dockertest.Pool, network *dockertest networkAlias := "target" resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: c.DockerMirror + "/linuxserver/openssh-server", + Repository: fmt.Sprintf("%s/%s", c.DockerMirror, repository), + Tag: tag, Env: []string{ "PUID=1000", "PGID=1000", diff --git a/testing/internal/e2e/tests/database/migration_test.go b/testing/internal/e2e/tests/database/migration_test.go index 4664fffe7..a8fa071b5 100644 --- a/testing/internal/e2e/tests/database/migration_test.go +++ b/testing/internal/e2e/tests/database/migration_test.go @@ -45,8 +45,12 @@ func TestDatabaseMigration(t *testing.T) { require.NoError(t, err) ctx := context.Background() - te := setupEnvironment(t, ctx, c) - populateBoundaryDatabase(t, ctx, c, te) + + boundaryRepo := "hashicorp/boundary" + boundaryTag := "latest" + + te := setupEnvironment(t, ctx, c, boundaryRepo, boundaryTag) + populateBoundaryDatabase(t, ctx, c, te, boundaryRepo, boundaryTag) // Migrate database t.Log("Stopping boundary before migrating...") @@ -70,25 +74,13 @@ func TestDatabaseMigration(t *testing.T) { t.Logf("Migration Output: %s", output.Stderr) } -func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironment { +func setupEnvironment(t testing.TB, ctx context.Context, c *config, boundaryRepo, boundaryTag string) TestEnvironment { pool, err := dockertest.NewPool("") require.NoError(t, err) err = pool.Client.Ping() require.NoError(t, err) pool.MaxWait = 10 * time.Second - // This ensures that the latest images are used - err = pool.Client.PullImage(docker.PullImageOptions{ - Repository: "hashicorp/boundary", - Tag: "latest", - }, docker.AuthConfiguration{}) - require.NoError(t, err) - err = pool.Client.PullImage(docker.PullImageOptions{ - Repository: "hashicorp/vault", - Tag: "latest", - }, docker.AuthConfiguration{}) - require.NoError(t, err) - // Set up docker network network, err := pool.CreateNetwork(t.Name()) require.NoError(t, err) @@ -97,7 +89,7 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm }) // Start Vault - v, vaultToken := infra.StartVault(t, pool, network) + v, vaultToken := infra.StartVault(t, pool, network, "hashicorp/vault", "latest") t.Cleanup(func() { pool.Purge(v.Resource) }) @@ -120,7 +112,7 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm require.NoError(t, err) // Start a Boundary database and wait until it's ready - db := infra.StartBoundaryDatabase(t, pool, network) + db := infra.StartBoundaryDatabase(t, pool, network, "library/postgres", "latest") t.Cleanup(func() { pool.Purge(db.Resource) }) @@ -135,20 +127,35 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm require.NoError(t, err) // Create a target - target := infra.StartOpenSshServer(t, pool, network, c.TargetSshUser, c.TargetSshKeyPath) + target := infra.StartOpenSshServer( + t, + pool, + network, + "linuxserver/openssh-server", + "latest", + c.TargetSshUser, + c.TargetSshKeyPath, + ) t.Cleanup(func() { pool.Purge(target.Resource) }) // Initialize the database and extract resulting information - dbInit := infra.InitBoundaryDatabase(t, pool, network, db.UriNetwork) + dbInit := infra.InitBoundaryDatabase( + t, + pool, + network, + boundaryRepo, + boundaryTag, + db.UriNetwork, + ) t.Cleanup(func() { pool.Purge(dbInit.Resource) }) dbInitInfo := infra.GetDbInitInfoFromContainer(t, pool, dbInit) // Start a Boundary server and wait until Boundary has finished loading - b := infra.StartBoundary(t, pool, network, db.UriNetwork) + b := infra.StartBoundary(t, pool, network, boundaryRepo, boundaryTag, db.UriNetwork) t.Cleanup(func() { pool.Purge(b.Resource) }) @@ -191,7 +198,7 @@ func setupEnvironment(t testing.TB, ctx context.Context, c *config) TestEnvironm } } -func populateBoundaryDatabase(t testing.TB, ctx context.Context, c *config, te TestEnvironment) { +func populateBoundaryDatabase(t testing.TB, ctx context.Context, c *config, te TestEnvironment, boundaryRepo, boundaryTag string) { // Create resources for target. Uses the local CLI so that these methods can be reused. // While the CLI version used won't necessarily match the controller version, it should be (and is // supposed to be) backwards ompatible @@ -323,7 +330,16 @@ func populateBoundaryDatabase(t testing.TB, ctx context.Context, c *config, te T auth_token, ok := authenticationResult.Item.Attributes["token"].(string) require.True(t, ok) - connectTarget := infra.ConnectToTarget(t, te.Pool, te.Network, te.Boundary.UriNetwork, auth_token, newTargetId) + connectTarget := infra.ConnectToTarget( + t, + te.Pool, + te.Network, + boundaryRepo, + boundaryTag, + te.Boundary.UriNetwork, + auth_token, + newTargetId, + ) t.Cleanup(func() { te.Pool.Purge(connectTarget.Resource) })