forked from coop-cloud/abra
150 lines
3.8 KiB
Go
150 lines
3.8 KiB
Go
package compose
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"coopcloud.tech/abra/pkg/config"
|
|
"coopcloud.tech/abra/pkg/upstream/stack"
|
|
loader "coopcloud.tech/abra/pkg/upstream/stack"
|
|
composetypes "github.com/docker/cli/cli/compose/types"
|
|
"github.com/docker/distribution/reference"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// UpdateTag updates an image tag in-place on file system local compose files.
|
|
func UpdateTag(pattern, image, tag, recipeName string) error {
|
|
composeFiles, err := filepath.Glob(pattern)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
logrus.Debugf("considering '%s' config(s) for tag update", strings.Join(composeFiles, ", "))
|
|
|
|
for _, composeFile := range composeFiles {
|
|
opts := stack.Deploy{Composefiles: []string{composeFile}}
|
|
|
|
envSamplePath := path.Join(config.ABRA_DIR, "apps", recipeName, ".env.sample")
|
|
sampleEnv, err := config.ReadEnv(envSamplePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
compose, err := loader.LoadComposefile(opts, sampleEnv)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, service := range compose.Services {
|
|
if service.Image == "" {
|
|
continue // may be a compose.$optional.yml file
|
|
}
|
|
|
|
img, _ := reference.ParseNormalizedNamed(service.Image)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
composeImage := reference.Path(img)
|
|
if strings.Contains(composeImage, "library") {
|
|
// ParseNormalizedNamed prepends 'library' to images like nginx:<tag>,
|
|
// postgres:<tag>, i.e. images which do not have a username in the
|
|
// first position of the string
|
|
composeImage = strings.Split(composeImage, "/")[1]
|
|
}
|
|
composeTag := img.(reference.NamedTagged).Tag()
|
|
|
|
logrus.Debugf("parsed '%s' from '%s'", composeTag, service.Image)
|
|
|
|
if image == composeImage {
|
|
bytes, err := ioutil.ReadFile(composeFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
old := fmt.Sprintf("%s:%s", composeImage, composeTag)
|
|
new := fmt.Sprintf("%s:%s", composeImage, tag)
|
|
replacedBytes := strings.Replace(string(bytes), old, new, -1)
|
|
|
|
logrus.Debugf("updating '%s' to '%s' in '%s'", old, new, compose.Filename)
|
|
|
|
if err := ioutil.WriteFile(compose.Filename, []byte(replacedBytes), 0644); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateLabel updates a label in-place on file system local compose files.
|
|
func UpdateLabel(pattern, serviceName, label, recipeName string) error {
|
|
composeFiles, err := filepath.Glob(pattern)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
logrus.Debugf("considering '%s' config(s) for label update", strings.Join(composeFiles, ", "))
|
|
|
|
for _, composeFile := range composeFiles {
|
|
opts := stack.Deploy{Composefiles: []string{composeFile}}
|
|
|
|
envSamplePath := path.Join(config.ABRA_DIR, "apps", recipeName, ".env.sample")
|
|
sampleEnv, err := config.ReadEnv(envSamplePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
compose, err := loader.LoadComposefile(opts, sampleEnv)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
serviceExists := false
|
|
var service composetypes.ServiceConfig
|
|
for _, s := range compose.Services {
|
|
if s.Name == serviceName {
|
|
service = s
|
|
serviceExists = true
|
|
}
|
|
}
|
|
|
|
if !serviceExists {
|
|
continue
|
|
}
|
|
|
|
discovered := false
|
|
for oldLabel, value := range service.Deploy.Labels {
|
|
if strings.HasPrefix(oldLabel, "coop-cloud") {
|
|
discovered = true
|
|
|
|
bytes, err := ioutil.ReadFile(composeFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
old := fmt.Sprintf("coop-cloud.${STACK_NAME}.version=%s", value)
|
|
replacedBytes := strings.Replace(string(bytes), old, label, -1)
|
|
|
|
logrus.Debugf("updating %s to %s in %s", old, label, compose.Filename)
|
|
|
|
if err := ioutil.WriteFile(compose.Filename, []byte(replacedBytes), 0644); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
if !discovered {
|
|
logrus.Warn("no existing label found, cannot continue...")
|
|
logrus.Fatalf("add '%s' manually, automagic insertion not supported yet", label)
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|