This repository has been archived on 2023-05-06. You can view files and clone it, but cannot push or open issues or pull requests.
helix/internal/stacks/containers.go
Dan Anglin fda0d6a682
feat: add traefik in the new containers stack
This commit adds the new containers stack which
now builds the traefik docker image and creates
the traefik docker container.

Pulumi needed to be downgraded to version 3.2.1
because later versions panic when building
the docker image.
2021-07-10 12:41:15 +01:00

129 lines
3.9 KiB
Go

package stacks
import (
"context"
_ "embed"
"fmt"
"os"
"path/filepath"
"github.com/pulumi/pulumi/sdk/v3/go/auto"
"github.com/pulumi/pulumi/sdk/v3/go/auto/optdestroy"
"github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview"
"github.com/pulumi/pulumi/sdk/v3/go/auto/optup"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"gitlab.com/dananglin/helix/internal/config"
"gitlab.com/dananglin/helix/internal/docker"
)
// ContainerStack is a stack for managing the containers
// for the forge platform.
type ContainerStack struct {
Name string
Stack auto.Stack
}
//go:embed templates/traefik/Dockerfile.tmpl
var templateTraefikDockerfile string
//go:embed templates/traefik/traefik.yaml.tmpl
var templateTraefikStaticConfig string
// newContainerStack creates the ContainerStack value.
func newContainerStack(ctx context.Context, project, stack, dockerNetwork string, conf config.TraefikConfig) (*ContainerStack, error) {
deployFunc := deployContainerStack(project, dockerNetwork, conf)
s, err := createOrSelectStack(ctx, project, stack, deployFunc)
if err != nil {
return nil, fmt.Errorf("unable to initialise the '%s' stack...\n%w", stack, err)
}
c := ContainerStack{
Name: stack,
Stack: s,
}
return &c, nil
}
// Preview the proposed changes to the container stack.
func (c *ContainerStack) Preview(ctx context.Context) error {
streamer := optpreview.ProgressStreams(os.Stdout)
_, err := c.Stack.Preview(ctx, streamer)
if err != nil {
return fmt.Errorf("unable to preview the '%s' stack...\n%w", c.Name, err)
}
return nil
}
// Update the container stack.
func (c *ContainerStack) Update(ctx context.Context) error {
streamer := optup.ProgressStreams(os.Stdout)
_, err := c.Stack.Up(ctx, streamer)
if err != nil {
return fmt.Errorf("unable to update '%s' stack...\n%w", c.Name, err)
}
return nil
}
// Destroy the container stack.
func (c *ContainerStack) Destroy(ctx context.Context) error {
streamer := optdestroy.ProgressStreams(os.Stdout)
_, err := c.Stack.Destroy(ctx, streamer)
if err != nil {
return fmt.Errorf("unable to destroy '%s' stack...\n%w", c.Name, err)
}
return nil
}
// deployContainerStack returns a Pulumi run function
// that is used to deploy the container stack.
func deployContainerStack(project, dockerNetwork string, t config.TraefikConfig) pulumi.RunFunc {
return func(ctx *pulumi.Context) error {
base_cache, err := os.UserCacheDir()
if err != nil {
return fmt.Errorf("unable to get the base cache directory...\n%w", err)
}
traefikContextDir := filepath.Join(base_cache, "helix", project, "traefik")
if err := os.MkdirAll(traefikContextDir, 0700); err != nil {
return fmt.Errorf("unable to make the cache directory for traefik...\n%w", err)
}
if err := generateFile(t, templateTraefikDockerfile, "traefikDocker", filepath.Join(traefikContextDir, "Dockerfile")); err != nil {
return fmt.Errorf("unable to generate the Traefik Dockerfile from template...\n%w", err)
}
if err := generateFile(t, templateTraefikStaticConfig, "traefikStaticConf", filepath.Join(traefikContextDir, "traefik.yml")); err != nil {
return fmt.Errorf("unable to generate the Traefik static configuration from template...\n%w", err)
}
c := docker.DockerImageInput{
BuildContext: pulumi.String(traefikContextDir),
Dockerfile: pulumi.String(filepath.Join(traefikContextDir, "Dockerfile")),
ImageName: pulumi.String("helix-traefik"),
ImageTag: pulumi.String(t.Version),
UniqueLabel: "traefik-image",
}
traefikImage, err := docker.CreateDockerImage(ctx, c)
if err != nil {
return err
}
traefikContainerInput := docker.DockerContainerInput{
Image: traefikImage.ImageName,
Ipv4Address: pulumi.String(t.ContainerIp),
Name: pulumi.String("helix-traefik"),
Network: pulumi.String(dockerNetwork),
UniqueLabel: "traefik-container",
}
if err = docker.CreateDockerContainer(ctx, traefikContainerInput); err != nil {
return err
}
return nil
}
}