blob: 8a93d914be64f2af2bdea27c51f8eece1715db61 [file] [log] [blame]
// +build linux darwin
package impl
import (
"fmt"
"log"
"os"
"path/filepath"
"syscall"
)
// Chown is only availabe on UNIX platforms so this file has a build
// restriction.
func (hw *WorkParameters) Chown() error {
chown := func(path string, _ os.FileInfo, inerr error) error {
if inerr != nil {
return inerr
}
if hw.dryrun {
log.Printf("[dryrun] os.Chown(%s, %d, %d)", path, hw.uid, hw.gid)
return nil
}
return os.Chown(path, hw.uid, hw.gid)
}
for _, p := range []string{hw.workspace, hw.logDir} {
// TODO(rjkroege): Ensure that the device manager can read log entries.
if err := filepath.Walk(p, chown); err != nil {
return fmt.Errorf("os.Chown(%s, %d, %d) failed: %v", p, hw.uid, hw.gid, err)
}
}
return nil
}
func (hw *WorkParameters) Exec() error {
attr := new(syscall.ProcAttr)
if dir, err := os.Getwd(); err != nil {
log.Printf("error Getwd(): %v\n", err)
return fmt.Errorf("os.Getwd failed: %v", err)
attr.Dir = dir
}
attr.Env = hw.envv
if hw.dryrun {
log.Printf("[dryrun] syscall.Setgid(%d)", hw.gid)
log.Printf("[dryrun] syscall.Setuid(%d)", hw.uid)
} else {
attr.Sys = new(syscall.SysProcAttr)
attr.Sys.Credential = new(syscall.Credential)
attr.Sys.Credential.Gid = uint32(hw.gid)
attr.Sys.Credential.Uid = uint32(hw.uid)
}
_, _, err := syscall.StartProcess(hw.argv0, hw.argv, attr)
if err != nil {
if !hw.dryrun {
log.Printf("StartProcess failed: attr: %#v, attr.Sys: %#v, attr.Sys.Cred: %#v error: %v\n", attr, attr.Sys, attr.Sys.Credential, err)
} else {
log.Printf("StartProcess failed: %v", err)
}
return fmt.Errorf("syscall.StartProcess(%s) failed: %v", hw.argv0, err)
}
// TODO(rjkroege): Return the pid to the node manager.
os.Exit(0)
return nil // Not reached.
}
func (hw *WorkParameters) Remove() error {
for _, p := range hw.argv {
if err := os.RemoveAll(p); err != nil {
return fmt.Errorf("os.RemoveAll(%s) failed: %v", p, err)
}
}
return nil
}