Allow using specific object ID on diff (#11400)

This commit is contained in:
Luiz Aoqui 2021-11-01 15:16:31 -04:00 committed by GitHub
parent e151d93c9c
commit 655ac2719f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 10 deletions

3
.changelog/11400.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
cli: Improve `nomad job plan` output for `artifact` and `template` changes
```

View File

@ -10,6 +10,14 @@ import (
"github.com/mitchellh/hashstructure"
)
// DiffableWithID defines an object that has a unique and stable value that can
// be used as an identifier when generating a diff.
type DiffableWithID interface {
// DiffID returns the value to use to match entities between the old and
// the new input.
DiffID() string
}
// DiffType denotes the type of a diff object.
type DiffType string
@ -2419,11 +2427,20 @@ func primitiveObjectSetDiff(old, new []interface{}, filter []string, name string
makeSet := func(objects []interface{}) map[string]interface{} {
objMap := make(map[string]interface{}, len(objects))
for _, obj := range objects {
var key string
if diffable, ok := obj.(DiffableWithID); ok {
key = diffable.DiffID()
}
if key == "" {
hash, err := hashstructure.Hash(obj, nil)
if err != nil {
panic(err)
}
objMap[fmt.Sprintf("%d", hash)] = obj
key = fmt.Sprintf("%d", hash)
}
objMap[key] = obj
}
return objMap
@ -2433,10 +2450,11 @@ func primitiveObjectSetDiff(old, new []interface{}, filter []string, name string
newSet := makeSet(new)
var diffs []*ObjectDiff
for k, v := range oldSet {
// Deleted
if _, ok := newSet[k]; !ok {
diffs = append(diffs, primitiveObjectDiff(v, nil, filter, name, contextual))
for k, oldObj := range oldSet {
newObj := newSet[k]
diff := primitiveObjectDiff(oldObj, newObj, filter, name, contextual)
if diff != nil {
diffs = append(diffs, diff)
}
}
for k, v := range newSet {

View File

@ -4459,7 +4459,7 @@ func TestTaskDiff(t *testing.T) {
New: &Task{
Artifacts: []*TaskArtifact{
{
GetterSource: "foo",
GetterSource: "foo/bar",
GetterOptions: map[string]string{
"foo": "bar",
},
@ -4482,6 +4482,18 @@ func TestTaskDiff(t *testing.T) {
Expected: &TaskDiff{
Type: DiffTypeEdited,
Objects: []*ObjectDiff{
{
Type: DiffTypeEdited,
Name: "Artifact",
Fields: []*FieldDiff{
{
Type: DiffTypeEdited,
Name: "GetterSource",
Old: "foo",
New: "foo/bar",
},
},
},
{
Type: DiffTypeAdded,
Name: "Artifact",
@ -6914,7 +6926,7 @@ func TestTaskDiff(t *testing.T) {
{
SourcePath: "foo",
DestPath: "bar",
EmbeddedTmpl: "baz",
EmbeddedTmpl: "baz new",
ChangeMode: "bam",
ChangeSignal: "SIGHUP",
Splay: 1,
@ -6934,6 +6946,18 @@ func TestTaskDiff(t *testing.T) {
Expected: &TaskDiff{
Type: DiffTypeEdited,
Objects: []*ObjectDiff{
{
Type: DiffTypeEdited,
Name: "Template",
Fields: []*FieldDiff{
{
Type: DiffTypeEdited,
Name: "EmbeddedTmpl",
Old: "baz",
New: "baz new",
},
},
},
{
Type: DiffTypeAdded,
Name: "Template",

View File

@ -7479,6 +7479,11 @@ func (t *Template) Warnings() error {
return mErr.ErrorOrNil()
}
// DiffID fulfills the DiffableWithID interface.
func (t *Template) DiffID() string {
return t.DestPath
}
// AllocState records a single event that changes the state of the whole allocation
type AllocStateField uint8
@ -8120,6 +8125,11 @@ func (ta *TaskArtifact) GoString() string {
return fmt.Sprintf("%+v", ta)
}
// DiffID fulfills the DiffableWithID interface.
func (ta *TaskArtifact) DiffID() string {
return ta.RelativeDest
}
// hashStringMap appends a deterministic hash of m onto h.
func hashStringMap(h hash.Hash, m map[string]string) {
keys := make([]string, 0, len(m))