Skip to content

Commit

Permalink
fix(worker): windows and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fsamin authored and richardlt committed Jan 17, 2020
1 parent 378259c commit 8ac8fae
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 43 deletions.
8 changes: 4 additions & 4 deletions engine/worker/internal/action/builtin_gitclone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestRunGitCloneInSSHWithPrivateKey(t *testing.T) {
},
[]sdk.Variable{
{
Name: "proj-ssh-key",
Name: "cds.key.proj-ssh-key.priv",
Value: string(test.TestKey),
},
})
Expand Down Expand Up @@ -83,7 +83,7 @@ func TestRunGitCloneInSSHWithTheWrongPrivateKeyShouldFail(t *testing.T) {
},
[]sdk.Variable{
{
Name: "proj-ssh-key",
Name: "cds.key.proj-ssh-key.priv",
Value: "this not a private key",
},
})
Expand Down Expand Up @@ -111,7 +111,7 @@ func TestRunGitCloneInSSHWithPrivateKeyWithTargetDirectory(t *testing.T) {
},
[]sdk.Variable{
{
Name: "proj-ssh-key",
Name: "cds.key.proj-ssh-key.priv",
Value: string(test.TestKey),
},
})
Expand Down Expand Up @@ -152,7 +152,7 @@ func TestRunGitCloneInSSHWithPrivateKeyAndExtractInfo(t *testing.T) {
},
[]sdk.Variable{
{
Name: "proj-ssh-key",
Name: "cds.key.proj-ssh-key.priv",
Value: string(test.TestKey),
},
})
Expand Down
81 changes: 44 additions & 37 deletions engine/worker/internal/action/builtin_script.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import (
"runtime"
"strings"

"github.com/spf13/afero"

"github.com/kardianos/osext"
"github.com/spf13/afero"

"github.com/ovh/cds/engine/worker/pkg/workerruntime"
"github.com/ovh/cds/sdk"
Expand All @@ -30,7 +29,7 @@ type script struct {
opts []string
}

func prepareScriptContent(parameters []sdk.Parameter) (*script, error) {
func prepareScriptContent(parameters []sdk.Parameter, basedir afero.Fs, workdir afero.File) (*script, error) {
var script = script{
shell: "/bin/sh",
}
Expand All @@ -46,7 +45,7 @@ func prepareScriptContent(parameters []sdk.Parameter) (*script, error) {
}

// except on windows where it's powershell
if sdk.GOOS == "windows" {
if isWindows() {
script.shell = "PowerShell"
script.opts = []string{"-ExecutionPolicy", "Bypass", "-Command"}
// on windows, we add ErrorActionPreference just below
Expand All @@ -68,9 +67,19 @@ func prepareScriptContent(parameters []sdk.Parameter) (*script, error) {

script.content = []byte(scriptContent)

if x, ok := basedir.(*afero.BasePathFs); ok {
script.dir, _ = x.RealPath(workdir.Name())
} else {
script.dir = workdir.Name()
}

return &script, nil
}

func isWindows() bool {
return sdk.GOOS == "windows" || runtime.GOOS == "windows" || os.Getenv("CDS_WORKER_PSHELL_MODE") == "true"
}

func writeScriptContent(ctx context.Context, script *script, fs afero.Fs, basedir afero.File) (func(), error) {
fi, err := basedir.Stat()
if err != nil {
Expand All @@ -89,11 +98,16 @@ func writeScriptContent(ctx context.Context, script *script, fs afero.Fs, basedi
}
tmpFileName := hex.EncodeToString(bs)[0:16]
log.Debug("writeScriptContent> Basedir name is %s (%T)", basedir.Name(), basedir)
path := filepath.Join(basedir.Name(), tmpFileName)

log.Debug("writeScriptContent> Opening file %s", path)
if isWindows() {
tmpFileName += ".PS1"
log.Debug("runScriptAction> renaming powershell script to %s", tmpFileName)
}

scriptPath := filepath.Join(path.Dir(basedir.Name()), tmpFileName)
log.Debug("writeScriptContent> Opening file %s", scriptPath)

tmpscript, err := fs.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0700)
tmpscript, err := fs.OpenFile(scriptPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0700)
if err != nil {
log.Warning(ctx, "writeScriptContent> Cannot create tmp file: %s", err)
return nil, fmt.Errorf("cannot create temporary file, aborting: %v", err)
Expand All @@ -104,9 +118,9 @@ func writeScriptContent(ctx context.Context, script *script, fs afero.Fs, basedi
n, errw := tmpscript.Write(script.content)
if errw != nil || n != len(script.content) {
if errw != nil {
log.Warning(ctx, "cannot write script: %s", errw)
log.Warning(ctx, "writeScriptContent> cannot write script: %s", errw)
} else {
log.Warning(ctx, "cannot write all script: %d/%d", n, len(script.content))
log.Warning(ctx, "writeScriptContent> cannot write all script: %d/%d", n, len(script.content))
}
return nil, errors.New("cannot write script in temporary file, aborting")
}
Expand All @@ -115,32 +129,31 @@ func writeScriptContent(ctx context.Context, script *script, fs afero.Fs, basedi
return nil, fmt.Errorf("unable to write script to %s", tmpscript)
}

if runtime.GOOS == "windows" {
//and add .PS1 extension
//newName := tmpFileName + ".PS1"
//if err := basedir.Rename(tmpFileName, newName); err != nil {
// return nil, errors.New("cannot rename script to add powershell Extension, aborting")
//}
//tmpFileName = newName
////This aims to stop a the very first error and return the right exit code
//psCommand := fmt.Sprintf("& { $ErrorActionPreference='Stop'; & %s ;exit $LastExitCode}", tmpFileName)
//scriptPath = newPath
//script.opts = append(script.opts, psCommand)
if isWindows() {
//This aims to stop a the very first error and return the right exit code
psCommand := fmt.Sprintf("& { $ErrorActionPreference='Stop'; & %s ;exit $LastExitCode}", tmpFileName)
script.opts = append(script.opts, psCommand)
} else {
script.opts = append(script.opts, tmpFileName)
switch x := fs.(type) {
case *afero.BasePathFs:
script.dir, err = x.RealPath(basedir.Name())
if err != nil {
return nil, fmt.Errorf("unable to get script working dir: %v", err)
}
default:
script.dir = basedir.Name()
}

switch x := fs.(type) {
case *afero.BasePathFs:
script.dir, err = x.RealPath(path.Dir(basedir.Name()))
if err != nil {
return nil, fmt.Errorf("unable to get script working dir: %v", err)
}
default:
script.dir = path.Dir(basedir.Name())
}

log.Debug("writeScriptContent> script.dir is %s", script.dir)

deferFunc := func() {
if err := fs.Remove(tmpFileName); err != nil {
log.Error(ctx, "unable to remove %s: %v", tmpFileName, err)
filename := filepath.Join(path.Dir(basedir.Name()), tmpFileName)
log.Debug("writeScriptContent> removing file %s", filename)
if err := fs.Remove(filename); err != nil {
log.Error(ctx, "unable to remove %s: %v", filename, err)
}
}

Expand All @@ -164,17 +177,11 @@ func RunScriptAction(ctx context.Context, wk workerruntime.Runtime, a sdk.Action

go func() {
res := sdk.Result{Status: sdk.StatusSuccess}
script, err := prepareScriptContent(a.Parameters)
script, err := prepareScriptContent(a.Parameters, wk.BaseDir(), workdir)
if err != nil {
chanErr <- err
}

if x, ok := wk.BaseDir().(*afero.BasePathFs); ok {
script.dir, _ = x.RealPath(workdir.Name())
} else {
script.dir = workdir.Name()
}

deferFunc, err := writeScriptContent(ctx, script, wk.BaseDir(), workdir)
if deferFunc != nil {
defer deferFunc()
Expand Down
31 changes: 29 additions & 2 deletions engine/worker/internal/action/builtin_script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/ovh/cds/sdk/log"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func init() {
Expand Down Expand Up @@ -71,7 +72,8 @@ echo "lol"`,

for _, tst := range tests {
t.Run(tst.name, func(t *testing.T) {
script, err := prepareScriptContent(tst.parameters)
wk, _ := setupTest(t)
script, err := prepareScriptContent(tst.parameters, wk.BaseDir(), wk.workingDirectory)
if tst.shouldHaveError {
assert.Error(t, err)
} else {
Expand All @@ -82,7 +84,6 @@ echo "lol"`,
}
})
}

}

func TestRunScriptAction(t *testing.T) {
Expand All @@ -105,3 +106,29 @@ func TestRunScriptAction(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, sdk.StatusSuccess, res.Status)
}

func Test_writeScriptContent_windows(t *testing.T) {
sdk.GOOS = "windows"
defer func() {
sdk.GOOS = ""
}()

wk, ctx := setupTest(t)

script, err := prepareScriptContent([]sdk.Parameter{
{
Name: "script",
Value: "sleep 1\necho this is a test from %HOME%\nsleep 1",
},
}, wk.BaseDir(), wk.workingDirectory)
require.NoError(t, err)
require.NotNil(t, script)

deferFunc, err := writeScriptContent(ctx, script, wk.BaseDir(), wk.workingDirectory)
if deferFunc != nil {
defer deferFunc()
}
require.NoError(t, err)

t.Logf("script: %+v", script)
}

0 comments on commit 8ac8fae

Please sign in to comment.