Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ecsta cp command #61

Merged
merged 12 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: "1.23"
go-version-file: ./go.mod
cache: true
- name: download
run: |
go mod download
make download-assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
Expand Down
12 changes: 8 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v4
go-version-file: ./go.mod
cache: true

- name: Build & Test
run: |
go mod download
make download-assets
go test -race -v ./...
env:
TZ: Asia/Tokyo # for time.Local
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.PHONY: test install clean

TNCL_VERSION=v0.0.4

test:
TZ=Asia/Tokyo go test ./...

Expand All @@ -10,4 +12,10 @@ dist/:
goreleaser build --snapshot --rm-dist

clean:
rm -fr dist/
rm -fr dist/ assets/*

download-assets:
cd assets && \
gh release download $(TNCL_VERSION) \
--repo fujiwara/tncl \
--pattern 'tncl-*-linux-musl'
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,54 @@ Flags:

When `--start-time` and `--follow` is specified both, `--start-time` may not work correctly.

### copy files

```console
Usage: ecsta cp <src> <dest> [flags]

Copy files from/to a task

Arguments:
<src> Source
<dest> Destination

Flags:
--port=12345 port number for file transfer
--[no-]progress show progress bar
--id=STRING task ID
--container=STRING container name
--family=FAMILY task definition family name
--service=SERVICE ECS service name
```

Example:

```console
$ ecsta cp /path/to/file.txt _:/tmp/file.txt # copy file to a task(_ is the selected task)
$ ecsta cp 75dc060ef49b4ba1b2a33581dc5b876f:/tmp/file.txt /path/to/file.txt # copy file from the task.
```

`ecsta cp` copies files from/to a task.

#### How to work `ecsta cp`

`ecsta cp` works as below.

1. `ecsta` starts a temporary TCP server on the task vie ECS Exec.
- The server listens on the specified port (default is 12345).
- [tncl](https://github.com/fujiwara/tncl) is used as the server. It is a tiny TCP server that like `nc -l` command.
- The server is terminated when the file transfer is completed.
2. `ecsta` starts a port forwarding to the temporary server.
3. `ecsta` connects to the temporary server via the port forwarding.
4. `ecsta` sends or receives a file via the connection.

Requirements:
- The task must have the ECS Exec feature enabled.
- The task must have `sh`, `base64`, and `chmod` commands.

Limitations:
- Multiple files and directories are not supported.

### `--task-format-query(-q)` option

This option provides a formatter by [jq](https://stedolan.github.io/jq/) query. The query processes tasks JSON (that output equals to ecsta describe) in task selector outputs.
Expand Down
1 change: 1 addition & 0 deletions assets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
Empty file added assets/.gitkeep
Empty file.
11 changes: 11 additions & 0 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ecsta
import (
"context"
"fmt"
"log/slog"
"strings"

"github.com/alecthomas/kong"
Expand All @@ -13,6 +14,7 @@ type CLI struct {
Region string `help:"AWS region" short:"r" env:"AWS_REGION"`
Output string `help:"output format (table, tsv, json)" short:"o" default:"table" enum:"table,tsv,json" env:"ECSTA_OUTPUT"`
TaskFormatQuery string `help:"A jq query to format task in selector" short:"q" env:"ECSTA_TASK_FORMAT_QUERY"`
Debug bool `help:"enable debug output" env:"ECSTA_DEBUG"`

Configure *ConfigureOption `cmd:"" help:"Create a configuration file of ecsta"`
Describe *DescribeOption `cmd:"" help:"Describe tasks"`
Expand All @@ -22,6 +24,7 @@ type CLI struct {
Portforward *PortforwardOption `cmd:"" help:"Forward a port of a task"`
Stop *StopOption `cmd:"" help:"Stop a task"`
Trace *TraceOption `cmd:"" help:"Trace a task"`
CP *CpOption `cmd:"" help:"Copy files from/to a task"`
Version struct{} `cmd:"" help:"Show version"`
}

Expand All @@ -35,6 +38,12 @@ func RunCLI(ctx context.Context, args []string) error {
if err != nil {
return err
}
if cli.Debug {
slog.SetLogLoggerLevel(slog.LevelDebug)
} else {
slog.SetLogLoggerLevel(slog.LevelInfo)
}

app, err := New(ctx, cli.Region, cli.Cluster)
if err != nil {
return err
Expand Down Expand Up @@ -62,6 +71,8 @@ func (app *Ecsta) Dispatch(ctx context.Context, command string, cli *CLI) error
return app.RunStop(ctx, cli.Stop)
case "trace":
return app.RunTrace(ctx, cli.Trace)
case "cp":
return app.RunCp(ctx, cli.CP)
case "version":
fmt.Printf("ecsta %s\n", Version)
return nil
Expand Down
Loading
Loading