feat: the docker stack

Here we rename the containers stack to the docker stack.
The docker_network stack is now deleted and the docker network is
now managed in the docker stack.
This commit is contained in:
Dan Anglin 2021-07-11 10:49:53 +01:00
parent fda0d6a682
commit 99cf3dca17
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
4 changed files with 53 additions and 130 deletions

View file

@ -15,8 +15,14 @@ type DockerNetworkConfig struct {
Driver pulumi.StringInput Driver pulumi.StringInput
} }
type DockerNetworkResults struct {
Name pulumi.StringOutput
}
// CreateNetwork creates the forge platform's Docker network. // CreateNetwork creates the forge platform's Docker network.
func CreateNetwork(ctx *pulumi.Context, c DockerNetworkConfig) error { func CreateNetwork(ctx *pulumi.Context, c DockerNetworkConfig) (DockerNetworkResults, error) {
var result DockerNetworkResults
args := docker.NetworkArgs{ args := docker.NetworkArgs{
Name: c.Name, Name: c.Name,
IpamDriver: c.Driver, IpamDriver: c.Driver,
@ -27,10 +33,14 @@ func CreateNetwork(ctx *pulumi.Context, c DockerNetworkConfig) error {
}, },
} }
_, err := docker.NewNetwork(ctx, "docker_network", &args) n, err := docker.NewNetwork(ctx, "docker_network", &args)
if err != nil { if err != nil {
return fmt.Errorf("unable to create the docker network...\n%w", err) return result, fmt.Errorf("unable to create the docker network...\n%w", err)
} }
return nil result = DockerNetworkResults{
Name: n.Name,
}
return result, nil
} }

View file

