For windows, use exec.Command instead of syscall.Execve.

sycall.Execve is not supported on windows.
This commit is contained in:
Pradeep Sawlani 2019-04-05 17:42:17 -07:00 committed by Pradeep Sawlani
parent 20cece67b5
commit 13be373ce7
4 changed files with 29 additions and 6 deletions

View File

@ -22,6 +22,7 @@ import (
"io"
"os"
"os/exec"
"runtime"
"strings"
"syscall"
@ -364,7 +365,24 @@ func (h *DefaultPluginHandler) Lookup(filename string) (string, bool) {
// Execute implements PluginHandler
func (h *DefaultPluginHandler) Execute(executablePath string, cmdArgs, environment []string) error {
return syscall.Exec(executablePath, cmdArgs, environment)
// Windows does not support exec syscall.
if runtime.GOOS == "windows" {
cmd := exec.Command(executablePath, cmdArgs...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Env = environment
err := cmd.Run()
if err == nil {
os.Exit(0)
}
return err
}
// invoke cmd binary relaying the environment and args given
// append executablePath to cmdArgs, as execve will make first argument the "binary name".
return syscall.Exec(executablePath, append([]string{executablePath}, cmdArgs...), environment)
}
// HandlePluginCommand receives a pluginHandler and command-line arguments and attempts to find
@ -398,9 +416,7 @@ func HandlePluginCommand(pluginHandler PluginHandler, cmdArgs []string) error {
}
// invoke cmd binary relaying the current environment and args given
// remainingArgs will always have at least one element.
// execve will make remainingArgs[0] the "binary name".
if err := pluginHandler.Execute(foundBinaryPath, append([]string{foundBinaryPath}, cmdArgs[len(remainingArgs):]...), os.Environ()); err != nil {
if err := pluginHandler.Execute(foundBinaryPath, cmdArgs[len(remainingArgs):], os.Environ()); err != nil {
return err
}

View File

@ -125,7 +125,7 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) {
name: "test that a plugin executable is found based on command args",
args: []string{"kubectl", "foo", "--bar"},
expectPlugin: "plugin/testdata/kubectl-foo",
expectPluginArgs: []string{"foo", "--bar"},
expectPluginArgs: []string{"--bar"},
},
{
name: "test that a plugin does not execute over an existing command by the same name",
@ -158,7 +158,7 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) {
}
if len(pluginsHandler.withArgs) != len(test.expectPluginArgs) {
t.Fatalf("unexpected plugin execution args: expedcted %q, got %q", test.expectPluginArgs, pluginsHandler.withArgs)
t.Fatalf("unexpected plugin execution args: expected %q, got %q", test.expectPluginArgs, pluginsHandler.withArgs)
}
})
}

View File

@ -44,6 +44,10 @@ run_plugins_tests() {
output_message=$(PATH=${PATH}:"test/fixtures/pkg/kubectl/plugins" kubectl foo)
kube::test::if_has_string "${output_message}" 'plugin foo'
# check arguments passed to the plugin
output_message=$(PATH=${PATH}:"test/fixtures/pkg/kubectl/plugins/bar" kubectl bar arg1)
kube::test::if_has_string "${output_message}" 'test/fixtures/pkg/kubectl/plugins/bar/kubectl-bar arg1'
# ensure that a kubectl command supersedes a plugin that overshadows it
output_message=$(PATH=${PATH}:"test/fixtures/pkg/kubectl/plugins/version" kubectl version)
kube::test::if_has_string "${output_message}" 'Client Version'

View File

@ -0,0 +1,3 @@
#!/bin/bash
echo "I am plugin bar called with args $0 $@"