Compare commits

..

3 commits

Author SHA1 Message Date
d2c52510a6
checkpoint: config to instance 2021-09-09 00:04:08 +01:00
649ee06c63
checkpoint: update config refactor 2021-09-07 22:55:52 +01:00
8d5bde3c2f
checkpoint: default config 2021-09-07 02:01:13 +01:00
7 changed files with 180 additions and 118 deletions

View file

@ -1,86 +0,0 @@
package config
import (
"encoding/json"
"fmt"
"io/ioutil"
)
// Config is the whole configuration for the forge platform deployment.
type Config struct {
ProjectName string `json:"project"`
Docker DockerConfig `json:"docker"`
Services ServicesConfig `json:"services"`
}
// DockerConfig contains the configuration for docker specific components.
type DockerConfig struct {
Network DockerNetworkConfig `json:"network"`
SharedVolume DockerSharedVolumeConfig `json:"sharedVolume"`
}
// DockerNetworkConfig contains configuration for creating the docker network.
type DockerNetworkConfig struct {
Name string `json:"name"`
Subnet string `json:"subnet"`
Driver string `json:"driver"`
}
// DockerSharedVolumeConfig contains 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 {
Traefik TraefikConfig `json:"traefik"`
Gitea GiteaConfig `json:"gitea"`
}
// TraefikConfig contains configuration for the Traefik container.
type TraefikConfig struct {
CheckNewVersion bool `json:"checkNewVersion"`
ContainerIp string `json:"containerIp"`
Domain string `json:"domain"`
GroupId int
LogLevel string `json:"logLevel"`
SendAnonymousUsage bool `json:"sendAnonymousUsage"`
Version string `json:"version"`
}
// GiteaConfig contains configuration for the Gitea container.
type GiteaConfig struct {
AppName string `json:"appName"`
BaseUri string `json:"baseUri"`
ContainerIp string `json:"containerIp"`
DataDirectory string `json:"dataDirectory"`
Domain string `json:"domain"`
GroupId int
HttpPort int `json:"httpPort"`
InternalToken string `json:"internalToken"`
LogLevel string `json:"logLevel"`
RootUrl string `json:"rootUrl"`
RunMode string `json:"runMode"`
SecretKey string `json:"secretKey"`
SshDomain string `json:"sshDomain"`
SshPort int `json:"sshPort"`
UserId int
Version string `json:"version"`
}
// NewConfig creates a new Config value from a given JSON file.
func NewConfig(file string) (Config, error) {
var c Config
var err error
data, err := ioutil.ReadFile(file)
if err != nil {
return c, fmt.Errorf("unable to read data from %s...\n%v", file, err)
}
if err = json.Unmarshal(data, &c); err != nil {
return c, fmt.Errorf("unable to decode the JSON configuration from %s...\n%v", file, err)
}
return c, nil
}

View file

