Compare commits

..
10 Commits
43 changed files with 199 additions and 335 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ steps:
event: tag
- name: release
image: goreleaser/goreleaser:v1.24.0
image: goreleaser/goreleaser:v1.18.2
environment:
GITEA_TOKEN:
from_secret: goreleaser_gitea_token
+6
View File
@@ -51,6 +51,12 @@ builds:
- "-X 'main.Commit={{ .Commit }}'"
- "-X 'main.Version={{ .Version }}'"
archives:
- replacements:
386: i386
amd64: x86_64
format: binary
checksum:
name_template: "checksums.txt"
+3 -4
View File
@@ -5,7 +5,6 @@ import (
"coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus"
"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 {
app := internal.ValidateApp(c)
if err := recipe.EnsureExists(app.Recipe); err != nil {
if err := recipePkg.EnsureExists(app.Recipe); err != nil {
logrus.Fatal(err)
}
@@ -68,9 +67,9 @@ ${FOO:<default>} syntax). "check" does not confirm or deny this for you.`,
for _, envVar := range envVars {
if envVar.Present {
table.Append([]string{envVar.Name, "✅"})
table.Append([]string{envVar.Name, "✅ OK"})
} else {
table.Append([]string{envVar.Name, "❌"})
table.Append([]string{envVar.Name, "❌ Missing"})
}
}
+2 -3
View File
@@ -14,7 +14,6 @@ import (
"coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@@ -60,7 +59,7 @@ Example:
Action: func(c *cli.Context) error {
app := internal.ValidateApp(c)
if err := recipe.EnsureExists(app.Recipe); err != nil {
if err := recipePkg.EnsureExists(app.Recipe); err != nil {
logrus.Fatal(err)
}
@@ -228,7 +227,7 @@ var appCmdListCommand = cli.Command{
Action: func(c *cli.Context) error {
app := internal.ValidateApp(c)
if err := recipe.EnsureExists(app.Recipe); err != nil {
if err := recipePkg.EnsureExists(app.Recipe); err != nil {
logrus.Fatal(err)
}
+5 -5
View File
@@ -270,17 +270,17 @@ can take some time.
table.Render()
if status {
fmt.Println(fmt.Sprintf(
"server: %s | total apps: %v | versioned: %v | unversioned: %v | latest: %v | upgrade: %v",
fmt.Printf(
"server: %s | total apps: %v | versioned: %v | unversioned: %v | latest: %v | upgrade: %v\n",
app.Server,
serverStat.AppCount,
serverStat.VersionCount,
serverStat.UnversionedCount,
serverStat.LatestCount,
serverStat.UpgradeCount,
))
)
} 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 {
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
+9 -24
View File
@@ -10,7 +10,6 @@ import (
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/jsontable"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/secret"
"github.com/AlecAivazis/survey/v2"
@@ -54,17 +53,9 @@ var appNewCommand = cli.Command{
internal.OfflineFlag,
internal.ChaosFlag,
},
Before: internal.SubCommandBefore,
ArgsUsage: "[<recipe>] [<version>]",
BashComplete: func(ctx *cli.Context) {
args := ctx.Args()
switch len(args) {
case 0:
autocomplete.RecipeNameComplete(ctx)
case 1:
autocomplete.RecipeVersionComplete(ctx.Args().Get(0))
}
},
Before: internal.SubCommandBefore,
ArgsUsage: "[<recipe>]",
BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipe(c)
@@ -77,14 +68,8 @@ var appNewCommand = cli.Command{
logrus.Fatal(err)
}
}
if c.Args().Get(1) == "" {
if err := recipePkg.EnsureLatest(recipe.Name); err != nil {
logrus.Fatal(err)
}
} else {
if err := recipePkg.EnsureVersion(recipe.Name, c.Args().Get(1)); err != nil {
logrus.Fatal(err)
}
if err := recipePkg.EnsureLatest(recipe.Name); err != nil {
logrus.Fatal(err)
}
}
@@ -156,15 +141,15 @@ var appNewCommand = cli.Command{
table := formatter.CreateTable(tableCol)
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("")
table.Render()
fmt.Println("")
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("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 {
fmt.Println("")
@@ -206,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/
func ensureDomainFlag(recipe recipe.Recipe, server string) error {
func ensureDomainFlag(recipe recipePkg.Recipe, server string) error {
if internal.Domain == "" && !internal.NoInput {
prompt := &survey.Input{
Message: "Specify app domain",
+3 -25
View File
@@ -3,9 +3,7 @@ package app
import (
"context"
"fmt"
"log"
"os"
"time"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete"
@@ -112,7 +110,7 @@ flag.
logrus.Fatal(err)
}
volumeListOptions := volume.ListOptions{fs}
volumeListOptions := volume.ListOptions{Filters: fs}
volumeListOKBody, err := cl.VolumeList(context.Background(), volumeListOptions)
volumeList := volumeListOKBody.Volumes
if err != nil {
@@ -126,11 +124,9 @@ flag.
if len(vols) > 0 {
for _, vol := range vols {
err = retryFunc(5, func() error {
return cl.VolumeRemove(context.Background(), vol, internal.Force) // last argument is for force removing
})
err := cl.VolumeRemove(context.Background(), vol, internal.Force) // last argument is for force removing
if err != nil {
log.Fatalf("removing volumes failed: %s", err)
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("volume %s removed", vol))
}
@@ -147,21 +143,3 @@ flag.
return nil
},
}
// retryFunc retries the given function for the given retries. After the nth
// retry it waits (n + 1)^2 seconds before the next retry (starting with n=0).
// It returns an error if the function still failed after the last retry.
func retryFunc(retries int, fn func() error) error {
for i := 0; i < retries; i++ {
err := fn()
if err == nil {
return nil
}
if i+1 < retries {
sleep := time.Duration(i+1) * time.Duration(i+1)
logrus.Infof("%s: waiting %d seconds before next retry", err, sleep)
time.Sleep(sleep * time.Second)
}
}
return fmt.Errorf("%d retries failed", retries)
}
-26
View File
@@ -1,26 +0,0 @@
package app
import (
"fmt"
"testing"
)
func TestRetryFunc(t *testing.T) {
err := retryFunc(1, func() error { return nil })
if err != nil {
t.Errorf("should not return an error: %s", err)
}
i := 0
fn := func() error {
i++
return fmt.Errorf("oh no, something went wrong!")
}
err = retryFunc(2, fn)
if err == nil {
t.Error("should return an error")
}
if i != 2 {
t.Errorf("The function should have been called 1 times, got %d", i)
}
}
+1 -2
View File
@@ -11,7 +11,6 @@ import (
"coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config"
containerPkg "coopcloud.tech/abra/pkg/container"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/upstream/container"
"github.com/docker/cli/cli/command"
@@ -60,7 +59,7 @@ Example:
Action: func(c *cli.Context) error {
app := internal.ValidateApp(c)
recipe, err := recipe.Get(app.Recipe, internal.Offline)
recipe, err := recipePkg.Get(app.Recipe, internal.Offline)
if err != nil {
logrus.Fatal(err)
}
+3 -4
View File
@@ -9,7 +9,6 @@ import (
"coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/lint"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe"
stack "coopcloud.tech/abra/pkg/upstream/stack"
"coopcloud.tech/tagcmp"
@@ -62,17 +61,17 @@ recipes.
}
if !internal.Chaos {
if err := recipe.EnsureIsClean(app.Recipe); err != nil {
if err := recipePkg.EnsureIsClean(app.Recipe); err != nil {
logrus.Fatal(err)
}
if !internal.Offline {
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
if err := recipePkg.EnsureUpToDate(app.Recipe); err != nil {
logrus.Fatal(err)
}
}
if err := recipe.EnsureLatest(app.Recipe); err != nil {
if err := recipePkg.EnsureLatest(app.Recipe); err != nil {
logrus.Fatal(err)
}
}
+10 -9
View File
@@ -80,29 +80,26 @@ Example:
switch shellType {
case "bash":
fmt.Println(fmt.Sprintf(`
# Run the following commands to install auto-completion
fmt.Printf(`# Run the following commands to install auto-completion
sudo mkdir /etc/bash_completion.d/
sudo cp %s /etc/bash_completion.d/abra
echo "source /etc/bash_completion.d/abra" >> ~/.bashrc
# To test, run the following: "abra app <hit tab key>" - you should see command completion!
`, autocompletionFile))
`, autocompletionFile)
case "zsh":
fmt.Println(fmt.Sprintf(`
# Run the following commands to install auto-completion
fmt.Printf(`# Run the following commands to install auto-completion
sudo mkdir /etc/zsh/completion.d/
sudo cp %s /etc/zsh/completion.d/abra
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!
`, autocompletionFile))
`, autocompletionFile)
case "fish":
fmt.Println(fmt.Sprintf(`
# Run the following commands to install auto-completion
fmt.Printf(`# Run the following commands to install auto-completion
sudo mkdir -p /etc/fish/completions
sudo cp %s /etc/fish/completions/abra
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!
`, autocompletionFile))
`, autocompletionFile)
}
return nil
@@ -117,6 +114,10 @@ var UpgradeCommand = cli.Command{
Description: `
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
that it may contain catastrophic bugs. Thank you very much for the testing
efforts!
+2 -2
View File
@@ -162,14 +162,14 @@ var NewAppServer string
var NewAppServerFlag = &cli.StringFlag{
Name: "server, s",
Value: "",
Usage: "Show apps of a specific server",
Usage: "Use a specific server",
Destination: &NewAppServer,
}
var NoDomainChecks bool
var NoDomainChecksFlag = &cli.BoolFlag{
Name: "no-domain-checks, D",
Usage: "Disable app domain sanity checks",
Usage: "Disable domain sanity checks",
Destination: &NoDomainChecks,
}
+1 -1
View File
@@ -40,7 +40,7 @@ Here is a semver cheat sheet (more on https://semver.org):
var chosenBumpType string
prompt := &survey.Select{
Message: fmt.Sprintf("select recipe version increment type"),
Message: "select recipe version increment type",
Options: []string{"major", "minor", "patch"},
}
+8 -14
View File
@@ -3,7 +3,6 @@ package recipe
import (
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/recipe"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@@ -18,31 +17,26 @@ var recipeFetchCommand = cli.Command{
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.OfflineFlag,
},
Before: internal.SubCommandBefore,
BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error {
recipeName := c.Args().First()
if recipeName != "" {
internal.ValidateRecipe(c)
if err := recipe.Ensure(recipeName); err != nil {
logrus.Fatal(err)
}
return nil
}
catalogue, err := recipe.ReadRecipeCatalogue(internal.Offline)
if err != nil {
if err := recipe.EnsureExists(recipeName); err != nil {
logrus.Fatal(err)
}
catlBar := formatter.CreateProgressbar(len(catalogue), "fetching latest recipes...")
for recipeName := range catalogue {
if err := recipe.Ensure(recipeName); err != nil {
logrus.Error(err)
}
catlBar.Add(1)
if err := recipe.EnsureUpToDate(recipeName); err != nil {
logrus.Fatal(err)
}
if err := recipe.EnsureLatest(recipeName); err != nil {
logrus.Fatal(err)
}
return nil
+2 -2
View File
@@ -103,7 +103,7 @@ recipe and domain in the sample environment config).
logrus.Fatal(err)
}
fmt.Print(fmt.Sprintf(`
fmt.Printf(`
Your new %s recipe has been created in %s.
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!
`, recipeName, path.Join(config.RECIPES_DIR, recipeName), recipeName))
`, recipeName, path.Join(config.RECIPES_DIR, recipeName), recipeName)
return nil
},
+2 -2
View File
@@ -68,7 +68,7 @@ local file system.
if internal.NoInput {
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
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
@@ -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
likely to change.
`, recipe.Name, recipe.Name))
`, recipe.Name, recipe.Name)
var chosenVersion string
edPrompt := &survey.Select{
Message: "which version do you want to begin with?",
+24 -13
View File
@@ -53,7 +53,7 @@ func cleanUp(domainName string) {
// Docker manages SSH connection details. These are stored to disk in
// ~/.docker. Abra can manage this completely for the user, so it's an
// implementation detail.
func newContext(c *cli.Context, domainName, username, port string) error {
func newContext(c *cli.Context, name, host, username, port string) error {
store := contextPkg.NewDefaultDockerContextStore()
contexts, err := store.Store.List()
if err != nil {
@@ -61,15 +61,15 @@ func newContext(c *cli.Context, domainName, username, port string) error {
}
for _, context := range contexts {
if context.Name == domainName {
logrus.Debugf("context for %s already exists", domainName)
if context.Name == name {
logrus.Debugf("context for %s already exists", name)
return nil
}
}
logrus.Debugf("creating context with domain %s, username %s and port %s", domainName, username, port)
logrus.Debugf("creating context with name %s, host %s, username %s and port %s", name, host, username, port)
if err := client.CreateContext(domainName, username, port); err != nil {
if err := client.CreateContext(name, host, username, port); err != nil {
return err
}
@@ -112,11 +112,16 @@ Abra can then load SSH connection details from this configuratiion with:
If "--local" is passed, then Abra assumes that the current local server is
intended as the target server. This is useful when you want to have your entire
Co-op Cloud config located on the server itself, and not on your local
developer machine.
developer machine. The domain is then set to "default".
You can also pass "--no-domain-checks" flag to use any arbitrary name instead
of a real domain. Host will be resolved with the "hostname" entry of your SSH
configuration. Checks for a valid online domain will be skipped.
`,
Flags: []cli.Flag{
internal.DebugFlag,
internal.NoInputFlag,
internal.NoDomainChecksFlag,
localFlag,
},
Before: internal.SubCommandBefore,
@@ -150,23 +155,29 @@ developer machine.
return nil
}
if _, err := dns.EnsureIPv4(domainName); err != nil {
logrus.Fatal(err)
}
if err := createServerDir(domainName); err != nil {
logrus.Fatal(err)
if !internal.NoDomainChecks {
if _, err := dns.EnsureIPv4(domainName); err != nil {
logrus.Fatal(err)
}
}
hostConfig, err := sshPkg.GetHostConfig(domainName)
if err != nil {
logrus.Fatal(err)
}
if hostConfig.Host == "" {
hostConfig.Host = domainName
}
if err := newContext(c, domainName, hostConfig.User, hostConfig.Port); err != nil {
if err := createServerDir(domainName); err != nil {
logrus.Fatal(err)
}
if err := newContext(c, domainName, hostConfig.Host, hostConfig.User, hostConfig.Port); err != nil {
logrus.Fatal(err)
cleanUp(domainName)
}
logrus.Infof("attempting to create client for %s", domainName)
if _, err := client.New(domainName); err != nil {
cleanUp(domainName)
-14
View File
@@ -51,20 +51,6 @@ func RecipeNameComplete(c *cli.Context) {
}
}
// RecipeVersionComplete completes versions for the recipe.
func RecipeVersionComplete(recipeName string) {
catl, err := recipe.ReadRecipeCatalogue(false)
if err != nil {
logrus.Warn(err)
}
for _, v := range catl[recipeName].Versions {
for v2 := range v {
fmt.Println(v2)
}
}
}
// ServerNameComplete completes server names.
func ServerNameComplete(c *cli.Context) {
files, err := config.LoadAppFiles("")
+1 -2
View File
@@ -14,8 +14,7 @@ import (
type Context = contextStore.Metadata
func CreateContext(contextName string, user string, port string) error {
host := contextName
func CreateContext(contextName string, host string, user string, port string) error {
if user != "" {
host = fmt.Sprintf("%s@%s", user, host)
}
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
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)
volumeList := volumeListOKBody.Volumes
if err != nil {
+8 -10
View File
@@ -16,25 +16,23 @@ import (
"github.com/sirupsen/logrus"
)
// getBaseDir retrieves the Abra base directory.
func getBaseDir() string {
home := os.ExpandEnv("$HOME/.abra")
if customAbraDir, exists := os.LookupEnv("ABRA_DIR"); exists && customAbraDir != "" {
home = customAbraDir
func getFromEnvOrDefault(envStr string, defaultStr string) string {
if envVar, exists := os.LookupEnv(envStr); exists && envVar != "" {
return envVar
}
return home
return defaultStr
}
var ABRA_DIR = getBaseDir()
var ABRA_DIR = getFromEnvOrDefault("ABRA_DIR", os.ExpandEnv("$HOME/.abra"))
var SERVERS_DIR = path.Join(ABRA_DIR, "servers")
var RECIPES_DIR = path.Join(ABRA_DIR, "recipes")
var VENDOR_DIR = path.Join(ABRA_DIR, "vendor")
var BACKUP_DIR = path.Join(ABRA_DIR, "backups")
var CATALOGUE_DIR = path.Join(ABRA_DIR, "catalogue")
var RECIPES_JSON = path.Join(ABRA_DIR, "catalogue", "recipes.json")
var REPOS_BASE_URL = "https://git.coopcloud.tech/coop-cloud"
var CATALOGUE_JSON_REPO_NAME = "recipes-catalogue-json"
var SSH_URL_TEMPLATE = "ssh://git@git.coopcloud.tech:2222/coop-cloud/%s.git"
var REPOS_BASE_URL = getFromEnvOrDefault("ABRA_REPOS_BASE_URL", "https://git.coopcloud.tech/coop-cloud")
var CATALOGUE_JSON_REPO_NAME = getFromEnvOrDefault("ABRA_CATALOGUE_JSON_REPO_NAME", "recipes-catalogue-json")
var SSH_URL_TEMPLATE = getFromEnvOrDefault("ABRA_SSH_URL_TEMPLATE", "ssh://git@git.coopcloud.tech:2222/coop-cloud/%s.git")
// envVarModifiers is a list of env var modifier strings. These are added to
// env vars as comments and modify their processing by Abra, e.g. determining
+1 -1
View File
@@ -9,7 +9,7 @@ import (
func EnsureIPv4(domainName string) (string, error) {
ipv4, err := net.ResolveIPAddr("ip4", domainName)
if err != nil {
return "", err
return "", fmt.Errorf("unable to resolve ipv4 address for %s, %s", domainName, err)
}
// NOTE(d1): e.g. when there is only an ipv6 record available
+1 -1
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
// concurrent operations.
func New(limit int) *Limiter {
return &Limiter{make(chan struct{}, limit)}
return &Limiter{sem: make(chan struct{}, limit)}
}
// Begin an operation.
+20 -21
View File
@@ -7,7 +7,6 @@ import (
"path"
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/tagcmp"
"github.com/docker/distribution/reference"
@@ -19,13 +18,13 @@ import (
var Warn = "warn"
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
// 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.
// 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
// 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.
func (l LintRule) Skip(recipe recipe.Recipe) bool {
func (l LintRule) Skip(recipe recipePkg.Recipe) bool {
if l.SkipCondition != nil {
ok, err := l.SkipCondition(recipe)
if err != nil {
@@ -166,7 +165,7 @@ var LintRules = map[string][]LintRule{
// 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
// 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)
for level := range LintRules {
@@ -194,7 +193,7 @@ func LintForErrors(recipe recipe.Recipe) error {
return nil
}
func LintComposeVersion(recipe recipe.Recipe) (bool, error) {
func LintComposeVersion(recipe recipePkg.Recipe) (bool, error) {
if recipe.Config.Version == "3.8" {
return true, nil
}
@@ -202,7 +201,7 @@ func LintComposeVersion(recipe recipe.Recipe) (bool, error) {
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)
if _, err := os.Stat(envSample); !os.IsNotExist(err) {
return true, nil
@@ -211,7 +210,7 @@ func LintEnvConfigPresent(recipe recipe.Recipe) (bool, error) {
return false, nil
}
func LintAppService(recipe recipe.Recipe) (bool, error) {
func LintAppService(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
if service.Name == "app" {
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
// the recipe. This typically means that no domain is required to deploy and
// 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")
sampleEnv, err := config.ReadEnv(envSamplePath)
if err != nil {
@@ -239,7 +238,7 @@ func LintTraefikEnabledSkipCondition(recipe recipe.Recipe) (bool, error) {
return false, nil
}
func LintTraefikEnabled(recipe recipe.Recipe) (bool, error) {
func LintTraefikEnabled(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
for label := range service.Deploy.Labels {
if label == "traefik.enable" {
@@ -253,7 +252,7 @@ func LintTraefikEnabled(recipe recipe.Recipe) (bool, error) {
return false, nil
}
func LintHealthchecks(recipe recipe.Recipe) (bool, error) {
func LintHealthchecks(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
if service.HealthCheck == nil {
return false, nil
@@ -263,7 +262,7 @@ func LintHealthchecks(recipe recipe.Recipe) (bool, error) {
return true, nil
}
func LintAllImagesTagged(recipe recipe.Recipe) (bool, error) {
func LintAllImagesTagged(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil {
@@ -277,7 +276,7 @@ func LintAllImagesTagged(recipe recipe.Recipe) (bool, error) {
return true, nil
}
func LintNoUnstableTags(recipe recipe.Recipe) (bool, error) {
func LintNoUnstableTags(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil {
@@ -300,7 +299,7 @@ func LintNoUnstableTags(recipe recipe.Recipe) (bool, error) {
return true, nil
}
func LintSemverLikeTags(recipe recipe.Recipe) (bool, error) {
func LintSemverLikeTags(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil {
@@ -323,7 +322,7 @@ func LintSemverLikeTags(recipe recipe.Recipe) (bool, error) {
return true, nil
}
func LintImagePresent(recipe recipe.Recipe) (bool, error) {
func LintImagePresent(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
if service.Image == "" {
return false, nil
@@ -332,7 +331,7 @@ func LintImagePresent(recipe recipe.Recipe) (bool, error) {
return true, nil
}
func LintHasPublishedVersion(recipe recipe.Recipe) (bool, error) {
func LintHasPublishedVersion(recipe recipePkg.Recipe) (bool, error) {
catl, err := recipePkg.ReadRecipeCatalogue(false)
if err != nil {
logrus.Fatal(err)
@@ -350,8 +349,8 @@ func LintHasPublishedVersion(recipe recipe.Recipe) (bool, error) {
return true, nil
}
func LintMetadataFilledIn(r recipe.Recipe) (bool, error) {
features, category, err := recipe.GetRecipeFeaturesAndCategory(r.Name)
func LintMetadataFilledIn(recipe recipePkg.Recipe) (bool, error) {
features, category, err := recipePkg.GetRecipeFeaturesAndCategory(recipe.Name)
if err != nil {
return false, err
}
@@ -371,7 +370,7 @@ func LintMetadataFilledIn(r recipe.Recipe) (bool, error) {
return true, nil
}
func LintAbraShVendors(recipe recipe.Recipe) (bool, error) {
func LintAbraShVendors(recipe recipePkg.Recipe) (bool, error) {
for _, service := range recipe.Config.Services {
if len(service.Configs) > 0 {
abraSh := path.Join(config.RECIPES_DIR, recipe.Name, "abra.sh")
@@ -386,7 +385,7 @@ func LintAbraShVendors(recipe recipe.Recipe) (bool, error) {
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)
res, err := http.Get(url)
@@ -401,7 +400,7 @@ func LintHasRecipeRepo(recipe recipe.Recipe) (bool, error) {
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)
repo, err := git.PlainOpen(recipeDir)
-14
View File
@@ -264,20 +264,6 @@ func (r Recipe) SampleEnv() (map[string]string, error) {
return sampleEnv, nil
}
// Ensure makes sure the recipe exists, is up to date and has the latest version checked out.
func Ensure(recipeName string) error {
if err := EnsureExists(recipeName); err != nil {
return err
}
if err := EnsureUpToDate(recipeName); err != nil {
return err
}
if err := EnsureLatest(recipeName); err != nil {
return err
}
return nil
}
// EnsureExists ensures that a recipe is locally cloned
func EnsureExists(recipeName string) error {
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
+6 -6
View File
@@ -66,19 +66,19 @@ func GetDeployedServicesByLabel(cl *dockerClient.Client, contextName string, lab
filters.Add("label", label)
services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: filters})
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 {
services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: getAllStacksFilter()})
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
@@ -88,10 +88,10 @@ func GetDeployedServicesByName(ctx context.Context, cl *dockerClient.Client, sta
services, err := cl.ServiceList(ctx, types.ServiceListOptions{Filters: filters})
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.
+5 -7
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
ABRA_VERSION="0.9.0-beta"
ABRA_VERSION="0.8.1-beta"
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
RC_VERSION="0.8.0-rc1-beta"
RC_VERSION="0.8.1-beta"
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION"
for arg in "$@"; do
@@ -65,19 +65,17 @@ function install_abra_release {
checksums=$(wget -q -O- $checksums_url)
checksum=$(echo "$checksums" | grep "$FILENAME" - | sed -En 's/([0-9a-f]{64})\s+'"$FILENAME"'.*/\1/p')
abra_download="/tmp/abra-download"
echo "downloading $ABRA_VERSION $PLATFORM binary release for abra..."
wget -q "$release_url" -O $abra_download
localsum=$(sha256sum $abra_download | sed -En 's/([0-9a-f]{64})\s+.*/\1/p')
wget -q "$release_url" -O "$HOME/.local/bin/.abra-download"
localsum=$(sha256sum $HOME/.local/bin/.abra-download | sed -En 's/([0-9a-f]{64})\s+.*/\1/p')
echo "checking if checksums match..."
if [[ "$localsum" != "$checksum" ]]; then
print_checksum_error
exit 1
fi
echo "$(tput setaf 2)check successful!$(tput sgr0)"
mv "$abra_download" "$HOME/.local/bin/abra"
mv "$HOME/.local/bin/.abra-download" "$HOME/.local/bin/abra"
chmod +x "$HOME/.local/bin/abra"
x=$(echo $PATH | grep $HOME/.local/bin)
+4 -4
View File
@@ -70,13 +70,13 @@ setup(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app check "$TEST_APP_DOMAIN"
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
refute_output --partial 'behind 3'
_reset_recipe
}
@@ -86,7 +86,7 @@ setup(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "Your branch is behind 'origin/main' by 1 commit"
assert_output --partial 'behind 1'
# NOTE(d1): we can't quite tell if this will fail or not in the future, so,
# since it isn't an important part of what we're testing here, we don't check
@@ -94,7 +94,7 @@ setup(){
run $ABRA app check "$TEST_APP_DOMAIN" --offline
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "Your branch is behind 'origin/main' by 1 commit"
assert_output --partial 'behind 1'
_reset_recipe
}
+16 -16
View File
@@ -58,7 +58,7 @@ test_cmd_export"
assert_success
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE"
run $ABRA app cmd --local "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local
assert_success
assert_output --partial 'baz'
@@ -70,7 +70,7 @@ test_cmd_export"
assert_success
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
run $ABRA app cmd --local "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local
assert_failure
assert_output --partial 'locally unstaged changes'
@@ -83,7 +83,7 @@ test_cmd_export"
assert_success
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
run $ABRA app cmd --local --chaos "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local --chaos
assert_success
assert_output --partial 'baz'
@@ -96,14 +96,14 @@ test_cmd_export"
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app cmd --local "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local
assert_success
assert_output --partial 'baz'
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "up to date"
refute_output --partial 'behind 3'
_reset_recipe "$TEST_RECIPE"
}
@@ -113,14 +113,14 @@ test_cmd_export"
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app cmd --local --offline "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local --offline
assert_success
assert_output --partial 'baz'
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
_reset_recipe "$TEST_RECIPE"
}
@@ -132,13 +132,13 @@ test_cmd_export"
}
@test "error if missing arguments when passing --local" {
run $ABRA app cmd --local "$TEST_APP_DOMAIN"
run $ABRA app cmd "$TEST_APP_DOMAIN" --local
assert_failure
assert_output --partial 'missing arguments'
}
@test "cannot use --local and --user at same time" {
run $ABRA app cmd --local --user root "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local --user root
assert_failure
assert_output --partial 'cannot use --local & --user together'
}
@@ -147,7 +147,7 @@ test_cmd_export"
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/abra.sh"
assert_success
run $ABRA app cmd --local --chaos "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local --chaos
assert_failure
assert_output --partial "$ABRA_DIR/recipes/$TEST_RECIPE/abra.sh does not exist"
@@ -155,25 +155,25 @@ test_cmd_export"
}
@test "error if missing command" {
run $ABRA app cmd --local "$TEST_APP_DOMAIN" doesnt_exist
run $ABRA app cmd "$TEST_APP_DOMAIN" doesnt_exist --local
assert_failure
assert_output --partial "doesn't have a doesnt_exist function"
}
@test "run --local command" {
run $ABRA app cmd --local "$TEST_APP_DOMAIN" test_cmd
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd --local
assert_success
assert_output --partial 'baz'
}
@test "run command with single arg" {
run $ABRA app cmd --local "$TEST_APP_DOMAIN" test_cmd_arg -- bing
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd_arg --local -- bing
assert_success
assert_output --partial 'bing'
}
@test "run command with several args" {
run $ABRA app cmd --local "$TEST_APP_DOMAIN" test_cmd_args -- bong bang
run $ABRA app cmd "$TEST_APP_DOMAIN" test_cmd_args --local -- bong bang
assert_success
assert_output --partial 'bong bang'
}
+5 -13
View File
@@ -16,7 +16,6 @@ teardown_file(){
setup(){
load "$PWD/tests/integration/helpers/common"
_common_setup
_reset_recipe
}
teardown(){
@@ -83,13 +82,13 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
refute_output --regexp 'behind .* 3 commits'
refute_output --partial 'behind 3'
_reset_recipe
_undeploy_app
@@ -101,7 +100,7 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
# NOTE(d1): need to use --chaos to force same commit
run $ABRA app deploy "$TEST_APP_DOMAIN" \
@@ -109,7 +108,7 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
_undeploy_app
_reset_recipe
@@ -117,9 +116,6 @@ teardown(){
# bats test_tags=slow
@test "deploy latest commit if no published versions and no --chaos" {
# TODO(d1): fix with a new test recipe which has no published versions?
skip "known issue, abra-test-recipe has published versions now"
latestCommit="$(git -C "$ABRA_DIR/recipes/$TEST_RECIPE" rev-parse --short HEAD)"
_remove_tags
@@ -144,7 +140,7 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
threeCommitsBack="$(git -C "$ABRA_DIR/recipes/$TEST_RECIPE" rev-parse --short HEAD)"
@@ -277,10 +273,6 @@ teardown(){
}
@test "ensure domain is checked" {
if [[ "$TEST_SERVER" == "default" ]]; then
skip "domain checks are disabled for local server"
fi
appDomain="custom-html.DOESNTEXIST"
run $ABRA app new custom-html \
+11 -42
View File
@@ -18,24 +18,9 @@ setup(){
}
teardown(){
load "$PWD/tests/integration/helpers/common"
_rm_app
}
@test "autocomplete" {
run $ABRA app new --generate-bash-completion
assert_success
assert_output --partial "traefik"
assert_output --partial "abra-test-recipe"
# Note: this test needs to be updated when a new version of the test recipe is published.
run $ABRA app new abra-test-recipe --generate-bash-completion
assert_success
assert_output "0.1.0+1.20.0
0.1.1+1.20.2
0.2.0+1.21.0"
}
@test "create new app" {
run $ABRA app new "$TEST_RECIPE" \
--no-input \
@@ -43,29 +28,10 @@ teardown(){
--domain "$TEST_APP_DOMAIN"
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "up to date"
}
@test "create new app with version" {
run $ABRA app new "$TEST_RECIPE" 0.1.1+1.20.2 \
--no-input \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" log -1
assert_output --partial "453db7121c0a56a7a8f15378f18fe3bf21ccfdef"
}
@test "does not overwrite existing env files" {
run $ABRA app new "$TEST_RECIPE" \
--no-input \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
assert_success
_new_app
run $ABRA app new "$TEST_RECIPE" \
--no-input \
@@ -108,7 +74,8 @@ teardown(){
--no-input \
--chaos \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
--domain "$TEST_APP_DOMAIN" \
--secrets
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@@ -121,17 +88,18 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app new "$TEST_RECIPE" \
--no-input \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
--domain "$TEST_APP_DOMAIN" \
--secrets
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "up to date"
refute_output --partial 'behind 3'
_reset_recipe
}
@@ -141,7 +109,7 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
# NOTE(d1): need to use --chaos to force same commit
run $ABRA app new "$TEST_RECIPE" \
@@ -149,12 +117,13 @@ teardown(){
--offline \
--chaos \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
--domain "$TEST_APP_DOMAIN" \
--secrets
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
_reset_recipe
}
+6 -3
View File
@@ -104,10 +104,10 @@ teardown(){
_undeploy_app
# TODO: should wait as long as volume is no longer in use
sleep 10
# NOTE(d1): to let the stack come down before nuking volumes
sleep 5
run $ABRA app volume rm "$TEST_APP_DOMAIN" --no-input
run $ABRA app volume rm "$TEST_APP_DOMAIN" --force
assert_success
run $ABRA app volume ls "$TEST_APP_DOMAIN"
@@ -132,6 +132,9 @@ teardown(){
_undeploy_app
# NOTE(d1): to let the stack come down before nuking volumes
sleep 5
run $ABRA app rm "$TEST_APP_DOMAIN" --no-input
assert_success
assert_output --partial 'test-volume'
+7 -7
View File
@@ -109,13 +109,13 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app restore "$TEST_APP_DOMAIN" app
run $ABRA app restore "$TEST_APP_DOMAIN" app DOESNTEXIST
assert_failure
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "up to date"
refute_output --partial 'behind 3'
}
@test "ensure recipe not up to date if --offline" {
@@ -126,19 +126,19 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app restore "$TEST_APP_DOMAIN" app --offline
run $ABRA app restore "$TEST_APP_DOMAIN" app DOESNTEXIST --offline
assert_failure
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$latestCommit"
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "HEAD detached at $latestCommit"
refute_output --partial 'behind 3'
}
@test "error if missing service" {
+5 -5
View File
@@ -50,13 +50,13 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app rollback "$TEST_APP_DOMAIN" --no-input --no-converge-checks
assert_failure
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --partial "up to date"
refute_output --partial 'behind 3'
}
@test "ensure recipe not up to date if --offline" {
@@ -67,14 +67,14 @@ teardown(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA app rollback "$TEST_APP_DOMAIN" \
--no-input --no-converge-checks --offline
assert_failure
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$latestCommit"
assert_success
@@ -131,7 +131,7 @@ teardown(){
latestCommit="$(git -C "$ABRA_DIR/recipes/$TEST_RECIPE" rev-parse --short HEAD)"
run $ABRA app deploy "$TEST_APP_DOMAIN" \
--no-input --chaos
--no-input --no-converge-checks --chaos
assert_success
assert_output --partial "$latestCommit"
assert_output --partial 'chaos'
+8 -1
View File
@@ -8,7 +8,7 @@ setup_file(){
run $ABRA app new "$TEST_RECIPE" \
--no-input \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
--domain "$TEST_APP_DOMAIN" \
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
}
@@ -19,6 +19,13 @@ teardown_file(){
_reset_recipe
}
teardown(){
# https://github.com/bats-core/bats-core/issues/383#issuecomment-738628888
if [[ -z "${BATS_TEST_COMPLETED}" ]]; then
_undeploy_app
fi
}
setup(){
load "$PWD/tests/integration/helpers/common"
_common_setup
+1 -3
View File
@@ -59,8 +59,6 @@ teardown(){
# bats test_tags=slow
@test "error if not in catalogue" {
skip "known issue, see https://git.coopcloud.tech/coop-cloud/recipes-catalogue-json/issues/6"
_deploy_app
run $ABRA app version "$TEST_APP_DOMAIN"
@@ -94,7 +92,7 @@ teardown(){
assert_success
# NOTE(d1): to let the stack come down before nuking volumes
sleep 5
sleep 3
run $ABRA app volume remove "$appDomain" --no-input
assert_success
+2 -2
View File
@@ -79,7 +79,7 @@ teardown(){
_undeploy_app
# NOTE(d1): to let the stack come down before nuking volumes
sleep 10
sleep 5
run $ABRA app volume rm "$TEST_APP_DOMAIN" --force
assert_success
@@ -93,7 +93,7 @@ teardown(){
_undeploy_app
# NOTE(d1): to let the stack come down before nuking volumes
sleep 10
sleep 5
run $ABRA app volume rm "$TEST_APP_DOMAIN" --force
assert_success
+1 -1
View File
@@ -49,7 +49,7 @@ _reset_app(){
run $ABRA app new "$TEST_RECIPE" \
--no-input \
--server "$TEST_SERVER" \
--domain "$TEST_APP_DOMAIN"
--domain "$TEST_APP_DOMAIN" \
assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
}
+1 -5
View File
@@ -11,11 +11,7 @@ _add_server() {
}
_rm_server() {
if [[ "$TEST_SERVER" == "default" ]]; then
run rm -rf "$ABRA_DIR/servers/default"
else
run $ABRA server remove --no-input "$TEST_SERVER"
fi
run $ABRA server remove --no-input "$TEST_SERVER"
assert_success
assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER"
}
+1 -11
View File
@@ -5,17 +5,7 @@ setup() {
_common_setup
}
@test "recipe fetch all" {
run rm -rf "$ABRA_DIR/recipes/matrix-synapse"
assert_success
assert_not_exists "$ABRA_DIR/recipes/matrix-synapse"
run $ABRA recipe fetch
assert_success
assert_exists "$ABRA_DIR/recipes/matrix-synapse"
}
@test "recipe fetch single recipe" {
@test "recipe fetch" {
run rm -rf "$ABRA_DIR/recipes/matrix-synapse"
assert_success
assert_not_exists "$ABRA_DIR/recipes/matrix-synapse"
+4 -4
View File
@@ -66,13 +66,13 @@ setup() {
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA recipe lint "$TEST_RECIPE"
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
refute_output --partial 'behind 3'
_reset_recipe
}
@@ -82,13 +82,13 @@ setup() {
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA recipe lint "$TEST_RECIPE" --offline
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
_reset_recipe
}
+2 -2
View File
@@ -61,14 +61,14 @@ setup(){
assert_success
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
assert_output --partial 'behind 3'
run $ABRA recipe upgrade "$TEST_RECIPE" --no-input
assert_success
assert_output --partial 'can upgrade service: app'
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_output --regexp 'behind .* 3 commits'
refute_output --partial 'behind 3'
_reset_recipe
}
-2
View File
@@ -12,8 +12,6 @@ setup() {
}
@test "error if not present in catalogue" {
skip "known issue, see https://git.coopcloud.tech/coop-cloud/recipes-catalogue-json/issues/6"
run $ABRA recipe versions "$TEST_RECIPE"
assert_failure
assert_output --partial "is not published on the catalogue"