WIP: minor improvements #397

Draft
wykwit wants to merge 7 commits from wykwit/abra:minor-improvements into main
16 changed files with 63 additions and 68 deletions

View File

@ -5,7 +5,6 @@ import (
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
Review

I think "coopcloud.tech/abra/pkg/recipe" should be the preferd way to import the package. Or is there a specific reason why you changed the import everywhere?

I think `"coopcloud.tech/abra/pkg/recipe"` should be the preferd way to import the package. Or is there a specific reason why you changed the import everywhere?
Review

I changed it wherever there was a double import, because in some places recipe can either be a variable or a package. It was used inconsistently within those source files, referring to the package sometimes as recipePkg and sometimes as just recipe which is additionally confusing when recipe is also used there as a common variable name. There are still some other places where the import is not renamed, but when the package name gets overshadowed it's not used anymore.

I changed it wherever there was a double import, because in some places `recipe` can either be a variable or a package. It was used inconsistently within those source files, referring to the package sometimes as `recipePkg` and sometimes as just `recipe` which is additionally confusing when `recipe` is also used there as a common variable name. There are still some other places where the import is not renamed, but when the package name gets overshadowed it's not used anymore.
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -38,7 +37,7 @@ ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if err := recipe.EnsureExists(app.Recipe); err != nil { if err := recipePkg.EnsureExists(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -68,9 +67,9 @@ ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
for _, envVar := range envVars { for _, envVar := range envVars {
if envVar.Present { if envVar.Present {
table.Append([]string{envVar.Name, "✅"}) table.Append([]string{envVar.Name, "✅ OK"})
} else { } else {
table.Append([]string{envVar.Name, "❌"}) table.Append([]string{envVar.Name, "❌ Missing"})
} }
} }

View File

@ -14,7 +14,6 @@ import (
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -60,7 +59,7 @@ Example:
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if err := recipe.EnsureExists(app.Recipe); err != nil { if err := recipePkg.EnsureExists(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -228,7 +227,7 @@ var appCmdListCommand = cli.Command{
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if err := recipe.EnsureExists(app.Recipe); err != nil { if err := recipePkg.EnsureExists(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -270,17 +270,17 @@ can take some time.
table.Render() table.Render()
if status { if status {
fmt.Println(fmt.Sprintf( fmt.Printf(
"server: %s | total apps: %v | versioned: %v | unversioned: %v | latest: %v | upgrade: %v", "server: %s | total apps: %v | versioned: %v | unversioned: %v | latest: %v | upgrade: %v\n",
app.Server, app.Server,
serverStat.AppCount, serverStat.AppCount,
serverStat.VersionCount, serverStat.VersionCount,
serverStat.UnversionedCount, serverStat.UnversionedCount,
serverStat.LatestCount, serverStat.LatestCount,
serverStat.UpgradeCount, serverStat.UpgradeCount,
)) )
} else { } else {
fmt.Println(fmt.Sprintf("server: %s | total apps: %v", app.Server, serverStat.AppCount)) fmt.Printf("server: %s | total apps: %v\n", app.Server, serverStat.AppCount)
} }
} }
@ -292,7 +292,7 @@ can take some time.
} }
if len(allStats) > 1 { if len(allStats) > 1 {
fmt.Println(fmt.Sprintf("total servers: %v | total apps: %v ", totalServersCount, totalAppsCount)) fmt.Printf("total servers: %v | total apps: %v\n", totalServersCount, totalAppsCount)
} }
return nil return nil

View File

@ -10,7 +10,6 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/jsontable" "coopcloud.tech/abra/pkg/jsontable"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/secret" "coopcloud.tech/abra/pkg/secret"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
@ -142,15 +141,15 @@ var appNewCommand = cli.Command{
table := formatter.CreateTable(tableCol) table := formatter.CreateTable(tableCol)
table.Append([]string{internal.NewAppServer, recipe.Name, internal.Domain}) table.Append([]string{internal.NewAppServer, recipe.Name, internal.Domain})
fmt.Println(fmt.Sprintf("A new %s app has been created! Here is an overview:", recipe.Name)) fmt.Printf("A new %s app has been created! Here is an overview:\n", recipe.Name)
fmt.Println("") fmt.Println("")
table.Render() table.Render()
fmt.Println("") fmt.Println("")
fmt.Println("You can configure this app by running the following:") fmt.Println("You can configure this app by running the following:")
fmt.Println(fmt.Sprintf("\n abra app config %s", internal.Domain)) fmt.Printf("\n abra app config %s\n", internal.Domain)
fmt.Println("") fmt.Println("")
fmt.Println("You can deploy this app by running the following:") fmt.Println("You can deploy this app by running the following:")
fmt.Println(fmt.Sprintf("\n abra app deploy %s", internal.Domain)) fmt.Printf("\n abra app deploy %s\n", internal.Domain)
if len(secrets) > 0 { if len(secrets) > 0 {
fmt.Println("") fmt.Println("")
@ -192,7 +191,7 @@ func createSecrets(cl *dockerClient.Client, secretsConfig map[string]secret.Secr
} }
// ensureDomainFlag checks if the domain flag was used. if not, asks the user for it/ // ensureDomainFlag checks if the domain flag was used. if not, asks the user for it/
func ensureDomainFlag(recipe recipe.Recipe, server string) error { func ensureDomainFlag(recipe recipePkg.Recipe, server string) error {
if internal.Domain == "" && !internal.NoInput { if internal.Domain == "" && !internal.NoInput {
prompt := &survey.Input{ prompt := &survey.Input{
Message: "Specify app domain", Message: "Specify app domain",

View File

@ -110,7 +110,7 @@ flag.
logrus.Fatal(err) logrus.Fatal(err)
} }
volumeListOptions := volume.ListOptions{fs} volumeListOptions := volume.ListOptions{Filters: fs}
volumeListOKBody, err := cl.VolumeList(context.Background(), volumeListOptions) volumeListOKBody, err := cl.VolumeList(context.Background(), volumeListOptions)
volumeList := volumeListOKBody.Volumes volumeList := volumeListOKBody.Volumes
if err != nil { if err != nil {

View File

@ -11,7 +11,6 @@ import (
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
containerPkg "coopcloud.tech/abra/pkg/container" containerPkg "coopcloud.tech/abra/pkg/container"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/upstream/container" "coopcloud.tech/abra/pkg/upstream/container"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
@ -60,7 +59,7 @@ Example:
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
recipe, err := recipe.Get(app.Recipe, internal.Offline) recipe, err := recipePkg.Get(app.Recipe, internal.Offline)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -9,7 +9,6 @@ import (
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/lint"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
stack "coopcloud.tech/abra/pkg/upstream/stack" stack "coopcloud.tech/abra/pkg/upstream/stack"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
@ -62,17 +61,17 @@ recipes.
} }
if !internal.Chaos { if !internal.Chaos {
if err := recipe.EnsureIsClean(app.Recipe); err != nil { if err := recipePkg.EnsureIsClean(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
if !internal.Offline { if !internal.Offline {
if err := recipe.EnsureUpToDate(app.Recipe); err != nil { if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
} }
if err := recipe.EnsureLatest(app.Recipe); err != nil { if err := recipePkg.EnsureLatest(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
} }

View File

@ -80,29 +80,26 @@ Example:
switch shellType { switch shellType {
case "bash": case "bash":
fmt.Println(fmt.Sprintf(` fmt.Printf(`# Run the following commands to install auto-completion
# Run the following commands to install auto-completion
sudo mkdir /etc/bash_completion.d/ sudo mkdir /etc/bash_completion.d/
sudo cp %s /etc/bash_completion.d/abra sudo cp %s /etc/bash_completion.d/abra
echo "source /etc/bash_completion.d/abra" >> ~/.bashrc echo "source /etc/bash_completion.d/abra" >> ~/.bashrc
# To test, run the following: "abra app <hit tab key>" - you should see command completion! # To test, run the following: "abra app <hit tab key>" - you should see command completion!
`, autocompletionFile)) `, autocompletionFile)
case "zsh": case "zsh":
fmt.Println(fmt.Sprintf(` fmt.Printf(`# Run the following commands to install auto-completion
# Run the following commands to install auto-completion
sudo mkdir /etc/zsh/completion.d/ sudo mkdir /etc/zsh/completion.d/
sudo cp %s /etc/zsh/completion.d/abra sudo cp %s /etc/zsh/completion.d/abra
echo "PROG=abra\n_CLI_ZSH_AUTOCOMPLETE_HACK=1\nsource /etc/zsh/completion.d/abra" >> ~/.zshrc echo "PROG=abra\n_CLI_ZSH_AUTOCOMPLETE_HACK=1\nsource /etc/zsh/completion.d/abra" >> ~/.zshrc
# To test, run the following: "abra app <hit tab key>" - you should see command completion! # To test, run the following: "abra app <hit tab key>" - you should see command completion!
`, autocompletionFile)) `, autocompletionFile)
case "fish": case "fish":
fmt.Println(fmt.Sprintf(` fmt.Printf(`# Run the following commands to install auto-completion
# Run the following commands to install auto-completion
sudo mkdir -p /etc/fish/completions sudo mkdir -p /etc/fish/completions
sudo cp %s /etc/fish/completions/abra sudo cp %s /etc/fish/completions/abra
echo "source /etc/fish/completions/abra" >> ~/.config/fish/config.fish echo "source /etc/fish/completions/abra" >> ~/.config/fish/config.fish
# To test, run the following: "abra app <hit tab key>" - you should see command completion! # To test, run the following: "abra app <hit tab key>" - you should see command completion!
`, autocompletionFile)) `, autocompletionFile)
} }
return nil return nil
@ -117,6 +114,10 @@ var UpgradeCommand = cli.Command{
Description: ` Description: `
Upgrade Abra in-place with the latest stable or release candidate. Upgrade Abra in-place with the latest stable or release candidate.
This command uses wget and bash. The install script is pulled from:
- default stable release: https://install.abra.coopcloud.tech
- release candidate: https://git.coopcloud.tech/coop-cloud/abra/
Pass "-r/--rc" to install the latest release candidate. Please bear in mind Pass "-r/--rc" to install the latest release candidate. Please bear in mind
that it may contain catastrophic bugs. Thank you very much for the testing that it may contain catastrophic bugs. Thank you very much for the testing
efforts! efforts!

View File

@ -162,7 +162,7 @@ var NewAppServer string
var NewAppServerFlag = &cli.StringFlag{ var NewAppServerFlag = &cli.StringFlag{
Name: "server, s", Name: "server, s",
Value: "", Value: "",
Usage: "Show apps of a specific server", Usage: "Use a specific server",
Destination: &NewAppServer, Destination: &NewAppServer,
} }

View File

@ -40,7 +40,7 @@ Here is a semver cheat sheet (more on https://semver.org):
var chosenBumpType string var chosenBumpType string
prompt := &survey.Select{ prompt := &survey.Select{
Message: fmt.Sprintf("select recipe version increment type"), Message: "select recipe version increment type",
Options: []string{"major", "minor", "patch"}, Options: []string{"major", "minor", "patch"},
} }

View File

@ -103,7 +103,7 @@ recipe and domain in the sample environment config).
logrus.Fatal(err) logrus.Fatal(err)
} }
fmt.Print(fmt.Sprintf(` fmt.Printf(`
Your new %s recipe has been created in %s. Your new %s recipe has been created in %s.
In order to share your recipe, you can upload it the git repository to: In order to share your recipe, you can upload it the git repository to:
@ -118,7 +118,7 @@ See "abra recipe -h" for additional recipe maintainer commands.
Happy Hacking! Happy Hacking!
`, recipeName, path.Join(config.RECIPES_DIR, recipeName), recipeName)) `, recipeName, path.Join(config.RECIPES_DIR, recipeName), recipeName)
return nil return nil
}, },

View File

@ -68,7 +68,7 @@ local file system.
if internal.NoInput { if internal.NoInput {
logrus.Fatalf("unable to continue, input required for initial version") logrus.Fatalf("unable to continue, input required for initial version")
} }
fmt.Println(fmt.Sprintf(` fmt.Printf(`
The following options are two types of initial semantic version that you can The following options are two types of initial semantic version that you can
pick for %s that will be published in the recipe catalogue. This follows the pick for %s that will be published in the recipe catalogue. This follows the
semver convention (more on https://semver.org), here is a short cheatsheet semver convention (more on https://semver.org), here is a short cheatsheet
@ -85,7 +85,7 @@ If you want people to be able alpha test your current config for %s but don't
think it is quite reliable, go with 0.1.0 and people will know that things are think it is quite reliable, go with 0.1.0 and people will know that things are
likely to change. likely to change.
`, recipe.Name, recipe.Name)) `, recipe.Name, recipe.Name)
var chosenVersion string var chosenVersion string
edPrompt := &survey.Select{ edPrompt := &survey.Select{
Message: "which version do you want to begin with?", Message: "which version do you want to begin with?",

View File

@ -9,7 +9,7 @@ import (
) )
func GetVolumes(cl *client.Client, ctx context.Context, server string, fs filters.Args) ([]*volume.Volume, error) { func GetVolumes(cl *client.Client, ctx context.Context, server string, fs filters.Args) ([]*volume.Volume, error) {
volumeListOptions := volume.ListOptions{fs} volumeListOptions := volume.ListOptions{Filters: fs}
volumeListOKBody, err := cl.VolumeList(ctx, volumeListOptions) volumeListOKBody, err := cl.VolumeList(ctx, volumeListOptions)
volumeList := volumeListOKBody.Volumes volumeList := volumeListOKBody.Volumes
if err != nil { if err != nil {

View File

@ -6,7 +6,7 @@ type Limiter struct{ sem chan struct{} }
// New returns a new Limiter. The limit param is the maximum number of // New returns a new Limiter. The limit param is the maximum number of
// concurrent operations. // concurrent operations.
func New(limit int) *Limiter { func New(limit int) *Limiter {
return &Limiter{make(chan struct{}, limit)} return &Limiter{sem: make(chan struct{}, limit)}
} }
// Begin an operation. // Begin an operation.

View File

@ -7,7 +7,6 @@ import (
"path" "path"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
@ -19,13 +18,13 @@ import (
var Warn = "warn" var Warn = "warn"
var Critical = "critical" var Critical = "critical"
type LintFunction func(recipe.Recipe) (bool, error) type LintFunction func(recipePkg.Recipe) (bool, error)
// SkipFunction determines whether the LintFunction is run or not. It should // SkipFunction determines whether the LintFunction is run or not. It should
// not take the lint rule level into account because some rules are always an // not take the lint rule level into account because some rules are always an
// error but may depend on some additional context of the recipe configuration. // error but may depend on some additional context of the recipe configuration.
// This function aims to cover those additional cases. // This function aims to cover those additional cases.
type SkipFunction func(recipe.Recipe) (bool, error) type SkipFunction func(recipePkg.Recipe) (bool, error)
// LintRule is a linting rule which helps a recipe maintainer avoid common // LintRule is a linting rule which helps a recipe maintainer avoid common
// problems in their recipe configurations. We aim to highlight things that // problems in their recipe configurations. We aim to highlight things that
@ -42,7 +41,7 @@ type LintRule struct {
} }
// Skip implements the SkipFunction for the lint rule. // Skip implements the SkipFunction for the lint rule.
func (l LintRule) Skip(recipe recipe.Recipe) bool { func (l LintRule) Skip(recipe recipePkg.Recipe) bool {
if l.SkipCondition != nil { if l.SkipCondition != nil {
ok, err := l.SkipCondition(recipe) ok, err := l.SkipCondition(recipe)
if err != nil { if err != nil {
@ -166,7 +165,7 @@ var LintRules = map[string][]LintRule{
// LintForErrors lints specifically for errors and not other levels. This is // LintForErrors lints specifically for errors and not other levels. This is
// used in code paths such as "app deploy" to avoid nasty surprises but not for // used in code paths such as "app deploy" to avoid nasty surprises but not for
// the typical linting commands, which do handle other levels. // the typical linting commands, which do handle other levels.
func LintForErrors(recipe recipe.Recipe) error { func LintForErrors(recipe recipePkg.Recipe) error {
logrus.Debugf("linting for critical errors in %s configs", recipe.Name) logrus.Debugf("linting for critical errors in %s configs", recipe.Name)
for level := range LintRules { for level := range LintRules {
@ -194,7 +193,7 @@ func LintForErrors(recipe recipe.Recipe) error {
return nil return nil
} }
func LintComposeVersion(recipe recipe.Recipe) (bool, error) { func LintComposeVersion(recipe recipePkg.Recipe) (bool, error) {
if recipe.Config.Version == "3.8" { if recipe.Config.Version == "3.8" {
return true, nil return true, nil
} }
@ -202,7 +201,7 @@ func LintComposeVersion(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintEnvConfigPresent(recipe recipe.Recipe) (bool, error) { func LintEnvConfigPresent(recipe recipePkg.Recipe) (bool, error) {
envSample := fmt.Sprintf("%s/%s/.env.sample", config.RECIPES_DIR, recipe.Name) envSample := fmt.Sprintf("%s/%s/.env.sample", config.RECIPES_DIR, recipe.Name)
if _, err := os.Stat(envSample); !os.IsNotExist(err) { if _, err := os.Stat(envSample); !os.IsNotExist(err) {
return true, nil return true, nil
@ -211,7 +210,7 @@ func LintEnvConfigPresent(recipe recipe.Recipe) (bool, error) {
return false, nil return false, nil
} }
func LintAppService(recipe recipe.Recipe) (bool, error) { func LintAppService(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
if service.Name == "app" { if service.Name == "app" {
return true, nil return true, nil
@ -225,7 +224,7 @@ func LintAppService(recipe recipe.Recipe) (bool, error) {
// confirms that there is no "DOMAIN=..." in the .env.sample configuration of // confirms that there is no "DOMAIN=..." in the .env.sample configuration of
// the recipe. This typically means that no domain is required to deploy and // the recipe. This typically means that no domain is required to deploy and
// therefore no matching traefik deploy label will be present. // therefore no matching traefik deploy label will be present.
func LintTraefikEnabledSkipCondition(recipe recipe.Recipe) (bool, error) { func LintTraefikEnabledSkipCondition(recipe recipePkg.Recipe) (bool, error) {
envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample") envSamplePath := path.Join(config.RECIPES_DIR, recipe.Name, ".env.sample")
sampleEnv, err := config.ReadEnv(envSamplePath) sampleEnv, err := config.ReadEnv(envSamplePath)
if err != nil { if err != nil {
@ -239,7 +238,7 @@ func LintTraefikEnabledSkipCondition(recipe recipe.Recipe) (bool, error) {
return false, nil return false, nil
} }
func LintTraefikEnabled(recipe recipe.Recipe) (bool, error) { func LintTraefikEnabled(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
for label := range service.Deploy.Labels { for label := range service.Deploy.Labels {
if label == "traefik.enable" { if label == "traefik.enable" {
@ -253,7 +252,7 @@ func LintTraefikEnabled(recipe recipe.Recipe) (bool, error) {
return false, nil return false, nil
} }
func LintHealthchecks(recipe recipe.Recipe) (bool, error) { func LintHealthchecks(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
if service.HealthCheck == nil { if service.HealthCheck == nil {
return false, nil return false, nil
@ -263,7 +262,7 @@ func LintHealthchecks(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintAllImagesTagged(recipe recipe.Recipe) (bool, error) { func LintAllImagesTagged(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
img, err := reference.ParseNormalizedNamed(service.Image) img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil { if err != nil {
@ -277,7 +276,7 @@ func LintAllImagesTagged(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintNoUnstableTags(recipe recipe.Recipe) (bool, error) { func LintNoUnstableTags(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
img, err := reference.ParseNormalizedNamed(service.Image) img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil { if err != nil {
@ -300,7 +299,7 @@ func LintNoUnstableTags(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintSemverLikeTags(recipe recipe.Recipe) (bool, error) { func LintSemverLikeTags(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
img, err := reference.ParseNormalizedNamed(service.Image) img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil { if err != nil {
@ -323,7 +322,7 @@ func LintSemverLikeTags(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintImagePresent(recipe recipe.Recipe) (bool, error) { func LintImagePresent(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
if service.Image == "" { if service.Image == "" {
return false, nil return false, nil
@ -332,7 +331,7 @@ func LintImagePresent(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintHasPublishedVersion(recipe recipe.Recipe) (bool, error) { func LintHasPublishedVersion(recipe recipePkg.Recipe) (bool, error) {
catl, err := recipePkg.ReadRecipeCatalogue(false) catl, err := recipePkg.ReadRecipeCatalogue(false)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
@ -350,8 +349,8 @@ func LintHasPublishedVersion(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintMetadataFilledIn(r recipe.Recipe) (bool, error) { func LintMetadataFilledIn(recipe recipePkg.Recipe) (bool, error) {
features, category, err := recipe.GetRecipeFeaturesAndCategory(r.Name) features, category, err := recipePkg.GetRecipeFeaturesAndCategory(recipe.Name)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -371,7 +370,7 @@ func LintMetadataFilledIn(r recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintAbraShVendors(recipe recipe.Recipe) (bool, error) { func LintAbraShVendors(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services { for _, service := range recipe.Config.Services {
if len(service.Configs) > 0 { if len(service.Configs) > 0 {
abraSh := path.Join(config.RECIPES_DIR, recipe.Name, "abra.sh") abraSh := path.Join(config.RECIPES_DIR, recipe.Name, "abra.sh")
@ -386,7 +385,7 @@ func LintAbraShVendors(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintHasRecipeRepo(recipe recipe.Recipe) (bool, error) { func LintHasRecipeRepo(recipe recipePkg.Recipe) (bool, error) {
url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipe.Name) url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipe.Name)
res, err := http.Get(url) res, err := http.Get(url)
@ -401,7 +400,7 @@ func LintHasRecipeRepo(recipe recipe.Recipe) (bool, error) {
return true, nil return true, nil
} }
func LintValidTags(recipe recipe.Recipe) (bool, error) { func LintValidTags(recipe recipePkg.Recipe) (bool, error) {
recipeDir := path.Join(config.RECIPES_DIR, recipe.Name) recipeDir := path.Join(config.RECIPES_DIR, recipe.Name)
repo, err := git.PlainOpen(recipeDir) repo, err := git.PlainOpen(recipeDir)

View File

@ -66,19 +66,19 @@ func GetDeployedServicesByLabel(cl *dockerClient.Client, contextName string, lab
filters.Add("label", label) filters.Add("label", label)
services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: filters}) services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: filters})
if err != nil { if err != nil {
return StackStatus{[]swarm.Service{}, err} return StackStatus{Services: []swarm.Service{}, Err: err}
} }
return StackStatus{services, nil} return StackStatus{Services: services, Err: nil}
} }
func GetAllDeployedServices(cl *dockerClient.Client, contextName string) StackStatus { func GetAllDeployedServices(cl *dockerClient.Client, contextName string) StackStatus {
services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: getAllStacksFilter()}) services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: getAllStacksFilter()})
if err != nil { if err != nil {
return StackStatus{[]swarm.Service{}, err} return StackStatus{Services: []swarm.Service{}, Err: err}
} }
return StackStatus{services, nil} return StackStatus{Services: services, Err: nil}
} }
// GetDeployedServicesByName filters services by name // GetDeployedServicesByName filters services by name
@ -88,10 +88,10 @@ func GetDeployedServicesByName(ctx context.Context, cl *dockerClient.Client, sta
services, err := cl.ServiceList(ctx, types.ServiceListOptions{Filters: filters}) services, err := cl.ServiceList(ctx, types.ServiceListOptions{Filters: filters})
if err != nil { if err != nil {
return StackStatus{[]swarm.Service{}, err} return StackStatus{Services: []swarm.Service{}, Err: err}
} }
return StackStatus{services, nil} return StackStatus{Services: services, Err: nil}
} }
// IsDeployed chekcks whether an appp is deployed or not. // IsDeployed chekcks whether an appp is deployed or not.