<commit_before>package cmd

import (
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/jakubknejzlik/kontena-git-cli/kontena"
	"github.com/jakubknejzlik/kontena-git-cli/model"
	"github.com/jakubknejzlik/kontena-git-cli/utils"

	"github.com/urfave/cli"
)

// GridCommand ...
func GridCommand() cli.Command {
	return cli.Command{
		Name: "grid",
		Subcommands: []cli.Command{
			gridInstallCommand(),
			gridDeployCommand(),
		},
	}
}

func gridInstallCommand() cli.Command {
	return cli.Command{
		Name:      "install",
		ArgsUsage: "GRID",
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "deploy",
				Usage: "automatically deploy all services",
			},
		},
		Action: func(c *cli.Context) error {
			client := kontena.Client{}
			grid := c.Args().First()

			if err := client.EnsureMasterLogin(); err != nil {
				return cli.NewExitError(err, 1)
			}

			if grid == "" {
				return cli.NewExitError("GRID argument not specified", 1)
			}

			if err := client.GridUse(grid); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installCertificatesCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installCoreCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installRegistriesCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := pruneStacksCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installOrUpgradeStacksCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if c.Bool("deploy") {
				if err := deployStacksCommand().Run(c); err != nil {
					return cli.NewExitError(err, 1)
				}
			}

			return nil
		},
	}
}

func gridDeployCommand() cli.Command {
	return cli.Command{
		Name:        "deploy",
		ArgsUsage:   "GRID",
		Description: "Deploy all stacks in grid",
		Action: func(c *cli.Context) error {
			client := kontena.Client{}
			grid := c.Args().First()

			if err := client.EnsureMasterLogin(); err != nil {
				return cli.NewExitError(err, 1)
			}

			if grid == "" {
				return cli.NewExitError("GRID argument not specified", 1)
			}

			if err := client.GridUse(grid); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := deployStacksCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			return nil
		},
	}
}

func installOrUpgradeStacksCommand() cli.Command {
	return cli.Command{
		Name: "stacks",
		Action: func(c *cli.Context) error {
			utils.LogSection("Installing/upgrading stacks")
			client := kontena.Client{}

			stacks, _ := ioutil.ReadDir("./stacks")
			for _, stack := range stacks {
				stackName := stack.Name()
				if err := client.SecretsImport(stackName, fmt.Sprintf("./stacks/%s/secrets.yml", stackName)); err != nil {
					return cli.NewExitError(err, 1)
				}
				if !client.StackExists(stackName) {
					utils.Log("installing stack", stackName)
					dc, stackErr := getStackFromGrid(stackName)
					if stackErr != nil {
						dc = getDefaultStack(stackName, client.SecretExists("VIRTUAL_HOSTS", stackName))
					}

					if err := client.StackInstall(dc); err != nil {
						return cli.NewExitError(err, 1)
					}
				} else {
					if stack, err := getStackFromGrid(stackName); err == nil {
						utils.Log("upgrading stack", stackName)
						if err := client.StackUpgrade(stack); err != nil {
							return cli.NewExitError(err, 1)
						}
					}
				}
				time.Sleep(time.Second * 1)
			}
			return nil
		},
	}
}

func deployStacksCommand() cli.Command {
	return cli.Command{
		Name: "stacks",
		Action: func(c *cli.Context) error {
			utils.LogSection("Deploying stacks")
			client := kontena.Client{}

			stacks, _ := ioutil.ReadDir("./stacks")
			for _, stack := range stacks {
				stackName := stack.Name()

				utils.Log("deploying stack", stackName)
				if err := client.StackDeploy(stackName); err != nil {
					return cli.NewExitError(err, 1)
				}
			}
			return nil
		},
	}
}

func getStackFromGrid(name string) (model.KontenaStack, error) {
	var k model.KontenaStack
	stackConfigPath := fmt.Sprintf("./stacks/%s/kontena.yml", name)
	if _, err := os.Stat(stackConfigPath); err != nil {
		return k, err
	}
	return model.KontenaLoad(stackConfigPath)
}

func getDefaultStack(name string, hasHost bool) model.KontenaStack {
	secrets := []model.KontenaSecret{}
	links := []string{}

	if hasHost {
		hostSecret := model.KontenaSecret{
			Secret: "VIRTUAL_HOSTS",
			Name:   "KONTENA_LB_VIRTUAL_HOSTS",
			Type:   "env",
		}
		secrets = append(secrets, hostSecret)
		links = append(links, "core/internet_lb")
	}

	return model.KontenaStack{
		Name:    name,
		Version: "0.0.1",
		Services: map[string]model.KontenaService{
			"web": model.KontenaService{
				Image:   "ksdn117/test-page",
				Links:   links,
				Secrets: secrets,
			},
		},
	}
}
<commit_msg>Update grid install order<commit_after>package cmd

import (
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/jakubknejzlik/kontena-git-cli/kontena"
	"github.com/jakubknejzlik/kontena-git-cli/model"
	"github.com/jakubknejzlik/kontena-git-cli/utils"

	"github.com/urfave/cli"
)

