diff --git a/pkg/plugin/ipam.go b/pkg/plugin/ipam.go index 8b59cab7..4124d0f8 100644 --- a/pkg/plugin/ipam.go +++ b/pkg/plugin/ipam.go @@ -125,9 +125,18 @@ func ConfigureIface(ifName string, res *Result) error { return nil } -// PrintResult writes out prettified Result to stdout +// PrintResult writes out prettified Result JSON to stdout func PrintResult(res *Result) error { - data, err := json.MarshalIndent(res, "", " ") + return prettyPrint(res) +} + +// PrintError writes out prettified Error JSON to stdout +func PrintError(err *Error) error { + return prettyPrint(err) +} + +func prettyPrint(obj interface{}) error { + data, err := json.MarshalIndent(obj, "", " ") if err != nil { return err } diff --git a/pkg/plugin/types.go b/pkg/plugin/types.go index 6eb6ac21..9db0f10e 100644 --- a/pkg/plugin/types.go +++ b/pkg/plugin/types.go @@ -48,6 +48,12 @@ type Route struct { GW net.IP } +type Error struct { + Code uint `json:"code"` + Msg string `json:"msg"` + Details string `json:"details,omitempty"` +} + // net.IPNet is not JSON (un)marshallable so this duality is needed // for our custom ip.IPNet type diff --git a/pkg/skel/skel.go b/pkg/skel/skel.go index 9f033350..4f159adb 100644 --- a/pkg/skel/skel.go +++ b/pkg/skel/skel.go @@ -17,9 +17,12 @@ package skel import ( + "fmt" "io/ioutil" "log" "os" + + "github.com/appc/cni/pkg/plugin" ) // CmdArgs captures all the arguments passed in to the plugin @@ -61,13 +64,12 @@ func PluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error) { } if argsMissing { - os.Exit(1) + die("required env variables missing") } stdinData, err := ioutil.ReadAll(os.Stdin) if err != nil { - log.Printf("Error reading from stdin: %v", err) - os.Exit(1) + die("error reading from stdin: %v", err) } cmdArgs := &CmdArgs{ @@ -87,12 +89,18 @@ func PluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error) { err = cmdDel(cmdArgs) default: - log.Printf("Unknown CNI_COMMAND: %v", cmd) - os.Exit(1) + die("unknown CNI_COMMAND: %v", cmd) } if err != nil { - log.Printf("%v: %v", cmd, err) - os.Exit(1) + die(err.Error()) } } + +func die(f string, args ...interface{}) { + plugin.PrintError(&plugin.Error{ + Code: 100, + Msg: fmt.Sprintf(f, args...), + }) + os.Exit(1) +}