kube-forge v2: embede python with ansible (kubespray) and cobra as cli building tool
This commit is contained in:
161
internal/python/utils.go
Normal file
161
internal/python/utils.go
Normal file
@@ -0,0 +1,161 @@
|
||||
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}
|
||||
}
|
||||
Reference in New Issue
Block a user