Files
Turbine/pkg/launchpad/deploy/deploy.go
2025-12-13 16:16:15 +08:00

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)
}