mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
etcdctl: support exec on lock
The lock command is clumsy to use from the command line, needing mkfifo, wait, etc. Instead, make like consul and support launching a command if one is given.
This commit is contained in:
parent
8c1ab62bc5
commit
643c2a310d
@ -790,7 +790,7 @@ Prints a line of JSON encoding the database hash, revision, total keys, and size
|
||||
|
||||
## Concurrency commands
|
||||
|
||||
### LOCK \<lockname\>
|
||||
### LOCK \<lockname\> [command arg1 arg2 ...]
|
||||
|
||||
LOCK acquires a distributed named mutex with a given name. Once the lock is acquired, it will be held until etcdctl is terminated.
|
||||
|
||||
@ -798,13 +798,24 @@ LOCK acquires a distributed named mutex with a given name. Once the lock is acqu
|
||||
|
||||
Once the lock is acquired, the result for the GET on the unique lock holder key is displayed.
|
||||
|
||||
If a command is given, it will be launched with environment variables `ETCD_LOCK_KEY` and `ETCD_LOCK_REV` set to the lock's holder key and revision.
|
||||
|
||||
#### Example
|
||||
|
||||
Acquire lock with standard output display:
|
||||
|
||||
```bash
|
||||
./etcdctl lock mylock
|
||||
# mylock/1234534535445
|
||||
```
|
||||
|
||||
Acquire lock and execute `echo lock acquired`:
|
||||
|
||||
```bash
|
||||
./etcdctl lock mylock echo lock acquired
|
||||
# lock acquired
|
||||
```
|
||||
|
||||
#### Remarks
|
||||
|
||||
LOCK returns a zero exit code only if it is terminated by a signal and releases the lock.
|
||||
|
@ -16,7 +16,9 @@ package command
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
@ -29,7 +31,7 @@ import (
|
||||
// NewLockCommand returns the cobra command for "lock".
|
||||
func NewLockCommand() *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
Use: "lock <lockname>",
|
||||
Use: "lock <lockname> [exec-command arg1 arg2 ...]",
|
||||
Short: "Acquires a named lock",
|
||||
Run: lockCommandFunc,
|
||||
}
|
||||
@ -37,16 +39,16 @@ func NewLockCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
func lockCommandFunc(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 1 {
|
||||
ExitWithError(ExitBadArgs, errors.New("lock takes one lock name argument."))
|
||||
if len(args) == 0 {
|
||||
ExitWithError(ExitBadArgs, errors.New("lock takes a lock name argument and an optional command to execute."))
|
||||
}
|
||||
c := mustClientFromCmd(cmd)
|
||||
if err := lockUntilSignal(c, args[0]); err != nil {
|
||||
if err := lockUntilSignal(c, args[0], args[1:]); err != nil {
|
||||
ExitWithError(ExitError, err)
|
||||
}
|
||||
}
|
||||
|
||||
func lockUntilSignal(c *clientv3.Client, lockname string) error {
|
||||
func lockUntilSignal(c *clientv3.Client, lockname string, cmdArgs []string) error {
|
||||
s, err := concurrency.NewSession(c)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -69,6 +71,18 @@ func lockUntilSignal(c *clientv3.Client, lockname string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(cmdArgs) > 0 {
|
||||
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
|
||||
cmd.Env = append(environLockResponse(m), os.Environ()...)
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
err := cmd.Run()
|
||||
unlockErr := m.Unlock(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return unlockErr
|
||||
}
|
||||
|
||||
k, kerr := c.Get(ctx, m.Key())
|
||||
if kerr != nil {
|
||||
return kerr
|
||||
@ -76,7 +90,6 @@ func lockUntilSignal(c *clientv3.Client, lockname string) error {
|
||||
if len(k.Kvs) == 0 {
|
||||
return errors.New("lock lost on init")
|
||||
}
|
||||
|
||||
display.Get(*k)
|
||||
|
||||
select {
|
||||
@ -87,3 +100,10 @@ func lockUntilSignal(c *clientv3.Client, lockname string) error {
|
||||
|
||||
return errors.New("session expired")
|
||||
}
|
||||
|
||||
func environLockResponse(m *concurrency.Mutex) []string {
|
||||
return []string{
|
||||
"ETCD_LOCK_KEY=" + m.Key(),
|
||||
fmt.Sprintf("ETCD_LOCK_REV=%d", m.Header().Revision),
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user