Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
schmichael authored Jul 6, 2017
2 parents bdfd0b4 + d4c90fe commit 58186bf
Show file tree
Hide file tree
Showing 209 changed files with 11,344 additions and 6,302 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ branches:

before_install:
- sudo apt-get update
- sudo apt-get install -y docker-engine liblxc1 lxc-dev lxc
- sudo apt-get install -y liblxc1 lxc-dev lxc
- sudo apt-get install -y qemu
- ./scripts/install_rkt.sh
- ./scripts/install_consul.sh
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,62 @@
## 0.6.0 (Unreleased)

IMPROVEMENTS:
* agent/config: Late binding to IP addresses using go-sockaddr/template syntax
[GH-2399]
* core: Rolling updates based on allocation health [GH-2621, GH-2634]
* core: Default advertise to private IP address if bind is 0.0.0.0 [GH-2399]
* core: Track multiple job versions and add a stopped state for jobs [GH-2566]
* core: Back-pressure when evaluations are nacked and ensure scheduling
progress on evaluation failures [GH-2555]
* api: Add `verify_https_client` to require certificates from HTTP clients
[GH-2587]
* api/job: Ability to revert job to older versions [GH-2575]
* client: Use a random host UUID by default [GH-2735]
* client: Environment variables for client DC and Region [GH-2507]
* client: Hash host ID so its stable and well distributed [GH-2541]
* client: GC dead allocs if total allocs > `gc_max_allocs` tunable [GH-2636]
* client: Persist state using bolt-db and more efficient write patterns
[GH-2610]
* client: Fingerprint all routable addresses on an interface including IPv6
addresses [GH-2536]
* client/artifact: Allow specifying a go-getter mode [GH-2781]
* client/artifact: Support non-Amazon S3-compatible sources [GH-2781]
* client/template: Support reading env vars from templates [GH-2654]
* config: Support Unix socket addresses for Consul [GH-2622]
* discovery: Advertise driver-specified IP address and port [GH-2709]
* driver/docker: Allow specifying extra hosts [GH-2547]
* driver/docker: Allow setting seccomp profiles [GH-2658]
* driver/docker: Support Docker credential helpers [GH-2651]
* driver/docker: Allow setting container IP with user defined networks
[GH-2535]
* driver/rkt: Support `no_overlay` [GH-2702]
* driver/rkt: Support `insecure_options` list [GH-2695]

BUG FIXES:
* core: Protect against nil job in new allocation, avoiding panic [GH-2592]
* core: System jobs should be running until explicitly stopped [GH-2750]
* core: Prevent invalid job updates (eg service -> batch) [GH-2746]
* client: Lookup `ip` utility on `$PATH` [GH-2729]
* client: Add sticky bit to temp directory [GH-2519]
* client: Shutdown task group leader before other tasks [GH-2753]
* client: Include symlinks in snapshots when migrating disks [GH-2687]
* client: Regression for allocation directory unix perms introduced in v0.5.6
fixed [GH-2675]
* client: Client syncs allocation state with server before waiting for
allocation destroy fixing a corner case in which an allocation may be blocked
till destroy [GH-2563]
* client/artifact: Honor netrc [GH-2524]
* client/artifact: Handle tars where file in directory is listed before
directory [GH-2524]
* client/config: Use `cpu_total_compute` whenever it is set [GH-2745]
* driver/exec: Properly set file/dir ownership in chroots [GH-2552]
* driver/docker: Fix panic in Docker driver on Windows [GH-2614]
* driver/rkt: Fix env var interpolation [GH-2777]
* server: Reject non-TLS clients when TLS enabled [GH-2525]
* server: Fix a panic in plan evaluation with partial failures and all_at_once
set [GH-2544]
* server/vault: Fix Vault Client panic when given nonexistant role [GH-2648]
* telemetry: Fix merging of use node name [GH-2762]

## 0.5.6 (March 31, 2017)

Expand Down
2 changes: 1 addition & 1 deletion Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ VAGRANTFILE_API_VERSION = "2"