@ -16,9 +16,9 @@ import (
"gitlab.com/dananglin/helix/internal/docker" "gitlab.com/dananglin/helix/internal/docker"
) )
// ContainerStack is a stack for managing the containers // DockerStack is a stack for managing the containers
// for the forge platform. // for the forge platform.
type ContainerStack struct { type DockerStack struct {
Name string Name string
Stack auto.Stack Stack auto.Stack
} }
@ -30,24 +30,24 @@ var templateTraefikDockerfile string
var templateTraefikStaticConfig string var templateTraefikStaticConfig string
// newContainerStack creates the ContainerStack value. // newContainerStack creates the ContainerStack value.
func newContainerStack(ctx context.Context, project, stack, dockerNetwork string, conf config.TraefikConfig) (*ContainerStack, error) { func newDockerStack(ctx context.Context, project, stack string, c config.Config) (*DockerStack, error) {
deployFunc := deployContainerStack(project, dockerNetwork, conf) deployFunc := deployDockerStack(project, c.Docker.Network, c.Services)
s, err := createOrSelectStack(ctx, project, stack, deployFunc) s, err := createOrSelectStack(ctx, project, stack, deployFunc)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to initialise the '%s' stack...\n%w", stack, err) return nil, fmt.Errorf("unable to initialise the '%s' stack...\n%w", stack, err)
} }
c := ContainerStack{ d := DockerStack{
Name: stack, Name: stack,
Stack: s, Stack: s,
} }
return &c, nil return &d, nil
} }
// Preview the proposed changes to the container stack. // Preview the proposed changes to the container stack.
func (c *ContainerStack) Preview(ctx context.Context) error { func (c *DockerStack) Preview(ctx context.Context) error {
streamer := optpreview.ProgressStreams(os.Stdout) streamer := optpreview.ProgressStreams(os.Stdout)
_, err := c.Stack.Preview(ctx, streamer) _, err := c.Stack.Preview(ctx, streamer)
if err != nil { if err != nil {
@ -57,7 +57,7 @@ func (c *ContainerStack) Preview(ctx context.Context) error {
} }
// Update the container stack. // Update the container stack.
func (c *ContainerStack) Update(ctx context.Context) error { func (c *DockerStack) Update(ctx context.Context) error {
streamer := optup.ProgressStreams(os.Stdout) streamer := optup.ProgressStreams(os.Stdout)
_, err := c.Stack.Up(ctx, streamer) _, err := c.Stack.Up(ctx, streamer)
if err != nil { if err != nil {
@ -67,7 +67,7 @@ func (c *ContainerStack) Update(ctx context.Context) error {
} }
// Destroy the container stack. // Destroy the container stack.
func (c *ContainerStack) Destroy(ctx context.Context) error { func (c *DockerStack) Destroy(ctx context.Context) error {
streamer := optdestroy.ProgressStreams(os.Stdout) streamer := optdestroy.ProgressStreams(os.Stdout)
_, err := c.Stack.Destroy(ctx, streamer) _, err := c.Stack.Destroy(ctx, streamer)
if err != nil { if err != nil {
@ -76,26 +76,41 @@ func (c *ContainerStack) Destroy(ctx context.Context) error {
return nil return nil
} }
// deployContainerStack returns a Pulumi run function // deployDockerStack returns a Pulumi run function
// that is used to deploy the container stack. // that is used to deploy the docker stack.
func deployContainerStack(project, dockerNetwork string, t config.TraefikConfig) pulumi.RunFunc { func deployDockerStack(project string, network config.DockerNetworkConfig, services config.ServicesConfig) pulumi.RunFunc {
return func(ctx *pulumi.Context) error { return func(ctx *pulumi.Context) error {
// TODO: Create the provider when we start playing with remote hosts
// Create the docker network
config := docker.DockerNetworkConfig{
Name: pulumi.String(network.Name),
Subnet: pulumi.String(network.Subnet),
Driver: pulumi.String(network.Driver),
}
network, err := docker.CreateNetwork(ctx, config)
if err != nil {
return err
}
base_cache, err := os.UserCacheDir() base_cache, err := os.UserCacheDir()
if err != nil { if err != nil {
return fmt.Errorf("unable to get the base cache directory...\n%w", err) return fmt.Errorf("unable to get the base cache directory...\n%w", err)
} }
// Create the Traefik service
traefikContextDir := filepath.Join(base_cache, "helix", project, "traefik") traefikContextDir := filepath.Join(base_cache, "helix", project, "traefik")
if err := os.MkdirAll(traefikContextDir, 0700); err != nil { if err := os.MkdirAll(traefikContextDir, 0700); err != nil {
return fmt.Errorf("unable to make the cache directory for traefik...\n%w", err) 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 { if err := generateFile(services.Traefik, templateTraefikDockerfile, "traefikDocker", filepath.Join(traefikContextDir, "Dockerfile")); err != nil {
return fmt.Errorf("unable to generate the Traefik Dockerfile from template...\n%w", err) 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 { if err := generateFile(services.Traefik, templateTraefikStaticConfig, "traefikStaticConf", filepath.Join(traefikContextDir, "traefik.yml")); err != nil {
return fmt.Errorf("unable to generate the Traefik static configuration from template...\n%w", err) return fmt.Errorf("unable to generate the Traefik static configuration from template...\n%w", err)
} }
@ -103,7 +118,7 @@ func deployContainerStack(project, dockerNetwork string, t config.TraefikConfig)
BuildContext: pulumi.String(traefikContextDir), BuildContext: pulumi.String(traefikContextDir),
Dockerfile: pulumi.String(filepath.Join(traefikContextDir, "Dockerfile")), Dockerfile: pulumi.String(filepath.Join(traefikContextDir, "Dockerfile")),
ImageName: pulumi.String("helix-traefik"), ImageName: pulumi.String("helix-traefik"),
ImageTag: pulumi.String(t.Version), ImageTag: pulumi.String(services.Traefik.Version),
UniqueLabel: "traefik-image", UniqueLabel: "traefik-image",
} }
@ -114,9 +129,9 @@ func deployContainerStack(project, dockerNetwork string, t config.TraefikConfig)
traefikContainerInput := docker.DockerContainerInput{ traefikContainerInput := docker.DockerContainerInput{
Image: traefikImage.ImageName, Image: traefikImage.ImageName,
Ipv4Address: pulumi.String(t.ContainerIp), Ipv4Address: pulumi.String(services.Traefik.ContainerIp),
Name: pulumi.String("helix-traefik"), Name: pulumi.String("helix-traefik"),
Network: pulumi.String(dockerNetwork), Network: network.Name,
UniqueLabel: "traefik-container", UniqueLabel: "traefik-container",
} }

View file

@ -1,86 +0,0 @@
package stacks
import (
"context"
"fmt"
"os"
"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"
)
// DockerNetworkStack is a stack for
// managing the Docker network.
type DockerNetworkStack struct {
Name string
Stack auto.Stack
}
// newDockerNetworkStack creates a new DockerNetworkStack value.
func newDockerNetworkStack(ctx context.Context, project, stack string, args config.DockerNetworkConfig) (*DockerNetworkStack, error) {
deployFunc := deployDockerNetworkStack(args.Name, args.Subnet, args.Driver)
s, err := createOrSelectStack(ctx, project, stack, deployFunc)
if err != nil {
return nil, fmt.Errorf("unable to initialise the '%s' stack...\n%w", stack, err)
}
n := DockerNetworkStack{
Name: stack,
Stack: s,
}
return &n, nil
}
func (d *DockerNetworkStack) Preview(ctx context.Context) error {
stdoutStreamer := optpreview.ProgressStreams(os.Stdout)
_, err := d.Stack.Preview(ctx, stdoutStreamer)
if err != nil {
return fmt.Errorf("unable to preview the '%s' stack...\n%w", d.Name, err)
}
return nil
}
func (d *DockerNetworkStack) Update(ctx context.Context) error {
stdoutStreamer := optup.ProgressStreams(os.Stdout)
_, err := d.Stack.Up(ctx, stdoutStreamer)
if err != nil {
return fmt.Errorf("unable to update the '%s' stack...\n%w", d.Name, err)
}
return nil
}
func (d *DockerNetworkStack) Destroy(ctx context.Context) error {
stdoutStreamer := optdestroy.ProgressStreams(os.Stdout)
_, err := d.Stack.Destroy(ctx, stdoutStreamer)
if err != nil {
return fmt.Errorf("unable to destroy the '%s' stack...\n%w", d.Name, err)
}
return nil
}
// deployDockerNetworkStack returns a Pulumi run function
// that deploys the Docker network stack.
func deployDockerNetworkStack(name, subnet, driver string) pulumi.RunFunc {
return func(ctx *pulumi.Context) error {
config := docker.DockerNetworkConfig{
Name: pulumi.String(name),
Subnet: pulumi.String(subnet),
Driver: pulumi.String(driver),
}
if err := docker.CreateNetwork(ctx, config); err != nil {
return fmt.Errorf("unable to complete the deployment...\n%w", err)
}
return nil
}
}

View file

@ -15,8 +15,7 @@ import (
) )
const ( const (
dockerNetworkStackName string = "docker_network" dockerStackName string = "docker"
containerStackName string = "containers"
) )
type Previewer interface { type Previewer interface {
@ -36,13 +35,8 @@ func NewPreviewer(ctx context.Context, stack string, c config.Config) (Previewer
var err error var err error
switch stack { switch stack {
case dockerNetworkStackName: case dockerStackName:
p, err = newDockerNetworkStack(ctx, c.ProjectName, stack, c.Docker.Network) p, err = newDockerStack(ctx, c.ProjectName, stack, c)
if err != nil {
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err)
}
case containerStackName:
p, err = newContainerStack(ctx, c.ProjectName, stack, c.Docker.Network.Name, c.Services.Traefik)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err) return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err)
} }
@ -58,13 +52,8 @@ func NewUpdater(ctx context.Context, stack string, c config.Config) (Updater, er
var err error var err error
switch stack { switch stack {
case dockerNetworkStackName: case dockerStackName:
u, err = newDockerNetworkStack(ctx, c.ProjectName, stack, c.Docker.Network) u, err = newDockerStack(ctx, c.ProjectName, stack, c)
if err != nil {
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err)
}
case containerStackName:
u, err = newContainerStack(ctx, c.ProjectName, stack, c.Docker.Network.Name, c.Services.Traefik)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err) return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err)
} }
@ -80,13 +69,8 @@ func NewDestroyer(ctx context.Context, stack string, c config.Config) (Destroyer
var err error var err error
switch stack { switch stack {
case dockerNetworkStackName: case dockerStackName:
d, err = newDockerNetworkStack(ctx, c.ProjectName, stack, c.Docker.Network) d, err = newDockerStack(ctx, c.ProjectName, stack, c)
if err != nil {
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err)
}
case containerStackName:
d, err = newContainerStack(ctx, c.ProjectName, stack, c.Docker.Network.Name, c.Services.Traefik)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err) return nil, fmt.Errorf("unable to initialise '%s' stack...\n%w", stack, err)
} }