forked from toolshed/abra
refactor: create compose package
This commit is contained in:
115
pkg/compose/compose.go
Normal file
115
pkg/compose/compose.go
Normal file
@ -0,0 +1,115 @@
|
||||
package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"coopcloud.tech/abra/pkg/client/stack"
|
||||
loader "coopcloud.tech/abra/pkg/client/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 string) error {
|
||||
composeFiles, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, composeFile := range composeFiles {
|
||||
opts := stack.Deploy{Composefiles: []string{composeFile}}
|
||||
emptyEnv := make(map[string]string)
|
||||
compose, err := loader.LoadComposefile(opts, emptyEnv)
|
||||
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 {
|
||||
logrus.Fatal(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()
|
||||
|
||||
if image == composeImage {
|
||||
bytes, err := ioutil.ReadFile(composeFile)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
old := fmt.Sprintf("%s:%s", composeImage, composeTag)
|
||||
new := fmt.Sprintf("%s:%s", composeImage, tag)
|
||||
replacedBytes := strings.Replace(string(bytes), old, new, -1)
|
||||
|
||||
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 string) error {
|
||||
composeFiles, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, composeFile := range composeFiles {
|
||||
opts := stack.Deploy{Composefiles: []string{composeFile}}
|
||||
emptyEnv := make(map[string]string)
|
||||
compose, err := loader.LoadComposefile(opts, emptyEnv)
|
||||
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
|
||||
}
|
||||
|
||||
for oldLabel, value := range service.Deploy.Labels {
|
||||
if strings.HasPrefix(oldLabel, "coop-cloud") {
|
||||
bytes, err := ioutil.ReadFile(composeFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
old := fmt.Sprintf("coop-cloud.${STACK_NAME}.%s.version=%s", service.Name, value)
|
||||
replacedBytes := strings.Replace(string(bytes), old, label, -1)
|
||||
if err := ioutil.WriteFile(compose.Filename, []byte(replacedBytes), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -13,8 +13,6 @@ import (
|
||||
loader "coopcloud.tech/abra/pkg/client/stack"
|
||||
stack "coopcloud.tech/abra/pkg/client/stack"
|
||||
composetypes "github.com/docker/cli/cli/compose/types"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Type aliases to make code hints easier to understand
|
||||
@ -258,102 +256,3 @@ func GetAppComposeConfig(recipe string, opts stack.Deploy, appEnv AppEnv) (*comp
|
||||
}
|
||||
return compose, nil
|
||||
}
|
||||
|
||||
func UpdateAppComposeTag(recipe, image, tag string, appEnv AppEnv) error {
|
||||
pattern := fmt.Sprintf("%s/%s/compose**yml", APPS_DIR, recipe)
|
||||
composeFiles, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, composeFile := range composeFiles {
|
||||
opts := stack.Deploy{Composefiles: []string{composeFile}}
|
||||
compose, err := loader.LoadComposefile(opts, appEnv)
|
||||
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 {
|
||||
logrus.Fatal(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()
|
||||
|
||||
if image == composeImage {
|
||||
bytes, err := ioutil.ReadFile(composeFile)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
old := fmt.Sprintf("%s:%s", composeImage, composeTag)
|
||||
new := fmt.Sprintf("%s:%s", composeImage, tag)
|
||||
replacedBytes := strings.Replace(string(bytes), old, new, -1)
|
||||
|
||||
if err := ioutil.WriteFile(compose.Filename, []byte(replacedBytes), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateAppComposeLabel(recipe, serviceName, newLabel string, appEnv AppEnv) error {
|
||||
pattern := fmt.Sprintf("%s/%s/compose**yml", APPS_DIR, recipe)
|
||||
composeFiles, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, composeFile := range composeFiles {
|
||||
opts := stack.Deploy{Composefiles: []string{composeFile}}
|
||||
compose, err := loader.LoadComposefile(opts, appEnv)
|
||||
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
|
||||
}
|
||||
|
||||
for oldLabel, value := range service.Deploy.Labels {
|
||||
if strings.HasPrefix(oldLabel, "coop-cloud") {
|
||||
bytes, err := ioutil.ReadFile(composeFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
old := fmt.Sprintf("coop-cloud.${STACK_NAME}.%s.version=%s", service.Name, value)
|
||||
replacedBytes := strings.Replace(string(bytes), old, newLabel, -1)
|
||||
if err := ioutil.WriteFile(compose.Filename, []byte(replacedBytes), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -4,9 +4,13 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"coopcloud.tech/abra/pkg/client/stack"
|
||||
loader "coopcloud.tech/abra/pkg/client/stack"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
composetypes "github.com/docker/cli/cli/compose/types"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
)
|
||||
@ -66,3 +70,21 @@ func EnsureVersion(version string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetComposeConfig merges and loads a recipe compose configuration.
|
||||
func GetComposeConfig(recipeName string) (*composetypes.Config, error) {
|
||||
pattern := fmt.Sprintf("%s/%s/compose**yml", config.APPS_DIR, recipeName)
|
||||
composeFiles, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return &composetypes.Config{}, err
|
||||
}
|
||||
|
||||
opts := stack.Deploy{Composefiles: composeFiles}
|
||||
emptyEnv := make(map[string]string)
|
||||
compose, err := loader.LoadComposefile(opts, emptyEnv)
|
||||
if err != nil {
|
||||
return &composetypes.Config{}, err
|
||||
}
|
||||
|
||||
return compose, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user