mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 02:15:43 +03:00
Merge pull request #3484 from hashicorp/b-nomad-0.7.1
merge nomad 0.7.1 branch
This commit is contained in:
@@ -115,7 +115,8 @@ func (s *HTTPServer) ClientGCRequest(resp http.ResponseWriter, req *http.Request
|
||||
return nil, structs.ErrPermissionDenied
|
||||
}
|
||||
|
||||
return nil, s.agent.Client().CollectAllAllocs()
|
||||
s.agent.Client().CollectAllAllocs()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *HTTPServer) allocGC(allocID string, resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
@@ -131,7 +132,12 @@ func (s *HTTPServer) allocGC(allocID string, resp http.ResponseWriter, req *http
|
||||
} else if aclObj != nil && !aclObj.AllowNsOp(namespace, acl.NamespaceCapabilitySubmitJob) {
|
||||
return nil, structs.ErrPermissionDenied
|
||||
}
|
||||
return nil, s.agent.Client().CollectAllocation(allocID)
|
||||
|
||||
if !s.agent.Client().CollectAllocation(allocID) {
|
||||
// Could not find alloc
|
||||
return nil, fmt.Errorf("unable to collect allocation: not present")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *HTTPServer) allocSnapshot(allocID string, resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
|
||||
@@ -152,6 +152,7 @@ tls {
|
||||
ca_file = "foo"
|
||||
cert_file = "bar"
|
||||
key_file = "pipe"
|
||||
rpc_upgrade_mode = true
|
||||
verify_https_client = true
|
||||
}
|
||||
sentinel {
|
||||
|
||||
@@ -771,6 +771,7 @@ func parseTLSConfig(result **config.TLSConfig, list *ast.ObjectList) error {
|
||||
"http",
|
||||
"rpc",
|
||||
"verify_server_hostname",
|
||||
"rpc_upgrade_mode",
|
||||
"ca_file",
|
||||
"cert_file",
|
||||
"key_file",
|
||||
|
||||
@@ -172,6 +172,7 @@ func TestConfig_Parse(t *testing.T) {
|
||||
CAFile: "foo",
|
||||
CertFile: "bar",
|
||||
KeyFile: "pipe",
|
||||
RPCUpgradeMode: true,
|
||||
VerifyHTTPSClient: true,
|
||||
},
|
||||
HTTPAPIResponseHeaders: map[string]string{
|
||||
|
||||
@@ -214,6 +214,16 @@ func (c *AllocStatusCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
func formatAllocBasicInfo(alloc *api.Allocation, client *api.Client, uuidLength int, verbose bool) (string, error) {
|
||||
var formattedCreateTime, formattedModifyTime string
|
||||
|
||||
if verbose {
|
||||
formattedCreateTime = formatUnixNanoTime(alloc.CreateTime)
|
||||
formattedModifyTime = formatUnixNanoTime(alloc.ModifyTime)
|
||||
} else {
|
||||
formattedCreateTime = prettyTimeDiff(time.Unix(0, alloc.CreateTime), time.Now())
|
||||
formattedModifyTime = prettyTimeDiff(time.Unix(0, alloc.ModifyTime), time.Now())
|
||||
}
|
||||
|
||||
basic := []string{
|
||||
fmt.Sprintf("ID|%s", limit(alloc.ID, uuidLength)),
|
||||
fmt.Sprintf("Eval ID|%s", limit(alloc.EvalID, uuidLength)),
|
||||
@@ -225,7 +235,8 @@ func formatAllocBasicInfo(alloc *api.Allocation, client *api.Client, uuidLength
|
||||
fmt.Sprintf("Client Description|%s", alloc.ClientDescription),
|
||||
fmt.Sprintf("Desired Status|%s", alloc.DesiredStatus),
|
||||
fmt.Sprintf("Desired Description|%s", alloc.DesiredDescription),
|
||||
fmt.Sprintf("Created At|%s", formatUnixNanoTime(alloc.CreateTime)),
|
||||
fmt.Sprintf("Created|%s", formattedCreateTime),
|
||||
fmt.Sprintf("Modified|%s", formattedModifyTime),
|
||||
}
|
||||
|
||||
if alloc.DeploymentID != "" {
|
||||
|
||||
@@ -128,9 +128,14 @@ func TestAllocStatusCommand_Run(t *testing.T) {
|
||||
t.Fatalf("expected exit 0, got: %d", code)
|
||||
}
|
||||
out := ui.OutputWriter.String()
|
||||
if !strings.Contains(out, "Created At") {
|
||||
t.Fatalf("expected to have 'Created At' but saw: %s", out)
|
||||
if !strings.Contains(out, "Created") {
|
||||
t.Fatalf("expected to have 'Created' but saw: %s", out)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "Modified") {
|
||||
t.Fatalf("expected to have 'Modified' but saw: %s", out)
|
||||
}
|
||||
|
||||
ui.OutputWriter.Reset()
|
||||
|
||||
if code := cmd.Run([]string{"-address=" + url, "-verbose", allocId1}); code != 0 {
|
||||
@@ -140,8 +145,8 @@ func TestAllocStatusCommand_Run(t *testing.T) {
|
||||
if !strings.Contains(out, allocId1) {
|
||||
t.Fatal("expected to find alloc id in output")
|
||||
}
|
||||
if !strings.Contains(out, "Created At") {
|
||||
t.Fatalf("expected to have 'Created At' but saw: %s", out)
|
||||
if !strings.Contains(out, "Created") {
|
||||
t.Fatalf("expected to have 'Created' but saw: %s", out)
|
||||
}
|
||||
ui.OutputWriter.Reset()
|
||||
|
||||
@@ -150,8 +155,8 @@ func TestAllocStatusCommand_Run(t *testing.T) {
|
||||
t.Fatalf("expected exit 0, got: %d", code)
|
||||
}
|
||||
out = ui.OutputWriter.String()
|
||||
if !strings.Contains(out, "Created At") {
|
||||
t.Fatalf("expected to have 'Created At' but saw: %s", out)
|
||||
if !strings.Contains(out, "Created") {
|
||||
t.Fatalf("expected to have 'Created' but saw: %s", out)
|
||||
}
|
||||
ui.OutputWriter.Reset()
|
||||
|
||||
|
||||
@@ -75,6 +75,116 @@ func formatTimeDifference(first, second time.Time, d time.Duration) string {
|
||||
return second.Truncate(d).Sub(first.Truncate(d)).String()
|
||||
}
|
||||
|
||||
// fmtInt formats v into the tail of buf.
|
||||
// It returns the index where the output begins.
|
||||
func fmtInt(buf []byte, v uint64) int {
|
||||
w := len(buf)
|
||||
for v > 0 {
|
||||
w--
|
||||
buf[w] = byte(v%10) + '0'
|
||||
v /= 10
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
// prettyTimeDiff prints a human readable time difference.
|
||||
// It uses abbreviated forms for each period - s for seconds, m for minutes, h for hours,
|
||||
// d for days, mo for months, and y for years. Time difference is rounded to the nearest second,
|
||||
// and the top two least granular periods are returned. For example, if the time difference
|
||||
// is 10 months, 12 days, 3 hours and 2 seconds, the string "10mo12d" is returned. Zero values return the empty string
|
||||
func prettyTimeDiff(first, second time.Time) string {
|
||||
// handle zero values
|
||||
if first.Second() == 0 {
|
||||
return ""
|
||||
}
|
||||
// round to the nearest second
|
||||
first = first.Round(time.Second)
|
||||
second = second.Round(time.Second)
|
||||
|
||||
// calculate time difference in seconds
|
||||
d := second.Sub(first)
|
||||
u := uint64(d.Seconds())
|
||||
|
||||
var buf [32]byte
|
||||
w := len(buf)
|
||||
secs := u % 60
|
||||
|
||||
// track indexes of various periods
|
||||
var indexes []int
|
||||
|
||||
if secs > 0 {
|
||||
w--
|
||||
buf[w] = 's'
|
||||
// u is now seconds
|
||||
w = fmtInt(buf[:w], secs)
|
||||
indexes = append(indexes, w)
|
||||
}
|
||||
u /= 60
|
||||
// u is now minutes
|
||||
if u > 0 {
|
||||
mins := u % 60
|
||||
if mins > 0 {
|
||||
w--
|
||||
buf[w] = 'm'
|
||||
w = fmtInt(buf[:w], mins)
|
||||
indexes = append(indexes, w)
|
||||
}
|
||||
u /= 60
|
||||
// u is now hours
|
||||
if u > 0 {
|
||||
hrs := u % 24
|
||||
if hrs > 0 {
|
||||
w--
|
||||
buf[w] = 'h'
|
||||
w = fmtInt(buf[:w], hrs)
|
||||
indexes = append(indexes, w)
|
||||
}
|
||||
u /= 24
|
||||
}
|
||||
// u is now days
|
||||
if u > 0 {
|
||||
days := u % 30
|
||||
if days > 0 {
|
||||
w--
|
||||
buf[w] = 'd'
|
||||
w = fmtInt(buf[:w], days)
|
||||
indexes = append(indexes, w)
|
||||
}
|
||||
u /= 30
|
||||
}
|
||||
// u is now months
|
||||
if u > 0 {
|
||||
months := u % 12
|
||||
if months > 0 {
|
||||
w--
|
||||
buf[w] = 'o'
|
||||
w--
|
||||
buf[w] = 'm'
|
||||
w = fmtInt(buf[:w], months)
|
||||
indexes = append(indexes, w)
|
||||
}
|
||||
u /= 12
|
||||
}
|
||||
// u is now years
|
||||
if u > 0 {
|
||||
w--
|
||||
buf[w] = 'y'
|
||||
w = fmtInt(buf[:w], u)
|
||||
indexes = append(indexes, w)
|
||||
}
|
||||
}
|
||||
start := w
|
||||
end := len(buf)
|
||||
|
||||
// truncate to the first two periods
|
||||
num_periods := len(indexes)
|
||||
if num_periods > 2 {
|
||||
end = indexes[num_periods-3]
|
||||
}
|
||||
return string(buf[start:end]) + " ago"
|
||||
|
||||
}
|
||||
|
||||
// getLocalNodeID returns the node ID of the local Nomad Client and an error if
|
||||
// it couldn't be determined or the Agent is not running in Client mode.
|
||||
func getLocalNodeID(client *api.Client) (string, error) {
|
||||
|
||||
@@ -294,3 +294,35 @@ func TestJobGetter_HTTPServer(t *testing.T) {
|
||||
t.Fatalf("Unexpected file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrettyTimeDiff(t *testing.T) {
|
||||
test_cases := []struct {
|
||||
d time.Duration
|
||||
exp string
|
||||
}{
|
||||
{-740 * time.Second, "12m20s ago"},
|
||||
{-12 * time.Minute, "12m ago"},
|
||||
{-60 * time.Minute, "1h ago"},
|
||||
{-80 * time.Minute, "1h20m ago"},
|
||||
{-6 * time.Hour, "6h ago"},
|
||||
{-22165 * time.Second, "6h9m ago"},
|
||||
{-100 * time.Hour, "4d4h ago"},
|
||||
{-438000 * time.Minute, "10mo4d ago"},
|
||||
{-20460 * time.Hour, "2y4mo ago"},
|
||||
}
|
||||
for _, tc := range test_cases {
|
||||
t2 := time.Now().Add(tc.d)
|
||||
out := prettyTimeDiff(t2, time.Now())
|
||||
if out != tc.exp {
|
||||
t.Fatalf("expected :%v but got :%v", tc.exp, out)
|
||||
}
|
||||
}
|
||||
|
||||
var t1 time.Time
|
||||
out := prettyTimeDiff(t1, time.Now())
|
||||
|
||||
if out != "" {
|
||||
t.Fatalf("Expected empty output but got:%v", out)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -406,9 +406,9 @@ func formatAllocListStubs(stubs []*api.AllocationListStub, verbose bool, uuidLen
|
||||
|
||||
allocs := make([]string, len(stubs)+1)
|
||||
if verbose {
|
||||
allocs[0] = "ID|Eval ID|Node ID|Task Group|Version|Desired|Status|Created At"
|
||||
allocs[0] = "ID|Eval ID|Node ID|Task Group|Version|Desired|Status|Created|Modified"
|
||||
for i, alloc := range stubs {
|
||||
allocs[i+1] = fmt.Sprintf("%s|%s|%s|%s|%d|%s|%s|%s",
|
||||
allocs[i+1] = fmt.Sprintf("%s|%s|%s|%s|%d|%s|%s|%s|%s",
|
||||
limit(alloc.ID, uuidLength),
|
||||
limit(alloc.EvalID, uuidLength),
|
||||
limit(alloc.NodeID, uuidLength),
|
||||
@@ -416,19 +416,23 @@ func formatAllocListStubs(stubs []*api.AllocationListStub, verbose bool, uuidLen
|
||||
alloc.JobVersion,
|
||||
alloc.DesiredStatus,
|
||||
alloc.ClientStatus,
|
||||
formatUnixNanoTime(alloc.CreateTime))
|
||||
formatUnixNanoTime(alloc.CreateTime),
|
||||
formatUnixNanoTime(alloc.ModifyTime))
|
||||
}
|
||||
} else {
|
||||
allocs[0] = "ID|Node ID|Task Group|Version|Desired|Status|Created At"
|
||||
allocs[0] = "ID|Node ID|Task Group|Version|Desired|Status|Created|Modified"
|
||||
for i, alloc := range stubs {
|
||||
allocs[i+1] = fmt.Sprintf("%s|%s|%s|%d|%s|%s|%s",
|
||||
createTimePretty := prettyTimeDiff(time.Unix(0, alloc.CreateTime), time.Now())
|
||||
modTimePretty := prettyTimeDiff(time.Unix(0, alloc.ModifyTime), time.Now())
|
||||
allocs[i+1] = fmt.Sprintf("%s|%s|%s|%d|%s|%s|%s|%s",
|
||||
limit(alloc.ID, uuidLength),
|
||||
limit(alloc.NodeID, uuidLength),
|
||||
alloc.TaskGroup,
|
||||
alloc.JobVersion,
|
||||
alloc.DesiredStatus,
|
||||
alloc.ClientStatus,
|
||||
formatUnixNanoTime(alloc.CreateTime))
|
||||
createTimePretty,
|
||||
modTimePretty)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,9 +113,12 @@ func TestJobStatusCommand_Run(t *testing.T) {
|
||||
if !strings.Contains(out, "Allocations") {
|
||||
t.Fatalf("should dump allocations")
|
||||
}
|
||||
if !strings.Contains(out, "Created At") {
|
||||
if !strings.Contains(out, "Created") {
|
||||
t.Fatal("should have created header")
|
||||
}
|
||||
if !strings.Contains(out, "Modified") {
|
||||
t.Fatal("should have modified header")
|
||||
}
|
||||
ui.ErrorWriter.Reset()
|
||||
ui.OutputWriter.Reset()
|
||||
|
||||
@@ -138,6 +141,14 @@ func TestJobStatusCommand_Run(t *testing.T) {
|
||||
if !strings.Contains(out, "job1_sfx") || strings.Contains(out, "job2_sfx") {
|
||||
t.Fatalf("expected only job1_sfx, got: %s", out)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "Created") {
|
||||
t.Fatal("should have created header")
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "Modified") {
|
||||
t.Fatal("should have modified header")
|
||||
}
|
||||
ui.OutputWriter.Reset()
|
||||
|
||||
// Query in short view mode
|
||||
|
||||
Reference in New Issue
Block a user