Compare commits
34 Commits
0.3.1-alph
...
0.3.1-alph
Author | SHA1 | Date | |
---|---|---|---|
a7ebcd8950 | |||
e589709cb0 | |||
56c3e070f5 | |||
cc37615d83 | |||
0b37f63248 | |||
9c3a06a7d9 | |||
cdef8b5ea5 | |||
cba261b18c | |||
1f6e4fa4a3 | |||
4a245c3e02 | |||
299faa1adf
|
|||
704e773a16 | |||
7143d09fd4 | |||
4e76d49c80 | |||
c9dff0c3bd | |||
e77e72a9e6 | |||
af6f759c92 | |||
034295332c | |||
dac2489e6d | |||
7bdc1946a2 | |||
2439643895 | |||
0876f677d1 | |||
31dafb3ae4 | |||
915083b426 | |||
486a1717e7 | |||
9122c0a9b8 | |||
85ff04202f | |||
ecba4e01f1 | |||
751b187df6 | |||
f74261dbe6 | |||
2600a8137c | |||
b6a6163eff | |||
c25b2b17df
|
|||
713308e0b8 |
14
README.md
14
README.md
@ -9,6 +9,20 @@ The Co-op Cloud utility belt 🎩🐇
|
|||||||
|
|
||||||
`abra` is a command-line tool for managing your own [Co-op Cloud](https://coopcloud.tech). It can provision new servers, create apps, deploy them, run backup and restore operations and a whole lot of other things. Please see [docs.coopcloud.tech](https://docs.coopcloud.tech) for more extensive documentation.
|
`abra` is a command-line tool for managing your own [Co-op Cloud](https://coopcloud.tech). It can provision new servers, create apps, deploy them, run backup and restore operations and a whole lot of other things. Please see [docs.coopcloud.tech](https://docs.coopcloud.tech) for more extensive documentation.
|
||||||
|
|
||||||
|
## Quick install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://install.abra.autonomic.zone | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Or using the latest release candidate (extra experimental!):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://install.abra.autonomic.zone | bash -s -- --rc
|
||||||
|
```
|
||||||
|
|
||||||
|
Source for this script is in [scripts/installer/installer](./scripts/installer/installer).
|
||||||
|
|
||||||
## Hacking
|
## Hacking
|
||||||
|
|
||||||
### Getting started
|
### Getting started
|
||||||
|
@ -5,13 +5,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/formatter"
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
"github.com/docker/docker/pkg/archive"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
@ -21,6 +16,18 @@ var appCpCommand = &cli.Command{
|
|||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
ArgsUsage: "<src> <dst>",
|
ArgsUsage: "<src> <dst>",
|
||||||
Usage: "Copy files to/from a running app service",
|
Usage: "Copy files to/from a running app service",
|
||||||
|
Description: `
|
||||||
|
This command supports copying files to and from any app service file system.
|
||||||
|
|
||||||
|
If you want to copy a myfile.txt to the root of the app service:
|
||||||
|
|
||||||
|
abra app cp <app> myfile.txt app:/
|
||||||
|
|
||||||
|
And if you want to copy that file back to your current working directory locally:
|
||||||
|
|
||||||
|
abra app cp <app> app:/myfile.txt .
|
||||||
|
|
||||||
|
`,
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(c)
|
||||||
|
|
||||||
@ -64,61 +71,28 @@ var appCpCommand = &cli.Command{
|
|||||||
logrus.Debugf("assuming transfer is going TO the container")
|
logrus.Debugf("assuming transfer is going TO the container")
|
||||||
}
|
}
|
||||||
|
|
||||||
appFiles, err := config.LoadAppFiles("")
|
if !isToContainer {
|
||||||
|
if _, err := os.Stat(dstPath); os.IsNotExist(err) {
|
||||||
|
logrus.Fatalf("%s does not exist locally?", dstPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := internal.ConfigureAndCp(c, app, srcPath, dstPath, service, isToContainer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
appEnv, err := config.GetApp(appFiles, app.Name)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("name", fmt.Sprintf("%s_%s", appEnv.StackName(), service))
|
|
||||||
containers, err := cl.ContainerList(c.Context, types.ContainerListOptions{Filters: filters})
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(containers) != 1 {
|
|
||||||
logrus.Fatalf("expected 1 container but got %v", len(containers))
|
|
||||||
}
|
|
||||||
container := containers[0]
|
|
||||||
|
|
||||||
logrus.Debugf("retrieved '%s' as target container on '%s'", formatter.ShortenID(container.ID), app.Server)
|
|
||||||
|
|
||||||
if isToContainer {
|
|
||||||
if _, err := os.Stat(srcPath); err != nil {
|
|
||||||
logrus.Fatalf("'%s' does not exist?", srcPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
toTarOpts := &archive.TarOptions{NoOverwriteDirNonDir: true, Compression: archive.Gzip}
|
|
||||||
content, err := archive.TarWithOptions(srcPath, toTarOpts)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
copyOpts := types.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false}
|
|
||||||
if err := cl.CopyToContainer(c.Context, container.ID, dstPath, content, copyOpts); err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
content, _, err := cl.CopyFromContainer(c.Context, container.ID, srcPath)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
defer content.Close()
|
|
||||||
fromTarOpts := &archive.TarOptions{NoOverwriteDirNonDir: true, Compression: archive.Gzip}
|
|
||||||
if err := archive.Untar(content, dstPath, fromTarOpts); err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
},
|
||||||
|
BashComplete: func(c *cli.Context) {
|
||||||
|
appNames, err := config.GetAppNames()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warn(err)
|
||||||
|
}
|
||||||
|
if c.NArg() > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, a := range appNames {
|
||||||
|
fmt.Println(a)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@ import (
|
|||||||
// CatalogueSkipList is all the repos that are not recipes.
|
// CatalogueSkipList is all the repos that are not recipes.
|
||||||
var CatalogueSkipList = map[string]bool{
|
var CatalogueSkipList = map[string]bool{
|
||||||
"abra": true,
|
"abra": true,
|
||||||
"abra-bash": true,
|
|
||||||
"abra-apps": true,
|
"abra-apps": true,
|
||||||
"abra-aur": true,
|
"abra-aur": true,
|
||||||
|
"abra-bash": true,
|
||||||
"abra-capsul": true,
|
"abra-capsul": true,
|
||||||
"abra-gandi": true,
|
"abra-gandi": true,
|
||||||
"abra-hetzner": true,
|
"abra-hetzner": true,
|
||||||
@ -34,6 +34,7 @@ var CatalogueSkipList = map[string]bool{
|
|||||||
"auto-mirror": true,
|
"auto-mirror": true,
|
||||||
"backup-bot": true,
|
"backup-bot": true,
|
||||||
"backup-bot-two": true,
|
"backup-bot-two": true,
|
||||||
|
"comrade-renovate-bot": true,
|
||||||
"coopcloud.tech": true,
|
"coopcloud.tech": true,
|
||||||
"coturn": true,
|
"coturn": true,
|
||||||
"docker-cp-deploy": true,
|
"docker-cp-deploy": true,
|
||||||
|
16
cli/cli.go
16
cli/cli.go
@ -30,18 +30,6 @@ var VerboseFlag = &cli.BoolFlag{
|
|||||||
Usage: "Show INFO messages",
|
Usage: "Show INFO messages",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug stores the variable from DebugFlag.
|
|
||||||
var Debug bool
|
|
||||||
|
|
||||||
// DebugFlag turns on/off verbose logging down to the DEBUG level.
|
|
||||||
var DebugFlag = &cli.BoolFlag{
|
|
||||||
Name: "debug",
|
|
||||||
Aliases: []string{"d"},
|
|
||||||
Value: false,
|
|
||||||
Destination: &Debug,
|
|
||||||
Usage: "Show DEBUG messages",
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAbraApp(version, commit string) *cli.App {
|
func newAbraApp(version, commit string) *cli.App {
|
||||||
app := &cli.App{
|
app := &cli.App{
|
||||||
Name: "abra",
|
Name: "abra",
|
||||||
@ -66,7 +54,7 @@ func newAbraApp(version, commit string) *cli.App {
|
|||||||
},
|
},
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
VerboseFlag,
|
VerboseFlag,
|
||||||
DebugFlag,
|
internal.DebugFlag,
|
||||||
internal.NoInputFlag,
|
internal.NoInputFlag,
|
||||||
},
|
},
|
||||||
Authors: []*cli.Author{
|
Authors: []*cli.Author{
|
||||||
@ -80,7 +68,7 @@ func newAbraApp(version, commit string) *cli.App {
|
|||||||
app.EnableBashCompletion = true
|
app.EnableBashCompletion = true
|
||||||
|
|
||||||
app.Before = func(c *cli.Context) error {
|
app.Before = func(c *cli.Context) error {
|
||||||
if Debug {
|
if internal.Debug {
|
||||||
logrus.SetLevel(logrus.DebugLevel)
|
logrus.SetLevel(logrus.DebugLevel)
|
||||||
logrus.SetFormatter(&logrus.TextFormatter{})
|
logrus.SetFormatter(&logrus.TextFormatter{})
|
||||||
logrus.SetOutput(os.Stderr)
|
logrus.SetOutput(os.Stderr)
|
||||||
|
@ -259,3 +259,15 @@ var HetznerCloudAPITokenFlag = &cli.StringFlag{
|
|||||||
EnvVars: []string{"HCLOUD_TOKEN"},
|
EnvVars: []string{"HCLOUD_TOKEN"},
|
||||||
Destination: &HetznerCloudAPIToken,
|
Destination: &HetznerCloudAPIToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debug stores the variable from DebugFlag.
|
||||||
|
var Debug bool
|
||||||
|
|
||||||
|
// DebugFlag turns on/off verbose logging down to the DEBUG level.
|
||||||
|
var DebugFlag = &cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
Aliases: []string{"d"},
|
||||||
|
Value: false,
|
||||||
|
Destination: &Debug,
|
||||||
|
Usage: "Show DEBUG messages",
|
||||||
|
}
|
||||||
|
74
cli/internal/copy.go
Normal file
74
cli/internal/copy.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"coopcloud.tech/abra/cli/formatter"
|
||||||
|
"coopcloud.tech/abra/pkg/client"
|
||||||
|
"coopcloud.tech/abra/pkg/config"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/docker/docker/pkg/archive"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConfigureAndCp(c *cli.Context, app config.App, srcPath string, dstPath string, service string, isToContainer bool) error {
|
||||||
|
appFiles, err := config.LoadAppFiles("")
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
appEnv, err := config.GetApp(appFiles, app.Name)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cl, err := client.New(app.Server)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filters := filters.NewArgs()
|
||||||
|
filters.Add("name", fmt.Sprintf("%s_%s", appEnv.StackName(), service))
|
||||||
|
containers, err := cl.ContainerList(c.Context, types.ContainerListOptions{Filters: filters})
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(containers) != 1 {
|
||||||
|
logrus.Fatalf("expected 1 container but got %v", len(containers))
|
||||||
|
}
|
||||||
|
container := containers[0]
|
||||||
|
|
||||||
|
logrus.Debugf("retrieved '%s' as target container on '%s'", formatter.ShortenID(container.ID), app.Server)
|
||||||
|
|
||||||
|
if isToContainer {
|
||||||
|
if _, err := os.Stat(srcPath); err != nil {
|
||||||
|
logrus.Fatalf("'%s' does not exist?", srcPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
toTarOpts := &archive.TarOptions{NoOverwriteDirNonDir: true, Compression: archive.Gzip}
|
||||||
|
content, err := archive.TarWithOptions(srcPath, toTarOpts)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
copyOpts := types.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false}
|
||||||
|
if err := cl.CopyToContainer(c.Context, container.ID, dstPath, content, copyOpts); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content, _, err := cl.CopyFromContainer(c.Context, container.ID, srcPath)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
defer content.Close()
|
||||||
|
fromTarOpts := &archive.TarOptions{NoOverwriteDirNonDir: true, Compression: archive.Gzip}
|
||||||
|
if err := archive.Untar(content, dstPath, fromTarOpts); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -8,6 +8,7 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/catalogue"
|
"coopcloud.tech/abra/pkg/catalogue"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
|
"coopcloud.tech/abra/pkg/dns"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -107,6 +108,16 @@ func DeployAction(c *cli.Context) error {
|
|||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
domainName := app.Env["DOMAIN"]
|
||||||
|
ipv4, err := dns.EnsureIPv4(domainName)
|
||||||
|
if err != nil || ipv4 == "" {
|
||||||
|
logrus.Fatalf("could not find an IP address assigned to %s?", domainName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = dns.EnsureDomainsResolveSameIPv4(domainName, app.Server); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := stack.RunDeploy(cl, deployOpts, compose); err != nil {
|
if err := stack.RunDeploy(cl, deployOpts, compose); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,11 @@ The new example repository is cloned to ~/.abra/apps/<recipe>.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newGitRepo := path.Join(config.APPS_DIR, recipeName)
|
||||||
|
if err := git.Init(newGitRepo, true); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
logrus.Infof(
|
logrus.Infof(
|
||||||
"new recipe '%s' created in %s, happy hacking!\n",
|
"new recipe '%s' created in %s, happy hacking!\n",
|
||||||
recipeName, path.Join(config.APPS_DIR, recipeName),
|
recipeName, path.Join(config.APPS_DIR, recipeName),
|
||||||
|
@ -1,23 +1,21 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
contextPkg "coopcloud.tech/abra/pkg/context"
|
contextPkg "coopcloud.tech/abra/pkg/context"
|
||||||
|
"coopcloud.tech/abra/pkg/dns"
|
||||||
"coopcloud.tech/abra/pkg/server"
|
"coopcloud.tech/abra/pkg/server"
|
||||||
"coopcloud.tech/abra/pkg/ssh"
|
"coopcloud.tech/abra/pkg/ssh"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -268,33 +266,11 @@ func initSwarmLocal(c *cli.Context, cl *dockerClient.Client, domainName string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initSwarm(c *cli.Context, cl *dockerClient.Client, domainName string) error {
|
func initSwarm(c *cli.Context, cl *dockerClient.Client, domainName string) error {
|
||||||
// comrade librehosters DNS resolver -> https://www.privacy-handbuch.de/handbuch_93d.htm
|
ipv4, err := dns.EnsureIPv4(domainName)
|
||||||
freifunkDNS := "5.1.66.255:53"
|
|
||||||
|
|
||||||
resolver := &net.Resolver{
|
|
||||||
PreferGo: false,
|
|
||||||
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
||||||
d := net.Dialer{
|
|
||||||
Timeout: time.Millisecond * time.Duration(10000),
|
|
||||||
}
|
|
||||||
return d.DialContext(ctx, "udp", freifunkDNS)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.Debugf("created DNS resolver via '%s'", freifunkDNS)
|
|
||||||
|
|
||||||
ips, err := resolver.LookupIPAddr(c.Context, domainName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ips) == 0 {
|
|
||||||
return fmt.Errorf("unable to retrieve ipv4 address for %s", domainName)
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv4 := ips[0].IP.To4().String()
|
|
||||||
logrus.Debugf("discovered the following ipv4 addr: %s", ipv4)
|
|
||||||
|
|
||||||
initReq := swarm.InitRequest{
|
initReq := swarm.InitRequest{
|
||||||
ListenAddr: "0.0.0.0:2377",
|
ListenAddr: "0.0.0.0:2377",
|
||||||
AdvertiseAddr: ipv4,
|
AdvertiseAddr: ipv4,
|
||||||
|
@ -8,12 +8,24 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var RC bool
|
||||||
|
var RCFlag = &cli.BoolFlag{
|
||||||
|
Name: "rc",
|
||||||
|
Value: false,
|
||||||
|
Destination: &RC,
|
||||||
|
Usage: "Insatll the latest Release Candidate",
|
||||||
|
}
|
||||||
|
|
||||||
// UpgradeCommand upgrades abra in-place.
|
// UpgradeCommand upgrades abra in-place.
|
||||||
var UpgradeCommand = &cli.Command{
|
var UpgradeCommand = &cli.Command{
|
||||||
Name: "upgrade",
|
Name: "upgrade",
|
||||||
Usage: "Upgrade abra",
|
Usage: "Upgrade abra",
|
||||||
|
Flags: []cli.Flag{RCFlag},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
cmd := exec.Command("bash", "-c", "curl -s https://install.abra.coopcloud.tech | bash")
|
cmd := exec.Command("bash", "-c", "curl -s https://install.abra.coopcloud.tech | bash")
|
||||||
|
if RC {
|
||||||
|
cmd = exec.Command("bash", "-c", "curl -s https://git.coopcloud.tech/coop-cloud/abra/raw/branch/main/scripts/installer/installer | bash -s -- --rc")
|
||||||
|
}
|
||||||
logrus.Debugf("attempting to run '%s'", cmd)
|
logrus.Debugf("attempting to run '%s'", cmd)
|
||||||
if err := internal.RunCmd(cmd); err != nil {
|
if err := internal.RunCmd(cmd); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
|
16
go.mod
16
go.mod
@ -4,16 +4,16 @@ go 1.16
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
coopcloud.tech/tagcmp v0.0.0-20211103052201-885b22f77d52
|
coopcloud.tech/tagcmp v0.0.0-20211103052201-885b22f77d52
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.1
|
github.com/AlecAivazis/survey/v2 v2.3.2
|
||||||
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4
|
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4
|
||||||
github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4
|
github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4
|
||||||
github.com/docker/cli v20.10.8+incompatible
|
github.com/docker/cli v20.10.11+incompatible
|
||||||
github.com/docker/distribution v2.7.1+incompatible
|
github.com/docker/distribution v2.7.1+incompatible
|
||||||
github.com/docker/docker v20.10.8+incompatible
|
github.com/docker/docker v20.10.11+incompatible
|
||||||
github.com/docker/go-units v0.4.0
|
github.com/docker/go-units v0.4.0
|
||||||
github.com/go-git/go-git/v5 v5.4.2
|
github.com/go-git/go-git/v5 v5.4.2
|
||||||
github.com/hetznercloud/hcloud-go v1.32.0
|
github.com/hetznercloud/hcloud-go v1.33.1
|
||||||
github.com/moby/sys/signal v0.5.0
|
github.com/moby/sys/signal v0.6.0
|
||||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
|
||||||
github.com/olekukonko/tablewriter v0.0.5
|
github.com/olekukonko/tablewriter v0.0.5
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
@ -31,10 +31,10 @@ require (
|
|||||||
github.com/docker/docker-credential-helpers v0.6.4 // indirect
|
github.com/docker/docker-credential-helpers v0.6.4 // indirect
|
||||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
||||||
github.com/fvbommel/sortorder v1.0.2 // indirect
|
github.com/fvbommel/sortorder v1.0.2 // indirect
|
||||||
github.com/gliderlabs/ssh v0.2.2
|
github.com/gliderlabs/ssh v0.3.3
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351
|
github.com/kevinburke/ssh_config v1.1.0
|
||||||
github.com/libdns/gandi v1.0.2
|
github.com/libdns/gandi v1.0.2
|
||||||
github.com/libdns/libdns v0.2.1
|
github.com/libdns/libdns v0.2.1
|
||||||
github.com/moby/sys/mount v0.2.0 // indirect
|
github.com/moby/sys/mount v0.2.0 // indirect
|
||||||
@ -43,5 +43,5 @@ require (
|
|||||||
github.com/theupdateframework/notary v0.7.0 // indirect
|
github.com/theupdateframework/notary v0.7.0 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||||
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359
|
||||||
)
|
)
|
||||||
|
34
go.sum
34
go.sum
@ -26,8 +26,8 @@ coopcloud.tech/libcapsul v0.0.0-20211022074848-c35e78fe3f3e/go.mod h1:HEQ9pSJRsD
|
|||||||
coopcloud.tech/tagcmp v0.0.0-20211103052201-885b22f77d52 h1:cyFFOl0tKe+dVHt8saejG8xoff33eQiHxFCVzRpPUjM=
|
coopcloud.tech/tagcmp v0.0.0-20211103052201-885b22f77d52 h1:cyFFOl0tKe+dVHt8saejG8xoff33eQiHxFCVzRpPUjM=
|
||||||
coopcloud.tech/tagcmp v0.0.0-20211103052201-885b22f77d52/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
coopcloud.tech/tagcmp v0.0.0-20211103052201-885b22f77d52/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.1 h1:lzkuHA60pER7L4eYL8qQJor4bUWlJe4V0gqAT19tdOA=
|
github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8=
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.1/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg=
|
github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg=
|
||||||
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4 h1:aYUdiI42a4fWfPoUr25XlaJrFEICv24+o/gWhqYS/jk=
|
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4 h1:aYUdiI42a4fWfPoUr25XlaJrFEICv24+o/gWhqYS/jk=
|
||||||
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4/go.mod h1:oZRCMMRS318l07ei4DTqbZoOawfJlJ4yyo8juk2v4Rk=
|
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4/go.mod h1:oZRCMMRS318l07ei4DTqbZoOawfJlJ4yyo8juk2v4Rk=
|
||||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
@ -88,8 +88,9 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
|||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
@ -259,14 +260,14 @@ github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11
|
|||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||||
github.com/docker/cli v20.10.8+incompatible h1:/zO/6y9IOpcehE49yMRTV9ea0nBpb8OeqSskXLNfH1E=
|
github.com/docker/cli v20.10.11+incompatible h1:tXU1ezXcruZQRrMP8RN2z9N91h+6egZTS1gsPsKantc=
|
||||||
github.com/docker/cli v20.10.8+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v20.10.8+incompatible h1:RVqD337BgQicVCzYrrlhLDWhq6OAD2PJDUg2LsEUvKM=
|
github.com/docker/docker v20.10.11+incompatible h1:OqzI/g/W54LczvhnccGqniFoQghHx3pklbLuhfXpqGo=
|
||||||
github.com/docker/docker v20.10.8+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
|
github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
|
||||||
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
|
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||||
@ -302,7 +303,6 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
|
|||||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
|
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
|
||||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||||
@ -315,8 +315,9 @@ github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui72
|
|||||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
|
||||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
|
github.com/gliderlabs/ssh v0.3.3 h1:mBQ8NiOgDkINJrZtoizkC3nDNYgSaWtxyem6S2XHBtA=
|
||||||
|
github.com/gliderlabs/ssh v0.3.3/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
|
||||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
@ -449,8 +450,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hetznercloud/hcloud-go v1.32.0 h1:7zyN2V7hMlhm3HZdxOarmOtvzKvkcYKjM0hcwYMQZz0=
|
github.com/hetznercloud/hcloud-go v1.33.1 h1:W1HdO2bRLTKU4WsyqAasDSpt54fYO4WNckWYfH5AuCQ=
|
||||||
github.com/hetznercloud/hcloud-go v1.32.0/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME=
|
github.com/hetznercloud/hcloud-go v1.33.1/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME=
|
||||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
|
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
|
||||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
@ -489,8 +490,9 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
|
|||||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
|
github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+mdNo/o=
|
||||||
|
github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
@ -563,8 +565,8 @@ github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7s
|
|||||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||||
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
|
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
|
||||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||||
github.com/moby/sys/signal v0.5.0 h1:MzpEFrMxugDynb1gkTIThU1O3wEmrAkOY+G9dHcHnCc=
|
github.com/moby/sys/signal v0.6.0 h1:aDpY94H8VlhTGa9sNYUFCFsMZIUh5wm0B6XkIoJj/iY=
|
||||||
github.com/moby/sys/signal v0.5.0/go.mod h1:JwObcMnOrUy2VTP5swPKWwywH0Mbgk8Y5qua9iwtIRM=
|
github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
||||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
|
||||||
@ -820,6 +822,7 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
|
|||||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
|
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@ -972,8 +975,9 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg=
|
|
||||||
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik=
|
||||||
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -26,3 +29,68 @@ func NewToken(provider, providerTokenEnvVar string) (string, error) {
|
|||||||
|
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnsureIPv4 ensures that an ipv4 address is set for a domain name
|
||||||
|
func EnsureIPv4(domainName string) (string, error) {
|
||||||
|
var ipv4 string
|
||||||
|
|
||||||
|
// comrade librehosters DNS resolver -> https://www.privacy-handbuch.de/handbuch_93d.htm
|
||||||
|
freifunkDNS := "5.1.66.255:53"
|
||||||
|
|
||||||
|
resolver := &net.Resolver{
|
||||||
|
PreferGo: false,
|
||||||
|
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
d := net.Dialer{
|
||||||
|
Timeout: time.Millisecond * time.Duration(10000),
|
||||||
|
}
|
||||||
|
return d.DialContext(ctx, "udp", freifunkDNS)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("created DNS resolver via '%s'", freifunkDNS)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
ips, err := resolver.LookupIPAddr(ctx, domainName)
|
||||||
|
if err != nil {
|
||||||
|
return ipv4, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ips) == 0 {
|
||||||
|
return ipv4, fmt.Errorf("unable to retrieve ipv4 address for %s", domainName)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv4 = ips[0].IP.To4().String()
|
||||||
|
logrus.Debugf("discovered the following ipv4 addr: %s", ipv4)
|
||||||
|
|
||||||
|
return ipv4, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnsureDomainsResolveSameIPv4 ensures that domains resolve to the same ipv4 address
|
||||||
|
func EnsureDomainsResolveSameIPv4(domainName, server string) (string, error) {
|
||||||
|
var ipv4 string
|
||||||
|
|
||||||
|
domainIPv4, err := EnsureIPv4(domainName)
|
||||||
|
if err != nil {
|
||||||
|
return ipv4, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if domainIPv4 == "" {
|
||||||
|
return ipv4, fmt.Errorf("cannot resolve ipv4 for %s?", domainName)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverIPv4, err := EnsureIPv4(server)
|
||||||
|
if err != nil {
|
||||||
|
return ipv4, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if serverIPv4 == "" {
|
||||||
|
return ipv4, fmt.Errorf("cannot resolve ipv4 for %s?", server)
|
||||||
|
}
|
||||||
|
|
||||||
|
if domainIPv4 != serverIPv4 {
|
||||||
|
err := "app domain %s (%s) does not appear to resolve to app server %s (%s)?"
|
||||||
|
return ipv4, fmt.Errorf(err, domainName, domainIPv4, server, serverIPv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipv4, nil
|
||||||
|
}
|
||||||
|
14
pkg/git/common.go
Normal file
14
pkg/git/common.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnsureGitRepo ensures a git repo .git folder exists
|
||||||
|
func EnsureGitRepo(repoPath string) error {
|
||||||
|
if _, err := os.Stat(repoPath); os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("no .git directory in %s?", repoPath)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
38
pkg/git/init.go
Normal file
38
pkg/git/init.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-git/go-git/v5"
|
||||||
|
gitPkg "github.com/go-git/go-git/v5"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Init inits a new repo and commits all the stuff if you want
|
||||||
|
func Init(repoPath string, commit bool) error {
|
||||||
|
if _, err := gitPkg.PlainInit(repoPath, false); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
logrus.Debugf("initialised new git repo in %s", repoPath)
|
||||||
|
|
||||||
|
if commit {
|
||||||
|
commitRepo, err := git.PlainOpen(repoPath)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
commitWorktree, err := commitRepo.Worktree()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := commitWorktree.AddGlob("**"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = commitWorktree.Commit("init", &git.CommitOptions{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logrus.Debugf("init committed all files for new git repo in %s", repoPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -2,6 +2,7 @@ package recipe
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -95,13 +96,22 @@ func Get(recipeName string) (Recipe, error) {
|
|||||||
return Recipe{Name: recipeName, Config: config}, nil
|
return Recipe{Name: recipeName, Config: config}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureExists checks whether a recipe has been cloned locally or not.
|
// EnsureExists ensures that a recipe is locally cloned
|
||||||
func EnsureExists(recipe string) error {
|
func EnsureExists(recipe string) error {
|
||||||
recipeDir := path.Join(config.ABRA_DIR, "apps", strings.ToLower(recipe))
|
recipeDir := path.Join(config.ABRA_DIR, "apps", strings.ToLower(recipe))
|
||||||
url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipe)
|
|
||||||
if err := gitPkg.Clone(recipeDir, url); err != nil {
|
if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
|
||||||
|
logrus.Debugf("%s does not exist, attemmpting to clone", recipeDir)
|
||||||
|
url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, recipe)
|
||||||
|
if err := gitPkg.Clone(recipeDir, url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +128,10 @@ func EnsureVersion(recipeName, version string) error {
|
|||||||
return fmt.Errorf("'%s' has locally unstaged changes", recipeName)
|
return fmt.Errorf("'%s' has locally unstaged changes", recipeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
repo, err := git.PlainOpen(recipeDir)
|
repo, err := git.PlainOpen(recipeDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -178,6 +192,10 @@ func EnsureLatest(recipeName string) error {
|
|||||||
return fmt.Errorf("'%s' has locally unstaged changes", recipeName)
|
return fmt.Errorf("'%s' has locally unstaged changes", recipeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := gitPkg.EnsureGitRepo(recipeDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
logrus.Debugf("attempting to open git repository in '%s'", recipeDir)
|
logrus.Debugf("attempting to open git repository in '%s'", recipeDir)
|
||||||
|
|
||||||
repo, err := git.PlainOpen(recipeDir)
|
repo, err := git.PlainOpen(recipeDir)
|
||||||
|
@ -409,12 +409,31 @@ func connect(username, host, port string, authMethod ssh.AuthMethod, timeout tim
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connectWithAgentTimeout(host, username, port string, timeout time.Duration) (*Client, error) {
|
func connectWithAgentTimeout(host, username, port string, timeout time.Duration) (*Client, error) {
|
||||||
|
logrus.Debugf("using ssh-agent to make an SSH connection for %s", host)
|
||||||
|
|
||||||
sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
|
sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
authMethod := ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)
|
agentCl := agent.NewClient(sshAgent)
|
||||||
|
authMethod := ssh.PublicKeysCallback(agentCl.Signers)
|
||||||
|
|
||||||
|
loadedKeys, err := agentCl.List()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var convertedKeys []string
|
||||||
|
for _, key := range loadedKeys {
|
||||||
|
convertedKeys = append(convertedKeys, key.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(convertedKeys) > 0 {
|
||||||
|
logrus.Debugf("ssh-agent has these keys loaded: %s", strings.Join(convertedKeys, ","))
|
||||||
|
} else {
|
||||||
|
logrus.Debug("ssh-agent has no keys loaded")
|
||||||
|
}
|
||||||
|
|
||||||
return connect(username, host, port, authMethod, timeout)
|
return connect(username, host, port, authMethod, timeout)
|
||||||
}
|
}
|
||||||
@ -544,11 +563,16 @@ func GetHostConfig(hostname, username, port string) (HostConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
idf = ssh_config.Get(hostname, "IdentityFile")
|
idf = ssh_config.Get(hostname, "IdentityFile")
|
||||||
|
|
||||||
hostConfig.Host = host
|
|
||||||
if idf != "" {
|
if idf != "" {
|
||||||
|
var err error
|
||||||
|
idf, err = identityFileAbsPath(idf)
|
||||||
|
if err != nil {
|
||||||
|
return hostConfig, err
|
||||||
|
}
|
||||||
hostConfig.IdentityFile = idf
|
hostConfig.IdentityFile = idf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostConfig.Host = host
|
||||||
hostConfig.Port = port
|
hostConfig.Port = port
|
||||||
hostConfig.User = username
|
hostConfig.User = username
|
||||||
|
|
||||||
@ -556,3 +580,25 @@ func GetHostConfig(hostname, username, port string) (HostConfig, error) {
|
|||||||
|
|
||||||
return hostConfig, nil
|
return hostConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func identityFileAbsPath(relPath string) (string, error) {
|
||||||
|
var err error
|
||||||
|
var absPath string
|
||||||
|
|
||||||
|
if strings.HasPrefix(relPath, "~/") {
|
||||||
|
systemUser, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
return absPath, err
|
||||||
|
}
|
||||||
|
absPath = filepath.Join(systemUser.HomeDir, relPath[2:])
|
||||||
|
} else {
|
||||||
|
absPath, err = filepath.Abs(relPath)
|
||||||
|
if err != nil {
|
||||||
|
return absPath, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("resolved %s to %s to read the ssh identity file", relPath, absPath)
|
||||||
|
|
||||||
|
return absPath, nil
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package commandconn
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
@ -34,9 +35,25 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*connhelper.Conne
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "ssh host connection is not valid")
|
return nil, errors.Wrap(err, "ssh host connection is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sshPkg.EnsureHostKey(ctxConnDetails.Host); err != nil {
|
if err := sshPkg.EnsureHostKey(ctxConnDetails.Host); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostConfig, err := sshPkg.GetHostConfig(
|
||||||
|
ctxConnDetails.Host,
|
||||||
|
ctxConnDetails.User,
|
||||||
|
ctxConnDetails.Port,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if hostConfig.IdentityFile != "" {
|
||||||
|
msg := "discovered %s as identity file for %s, using for ssh connection"
|
||||||
|
logrus.Debugf(msg, hostConfig.IdentityFile, ctxConnDetails.Host)
|
||||||
|
sshFlags = append(sshFlags, fmt.Sprintf("-o IdentityFile=%s", hostConfig.IdentityFile))
|
||||||
|
}
|
||||||
|
|
||||||
return &connhelper.ConnectionHelper{
|
return &connhelper.ConnectionHelper{
|
||||||
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
return New(ctx, "ssh", append(sshFlags, ctxConnDetails.Args("docker", "system", "dial-stdio")...)...)
|
return New(ctx, "ssh", append(sshFlags, ctxConnDetails.Args("docker", "system", "dial-stdio")...)...)
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
abraClient "coopcloud.tech/abra/pkg/client"
|
abraClient "coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/upstream/convert"
|
"coopcloud.tech/abra/pkg/upstream/convert"
|
||||||
@ -479,5 +480,13 @@ func waitOnService(ctx context.Context, cl *dockerclient.Client, serviceID strin
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
go io.Copy(ioutil.Discard, pipeReader)
|
go io.Copy(ioutil.Discard, pipeReader)
|
||||||
return <-errChan
|
|
||||||
|
timeout := 60 * time.Second
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err := <-errChan:
|
||||||
|
return err
|
||||||
|
case <-time.After(timeout):
|
||||||
|
return fmt.Errorf("%s has still not converged (%s second timeout)?", serviceID, timeout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
3
renovate.json
Normal file
3
renovate.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
ABRA_VERSION="0.3.0-alpha"
|
ABRA_VERSION="0.3.0-alpha"
|
||||||
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
|
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
|
||||||
RC_VERSION="0.3.1-alpha-rc1"
|
RC_VERSION="0.3.1-alpha-rc2"
|
||||||
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION"
|
RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION"
|
||||||
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
|
Reference in New Issue
Block a user