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