103 lines
2.9 KiB
Go
103 lines
2.9 KiB
Go
package deploy
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
|
|
"git.solsynth.dev/goatworks/turbine/pkg/launchpad/config"
|
|
"github.com/rs/zerolog/log"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// --- Docker Compose Structures for YAML Marshalling ---
|
|
|
|
type ComposeFile struct {
|
|
Version string `yaml:"version"`
|
|
Services map[string]ComposeService `yaml:"services"`
|
|
Networks map[string]interface{} `yaml:"networks,omitempty"`
|
|
}
|
|
|
|
type ComposeService struct {
|
|
Image string `yaml:"image,omitempty"`
|
|
Build *ComposeBuild `yaml:"build,omitempty"`
|
|
Command interface{} `yaml:"command,omitempty"`
|
|
Ports []string `yaml:"ports,omitempty"`
|
|
Expose []string `yaml:"expose,omitempty"`
|
|
Environment map[string]string `yaml:"environment,omitempty"`
|
|
Volumes []string `yaml:"volumes,omitempty"`
|
|
DependsOn map[string]config.Dependency `yaml:"depends_on,omitempty"`
|
|
Networks []string `yaml:"networks,omitempty"`
|
|
Healthcheck *config.Healthcheck `yaml:"healthcheck,omitempty"`
|
|
}
|
|
|
|
type ComposeBuild struct {
|
|
Context string `yaml:"context,omitempty"`
|
|
Dockerfile string `yaml:"dockerfile,omitempty"`
|
|
}
|
|
|
|
// GenerateDockerCompose creates a docker-compose.yml file from the launchpad config.
|
|
func GenerateDockerCompose(cfg config.LaunchpadConfig) {
|
|
compose := ComposeFile{
|
|
Version: "3.8",
|
|
Services: make(map[string]ComposeService),
|
|
Networks: cfg.Networks,
|
|
}
|
|
|
|
for _, s := range cfg.Services {
|
|
subst := func(val string) string {
|
|
return os.ExpandEnv(val)
|
|
}
|
|
|
|
composeService := ComposeService{
|
|
Image: subst(s.Prod.Image),
|
|
Command: s.Prod.Command,
|
|
Ports: s.Prod.Ports,
|
|
Expose: s.Prod.Expose,
|
|
Volumes: s.Prod.Volumes,
|
|
DependsOn: s.Prod.DependsOn,
|
|
Networks: s.Prod.Networks,
|
|
}
|
|
|
|
// Add healthcheck if defined
|
|
if len(s.Prod.Healthcheck.Test) > 0 {
|
|
composeService.Healthcheck = &s.Prod.Healthcheck
|
|
}
|
|
|
|
if s.Prod.Dockerfile != "" {
|
|
context := "."
|
|
if s.Prod.BuildContext != "" {
|
|
context = s.Prod.BuildContext
|
|
}
|
|
composeService.Build = &ComposeBuild{
|
|
Context: context,
|
|
Dockerfile: s.Prod.Dockerfile,
|
|
}
|
|
}
|
|
|
|
if len(s.Prod.Environment) > 0 {
|
|
envMap := make(map[string]string)
|
|
for _, env := range s.Prod.Environment {
|
|
parts := strings.SplitN(subst(env), "=", 2)
|
|
if len(parts) == 2 {
|
|
envMap[parts[0]] = parts[1]
|
|
}
|
|
}
|
|
composeService.Environment = envMap
|
|
}
|
|
|
|
compose.Services[s.Name] = composeService
|
|
}
|
|
|
|
yamlData, err := yaml.Marshal(&compose)
|
|
if err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to generate YAML for docker-compose")
|
|
}
|
|
|
|
outFile := "docker-compose.yml"
|
|
if err := os.WriteFile(outFile, yamlData, 0o644); err != nil {
|
|
log.Fatal().Err(err).Msgf("Failed to write %s", outFile)
|
|
}
|
|
|
|
log.Info().Msgf("Successfully generated %s", outFile)
|
|
}
|