|
|
|
@ -5,6 +5,7 @@ import (
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"sort"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/docker/docker/pkg/ioutils"
|
|
|
|
|
"github.com/gofrs/flock"
|
|
|
|
@ -15,6 +16,7 @@ import (
|
|
|
|
|
const (
|
|
|
|
|
instanceDir = "instances"
|
|
|
|
|
defaultsDir = "defaults"
|
|
|
|
|
activityDir = "activity"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func New(root string) (*Store, error) {
|
|
|
|
@ -24,6 +26,9 @@ func New(root string) (*Store, error) {
|
|
|
|
|
if err := os.MkdirAll(filepath.Join(root, defaultsDir), 0700); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if err := os.MkdirAll(filepath.Join(root, activityDir), 0700); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &Store{root: root}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -86,6 +91,9 @@ func (t *Txn) NodeGroupByName(name string) (*NodeGroup, error) {
|
|
|
|
|
if err := json.Unmarshal(dt, &ng); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if ng.LastActivity, err = t.GetLastActivity(&ng); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &ng, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -94,6 +102,9 @@ func (t *Txn) Save(ng *NodeGroup) error {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if err := t.UpdateLastActivity(ng); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
dt, err := json.Marshal(ng)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
@ -106,6 +117,9 @@ func (t *Txn) Remove(name string) error {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if err := t.RemoveLastActivity(name); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return os.RemoveAll(filepath.Join(t.s.root, instanceDir, name))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -135,6 +149,29 @@ func (t *Txn) SetCurrent(key, name string, global, def bool) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Txn) UpdateLastActivity(ng *NodeGroup) error {
|
|
|
|
|
return ioutils.AtomicWriteFile(filepath.Join(t.s.root, activityDir, ng.Name), []byte(time.Now().UTC().Format(time.RFC3339)), 0600)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Txn) GetLastActivity(ng *NodeGroup) (la time.Time, _ error) {
|
|
|
|
|
dt, err := os.ReadFile(filepath.Join(t.s.root, activityDir, ng.Name))
|
|
|
|
|
if err != nil {
|
|
|
|
|
if os.IsNotExist(errors.Cause(err)) {
|
|
|
|
|
return la, nil
|
|
|
|
|
}
|
|
|
|
|
return la, err
|
|
|
|
|
}
|
|
|
|
|
return time.Parse(time.RFC3339, string(dt))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Txn) RemoveLastActivity(name string) error {
|
|
|
|
|
name, err := ValidateName(name)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return os.RemoveAll(filepath.Join(t.s.root, activityDir, name))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Txn) reset(key string) error {
|
|
|
|
|
dt, err := json.Marshal(current{Key: key})
|
|
|
|
|
if err != nil {
|
|
|
|
|