refactor(cmd): move RunCmdRemote EnsureCommand
This commit is contained in:
parent
5e508538f3
commit
ea09e65f1d
100
cli/app/cmd.go
100
cli/app/cmd.go
@ -1,10 +1,8 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
@ -14,14 +12,6 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
containerPkg "coopcloud.tech/abra/pkg/container"
|
|
||||||
"coopcloud.tech/abra/pkg/formatter"
|
|
||||||
"coopcloud.tech/abra/pkg/upstream/container"
|
|
||||||
"github.com/docker/cli/cli/command"
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/filters"
|
|
||||||
dockerClient "github.com/docker/docker/client"
|
|
||||||
"github.com/docker/docker/pkg/archive"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -75,7 +65,7 @@ Example:
|
|||||||
|
|
||||||
if internal.LocalCmd {
|
if internal.LocalCmd {
|
||||||
cmdName := c.Args().Get(1)
|
cmdName := c.Args().Get(1)
|
||||||
if err := ensureCommand(abraSh, app.Recipe, cmdName); err != nil {
|
if err := internal.EnsureCommand(abraSh, app.Recipe, cmdName); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +98,7 @@ Example:
|
|||||||
targetServiceName := c.Args().Get(1)
|
targetServiceName := c.Args().Get(1)
|
||||||
|
|
||||||
cmdName := c.Args().Get(2)
|
cmdName := c.Args().Get(2)
|
||||||
if err := ensureCommand(abraSh, app.Recipe, cmdName); err != nil {
|
if err := internal.EnsureCommand(abraSh, app.Recipe, cmdName); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +126,7 @@ Example:
|
|||||||
logrus.Debug("did not detect any command arguments")
|
logrus.Debug("did not detect any command arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runCmdRemote(cl, app, abraSh, targetServiceName, cmdName, parsedCmdArgs); err != nil {
|
if err := internal.RunCmdRemote(cl, app, abraSh, targetServiceName, cmdName, parsedCmdArgs); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,87 +153,3 @@ func parseCmdArgs(args []string, isLocal bool) (bool, string) {
|
|||||||
|
|
||||||
return hasCmdArgs, parsedCmdArgs
|
return hasCmdArgs, parsedCmdArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureCommand(abraSh, recipeName, execCmd string) error {
|
|
||||||
bytes, err := ioutil.ReadFile(abraSh)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(string(bytes), execCmd) {
|
|
||||||
return fmt.Errorf("%s doesn't have a %s function", recipeName, execCmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func runCmdRemote(cl *dockerClient.Client, app config.App, abraSh, serviceName, cmdName, cmdArgs string) error {
|
|
||||||
filters := filters.NewArgs()
|
|
||||||
filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(), serviceName))
|
|
||||||
|
|
||||||
targetContainer, err := containerPkg.GetContainer(context.Background(), cl, filters, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.Debugf("retrieved %s as target container on %s", formatter.ShortenID(targetContainer.ID), app.Server)
|
|
||||||
|
|
||||||
toTarOpts := &archive.TarOptions{NoOverwriteDirNonDir: true, Compression: archive.Gzip}
|
|
||||||
content, err := archive.TarWithOptions(abraSh, toTarOpts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
copyOpts := types.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false}
|
|
||||||
if err := cl.CopyToContainer(context.Background(), targetContainer.ID, "/tmp", content, copyOpts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: avoid instantiating a new CLI
|
|
||||||
dcli, err := command.NewDockerCli()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
shell := "/bin/bash"
|
|
||||||
findShell := []string{"test", "-e", shell}
|
|
||||||
execCreateOpts := types.ExecConfig{
|
|
||||||
AttachStderr: true,
|
|
||||||
AttachStdin: true,
|
|
||||||
AttachStdout: true,
|
|
||||||
Cmd: findShell,
|
|
||||||
Detach: false,
|
|
||||||
Tty: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := container.RunExec(dcli, cl, targetContainer.ID, &execCreateOpts); err != nil {
|
|
||||||
logrus.Infof("%s does not exist for %s, use /bin/sh as fallback", shell, app.Name)
|
|
||||||
shell = "/bin/sh"
|
|
||||||
}
|
|
||||||
|
|
||||||
var cmd []string
|
|
||||||
if cmdArgs != "" {
|
|
||||||
cmd = []string{shell, "-c", fmt.Sprintf("TARGET=%s; APP_NAME=%s; STACK_NAME=%s; . /tmp/abra.sh; %s %s", serviceName, app.Name, app.StackName(), cmdName, cmdArgs)}
|
|
||||||
} else {
|
|
||||||
cmd = []string{shell, "-c", fmt.Sprintf("TARGET=%s; APP_NAME=%s; STACK_NAME=%s; . /tmp/abra.sh; %s", serviceName, app.Name, app.StackName(), cmdName)}
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.Debugf("running command: %s", strings.Join(cmd, " "))
|
|
||||||
|
|
||||||
if internal.RemoteUser != "" {
|
|
||||||
logrus.Debugf("running command with user %s", internal.RemoteUser)
|
|
||||||
execCreateOpts.User = internal.RemoteUser
|
|
||||||
}
|
|
||||||
|
|
||||||
execCreateOpts.Cmd = cmd
|
|
||||||
execCreateOpts.Tty = true
|
|
||||||
if internal.Tty {
|
|
||||||
execCreateOpts.Tty = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := container.RunExec(dcli, cl, targetContainer.ID, &execCreateOpts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -2,10 +2,108 @@ package internal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"coopcloud.tech/abra/pkg/config"
|
||||||
|
containerPkg "coopcloud.tech/abra/pkg/container"
|
||||||
|
"coopcloud.tech/abra/pkg/formatter"
|
||||||
|
"coopcloud.tech/abra/pkg/upstream/container"
|
||||||
|
"github.com/docker/cli/cli/command"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
dockerClient "github.com/docker/docker/client"
|
||||||
|
"github.com/docker/docker/pkg/archive"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func RunCmdRemote(cl *dockerClient.Client, app config.App, abraSh, serviceName, cmdName, cmdArgs string) error {
|
||||||
|
filters := filters.NewArgs()
|
||||||
|
filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(), serviceName))
|
||||||
|
|
||||||
|
targetContainer, err := containerPkg.GetContainer(context.Background(), cl, filters, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("retrieved %s as target container on %s", formatter.ShortenID(targetContainer.ID), app.Server)
|
||||||
|
|
||||||
|
toTarOpts := &archive.TarOptions{NoOverwriteDirNonDir: true, Compression: archive.Gzip}
|
||||||
|
content, err := archive.TarWithOptions(abraSh, toTarOpts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
copyOpts := types.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false}
|
||||||
|
if err := cl.CopyToContainer(context.Background(), targetContainer.ID, "/tmp", content, copyOpts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: avoid instantiating a new CLI
|
||||||
|
dcli, err := command.NewDockerCli()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
shell := "/bin/bash"
|
||||||
|
findShell := []string{"test", "-e", shell}
|
||||||
|
execCreateOpts := types.ExecConfig{
|
||||||
|
AttachStderr: true,
|
||||||
|
AttachStdin: true,
|
||||||
|
AttachStdout: true,
|
||||||
|
Cmd: findShell,
|
||||||
|
Detach: false,
|
||||||
|
Tty: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := container.RunExec(dcli, cl, targetContainer.ID, &execCreateOpts); err != nil {
|
||||||
|
logrus.Infof("%s does not exist for %s, use /bin/sh as fallback", shell, app.Name)
|
||||||
|
shell = "/bin/sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd []string
|
||||||
|
if cmdArgs != "" {
|
||||||
|
cmd = []string{shell, "-c", fmt.Sprintf("TARGET=%s; APP_NAME=%s; STACK_NAME=%s; . /tmp/abra.sh; %s %s", serviceName, app.Name, app.StackName(), cmdName, cmdArgs)}
|
||||||
|
} else {
|
||||||
|
cmd = []string{shell, "-c", fmt.Sprintf("TARGET=%s; APP_NAME=%s; STACK_NAME=%s; . /tmp/abra.sh; %s", serviceName, app.Name, app.StackName(), cmdName)}
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("running command: %s", strings.Join(cmd, " "))
|
||||||
|
|
||||||
|
if RemoteUser != "" {
|
||||||
|
logrus.Debugf("running command with user %s", RemoteUser)
|
||||||
|
execCreateOpts.User = RemoteUser
|
||||||
|
}
|
||||||
|
|
||||||
|
execCreateOpts.Cmd = cmd
|
||||||
|
execCreateOpts.Tty = true
|
||||||
|
if Tty {
|
||||||
|
execCreateOpts.Tty = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := container.RunExec(dcli, cl, targetContainer.ID, &execCreateOpts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureCommand(abraSh, recipeName, execCmd string) error {
|
||||||
|
bytes, err := ioutil.ReadFile(abraSh)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(string(bytes), execCmd) {
|
||||||
|
return fmt.Errorf("%s doesn't have a %s function", recipeName, execCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// RunCmd runs a shell command and streams stdout/stderr in real-time.
|
// RunCmd runs a shell command and streams stdout/stderr in real-time.
|
||||||
func RunCmd(cmd *exec.Cmd) error {
|
func RunCmd(cmd *exec.Cmd) error {
|
||||||
r, err := cmd.StdoutPipe()
|
r, err := cmd.StdoutPipe()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user