162 lines
3.5 KiB
Go
162 lines
3.5 KiB
Go
package python
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"kube-forge/internal/python/data"
|
|
"kube-forge/internal/resources"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
|
|
executable "github.com/apenella/go-ansible/v2/pkg/execute/exec"
|
|
"github.com/kluctl/go-embed-python/embed_util"
|
|
"github.com/kluctl/go-embed-python/python"
|
|
)
|
|
|
|
type PythonExec struct {
|
|
ep *python.EmbeddedPython
|
|
PythonLibFsPath string
|
|
ResourcesFsPath string
|
|
}
|
|
|
|
type CmdWrapper struct {
|
|
*exec.Cmd
|
|
}
|
|
|
|
func (c *CmdWrapper) CombinedOutput() ([]byte, error) {
|
|
return c.Cmd.CombinedOutput()
|
|
}
|
|
|
|
func (c *CmdWrapper) Environ() []string {
|
|
return c.Cmd.Environ()
|
|
}
|
|
|
|
func (c *CmdWrapper) Output() ([]byte, error) {
|
|
return c.Cmd.Output()
|
|
}
|
|
|
|
func (c *CmdWrapper) Run() error {
|
|
return c.Cmd.Run()
|
|
}
|
|
|
|
func (c *CmdWrapper) Start() error {
|
|
return c.Cmd.Start()
|
|
}
|
|
|
|
func (c *CmdWrapper) StderrPipe() (io.ReadCloser, error) {
|
|
return c.Cmd.StderrPipe()
|
|
}
|
|
|
|
func (c *CmdWrapper) StdinPipe() (io.WriteCloser, error) {
|
|
return c.Cmd.StdinPipe()
|
|
}
|
|
|
|
func (c *CmdWrapper) StdoutPipe() (io.ReadCloser, error) {
|
|
return c.Cmd.StdoutPipe()
|
|
}
|
|
|
|
func (c *CmdWrapper) String() string {
|
|
return c.Cmd.String()
|
|
}
|
|
|
|
func (c *CmdWrapper) Wait() error {
|
|
return c.Cmd.Wait()
|
|
}
|
|
|
|
type ErrorCmd struct {
|
|
err error
|
|
}
|
|
|
|
func (e *ErrorCmd) CombinedOutput() ([]byte, error) {
|
|
return nil, e.err
|
|
}
|
|
|
|
func (e *ErrorCmd) Environ() []string {
|
|
return nil
|
|
}
|
|
|
|
func (e *ErrorCmd) Output() ([]byte, error) {
|
|
return nil, e.err
|
|
}
|
|
|
|
func (e *ErrorCmd) Run() error {
|
|
return e.err
|
|
}
|
|
|
|
func (e *ErrorCmd) Start() error {
|
|
return e.err
|
|
}
|
|
|
|
func (e *ErrorCmd) StderrPipe() (io.ReadCloser, error) {
|
|
return nil, e.err
|
|
}
|
|
|
|
func (e *ErrorCmd) StdinPipe() (io.WriteCloser, error) {
|
|
return nil, e.err
|
|
}
|
|
|
|
func (e *ErrorCmd) StdoutPipe() (io.ReadCloser, error) {
|
|
return nil, e.err
|
|
}
|
|
|
|
func (e *ErrorCmd) String() string {
|
|
return fmt.Sprintf("ErrorCmd: %v", e.err)
|
|
}
|
|
|
|
func (e *ErrorCmd) Wait() error {
|
|
return e.err
|
|
}
|
|
|
|
func NewPythonExec() *PythonExec {
|
|
tmpDir := filepath.Join(os.TempDir(), "go-ansible")
|
|
pythonDir := tmpDir + "-python"
|
|
pythonLibDir := tmpDir + "-python-lib"
|
|
resourcesDir := tmpDir + "-resources"
|
|
|
|
pythonLibFs, err := embed_util.NewEmbeddedFilesWithTmpDir(data.Data, pythonLibDir, true)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
pythonLibFsPath := pythonLibFs.GetExtractedPath()
|
|
resourcesFs, _ := embed_util.NewEmbeddedFilesWithTmpDir(resources.Kubespray, resourcesDir, true)
|
|
resourcesFsPath := resourcesFs.GetExtractedPath()
|
|
|
|
ep, _ := python.NewEmbeddedPythonWithTmpDir(pythonDir, true)
|
|
ep.AddPythonPath(pythonLibFs.GetExtractedPath())
|
|
ep.AddPythonPath(resourcesFs.GetExtractedPath())
|
|
|
|
return &PythonExec{
|
|
ep: ep,
|
|
PythonLibFsPath: pythonLibFsPath,
|
|
ResourcesFsPath: resourcesFsPath,
|
|
}
|
|
}
|
|
|
|
func (e *PythonExec) Command(name string, arg ...string) executable.Cmder {
|
|
cmd := append([]string{name}, arg...)
|
|
execCmd, err := e.ep.PythonCmd2(cmd)
|
|
if err != nil {
|
|
return &ErrorCmd{err: fmt.Errorf("failed to create python command: %w", err)}
|
|
}
|
|
return &CmdWrapper{Cmd: execCmd}
|
|
}
|
|
|
|
func (e *PythonExec) CommandContext(ctx context.Context, name string, arg ...string) executable.Cmder {
|
|
cmd := append([]string{name}, arg...)
|
|
execCmd, err := e.ep.PythonCmd2(cmd)
|
|
if err != nil {
|
|
return &ErrorCmd{err: fmt.Errorf("failed to create python command: %w", err)}
|
|
}
|
|
|
|
ctxCmd := exec.CommandContext(ctx, execCmd.Path, execCmd.Args[1:]...)
|
|
ctxCmd.Env = execCmd.Env
|
|
ctxCmd.Dir = execCmd.Dir
|
|
ctxCmd.Stdin = execCmd.Stdin
|
|
ctxCmd.Stdout = execCmd.Stdout
|
|
ctxCmd.Stderr = execCmd.Stderr
|
|
|
|
return &CmdWrapper{Cmd: ctxCmd}
|
|
}
|