package internal import ( "fmt" "os" "strings" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" "github.com/AlecAivazis/survey/v2" dockerClient "github.com/docker/docker/client" ) // NewVersionOverview shows an upgrade or downgrade overview func NewVersionOverview(app appPkg.App, currentVersion, chaosVersion, newVersion, releaseNotes string) error { tableCol := []string{"server", "recipe", "config", "domain", "version", "chaos", "to deploy"} table := formatter.CreateTable(tableCol) deployConfig := "compose.yml" if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { deployConfig = strings.Join(strings.Split(composeFiles, ":"), "\n") } server := app.Server if app.Server == "default" { server = "local" } table.Append([]string{ server, app.Recipe.Name, deployConfig, app.Domain, currentVersion, chaosVersion, newVersion, }) table.Render() if releaseNotes != "" && newVersion != "" { fmt.Println() fmt.Print(releaseNotes) } else { log.Warnf("no release notes available for %s", newVersion) } if NoInput { return nil } response := false prompt := &survey.Confirm{ Message: "continue with deployment?", } if err := survey.AskOne(prompt, &response); err != nil { return err } if !response { log.Fatal("exiting as requested") } return nil } // PostCmds parses a string of commands and executes them inside of the respective services // the commands string must have the following format: // " | |... " func PostCmds(cl *dockerClient.Client, app appPkg.App, commands string) error { if _, err := os.Stat(app.Recipe.AbraShPath); err != nil { if os.IsNotExist(err) { return fmt.Errorf(fmt.Sprintf("%s does not exist for %s?", app.Recipe.AbraShPath, app.Name)) } return err } for _, command := range strings.Split(commands, "|") { commandParts := strings.Split(command, " ") if len(commandParts) < 2 { return fmt.Errorf(fmt.Sprintf("not enough arguments: %s", command)) } targetServiceName := commandParts[0] cmdName := commandParts[1] parsedCmdArgs := "" if len(commandParts) > 2 { parsedCmdArgs = fmt.Sprintf("%s ", strings.Join(commandParts[2:], " ")) } log.Infof("running post-command '%s %s' in container %s", cmdName, parsedCmdArgs, targetServiceName) if err := EnsureCommand(app.Recipe.AbraShPath, app.Recipe.Name, cmdName); err != nil { return err } serviceNames, err := appPkg.GetAppServiceNames(app.Name) if err != nil { return err } matchingServiceName := false for _, serviceName := range serviceNames { if serviceName == targetServiceName { matchingServiceName = true } } if !matchingServiceName { return fmt.Errorf(fmt.Sprintf("no service %s for %s?", targetServiceName, app.Name)) } log.Debugf("running command %s %s within the context of %s_%s", cmdName, parsedCmdArgs, app.StackName(), targetServiceName) Tty = true if err := RunCmdRemote(cl, app, app.Recipe.AbraShPath, targetServiceName, cmdName, parsedCmdArgs); err != nil { return err } } return nil } // DeployOverview shows a deployment overview func DeployOverview(app appPkg.App, version, chaosVersion, message string) error { tableCol := []string{"server", "recipe", "config", "domain", "version", "chaos"} table := formatter.CreateTable(tableCol) deployConfig := "compose.yml" if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { deployConfig = strings.Join(strings.Split(composeFiles, ":"), "\n") } server := app.Server if app.Server == "default" { server = "local" } table.Append([]string{ server, app.Recipe.Name, deployConfig, app.Domain, version, chaosVersion, }) table.Render() if NoInput { return nil } response := false prompt := &survey.Confirm{ Message: message, } if err := survey.AskOne(prompt, &response); err != nil { return err } if !response { log.Fatal("exiting as requested") } return nil }