mirror of
https://github.com/postmannen/ctrl.git
synced 2025-03-31 01:24:31 +00:00
For the Linux and Darwin operating system we allow to automatically detect shell interpreter, so the user don't have to type "bash", "-c" as the first two arguments of the methodArgs.
This commit is contained in:
parent
8ce651793c
commit
c89983c489
3 changed files with 61 additions and 16 deletions
|
@ -2,9 +2,12 @@ package ctrl
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
@ -16,6 +19,8 @@ import (
|
|||
// an if check should be added to the checkConfigValues function
|
||||
// to set default values when reading from config file.
|
||||
type Configuration struct {
|
||||
// Shell on the operating system to use when executing cliCommands
|
||||
ShellOnNode string
|
||||
// ConfigFolder, the location for the configuration folder on disk
|
||||
ConfigFolder string `comment:"ConfigFolder, the location for the configuration folder on disk"`
|
||||
// The folder where the socket file should live
|
||||
|
@ -152,6 +157,7 @@ func NewConfiguration() *Configuration {
|
|||
}
|
||||
|
||||
//flag.StringVar(&c.ConfigFolder, "configFolder", fc.ConfigFolder, "Defaults to ./usr/local/ctrl/etc/. *NB* This flag is not used, if your config file are located somwhere else than default set the location in an env variable named CONFIGFOLDER")
|
||||
flag.StringVar(&c.ShellOnNode, "shellOnNode", CheckEnv("SHELL_ON_NODE", c.ShellOnNode).(string), "set a value to override the default shell used as interpreter for running cliCommand's on node.")
|
||||
flag.StringVar(&c.SocketFolder, "socketFolder", CheckEnv("SOCKET_FOLDER", c.SocketFolder).(string), "folder who contains the socket file. Defaults to ./tmp/. If other folder is used this flag must be specified at startup.")
|
||||
flag.StringVar(&c.ReadFolder, "readFolder", CheckEnv("READ_FOLDER", c.ReadFolder).(string), "folder who contains the readfolder. Defaults to ./readfolder/. If other folder is used this flag must be specified at startup.")
|
||||
flag.StringVar(&c.TCPListener, "tcpListener", CheckEnv("TCP_LISTENER", c.TCPListener).(string), "start up a TCP listener in addition to the Unix Socket, to give messages to the system. e.g. localhost:8888. No value means not to start the listener, which is default. NB: You probably don't want to start this on any other interface than localhost")
|
||||
|
@ -220,14 +226,30 @@ func NewConfiguration() *Configuration {
|
|||
log.Fatalf("error: the centralNodeName config option or flag cannot be empty, check -help\n")
|
||||
}
|
||||
|
||||
c.ShellOnNode = getShell()
|
||||
fmt.Printf("\n******** DETECTED SHELL: %v\n\n", c.ShellOnNode)
|
||||
|
||||
flag.Parse()
|
||||
|
||||
return &c
|
||||
}
|
||||
|
||||
func getShell() string {
|
||||
out, err := exec.Command("echo", os.ExpandEnv("$SHELL")).Output()
|
||||
if err != nil {
|
||||
log.Fatalf("error: unable to detect shell: %v\n", err)
|
||||
}
|
||||
|
||||
shell := string(out)
|
||||
shell = strings.TrimSuffix(shell, "\n")
|
||||
|
||||
return string(shell)
|
||||
}
|
||||
|
||||
// Get a Configuration struct with the default values set.
|
||||
func newConfigurationDefaults() Configuration {
|
||||
c := Configuration{
|
||||
ShellOnNode: "",
|
||||
ConfigFolder: "./etc/",
|
||||
SocketFolder: "./tmp",
|
||||
ReadFolder: "./readfolder",
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
@ -27,8 +28,6 @@ func methodCliCommand(proc process, message Message, node string) ([]byte, error
|
|||
go func() {
|
||||
defer proc.processes.wg.Done()
|
||||
|
||||
var a []string
|
||||
|
||||
switch {
|
||||
case len(message.MethodArgs) < 1:
|
||||
er := fmt.Errorf("error: methodCliCommand: got <1 number methodArgs")
|
||||
|
@ -36,12 +35,8 @@ func methodCliCommand(proc process, message Message, node string) ([]byte, error
|
|||
newReplyMessage(proc, msgForErrors, []byte(er.Error()))
|
||||
|
||||
return
|
||||
case len(message.MethodArgs) >= 0:
|
||||
a = message.MethodArgs[1:]
|
||||
}
|
||||
|
||||
c := message.MethodArgs[0]
|
||||
|
||||
// Get a context with the timeout specified in message.MethodTimeout.
|
||||
ctx, cancel := getContextForMethodTimeout(proc.ctx, message)
|
||||
|
||||
|
@ -70,7 +65,24 @@ func methodCliCommand(proc process, message Message, node string) ([]byte, error
|
|||
}
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, c, a...)
|
||||
var cmd *exec.Cmd
|
||||
|
||||
// For the Linux and Darwin operating system we allow to automatically detect
|
||||
// shell interpreter, so the user don't have to type "bash", "-c" as the first
|
||||
// two arguments of the methodArgs.
|
||||
// We use the shell defined in the ShellOnNode variable as interpreter. Since
|
||||
// it expects a "-c" directly after in the command we prefix it to the args.
|
||||
if proc.configuration.ShellOnNode != "" {
|
||||
switch runtime.GOOS {
|
||||
case "linux", "darwin":
|
||||
args := []string{"-c"}
|
||||
args = append(args, message.MethodArgs...)
|
||||
|
||||
cmd = exec.CommandContext(ctx, proc.configuration.ShellOnNode, args...)
|
||||
default:
|
||||
cmd = exec.CommandContext(ctx, message.MethodArgs[0], message.MethodArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the use of env variable for CTRL_DATA, and set env if found.
|
||||
if foundEnvData {
|
||||
|
@ -149,8 +161,6 @@ func methodCliCommandCont(proc process, message Message, node string) ([]byte, e
|
|||
// fmt.Printf(" * DONE *\n")
|
||||
}()
|
||||
|
||||
var a []string
|
||||
|
||||
switch {
|
||||
case len(message.MethodArgs) < 1:
|
||||
er := fmt.Errorf("error: methodCliCommand: got <1 number methodArgs")
|
||||
|
@ -158,12 +168,8 @@ func methodCliCommandCont(proc process, message Message, node string) ([]byte, e
|
|||
newReplyMessage(proc, msgForErrors, []byte(er.Error()))
|
||||
|
||||
return
|
||||
case len(message.MethodArgs) >= 0:
|
||||
a = message.MethodArgs[1:]
|
||||
}
|
||||
|
||||
c := message.MethodArgs[0]
|
||||
|
||||
// Get a context with the timeout specified in message.MethodTimeout.
|
||||
ctx, cancel := getContextForMethodTimeout(proc.ctx, message)
|
||||
// deadline, _ := ctx.Deadline()
|
||||
|
@ -176,7 +182,24 @@ func methodCliCommandCont(proc process, message Message, node string) ([]byte, e
|
|||
go func() {
|
||||
defer proc.processes.wg.Done()
|
||||
|
||||
cmd := exec.CommandContext(ctx, c, a...)
|
||||
var cmd *exec.Cmd
|
||||
|
||||
// For the Linux and Darwin operating system we allow to automatically detect
|
||||
// shell interpreter, so the user don't have to type "bash", "-c" as the first
|
||||
// two arguments of the methodArgs.
|
||||
// We use the shell defined in the ShellOnNode variable as interpreter. Since
|
||||
// it expects a "-c" directly after in the command we prefix it to the args.
|
||||
if proc.configuration.ShellOnNode != "" {
|
||||
switch runtime.GOOS {
|
||||
case "linux", "darwin":
|
||||
args := []string{"-c"}
|
||||
args = append(args, message.MethodArgs...)
|
||||
|
||||
cmd = exec.CommandContext(ctx, proc.configuration.ShellOnNode, args...)
|
||||
default:
|
||||
cmd = exec.CommandContext(ctx, message.MethodArgs[0], message.MethodArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
// Using cmd.StdoutPipe here so we are continuosly
|
||||
// able to read the out put of the command.
|
||||
|
|
|
@ -61,7 +61,7 @@ func methodOpProcessStart(proc process, message Message, node string) ([]byte, e
|
|||
method := Method(m)
|
||||
tmpH := mt.getHandler(Method(method))
|
||||
if tmpH == nil {
|
||||
er := fmt.Errorf("error: OpProcessStart: no such request type defined: %v" + m)
|
||||
er := fmt.Errorf("error: OpProcessStart: no such request type defined: %v", m)
|
||||
proc.errorKernel.errSend(proc, message, er, logWarning)
|
||||
return
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ func methodOpProcessStop(proc process, message Message, node string) ([]byte, er
|
|||
method := Method(methodString)
|
||||
tmpH := mt.getHandler(Method(method))
|
||||
if tmpH == nil {
|
||||
er := fmt.Errorf("error: OpProcessStop: no such request type defined: %v, check that the methodArgs are correct: " + methodString)
|
||||
er := fmt.Errorf("error: OpProcessStop: no such request type defined: %v, check that the methodArgs are correct: ", methodString)
|
||||
proc.errorKernel.errSend(proc, message, er, logWarning)
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue