engine: nspawn: Add an nspawn example with an improved exec

This adds the cwd fields to exec, better error messages to svc (which is
nested in nspawn) and a fancier nspawn example!
This commit is contained in:
James Shubin
2019-02-01 09:44:55 -05:00
parent 81faec508c
commit 4a3e2c3611
3 changed files with 52 additions and 4 deletions

View File

@@ -47,11 +47,14 @@ type ExecRes struct {
init *engine.Init init *engine.Init
Cmd string `yaml:"cmd"` // the command to run Cmd string `yaml:"cmd"` // the command to run
Cwd string `yaml:"cwd"` // the dir to run the command in (empty means use `pwd` of command)
Shell string `yaml:"shell"` // the (optional) shell to use to run the cmd Shell string `yaml:"shell"` // the (optional) shell to use to run the cmd
Timeout int `yaml:"timeout"` // the cmd timeout in seconds Timeout int `yaml:"timeout"` // the cmd timeout in seconds
WatchCmd string `yaml:"watchcmd"` // the watch command to run WatchCmd string `yaml:"watchcmd"` // the watch command to run
WatchCwd string `yaml:"watchcwd"` // the dir to run the watch command in (empty means use `pwd` of command)
WatchShell string `yaml:"watchshell"` // the (optional) shell to use to run the watch cmd WatchShell string `yaml:"watchshell"` // the (optional) shell to use to run the watch cmd
IfCmd string `yaml:"ifcmd"` // the if command to run IfCmd string `yaml:"ifcmd"` // the if command to run
IfCwd string `yaml:"ifcwd"` // the dir to run the if command in (empty means use `pwd` of command)
IfShell string `yaml:"ifshell"` // the (optional) shell to use to run the if cmd IfShell string `yaml:"ifshell"` // the (optional) shell to use to run the if cmd
User string `yaml:"user"` // the (optional) user to use to execute the command User string `yaml:"user"` // the (optional) user to use to execute the command
Group string `yaml:"group"` // the (optional) group to use to execute the command Group string `yaml:"group"` // the (optional) group to use to execute the command
@@ -122,7 +125,7 @@ func (obj *ExecRes) Watch() error {
cmdArgs = []string{"-c", obj.WatchCmd} cmdArgs = []string{"-c", obj.WatchCmd}
} }
cmd := exec.Command(cmdName, cmdArgs...) cmd := exec.Command(cmdName, cmdArgs...)
//cmd.Dir = "" // look for program in pwd ? cmd.Dir = obj.WatchCwd // run program in pwd if ""
// ignore signals sent to parent process (we're in our own group) // ignore signals sent to parent process (we're in our own group)
cmd.SysProcAttr = &syscall.SysProcAttr{ cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, Setpgid: true,
@@ -208,7 +211,6 @@ func (obj *ExecRes) CheckApply(apply bool) (bool, error) {
// have a chance to execute, and all without the check of obj.Refresh()! // have a chance to execute, and all without the check of obj.Refresh()!
if obj.IfCmd != "" { // if there is no onlyif check, we should just run if obj.IfCmd != "" { // if there is no onlyif check, we should just run
var cmdName string var cmdName string
var cmdArgs []string var cmdArgs []string
if obj.IfShell == "" { if obj.IfShell == "" {
@@ -224,6 +226,7 @@ func (obj *ExecRes) CheckApply(apply bool) (bool, error) {
cmdArgs = []string{"-c", obj.IfCmd} cmdArgs = []string{"-c", obj.IfCmd}
} }
cmd := exec.Command(cmdName, cmdArgs...) cmd := exec.Command(cmdName, cmdArgs...)
cmd.Dir = obj.IfCwd // run program in pwd if ""
// ignore signals sent to parent process (we're in our own group) // ignore signals sent to parent process (we're in our own group)
cmd.SysProcAttr = &syscall.SysProcAttr{ cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, Setpgid: true,
@@ -266,7 +269,7 @@ func (obj *ExecRes) CheckApply(apply bool) (bool, error) {
cmdArgs = []string{"-c", obj.Cmd} cmdArgs = []string{"-c", obj.Cmd}
} }
cmd := exec.Command(cmdName, cmdArgs...) cmd := exec.Command(cmdName, cmdArgs...)
//cmd.Dir = "" // look for program in pwd ? cmd.Dir = obj.Cwd // run program in pwd if ""
// ignore signals sent to parent process (we're in our own group) // ignore signals sent to parent process (we're in our own group)
cmd.SysProcAttr = &syscall.SysProcAttr{ cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, Setpgid: true,
@@ -373,6 +376,9 @@ func (obj *ExecRes) Compare(r engine.Res) bool {
if obj.Cmd != res.Cmd { if obj.Cmd != res.Cmd {
return false return false
} }
if obj.Cwd != res.Cwd {
return false
}
if obj.Shell != res.Shell { if obj.Shell != res.Shell {
return false return false
} }
@@ -382,12 +388,18 @@ func (obj *ExecRes) Compare(r engine.Res) bool {
if obj.WatchCmd != res.WatchCmd { if obj.WatchCmd != res.WatchCmd {
return false return false
} }
if obj.WatchCwd != res.WatchCwd {
return false
}
if obj.WatchShell != res.WatchShell { if obj.WatchShell != res.WatchShell {
return false return false
} }
if obj.IfCmd != res.IfCmd { if obj.IfCmd != res.IfCmd {
return false return false
} }
if obj.IfCwd != res.IfCwd {
return false
}
if obj.IfShell != res.IfShell { if obj.IfShell != res.IfShell {
return false return false
} }

View File

@@ -349,7 +349,12 @@ func (obj *SvcRes) CheckApply(apply bool) (checkOK bool, err error) {
if &status == nil { if &status == nil {
return false, fmt.Errorf("systemd service action result is nil") return false, fmt.Errorf("systemd service action result is nil")
} }
if status != "done" { switch status {
case "done":
// pass
case "failed":
return false, fmt.Errorf("svc failed (selinux?)")
default:
return false, fmt.Errorf("unknown systemd return string: %v", status) return false, fmt.Errorf("unknown systemd return string: %v", status)
} }

31
examples/lang/nspawn0.mcl Normal file
View File

@@ -0,0 +1,31 @@
# setenforce Permissive
import "fmt"
$codename = "stretch"
$baserepo = "https://deb.debian.org/debian/"
$rootpath = "/var/lib/machines/"
pkg "debootstrap" {
state => "newest",
}
$dir = $codename + "-" + "nspawn" # dir name
$cmd = fmt.printf("debootstrap --include=systemd-container %s %s %s", $codename, $dir, $baserepo)
exec "debootstrap-" + $codename {
cwd => $rootpath,
shell => "/bin/bash",
cmd => $cmd,
ifshell => "/bin/bash",
ifcmd => fmt.printf("test ! -d %s", $rootpath),
Depend => Pkg["debootstrap"],
}
nspawn $dir {
state => "running",
Depend => Exec["debootstrap-" + $codename],
}