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

support of mcopy command type #56

Merged
merged 1 commit into from
May 3, 2023
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ Spot supports the following command types:

- `script`: can be any valid shell script. The script will be executed on the remote host(s) using SSH, inside a shell.
- `copy`: copies a file from the local machine to the remote host(s). Example: `copy: {"src": "testdata/conf.yml", "dst": "/tmp/conf.yml", "mkdir": true}`. If `mkdir` is set to `true` the command will create the destination directory if it doesn't exist, same as `mkdir -p` in bash.
- `mcopy`: copies multiple files from the local machine to the remote host(s). Example: `mcopy: [{"src": "testdata/1.yml", "dst": "/tmp/1.yml", "mkdir": true}, {"src": "testdata/1.txt", "dst": "/tmp/1.txt"}]`. This is just a shortcut for multiple `copy` commands.
- `sync`: syncs directory from the local machine to the remote host(s). Optionally supports deleting files on the remote host(s) that don't exist locally. Example: `sync: {"src": "testdata", "dst": "/tmp/things", "delete": true}`
- `delete`: deletes a file or directory on the remote host(s), optionally can remove recursively. Example: `delete: {"path": "/tmp/things", "recur": true}`
- `wait`: waits for the specified command to finish on the remote host(s) with 0 error code. This command is useful when you need to wait for a service to start before executing the next command. Allows to specify the timeout as well as check interval. Example: `wait: {"cmd": "curl -s --fail localhost:8080", "timeout": "30s", "interval": "1s"}`
Expand Down
1 change: 1 addition & 0 deletions app/config/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
type Cmd struct {
Name string `yaml:"name" toml:"name"`
Copy CopyInternal `yaml:"copy" toml:"copy"`
MCopy []CopyInternal `yaml:"mcopy" toml:"mcopy"`
Sync SyncInternal `yaml:"sync" toml:"sync"`
Delete DeleteInternal `yaml:"delete" toml:"delete"`
Wait WaitInternal `yaml:"wait" toml:"wait"`
Expand Down
16 changes: 15 additions & 1 deletion app/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func (p *Process) execCommand(ctx context.Context, ep execCmdParams) (details st
return details, fmt.Errorf("can't run script on %s: %w", ep.hostAddr, err)
}
case ep.cmd.Copy.Source != "" && ep.cmd.Copy.Dest != "":
log.Printf("[DEBUG] copy file on %s", ep.hostAddr)
log.Printf("[DEBUG] copy file to %s", ep.hostAddr)
src := p.applyTemplates(ep.cmd.Copy.Source,
templateData{hostAddr: ep.hostAddr, hostName: ep.hostName, task: ep.tsk, command: ep.cmd.Name})
dst := p.applyTemplates(ep.cmd.Copy.Dest,
Expand All @@ -206,6 +206,20 @@ func (p *Process) execCommand(ctx context.Context, ep execCmdParams) (details st
if err := ep.exec.Upload(ctx, src, dst, ep.cmd.Copy.Mkdir); err != nil {
return details, fmt.Errorf("can't copy file on %s: %w", ep.hostAddr, err)
}
case len(ep.cmd.MCopy) > 0:
log.Printf("[DEBUG] copy multiple files to %s", ep.hostAddr)
msgs := []string{}
for _, c := range ep.cmd.MCopy {
src := p.applyTemplates(c.Source,
templateData{hostAddr: ep.hostAddr, hostName: ep.hostName, task: ep.tsk, command: ep.cmd.Name})
dst := p.applyTemplates(c.Dest,
templateData{hostAddr: ep.hostAddr, hostName: ep.hostName, task: ep.tsk, command: ep.cmd.Name})
msgs = append(msgs, fmt.Sprintf("%s -> %s", src, dst))
if err := ep.exec.Upload(ctx, src, dst, c.Mkdir); err != nil {
return details, fmt.Errorf("can't copy file on %s: %w", ep.hostAddr, err)
}
}
details = fmt.Sprintf(" {copy: %s}", strings.Join(msgs, ", "))
case ep.cmd.Sync.Source != "" && ep.cmd.Sync.Dest != "":
log.Printf("[DEBUG] sync files on %s", ep.hostAddr)
src := p.applyTemplates(ep.cmd.Sync.Source,
Expand Down
6 changes: 3 additions & 3 deletions app/runner/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestProcess_Run(t *testing.T) {
}
res, err := p.Run(ctx, "task1", hostAndPort)
require.NoError(t, err)
assert.Equal(t, 6, res.Commands)
assert.Equal(t, 7, res.Commands)
assert.Equal(t, 1, res.Hosts)
}

Expand Down Expand Up @@ -82,7 +82,7 @@ func TestProcess_RunDry(t *testing.T) {
}
res, err := p.Run(ctx, "task1", hostAndPort)
require.NoError(t, err)
assert.Equal(t, 6, res.Commands)
assert.Equal(t, 7, res.Commands)
assert.Equal(t, 1, res.Hosts)
}

Expand Down Expand Up @@ -151,7 +151,7 @@ func TestProcess_RunSkip(t *testing.T) {
}
res, err := p.Run(ctx, "task1", hostAndPort)
require.NoError(t, err)
assert.Equal(t, 4, res.Commands)
assert.Equal(t, 5, res.Commands)
assert.Equal(t, 1, res.Hosts)
}

Expand Down
5 changes: 5 additions & 0 deletions app/runner/testdata/conf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ tasks:
- name: copy configuration
copy: {"src": "testdata/conf.yml", "dst": "/tmp/conf.yml", "mkdir": true}

- name: copy multiple files
mcopy:
- {src: "testdata/conf2.yml", dst: "/tmp/conf2.yml"}
- {src: "testdata/conf-local.yml", dst: "/tmp/conf3.yml"}

- name: sync things
sync: {"src": "testdata", "dst": "/tmp/things"}

Expand Down