1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
package exec
import (
"bytes"
"context"
"encoding/json"
"reflect"
"time"
"github.com/davecgh/go-spew/spew"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/pmezard/go-difflib/difflib"
"github.com/sirupsen/logrus"
)
var spewConfig = spew.ConfigState{
Indent: " ",
DisablePointerAddresses: true,
DisableCapacities: true,
SortKeys: true,
}
// RuntimeConfigFilter calls a series of hooks. But instead of
// passing container state on their standard input,
// RuntimeConfigFilter passes the proposed runtime configuration (and
// reads back a possibly-altered form from their standard output).
func RuntimeConfigFilter(ctx context.Context, hooks []spec.Hook, config *spec.Spec, postKillTimeout time.Duration) (hookErr, err error) {
data, err := json.Marshal(config)
if err != nil {
return nil, err
}
for i, hook := range hooks {
hook := hook
var stdout bytes.Buffer
hookErr, err = Run(ctx, &hook, data, &stdout, nil, postKillTimeout)
if err != nil {
return hookErr, err
}
data = stdout.Bytes()
var newConfig spec.Spec
err = json.Unmarshal(data, &newConfig)
if err != nil {
logrus.Debugf("invalid JSON from config-filter hook %d:\n%s", i, string(data))
return nil, errors.Wrapf(err, "unmarshal output from config-filter hook %d", i)
}
if !reflect.DeepEqual(config, &newConfig) {
oldConfig := spewConfig.Sdump(config)
newConfig := spewConfig.Sdump(&newConfig)
diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
A: difflib.SplitLines(oldConfig),
B: difflib.SplitLines(newConfig),
FromFile: "Old",
FromDate: "",
ToFile: "New",
ToDate: "",
Context: 1,
})
if err == nil {
logrus.Debugf("precreate hook %d made configuration changes:\n%s", i, diff)
} else {
logrus.Warnf("precreate hook %d made configuration changes, but we could not compute a diff: %v", i, err)
}
}
*config = newConfig
}
return nil, nil
}
|