feat: create a shared volume

The shared volume will be used by each container
to share their specific traefik dynamic
configuration to allow Traefik to dynamically
configure the backend.
This commit is contained in:
Dan Anglin 2021-07-11 13:32:01 +01:00
parent 99cf3dca17
commit 2a761272a0
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
8 changed files with 78 additions and 18 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
helix

View file

@ -6,28 +6,34 @@ import (
"io/ioutil" "io/ioutil"
) )
// Config is the whole configuration for the forge platform deployment.
type Config struct { type Config struct {
ProjectName string `json:"project"` ProjectName string `json:"project"`
Docker DockerConfig `json:"docker"` Docker DockerConfig `json:"docker"`
Services ServicesConfig `json:"services"` Services ServicesConfig `json:"services"`
} }
// DockerConfig contains the configuration for // DockerConfig contains the configuration for docker specific components.
// docker specific components.
type DockerConfig struct { type DockerConfig struct {
Network DockerNetworkConfig `json:"network"` Network DockerNetworkConfig `json:"network"`
SharedVolume DockerSharedVolumeConfig `json:"sharedVolume"`
} }
// DockerNetworkStackArgs contains arguments for // DockerNetworkConfig contains configuration for creating the docker network.
// creating the DockerNetworkStack
type DockerNetworkConfig struct { type DockerNetworkConfig struct {
Name string `json:"name"` Name string `json:"name"`
Subnet string `json:"subnet"` Subnet string `json:"subnet"`
Driver string `json:"driver"` Driver string `json:"driver"`
} }
// Services contains a list of // DockerSharedVolumeConfig contains configuration
// services and their configuration // for creating the shared volume.
type DockerSharedVolumeConfig struct {
Name string `json:"name"`
}
// Services contains a list of services and their configuration.
type ServicesConfig struct { type ServicesConfig struct {
Traefik TraefikConfig `json:"traefik"` Traefik TraefikConfig `json:"traefik"`
} }

View file

@ -23,6 +23,9 @@ func TestValidConfig(t *testing.T) {
Subnet: "172.17.1.0/24", Subnet: "172.17.1.0/24",
Driver: "default", Driver: "default",
}, },
SharedVolume: DockerSharedVolumeConfig{
Name: "shared-volume",
},
}, },
Services: ServicesConfig{ Services: ServicesConfig{
Traefik: TraefikConfig{ Traefik: TraefikConfig{

View file

@ -5,6 +5,9 @@
"subnet": "172.17.1.0/24", "subnet": "172.17.1.0/24",
"name": "forge-platform-test-netwwork", "name": "forge-platform-test-netwwork",
"driver": "default" "driver": "default"
},
"sharedVolume": {
"name": "shared-volume"
} }
}, },
"services": { "services": {

View file

@ -27,7 +27,7 @@ type DockerVolumeMount struct {
MountPath pulumi.StringInput MountPath pulumi.StringInput
} }
func CreateDockerContainer(ctx *pulumi.Context, c DockerContainerInput) error { func CreateContainer(ctx *pulumi.Context, c DockerContainerInput) error {
// all containers will mount the host's timezone and localtime files // all containers will mount the host's timezone and localtime files
// to ensure the correct time is synced. // to ensure the correct time is synced.
volumes := []docker.ContainerVolumeInput{ volumes := []docker.ContainerVolumeInput{

View file

@ -25,7 +25,7 @@ type DockerImageOutput struct {
} }
// CreateDockerImage creates a local Docker image. // CreateDockerImage creates a local Docker image.
func CreateDockerImage(ctx *pulumi.Context, c DockerImageInput) (DockerImageOutput, error) { func CreateImage(ctx *pulumi.Context, c DockerImageInput) (DockerImageOutput, error) {
var output DockerImageOutput var output DockerImageOutput
args := docker.ImageArgs{ args := docker.ImageArgs{

36
internal/docker/volume.go Normal file
View file

@ -0,0 +1,36 @@
package docker
import (
"fmt"
"github.com/pulumi/pulumi-docker/sdk/v3/go/docker"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
type DockerVolumeInput struct {
Name pulumi.StringInput
UniqueLabel string
}
type DockerVolumeOutput struct {
Name pulumi.StringOutput
}
func CreateVolume(ctx *pulumi.Context, input DockerVolumeInput) (DockerVolumeOutput, error) {
var output DockerVolumeOutput
args := docker.VolumeArgs{
Name: input.Name,
}
volume, err := docker.NewVolume(ctx, input.UniqueLabel, &args)
if err != nil {
return output, fmt.Errorf("unable to create the %s volume...\n%v", input.UniqueLabel, err)
}
output = DockerVolumeOutput{
Name: volume.Name,
}
return output, nil
}

View file

@ -31,7 +31,7 @@ var templateTraefikStaticConfig string
// newContainerStack creates the ContainerStack value. // newContainerStack creates the ContainerStack value.
func newDockerStack(ctx context.Context, project, stack string, c config.Config) (*DockerStack, error) { func newDockerStack(ctx context.Context, project, stack string, c config.Config) (*DockerStack, error) {
deployFunc := deployDockerStack(project, c.Docker.Network, c.Services) deployFunc := deployDockerStack(project, c.Docker, c.Services)
s, err := createOrSelectStack(ctx, project, stack, deployFunc) s, err := createOrSelectStack(ctx, project, stack, deployFunc)
if err != nil { if err != nil {
@ -78,18 +78,29 @@ func (c *DockerStack) Destroy(ctx context.Context) error {
// deployDockerStack returns a Pulumi run function // deployDockerStack returns a Pulumi run function
// that is used to deploy the docker stack. // that is used to deploy the docker stack.
func deployDockerStack(project string, network config.DockerNetworkConfig, services config.ServicesConfig) pulumi.RunFunc { func deployDockerStack(project string, dockerConfig config.DockerConfig, 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 // TODO: Create the provider when we start playing with remote hosts
// Create the docker network // Create the docker network
config := docker.DockerNetworkConfig{ networkConfig := docker.DockerNetworkConfig{
Name: pulumi.String(network.Name), Name: pulumi.String(dockerConfig.Network.Name),
Subnet: pulumi.String(network.Subnet), Subnet: pulumi.String(dockerConfig.Network.Subnet),
Driver: pulumi.String(network.Driver), Driver: pulumi.String(dockerConfig.Network.Driver),
} }
network, err := docker.CreateNetwork(ctx, config) network, err := docker.CreateNetwork(ctx, networkConfig)
if err != nil {
return err
}
// Create the shared volume
sharedVolumeInput := docker.DockerVolumeInput{
Name: pulumi.String(dockerConfig.SharedVolume.Name),
UniqueLabel: "shared",
}
_, err = docker.CreateVolume(ctx, sharedVolumeInput)
if err != nil { if err != nil {
return err return err
} }
@ -122,7 +133,7 @@ func deployDockerStack(project string, network config.DockerNetworkConfig, servi
UniqueLabel: "traefik-image", UniqueLabel: "traefik-image",
} }
traefikImage, err := docker.CreateDockerImage(ctx, c) traefikImage, err := docker.CreateImage(ctx, c)
if err != nil { if err != nil {
return err return err
} }
@ -135,7 +146,7 @@ func deployDockerStack(project string, network config.DockerNetworkConfig, servi
UniqueLabel: "traefik-container", UniqueLabel: "traefik-container",
} }
if err = docker.CreateDockerContainer(ctx, traefikContainerInput); err != nil { if err = docker.CreateContainer(ctx, traefikContainerInput); err != nil {
return err return err
} }