DEFAULT_CPU_COUNT = 2
$script = <<SCRIPT
GO_VERSION="1.8.1"
GO_VERSION="1.8.3"
export DEBIAN_FRONTEND=noninteractive
Expand Down
20 changes: 10 additions & 10 deletions api/evaluations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestEvaluations_List(t *testing.T) {
// Register a job. This will create an evaluation.
jobs := c.Jobs()
job := testJob()
evalID, wm, err := jobs.Register(job, nil)
resp, wm, err := jobs.Register(job, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
Expand All @@ -43,8 +43,8 @@ func TestEvaluations_List(t *testing.T) {
// if the eval fails fast there can be more than 1
// but they are in order of most recent first, so look at the last one
idx := len(result) - 1
if len(result) == 0 || result[idx].ID != evalID {
t.Fatalf("expected eval (%s), got: %#v", evalID, result[idx])
if len(result) == 0 || result[idx].ID != resp.EvalID {
t.Fatalf("expected eval (%s), got: %#v", resp.EvalID, result[idx])
}
}

Expand All @@ -68,21 +68,21 @@ func TestEvaluations_PrefixList(t *testing.T) {
// Register a job. This will create an evaluation.
jobs := c.Jobs()
job := testJob()
evalID, wm, err := jobs.Register(job, nil)
resp, wm, err := jobs.Register(job, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
assertWriteMeta(t, wm)

// Check the evaluations again
result, qm, err = e.PrefixList(evalID[:4])
result, qm, err = e.PrefixList(resp.EvalID[:4])
if err != nil {
t.Fatalf("err: %s", err)
}
assertQueryMeta(t, qm)

// Check if we have the right list
if len(result) != 1 || result[0].ID != evalID {
if len(result) != 1 || result[0].ID != resp.EvalID {
t.Fatalf("bad: %#v", result)
}
}
Expand All @@ -101,22 +101,22 @@ func TestEvaluations_Info(t *testing.T) {
// Register a job. Creates a new evaluation.
jobs := c.Jobs()
job := testJob()
evalID, wm, err := jobs.Register(job, nil)
resp, wm, err := jobs.Register(job, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
assertWriteMeta(t, wm)

// Try looking up by the new eval ID
result, qm, err := e.Info(evalID, nil)
result, qm, err := e.Info(resp.EvalID, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
assertQueryMeta(t, qm)

// Check that we got the right result
if result == nil || result.ID != evalID {
t.Fatalf("expected eval %q, got: %#v", evalID, result)
if result == nil || result.ID != resp.EvalID {
t.Fatalf("expected eval %q, got: %#v", resp.EvalID, result)
}
}

Expand Down
136 changes: 127 additions & 9 deletions api/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/gorhill/cronexpr"
"github.com/hashicorp/nomad/helper"
"github.com/hashicorp/nomad/nomad/structs"
)

const (
Expand Down Expand Up @@ -50,20 +51,20 @@ func (j *Jobs) Validate(job *Job, q *WriteOptions) (*JobValidateResponse, *Write

// Register is used to register a new job. It returns the ID
// of the evaluation, along with any errors encountered.
func (j *Jobs) Register(job *Job, q *WriteOptions) (string, *WriteMeta, error) {
func (j *Jobs) Register(job *Job, q *WriteOptions) (*JobRegisterResponse, *WriteMeta, error) {

var resp JobRegisterResponse

req := &RegisterJobRequest{Job: job}
wm, err := j.client.write("/v1/jobs", req, &resp, q)
if err != nil {
return "", nil, err
return nil, nil, err
}
return resp.EvalID, wm, nil
return &resp, wm, nil
}

// EnforceRegister is used to register a job enforcing its job modify index.
func (j *Jobs) EnforceRegister(job *Job, modifyIndex uint64, q *WriteOptions) (string, *WriteMeta, error) {
func (j *Jobs) EnforceRegister(job *Job, modifyIndex uint64, q *WriteOptions) (*JobRegisterResponse, *WriteMeta, error) {

var resp JobRegisterResponse

Expand All @@ -74,9 +75,9 @@ func (j *Jobs) EnforceRegister(job *Job, modifyIndex uint64, q *WriteOptions) (s
}
wm, err := j.client.write("/v1/jobs", req, &resp, q)
if err != nil {
return "", nil, err
return nil, nil, err
}
return resp.EvalID, wm, nil
return &resp, wm, nil
}

// List is used to list all of the existing jobs.
Expand Down Expand Up @@ -247,10 +248,111 @@ type periodicForceResponse struct {
EvalID string
}

// UpdateStrategy is for serializing update strategy for a job.
// UpdateStrategy defines a task groups update strategy.
type UpdateStrategy struct {
Stagger time.Duration
MaxParallel int `mapstructure:"max_parallel"`
// COMPAT: Remove in 0.7.0. Stagger is deprecated in 0.6.0.
Stagger time.Duration `mapstructure:"stagger"`
MaxParallel *int `mapstructure:"max_parallel"`
HealthCheck *string `mapstructure:"health_check"`
MinHealthyTime *time.Duration `mapstructure:"min_healthy_time"`
HealthyDeadline *time.Duration `mapstructure:"healthy_deadline"`
AutoRevert *bool `mapstructure:"auto_revert"`
Canary *int `mapstructure:"canary"`
}

func (u *UpdateStrategy) Copy() *UpdateStrategy {
if u == nil {
return nil
}

copy := new(UpdateStrategy)

// COMPAT: Remove in 0.7.0. Stagger is deprecated in 0.6.0.
copy.Stagger = u.Stagger

if u.MaxParallel != nil {
copy.MaxParallel = helper.IntToPtr(*u.MaxParallel)
}

if u.HealthCheck != nil {
copy.HealthCheck = helper.StringToPtr(*u.HealthCheck)
}

if u.MinHealthyTime != nil {
copy.MinHealthyTime = helper.TimeToPtr(*u.MinHealthyTime)
}

if u.HealthyDeadline != nil {
copy.HealthyDeadline = helper.TimeToPtr(*u.HealthyDeadline)
}

if u.AutoRevert != nil {
copy.AutoRevert = helper.BoolToPtr(*u.AutoRevert)
}

if u.Canary != nil {
copy.Canary = helper.IntToPtr(*u.Canary)
}

return copy
}

func (u *UpdateStrategy) Merge(o *UpdateStrategy) {
if o == nil {
return
}

if o.MaxParallel != nil {
u.MaxParallel = helper.IntToPtr(*o.MaxParallel)
}

if o.HealthCheck != nil {
u.HealthCheck = helper.StringToPtr(*o.HealthCheck)
}

if o.MinHealthyTime != nil {
u.MinHealthyTime = helper.TimeToPtr(*o.MinHealthyTime)
}

if o.HealthyDeadline != nil {
u.HealthyDeadline = helper.TimeToPtr(*o.HealthyDeadline)
}

if o.AutoRevert != nil {
u.AutoRevert = helper.BoolToPtr(*o.AutoRevert)
}

if o.Canary != nil {
u.Canary = helper.IntToPtr(*o.Canary)
}
}

func (u *UpdateStrategy) Canonicalize() {
if u.MaxParallel == nil {
u.MaxParallel = helper.IntToPtr(0)
}

d := structs.DefaultUpdateStrategy

if u.HealthCheck == nil {
u.HealthCheck = helper.StringToPtr(d.HealthCheck)
}

if u.HealthyDeadline == nil {
u.HealthyDeadline = helper.TimeToPtr(d.HealthyDeadline)
}

if u.MinHealthyTime == nil {
u.MinHealthyTime = helper.TimeToPtr(d.MinHealthyTime)
}

if u.AutoRevert == nil {
u.AutoRevert = helper.BoolToPtr(d.AutoRevert)
}

if u.Canary == nil {
u.Canary = helper.IntToPtr(d.Canary)
}
}

// PeriodicConfig is for serializing periodic config for a job.
Expand Down Expand Up @@ -399,6 +501,9 @@ func (j *Job) Canonicalize() {
if j.Periodic != nil {
j.Periodic.Canonicalize()
}
if j.Update != nil {
j.Update.Canonicalize()
}

for _, tg := range j.TaskGroups {
tg.Canonicalize(j)
Expand Down Expand Up @@ -556,6 +661,10 @@ type JobValidateResponse struct {

// Error is a string version of any error that may have occured
Error string

// Warnings contains any warnings about the given job. These may include
// deprecation warnings.
Warnings string
}

// JobRevertRequest is used to revert a job to a prior version.
Expand Down Expand Up @@ -597,6 +706,11 @@ type JobRegisterResponse struct {
EvalID string
EvalCreateIndex uint64
JobModifyIndex uint64

// Warnings contains any warnings about the given job. These may include
// deprecation warnings.
Warnings string

QueryMeta
}

Expand All @@ -621,6 +735,10 @@ type JobPlanResponse struct {
Annotations *PlanAnnotations
FailedTGAllocs map[string]*AllocationMetric
NextPeriodicLaunch time.Time

// Warnings contains any warnings about the given job. These may include
// deprecation warnings.
Warnings string
}

type JobDiff struct {
Expand Down
Loading

0 comments on commit 58186bf

Please sign in to comment.