@ -0,0 +1,88 @@
package instance
import (
"errors"
"encoding/json"
"fmt"
"io/ioutil"
)
// ReadInstance reads an instance's details from a given JSON file.
func ReadInstance(file string) (Instance, error) {
var err error
i := defaultInstance()
data, err := ioutil.ReadFile(file)
if err != nil {
return i, fmt.Errorf("unable to read data from %s...\n%v", file, err)
}
if err = json.Unmarshal(data, &i); err != nil {
return i, fmt.Errorf("unable to decode the JSON configuration from %s...\n%v", file, err)
}
if len(i.Project) == 0 {
return i, errors.New("the value for 'project' must not be empty")
}
// Propagate the domain to the services as appropriate
i.Services.Gitea.Domain = i.Domain
i.Services.Traefik.Domain = i.Domain
i.Services.Gitea.RootUrl = fmt.Sprintf("https://%s/%s", i.Domain, i.Services.Gitea.BaseUri)
i.Services.Gitea.SshDomain = i.Domain
// Propagate the shared Group ID to the serivces as appropriate
i.Services.Traefik.GroupId = i.SharedGroupId
i.Services.Gitea.GroupId = i.SharedGroupId
return i, nil
}
func defaultInstance() Instance {
c := Instance{
Project: "",
Domain: "localhost",
SharedGroupId: 2239,
Docker: DockerConfig{
Network: DockerNetworkConfig{
Name: "forge-platform-network",
Subnet: "172.20.0.0/24",
Driver: "default",
},
SharedVolume: DockerSharedVolumeConfig{
Name: "forge-platform-shared-volume",
MountPath: "/forge-platform/shared",
},
},
Services: ServicesConfig{
Traefik: TraefikConfig{
CheckNewVersion: false,
ContainerIp: "172.20.0.2",
LogLevel: "info",
SendAnonymousUsage: false,
Version: "v2.5.2",
},
Gitea: GiteaConfig{
AppName: "Gitea",
BaseUri: "git",
ContainerIp: "172.20.0.3",
ContainerDataDirectory: "/forge-platform/data",
ContainerTemporaryDirectory: "/forge-platform/tmp",
HostDataDirectory: "/mnt/forge-platform/gitea",
HttpPort: 3000,
InternalToken: "",
LogLevel: "info",
RunMode: "prod",
SecretKey: "",
SshPort: 2222,
UserId: 2000,
Version: "1.50.0",
},
},
}
return c
}

View file

