diff --git a/cmd/stop.go b/cmd/stop.go new file mode 100644 index 0000000..642778a --- /dev/null +++ b/cmd/stop.go @@ -0,0 +1,173 @@ +package cmd + +import ( + "fmt" +// "log" +// "strings" + "os/exec" +) + +// TODO : Use SYS_RCTL_GET_RACCT syscall +func removeRctlRules(jail string, rules []string) error { + var cmd []string + + if len(rules) == 0 { + rules[0] = "" + } + + for _, r := range rules { + if gUseSudo { + cmd = append(cmd, "sudo") + } + cmd = append(cmd, "/usr/bin/rctl") + cmd = append(cmd, "-r") + cmd = append(cmd, fmt.Sprintf("jail:%s:%s", jail, r)) + + // TODO : Log in another channel than stdout (will scramble diusplay) + //log.Println(fmt.Sprintf("Removing all rules for jail %s: %s", jail, cmd)) + + //out, err := exec.Command(cmd[0], cmd[1:]...).Output() + _, err := exec.Command(cmd[0], cmd[1:]...).Output() + return err + } + + return nil +} + +/* Moved into cmd/utils.go +func executeCommand(cmdline string) (string, error) { + var cmd []string + var out []byte + var err error + + if gUseSudo { + cmd = append(cmd, "sudo") + } + cs := strings.Split(cmdline, " ") + + cmd = append(cmd, cs...) + + if len (cmd) > 1 { + out, err = exec.Command(cmd[0], cmd[1:]...).Output() + } else { + out, err = exec.Command(cmd[0]).Output() + } + + return string(out), err +} + + +func executeCommandInJail(jail *Jail, cmdline string) (string, error) { + var cmd []string + + if gUseSudo { + cmd = append(cmd, "sudo") + } + + cmd = append(cmd, "setfib") + if len(jail.Config.Exec_fib) > 0 { + cmd = append(cmd, jail.Config.Exec_fib) + } else { + cmd = append(cmd, "0") + } + + cmd = append(cmd, "jexec", jail.InternalName) + + cs := strings.Split(cmdline, " ") + cmd = append(cmd, cs...) + + out, err := exec.Command(cmd[0], cmd[1:]...).Output() + + return string(out), err +} +*/ + +// TODO +func umountJailedZFS(jail *Jail) error { +/* + for _, zd := range jail.Config.Jail_zfs_dataset { + + } +*/ + return nil +} + + +/* + Stop jail: + Remove rctl rules + Execute prestop if set (jailhost perimeter) + Execute stop if set (inside jail) + Umount ZFS dataset + Unmount mountpoint + Delete devfs ruleset + + Use setfib for each command + + Shouldnt rctl rules be removed last, when jail is stopped? +*/ +func stopJail(args []string) { + // Current jail were stopping + var cj *Jail + + for _, j := range args { + fmt.Printf("> Stopping jail %s\n", j) + + for _, rj := range gJails { + if rj.Name == j { + cj = &rj + break + } + } + if cj == nil { + fmt.Printf("Jail not found: %s\n", j) + continue + } + if cj.Running == false { + fmt.Printf("Jail %s is not running!\n", cj.Name) + continue + } + + fmt.Printf(" > Remove RCTL rules: ") + err := removeRctlRules(cj.InternalName, []string{""}) + if err != nil { + fmt.Printf("ERROR: %s\n", err.Error()) + } else { + fmt.Printf("OK\n") + } + + if len (cj.Config.Exec_prestop) > 0 { + fmt.Printf(" > Execute prestop: ") + out, err := executeCommand(cj.Config.Exec_prestop) + if err != nil { + fmt.Printf("ERROR: %s\n", err.Error()) + } else { + fmt.Printf("OK\n") + fmt.Printf("%s\n", out) + } + } + + if len (cj.Config.Exec_stop) > 0 { + fmt.Printf(" > Execute stop: ") + out, err := executeCommandInJail(cj, cj.Config.Exec_stop) + if err != nil { + fmt.Printf("ERROR: %s\n", err.Error()) + } else { + fmt.Printf("OK\n") + fmt.Printf("%s\n", out) + } + } + + if cj.Config.Jail_zfs > 0 { + fmt.Printf(" > Umount jailed ZFS: ") + err := umountJailedZFS(cj) + if err != nil { + fmt.Printf("ERROR: %s\n", err.Error()) + } else { + fmt.Printf("OK\n") + } + } + + } +} + diff --git a/cmd/utils.go b/cmd/utils.go new file mode 100644 index 0000000..8f86f36 --- /dev/null +++ b/cmd/utils.go @@ -0,0 +1,53 @@ +package cmd + +import ( + "os/exec" + "strings" +) + +func executeCommand(cmdline string) (string, error) { + var cmd []string + var out []byte + var err error + + if gUseSudo { + cmd = append(cmd, "sudo") + } + cs := strings.Split(cmdline, " ") + + cmd = append(cmd, cs...) + + if len (cmd) > 1 { + out, err = exec.Command(cmd[0], cmd[1:]...).Output() + } else { + out, err = exec.Command(cmd[0]).Output() + } + + return string(out), err +} + + +func executeCommandInJail(jail *Jail, cmdline string) (string, error) { + var cmd []string + + if gUseSudo { + cmd = append(cmd, "sudo") + } + + cmd = append(cmd, "setfib") + if len(jail.Config.Exec_fib) > 0 { + cmd = append(cmd, jail.Config.Exec_fib) + } else { + cmd = append(cmd, "0") + } + + cmd = append(cmd, "jexec", jail.InternalName) + + cs := strings.Split(cmdline, " ") + cmd = append(cmd, cs...) + + out, err := exec.Command(cmd[0], cmd[1:]...).Output() + + return string(out), err +} +