feat(exec): initial
This commit is contained in:
parent
8cf92167df
commit
653b4ff158
|
@ -1,2 +1,3 @@
|
|||
/cmd/wingmate/wingmate
|
||||
/cmd/pidproxy/pidproxy
|
||||
/cmd/pidproxy/pidproxy
|
||||
/cmd/exec/exec
|
4
Makefile
4
Makefile
|
@ -8,6 +8,9 @@ wingmate:
|
|||
pidproxy:
|
||||
$(MAKE) -C cmd/pidproxy all
|
||||
|
||||
exec:
|
||||
$(MAKE) -C cmd/exec all
|
||||
|
||||
dummy:
|
||||
$(MAKE) -C cmd/experiment/dummy all
|
||||
|
||||
|
@ -23,6 +26,7 @@ starter:
|
|||
clean:
|
||||
$(MAKE) -C cmd/wingmate clean
|
||||
$(MAKE) -C cmd/pidproxy clean
|
||||
$(MAKE) -C cmd/exec clean
|
||||
$(MAKE) -C cmd/experiment/dummy clean
|
||||
$(MAKE) -C cmd/experiment/oneshot clean
|
||||
$(MAKE) -C cmd/experiment/spawner clean
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
all:
|
||||
go build -v
|
||||
|
||||
clean:
|
||||
go clean -i -cache -testcache
|
|
@ -0,0 +1,11 @@
|
|||
//go:build !(cgo && linux)
|
||||
|
||||
package main
|
||||
|
||||
func getUid(user string) (uint64, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func getGid(group string) (uint64, error) {
|
||||
panic("not implemented")
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
//go:build cgo && linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
func getUid(user string) (uint64, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func getGid(group string) (uint64, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gitea.suyono.dev/suyono/wingmate"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
setsidFlag = "setsid"
|
||||
EnvSetsid = "SETSID"
|
||||
userFlag = "user"
|
||||
EnvUser = "USER"
|
||||
)
|
||||
|
||||
var (
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "wmexec",
|
||||
RunE: execCmd,
|
||||
}
|
||||
|
||||
childArgs []string
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
found bool
|
||||
i int
|
||||
arg string
|
||||
selfArgs []string
|
||||
)
|
||||
|
||||
rootCmd.PersistentFlags().BoolP(setsidFlag, "s", false, "set to true to run setsid() before exec")
|
||||
viper.BindPFlag(EnvSetsid, rootCmd.PersistentFlags().Lookup(setsidFlag))
|
||||
|
||||
rootCmd.PersistentFlags().StringP(userFlag, "u", "", "\"user:[group]\"")
|
||||
viper.BindPFlag(EnvUser, rootCmd.PersistentFlags().Lookup(userFlag))
|
||||
|
||||
viper.SetEnvPrefix(wingmate.EnvPrefix)
|
||||
viper.BindEnv(EnvUser)
|
||||
viper.BindEnv(EnvSetsid)
|
||||
viper.SetDefault(EnvSetsid, false)
|
||||
viper.SetDefault(EnvUser, "")
|
||||
|
||||
found = false
|
||||
for i, arg = range os.Args {
|
||||
if arg == "--" {
|
||||
found = true
|
||||
if len(os.Args) <= i+1 {
|
||||
log.Println("invalid argument")
|
||||
os.Exit(1)
|
||||
}
|
||||
selfArgs = os.Args[1:i]
|
||||
childArgs = os.Args[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
log.Println("invalid argument")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(childArgs) == 0 {
|
||||
log.Println("invalid argument")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
rootCmd.SetArgs(selfArgs)
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func execCmd(cmd *cobra.Command, args []string) error {
|
||||
if viper.GetBool(EnvSetsid) {
|
||||
_, _ = unix.Setsid()
|
||||
}
|
||||
|
||||
var (
|
||||
uid uint64
|
||||
gid uint64
|
||||
err error
|
||||
path string
|
||||
)
|
||||
|
||||
ug := viper.GetString(EnvUser)
|
||||
if len(ug) > 0 {
|
||||
user, group, ok := strings.Cut(ug, ":")
|
||||
uid, err = strconv.ParseUint(user, 10, 32)
|
||||
if err != nil {
|
||||
if uid, err = getUid(user); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = unix.Setuid(int(uid)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ok {
|
||||
if gid, err = strconv.ParseUint(group, 10, 32); err != nil {
|
||||
if gid, err = getGid(group); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = unix.Setgid(int(gid)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if path, err = exec.LookPath(childArgs[0]); err != nil {
|
||||
if !errors.Is(err, exec.ErrDot) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = unix.Exec(path, childArgs, os.Environ()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -42,11 +42,6 @@ func main() {
|
|||
viper.BindEnv(EnvStartSecs)
|
||||
viper.SetDefault(EnvStartSecs, EnvDefaultStartSecs)
|
||||
|
||||
if len(os.Args) <= 2 {
|
||||
log.Println("invalid argument")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
rootCmd.PersistentFlags().StringP(pidFileFlag, "p", "", "location of pid file")
|
||||
rootCmd.MarkFlagRequired(pidFileFlag)
|
||||
viper.BindPFlag(pidFileFlag, rootCmd.PersistentFlags().Lookup(pidFileFlag))
|
||||
|
@ -55,11 +50,11 @@ func main() {
|
|||
for i, arg = range os.Args {
|
||||
if arg == "--" {
|
||||
found = true
|
||||
selfArgs = os.Args[1:i]
|
||||
if len(os.Args) <= i+1 {
|
||||
log.Println("invalid argument")
|
||||
os.Exit(1)
|
||||
}
|
||||
selfArgs = os.Args[1:i]
|
||||
childArgs = os.Args[i+1:]
|
||||
break
|
||||
}
|
||||
|
@ -69,6 +64,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(childArgs) == 0 {
|
||||
log.Println("invalid argument")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
rootCmd.SetArgs(selfArgs)
|
||||
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
|
|
Loading…
Reference in New Issue