@ -1,4 +1,4 @@
package config package instance
import ( import (
"reflect" "reflect"
@ -10,12 +10,12 @@ func TestValidConfig(t *testing.T) {
name string name string
description string description string
file string file string
want Config want Instance
}{ }{
name: "Test case: A valid Config", name: "Test case: A valid Config",
description: "Testing the parsing of valid configuration.", description: "Testing the parsing of valid configuration.",
file: "./testdata/config-valid.json", file: "./testdata/config-valid.json",
want: Config{ want: Instance{
ProjectName: "forge-platform-test-config", ProjectName: "forge-platform-test-config",
Docker: DockerConfig{ Docker: DockerConfig{
Network: DockerNetworkConfig{ Network: DockerNetworkConfig{
@ -60,7 +60,7 @@ func TestValidConfig(t *testing.T) {
testFunc := func(t *testing.T) { testFunc := func(t *testing.T) {
t.Log(testCase.description) t.Log(testCase.description)
got, err := NewConfig(testCase.file) got, err := ReadInstance(testCase.file)
if err != nil { if err != nil {
t.Fatalf("Unable to create the configuration from file: %v", err) t.Fatalf("Unable to create the configuration from file: %v", err)
} }
@ -88,7 +88,7 @@ func TestInvalidConfig(t *testing.T) {
testFunc := func(t *testing.T) { testFunc := func(t *testing.T) {
t.Log(testCase.description) t.Log(testCase.description)
_, err := NewConfig(testCase.file) _, err := ReadInstance(testCase.file)
if err == nil { if err == nil {
t.Error("Expected an error with this invalid configuration.") t.Error("Expected an error with this invalid configuration.")
} else { } else {

View file

@ -0,0 +1,68 @@
package instance
// Instance is the whole configuration for the forge platform deployment.
type Instance struct {
Project string `json:"project"`
Domain string `json:"domain"`
SharedGroupId int `json:"sharedGroupId"`
Docker DockerConfig `json:"docker"`
Services ServicesConfig `json:"services"`
}
// DockerConfig contains the configuration for docker specific components.
type DockerConfig struct {
Network DockerNetworkConfig `json:"network"`
SharedVolume DockerSharedVolumeConfig `json:"sharedVolume"`
}
// DockerNetworkConfig contains configuration for creating the docker network.
type DockerNetworkConfig struct {
Name string `json:"name"`
Subnet string `json:"subnet"`
Driver string `json:"driver"`
}
// DockerSharedVolumeConfig contains configuration for creating the shared volume.
type DockerSharedVolumeConfig struct {
Name string `json:"name"`
MountPath string `json:"mountPath"`
}
// Services contains a list of services and their configuration.
type ServicesConfig struct {
Traefik TraefikConfig `json:"traefik"`
Gitea GiteaConfig `json:"gitea"`
}
// TraefikConfig contains configuration for the Traefik container.
type TraefikConfig struct {
CheckNewVersion bool `json:"checkNewVersion"`
SendAnonymousUsage bool `json:"sendAnonymousUsage"`
GroupId int
ContainerIp string `json:"containerIp"`
Domain string
LogLevel string `json:"logLevel"`
Version string `json:"version"`
}
// GiteaConfig contains configuration for the Gitea container.
type GiteaConfig struct {
AppName string `json:"appName"`
BaseUri string `json:"baseUri"`
ContainerIp string `json:"containerIp"`
ContainerDataDirectory string `json:"containerDataDirectory"`
ContainerTemporaryDirectory string `json:"containerTemporaryDirectory"`
Domain string
HostDataDirectory string `json:"hostDataDirectory"`
HttpPort int `json:"httpPort"`
InternalToken string `json:"internalToken"`
LogLevel string `json:"logLevel"`
RootUrl string `json:"rootUrl"`
RunMode string `json:"runMode"`
SecretKey string `json:"secretKey"`
SshDomain string
SshPort int `json:"sshPort"`
UserId int `json:"userId"`
GroupId int
Version string `json:"version"`
}

View file

@ -75,15 +75,6 @@ func (c *DockerStack) Destroy(ctx context.Context) error {
// deployDockerStack returns a Pulumi run function that is used to deploy the docker stack. // deployDockerStack returns a Pulumi run function that is used to deploy the docker stack.
func deployDockerStack(project string, dockerConfig config.DockerConfig, services config.ServicesConfig) pulumi.RunFunc { func deployDockerStack(project string, dockerConfig config.DockerConfig, services config.ServicesConfig) pulumi.RunFunc {
sharedVolumeMountPath := "/helix/shared"
groupId := 2239
services.Traefik.GroupId = groupId
services.Gitea.GroupId = groupId
services.Gitea.UserId = 2000
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
@ -144,7 +135,7 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service
DockerVolumes: []docker.DockerVolume{ DockerVolumes: []docker.DockerVolume{
{ {
Name: sharedVolume.Name, Name: sharedVolume.Name,
MountPath: pulumi.String(sharedVolumeMountPath), MountPath: pulumi.String(dockerConfig.SharedVolume.MountPath),
}, },
}, },
} }
@ -154,6 +145,7 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service
} }
// Gitea service // Gitea service
// TODO: Template the data directory.
if err = renderTemplates(services.Gitea, "gitea", projectCacheRoot); err != nil { if err = renderTemplates(services.Gitea, "gitea", projectCacheRoot); err != nil {
return err return err
} }
@ -179,13 +171,13 @@ func deployDockerStack(project string, dockerConfig config.DockerConfig, service
DockerVolumes: []docker.DockerVolume{ DockerVolumes: []docker.DockerVolume{
{ {
Name: sharedVolume.Name, Name: sharedVolume.Name,
MountPath: pulumi.String(sharedVolumeMountPath), MountPath: pulumi.String(dockerConfig.SharedVolume.MountPath),
}, },
}, },
HostPathVolumes: []docker.HostPathVolume{ HostPathVolumes: []docker.HostPathVolume{
{ {
HostPath: pulumi.String(services.Gitea.DataDirectory), HostPath: pulumi.String(services.Gitea.HostDataDirectory),
MountPath: pulumi.String("/helix/gitea/data"), MountPath: pulumi.String(services.Gitea.ContainerDataDirectory),
}, },
}, },
UniqueLabel: "gitea-container", UniqueLabel: "gitea-container",