-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.go
99 lines (81 loc) · 2.19 KB
/
file.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"errors"
"fmt"
"math"
"time"
"github.com/gage-technologies/safelock"
"github.com/google/uuid"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
const (
// File Lock flags
flagFileLockFilename = "filename"
flagFileLockAction = "action"
flagFileLockID = "lock-id"
flagFileLockNode = "node"
)
func initFileLockFlags(flag *pflag.FlagSet) {
flag.String(flagFileLockFilename, "", "The filename")
flag.String(flagFileLockAction, actionLock, "The action to use")
flag.Uint64(flagFileLockID, uint64(time.Now().UnixNano()), "The id of the lock to act upon")
flag.Uint(flagFileLockNode, math.MaxInt, "The node of the lock to act upon")
}
func checkFileLockConfig(v *viper.Viper) error {
filename := v.GetString(flagFileLockFilename)
if len(filename) == 0 {
return errors.New("A filename is required")
}
action := v.GetString(flagFileLockAction)
if !stringSliceContains(validActions, action) {
return fmt.Errorf("Action %q is not valid, must be one of %v", action, validActions)
}
if action == actionUnlock {
lockID := v.GetString(flagFileLockID)
if len(lockID) == 0 {
return errors.New("A lock ID is required when unlocking")
}
_, errParse := uuid.Parse(lockID)
if errParse != nil {
return fmt.Errorf("Lock ID %q is not a valid UUID", lockID)
}
}
return nil
}
func fileLockCmd(cmd *cobra.Command, args []string) error {
v, errViper := initViper(cmd)
if errViper != nil {
return fmt.Errorf("error initializing viper: %w", errViper)
}
if len(args) > 1 {
return cmd.Usage()
}
if errConfig := checkFileLockConfig(v); errConfig != nil {
return errConfig
}
filename := v.GetString(flagFileLockFilename)
action := v.GetString(flagFileLockAction)
node := v.GetUint(flagFileLockNode)
l := safelock.NewFileLock(uint16(node), filename)
lockID := v.GetUint64(flagFileLockID)
l.SetID(lockID)
switch action {
case actionLock:
errWaitForLock := l.WaitForLock(safelock.DefaultTimeout)
if errWaitForLock != nil {
return errWaitForLock
}
errLock := l.Lock()
if errLock != nil {
return errLock
}
case actionUnlock:
errUnlock := l.Unlock()
if errUnlock != nil {
return errUnlock
}
}
return nil
}