Skip to content

Commit

Permalink
Merge pull request #4792 from hashicorp/r-clientv2-rebased
Browse files Browse the repository at this point in the history
AllocRunner v2 Feature Branch PR
  • Loading branch information
schmichael committed Oct 17, 2018
2 parents fb3b8c0 + 2361c19 commit 84c9bc9
Show file tree
Hide file tree
Showing 934 changed files with 98,023 additions and 16,972 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
## 0.9.0 (Unreleased)

__BACKWARDS INCOMPATIBILITIES:__
* core: Switch to structured logging using [go-hclog](https://github.com/hashicorp/go-hclog)

IMPROVEMENTS:
* core: Added advertise address to client node meta data [[GH-4390](https://github.com/hashicorp/nomad/issues/4390)]
* core: Added support for specifying node affinities. Affinities allow job operators to specify weighted placement preferences
according to different node attributes [[GH-4512](https://github.com/hashicorp/nomad/issues/4512)]
* core: Added support for spreading allocations across a specific attribute. Operators can specify spread
target percentages across failure domains such as datacenter or rack [[GH-4512](https://github.com/hashicorp/nomad/issues/4512)]
* client: Refactor client to support plugins and improve state handling [[GH-4792](https://github.com/hashicorp/nomad/pull/4792)]
* client: Extend timeout to 60 seconds for Windows CPU fingerprinting [[GH-4441](https://github.com/hashicorp/nomad/pull/4441)]
* driver/docker: Add support for specifying `cpu_cfs_period` in the Docker driver [[GH-4462](https://github.com/hashicorp/nomad/issues/4462)]
* telemetry: All client metrics include a new `node_class` tag [[GH-3882](https://github.com/hashicorp/nomad/issues/3882)]
Expand All @@ -15,6 +19,7 @@ IMPROVEMENTS:

BUG FIXES:
* core: Fixed bug in reconciler where allocs already stopped were being unnecessarily updated [[GH-4764](https://github.com/hashicorp/nomad/issues/4764)]
* client: Fix an issue reloading the client config [[GH-4730](https://github.com/hashicorp/nomad/issues/4730)]

## 0.8.6 (September 26, 2018)

Expand Down
4 changes: 2 additions & 2 deletions client/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (c *Client) resolveTokenValue(secretID string) (*structs.ACLToken, error) {
if err := c.RPC("ACL.ResolveToken", &req, &resp); err != nil {
// If we encounter an error but have a cached value, mask the error and extend the cache
if ok {
c.logger.Printf("[WARN] client: failed to resolve token, using expired cached value: %v", err)
c.logger.Warn("failed to resolve token, using expired cached value", "error", err)
cached := raw.(*cachedACLValue)
return cached.Token, nil
}
Expand Down Expand Up @@ -198,7 +198,7 @@ func (c *Client) resolvePolicies(secretID string, policies []string) ([]*structs
if err := c.RPC("ACL.GetPolicies", &req, &resp); err != nil {
// If we encounter an error but have cached policies, mask the error and extend the cache
if len(missing) == 0 {
c.logger.Printf("[WARN] client: failed to resolve policies, using expired cached value: %v", err)
c.logger.Warn("failed to resolve policies, using expired cached value", "error", err)
out = append(out, expired...)
return out, nil
}
Expand Down
2 changes: 2 additions & 0 deletions client/alloc_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func TestAllocations_GarbageCollectAll_ACL(t *testing.T) {
}

func TestAllocations_GarbageCollect(t *testing.T) {
t.Skip("missing mock driver plugin implementation")
t.Parallel()
require := require.New(t)
client := TestClient(t, func(c *config.Config) {
Expand Down Expand Up @@ -174,6 +175,7 @@ func TestAllocations_GarbageCollect_ACL(t *testing.T) {
}

func TestAllocations_Stats(t *testing.T) {
t.Skip("missing exec driver plugin implementation")
t.Parallel()
require := require.New(t)
client := TestClient(t, nil)
Expand Down
1 change: 1 addition & 0 deletions client/alloc_watcher_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
// TestPrevAlloc_StreamAllocDir_TLS asserts ephemeral disk migrations still
// work when TLS is enabled.
func TestPrevAlloc_StreamAllocDir_TLS(t *testing.T) {
t.Skip("missing mock driver plugin implementation")
const (
caFn = "../helper/tlsutil/testdata/global-ca.pem"
serverCertFn = "../helper/tlsutil/testdata/global-server.pem"
Expand Down
39 changes: 34 additions & 5 deletions client/allocdir/alloc_dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"sync"
"time"

hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-multierror"
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/nomad/structs"
Expand Down Expand Up @@ -58,6 +59,8 @@ var (
TaskDirs = map[string]os.FileMode{TmpDirName: os.ModeSticky | 0777}
)

// AllocDir allows creating, destroying, and accessing an allocation's
// directory. All methods are safe for concurrent use.
type AllocDir struct {
// AllocDir is the directory used for storing any state
// of this allocation. It will be purged on alloc destroy.
Expand All @@ -73,7 +76,9 @@ type AllocDir struct {
// built is true if Build has successfully run
built bool

logger *log.Logger
mu sync.RWMutex

logger hclog.Logger
}

// AllocDirFS exposes file operations on the alloc dir
Expand All @@ -88,7 +93,8 @@ type AllocDirFS interface {

// NewAllocDir initializes the AllocDir struct with allocDir as base path for
// the allocation directory.
func NewAllocDir(logger *log.Logger, allocDir string) *AllocDir {
func NewAllocDir(logger hclog.Logger, allocDir string) *AllocDir {
logger = logger.Named("alloc_dir")
return &AllocDir{
AllocDir: allocDir,
SharedDir: filepath.Join(allocDir, SharedAllocName),
Expand All @@ -100,6 +106,9 @@ func NewAllocDir(logger *log.Logger, allocDir string) *AllocDir {
// Copy an AllocDir and all of its TaskDirs. Returns nil if AllocDir is
// nil.
func (d *AllocDir) Copy() *AllocDir {
d.mu.RLock()
defer d.mu.RUnlock()

if d == nil {
return nil
}
Expand All @@ -117,6 +126,9 @@ func (d *AllocDir) Copy() *AllocDir {

// NewTaskDir creates a new TaskDir and adds it to the AllocDirs TaskDirs map.
func (d *AllocDir) NewTaskDir(name string) *TaskDir {
d.mu.Lock()
defer d.mu.Unlock()

td := newTaskDir(d.logger, d.AllocDir, name)
d.TaskDirs[name] = td
return td
Expand All @@ -129,6 +141,9 @@ func (d *AllocDir) NewTaskDir(name string) *TaskDir {
// file "NOMAD-${ALLOC_ID}-ERROR.log" will be appended to the tar with the
// error message as the contents.
func (d *AllocDir) Snapshot(w io.Writer) error {
d.mu.RLock()
defer d.mu.RUnlock()

allocDataDir := filepath.Join(d.SharedDir, SharedDataDir)
rootPaths := []string{allocDataDir}
for _, taskdir := range d.TaskDirs {
Expand Down Expand Up @@ -195,7 +210,7 @@ func (d *AllocDir) Snapshot(w io.Writer) error {
// the snapshotting side closed the connect
// prematurely and won't try to use the tar
// anyway.
d.logger.Printf("[WARN] client: snapshotting failed and unable to write error marker: %v", writeErr)
d.logger.Warn("snapshotting failed and unable to write error marker", "error", writeErr)
}
return fmt.Errorf("failed to snapshot %s: %v", path, err)
}
Expand All @@ -206,11 +221,16 @@ func (d *AllocDir) Snapshot(w io.Writer) error {

// Move other alloc directory's shared path and local dir to this alloc dir.
func (d *AllocDir) Move(other *AllocDir, tasks []*structs.Task) error {
d.mu.RLock()
if !d.built {
// Enforce the invariant that Build is called before Move
d.mu.RUnlock()
return fmt.Errorf("unable to move to %q - alloc dir is not built", d.AllocDir)
}

// Moving is slow and only reads immutable fields, so unlock during heavy IO
d.mu.RUnlock()

// Move the data directory
otherDataDir := filepath.Join(other.SharedDir, SharedDataDir)
dataDir := filepath.Join(d.SharedDir, SharedDataDir)
Expand Down Expand Up @@ -246,7 +266,6 @@ func (d *AllocDir) Move(other *AllocDir, tasks []*structs.Task) error {

// Tears down previously build directory structure.
func (d *AllocDir) Destroy() error {

// Unmount all mounted shared alloc dirs.
var mErr multierror.Error
if err := d.UnmountAll(); err != nil {
Expand All @@ -258,12 +277,17 @@ func (d *AllocDir) Destroy() error {
}

// Unset built since the alloc dir has been destroyed.
d.mu.Lock()
d.built = false
d.mu.Unlock()
return mErr.ErrorOrNil()
}

// UnmountAll linked/mounted directories in task dirs.
func (d *AllocDir) UnmountAll() error {
d.mu.RLock()
defer d.mu.RUnlock()

var mErr multierror.Error
for _, dir := range d.TaskDirs {
// Check if the directory has the shared alloc mounted.
Expand Down Expand Up @@ -322,7 +346,9 @@ func (d *AllocDir) Build() error {
}

// Mark as built
d.mu.Lock()
d.built = true
d.mu.Unlock()
return nil
}

Expand Down Expand Up @@ -386,11 +412,14 @@ func (d *AllocDir) ReadAt(path string, offset int64) (io.ReadCloser, error) {
p := filepath.Join(d.AllocDir, path)

// Check if it is trying to read into a secret directory
d.mu.RLock()
for _, dir := range d.TaskDirs {
if filepath.HasPrefix(p, dir.SecretsDir) {
d.mu.RUnlock()
return nil, fmt.Errorf("Reading secret file prohibited: %s", path)
}
}
d.mu.RUnlock()

f, err := os.Open(p)
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions client/allocdir/alloc_dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestAllocDir_BuildAlloc(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
defer d.Destroy()
d.NewTaskDir(t1.Name)
d.NewTaskDir(t2.Name)
Expand Down Expand Up @@ -91,7 +91,7 @@ func TestAllocDir_MountSharedAlloc(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
defer d.Destroy()
if err := d.Build(); err != nil {
t.Fatalf("Build() failed: %v", err)
Expand Down Expand Up @@ -136,7 +136,7 @@ func TestAllocDir_Snapshot(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
defer d.Destroy()
if err := d.Build(); err != nil {
t.Fatalf("Build() failed: %v", err)
Expand Down Expand Up @@ -223,13 +223,13 @@ func TestAllocDir_Move(t *testing.T) {
defer os.RemoveAll(tmp2)

// Create two alloc dirs
d1 := NewAllocDir(testlog.Logger(t), tmp1)
d1 := NewAllocDir(testlog.HCLogger(t), tmp1)
if err := d1.Build(); err != nil {
t.Fatalf("Build() failed: %v", err)
}
defer d1.Destroy()

d2 := NewAllocDir(testlog.Logger(t), tmp2)
d2 := NewAllocDir(testlog.HCLogger(t), tmp2)
if err := d2.Build(); err != nil {
t.Fatalf("Build() failed: %v", err)
}
Expand Down Expand Up @@ -284,7 +284,7 @@ func TestAllocDir_EscapeChecking(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
if err := d.Build(); err != nil {
t.Fatalf("Build() failed: %v", err)
}
Expand Down Expand Up @@ -325,7 +325,7 @@ func TestAllocDir_ReadAt_SecretDir(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
if err := d.Build(); err != nil {
t.Fatalf("Build() failed: %v", err)
}
Expand Down Expand Up @@ -410,7 +410,7 @@ func TestAllocDir_CreateDir(t *testing.T) {
// TestAllocDir_Copy asserts that AllocDir.Copy does a deep copy of itself and
// all TaskDirs.
func TestAllocDir_Copy(t *testing.T) {
a := NewAllocDir(testlog.Logger(t), "foo")
a := NewAllocDir(testlog.HCLogger(t), "foo")
a.NewTaskDir("bar")
a.NewTaskDir("baz")

Expand Down
13 changes: 10 additions & 3 deletions client/allocdir/task_dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ package allocdir
import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

hclog "github.com/hashicorp/go-hclog"
cstructs "github.com/hashicorp/nomad/client/structs"
)

// TaskDir contains all of the paths relevant to a task. All paths are on the
// host system so drivers should mount/link into task containers as necessary.
type TaskDir struct {
// AllocDir is the path to the alloc directory on the host
AllocDir string

// Dir is the path to Task directory on the host
Dir string

Expand All @@ -37,16 +40,20 @@ type TaskDir struct {
// <task_dir>/secrets/
SecretsDir string

logger *log.Logger
logger hclog.Logger
}

// newTaskDir creates a TaskDir struct with paths set. Call Build() to
// create paths on disk.
//
// Call AllocDir.NewTaskDir to create new TaskDirs
func newTaskDir(logger *log.Logger, allocDir, taskName string) *TaskDir {
func newTaskDir(logger hclog.Logger, allocDir, taskName string) *TaskDir {
taskDir := filepath.Join(allocDir, taskName)

logger = logger.Named("task_dir").With("task_name", taskName)

return &TaskDir{
AllocDir: allocDir,
Dir: taskDir,
SharedAllocDir: filepath.Join(allocDir, SharedAllocName),
LogDir: filepath.Join(allocDir, SharedAllocName, LogDirName),
Expand Down
2 changes: 1 addition & 1 deletion client/allocdir/task_dir_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestLinuxSpecialDirs(t *testing.T) {
}
defer os.RemoveAll(allocDir)

td := newTaskDir(testlog.Logger(t), allocDir, "test")
td := newTaskDir(testlog.HCLogger(t), allocDir, "test")

// Despite the task dir not existing, unmountSpecialDirs should *not*
// return an error
Expand Down
8 changes: 4 additions & 4 deletions client/allocdir/task_dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestTaskDir_EmbedNonexistent(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
defer d.Destroy()
td := d.NewTaskDir(t1.Name)
if err := d.Build(); err != nil {
Expand All @@ -40,7 +40,7 @@ func TestTaskDir_EmbedDirs(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
defer d.Destroy()
td := d.NewTaskDir(t1.Name)
if err := d.Build(); err != nil {
Expand Down Expand Up @@ -97,7 +97,7 @@ func TestTaskDir_NonRoot_Image(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
defer d.Destroy()
td := d.NewTaskDir(t1.Name)
if err := d.Build(); err != nil {
Expand All @@ -120,7 +120,7 @@ func TestTaskDir_NonRoot(t *testing.T) {
}
defer os.RemoveAll(tmp)

d := NewAllocDir(testlog.Logger(t), tmp)
d := NewAllocDir(testlog.HCLogger(t), tmp)
defer d.Destroy()
td := d.NewTaskDir(t1.Name)
if err := d.Build(); err != nil {
Expand Down
Loading

0 comments on commit 84c9bc9

Please sign in to comment.