// GridCommand ...
func GridCommand() cli.Command {
	return cli.Command{
		Name: "grid",
		Subcommands: []cli.Command{
			gridInstallCommand(),
			gridDeployCommand(),
		},
	}
}

func gridInstallCommand() cli.Command {
	return cli.Command{
		Name:      "install",
		ArgsUsage: "GRID",
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "deploy",
				Usage: "automatically deploy all services",
			},
		},
		Action: func(c *cli.Context) error {
			client := kontena.Client{}
			grid := c.Args().First()

			if err := client.EnsureMasterLogin(); err != nil {
				return cli.NewExitError(err, 1)
			}

			if grid == "" {
				return cli.NewExitError("GRID argument not specified", 1)
			}

			if err := client.GridUse(grid); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installCoreCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installCertificatesCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installRegistriesCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := pruneStacksCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := installOrUpgradeStacksCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			if c.Bool("deploy") {
				if err := deployStacksCommand().Run(c); err != nil {
					return cli.NewExitError(err, 1)
				}
			}

			return nil
		},
	}
}

func gridDeployCommand() cli.Command {
	return cli.Command{
		Name:        "deploy",
		ArgsUsage:   "GRID",
		Description: "Deploy all stacks in grid",
		Action: func(c *cli.Context) error {
			client := kontena.Client{}
			grid := c.Args().First()

			if err := client.EnsureMasterLogin(); err != nil {
				return cli.NewExitError(err, 1)
			}

			if grid == "" {
				return cli.NewExitError("GRID argument not specified", 1)
			}

			if err := client.GridUse(grid); err != nil {
				return cli.NewExitError(err, 1)
			}

			if err := deployStacksCommand().Run(c); err != nil {
				return cli.NewExitError(err, 1)
			}

			return nil
		},
	}
}

func installOrUpgradeStacksCommand() cli.Command {
	return cli.Command{
		Name: "stacks",
		Action: func(c *cli.Context) error {
			utils.LogSection("Installing/upgrading stacks")
			client := kontena.Client{}

			stacks, _ := ioutil.ReadDir("./stacks")
			for _, stack := range stacks {
				stackName := stack.Name()
				if err := client.SecretsImport(stackName, fmt.Sprintf("./stacks/%s/secrets.yml", stackName)); err != nil {
					return cli.NewExitError(err, 1)
				}
				if !client.StackExists(stackName) {
					utils.Log("installing stack", stackName)
					dc, stackErr := getStackFromGrid(stackName)
					if stackErr != nil {
						dc = getDefaultStack(stackName, client.SecretExists("VIRTUAL_HOSTS", stackName))
					}

					if err := client.StackInstall(dc); err != nil {
						return cli.NewExitError(err, 1)
					}
				} else {
					if stack, err := getStackFromGrid(stackName); err == nil {
						utils.Log("upgrading stack", stackName)
						if err := client.StackUpgrade(stack); err != nil {
							return cli.NewExitError(err, 1)
						}
					}
				}
				time.Sleep(time.Second * 1)
			}
			return nil
		},
	}
}

func deployStacksCommand() cli.Command {
	return cli.Command{
		Name: "stacks",
		Action: func(c *cli.Context) error {
			utils.LogSection("Deploying stacks")
			client := kontena.Client{}

			stacks, _ := ioutil.ReadDir("./stacks")
			for _, stack := range stacks {
				stackName := stack.Name()

				utils.Log("deploying stack", stackName)
				if err := client.StackDeploy(stackName); err != nil {
					return cli.NewExitError(err, 1)
				}
			}
			return nil
		},
	}
}

func getStackFromGrid(name string) (model.KontenaStack, error) {
	var k model.KontenaStack
	stackConfigPath := fmt.Sprintf("./stacks/%s/kontena.yml", name)
	if _, err := os.Stat(stackConfigPath); err != nil {
		return k, err
	}
	return model.KontenaLoad(stackConfigPath)
}

func getDefaultStack(name string, hasHost bool) model.KontenaStack {
	secrets := []model.KontenaSecret{}
	links := []string{}

	if hasHost {
		hostSecret := model.KontenaSecret{
			Secret: "VIRTUAL_HOSTS",
			Name:   "KONTENA_LB_VIRTUAL_HOSTS",
			Type:   "env",
		}
		secrets = append(secrets, hostSecret)
		links = append(links, "core/internet_lb")
	}

	return model.KontenaStack{
		Name:    name,
		Version: "0.0.1",
		Services: map[string]model.KontenaService{
			"web": model.KontenaService{
				Image:   "ksdn117/test-page",
				Links:   links,
				Secrets: secrets,
			},
		},
	}
}

{'fraction_non_alphanumeric': 0.1495540344326903, 'fraction_numerical': 0.004978220286247666, 'mean_word_length': 3.1493115318416525, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4378411', 'n_tokens_mistral': 4184, 'n_tokens_neox': 3461, 'n_words': 723}