Compare commits
3 commits
main
...
config-ref
Author | SHA1 | Date | |
---|---|---|---|
d2c52510a6 | |||
649ee06c63 | |||
8d5bde3c2f |
7 changed files with 180 additions and 118 deletions
|
@ -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
|
|
||||||
}
|
|
88
internal/instance/instance.go
Normal file
88
internal/instance/instance.go
Normal 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
|
||||||
|
}
|
|
@ -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 {
|
68
internal/instance/types.go
Normal file
68
internal/instance/types.go
Normal 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"`
|
||||||
|
}
|
|
@ -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",
|
||||||
|
|
Reference in a new issue