diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 138e0330..b272918b 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -173,7 +173,7 @@ recipes. app.Env[k] = v } - composeFiles, err := recipe.GetComposeFiles(app.Recipe, app.Env) + composeFiles, err := r2.GetComposeFiles(app.Env) if err != nil { log.Fatal(err) } diff --git a/cli/app/new.go b/cli/app/new.go index 823609d9..0453650d 100644 --- a/cli/app/new.go +++ b/cli/app/new.go @@ -136,7 +136,7 @@ var appNewCommand = cli.Command{ log.Fatal(err) } - composeFiles, err := recipePkg.GetComposeFiles(recipe.Name, sampleEnv) + composeFiles, err := r.GetComposeFiles(sampleEnv) if err != nil { log.Fatal(err) } diff --git a/cli/app/ps.go b/cli/app/ps.go index 0db7a7dc..c6e62705 100644 --- a/cli/app/ps.go +++ b/cli/app/ps.go @@ -68,7 +68,8 @@ var appPsCommand = cli.Command{ // showPSOutput renders ps output. func showPSOutput(app appPkg.App, cl *dockerClient.Client) { - composeFiles, err := recipe.GetComposeFiles(app.Recipe, app.Env) + r := recipe.Get2(app.Name) + composeFiles, err := r.GetComposeFiles(app.Env) if err != nil { log.Fatal(err) return diff --git a/cli/app/rollback.go b/cli/app/rollback.go index edade3d0..afe1b23e 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -193,7 +193,7 @@ recipes. app.Env[k] = v } - composeFiles, err := recipe.GetComposeFiles(app.Recipe, app.Env) + composeFiles, err := r2.GetComposeFiles(app.Env) if err != nil { log.Fatal(err) } diff --git a/cli/app/secret.go b/cli/app/secret.go index 22ad9e9d..9618742c 100644 --- a/cli/app/secret.go +++ b/cli/app/secret.go @@ -72,7 +72,7 @@ var appSecretGenerateCommand = cli.Command{ internal.ShowSubcommandHelpAndError(c, err) } - composeFiles, err := recipe.GetComposeFiles(app.Recipe, app.Env) + composeFiles, err := r.GetComposeFiles(app.Env) if err != nil { log.Fatal(err) } @@ -270,7 +270,7 @@ Example: } } - composeFiles, err := recipe.GetComposeFiles(app.Recipe, app.Env) + composeFiles, err := r.GetComposeFiles(app.Env) if err != nil { log.Fatal(err) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index fe61d5be..5f2a129c 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -231,7 +231,7 @@ recipes. app.Env[k] = v } - composeFiles, err := recipePkg.GetComposeFiles(app.Recipe, app.Env) + composeFiles, err := r.GetComposeFiles(app.Env) if err != nil { log.Fatal(err) } diff --git a/cli/updater/updater.go b/cli/updater/updater.go index 49d0e854..8565f5d5 100644 --- a/cli/updater/updater.go +++ b/cli/updater/updater.go @@ -357,7 +357,7 @@ func mergeAbraShEnv(recipeName string, env envfile.AppEnv) error { } // createDeployConfig merges and enriches the compose config for the deployment. -func createDeployConfig(recipeName string, stackName string, env envfile.AppEnv) (*composetypes.Config, stack.Deploy, error) { +func createDeployConfig(r recipe.Recipe2, stackName string, env envfile.AppEnv) (*composetypes.Config, stack.Deploy, error) { env["STACK_NAME"] = stackName deployOpts := stack.Deploy{ @@ -367,7 +367,7 @@ func createDeployConfig(recipeName string, stackName string, env envfile.AppEnv) Detach: false, } - composeFiles, err := recipe.GetComposeFiles(recipeName, env) + composeFiles, err := r.GetComposeFiles(env) if err != nil { return nil, deployOpts, err } @@ -382,7 +382,7 @@ func createDeployConfig(recipeName string, stackName string, env envfile.AppEnv) // after the upgrade the deployment won't be in chaos state anymore appPkg.SetChaosLabel(compose, stackName, false) - appPkg.SetRecipeLabel(compose, stackName, recipeName) + appPkg.SetRecipeLabel(compose, stackName, r.Name) appPkg.SetUpdateLabel(compose, stackName, env) return compose, deployOpts, nil @@ -455,7 +455,7 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName, return err } - compose, deployOpts, err := createDeployConfig(recipeName, stackName, app.Env) + compose, deployOpts, err := createDeployConfig(r, stackName, app.Env) if err != nil { return err } diff --git a/pkg/app/app.go b/pkg/app/app.go index dbff9be9..09618341 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -161,7 +161,8 @@ func (a App) Filters(appendServiceNames, exactMatch bool, services ...string) (f return filters, nil } - composeFiles, err := recipe.GetComposeFiles(a.Recipe, a.Env) + r := recipe.Get2(a.Recipe) + composeFiles, err := r.GetComposeFiles(a.Env) if err != nil { return filters, err } @@ -317,7 +318,8 @@ func GetAppServiceNames(appName string) ([]string, error) { return serviceNames, err } - composeFiles, err := recipe.GetComposeFiles(app.Recipe, app.Env) + r := recipe.Get2(app.Recipe) + composeFiles, err := r.GetComposeFiles(app.Env) if err != nil { return serviceNames, err } diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 3f32e985..23828143 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -85,7 +85,8 @@ func TestGetComposeFiles(t *testing.T) { } for _, test := range tests { - composeFiles, err := recipe.GetComposeFiles(r.Name, test.appEnv) + r2 := recipe.Get2(r.Name) + composeFiles, err := r2.GetComposeFiles(test.appEnv) if err != nil { t.Fatal(err) } @@ -106,7 +107,8 @@ func TestGetComposeFilesError(t *testing.T) { } for _, test := range tests { - _, err := recipe.GetComposeFiles(r.Name, test.appEnv) + r2 := recipe.Get2(r.Name) + _, err := r2.GetComposeFiles(test.appEnv) if err == nil { t.Fatalf("should have failed: %v", test.appEnv) } diff --git a/pkg/recipe/compose.go b/pkg/recipe/compose.go index 7e6384ba..6e7c9264 100644 --- a/pkg/recipe/compose.go +++ b/pkg/recipe/compose.go @@ -3,6 +3,7 @@ package recipe import ( "fmt" "io/ioutil" + "os" "path/filepath" "strings" @@ -14,6 +15,50 @@ import ( composetypes "github.com/docker/cli/cli/compose/types" ) +// GetComposeFiles gets the list of compose files for an app (or recipe if you +// don't already have an app) which should be merged into a composetypes.Config +// while respecting the COMPOSE_FILE env var. +func (r Recipe2) GetComposeFiles(appEnv map[string]string) ([]string, error) { + composeFileEnvVar, ok := appEnv["COMPOSE_FILE"] + if !ok { + if err := ensurePathExists(r.ComposePath); err != nil { + return []string{}, err + } + log.Debugf("no COMPOSE_FILE detected, loading default: %s", r.ComposePath) + return []string{r.ComposePath}, nil + } + + if !strings.Contains(composeFileEnvVar, ":") { + path := fmt.Sprintf("%s/%s", r.Dir, composeFileEnvVar) + if err := ensurePathExists(path); err != nil { + return []string{}, err + } + log.Debugf("COMPOSE_FILE detected, loading %s", path) + return []string{path}, nil + } + + var composeFiles []string + + numComposeFiles := strings.Count(composeFileEnvVar, ":") + 1 + envVars := strings.SplitN(composeFileEnvVar, ":", numComposeFiles) + if len(envVars) != numComposeFiles { + return composeFiles, fmt.Errorf("COMPOSE_FILE (=\"%s\") parsing failed?", composeFileEnvVar) + } + + for _, file := range envVars { + path := fmt.Sprintf("%s/%s", r.Dir, file) + if err := ensurePathExists(path); err != nil { + return composeFiles, err + } + composeFiles = append(composeFiles, path) + } + + log.Debugf("COMPOSE_FILE detected (%s), loading %s", composeFileEnvVar, strings.Join(envVars, ", ")) + log.Debugf("retrieved %s configs for %s", strings.Join(composeFiles, ", "), r.Name) + + return composeFiles, nil +} + // UpdateTag updates an image tag in-place on file system local compose files. func (r Recipe2) UpdateTag(image, tag string) (bool, error) { fullPattern := fmt.Sprintf("%s/compose**yml", r.Dir) @@ -74,7 +119,7 @@ func (r Recipe2) UpdateTag(image, tag string) (bool, error) { log.Debugf("updating %s to %s in %s", old, new, compose.Filename) - if err := ioutil.WriteFile(compose.Filename, []byte(replacedBytes), 0764); err != nil { + if err := os.WriteFile(compose.Filename, []byte(replacedBytes), 0764); err != nil { return false, err } } diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index 0010cd3a..46998d29 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -188,6 +188,7 @@ func Get2(name string) Recipe2 { Dir: dir, SSHURL: fmt.Sprintf(config.SSH_URL_TEMPLATE, name), + ComposePath: path.Join(dir, "compose.yml"), ReadmePath: path.Join(dir, "README.md"), SampleEnvPath: path.Join(dir, ".env.sample"), } @@ -198,6 +199,7 @@ type Recipe2 struct { Dir string SSHURL string + ComposePath string ReadmePath string SampleEnvPath string } @@ -776,50 +778,3 @@ func ensurePathExists(path string) error { } return nil } - -// GetComposeFiles gets the list of compose files for an app (or recipe if you -// don't already have an app) which should be merged into a composetypes.Config -// while respecting the COMPOSE_FILE env var. -func GetComposeFiles(recipe string, appEnv map[string]string) ([]string, error) { - var composeFiles []string - - composeFileEnvVar, ok := appEnv["COMPOSE_FILE"] - if !ok { - path := fmt.Sprintf("%s/%s/compose.yml", config.RECIPES_DIR, recipe) - if err := ensurePathExists(path); err != nil { - return composeFiles, err - } - log.Debugf("no COMPOSE_FILE detected, loading default: %s", path) - composeFiles = append(composeFiles, path) - return composeFiles, nil - } - - if !strings.Contains(composeFileEnvVar, ":") { - path := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, recipe, composeFileEnvVar) - if err := ensurePathExists(path); err != nil { - return composeFiles, err - } - log.Debugf("COMPOSE_FILE detected, loading %s", path) - composeFiles = append(composeFiles, path) - return composeFiles, nil - } - - numComposeFiles := strings.Count(composeFileEnvVar, ":") + 1 - envVars := strings.SplitN(composeFileEnvVar, ":", numComposeFiles) - if len(envVars) != numComposeFiles { - return composeFiles, fmt.Errorf("COMPOSE_FILE (=\"%s\") parsing failed?", composeFileEnvVar) - } - - for _, file := range envVars { - path := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, recipe, file) - if err := ensurePathExists(path); err != nil { - return composeFiles, err - } - composeFiles = append(composeFiles, path) - } - - log.Debugf("COMPOSE_FILE detected (%s), loading %s", composeFileEnvVar, strings.Join(envVars, ", ")) - log.Debugf("retrieved %s configs for %s", strings.Join(composeFiles, ", "), recipe) - - return composeFiles, nil -} diff --git a/pkg/secret/secret.go b/pkg/secret/secret.go index fd69508a..0f1d6d7b 100644 --- a/pkg/secret/secret.go +++ b/pkg/secret/secret.go @@ -246,7 +246,8 @@ type secretStatuses []secretStatus func PollSecretsStatus(cl *dockerClient.Client, app appPkg.App) (secretStatuses, error) { var secStats secretStatuses - composeFiles, err := recipe.GetComposeFiles(app.Recipe, app.Env) + r := recipe.Get2(app.Name) + composeFiles, err := r.GetComposeFiles(app.Env) if err != nil { return secStats, err }