From ae3ceedd69cad73fa69850e88352f584952bf361 Mon Sep 17 00:00:00 2001 From: Eugene Yakubovich Date: Fri, 18 Sep 2015 10:30:10 -0700 Subject: [PATCH] bug fix: exec of DEL cmd caused JSON decode error When plugin is executed with a DEL command, it does not print result to stdout unless there is an error. Therefore it stdout bytes should not be passed to json.Unmarshal. --- invoke/exec.go | 22 ++++++++++++++++++---- ipam/ipam.go | 5 ++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/invoke/exec.go b/invoke/exec.go index d7c5b7ab..cf0cff47 100644 --- a/invoke/exec.go +++ b/invoke/exec.go @@ -41,7 +41,23 @@ func pluginErr(err error, output []byte) error { return err } -func ExecPlugin(pluginPath string, netconf []byte, args CNIArgs) (*types.Result, error) { +func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs) (*types.Result, error) { + stdoutBytes, err := execPlugin(pluginPath, netconf, args) + if err != nil { + return nil, err + } + + res := &types.Result{} + err = json.Unmarshal(stdoutBytes, res) + return res, err +} + +func ExecPluginWithoutResult(pluginPath string, netconf []byte, args CNIArgs) error { + _, err := execPlugin(pluginPath, netconf, args) + return err +} + +func execPlugin(pluginPath string, netconf []byte, args CNIArgs) ([]byte, error) { if pluginPath == "" { return nil, fmt.Errorf("could not find %q plugin", filepath.Base(pluginPath)) } @@ -60,7 +76,5 @@ func ExecPlugin(pluginPath string, netconf []byte, args CNIArgs) (*types.Result, return nil, pluginErr(err, stdout.Bytes()) } - res := &types.Result{} - err := json.Unmarshal(stdout.Bytes(), res) - return res, err + return stdout.Bytes(), nil } diff --git a/ipam/ipam.go b/ipam/ipam.go index a76299d7..6a593a26 100644 --- a/ipam/ipam.go +++ b/ipam/ipam.go @@ -29,15 +29,14 @@ func ExecAdd(plugin string, netconf []byte) (*types.Result, error) { if os.Getenv("CNI_COMMAND") != "ADD" { return nil, fmt.Errorf("CNI_COMMAND is not ADD") } - return invoke.ExecPlugin(invoke.Find(plugin), netconf, invoke.ArgsFromEnv()) + return invoke.ExecPluginWithResult(invoke.Find(plugin), netconf, invoke.ArgsFromEnv()) } func ExecDel(plugin string, netconf []byte) error { if os.Getenv("CNI_COMMAND") != "DEL" { return fmt.Errorf("CNI_COMMAND is not DEL") } - _, err := invoke.ExecPlugin(invoke.Find(plugin), netconf, invoke.ArgsFromEnv()) - return err + return invoke.ExecPluginWithoutResult(invoke.Find(plugin), netconf, invoke.ArgsFromEnv()) } // ConfigureIface takes the result of IPAM plugin and