Skip to content

Commit

Permalink
Fix execution of plugins on Windows
Browse files Browse the repository at this point in the history
- syscall.Exec is not supported on Windows systems. Use the os/exec
  package instead.
- On windows the plugin executables should have the .exe filename
  extension in order to execute them.

Signed-off-by: Han Verstraete (OpenFaaS Ltd) <[email protected]>
  • Loading branch information
welteki authored and alexellis committed Jan 26, 2024
1 parent 2f9258b commit a3e72b5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
39 changes: 31 additions & 8 deletions commands/faas.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
package commands

import (
"errors"
"fmt"
"log"
"os"
"os/exec"
"path"
"runtime"
"strings"
Expand Down Expand Up @@ -88,21 +90,42 @@ func Execute(customArgs []string) {
}

if cmd1 != nil && len(args1) > 0 {

found := ""
for _, plugin := range plugins {
if path.Base(plugin) == args1[0] {
pluginName := args1[0]
if runtime.GOOS == "windows" {
pluginName = fmt.Sprintf("%s.exe", args1[0])
}

if path.Base(plugin) == pluginName {
found = plugin
}
}
if len(found) > 0 {

// if we have found the plugin then sysexec it by replacing current process.
if err := syscall.Exec(found, append([]string{found}, os.Args[2:]...), os.Environ()); err != nil {
fmt.Fprintf(os.Stderr, "Error from plugin: %v", err)
os.Exit(127)
// If we have found the plugin then sysexec it by replacing the current process.
// On Windows we use the os/exec package to run the plugins since replacing the current
// process with syscall.exec is not supported.
if runtime.GOOS == "windows" {
cmd := exec.Command(found, os.Args[2:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
os.Exit(exitErr.ExitCode())
} else {
fmt.Println("Error from plugin", err)
os.Exit(127)
}
}
return
} else {
if err := syscall.Exec(found, append([]string{found}, os.Args[2:]...), os.Environ()); err != nil {
fmt.Fprintf(os.Stderr, "Error from plugin: %v", err)
os.Exit(127)
}
return
}
return
}
}

Expand Down
11 changes: 11 additions & 0 deletions commands/plugin_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@ func runPluginGetCmd(cmd *cobra.Command, args []string) error {
if err := archive.Untar(tarFile, pluginDir, gzipped, true); err != nil {
return fmt.Errorf("failed to untar %s: %w", tmpTar, err)
}

// Add the .exe filename extension to the plugin executable on windows.
// If the .exe extension is missing the plugin will not execute.
if runtime.GOOS == "windows" {
pluginPath := path.Join(pluginDir, pluginName)
err := os.Rename(pluginPath, fmt.Sprintf("%s.exe", pluginPath))
if err != nil {
return fmt.Errorf("failed to move plugin %w", err)
}
}

fmt.Printf("Downloaded in (%ds)\n\nUsage:\n faas-cli %s\n", int(time.Since(st).Seconds()), pluginName)
return nil
}
Expand Down

0 comments on commit a3e72b5

Please sign in to comment.