|
|
|
@ -0,0 +1,95 @@
|
|
|
|
|
package app
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"coopcloud.tech/abra/cli/internal"
|
|
|
|
|
"coopcloud.tech/abra/pkg/config"
|
|
|
|
|
"coopcloud.tech/abra/pkg/upstream/container"
|
|
|
|
|
"github.com/docker/cli/cli/command"
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var appEditCommand = &cli.Command{
|
|
|
|
|
Name: "edit-file",
|
|
|
|
|
Aliases: []string{"e", "edit"},
|
|
|
|
|
Usage: "Edit a file in the container",
|
|
|
|
|
Description: `
|
|
|
|
|
This command allows you to edit files inside a runnning container. This is
|
|
|
|
|
usually discouraged but sometimes necessary. Syntax:
|
|
|
|
|
|
|
|
|
|
abra app edit-file <app> <service> <file>
|
|
|
|
|
|
|
|
|
|
i.e.
|
|
|
|
|
abra app edit-file traefik_example_com app /etc/passwd
|
|
|
|
|
|
|
|
|
|
It will automatically get the ownership and access rights of the file using
|
|
|
|
|
stat inside the container and then run chmod and chown after sending the file.
|
|
|
|
|
`,
|
|
|
|
|
Action: func(c *cli.Context) error {
|
|
|
|
|
app := internal.ValidateApp(c)
|
|
|
|
|
|
|
|
|
|
service := c.Args().Get(1)
|
|
|
|
|
file := c.Args().Get(2)
|
|
|
|
|
if file == "" {
|
|
|
|
|
logrus.Fatal("missing <file> argument")
|
|
|
|
|
} else if service == "" {
|
|
|
|
|
logrus.Fatal("missing <service> argument")
|
|
|
|
|
}
|
|
|
|
|
splitpath := strings.Split(file, "/")
|
|
|
|
|
filename := splitpath[len(splitpath)-1]
|
|
|
|
|
editDir := fmt.Sprintf("%s/tmp/edits/%s_%s", config.ABRA_DIR, app.Name, service)
|
|
|
|
|
if err := os.MkdirAll(editDir, 0755); err != nil {
|
|
|
|
|
logrus.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("Success!!")
|
|
|
|
|
fmt.Println(editDir)
|
|
|
|
|
err := internal.ConfigureAndCp(c, app, file, editDir, service, false)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logrus.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pull stuff from stat
|
|
|
|
|
cmd := []string{"stat", "-c", "%a", file}
|
|
|
|
|
execCreateOpts := types.ExecConfig{
|
|
|
|
|
AttachStderr: true,
|
|
|
|
|
AttachStdin: true,
|
|
|
|
|
AttachStdout: true,
|
|
|
|
|
Cmd: cmd,
|
|
|
|
|
Detach: false,
|
|
|
|
|
Tty: true,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|