Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion builder/build/postbuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (b *Build) RunPostbuild() error {
if b.System() == BuildpackBuildSystemKeyword {
entrypoint = []string{"/cnb/lifecycle/launcher"}
}
err = b.containers.RunContainer(containerID, b.CodebuildBuildId, &container.Config{
err = b.containers.RunContainer(containerID, b.CodebuildBuildId, nil, &container.Config{
Image: imageName,
Cmd: []string{"/bin/sh", "-c", testScript},
Entrypoint: entrypoint,
Expand Down
9 changes: 7 additions & 2 deletions builder/build/prebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,22 +348,27 @@ func (b *Build) StartAddons() (map[string]string, error) {
addons := removeDuplicateStr(b.AppJSON.GetTestAddons())
redisImage := "redis:alpine"
postgresImage := "postgres:alpine"
// Container names must be unique on the CodeBuild Docker daemon (which is
// reused across builds), so prefix them with the build ID. The friendly
// name ("redis"/"db") is kept as a network alias so other containers can
// still reach the addon by that hostname.
namePrefix := strings.ReplaceAll(b.CodebuildBuildId, ":", "-")
// use a switch statement to iterate over addons
for _, addon := range addons {
switch addon {
case "heroku-redis:in-dyno":
if err = b.containers.PullImage(redisImage); err != nil {
return nil, err
}
if err = b.containers.RunContainer("redis", b.CodebuildBuildId, &container.Config{Image: redisImage}); err != nil {
if err = b.containers.RunContainer(fmt.Sprintf("%s-redis", namePrefix), b.CodebuildBuildId, []string{"redis"}, &container.Config{Image: redisImage}); err != nil {
return nil, err
}
envOverides["REDIS_URL"] = "redis://redis:6379"
case "heroku-postgresql:in-dyno":
if err = b.containers.PullImage(postgresImage); err != nil {
return nil, err
}
if err = b.containers.RunContainer("db", b.CodebuildBuildId, &container.Config{Image: postgresImage}); err != nil {
if err = b.containers.RunContainer(fmt.Sprintf("%s-db", namePrefix), b.CodebuildBuildId, []string{"db"}, &container.Config{Image: postgresImage}); err != nil {
return nil, err
}
envOverides["DATABASE_URL"] = "postgres://postgres:postgres@db:5432/postgres"
Expand Down
8 changes: 4 additions & 4 deletions builder/build/prebuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ func (c *MockContainers) CreateContainer(s1 string, cfg *container.Config) (*str
return args.Get(0).(*string), args.Error(1)
}

func (c *MockContainers) RunContainer(s1 string, s2 string, cfg *container.Config) error {
args := c.Called(s1, s2, cfg)
func (c *MockContainers) RunContainer(s1 string, s2 string, aliases []string, cfg *container.Config) error {
args := c.Called(s1, s2, aliases, cfg)
return args.Error(0)
}

Expand Down Expand Up @@ -578,15 +578,15 @@ func TestStartAddons(t *testing.T) {
).Return(nil)
mockedContainers.On(
"RunContainer",
"redis", CodebuildBuildId, &container.Config{Image: "redis:alpine"},
fmt.Sprintf("%s-redis", CodebuildBuildId), CodebuildBuildId, []string{"redis"}, &container.Config{Image: "redis:alpine"},
).Return(nil)
mockedContainers.On(
"PullImage",
"postgres:alpine",
).Return(nil)
mockedContainers.On(
"RunContainer",
"db", CodebuildBuildId, &container.Config{Image: "postgres:alpine"},
fmt.Sprintf("%s-db", CodebuildBuildId), CodebuildBuildId, []string{"db"}, &container.Config{Image: "postgres:alpine"},
).Return(nil)
b := Build{
CodebuildBuildId: CodebuildBuildId,
Expand Down
16 changes: 12 additions & 4 deletions builder/containers/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type ContainersI interface {
BuildImage(string, *BuildConfig) error
CreateContainer(string, *container.Config) (*string, error)
DeleteContainer(string) error
RunContainer(string, string, *container.Config) error
RunContainer(string, string, []string, *container.Config) error
GetContainerFile(string, string) (io.ReadCloser, error)
WaitForExit(string) (int, error)
AttachLogs(string, io.Writer, io.Writer) error
Expand Down Expand Up @@ -141,13 +141,21 @@ func (c *Containers) CreateContainer(name string, config *container.Config) (*st
return &resp.ID, nil
}

func (c *Containers) RunContainer(name string, networkID string, config *container.Config) error {
c.Log().Debug().Str("image", config.Image).Str("container", name).Msg("starting container")
// RunContainer creates and starts a container connected to networkID. The
// container is created with the (unique) name so it never collides on a
// reused Docker daemon. Any aliases are registered as network-scoped
// hostnames so other containers can reach it by a friendly name (e.g. "db").
func (c *Containers) RunContainer(name string, networkID string, aliases []string, config *container.Config) error {
c.Log().Debug().Str("image", config.Image).Str("container", name).Strs("aliases", aliases).Msg("starting container")
containerID, err := c.CreateContainer(name, config)
if err != nil {
return err
}
err = c.cli.NetworkConnect(c.ctx, networkID, *containerID, nil)
var endpoint *network.EndpointSettings
if len(aliases) > 0 {
endpoint = &network.EndpointSettings{Aliases: aliases}
}
err = c.cli.NetworkConnect(c.ctx, networkID, *containerID, endpoint)
if err != nil {
return err
}
Expand Down
Loading