Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#12 Kubernetes Environment #45

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions cmd/bifroest/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import goos "os"

func workingDirectory() string {
v, err := goos.Getwd()
if err == nil {
return v
}
return "/"
}
101 changes: 101 additions & 0 deletions cmd/bifroest/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package main

import (
goos "os"
"os/exec"
"os/signal"
"syscall"

"github.com/alecthomas/kingpin/v2"

"github.com/engity-com/bifroest/pkg/errors"
"github.com/engity-com/bifroest/pkg/sys"
)

var _ = registerCommand(func(app *kingpin.Application) {
opts := execOpts{
workingDirectory: workingDirectory(),
environment: sys.EnvVars{},
}

cmd := app.Command("exec", "Runs a given process with the given attributes (environment, working directory, ...).").
Hidden().
Action(func(*kingpin.ParseContext) error {
return doExec(&opts)
})
cmd.Flag("workingDir", "Directory to start in.").
Short('d').
Default(opts.workingDirectory).
PlaceHolder("<path>").
StringVar(&opts.workingDirectory)
cmd.Flag("executable", "Path to executable to be used. If not defined, first argument will be used.").
Short('p').
Default(opts.path).
PlaceHolder("<path>").
StringVar(&opts.path)
cmd.Flag("env", "Environment variables to execute the process with.").
Short('e').
StringMapVar(&opts.environment)
cmd.Arg("command", "Command to execute.").
Required().
StringsVar(&opts.argv)

registerExecCmdFlags(cmd, &opts)
})

func doExec(opts *execOpts) error {
fail := func(err error) error {
return err
}
failf := func(msg string, args ...any) error {
return fail(errors.System.Newf(msg, args...))
}

cmd := exec.Cmd{
Dir: opts.workingDirectory,
SysProcAttr: &syscall.SysProcAttr{},
Env: (sys.EnvVars(opts.environment)).Strings(),
Stderr: goos.Stderr,
Stdin: goos.Stdin,
Stdout: goos.Stdout,
Args: opts.argv,
Path: opts.path,
}

if cmd.Path == "" && len(cmd.Args) > 0 {
cmd.Path = cmd.Args[0]
}
var err error
if cmd.Path, err = exec.LookPath(cmd.Path); err != nil {
return fail(err)
}

if err := enrichExecCmd(&cmd, opts); err != nil {
return failf("cannot apply execution parameters to %v: :%w", cmd.Args, err)
}

sigs := make(chan goos.Signal, 1)
defer close(sigs)
signal.Notify(sigs)

go func() {
for {
sig, ok := <-sigs
if !ok {
return
}
_ = cmd.Process.Signal(sig)
}
}()

err = cmd.Run()
var eErr *exec.ExitError
if errors.As(err, &eErr) {
goos.Exit(eErr.ExitCode())
return nil
} else if err != nil {
return fail(err)
} else {
return nil
}
}
71 changes: 71 additions & 0 deletions cmd/bifroest/exec_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//go:build unix

package main

import (
"os/exec"
"os/user"
"strconv"
"syscall"

"github.com/alecthomas/kingpin/v2"

"github.com/engity-com/bifroest/pkg/errors"
)

type execOpts struct {
workingDirectory string
environment map[string]string
user, group string
path string
argv []string
}

func registerExecCmdFlags(cmd *kingpin.CmdClause, opts *execOpts) {
cmd.Flag("user", "User the process should run with.").
Default(opts.user).
Short('u').
StringVar(&opts.user)
cmd.Flag("group", "Group the process should run with.").
Default(opts.group).
Short('g').
StringVar(&opts.group)
}

func enrichExecCmd(cmd *exec.Cmd, with *execOpts) error {
if plainUser := with.user; plainUser != "" {
cmd.SysProcAttr.Credential = &syscall.Credential{}

u, err := user.LookupId(plainUser)
var uuiErr *user.UnknownUserIdError
if errors.As(err, &uuiErr) {
u, err = user.Lookup(plainUser)
}
if err != nil {
return err
}
if v, err := strconv.ParseUint(u.Uid, 10, 32); err != nil {
return err
} else {
cmd.SysProcAttr.Credential.Uid = uint32(v)
}

if plainGroup := with.group; plainGroup != "" {
g, err := user.LookupGroupId(plainGroup)
var ugiErr *user.UnknownGroupIdError
if errors.As(err, &ugiErr) {
g, err = user.LookupGroup(plainGroup)
}
if err != nil {
return err
}
if v, err := strconv.ParseUint(g.Gid, 10, 32); err != nil {
return err
} else {
cmd.SysProcAttr.Credential.Gid = uint32(v)
}
}
}

return nil
}
23 changes: 23 additions & 0 deletions cmd/bifroest/exec_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build windows

package main

import (
"os/exec"

"github.com/alecthomas/kingpin/v2"
)

type execOpts struct {
workingDirectory string
environment map[string]string
path string
argv []string
}

func registerExecCmdFlags(_ *kingpin.CmdClause, _ *execOpts) {
}

func enrichExecCmd(_ *exec.Cmd, _ *execOpts) error {
return nil
}
60 changes: 60 additions & 0 deletions cmd/bifroest/imp-init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"io"
goos "os"
"path/filepath"

"github.com/alecthomas/kingpin/v2"
log "github.com/echocat/slf4g"

"github.com/engity-com/bifroest/pkg/common"
"github.com/engity-com/bifroest/pkg/errors"
"github.com/engity-com/bifroest/pkg/imp"
"github.com/engity-com/bifroest/pkg/sys"
)

