feat: add app cp command
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
16297e8651
commit
547f785da5
2
TODO.md
2
TODO.md
|
@ -19,7 +19,7 @@
|
|||
- [x] `check`
|
||||
- [x] `version`
|
||||
- [x] `config`
|
||||
- [ ] `cp` (WIP: decentral1se)
|
||||
- [x] `cp`
|
||||
- [ ] `logs`
|
||||
- [x] `ps`
|
||||
- [ ] `restore`
|
||||
|
|
118
cli/app/cp.go
118
cli/app/cp.go
|
@ -1,8 +1,124 @@
|
|||
package app
|
||||
|
||||
import "github.com/urfave/cli/v2"
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/client"
|
||||
"coopcloud.tech/abra/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"
|
||||
)
|
||||
|
||||
var appCpCommand = &cli.Command{
|
||||
Name: "cp",
|
||||
ArgsUsage: "<src> <dst>",
|
||||
Usage: "copy files to/from running service container",
|
||||
Action: func(c *cli.Context) error {
|
||||
appName := c.Args().First()
|
||||
if appName == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("no app name provided"))
|
||||
}
|
||||
|
||||
src := c.Args().Get(1)
|
||||
dst := c.Args().Get(2)
|
||||
if src == "" {
|
||||
logrus.Fatal("missing <src> argument")
|
||||
} else if dst == "" {
|
||||
logrus.Fatal("missing <dest> argument")
|
||||
}
|
||||
|
||||
parsedSrc := strings.SplitN(src, ":", 2)
|
||||
parsedDst := strings.SplitN(dst, ":", 2)
|
||||
errorMsg := "one of <src>/<dest> arguments must take $SERVICE:$PATH form"
|
||||
if len(parsedSrc) == 2 && len(parsedDst) == 2 {
|
||||
logrus.Fatal(errorMsg)
|
||||
} else if len(parsedSrc) != 2 {
|
||||
if len(parsedDst) != 2 {
|
||||
logrus.Fatal(errorMsg)
|
||||
}
|
||||
} else if len(parsedDst) != 2 {
|
||||
if len(parsedSrc) != 2 {
|
||||
logrus.Fatal(errorMsg)
|
||||
}
|
||||
}
|
||||
|
||||
var service string
|
||||
var srcPath string
|
||||
var dstPath string
|
||||
isToContainer := false // <container:src> <dst>
|
||||
if len(parsedSrc) == 2 {
|
||||
service = parsedSrc[0]
|
||||
srcPath = parsedSrc[1]
|
||||
dstPath = dst
|
||||
} else if len(parsedDst) == 2 {
|
||||
service = parsedDst[0]
|
||||
dstPath = parsedDst[1]
|
||||
srcPath = src
|
||||
isToContainer = true // <src> <container:dst>
|
||||
}
|
||||
|
||||
appFiles, err := config.LoadAppFiles("")
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
appEnv, err := config.GetApp(appFiles, appName)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
host := appFiles[appName].Server
|
||||
cl, err := client.NewClientWithContext(host)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
filters := filters.NewArgs()
|
||||
filters.Add("name", fmt.Sprintf("%s_%s", appEnv.StackName(), service))
|
||||
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 %v", len(containers))
|
||||
}
|
||||
container := containers[0]
|
||||
|
||||
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(ctx, container.ID, dstPath, content, copyOpts); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
content, _, err := cl.CopyFromContainer(ctx, container.ID, srcPath)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
fromTarOpts := &archive.TarOptions{NoOverwriteDirNonDir: true, Compression: archive.Gzip}
|
||||
archive.Untar(content, dstPath, fromTarOpts)
|
||||
defer content.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
6
go.sum
6
go.sum
|
@ -21,8 +21,6 @@ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIA
|
|||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
coopcloud.tech/tagcmp v0.0.0-20210809131701-f81a7c03b97c h1:j4y6MBImeCU/nH7vFt9vIkFKJFcbtdSHk3OST79Mfj4=
|
||||
coopcloud.tech/tagcmp v0.0.0-20210809131701-f81a7c03b97c/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
||||
coopcloud.tech/tagcmp v0.0.0-20210813114741-44053d6bfba1 h1:C9PonNP/Y+X3GXarmk4Mn+XeAokspS8Ov1x2GtRzVtI=
|
||||
coopcloud.tech/tagcmp v0.0.0-20210813114741-44053d6bfba1/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
|
@ -146,6 +144,7 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1
|
|||
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||
github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5vHQ=
|
||||
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
|
@ -359,6 +358,7 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
|
|||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
|
@ -588,6 +588,7 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P
|
|||
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
||||
github.com/opencontainers/runc v1.0.1 h1:G18PGckGdAm3yVQRWDVQ1rLSLntiniKJ0cNRT2Tm5gs=
|
||||
github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
|
@ -758,6 +759,7 @@ go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvS
|
|||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
|
Loading…
Reference in New Issue