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") } } } }