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

130 lines
3.9 KiB
Go
Raw Normal View History

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
}
}