var _ = registerCommand(func(app *kingpin.Application) {
targetPath := imp.DefaultInitPath

cmd := app.Command("imp-init", "Prepares the environment to run Bifröst's imp inside.").
Hidden().
Action(func(*kingpin.ParseContext) error {
return doImpInit(targetPath)
})
cmd.Flag("targetPath", "Path to prepare.").
Default(targetPath).
PlaceHolder("<path>").
StringVar(&targetPath)
})

func doImpInit(targetPath string) (rErr error) {
log.WithAll(sys.VersionToMap(versionV)).
With("targetPath", targetPath).
Info("initialize target path for Engity's Bifröst imp...")

self, err := goos.Executable()
if err != nil {
return errors.System.Newf("cannot detect own location: %w", err)
}

sf, err := goos.Open(self)
if err != nil {
return errors.System.Newf("cannot open self (%s) for reading: %w", self, err)
}
defer common.IgnoreCloseError(sf)

_ = goos.MkdirAll(targetPath, 0755)
targetFile := filepath.Join(targetPath, versionV.Os().AppendExtToFilename("bifroest"))
tf, err := goos.OpenFile(targetFile, goos.O_CREATE|goos.O_TRUNC|goos.O_WRONLY, 0755)
if err != nil {
return errors.System.Newf("cannot open target file (%s) for writing: %w", targetFile, err)
}
defer common.KeepCloseError(&rErr, tf)

if _, err := io.Copy(tf, sf); err != nil {
return errors.System.Newf("cannot copy %s to %s: %w", self, targetFile, err)
}

return nil
}
2 changes: 1 addition & 1 deletion cmd/bifroest/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var _ = registerCommand(func(app *kingpin.Application) {
configureRunCmd(app)
})

func doRunDefault(conf configuration.ConfigurationRef) error {
func doRunDefault(conf configuration.Ref) error {
svc := service.Service{
Configuration: *conf.Get(),
Version: versionV,
Expand Down
4 changes: 2 additions & 2 deletions cmd/bifroest/run_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const (
)

func configureRunCmd(app *kingpin.Application) *kingpin.Application {
var conf configuration.ConfigurationRef
var conf configuration.Ref
cmd := app.Command("run", "Runs the service.").
Action(func(*kingpin.ParseContext) error {
return doRun(conf)
Expand All @@ -26,6 +26,6 @@ func configureRunCmd(app *kingpin.Application) *kingpin.Application {
return app
}

func doRun(conf configuration.ConfigurationRef) error {
func doRun(conf configuration.Ref) error {
return doRunDefault(conf)
}
4 changes: 2 additions & 2 deletions cmd/bifroest/run_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (

func configureRunCmd(app *kingpin.Application) *kingpin.Application {
var ws windowsService
var conf configuration.ConfigurationRef
var conf configuration.Ref
cmd := app.Command("run", "Runs the service.").
Action(func(*kingpin.ParseContext) error {
return doRun(conf, &ws)
Expand All @@ -36,7 +36,7 @@ func configureRunCmd(app *kingpin.Application) *kingpin.Application {

}

func doRun(conf configuration.ConfigurationRef, ws *windowsService) error {
func doRun(conf configuration.Ref, ws *windowsService) error {
inService, err := svc.IsWindowsService()
if err != nil {
return errors.System.Newf("failed to determine if we are running in service: %w", err)
Expand Down
6 changes: 3 additions & 3 deletions cmd/bifroest/service_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const (

type windowsService struct {
name string
conf configuration.ConfigurationRef
conf configuration.Ref
logger *eventlog.Log
}

Expand All @@ -42,7 +42,7 @@ func (this *windowsService) registerFlagsAt(cmd *kingpin.CmdClause) *kingpin.Cmd
var _ = registerCommand(func(app *kingpin.Application) {
svcCmd := app.Command("service", "")

var conf configuration.ConfigurationRef
var conf configuration.Ref
var svc windowsService
common := func(cmd *kingpin.CmdClause) *kingpin.CmdClause {
return svc.registerFlagsAt(cmd)
Expand Down Expand Up @@ -123,7 +123,7 @@ func (this *windowsService) Execute(_ []string, r <-chan svc.ChangeRequest, chan
return false, 0
}

func (this *windowsService) install(conf configuration.ConfigurationRef, start, retry bool) error {
func (this *windowsService) install(conf configuration.Ref, start, retry bool) error {
if err := conf.MakeAbsolute(); err != nil {
return err
}
Expand Down
23 changes: 8 additions & 15 deletions cmd/bifroest/sftp-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,23 @@ import (
"github.com/engity-com/bifroest/pkg/sftp"
)

var (
workingDir = func() string {
v, err := goos.Getwd()
if err == nil {
return v
}
return "/"
}()
)

var _ = registerCommand(func(app *kingpin.Application) {
cwd := workingDirectory()

cmd := app.Command("sftp-server", "Run the sftp server instance used by this instance.").
Hidden().
Action(func(*kingpin.ParseContext) error {
return doSftpServer()
return doSftpServer(cwd)
})
cmd.Flag("workingDir", "Directory to start in. Default: "+workingDir).
cmd.Flag("workingDir", "Directory to start in.").
Default(cwd).
PlaceHolder("<path>").
StringVar(&workingDir)
StringVar(&cwd)
})

func doSftpServer() error {
func doSftpServer(cwd string) error {
s := sftp.Server{
WorkingDir: workingDir,
WorkingDir: cwd,
}

if err := s.Run(&stdpipe{}); err != nil {
Expand Down
Loading
Loading