2021-08-02 01:10:41 +00:00
|
|
|
package app
|
|
|
|
|
|
|
|
import (
|
2021-08-29 16:21:30 +00:00
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"coopcloud.tech/abra/cli/internal"
|
2021-09-05 19:37:03 +00:00
|
|
|
"coopcloud.tech/abra/pkg/client"
|
|
|
|
"coopcloud.tech/abra/pkg/client/container"
|
|
|
|
"coopcloud.tech/abra/pkg/config"
|
2021-08-29 19:20:21 +00:00
|
|
|
"github.com/docker/cli/cli/command"
|
2021-08-29 16:21:30 +00:00
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/filters"
|
|
|
|
"github.com/sirupsen/logrus"
|
2021-08-02 01:10:41 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
)
|
|
|
|
|
2021-08-02 06:36:35 +00:00
|
|
|
var user string
|
|
|
|
var userFlag = &cli.StringFlag{
|
|
|
|
Name: "user",
|
|
|
|
Value: "",
|
|
|
|
Destination: &user,
|
|
|
|
}
|
|
|
|
|
|
|
|
var noTTY bool
|
|
|
|
var noTTYFlag = &cli.BoolFlag{
|
|
|
|
Name: "no-tty",
|
|
|
|
Value: false,
|
|
|
|
Destination: &noTTY,
|
|
|
|
}
|
|
|
|
|
2021-08-02 01:10:41 +00:00
|
|
|
var appRunCommand = &cli.Command{
|
|
|
|
Name: "run",
|
|
|
|
Flags: []cli.Flag{
|
2021-08-02 06:36:35 +00:00
|
|
|
noTTYFlag,
|
|
|
|
userFlag,
|
2021-08-02 01:10:41 +00:00
|
|
|
},
|
2021-09-04 23:34:56 +00:00
|
|
|
Aliases: []string{"r"},
|
2021-08-02 01:10:41 +00:00
|
|
|
ArgsUsage: "<service> <args>...",
|
2021-09-04 23:34:56 +00:00
|
|
|
Usage: "Run a command in a service container",
|
2021-08-29 16:21:30 +00:00
|
|
|
Action: func(c *cli.Context) error {
|
2021-09-05 20:04:48 +00:00
|
|
|
appName := internal.ValidateAppNameArg(c)
|
2021-08-29 16:21:30 +00:00
|
|
|
|
|
|
|
if c.Args().Len() < 2 {
|
|
|
|
internal.ShowSubcommandHelpAndError(c, errors.New("no <service> provided"))
|
|
|
|
}
|
|
|
|
|
|
|
|
appFiles, err := config.LoadAppFiles("")
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2021-09-04 22:41:31 +00:00
|
|
|
server := appFiles[appName].Server
|
2021-08-29 16:21:30 +00:00
|
|
|
ctx := context.Background()
|
2021-09-04 22:41:31 +00:00
|
|
|
cl, err := client.New(server)
|
2021-08-29 16:21:30 +00:00
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
appEnv, err := config.GetApp(appFiles, appName)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
serviceName := c.Args().Get(1)
|
|
|
|
filters := filters.NewArgs()
|
|
|
|
filters.Add("name", fmt.Sprintf("%s_%s", appEnv.StackName(), serviceName))
|
|
|
|
|
|
|
|
containers, err := cl.ContainerList(ctx, types.ContainerListOptions{Filters: filters})
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
if len(containers) > 1 {
|
|
|
|
logrus.Fatalf("expected 1 container but got %d", len(containers))
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd := c.Args().Slice()[2:]
|
|
|
|
execCreateOpts := types.ExecConfig{
|
2021-08-29 19:20:21 +00:00
|
|
|
AttachStderr: true,
|
|
|
|
AttachStdin: true,
|
|
|
|
AttachStdout: true,
|
|
|
|
Cmd: cmd,
|
|
|
|
Detach: false,
|
|
|
|
Tty: true,
|
2021-08-29 16:21:30 +00:00
|
|
|
}
|
2021-08-29 19:20:21 +00:00
|
|
|
|
2021-08-29 16:21:30 +00:00
|
|
|
if user != "" {
|
|
|
|
execCreateOpts.User = user
|
|
|
|
}
|
|
|
|
if noTTY {
|
|
|
|
execCreateOpts.Tty = false
|
|
|
|
}
|
|
|
|
|
2021-08-29 19:20:21 +00:00
|
|
|
// FIXME: an absolutely monumental hack to instantiate another command-line
|
|
|
|
// client withing our command-line client so that we pass something down
|
|
|
|
// the tubes that satisfies the necessary interface requirements. We should
|
|
|
|
// refactor our vendored container code to not require all this cruft. For
|
|
|
|
// now, It Works.
|
|
|
|
dcli, err := command.NewDockerCli()
|
|
|
|
if err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := container.RunExec(dcli, cl, containers[0].ID, &execCreateOpts); err != nil {
|
|
|
|
logrus.Fatal(err)
|
|
|
|
}
|
2021-08-29 16:21:30 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
2021-08-02 01:10:41 +00:00
|
|
|
}
|