2016-07-29 22:35:10 +00:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2016-08-08 18:58:41 +00:00
|
|
|
"fmt"
|
2016-09-19 07:21:14 +00:00
|
|
|
"io"
|
2016-07-29 22:35:10 +00:00
|
|
|
"os/exec"
|
2016-08-08 18:58:41 +00:00
|
|
|
"strings"
|
2016-08-01 23:48:12 +00:00
|
|
|
"syscall"
|
2017-03-02 00:50:09 +00:00
|
|
|
|
|
|
|
systemdDbus "github.com/coreos/go-systemd/dbus"
|
|
|
|
"github.com/godbus/dbus"
|
2016-07-29 22:35:10 +00:00
|
|
|
)
|
|
|
|
|
2016-09-19 07:21:14 +00:00
|
|
|
// ExecCmd executes a command with args and returns its output as a string along
|
|
|
|
// with an error, if any
|
2016-07-29 22:35:10 +00:00
|
|
|
func ExecCmd(name string, args ...string) (string, error) {
|
|
|
|
cmd := exec.Command(name, args...)
|
2016-08-08 18:58:41 +00:00
|
|
|
var stdout bytes.Buffer
|
|
|
|
var stderr bytes.Buffer
|
|
|
|
cmd.Stdout = &stdout
|
|
|
|
cmd.Stderr = &stderr
|
2016-07-29 22:35:10 +00:00
|
|
|
|
|
|
|
err := cmd.Run()
|
|
|
|
if err != nil {
|
2016-08-08 18:58:41 +00:00
|
|
|
return "", fmt.Errorf("`%v %v` failed: %v (%v)", name, strings.Join(args, " "), stderr.String(), err)
|
2016-07-29 22:35:10 +00:00
|
|
|
}
|
|
|
|
|
2016-08-08 18:58:41 +00:00
|
|
|
return stdout.String(), nil
|
2016-07-29 22:35:10 +00:00
|
|
|
}
|
2016-08-01 23:48:12 +00:00
|
|
|
|
2016-08-01 17:39:42 +00:00
|
|
|
// ExecCmdWithStdStreams execute a command with the specified standard streams.
|
2016-09-19 07:21:14 +00:00
|
|
|
func ExecCmdWithStdStreams(stdin io.Reader, stdout, stderr io.Writer, name string, args ...string) error {
|
2016-08-01 17:39:42 +00:00
|
|
|
cmd := exec.Command(name, args...)
|
|
|
|
cmd.Stdin = stdin
|
|
|
|
cmd.Stdout = stdout
|
|
|
|
cmd.Stderr = stderr
|
|
|
|
|
|
|
|
err := cmd.Run()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("`%v %v` failed: %v", name, strings.Join(args, " "), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:48:12 +00:00
|
|
|
// Prctl is a way to make the prctl linux syscall
|
|
|
|
func Prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
|
|
|
|
_, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
|
|
|
|
if e1 != 0 {
|
|
|
|
err = e1
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2016-08-01 17:39:42 +00:00
|
|
|
|
2016-10-18 14:48:33 +00:00
|
|
|
// StatusToExitCode converts wait status code to an exit code
|
|
|
|
func StatusToExitCode(status int) int {
|
|
|
|
return ((status) & 0xff00) >> 8
|
2016-08-01 17:39:42 +00:00
|
|
|
}
|
2017-03-02 00:50:09 +00:00
|
|
|
|
|
|
|
// RunUnderSystemdScope adds the specified pid to a systemd scope
|
|
|
|
func RunUnderSystemdScope(pid int, slice string, unitName string) error {
|
|
|
|
var properties []systemdDbus.Property
|
|
|
|
conn, err := systemdDbus.New()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
properties = append(properties, systemdDbus.PropSlice(slice))
|
|
|
|
properties = append(properties, newProp("PIDs", []uint32{uint32(pid)}))
|
|
|
|
properties = append(properties, newProp("Delegate", true))
|
|
|
|
properties = append(properties, newProp("DefaultDependencies", false))
|
2017-03-15 20:30:39 +00:00
|
|
|
_, err = conn.StartTransientUnit(unitName, "replace", properties, nil)
|
|
|
|
return err
|
2017-03-02 00:50:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func newProp(name string, units interface{}) systemdDbus.Property {
|
|
|
|
return systemdDbus.Property{
|
|
|
|
Name: name,
|
|
|
|
Value: dbus.MakeVariant(units),
|
|
|
|
}
|
|
|
|
}
|