Merge pull request #1439 from crazy-max/last-activity

store: set nodegroup last activity
pull/1468/head
Tõnis Tiigi 2 years ago committed by GitHub
commit 37811320ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -111,6 +111,9 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error
if err != nil { if err != nil {
return err return err
} }
if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil {
return errors.Wrapf(err, "failed to update builder last activity time")
}
nodes, err = b.LoadNodes(ctx, false) nodes, err = b.LoadNodes(ctx, false)
if err != nil { if err != nil {
return err return err

@ -18,6 +18,8 @@ import (
"github.com/docker/buildx/build" "github.com/docker/buildx/build"
"github.com/docker/buildx/builder" "github.com/docker/buildx/builder"
"github.com/docker/buildx/monitor" "github.com/docker/buildx/monitor"
"github.com/docker/buildx/store"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/buildflags"
"github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/confutil"
"github.com/docker/buildx/util/dockerutil" "github.com/docker/buildx/util/dockerutil"
@ -261,6 +263,9 @@ func runBuild(dockerCli command.Cli, in buildOptions) (err error) {
if err != nil { if err != nil {
return err return err
} }
if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil {
return errors.Wrapf(err, "failed to update builder last activity time")
}
nodes, err := b.LoadNodes(ctx, false) nodes, err := b.LoadNodes(ctx, false)
if err != nil { if err != nil {
return err return err
@ -730,3 +735,12 @@ func isExperimental() bool {
} }
return false return false
} }
func updateLastActivity(dockerCli command.Cli, ng *store.NodeGroup) error {
txn, release, err := storeutil.GetStore(dockerCli)
if err != nil {
return err
}
defer release()
return txn.UpdateLastActivity(ng)
}

@ -50,6 +50,9 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "Name:\t%s\n", b.Name) fmt.Fprintf(w, "Name:\t%s\n", b.Name)
fmt.Fprintf(w, "Driver:\t%s\n", b.Driver) fmt.Fprintf(w, "Driver:\t%s\n", b.Driver)
if !b.NodeGroup.LastActivity.IsZero() {
fmt.Fprintf(w, "Last Activity:\t%v\n", b.NodeGroup.LastActivity)
}
if err != nil { if err != nil {
fmt.Fprintf(w, "Error:\t%s\n", err.Error()) fmt.Fprintf(w, "Error:\t%s\n", err.Error())

@ -2,6 +2,7 @@ package store
import ( import (
"fmt" "fmt"
"time"
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
"github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/confutil"
@ -18,7 +19,8 @@ type NodeGroup struct {
Dynamic bool Dynamic bool
// skip the following fields from being saved in the store // skip the following fields from being saved in the store
DockerContext bool `json:"-"` DockerContext bool `json:"-"`
LastActivity time.Time `json:"-"`
} }
type Node struct { type Node struct {

@ -5,6 +5,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
"time"
"github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/ioutils"
"github.com/gofrs/flock" "github.com/gofrs/flock"
@ -12,11 +13,20 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
const (
instanceDir = "instances"
defaultsDir = "defaults"
activityDir = "activity"
)
func New(root string) (*Store, error) { func New(root string) (*Store, error) {
if err := os.MkdirAll(filepath.Join(root, "instances"), 0700); err != nil { if err := os.MkdirAll(filepath.Join(root, instanceDir), 0700); err != nil {
return nil, err
}
if err := os.MkdirAll(filepath.Join(root, defaultsDir), 0700); err != nil {
return nil, err return nil, err
} }
if err := os.MkdirAll(filepath.Join(root, "defaults"), 0700); err != nil { if err := os.MkdirAll(filepath.Join(root, activityDir), 0700); err != nil {
return nil, err return nil, err
} }
return &Store{root: root}, nil return &Store{root: root}, nil
@ -43,7 +53,7 @@ type Txn struct {
} }
func (t *Txn) List() ([]*NodeGroup, error) { func (t *Txn) List() ([]*NodeGroup, error) {
pp := filepath.Join(t.s.root, "instances") pp := filepath.Join(t.s.root, instanceDir)
fis, err := os.ReadDir(pp) fis, err := os.ReadDir(pp)
if err != nil { if err != nil {
return nil, err return nil, err
@ -73,7 +83,7 @@ func (t *Txn) NodeGroupByName(name string) (*NodeGroup, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
dt, err := os.ReadFile(filepath.Join(t.s.root, "instances", name)) dt, err := os.ReadFile(filepath.Join(t.s.root, instanceDir, name))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -81,6 +91,9 @@ func (t *Txn) NodeGroupByName(name string) (*NodeGroup, error) {
if err := json.Unmarshal(dt, &ng); err != nil { if err := json.Unmarshal(dt, &ng); err != nil {
return nil, err return nil, err
} }
if ng.LastActivity, err = t.GetLastActivity(&ng); err != nil {
return nil, err
}
return &ng, nil return &ng, nil
} }
@ -89,11 +102,14 @@ func (t *Txn) Save(ng *NodeGroup) error {
if err != nil { if err != nil {
return err return err
} }
if err := t.UpdateLastActivity(ng); err != nil {
return err
}
dt, err := json.Marshal(ng) dt, err := json.Marshal(ng)
if err != nil { if err != nil {
return err return err
} }
return ioutils.AtomicWriteFile(filepath.Join(t.s.root, "instances", name), dt, 0600) return ioutils.AtomicWriteFile(filepath.Join(t.s.root, instanceDir, name), dt, 0600)
} }
func (t *Txn) Remove(name string) error { func (t *Txn) Remove(name string) error {
@ -101,7 +117,10 @@ func (t *Txn) Remove(name string) error {
if err != nil { if err != nil {
return err return err
} }
return os.RemoveAll(filepath.Join(t.s.root, "instances", name)) if err := t.RemoveLastActivity(name); err != nil {
return err
}
return os.RemoveAll(filepath.Join(t.s.root, instanceDir, name))
} }
func (t *Txn) SetCurrent(key, name string, global, def bool) error { func (t *Txn) SetCurrent(key, name string, global, def bool) error {
@ -121,15 +140,38 @@ func (t *Txn) SetCurrent(key, name string, global, def bool) error {
h := toHash(key) h := toHash(key)
if def { if def {
if err := ioutils.AtomicWriteFile(filepath.Join(t.s.root, "defaults", h), []byte(name), 0600); err != nil { if err := ioutils.AtomicWriteFile(filepath.Join(t.s.root, defaultsDir, h), []byte(name), 0600); err != nil {
return err return err
} }
} else { } else {
os.RemoveAll(filepath.Join(t.s.root, "defaults", h)) // ignore error os.RemoveAll(filepath.Join(t.s.root, defaultsDir, h)) // ignore error
} }
return nil 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 { func (t *Txn) reset(key string) error {
dt, err := json.Marshal(current{Key: key}) dt, err := json.Marshal(current{Key: key})
if err != nil { if err != nil {
@ -173,7 +215,7 @@ func (t *Txn) Current(key string) (*NodeGroup, error) {
h := toHash(key) h := toHash(key)
dt, err = os.ReadFile(filepath.Join(t.s.root, "defaults", h)) dt, err = os.ReadFile(filepath.Join(t.s.root, defaultsDir, h))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
t.reset(key) t.reset(key)

@ -92,6 +92,7 @@ func TestNodeManagement(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "mybuild", ng.Name) require.Equal(t, "mybuild", ng.Name)
require.Equal(t, "mydriver", ng.Driver) require.Equal(t, "mydriver", ng.Driver)
require.True(t, !ng.LastActivity.IsZero())
_, err = txn.NodeGroupByName("mybuild2") _, err = txn.NodeGroupByName("mybuild2")
require.Error(t, err) require.Error(t, err)

@ -85,7 +85,7 @@ func GetNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.No
} }
for _, l := range list { for _, l := range list {
if l.Name == name { if l.Name == name {
return &store.NodeGroup{ ng = &store.NodeGroup{
Name: name, Name: name,
Nodes: []store.Node{ Nodes: []store.Node{
{ {
@ -93,8 +93,11 @@ func GetNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.No
Endpoint: name, Endpoint: name,
}, },
}, },
DockerContext: true, }
}, nil if ng.LastActivity, err = txn.GetLastActivity(ng); err != nil {
return nil, err
}
return ng, nil
} }
} }

Loading…
Cancel
Save