/
run.go
27 lines (22 loc) · 906 Bytes
/
run.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package lock
import (
"context"
"fmt"
"os/exec"
"strings"
"time"
)
// Run acquires a lock under the specified key, executes the command, and then unlocks the key.
// Returns ErrLocked if the key is already locked. Otherwise returns combined stdout and stderr
// of the command and the command error. If the unlock step fails the lock expires after 24 hours.
func (c *Client) Run(ctx context.Context, key, command string) (string, error) {
// use context.Background here so that unlock runs even if the context is cancelled
defer c.Unlock(context.Background(), key) //nolint:errcheck
err := c.Lock(ctx, key, time.Hour*24) //nolint:gomnd
if err != nil {
return "", fmt.Errorf("lock failed: %w", err)
}
fields := strings.Fields(command)
cmdout, cmderr := exec.CommandContext(ctx, fields[0], fields[1:]...).CombinedOutput() //nolint:gosec
return strings.TrimSpace(string(cmdout)), cmderr
}