WIP on start, go fmt on *

This commit is contained in:
yo 2022-04-24 16:49:54 +02:00
parent dbd9153513
commit 43f26d099f
12 changed files with 1498 additions and 1169 deletions

View File

@ -2,8 +2,8 @@ package cmd
import (
"fmt"
"net"
"golang.org/x/net/route"
"net"
)
var defaultRoute4 = [4]byte{0, 0, 0, 0}
@ -16,8 +16,8 @@ func Inet4AddrToString(ip4 route.Inet4Addr) string {
func Inet6AddrToString(ip6 route.Inet6Addr) string {
return fmt.Sprintf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
ip6.IP[0], ip6.IP[1], ip6.IP[2], ip6.IP[3], ip6.IP[4], ip6.IP[5], ip6.IP[6], ip6.IP[7],
ip6.IP[8], ip6.IP[9], ip6.IP[10], ip6.IP[11], ip6.IP[12], ip6.IP[13], ip6.IP[14], ip6.IP[15])
ip6.IP[0], ip6.IP[1], ip6.IP[2], ip6.IP[3], ip6.IP[4], ip6.IP[5], ip6.IP[6], ip6.IP[7],
ip6.IP[8], ip6.IP[9], ip6.IP[10], ip6.IP[11], ip6.IP[12], ip6.IP[13], ip6.IP[14], ip6.IP[15])
}
/*****************************************************************************
@ -83,7 +83,6 @@ func (jh *JailHost) InitNetworkProperties() {
}
}
func (jh *JailHost) GetDefaultInterface() string {
if len(jh.default_interface) == 0 {
jh.InitNetworkProperties()
@ -91,7 +90,6 @@ func (jh *JailHost) GetDefaultInterface() string {
return jh.default_interface
}
func (jh *JailHost) GetDefaultGateway4() string {
if len(jh.default_gateway4) == 0 {
jh.InitNetworkProperties()
@ -99,11 +97,9 @@ func (jh *JailHost) GetDefaultGateway4() string {
return jh.default_gateway4
}
func(jh *JailHost) GetDefaultGateway6() string {
func (jh *JailHost) GetDefaultGateway6() string {
if len(jh.default_gateway6) == 0 {
jh.InitNetworkProperties()
}
return jh.default_gateway6
}

View File

@ -1,15 +1,15 @@
package cmd
import (
"os"
"encoding/json"
"fmt"
"github.com/spf13/viper"
"gocage/jail"
"io/ioutil"
"log"
"os"
"reflect"
"strings"
"io/ioutil"
"gocage/jail"
"encoding/json"
"github.com/spf13/viper"
)
/********************************************************************************
@ -82,7 +82,6 @@ func ListJails(args []string, display bool) {
jails = gJails
}
/***************************************************************
/ Filter jails by names given on command line
/**************************************************************/
@ -112,7 +111,7 @@ func ListJails(args []string, display bool) {
var fctName string
if strings.HasPrefix(c, "-") {
fctName = fmt.Sprintf("%sDec", strings.Replace(c, "-", "", 1))
} else { // Par defaut (pas de prefix +/-) on considere un tri incremental
} else { // Par defaut (pas de prefix +/-) on considere un tri incremental
fctName = fmt.Sprintf("%sInc", strings.Replace(c, "+", "", 1))
}
@ -123,20 +122,23 @@ func ListJails(args []string, display bool) {
fmt.Printf("ERROR getting JailSort struct field %s. Please check the field name: %s\n", fctName, fieldName)
return
}
switch i+1 {
case 1: fct1 = fct
case 2: fct2 = fct
case 3: fct3 = fct
switch i + 1 {
case 1:
fct1 = fct
case 2:
fct2 = fct
case 3:
fct3 = fct
}
}
switch len(strings.Split(gSortFields, ",")) {
case 1:
JailsOrderedBy(fct1.Interface().(jailLessFunc)).Sort(jails)
case 2:
JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc)).Sort(jails)
case 3:
JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc), fct3.Interface().(jailLessFunc)).Sort(jails)
case 1:
JailsOrderedBy(fct1.Interface().(jailLessFunc)).Sort(jails)
case 2:
JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc)).Sort(jails)
case 3:
JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc), fct3.Interface().(jailLessFunc)).Sort(jails)
}
}
@ -148,47 +150,59 @@ func ListJails(args []string, display bool) {
}
}
func listJailsFromDatastore(datastore string) {
fileInfo, err := os.Stat(datastore)
if err != nil { log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", datastore)) }
if fileInfo.IsDir() == false { log.Fatalln(fmt.Sprintf("%s is not a directory", datastore)) }
if err != nil {
log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", datastore))
}
if fileInfo.IsDir() == false {
log.Fatalln(fmt.Sprintf("%s is not a directory", datastore))
}
// A datastore have to contain a "jails" directory
jailsDir := fmt.Sprintf("%s/jails", datastore)
fileInfo, err = os.Stat(jailsDir)
if err != nil { log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", jailsDir)) }
if fileInfo.IsDir() == false { log.Fatalln(fmt.Sprintf("%s is not a directory", jailsDir)) }
if err != nil {
log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", jailsDir))
}
if fileInfo.IsDir() == false {
log.Fatalln(fmt.Sprintf("%s is not a directory", jailsDir))
}
listJailsFromDirectory(jailsDir)
}
func listJailsFromDirectory(dir string) ([]Jail) {
func listJailsFromDirectory(dir string) []Jail {
files, err := ioutil.ReadDir(dir)
if err != nil { log.Fatalln(fmt.Sprintf("Unable to browse %s, check path and/or rights", dir)) }
if err != nil {
log.Fatalln(fmt.Sprintf("Unable to browse %s, check path and/or rights", dir))
}
for _, fi := range files {
if fi.IsDir() == true {
// 1. Get conf from config.json
// 1. Get conf from config.json
jailConfPath := fmt.Sprintf("%s/%s/%s", dir, fi.Name(), "config.json")
jailConf, err := getJailConfig(jailConfPath)
if err != nil { log.Println("ERROR reading jail config for %s", jailConfPath) }
// 2. Build jail object from config
jailRootPath := fmt.Sprintf("%s/%s/%s", dir, fi.Name(), "root")
j := Jail{
Name: jailConf.Host_hostname,
Config: jailConf,
ConfigPath: jailConfPath,
RootPath: jailRootPath,
Running: false,
if err != nil {
log.Println("ERROR reading jail config for %s", jailConfPath)
}
// 3. Add current running informations
// 2. Build jail object from config
jailRootPath := fmt.Sprintf("%s/%s/%s", dir, fi.Name(), "root")
j := Jail{
Name: jailConf.Host_hostname,
Config: jailConf,
ConfigPath: jailConfPath,
RootPath: jailRootPath,
Running: false,
}
// 3. Add current running informations
rjails, err := jail.GetJails()
if err != nil { log.Fatalln("Unable to list running jails") }
if err != nil {
log.Fatalln("Unable to list running jails")
}
for _, rj := range rjails {
if rj.Path == j.RootPath {
j.JID = rj.Jid
@ -198,7 +212,7 @@ func listJailsFromDirectory(dir string) ([]Jail) {
}
}
/* This op take some 600ms for ~40 jails :^( */
/* This op take some 600ms for ~40 jails :^( */
out, err := executeCommand(fmt.Sprintf("zfs list -H -o name %s", j.RootPath))
if err != nil {
fmt.Printf("ERROR getting dataset from %s: %s\n", j.RootPath, err.Error())
@ -213,10 +227,11 @@ func listJailsFromDirectory(dir string) ([]Jail) {
return gJails
}
func getJailConfig(jailConfigPath string) (JailConfig, error) {
content, err := ioutil.ReadFile(jailConfigPath)
if err != nil { log.Fatalln(fmt.Sprintf("Unable to read %s, check path and/or rights", jailConfigPath)) }
if err != nil {
log.Fatalln(fmt.Sprintf("Unable to read %s, check path and/or rights", jailConfigPath))
}
// Mandatory constructor to init default values
jc, err := NewJailConfig()
@ -224,7 +239,9 @@ func getJailConfig(jailConfigPath string) (JailConfig, error) {
return jc, err
}
err = json.Unmarshal([]byte(content), &jc)
if err != nil { log.Fatalln(fmt.Sprintf("Error occured during unmarshaling %s: %s", jailConfigPath, err.Error())) }
if err != nil {
log.Fatalln(fmt.Sprintf("Error occured during unmarshaling %s: %s", jailConfigPath, err.Error()))
}
return jc, err
}

View File

@ -1,11 +1,11 @@
package cmd
import (
"fmt"
"errors"
"fmt"
"reflect"
"strings"
"strconv"
"strings"
)
func GetJailProperties(args []string) {
@ -55,14 +55,14 @@ func getJailProperty(jail *Jail, propName string) (string, error) {
}
switch val.Kind() {
case reflect.String:
return val.String(), nil
case reflect.Int:
return strconv.FormatInt(val.Int(), 10), nil
case reflect.Bool:
return strconv.FormatBool(val.Bool()), nil
default:
return "", errors.New(fmt.Sprintf("Error: Unknown type for property %s: %s\n", propName, val.Kind()))
case reflect.String:
return val.String(), nil
case reflect.Int:
return strconv.FormatInt(val.Int(), 10), nil
case reflect.Bool:
return strconv.FormatBool(val.Bool()), nil
default:
return "", errors.New(fmt.Sprintf("Error: Unknown type for property %s: %s\n", propName, val.Kind()))
}
}
}
@ -72,8 +72,8 @@ func getJailProperty(jail *Jail, propName string) (string, error) {
func SetJailProperties(args []string) {
type properties struct {
name string
value string
name string
value string
}
var jail Jail
@ -120,5 +120,3 @@ func SetJailProperties(args []string) {
}
}
}

View File

@ -1,41 +1,43 @@
package cmd
import (
"os"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"io/ioutil"
"encoding/json"
"github.com/spf13/cobra"
"github.com/spf13/viper"
// TODO : Use log
//log "github.com/sirupsen/logrus"
)
const (
gVersion = "0.25"
gVersion = "0.26a"
)
var (
gJails []Jail
gJails []Jail
gUseSudo bool
gUseSudo bool
gConfigFile string
gDisplayColumns string
gFilterJails string
gSortFields string
gNoLineSep bool
gConfigFile string
gDisplayColumns string
gFilterJails string
gSortFields string
gNoLineSep bool
gHostVersion float64
gHostVersion float64
gTimeZone string
gSnapshotName string
gTimeZone string
gSnapshotName string
rootCmd = & cobra.Command {
Use: "gocage",
Short: "GoCage is a FreeBSD Jail management tool",
Long: `GoCage is a jail management tool. It support VNET, host-only, NAT networks. Provides snapshots and cloning.
rootCmd = &cobra.Command{
Use: "gocage",
Short: "GoCage is a FreeBSD Jail management tool",
Long: `GoCage is a jail management tool. It support VNET, host-only, NAT networks. Provides snapshots and cloning.
It support iocage jails and can coexist with iocage.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("GoCage v.%s on FreeBSD %.1f\n", gVersion, gHostVersion)
@ -43,19 +45,19 @@ It support iocage jails and can coexist with iocage.`,
},
}
versionCmd = &cobra.Command {
versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of GoCage",
Long: `Let this show you how much fail I had to get this *cough* perfect`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("GoCage v.%s on FreeBSD %.1f\n", gVersion, gHostVersion)
},
},
}
listCmd = &cobra.Command {
listCmd = &cobra.Command{
Use: "list",
Short: "Print jails",
Long: `Display jails, their IP and OS.
Long: `Display jails, their IP and OS.
Jail list can be restricted by adding name on command line
ex: gocage list srv-db srv-web`,
Run: func(cmd *cobra.Command, args []string) {
@ -63,7 +65,7 @@ ex: gocage list srv-db srv-web`,
},
}
listPropsCmd = &cobra.Command {
listPropsCmd = &cobra.Command{
Use: "properties",
Short: "Print jails properties",
Long: "Display jails properties. You can use properties to filter, get or set them.",
@ -72,7 +74,7 @@ ex: gocage list srv-db srv-web`,
},
}
stopCmd = &cobra.Command {
stopCmd = &cobra.Command{
Use: "stop",
Short: "stop jail",
Long: "shutdown jail",
@ -83,7 +85,7 @@ ex: gocage list srv-db srv-web`,
},
}
startCmd = &cobra.Command {
startCmd = &cobra.Command{
Use: "start",
Short: "start jail",
Run: func(cmd *cobra.Command, args []string) {
@ -94,20 +96,20 @@ ex: gocage list srv-db srv-web`,
},
}
/* shellCmd = &cobra.Command {
Use: "console",
Short: "Execute shell on jail",
Run: func(cmd *cobra.Command, args []string) {
// Load inventory
ListJails(args, false)
ShellJail(args)
},
}
*/
setCmd = &cobra.Command {
/* shellCmd = &cobra.Command {
Use: "console",
Short: "Execute shell on jail",
Run: func(cmd *cobra.Command, args []string) {
// Load inventory
ListJails(args, false)
ShellJail(args)
},
}
*/
setCmd = &cobra.Command{
Use: "set",
Short: "Set a jail property",
Long: `Set jail property value. Specify property=value, end command with jail name.
Long: `Set jail property value. Specify property=value, end command with jail name.
Multiples properties can be specified, separated with space (Ex: gocage set allow_mlock=1 boot=1 myjail)`,
Run: func(cmd *cobra.Command, args []string) {
// Load inventory
@ -117,10 +119,10 @@ Multiples properties can be specified, separated with space (Ex: gocage set allo
},
}
getCmd = &cobra.Command {
getCmd = &cobra.Command{
Use: "get",
Short: "Get a jail property",
Long: `Get jail property value. Specify property, end command with jail name.
Long: `Get jail property value. Specify property, end command with jail name.
Multiples properties can be specified, separated with space (Ex: gocage get allow_mlock boot myjail)
For all properties specify "all" (Ex: gocage get all myjail)`,
Run: func(cmd *cobra.Command, args []string) {
@ -130,7 +132,7 @@ For all properties specify "all" (Ex: gocage get all myjail)`,
},
}
snapshotCmd = &cobra.Command {
snapshotCmd = &cobra.Command{
Use: "snapshot",
Short: "snapshot jail",
Long: "Commands to manage jail snapshots. If no arguments given, ",
@ -139,10 +141,10 @@ For all properties specify "all" (Ex: gocage get all myjail)`,
},
}
snapshotListCmd = &cobra.Command {
snapshotListCmd = &cobra.Command{
Use: "list",
Short: "list snapshots",
Long: `List snapshots of a jail by specifying its name.
Long: `List snapshots of a jail by specifying its name.
List all snapshots if no jail name specified.
You can specify multiple jails.`,
Run: func(cmd *cobra.Command, args []string) {
@ -152,11 +154,11 @@ You can specify multiple jails.`,
},
}
snapshotCreateCmd = &cobra.Command {
Use: "create",
snapshotCreateCmd = &cobra.Command{
Use: "create",
Short: "create snapshots",
Long: `Create snapshot of a jail by specifying snapshot name and jail name.`,
// You can specify multiple jails.`,
// You can specify multiple jails.`,
Run: func(cmd *cobra.Command, args []string) {
// Load inventory
ListJails(args, false)
@ -164,11 +166,11 @@ You can specify multiple jails.`,
},
}
snapshotRollbackCmd = &cobra.Command {
Use: "rollback",
snapshotRollbackCmd = &cobra.Command{
Use: "rollback",
Short: "Rollback snapshots",
Long: `Rollback jail to specifyed snapshot.`,
// You can specify multiple jails.`,
// You can specify multiple jails.`,
Run: func(cmd *cobra.Command, args []string) {
// Load inventory
ListJails(args, false)
@ -176,7 +178,7 @@ You can specify multiple jails.`,
},
}
snapshotDeleteCmd = &cobra.Command {
snapshotDeleteCmd = &cobra.Command{
Use: "destroy",
Short: "destroy snapshots",
Long: `Destroy snapshot of a jail by specifying snapshot name and jail name.`,
@ -189,17 +191,16 @@ You can specify multiple jails.`,
}
)
// TODO : Init log level and log output
func init() {
cobra.OnInitialize(initConfig)
cobra.OnInitialize(initConfig)
// Global switches
// Global switches
rootCmd.PersistentFlags().StringVarP(&gConfigFile, "config", "c", "/usr/local/etc/gocage.conf.yml", "GoCage configuration file")
rootCmd.PersistentFlags().BoolVarP(&gUseSudo, "sudo", "u", false, "Use sudo to run commands")
rootCmd.PersistentFlags().StringVarP(&gTimeZone, "timezone", "t", "", "Specify timezone. Will get from /var/db/zoneinfo if not set.")
// Command dependant switches
// Command dependant switches
// These are persistent so we can reuse them in "gocage list snapshot myjail" command (TODO)
listCmd.PersistentFlags().StringVarP(&gDisplayColumns, "outcol", "o", "JID,Name,Config.Release,Config.Ip4_addr,Running", "Show these columns in output")
@ -215,7 +216,7 @@ func init() {
snapshotRollbackCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to rollback to")
snapshotRollbackCmd.MarkFlagRequired("snapname")
// Now declare commands
// Now declare commands
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(listCmd)
listCmd.AddCommand(listPropsCmd)
@ -245,7 +246,7 @@ func initConfig() {
os.Exit(1)
}
// fmt.Printf("We are in initConfig(), with config file %s\n", gConfigFile)
// fmt.Printf("We are in initConfig(), with config file %s\n", gConfigFile)
viper.SetConfigFile(gConfigFile)
@ -254,9 +255,9 @@ func initConfig() {
os.Exit(1)
}
// fmt.Println("Using config file:", viper.ConfigFileUsed())
// fmt.Printf("datastore in config : %s\n", viper.GetStringSlice("datastore"))
// fmt.Printf("datastore.0 in config : %s\n", viper.GetStringSlice("datastore.0"))
// fmt.Println("Using config file:", viper.ConfigFileUsed())
// fmt.Printf("datastore in config : %s\n", viper.GetStringSlice("datastore"))
// fmt.Printf("datastore.0 in config : %s\n", viper.GetStringSlice("datastore.0"))
// Command line flags have priority on config file
if rootCmd.Flags().Lookup("sudo") != nil && false == rootCmd.Flags().Lookup("sudo").Changed {
@ -292,7 +293,6 @@ func initConfig() {
}
}
/********************************************************************************
* Write jails config which been updated to disk.
* If changeauto not set, values which are in "auto" mode on disk
@ -352,5 +352,3 @@ func Execute() {
os.Exit(1)
}
}

View File

@ -1,13 +1,13 @@
package cmd
import (
"os"
"fmt"
"time"
"bufio"
"errors"
"fmt"
"os"
"regexp"
"strings"
"time"
)
/********************************************************************************
@ -36,10 +36,9 @@ func ListJailsSnapshots(args []string) {
}
}
}
displaySnapshotsFields(snapshots, []string{"Jailname","Name","Creation","Referenced","Used"})
displaySnapshotsFields(snapshots, []string{"Jailname", "Name", "Creation", "Referenced", "Used"})
}
/********************************************************************************
* List all snapshots a jail have
*******************************************************************************/
@ -73,12 +72,12 @@ func listJailSnapshots(jail Jail) []Snapshot {
subdir := strings.Replace(strings.Split(ls[0], "@")[0], rootDataset, "", 1)
snapshots = append(snapshots, Snapshot{Dsname: ls[0],
Name: fmt.Sprintf("%s%s", strings.Split(ls[0], "@")[1], subdir),
Jailname: jail.Name,
Name: fmt.Sprintf("%s%s", strings.Split(ls[0], "@")[1], subdir),
Jailname: jail.Name,
Mountpoint: ls[1],
Used: ls[2],
Used: ls[2],
Referenced: ls[3],
Creation: creationts})
Creation: creationts})
}
}
@ -89,7 +88,6 @@ func listJailSnapshots(jail Jail) []Snapshot {
return snapshots
}
/********************************************************************************
* Create snapshot for jail(s)
*******************************************************************************/

View File

@ -1,13 +1,16 @@
package cmd
import (
"os"
"fmt"
"errors"
"regexp"
"strings"
"strconv"
"fmt"
"github.com/c-robinson/iplib"
log "github.com/sirupsen/logrus"
"io/ioutil"
"net"
"os"
"regexp"
"strconv"
"strings"
)
// FIXME : Do not work?!
@ -93,22 +96,22 @@ func mountAllJailFsFromHost(jail *Jail) error {
devfsFound := false
fdescfsFound := false
cmd := "mount -p"
out, err := executeCommand(cmd)
if err != nil {
return errors.New(fmt.Sprintf("Error executing mount: %s", err.Error()))
}
cmd := "mount -p"
out, err := executeCommand(cmd)
if err != nil {
return errors.New(fmt.Sprintf("Error executing mount: %s", err.Error()))
}
var outclean []string
remSpPtrn := regexp.MustCompile(`\s+`)
for _, l := range strings.Split(out, "\n") {
remSpPtrn := regexp.MustCompile(`\s+`)
for _, l := range strings.Split(out, "\n") {
outclean = append(outclean, remSpPtrn.ReplaceAllString(l, " "))
}
// Check if these FS are already mounted
for _, l := range outclean {
f := strings.Split(l, " ")
if len(f) > 2 {
f := strings.Split(l, " ")
if len(f) > 2 {
if strings.EqualFold(f[1], fmt.Sprintf("%s/proc", jail.RootPath)) {
procfsFound = true
@ -128,22 +131,22 @@ func mountAllJailFsFromHost(jail *Jail) error {
// Mount wanted FS
if jail.Config.Mount_procfs > 0 && procfsFound == false {
err := mountProcFs(jail)
if err != nil {
return err
}
if err != nil {
return err
}
}
if jail.Config.Mount_linprocfs > 0 && linProcfsFound == false {
err = mountLinProcFs(jail)
if err != nil {
return err
}
if err != nil {
return err
}
}
if jail.Config.Mount_devfs > 0 && devfsFound == false {
err := mountDevFs(jail)
if err != nil {
return err
return err
}
}
if jail.Config.Mount_fdescfs > 0 && fdescfsFound == false {
@ -153,7 +156,6 @@ func mountAllJailFsFromHost(jail *Jail) error {
}
}
// Ces montages doivent-ils etre effectués une fois le jail démarré?
// FreeBSD <= 9.3 do not support fdescfs
@ -186,10 +188,9 @@ func mountAllJailFsFromHost(jail *Jail) error {
}
}
return nil
return nil
}
// TODO
func prepareJailedZfsDatasets(jail *Jail) error {
if jail.Config.Jail_zfs > 0 {
@ -229,9 +230,9 @@ func prepareJailedZfsDatasets(jail *Jail) error {
}
type NatDesc struct {
Proto string
JailPort string
HostPort string
Proto string
JailPort string
HostPort string
}
// tcp(80:8080),tcp(3300-3310:33060-33070)
@ -262,7 +263,7 @@ func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc,
if (ejrange - sjrange) != (ehrange - shrange) {
return res, errors.New(fmt.Sprintf("Invalid port range in nat_forwards: %s", match[0]))
}
for i := sjrange ; i <= ejrange ; i++ {
for i := sjrange; i <= ejrange; i++ {
nd := NatDesc{Proto: match[1],
JailPort: strconv.Itoa(i),
HostPort: strconv.Itoa(shrange + (i - sjrange)),
@ -271,8 +272,8 @@ func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc,
}
} else {
nd := NatDesc{Proto: match[1],
JailPort: match[2],
HostPort: match[3],
JailPort: match[2],
HostPort: match[3],
}
res = append(res, nd)
}
@ -281,6 +282,216 @@ func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc,
return res, nil
}
func enableRcKeyValue(rcconfpath string, key string, value string) error {
cmd := fmt.Sprintf("/usr/sbin/sysrc -f %s %s=%s", rcconfpath, key, value)
_, err := executeCommand(cmd)
if err != nil {
return err
}
return nil
}
func disableRcKey(rcconfpath string, key string) error {
cmd := fmt.Sprintf("/usr/sbin/sysrc -f %s -x %s", rcconfpath, key)
_, err := executeCommand(cmd)
if err != nil {
return err
}
return nil
}
/*****************************************************************************
* Enable or disables DHCP or accept_rtadv for interfaces declared with this
* option
****************************************************************************/
func configureDhcpOrAcceptRtadv(jail *Jail, ipproto int, enable bool) error {
var nics []string
// Iocage legacy behavior to enable on all interfaces if Config.Dhcp is set...
if ipproto == IPv4 && jail.Config.Dhcp > 0 || enable == false {
nic_list := strings.Split(jail.Config.Interfaces, ",")
for _, n := range nic_list {
nics = append(nics, strings.Split(n, ":")[0])
}
// ...else enable for selected interface in Config.IpX_addr
} else {
if ipproto == IPv4 {
for _, i := range strings.Split(jail.Config.Ip4_addr, ",") {
if strings.EqualFold(strings.ToLower(strings.Split(i, "|")[1]), "dhcp") {
nics = append(nics, i)
}
}
} else {
for _, i := range strings.Split(jail.Config.Ip6_addr, ",") {
if strings.EqualFold(strings.ToLower(strings.Split(i, "|")[1]), "accept_rtadv") {
nics = append(nics, i)
}
}
}
}
for _, n := range nics {
// vnet0 is epair0b inside jail
if strings.Contains(n, "vnet") {
n = fmt.Sprintf("%sb", strings.Replace(n, "vnet", "epair", 1))
}
key := fmt.Sprintf("ifconfig_%s", n)
value := "SYNCDHCP"
if ipproto == IPv6 {
key = fmt.Sprintf("%s_ipv6", key)
value = "inet6 auto_linklocal accept_rtadv autoconf"
}
if enable == true {
err := enableRcKeyValue(jail.ConfigPath, key, value)
if err != nil {
return fmt.Errorf("ERROR setting %s=%s with sysrc for jail %s: %s\n", key, value, jail.Name, err)
}
} else {
err := disableRcKey(jail.ConfigPath, key)
if err != nil {
return fmt.Errorf("ERROR deleting %s with sysrc for jail %s: %s\n", key, value, jail.Name, err)
}
}
}
return nil
}
func checkRtsold(jail *Jail) error {
if strings.Contains(jail.Config.Ip6_addr, "accept_rtadv") == false {
return fmt.Errorf("Must set at least one ip6_addr to accept_rtadv!\n")
}
err := enableRcKeyValue(jail.ConfigPath, "rtsold_enable", "yes")
if err != nil {
return fmt.Errorf("ERROR setting rtsold_enable=YES with sysrc for jail %s: %s\n", jail.Name, err)
}
return nil
}
func checkNat(backend string) error {
cmd := "/sbin/sysctl -q net.inet.ip.forwarding=1"
_, err := executeCommand(cmd)
if err != nil {
return fmt.Errorf("ERROR executing \"/sbin/sysctl -q net.inet.ip.forwarding=1\": %s", err)
}
if strings.EqualFold(backend, "pf") {
// Load module and enable pf
out, err := executeCommand("/sbin/kldload -n pf")
if err != nil {
if false == strings.Contains(out, "module already loaded or in kernel") {
return fmt.Errorf("ERROR executing \"/sbin/kldload pf\": %s", err)
}
}
out, err = executeCommand("/sbin/pfctl -e")
if err != nil {
if false == strings.Contains(out, "pf already enabled") {
return fmt.Errorf("ERROR executing \"/sbin/pfctl -e\": %s", err)
}
}
} else if strings.EqualFold(backend, "ipwf") {
// Check if module loaded
out, err := executeCommand("/sbin/sysctl net.inet.ip.fw.enable=1")
if err != nil {
if false == strings.Contains(out, "unknown oid 'net.inet.ip.fw.enable'") {
return fmt.Errorf("ERROR executing \"/sbin/sysctl net.inet.ip.fw.enable=1\": %s", err)
}
}
_, _ = executeCommand("/bin/kenv net.inet.ip.fw.default_to_accept=1")
_, _ = executeCommand("/sbin/kldload -n ipfw")
_, _ = executeCommand("/sbin/kldload -n ipfw_nat")
_, err = executeCommand("/sbin/sysctl -q net.inet.ip.fw.enable=1")
if err != nil {
return fmt.Errorf("ERROR executing \"/sbin/sysctl -q net.inet.ip.fw.enable=1\": %s", err)
}
}
return nil
}
func getJailsInUseIPv4() ([]string, error) {
var ips []string
re := regexp.MustCompile(ifconfigipv4re)
for _, j := range gJails {
out, err := executeCommandInJail(&j, "/sbin/ifconfig")
if err != nil {
return ips, fmt.Errorf("ERROR executing \"/sbin/ifconfig\" in jail %s: %s", j.Name, err)
}
for _, line := range strings.Split(out, "\n") {
if re.MatchString(line) {
ips = append(ips, re.FindStringSubmatch(line)[1])
}
}
}
return ips, nil
}
func getHostInUseIPv4() ([]string, error) {
var ips []string
re := regexp.MustCompile(ifconfigipv4re)
out, err := executeCommand("/sbin/ifconfig")
if err != nil {
return ips, fmt.Errorf("ERROR executing \"/sbin/ifconfig\": %s", err)
}
for _, line := range strings.Split(out, "\n") {
if re.MatchString(line) {
ips = append(ips, re.FindStringSubmatch(line)[1])
}
}
return ips, nil
}
func genNatIpv4(jail *Jail) ([]string, error) {
var ippair []string
// Get all IP in use, host and jails
inuseip4, err := getHostInUseIPv4()
if err != nil {
return ippair, err
}
ij, err := getJailsInUseIPv4()
if err != nil {
return ippair, err
}
inuseip4 = append(inuseip4, ij...)
// TODO : Voir https://github.com/iocage/iocage/blob/e94863d4c54f02523fb09e62e48be7db9ac92eda/iocage_lib/ioc_common.py#L1026
for i := 0; i < 256; i++ {
for j := 0; j < 256; j += 4 {
n := iplib.NewNet4(net.ParseIP(fmt.Sprintf("172.16.%d.%d", i, j)), 30)
for _, ip := range n.Enumerate(0, 0) {
ippair = append(ippair, ip.String())
}
found := false
for _, ip := range inuseip4 {
for _, ipn := range ippair {
if ip == ipn {
found = true
}
}
}
if found == false {
return ippair, nil
}
}
}
return ippair, nil
}
/*
Start jail:
Check jail fstab?
@ -309,6 +520,7 @@ func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc,
func StartJail(args []string) {
// jail we have to start
var cj *Jail
var err error
for _, j := range args {
fmt.Printf("> Starting jail %s\n", j)
@ -344,8 +556,8 @@ func StartJail(args []string) {
}
var props_missing []string
// DHCP can also be set with "DHCP" value in ip4_addr
if cj.Config.Dhcp > 0 || strings.EqualFold(cj.Config.Ip4_addr, "DHCP") == true {
// DHCP can also be set with "dhcp" value in ip4_addr (Eg: "vnet0|dhcp")
if cj.Config.Dhcp > 0 || strings.Contains(strings.ToLower(cj.Config.Ip4_addr), "dhcp") == true {
if cj.Config.Bpf == 0 {
props_missing = append(props_missing, fmt.Sprintf("%s: dhcp requires bpf", cj.Name))
}
@ -376,7 +588,7 @@ func StartJail(args []string) {
for _, cjn := range cjnd {
if jn == cjn {
fmt.Printf("nat_forwards rule \"%s\" is in conflict with jail %s, won't start\n",
fmt.Sprintf("%s(%s:%s)", cjn.Proto, cjn.JailPort, cjn.HostPort), j.Name)
fmt.Sprintf("%s(%s:%s)", cjn.Proto, cjn.JailPort, cjn.HostPort), j.Name)
return
}
}
@ -403,7 +615,48 @@ func StartJail(args []string) {
// "auto" default Gateway should not be updated to support jailhost route change
}
// Continue here
if strings.EqualFold(cj.Config.Ip6_addr, "accept_rtadv") && cj.Config.Vnet == 0 {
props_missing = append(props_missing, fmt.Sprintf("%s: accept_rtadv requires vnet", cj.Name))
}
if cj.Config.Bpf > 0 && cj.Config.Vnet == 0 {
props_missing = append(props_missing, fmt.Sprintf("%s: bpf requires vnet", cj.Name))
}
if len(props_missing) > 0 {
for _, m := range props_missing {
fmt.Printf("%s\n", m)
}
return
}
if cj.Config.Dhcp > 0 || strings.Contains(strings.ToLower(cj.Config.Ip4_addr), "dhcp") == true {
err = configureDhcpOrAcceptRtadv(cj, IPv4, true)
} else {
err = configureDhcpOrAcceptRtadv(cj, IPv4, false)
}
if err != nil {
fmt.Printf(err.Error())
return
}
if cj.Config.Rtsold > 0 {
err = checkRtsold(cj)
}
if err != nil {
fmt.Printf(err.Error())
return
}
if strings.Contains(strings.ToLower(cj.Config.Ip6_addr), "accept_rtadv") == true {
err = configureDhcpOrAcceptRtadv(cj, IPv6, true)
} else {
err = configureDhcpOrAcceptRtadv(cj, IPv6, false)
}
if err != nil {
fmt.Printf(err.Error())
return
}
fmt.Printf(" > Mount special filesystems:\n")
err := mountAllJailFsFromHost(cj)
@ -423,76 +676,115 @@ func StartJail(args []string) {
}
}
// TODO : Check capabilites relative to FreeBSD Version when executing jail with all parameters
// See l.335 of https://github.com/iocage/iocage/blob/e94863d4c54f02523fb09e62e48be7db9ac92eda/iocage_lib/ioc_start.py
//checkCapabilities(cj)
/*
out, err := executeCommand(fmt.Sprintf("rctl jail:%s", cj.InternalName))
if err == nil && len(out) > 0 {
fmt.Printf(" > Remove RCTL rules:\n")
err := removeRctlRules(cj.InternalName, []string{""})
// Check NAT backend
if cj.Config.Nat > 0 {
log.Debug("Check NAT backend %s\n", cj.Config.Nat_backend)
err = checkNat(cj.Config.Nat_backend)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
fmt.Printf(err.Error())
return
}
if cj.Config.Vnet == 0 {
log.Debug("Generate NAT IPv4 without VNet")
ip4, err := genNatIpv4(cj)
if err != nil {
fmt.Printf("%s\n", err.Error())
return
}
log.Debug("Configuring NAT : Set ip4_addr to %s", ip4[0])
// This IP should not be saved into json
cj.Config.Ip4_addr = fmt.Sprintf("%s|%s", cj.Config.Nat_interface, ip4[0])
} else {
fmt.Printf(" > Remove RCTL rules: OK\n")
log.Debug("Generate NAT IPv4 with VNet")
ip4, err := genNatIpv4(cj)
if err != nil {
fmt.Printf("%s\n", err.Error())
return
}
log.Debug("Configuring NAT : Set ip4_addr to %s, defaultrouter to %s", ip4[1], ip4[0])
// This IP should not be saved into json
cj.Config.Ip4_addr = fmt.Sprintf("vnet0|%s", ip4[1])
cj.Config.Defaultrouter = ip4[0]
}
}
if len (cj.Config.Exec_prestop) > 0 {
fmt.Printf(" > Execute prestop:\n")
_, err := executeCommand(cj.Config.Exec_prestop)
// CONTINUE HERE
// See https://github.com/iocage/iocage/blob/e94863d4c54f02523fb09e62e48be7db9ac92eda/iocage_lib/ioc_start.py:401
/*
out, err := executeCommand(fmt.Sprintf("rctl jail:%s", cj.InternalName))
if err == nil && len(out) > 0 {
fmt.Printf(" > Remove RCTL rules:\n")
err := removeRctlRules(cj.InternalName, []string{""})
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Remove RCTL rules: OK\n")
}
}
if len (cj.Config.Exec_prestop) > 0 {
fmt.Printf(" > Execute prestop:\n")
_, err := executeCommand(cj.Config.Exec_prestop)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Execute prestop: OK\n")
}
}
if len (cj.Config.Exec_stop) > 0 {
fmt.Printf(" > Execute stop:\n")
_, err := executeCommandInJail(cj, cj.Config.Exec_stop)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Execute stop: OK\n")
}
}
if cj.Config.Jail_zfs > 0 {
fmt.Printf(" > Umount jailed ZFS:\n")
err := umountAndUnjailZFS(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Umount jailed ZFS: OK\n")
}
}
if cj.Config.Vnet > 0 && len(cj.Config.Ip4_addr) > 0 {
fmt.Printf(" > Destroy VNet interfaces:\n")
err := destroyVNetInterfaces(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Destroy VNet interfaces: OK\n")
}
}
fmt.Printf(" > Remove devfsruleset %s:\n", cj.Config.Devfs_ruleset)
err = deleteDevfsRuleset(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Execute prestop: OK\n")
fmt.Printf(" > Remove devfsruleset %s: OK\n", cj.Config.Devfs_ruleset)
}
}
if len (cj.Config.Exec_stop) > 0 {
fmt.Printf(" > Execute stop:\n")
_, err := executeCommandInJail(cj, cj.Config.Exec_stop)
fmt.Printf(" > Stop jail %s:\n", cj.Name)
err = stopJail(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Execute stop: OK\n")
fmt.Printf(" > Stop jail %s: OK\n", cj.Name)
}
}
if cj.Config.Jail_zfs > 0 {
fmt.Printf(" > Umount jailed ZFS:\n")
err := umountAndUnjailZFS(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Umount jailed ZFS: OK\n")
}
}
if cj.Config.Vnet > 0 && len(cj.Config.Ip4_addr) > 0 {
fmt.Printf(" > Destroy VNet interfaces:\n")
err := destroyVNetInterfaces(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Destroy VNet interfaces: OK\n")
}
}
fmt.Printf(" > Remove devfsruleset %s:\n", cj.Config.Devfs_ruleset)
err = deleteDevfsRuleset(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Remove devfsruleset %s: OK\n", cj.Config.Devfs_ruleset)
}
fmt.Printf(" > Stop jail %s:\n", cj.Name)
err = stopJail(cj)
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
} else {
fmt.Printf(" > Stop jail %s: OK\n", cj.Name)
}
*/
*/
}
}

View File

@ -1,13 +1,13 @@
package cmd
import (
"os"
"fmt"
// "log"
"os"
// "log"
"errors"
"regexp"
"os/exec"
// "reflect"
"regexp"
// "reflect"
"strings"
)
@ -38,7 +38,6 @@ func removeRctlRules(jail string, rules []string) error {
return nil
}
// TODO: Validate with >1 dataset
func umountAndUnjailZFS(jail *Jail) error {
var ds []string
@ -79,7 +78,6 @@ func umountAndUnjailZFS(jail *Jail) error {
return nil
}
func destroyVNetInterfaces(jail *Jail) error {
for _, i := range strings.Split(jail.Config.Ip4_addr, ",") {
iname := fmt.Sprintf("%s.%d", strings.Split(i, "|")[0], jail.JID)
@ -119,7 +117,6 @@ func deleteDevfsRuleset(jail *Jail) error {
return nil
}
func umountJailFsFromHost(jail *Jail, mountpoint string) error {
cmd := "mount -p"
out, err := executeCommand(cmd)
@ -145,7 +142,6 @@ func umountJailFsFromHost(jail *Jail, mountpoint string) error {
return nil
}
// Internal usage only
func stopJail(jail *Jail) error {
cmd := "jail -q"
@ -221,7 +217,7 @@ func StopJail(args []string) {
}
}
if len (cj.Config.Exec_prestop) > 0 {
if len(cj.Config.Exec_prestop) > 0 {
fmt.Printf(" > Execute prestop:\n")
_, err := executeCommand(cj.Config.Exec_prestop)
if err != nil {
@ -231,7 +227,7 @@ func StopJail(args []string) {
}
}
if len (cj.Config.Exec_stop) > 0 {
if len(cj.Config.Exec_stop) > 0 {
fmt.Printf(" > Execute stop:\n")
_, err := executeCommandInJail(cj, cj.Config.Exec_stop)
if err != nil {
@ -340,4 +336,3 @@ func StopJail(args []string) {
}
}
}

View File

@ -4,19 +4,24 @@ import (
"time"
)
const (
IPv4 = 0
IPv6 = 1
)
// To allow sorting, just duplicate fields in JailSort below
type Jail struct {
Name string
InternalName string
JID int
Config JailConfig
RootPath string
ConfigPath string
ConfigUpdated bool
Running bool
Name string
InternalName string
JID int
Config JailConfig
RootPath string
ConfigPath string
ConfigUpdated bool
Running bool
// No need, Config.Release always represent what is running (plus it know release for non-running jails)
//Release string
Zpool string
Zpool string
}
// iocage struct as stored in config.json
@ -28,483 +33,483 @@ type Jail struct {
//
// To allow sorting, just duplicate fields in JailConfigSort below
type JailConfig struct {
Config_version string `json:"CONFIG_VERSION"`
Allow_chflags int `json:"allow_chflags"`
Allow_mlock int `json:"allow_mlock"`
Allow_mount int `json:"allow_mount"`
Allow_mount_devfs int `json:"allow_mount_devfs"`
Allow_mount_fusefs int `json:"allow_mount_fusefs"`
Allow_mount_nullfs int `json:"allow_mount_nullfs"`
Allow_mount_procfs int `json:"allow_mount_procfs"`
Allow_mount_tmpfs int `json:"allow_mount_tmpfs"`
Allow_mount_zfs int `json:"allow_mount_zfs"`
Allow_quotas int `json:"allow_quotas"`
Allow_raw_sockets int `json:"allow_raw_sockets"`
Allow_set_hostname int `json:"allow_set_hostname"`
Allow_socket_af int `json:"allow_socket_af"`
Allow_sysvipc int `json:"allow_sysvipc"`
Allow_tun int `json:"allow_tun"`
Allow_vmm int `json:"allow_vmm"`
Assign_localhost int `json:"assign_localhost"`
Available string `json:"available"`
Basejail int `json:"basejail"`
Boot int `json:"boot"`
Bpf int `json:"bpf"`
Children_max string `json:"children_max"`
Cloned_release string `json:"cloned_release"`
Comment string `json:"comment"`
Compression string `json:"compression"`
Compressratio string `json:"compressratio"`
Coredumpsize string `json:"coredumpsize"`
Count string `json:"count"`
Cpuset string `json:"cpuset"`
Cputime string `json:"cputime"`
Datasize string `json:"datasize"`
Dedup string `json:"dedup"`
Defaultrouter string `json:"defaultrouter"`
Defaultrouter6 string `json:"defaultrouter6"`
Depends string `json:"depends"`
Devfs_ruleset string `json:"devfs_ruleset"`
Dhcp int `json:"dhcp"`
Enforce_statfs string `json:"enforce_statfs"`
Exec_clean int `json:"exec_clean"`
Exec_created string `json:"exec_created"`
Exec_fib string `json:"exec_fib"`
Exec_jail_user string `json:"exec_jail_user"`
Exec_poststart string `json:"exec_poststart"`
Exec_poststop string `json:"exec_poststop"`
Exec_prestart string `json:"exec_prestart"`
Exec_prestop string `json:"exec_prestop"`
Exec_start string `json:"exec_start"`
Exec_stop string `json:"exec_stop"`
Exec_system_jail_user string `json:"exec_system_jail_user"`
Exec_system_user string `json:"exec_system_user"`
Exec_timeout string `json:"exec_timeout"`
Host_domainname string `json:"host_domainname"`
Host_hostname string `json:"host_hostname"`
Host_hostuuid string `json:"host_hostuuid"`
Host_time int `json:"host_time"`
Hostid string `json:"hostid"`
Hostid_strict_check int `json:"hostid_strict_check"`
Interfaces string `json:"interfaces"`
Ip4 string `json:"ip4"`
Ip4_addr string `json:"ip4_addr"`
Ip4_saddrsel string `json:"ip4_saddrsel"`
Ip6 string `json:"ip6"`
Ip6_addr string `json:"ip6_addr"`
Ip6_saddrsel string `json:"ip4_saddrsel"`
Ip_hostname int `json:"ip_hostname"`
Jail_zfs int `json:"jail_zfs"`
Jail_zfs_dataset string `json:"jail_zfs_dataset"`
Jail_zfs_mountpoint string `json:"jail_zfs_mountpoint"`
Last_started string `json:"last_started"`
Localhost_ip string `json:"localhost_ip"`
Login_flags string `json:"login_flags"`
Mac_prefix string `json:"mac_prefix"`
Maxproc string `json:"maxproc"`
Memorylocked string `json:"memorylocked"`
Memoryuse string `json:"memoryuse"`
Min_dyn_devfs_ruleset string `json:"min_dyn_devfs_ruleset"`
Mount_devfs int `json:"mount_devfs"`
Mount_fdescfs int `json:"mount_fdescfs"`
Mount_linprocfs int `json:"mount_linprocfs"`
Mount_procfs int `json:"mount_procfs"`
Mountpoint string `json:"mountpoint"`
Msgqqueued string `json:"msgqqueued"`
Msgqsize string `json:"msgqsize"`
Nat int `json:"nat"`
Nat_backend string `json:"nat_backend"`
Nat_forwards string `json:"nat_forwards"`
Nat_interface string `json:"nat_interface"`
Nat_prefix string `json:"nat_prefix"`
Nmsgq string `json:"nmsgq"`
Notes string `json:"notes"`
Nsem string `json:"nsem"`
Nsemop string `json:"nsemop"`
Nshm string `json:"nshm"`
Nthr string `json:"nthr"`
Openfiles string `json:"openfiles"`
Origin string `json:"origin"`
Owner string `json:"owner"`
Pcpu string `json:"pcpu"`
Plugin_name string `json:"plugin_name"`
Plugin_repository string `json:"plugin_repository"`
Priority string `json:"priority"`
Pseudoterminals string `json:"pseudoterminals"`
Quota string `json:"quota"`
Readbps string `json:"readbps"`
Readiops string `json:"readiops"`
Release string `json:"release"`
Reservation string `json:"reservation"`
Resolver string `json:"resolver"`
Rlimits string `json:"rlimits"`
Rtsold int `json:"rtsold"`
Securelevel string `json:"securelevel"`
Shmsize string `json:"shmsize"`
Stacksize string `json:"stacksize"`
Stop_timeout string `json:"stop_timeout"`
Swapuse string `json:"swapuse"`
Sync_state string `json:"sync_state"`
Sync_target string `json:"sync_target"`
Sync_tgt_zpool string `json:"sync_tgt_zpool"`
Sysvmsg string `json:"sysvmsg"`
Sysvsem string `json:"sysvsem"`
Sysvshm string `json:"sysvshm"`
Template int `json:"template"`
Config_version string `json:"CONFIG_VERSION"`
Allow_chflags int `json:"allow_chflags"`
Allow_mlock int `json:"allow_mlock"`
Allow_mount int `json:"allow_mount"`
Allow_mount_devfs int `json:"allow_mount_devfs"`
Allow_mount_fusefs int `json:"allow_mount_fusefs"`
Allow_mount_nullfs int `json:"allow_mount_nullfs"`
Allow_mount_procfs int `json:"allow_mount_procfs"`
Allow_mount_tmpfs int `json:"allow_mount_tmpfs"`
Allow_mount_zfs int `json:"allow_mount_zfs"`
Allow_quotas int `json:"allow_quotas"`
Allow_raw_sockets int `json:"allow_raw_sockets"`
Allow_set_hostname int `json:"allow_set_hostname"`
Allow_socket_af int `json:"allow_socket_af"`
Allow_sysvipc int `json:"allow_sysvipc"`
Allow_tun int `json:"allow_tun"`
Allow_vmm int `json:"allow_vmm"`
Assign_localhost int `json:"assign_localhost"`
Available string `json:"available"`
Basejail int `json:"basejail"`
Boot int `json:"boot"`
Bpf int `json:"bpf"`
Children_max string `json:"children_max"`
Cloned_release string `json:"cloned_release"`
Comment string `json:"comment"`
Compression string `json:"compression"`
Compressratio string `json:"compressratio"`
Coredumpsize string `json:"coredumpsize"`
Count string `json:"count"`
Cpuset string `json:"cpuset"`
Cputime string `json:"cputime"`
Datasize string `json:"datasize"`
Dedup string `json:"dedup"`
Defaultrouter string `json:"defaultrouter"`
Defaultrouter6 string `json:"defaultrouter6"`
Depends string `json:"depends"`
Devfs_ruleset string `json:"devfs_ruleset"`
Dhcp int `json:"dhcp"`
Enforce_statfs string `json:"enforce_statfs"`
Exec_clean int `json:"exec_clean"`
Exec_created string `json:"exec_created"`
Exec_fib string `json:"exec_fib"`
Exec_jail_user string `json:"exec_jail_user"`
Exec_poststart string `json:"exec_poststart"`
Exec_poststop string `json:"exec_poststop"`
Exec_prestart string `json:"exec_prestart"`
Exec_prestop string `json:"exec_prestop"`
Exec_start string `json:"exec_start"`
Exec_stop string `json:"exec_stop"`
Exec_system_jail_user string `json:"exec_system_jail_user"`
Exec_system_user string `json:"exec_system_user"`
Exec_timeout string `json:"exec_timeout"`
Host_domainname string `json:"host_domainname"`
Host_hostname string `json:"host_hostname"`
Host_hostuuid string `json:"host_hostuuid"`
Host_time int `json:"host_time"`
Hostid string `json:"hostid"`
Hostid_strict_check int `json:"hostid_strict_check"`
Interfaces string `json:"interfaces"`
Ip4 string `json:"ip4"`
Ip4_addr string `json:"ip4_addr"`
Ip4_saddrsel string `json:"ip4_saddrsel"`
Ip6 string `json:"ip6"`
Ip6_addr string `json:"ip6_addr"`
Ip6_saddrsel string `json:"ip4_saddrsel"`
Ip_hostname int `json:"ip_hostname"`
Jail_zfs int `json:"jail_zfs"`
Jail_zfs_dataset string `json:"jail_zfs_dataset"`
Jail_zfs_mountpoint string `json:"jail_zfs_mountpoint"`
Last_started string `json:"last_started"`
Localhost_ip string `json:"localhost_ip"`
Login_flags string `json:"login_flags"`
Mac_prefix string `json:"mac_prefix"`
Maxproc string `json:"maxproc"`
Memorylocked string `json:"memorylocked"`
Memoryuse string `json:"memoryuse"`
Min_dyn_devfs_ruleset string `json:"min_dyn_devfs_ruleset"`
Mount_devfs int `json:"mount_devfs"`
Mount_fdescfs int `json:"mount_fdescfs"`
Mount_linprocfs int `json:"mount_linprocfs"`
Mount_procfs int `json:"mount_procfs"`
Mountpoint string `json:"mountpoint"`
Msgqqueued string `json:"msgqqueued"`
Msgqsize string `json:"msgqsize"`
Nat int `json:"nat"`
Nat_backend string `json:"nat_backend"`
Nat_forwards string `json:"nat_forwards"`
Nat_interface string `json:"nat_interface"`
Nat_prefix string `json:"nat_prefix"`
Nmsgq string `json:"nmsgq"`
Notes string `json:"notes"`
Nsem string `json:"nsem"`
Nsemop string `json:"nsemop"`
Nshm string `json:"nshm"`
Nthr string `json:"nthr"`
Openfiles string `json:"openfiles"`
Origin string `json:"origin"`
Owner string `json:"owner"`
Pcpu string `json:"pcpu"`
Plugin_name string `json:"plugin_name"`
Plugin_repository string `json:"plugin_repository"`
Priority string `json:"priority"`
Pseudoterminals string `json:"pseudoterminals"`
Quota string `json:"quota"`
Readbps string `json:"readbps"`
Readiops string `json:"readiops"`
Release string `json:"release"`
Reservation string `json:"reservation"`
Resolver string `json:"resolver"`
Rlimits string `json:"rlimits"`
Rtsold int `json:"rtsold"`
Securelevel string `json:"securelevel"`
Shmsize string `json:"shmsize"`
Stacksize string `json:"stacksize"`
Stop_timeout string `json:"stop_timeout"`
Swapuse string `json:"swapuse"`
Sync_state string `json:"sync_state"`
Sync_target string `json:"sync_target"`
Sync_tgt_zpool string `json:"sync_tgt_zpool"`
Sysvmsg string `json:"sysvmsg"`
Sysvsem string `json:"sysvsem"`
Sysvshm string `json:"sysvshm"`
Template int `json:"template"`
// Go don't like a variable named "type" (And i dont care about finding a cleaner way)
Jailtype string `json:"type"`
Used string `json:"used"`
Vmemoryuse string `json:"vmemoryuse"`
Vnet int `json:"vnet"`
Vnet0_mac string `json:"vnet0_mac"`
Vnet1_mac string `json:"vnet1_mac"`
Vnet2_mac string `json:"vnet2_mac"`
Vnet3_mac string `json:"vnet3_mac"`
Vnet_default_interface string `json:"vnet_default_interface"`
Vnet_interfaces string `json:"vnet_interfaces"`
Wallclock string `json:"wallclock"`
Writebps string `json:"writebps"`
Writeiops string `json:"writeiops"`
Jailtype string `json:"type"`
Used string `json:"used"`
Vmemoryuse string `json:"vmemoryuse"`
Vnet int `json:"vnet"`
Vnet0_mac string `json:"vnet0_mac"`
Vnet1_mac string `json:"vnet1_mac"`
Vnet2_mac string `json:"vnet2_mac"`
Vnet3_mac string `json:"vnet3_mac"`
Vnet_default_interface string `json:"vnet_default_interface"`
Vnet_interfaces string `json:"vnet_interfaces"`
Wallclock string `json:"wallclock"`
Writebps string `json:"writebps"`
Writeiops string `json:"writeiops"`
}
// Represent an fstab line
type Mount struct {
Device string
Mountpoint string
Type string
Options []string
Fs_Freq int
Fs_Passno int
Device string
Mountpoint string
Type string
Options []string
Fs_Freq int
Fs_Passno int
}
type Snapshot struct {
// snapshot name is stored after '@' in dataset name
Name string
Dsname string
Jailname string
Mountpoint string
Used string
Referenced string
Creation time.Time
Name string
Dsname string
Jailname string
Mountpoint string
Used string
Referenced string
Creation time.Time
}
// Fields in this struct are acquired by their name using reflection
// So these char are forbidden for field name: -+.
//
type JailSort struct {
NameInc jailLessFunc
NameDec jailLessFunc
InternalNameInc jailLessFunc
InternalNameDec jailLessFunc
JIDInc jailLessFunc
JIDDec jailLessFunc
RootPathInc jailLessFunc
RootPathDec jailLessFunc
ConfigPathInc jailLessFunc
ConfigPathDec jailLessFunc
RunningInc jailLessFunc
RunningDec jailLessFunc
ZpoolInc jailLessFunc
ZpoolDec jailLessFunc
Config JailConfigSort
NameInc jailLessFunc
NameDec jailLessFunc
InternalNameInc jailLessFunc
InternalNameDec jailLessFunc
JIDInc jailLessFunc
JIDDec jailLessFunc
RootPathInc jailLessFunc
RootPathDec jailLessFunc
ConfigPathInc jailLessFunc
ConfigPathDec jailLessFunc
RunningInc jailLessFunc
RunningDec jailLessFunc
ZpoolInc jailLessFunc
ZpoolDec jailLessFunc
Config JailConfigSort
}
type JailConfigSort struct {
Config_versionInc jailLessFunc
Config_versionDec jailLessFunc
Allow_chflagsInc jailLessFunc
Allow_chflagsDec jailLessFunc
Allow_mlockInc jailLessFunc
Allow_mlockDec jailLessFunc
Allow_mountInc jailLessFunc
Allow_mountDec jailLessFunc
Allow_mount_devfsInc jailLessFunc
Allow_mount_devfsDec jailLessFunc
Allow_mount_fusefsInc jailLessFunc
Allow_mount_fusefsDec jailLessFunc
Allow_mount_nullfsInc jailLessFunc
Allow_mount_nullfsDec jailLessFunc
Allow_mount_procfsInc jailLessFunc
Allow_mount_procfsDec jailLessFunc
Allow_mount_tmpfsInc jailLessFunc
Allow_mount_tmpfsDec jailLessFunc
Allow_mount_zfsInc jailLessFunc
Allow_mount_zfsDec jailLessFunc
Allow_quotasInc jailLessFunc
Allow_quotasDec jailLessFunc
Allow_raw_socketsInc jailLessFunc
Allow_raw_socketsDec jailLessFunc
Allow_set_hostnameInc jailLessFunc
Allow_set_hostnameDec jailLessFunc
Allow_socket_afInc jailLessFunc
Allow_socket_afDec jailLessFunc
Allow_sysvipcInc jailLessFunc
Allow_sysvipcDec jailLessFunc
Allow_tunInc jailLessFunc
Allow_tunDec jailLessFunc
Allow_vmmInc jailLessFunc
Allow_vmmDec jailLessFunc
Assign_localhostInc jailLessFunc
Assign_localhostDec jailLessFunc
AvailableInc jailLessFunc
AvailableDec jailLessFunc
BasejailInc jailLessFunc
BasejailDec jailLessFunc
BootInc jailLessFunc
BootDec jailLessFunc
BpfInc jailLessFunc
BpfDec jailLessFunc
Children_maxInc jailLessFunc
Children_maxDec jailLessFunc
Cloned_releaseInc jailLessFunc
Cloned_releaseDec jailLessFunc
CommentInc jailLessFunc
CommentDec jailLessFunc
CompressionInc jailLessFunc
CompressionDec jailLessFunc
CompressratioInc jailLessFunc
CompressratioDec jailLessFunc
CoredumpsizeInc jailLessFunc
CoredumpsizeDec jailLessFunc
CountInc jailLessFunc
CountDec jailLessFunc
CpusetInc jailLessFunc
CpusetDec jailLessFunc
CputimeInc jailLessFunc
CputimeDec jailLessFunc
DatasizeInc jailLessFunc
DatasizeDec jailLessFunc
DedupInc jailLessFunc
DedupDec jailLessFunc
DefaultrouterInc jailLessFunc
DefaultrouterDec jailLessFunc
Defaultrouter6Inc jailLessFunc
Defaultrouter6Dec jailLessFunc
DependsInc jailLessFunc
DependsDec jailLessFunc
Devfs_rulesetInc jailLessFunc
Devfs_rulesetDec jailLessFunc
DhcpInc jailLessFunc
DhcpDec jailLessFunc
Enforce_statfsInc jailLessFunc
Enforce_statfsDec jailLessFunc
Exec_cleanInc jailLessFunc
Exec_cleanDec jailLessFunc
Exec_createdInc jailLessFunc
Exec_createdDec jailLessFunc
Exec_fibInc jailLessFunc
Exec_fibDec jailLessFunc
Exec_jail_userInc jailLessFunc
Exec_jail_userDec jailLessFunc
Exec_poststartInc jailLessFunc
Exec_poststartDec jailLessFunc
Exec_poststopInc jailLessFunc
Exec_poststopDec jailLessFunc
Exec_prestartInc jailLessFunc
Exec_prestartDec jailLessFunc
Exec_prestopInc jailLessFunc
Exec_prestopDec jailLessFunc
Exec_startInc jailLessFunc
Exec_startDec jailLessFunc
Exec_stopInc jailLessFunc
Exec_stopDec jailLessFunc
Exec_system_jail_userInc jailLessFunc
Exec_system_jail_userDec jailLessFunc
Exec_system_userInc jailLessFunc
Exec_system_userDec jailLessFunc
Exec_timeoutInc jailLessFunc
Exec_timeoutDec jailLessFunc
Host_domainnameInc jailLessFunc
Host_domainnameDec jailLessFunc
Host_hostnameInc jailLessFunc
Host_hostnameDec jailLessFunc
Host_hostuuidInc jailLessFunc
Host_hostuuidDec jailLessFunc
Host_timeInc jailLessFunc
Host_timeDec jailLessFunc
HostidInc jailLessFunc
HostidDec jailLessFunc
Hostid_strict_checkInc jailLessFunc
Hostid_strict_checkDec jailLessFunc
InterfacesInc jailLessFunc
InterfacesDec jailLessFunc
Ip4Inc jailLessFunc
Ip4Dec jailLessFunc
Ip4_addrInc jailLessFunc
Ip4_addrDec jailLessFunc
Ip4_saddrselInc jailLessFunc
Ip4_saddrselDec jailLessFunc
Ip6Inc jailLessFunc
Ip6Dec jailLessFunc
Ip6_addrInc jailLessFunc
Ip6_addrDec jailLessFunc
Ip6_saddrselInc jailLessFunc
Ip6_saddrselDec jailLessFunc
Ip_hostnameInc jailLessFunc
Ip_hostnameDec jailLessFunc
Jail_zfsInc jailLessFunc
Jail_zfsDec jailLessFunc
Jail_zfs_datasetInc jailLessFunc
Jail_zfs_datasetDec jailLessFunc
Jail_zfs_mountpointInc jailLessFunc
Jail_zfs_mountpointDec jailLessFunc
Last_startedInc jailLessFunc
Last_startedDec jailLessFunc
Localhost_ipInc jailLessFunc
Localhost_ipDec jailLessFunc
Login_flagsInc jailLessFunc
Login_flagsDec jailLessFunc
Mac_prefixInc jailLessFunc
Mac_prefixDec jailLessFunc
MaxprocInc jailLessFunc
MaxprocDec jailLessFunc
MemorylockedInc jailLessFunc
MemorylockedDec jailLessFunc
MemoryuseInc jailLessFunc
MemoryuseDec jailLessFunc
Min_dyn_devfs_rulesetInc jailLessFunc
Min_dyn_devfs_rulesetDec jailLessFunc
Mount_devfsInc jailLessFunc
Mount_devfsDec jailLessFunc
Mount_fdescfsInc jailLessFunc
Mount_fdescfsDec jailLessFunc
Mount_linprocfsInc jailLessFunc
Mount_linprocfsDec jailLessFunc
Mount_procfsInc jailLessFunc
Mount_procfsDec jailLessFunc
MountpointInc jailLessFunc
MountpointDec jailLessFunc
MsgqqueuedInc jailLessFunc
MsgqqueuedDec jailLessFunc
MsgqsizeInc jailLessFunc
MsgqsizeDec jailLessFunc
NatInc jailLessFunc
NatDec jailLessFunc
Nat_backendInc jailLessFunc
Nat_backendDec jailLessFunc
Nat_forwardsInc jailLessFunc
Nat_forwardsDec jailLessFunc
Nat_interfaceInc jailLessFunc
Nat_interfaceDec jailLessFunc
Nat_prefixInc jailLessFunc
Nat_prefixDec jailLessFunc
NmsgqInc jailLessFunc
NmsgqDec jailLessFunc
NotesInc jailLessFunc
NotesDec jailLessFunc
NsemInc jailLessFunc
NsemDec jailLessFunc
NsemopInc jailLessFunc
NsemopDec jailLessFunc
NshmInc jailLessFunc
NshmDec jailLessFunc
NthrInc jailLessFunc
NthrDec jailLessFunc
OpenfilesInc jailLessFunc
OpenfilesDec jailLessFunc
OriginInc jailLessFunc
OriginDec jailLessFunc
OwnerInc jailLessFunc
OwnerDec jailLessFunc
PcpuInc jailLessFunc
PcpuDec jailLessFunc
Plugin_nameInc jailLessFunc
Plugin_nameDec jailLessFunc
Plugin_repositoryInc jailLessFunc
Plugin_repositoryDec jailLessFunc
PriorityInc jailLessFunc
PriorityDec jailLessFunc
PseudoterminalsInc jailLessFunc
PseudoterminalsDec jailLessFunc
QuotaInc jailLessFunc
QuotaDec jailLessFunc
ReadbpsInc jailLessFunc
ReadbpsDec jailLessFunc
ReadiopsInc jailLessFunc
ReadiopsDec jailLessFunc
ReleaseInc jailLessFunc
ReleaseDec jailLessFunc
ReservationInc jailLessFunc
ReservationDec jailLessFunc
ResolverInc jailLessFunc
ResolverDec jailLessFunc
RlimitsInc jailLessFunc
RlimitsDec jailLessFunc
RtsoldInc jailLessFunc
RtsoldDec jailLessFunc
SecurelevelInc jailLessFunc
SecurelevelDec jailLessFunc
ShmsizeInc jailLessFunc
ShmsizeDec jailLessFunc
StacksizeInc jailLessFunc
StacksizeDec jailLessFunc
Stop_timeoutInc jailLessFunc
Stop_timeoutDec jailLessFunc
SwapuseInc jailLessFunc
SwapuseDec jailLessFunc
Sync_stateInc jailLessFunc
Sync_stateDec jailLessFunc
Sync_targetInc jailLessFunc
Sync_targetDec jailLessFunc
Sync_tgt_zpoolInc jailLessFunc
Sync_tgt_zpoolDec jailLessFunc
SysvmsgInc jailLessFunc
SysvmsgDec jailLessFunc
SysvsemInc jailLessFunc
SysvsemDec jailLessFunc
SysvshmInc jailLessFunc
SysvshmDec jailLessFunc
TemplateInc jailLessFunc
TemplateDec jailLessFunc
JailtypeInc jailLessFunc
JailtypeDec jailLessFunc
UsedInc jailLessFunc
UsedDec jailLessFunc
VmemoryuseInc jailLessFunc
VmemoryuseDec jailLessFunc
VnetInc jailLessFunc
VnetDec jailLessFunc
Vnet0_macInc jailLessFunc
Vnet0_macDec jailLessFunc
Vnet1_macInc jailLessFunc
Vnet1_macDec jailLessFunc
Vnet2_macInc jailLessFunc
Vnet2_macDec jailLessFunc
Vnet3_macInc jailLessFunc
Vnet3_macDec jailLessFunc
Vnet_default_interfaceInc jailLessFunc
Vnet_default_interfaceDec jailLessFunc
Vnet_interfacesInc jailLessFunc
Vnet_interfacesDec jailLessFunc
WallclockInc jailLessFunc
WallclockDec jailLessFunc
WritebpsInc jailLessFunc
WritebpsDec jailLessFunc
WriteiopsInc jailLessFunc
WriteiopsDec jailLessFunc
Config_versionInc jailLessFunc
Config_versionDec jailLessFunc
Allow_chflagsInc jailLessFunc
Allow_chflagsDec jailLessFunc
Allow_mlockInc jailLessFunc
Allow_mlockDec jailLessFunc
Allow_mountInc jailLessFunc
Allow_mountDec jailLessFunc
Allow_mount_devfsInc jailLessFunc
Allow_mount_devfsDec jailLessFunc
Allow_mount_fusefsInc jailLessFunc
Allow_mount_fusefsDec jailLessFunc
Allow_mount_nullfsInc jailLessFunc
Allow_mount_nullfsDec jailLessFunc
Allow_mount_procfsInc jailLessFunc
Allow_mount_procfsDec jailLessFunc
Allow_mount_tmpfsInc jailLessFunc
Allow_mount_tmpfsDec jailLessFunc
Allow_mount_zfsInc jailLessFunc
Allow_mount_zfsDec jailLessFunc
Allow_quotasInc jailLessFunc
Allow_quotasDec jailLessFunc
Allow_raw_socketsInc jailLessFunc
Allow_raw_socketsDec jailLessFunc
Allow_set_hostnameInc jailLessFunc
Allow_set_hostnameDec jailLessFunc
Allow_socket_afInc jailLessFunc
Allow_socket_afDec jailLessFunc
Allow_sysvipcInc jailLessFunc
Allow_sysvipcDec jailLessFunc
Allow_tunInc jailLessFunc
Allow_tunDec jailLessFunc
Allow_vmmInc jailLessFunc
Allow_vmmDec jailLessFunc
Assign_localhostInc jailLessFunc
Assign_localhostDec jailLessFunc
AvailableInc jailLessFunc
AvailableDec jailLessFunc
BasejailInc jailLessFunc
BasejailDec jailLessFunc
BootInc jailLessFunc
BootDec jailLessFunc
BpfInc jailLessFunc
BpfDec jailLessFunc
Children_maxInc jailLessFunc
Children_maxDec jailLessFunc
Cloned_releaseInc jailLessFunc
Cloned_releaseDec jailLessFunc
CommentInc jailLessFunc
CommentDec jailLessFunc
CompressionInc jailLessFunc
CompressionDec jailLessFunc
CompressratioInc jailLessFunc
CompressratioDec jailLessFunc
CoredumpsizeInc jailLessFunc
CoredumpsizeDec jailLessFunc
CountInc jailLessFunc
CountDec jailLessFunc
CpusetInc jailLessFunc
CpusetDec jailLessFunc
CputimeInc jailLessFunc
CputimeDec jailLessFunc
DatasizeInc jailLessFunc
DatasizeDec jailLessFunc
DedupInc jailLessFunc
DedupDec jailLessFunc
DefaultrouterInc jailLessFunc
DefaultrouterDec jailLessFunc
Defaultrouter6Inc jailLessFunc
Defaultrouter6Dec jailLessFunc
DependsInc jailLessFunc
DependsDec jailLessFunc
Devfs_rulesetInc jailLessFunc
Devfs_rulesetDec jailLessFunc
DhcpInc jailLessFunc
DhcpDec jailLessFunc
Enforce_statfsInc jailLessFunc
Enforce_statfsDec jailLessFunc
Exec_cleanInc jailLessFunc
Exec_cleanDec jailLessFunc
Exec_createdInc jailLessFunc
Exec_createdDec jailLessFunc
Exec_fibInc jailLessFunc
Exec_fibDec jailLessFunc
Exec_jail_userInc jailLessFunc
Exec_jail_userDec jailLessFunc
Exec_poststartInc jailLessFunc
Exec_poststartDec jailLessFunc
Exec_poststopInc jailLessFunc
Exec_poststopDec jailLessFunc
Exec_prestartInc jailLessFunc
Exec_prestartDec jailLessFunc
Exec_prestopInc jailLessFunc
Exec_prestopDec jailLessFunc
Exec_startInc jailLessFunc
Exec_startDec jailLessFunc
Exec_stopInc jailLessFunc
Exec_stopDec jailLessFunc
Exec_system_jail_userInc jailLessFunc
Exec_system_jail_userDec jailLessFunc
Exec_system_userInc jailLessFunc
Exec_system_userDec jailLessFunc
Exec_timeoutInc jailLessFunc
Exec_timeoutDec jailLessFunc
Host_domainnameInc jailLessFunc
Host_domainnameDec jailLessFunc
Host_hostnameInc jailLessFunc
Host_hostnameDec jailLessFunc
Host_hostuuidInc jailLessFunc
Host_hostuuidDec jailLessFunc
Host_timeInc jailLessFunc
Host_timeDec jailLessFunc
HostidInc jailLessFunc
HostidDec jailLessFunc
Hostid_strict_checkInc jailLessFunc
Hostid_strict_checkDec jailLessFunc
InterfacesInc jailLessFunc
InterfacesDec jailLessFunc
Ip4Inc jailLessFunc
Ip4Dec jailLessFunc
Ip4_addrInc jailLessFunc
Ip4_addrDec jailLessFunc
Ip4_saddrselInc jailLessFunc
Ip4_saddrselDec jailLessFunc
Ip6Inc jailLessFunc
Ip6Dec jailLessFunc
Ip6_addrInc jailLessFunc
Ip6_addrDec jailLessFunc
Ip6_saddrselInc jailLessFunc
Ip6_saddrselDec jailLessFunc
Ip_hostnameInc jailLessFunc
Ip_hostnameDec jailLessFunc
Jail_zfsInc jailLessFunc
Jail_zfsDec jailLessFunc
Jail_zfs_datasetInc jailLessFunc
Jail_zfs_datasetDec jailLessFunc
Jail_zfs_mountpointInc jailLessFunc
Jail_zfs_mountpointDec jailLessFunc
Last_startedInc jailLessFunc
Last_startedDec jailLessFunc
Localhost_ipInc jailLessFunc
Localhost_ipDec jailLessFunc
Login_flagsInc jailLessFunc
Login_flagsDec jailLessFunc
Mac_prefixInc jailLessFunc
Mac_prefixDec jailLessFunc
MaxprocInc jailLessFunc
MaxprocDec jailLessFunc
MemorylockedInc jailLessFunc
MemorylockedDec jailLessFunc
MemoryuseInc jailLessFunc
MemoryuseDec jailLessFunc
Min_dyn_devfs_rulesetInc jailLessFunc
Min_dyn_devfs_rulesetDec jailLessFunc
Mount_devfsInc jailLessFunc
Mount_devfsDec jailLessFunc
Mount_fdescfsInc jailLessFunc
Mount_fdescfsDec jailLessFunc
Mount_linprocfsInc jailLessFunc
Mount_linprocfsDec jailLessFunc
Mount_procfsInc jailLessFunc
Mount_procfsDec jailLessFunc
MountpointInc jailLessFunc
MountpointDec jailLessFunc
MsgqqueuedInc jailLessFunc
MsgqqueuedDec jailLessFunc
MsgqsizeInc jailLessFunc
MsgqsizeDec jailLessFunc
NatInc jailLessFunc
NatDec jailLessFunc
Nat_backendInc jailLessFunc
Nat_backendDec jailLessFunc
Nat_forwardsInc jailLessFunc
Nat_forwardsDec jailLessFunc
Nat_interfaceInc jailLessFunc
Nat_interfaceDec jailLessFunc
Nat_prefixInc jailLessFunc
Nat_prefixDec jailLessFunc
NmsgqInc jailLessFunc
NmsgqDec jailLessFunc
NotesInc jailLessFunc
NotesDec jailLessFunc
NsemInc jailLessFunc
NsemDec jailLessFunc
NsemopInc jailLessFunc
NsemopDec jailLessFunc
NshmInc jailLessFunc
NshmDec jailLessFunc
NthrInc jailLessFunc
NthrDec jailLessFunc
OpenfilesInc jailLessFunc
OpenfilesDec jailLessFunc
OriginInc jailLessFunc
OriginDec jailLessFunc
OwnerInc jailLessFunc
OwnerDec jailLessFunc
PcpuInc jailLessFunc
PcpuDec jailLessFunc
Plugin_nameInc jailLessFunc
Plugin_nameDec jailLessFunc
Plugin_repositoryInc jailLessFunc
Plugin_repositoryDec jailLessFunc
PriorityInc jailLessFunc
PriorityDec jailLessFunc
PseudoterminalsInc jailLessFunc
PseudoterminalsDec jailLessFunc
QuotaInc jailLessFunc
QuotaDec jailLessFunc
ReadbpsInc jailLessFunc
ReadbpsDec jailLessFunc
ReadiopsInc jailLessFunc
ReadiopsDec jailLessFunc
ReleaseInc jailLessFunc
ReleaseDec jailLessFunc
ReservationInc jailLessFunc
ReservationDec jailLessFunc
ResolverInc jailLessFunc
ResolverDec jailLessFunc
RlimitsInc jailLessFunc
RlimitsDec jailLessFunc
RtsoldInc jailLessFunc
RtsoldDec jailLessFunc
SecurelevelInc jailLessFunc
SecurelevelDec jailLessFunc
ShmsizeInc jailLessFunc
ShmsizeDec jailLessFunc
StacksizeInc jailLessFunc
StacksizeDec jailLessFunc
Stop_timeoutInc jailLessFunc
Stop_timeoutDec jailLessFunc
SwapuseInc jailLessFunc
SwapuseDec jailLessFunc
Sync_stateInc jailLessFunc
Sync_stateDec jailLessFunc
Sync_targetInc jailLessFunc
Sync_targetDec jailLessFunc
Sync_tgt_zpoolInc jailLessFunc
Sync_tgt_zpoolDec jailLessFunc
SysvmsgInc jailLessFunc
SysvmsgDec jailLessFunc
SysvsemInc jailLessFunc
SysvsemDec jailLessFunc
SysvshmInc jailLessFunc
SysvshmDec jailLessFunc
TemplateInc jailLessFunc
TemplateDec jailLessFunc
JailtypeInc jailLessFunc
JailtypeDec jailLessFunc
UsedInc jailLessFunc
UsedDec jailLessFunc
VmemoryuseInc jailLessFunc
VmemoryuseDec jailLessFunc
VnetInc jailLessFunc
VnetDec jailLessFunc
Vnet0_macInc jailLessFunc
Vnet0_macDec jailLessFunc
Vnet1_macInc jailLessFunc
Vnet1_macDec jailLessFunc
Vnet2_macInc jailLessFunc
Vnet2_macDec jailLessFunc
Vnet3_macInc jailLessFunc
Vnet3_macDec jailLessFunc
Vnet_default_interfaceInc jailLessFunc
Vnet_default_interfaceDec jailLessFunc
Vnet_interfacesInc jailLessFunc
Vnet_interfacesDec jailLessFunc
WallclockInc jailLessFunc
WallclockDec jailLessFunc
WritebpsInc jailLessFunc
WritebpsDec jailLessFunc
WriteiopsInc jailLessFunc
WriteiopsDec jailLessFunc
}
type SnapshotSort struct {
NameInc snapshotLessFunc
NameDec snapshotLessFunc
DsnameInc snapshotLessFunc
DsnameDec snapshotLessFunc
JailnameInc snapshotLessFunc
JailnameDec snapshotLessFunc
MountpointInc snapshotLessFunc
MountpointDec snapshotLessFunc
UsedInc snapshotLessFunc
UsedDec snapshotLessFunc
ReferencedInc snapshotLessFunc
ReferencedDec snapshotLessFunc
CreationInc snapshotLessFunc
CreationDec snapshotLessFunc
NameInc snapshotLessFunc
NameDec snapshotLessFunc
DsnameInc snapshotLessFunc
DsnameDec snapshotLessFunc
JailnameInc snapshotLessFunc
JailnameDec snapshotLessFunc
MountpointInc snapshotLessFunc
MountpointDec snapshotLessFunc
UsedInc snapshotLessFunc
UsedDec snapshotLessFunc
ReferencedInc snapshotLessFunc
ReferencedDec snapshotLessFunc
CreationInc snapshotLessFunc
CreationDec snapshotLessFunc
}
type JailHost struct {
hostname string
hostid string
default_gateway4 string
default_gateway6 string
default_interface string
hostname string
hostid string
default_gateway4 string
default_gateway6 string
default_interface string
}

View File

@ -1,19 +1,23 @@
package cmd
import (
"os"
"fmt"
"log"
"sort"
"bufio"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"reflect"
"strings"
"sort"
"strconv"
"io/ioutil"
"strings"
)
const (
ipv4re = `[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}`
ifconfigipv4re = `inet[[:space:]](` + ipv4re + `)`
)
/*****************************************************************************
* Mandatory constructor for JailConfig type. It set default values
@ -28,134 +32,134 @@ func NewJailConfig() (JailConfig, error) {
hostid = []byte(strings.Replace(string(hostid), "\n", "", -1))
}
jc.Allow_chflags = 0
jc.Allow_mlock = 0
jc.Allow_mount = 0
jc.Allow_mount_devfs = 0
jc.Allow_mount_fusefs = 0
jc.Allow_mount_nullfs = 0
jc.Allow_mount_procfs = 0
jc.Allow_mount_tmpfs = 0
jc.Allow_mount_zfs = 0
jc.Allow_quotas = 0
jc.Allow_raw_sockets = 0
jc.Allow_socket_af = 0
jc.Allow_set_hostname = 1
jc.Allow_sysvipc = 0
jc.Allow_tun = 0
jc.Allow_vmm = 0
jc.Assign_localhost = 0
jc.Available = "readonly"
jc.Basejail = 0
jc.Bpf = 0
jc.Boot = 0
jc.Children_max = "0"
jc.Comment = "none"
jc.Compression = "lz4"
jc.Compressratio = "readonly"
jc.Coredumpsize = "off"
jc.Count = "1"
jc.Cpuset = "off"
jc.Cputime = "off"
jc.Datasize = "off"
jc.Dedup = "off"
jc.Defaultrouter = "auto"
jc.Defaultrouter6 = "auto"
jc.Depends = "none"
jc.Devfs_ruleset = "4"
jc.Dhcp = 0
jc.Enforce_statfs = "2"
jc.Exec_clean = 1
jc.Exec_created = "/usr/bin/true"
jc.Exec_jail_user = "root"
jc.Exec_fib = "0"
jc.Exec_poststart = "/usr/bin/true"
jc.Exec_poststop = "/usr/bin/true"
jc.Exec_prestart = "/usr/bin/true"
jc.Exec_prestop = "/usr/bin/true"
jc.Exec_system_jail_user = "0"
jc.Exec_system_user = "root"
jc.Exec_start = "/bin/sh /etc/rc"
jc.Exec_stop = "/bin/sh /etc/rc.shutdown"
jc.Exec_timeout = "60"
jc.Hostid = string(hostid)
jc.Hostid_strict_check = 0
jc.Host_time = 1
jc.Interfaces = "vnet0:bridge0"
jc.Ip4_addr = "none"
jc.Ip4_saddrsel = "1"
jc.Ip4 = "new"
jc.Ip6_addr = "none"
jc.Ip6_saddrsel = "1"
jc.Ip6 = "new"
jc.Ip_hostname = 0
jc.Jailtype = "jail"
jc.Jail_zfs = 0
jc.Jail_zfs_mountpoint = "none"
jc.Last_started = "none"
jc.Localhost_ip = "none"
jc.Login_flags = "-f root"
jc.Maxproc = "off"
jc.Min_dyn_devfs_ruleset = "1000"
jc.Memoryuse = "off"
jc.Memorylocked = "off"
jc.Mountpoint = "readonly"
jc.Mount_devfs = 1
jc.Mount_fdescfs = 1
jc.Mount_procfs = 0
jc.Mount_linprocfs = 0
jc.Msgqqueued = "off"
jc.Msgqsize = "off"
jc.Nat = 0
jc.Nat_backend = "ipfw"
jc.Nat_forwards = "none"
jc.Nat_interface = "none"
jc.Nat_prefix = "172.16"
jc.Nmsgq = "off"
jc.Notes = "none"
jc.Nsem = "off"
jc.Nsemop = "off"
jc.Nshm = "off"
jc.Nthr = "off"
jc.Openfiles = "off"
jc.Origin = "readonly"
jc.Owner = "root"
jc.Pcpu = "off"
jc.Plugin_name = "none"
jc.Plugin_repository = "none"
jc.Priority = "99"
jc.Pseudoterminals = "off"
jc.Quota = "none"
jc.Readbps = "off"
jc.Readiops = "off"
jc.Reservation = "none"
jc.Resolver = "/etc/resolv.conf"
jc.Rlimits = "off"
jc.Rtsold = 0
jc.Securelevel = "2"
jc.Shmsize = "off"
jc.Stacksize = "off"
jc.Stop_timeout = "30"
jc.Sync_state = "none"
jc.Sync_target = "none"
jc.Sync_tgt_zpool = "none"
jc.Sysvmsg = "new"
jc.Sysvsem = "new"
jc.Sysvshm = "new"
jc.Swapuse = "off"
jc.Template = 0
jc.Used = "readonly"
jc.Vmemoryuse = "off"
jc.Vnet = 0
jc.Vnet0_mac = "none"
jc.Vnet1_mac = "none"
jc.Vnet2_mac = "none"
jc.Vnet3_mac = "none"
jc.Allow_chflags = 0
jc.Allow_mlock = 0
jc.Allow_mount = 0
jc.Allow_mount_devfs = 0
jc.Allow_mount_fusefs = 0
jc.Allow_mount_nullfs = 0
jc.Allow_mount_procfs = 0
jc.Allow_mount_tmpfs = 0
jc.Allow_mount_zfs = 0
jc.Allow_quotas = 0
jc.Allow_raw_sockets = 0
jc.Allow_socket_af = 0
jc.Allow_set_hostname = 1
jc.Allow_sysvipc = 0
jc.Allow_tun = 0
jc.Allow_vmm = 0
jc.Assign_localhost = 0
jc.Available = "readonly"
jc.Basejail = 0
jc.Bpf = 0
jc.Boot = 0
jc.Children_max = "0"
jc.Comment = "none"
jc.Compression = "lz4"
jc.Compressratio = "readonly"
jc.Coredumpsize = "off"
jc.Count = "1"
jc.Cpuset = "off"
jc.Cputime = "off"
jc.Datasize = "off"
jc.Dedup = "off"
jc.Defaultrouter = "auto"
jc.Defaultrouter6 = "auto"
jc.Depends = "none"
jc.Devfs_ruleset = "4"
jc.Dhcp = 0
jc.Enforce_statfs = "2"
jc.Exec_clean = 1
jc.Exec_created = "/usr/bin/true"
jc.Exec_jail_user = "root"
jc.Exec_fib = "0"
jc.Exec_poststart = "/usr/bin/true"
jc.Exec_poststop = "/usr/bin/true"
jc.Exec_prestart = "/usr/bin/true"
jc.Exec_prestop = "/usr/bin/true"
jc.Exec_system_jail_user = "0"
jc.Exec_system_user = "root"
jc.Exec_start = "/bin/sh /etc/rc"
jc.Exec_stop = "/bin/sh /etc/rc.shutdown"
jc.Exec_timeout = "60"
jc.Hostid = string(hostid)
jc.Hostid_strict_check = 0
jc.Host_time = 1
jc.Interfaces = "vnet0:bridge0"
jc.Ip4_addr = "none"
jc.Ip4_saddrsel = "1"
jc.Ip4 = "new"
jc.Ip6_addr = "none"
jc.Ip6_saddrsel = "1"
jc.Ip6 = "new"
jc.Ip_hostname = 0
jc.Jailtype = "jail"
jc.Jail_zfs = 0
jc.Jail_zfs_mountpoint = "none"
jc.Last_started = "none"
jc.Localhost_ip = "none"
jc.Login_flags = "-f root"
jc.Maxproc = "off"
jc.Min_dyn_devfs_ruleset = "1000"
jc.Memoryuse = "off"
jc.Memorylocked = "off"
jc.Mountpoint = "readonly"
jc.Mount_devfs = 1
jc.Mount_fdescfs = 1
jc.Mount_procfs = 0
jc.Mount_linprocfs = 0
jc.Msgqqueued = "off"
jc.Msgqsize = "off"
jc.Nat = 0
jc.Nat_backend = "ipfw"
jc.Nat_forwards = "none"
jc.Nat_interface = "none"
jc.Nat_prefix = "172.16"
jc.Nmsgq = "off"
jc.Notes = "none"
jc.Nsem = "off"
jc.Nsemop = "off"
jc.Nshm = "off"
jc.Nthr = "off"
jc.Openfiles = "off"
jc.Origin = "readonly"
jc.Owner = "root"
jc.Pcpu = "off"
jc.Plugin_name = "none"
jc.Plugin_repository = "none"
jc.Priority = "99"
jc.Pseudoterminals = "off"
jc.Quota = "none"
jc.Readbps = "off"
jc.Readiops = "off"
jc.Reservation = "none"
jc.Resolver = "/etc/resolv.conf"
jc.Rlimits = "off"
jc.Rtsold = 0
jc.Securelevel = "2"
jc.Shmsize = "off"
jc.Stacksize = "off"
jc.Stop_timeout = "30"
jc.Sync_state = "none"
jc.Sync_target = "none"
jc.Sync_tgt_zpool = "none"
jc.Sysvmsg = "new"
jc.Sysvsem = "new"
jc.Sysvshm = "new"
jc.Swapuse = "off"
jc.Template = 0
jc.Used = "readonly"
jc.Vmemoryuse = "off"
jc.Vnet = 0
jc.Vnet0_mac = "none"
jc.Vnet1_mac = "none"
jc.Vnet2_mac = "none"
jc.Vnet3_mac = "none"
jc.Vnet_default_interface = "auto"
jc.Vnet_interfaces = "none"
jc.Wallclock = "off"
jc.Writebps = "off"
jc.Writeiops = "off"
jc.Vnet_interfaces = "none"
jc.Wallclock = "off"
jc.Writebps = "off"
jc.Writeiops = "off"
return jc, nil
}
@ -166,49 +170,48 @@ func NewJailConfig() (JailConfig, error) {
*
*****************************************************************************/
func executeCommand(cmdline string) (string, error) {
var cmd []string
var out []byte
var err error
var cmd []string
var out []byte
var err error
if gUseSudo {
cmd = append(cmd, "sudo")
}
cs := strings.Split(cmdline, " ")
if gUseSudo {
cmd = append(cmd, "sudo")
}
cs := strings.Split(cmdline, " ")
cmd = append(cmd, cs...)
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()
}
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
return string(out), err
}
func executeCommandInJail(jail *Jail, cmdline string) (string, error) {
var cmd []string
var cmd []string
if gUseSudo {
cmd = append(cmd, "sudo")
}
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, "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)
cmd = append(cmd, "jexec", jail.InternalName)
cs := strings.Split(cmdline, " ")
cmd = append(cmd, cs...)
cs := strings.Split(cmdline, " ")
cmd = append(cmd, cs...)
out, err := exec.Command(cmd[0], cmd[1:]...).Output()
out, err := exec.Command(cmd[0], cmd[1:]...).Output()
return string(out), err
return string(out), err
}
/*****************************************************************************
@ -238,12 +241,12 @@ func getFstab(path string) ([]Mount, error) {
return mounts, fmt.Errorf("Incorrect format for fstab line %s: Pass is not an integer\n", scan.Text())
}
m := Mount{
Device : res[0],
Mountpoint : res[1],
Type : res[2],
Options : strings.Split(res[3], ","),
Fs_Freq : freq,
Fs_Passno : pass,
Device: res[0],
Mountpoint: res[1],
Type: res[2],
Options: strings.Split(res[3], ","),
Fs_Freq: freq,
Fs_Passno: pass,
}
mounts = append(mounts, m)
}
@ -251,7 +254,6 @@ func getFstab(path string) ([]Mount, error) {
return mounts, nil
}
/********************************************************************************
* Get a specific jail source reference, to update properties after a range loop
*******************************************************************************/
@ -269,40 +271,40 @@ func getJailFromArray(internalName string, jarray []Jail) (*Jail, error) {
* Nested fields are named with a dot (ex "MyStruct.MyField")
*******************************************************************************/
func getStructFieldKind(parentStruct interface{}, fieldName string) (reflect.Kind, string, error) {
v := reflect.ValueOf(parentStruct)
v := reflect.ValueOf(parentStruct)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
// For debugging
if false {
for i := 0 ; i < v.NumField(); i++ {
f := v.Field(i)
if f.Kind() == reflect.String {
fmt.Printf("%v=%v\n", v.Type().Field(i).Name, f.Interface())
}
}
}
if false {
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if f.Kind() == reflect.String {
fmt.Printf("%v=%v\n", v.Type().Field(i).Name, f.Interface())
}
}
}
if strings.Contains(fieldName, ".") {
fs := strings.Split(fieldName, ".")
f := v.FieldByName(fs[0])
if f.Kind() == reflect.Struct {
return getStructFieldKind(f.Interface(), strings.Join(fs[1:], "."))
} else {
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("%s is not a struct: %s\n", fs[0], f.Kind().String()))
}
} else {
f := v.FieldByName(fieldName)
if f.IsValid() {
return f.Kind(), fieldName, nil
} else {
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
}
}
if strings.Contains(fieldName, ".") {
fs := strings.Split(fieldName, ".")
f := v.FieldByName(fs[0])
if f.Kind() == reflect.Struct {
return getStructFieldKind(f.Interface(), strings.Join(fs[1:], "."))
} else {
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("%s is not a struct: %s\n", fs[0], f.Kind().String()))
}
} else {
f := v.FieldByName(fieldName)
if f.IsValid() {
return f.Kind(), fieldName, nil
} else {
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
}
}
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
}
/********************************************************************************
@ -313,7 +315,7 @@ func getStructFieldKind(parentStruct interface{}, fieldName string) (reflect.Kin
func getStructFieldNames(parentStruct interface{}, result []string, prefix string) []string {
v := reflect.ValueOf(parentStruct)
for i := 0 ; i < v.NumField() ; i++ {
for i := 0; i < v.NumField(); i++ {
if v.Type().Field(i).Type.Kind() == reflect.Struct {
result = getStructFieldNames(v.Field(i).Interface(), result, v.Type().Field(i).Name)
} else {
@ -337,7 +339,8 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
v := reflect.ValueOf(parentStruct)
// Get value while we're dealing with pointers
for ; v.Kind() == reflect.Ptr ; v = v.Elem() {}
for ; v.Kind() == reflect.Ptr; v = v.Elem() {
}
if v.Kind() != reflect.Struct {
return &v, fieldName, errors.New(fmt.Sprintf("parentStruct is not a struct! Kind: %s", v.Kind().String()))
@ -346,7 +349,7 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
typeOfV := v.Type()
if false {
for i := 0 ; i < v.NumField(); i++ {
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if f.Kind() == reflect.String {
fmt.Printf("%v=%v\n", v.Type().Field(i).Name, f.Interface())
@ -361,7 +364,7 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
// Loop through properties
for i, curF := range fs {
found = false
for j := 0 ; j < v.NumField() ; j++ {
for j := 0; j < v.NumField(); j++ {
if typeOfV.Field(j).Name == curF {
f = v.Field(j)
found = true
@ -372,7 +375,8 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
return &v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
}
for ; f.Kind() == reflect.Ptr ; f = f.Elem() {}
for ; f.Kind() == reflect.Ptr; f = f.Elem() {
}
/*fmt.Printf("v.kind() = %v\n", v.Kind().String())
fmt.Printf("v = %v\n", v)
@ -397,7 +401,6 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
return &v, fieldName, nil
}
/********************************************************************************
* TODO : Replace by getStructFieldValue
* Recurse into structure, returning reflect.Value of wanted field.
@ -411,7 +414,7 @@ func getStructField(parentStruct interface{}, fieldName string) (reflect.Value,
}
if false {
for i := 0 ; i < v.NumField(); i++ {
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if f.Kind() == reflect.String {
fmt.Printf("%v=%v\n", v.Type().Field(i).Name, f.Interface())
@ -442,22 +445,22 @@ func setStructFieldValue(parentStruct interface{}, propName string, propValue st
if val.CanSet() {
switch val.Kind() {
case reflect.String:
val.SetString(propValue)
case reflect.Int:
ival, err := strconv.ParseInt(propValue, 10, 64)
if err != nil {
return err
}
val.SetInt(ival)
case reflect.Bool:
bval, err := strconv.ParseBool(propValue)
if err != nil {
return err
}
val.SetBool(bval)
default:
return errors.New(fmt.Sprintf("Field is an unkown type: %s: %s", propName, val.Kind().String()))
case reflect.String:
val.SetString(propValue)
case reflect.Int:
ival, err := strconv.ParseInt(propValue, 10, 64)
if err != nil {
return err
}
val.SetInt(ival)
case reflect.Bool:
bval, err := strconv.ParseBool(propValue)
if err != nil {
return err
}
val.SetBool(bval)
default:
return errors.New(fmt.Sprintf("Field is an unkown type: %s: %s", propName, val.Kind().String()))
}
} else {
return errors.New(fmt.Sprintf("Field is not writable : %s", propName))
@ -480,9 +483,9 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
* Its value
*/
type Field struct {
Name string
MaxLen int
Value string
Name string
MaxLen int
Value string
}
type Line []Field
@ -501,7 +504,7 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
for i, f := range valsToDisplay {
a, f := getStructField(tj, f)
field := Field {
field := Field{
Name: f,
}
if a.FieldByName(f).IsValid() {
@ -530,7 +533,7 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
// Get real maximum length
maxlen := make([]int, len(valsToDisplay))
for i := 0; i< len(valsToDisplay); i++ {
for i := 0; i < len(valsToDisplay); i++ {
maxlen[i] = len(valsToDisplay[i])
}
for _, l := range out {
@ -567,13 +570,16 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
// Lets draw things on the screen!
// First, headers: 1st separator line
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("=") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("=")
}
fmt.Printf("+")
}
fmt.Printf("\n")
// Column names
for i, f := range out[0] {
if i == 0 {
@ -583,7 +589,7 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
* fmt.Printf(" %s", f.Name)
* for i := len(f.Name)+1 ; i < f.MaxLen+1 ; i++ { */
fmt.Printf(" %s", valsToDisplay[i])
for i := len(valsToDisplay[i])+1 ; i < f.MaxLen+1 ; i++ {
for i := len(valsToDisplay[i]) + 1; i < f.MaxLen+1; i++ {
fmt.Printf(" ")
}
fmt.Printf(" |")
@ -591,8 +597,12 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
// Finally separator line
fmt.Printf("\n")
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("=") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("=")
}
fmt.Printf("+")
}
fmt.Printf("\n")
@ -626,7 +636,7 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
fmt.Printf(" %s", f.Value)
}
// Complete with spaces to the max length
for i := len(f.Value)+1 ; i < f.MaxLen+1 ; i++ {
for i := len(f.Value) + 1; i < f.MaxLen+1; i++ {
fmt.Printf(" ")
}
fmt.Printf(" |")
@ -648,7 +658,7 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
//fmt.Printf(" %s", f.Value)
}
// Complete with spaces to the max length
for i := len(v)+1 ; i < f.MaxLen+1 ; i++ {
for i := len(v) + 1; i < f.MaxLen+1; i++ {
fmt.Printf(" ")
}
fmt.Printf(" |")
@ -658,8 +668,12 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
if !gNoLineSep {
fmt.Printf("\n")
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("-") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("-")
}
fmt.Printf("+")
}
}
@ -667,8 +681,12 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
}
if gNoLineSep {
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("-") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("-")
}
fmt.Printf("+")
}
}
@ -690,9 +708,9 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
* Its value
*/
type Field struct {
Name string
MaxLen int
Value string
Name string
MaxLen int
Value string
}
type Line []Field
@ -711,7 +729,7 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
for i, f := range valsToDisplay {
a, f := getStructField(tj, f)
field := Field {
field := Field{
Name: f,
}
if a.FieldByName(f).IsValid() {
@ -740,7 +758,7 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
// Get real maximum length
maxlen := make([]int, len(valsToDisplay))
for i := 0; i< len(valsToDisplay); i++ {
for i := 0; i < len(valsToDisplay); i++ {
maxlen[i] = len(valsToDisplay[i])
}
for _, l := range out {
@ -777,13 +795,16 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
// Lets draw things on the screen!
// First, headers: 1st separator line
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("=") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("=")
}
fmt.Printf("+")
}
fmt.Printf("\n")
// Column names
for i, f := range out[0] {
if i == 0 {
@ -793,7 +814,7 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
* fmt.Printf(" %s", f.Name)
* for i := len(f.Name)+1 ; i < f.MaxLen+1 ; i++ { */
fmt.Printf(" %s", valsToDisplay[i])
for i := len(valsToDisplay[i])+1 ; i < f.MaxLen+1 ; i++ {
for i := len(valsToDisplay[i]) + 1; i < f.MaxLen+1; i++ {
fmt.Printf(" ")
}
fmt.Printf(" |")
@ -801,8 +822,12 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
// Finally separator line
fmt.Printf("\n")
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("=") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("=")
}
fmt.Printf("+")
}
fmt.Printf("\n")
@ -819,24 +844,24 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
fmt.Printf("|")
}
// Special cases of value displaying
/* if f.Name == "JID" && f.Value == "0" {
fmt.Printf(" ")
} else if f.Name == "Ip4_addr" {
ia := strings.Split(f.Value, ",")
// If we have more than 1 value we need to finish this line, and store value for writing at the end of line loop
for i, inter := range ia {
if i > 0 {
supplines[f.Name] = inter
} else {
fmt.Printf(" %s", inter)
}
}
//fmt.Printf(" %s", strings.Split(strings.Split(f.Value, "|")[1], "/")[0])
} else {*/
fmt.Printf(" %s", f.Value)
/* if f.Name == "JID" && f.Value == "0" {
fmt.Printf(" ")
} else if f.Name == "Ip4_addr" {
ia := strings.Split(f.Value, ",")
// If we have more than 1 value we need to finish this line, and store value for writing at the end of line loop
for i, inter := range ia {
if i > 0 {
supplines[f.Name] = inter
} else {
fmt.Printf(" %s", inter)
}
}
//fmt.Printf(" %s", strings.Split(strings.Split(f.Value, "|")[1], "/")[0])
} else {*/
fmt.Printf(" %s", f.Value)
/*}*/
// Complete with spaces to the max length
for i := len(f.Value)+1 ; i < f.MaxLen+1 ; i++ {
for i := len(f.Value) + 1; i < f.MaxLen+1; i++ {
fmt.Printf(" ")
}
fmt.Printf(" |")
@ -858,7 +883,7 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
//fmt.Printf(" %s", f.Value)
}
// Complete with spaces to the max length
for i := len(v)+1 ; i < f.MaxLen+1 ; i++ {
for i := len(v) + 1; i < f.MaxLen+1; i++ {
fmt.Printf(" ")
}
fmt.Printf(" |")
@ -868,8 +893,12 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
if !gNoLineSep {
fmt.Printf("\n")
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("-") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("-")
}
fmt.Printf("+")
}
}
@ -877,8 +906,12 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
}
if gNoLineSep {
for i, f := range out[0] {
if i == 0 { fmt.Printf("+") }
for i := 0 ; i < f.MaxLen+2 ; i++ { fmt.Printf("-") }
if i == 0 {
fmt.Printf("+")
}
for i := 0; i < f.MaxLen+2; i++ {
fmt.Printf("-")
}
fmt.Printf("+")
}
}
@ -886,7 +919,6 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
fmt.Printf("\n")
}
/*****************************************************************************
*
* Sorting jails
@ -1767,8 +1799,8 @@ func initJailSortStruct() JailSort {
// jailSorter implements the Sort interface, sorting the jails within.
type jailSorter struct {
jails []Jail
less []jailLessFunc
jails []Jail
less []jailLessFunc
}
// Sort sorts the argument slice according to the less functions passed to JailsOrderedBy.
@ -1822,7 +1854,6 @@ func (js *jailSorter) Less(i, j int) bool {
return js.less[k](p, q)
}
/*****************************************************************************
*
* Sorting snapshots
@ -1882,8 +1913,8 @@ func initSnapshotSortStruct() SnapshotSort {
// snapshotSorter implements the Sort interface, sorting the jails within.
type snapshotSorter struct {
snapshots []Snapshot
less []snapshotLessFunc
snapshots []Snapshot
less []snapshotLessFunc
}
// Sort sorts the argument slice according to the less functions passed to OrderedBy.
@ -1923,12 +1954,12 @@ func (ss *snapshotSorter) Less(i, j int) bool {
for k = 0; k < len(ss.less)-1; k++ {
less := ss.less[k]
switch {
case less(p, q):
// p < q, so we have a decision.
return true
case less(q, p):
// p > q, so we have a decision.
return false
case less(p, q):
// p < q, so we have a decision.
return true
case less(q, p):
// p > q, so we have a decision.
return false
}
// p == q; try the next comparison.
}
@ -1937,7 +1968,6 @@ func (ss *snapshotSorter) Less(i, j int) bool {
return ss.less[k](p, q)
}
/*****************************************************************************
*
* Generic utilities
@ -1951,4 +1981,3 @@ func isStringInArray(strarr []string, searched string) bool {
}
return false
}

2
go.mod
View File

@ -3,6 +3,8 @@ module gocage
go 1.17
require (
github.com/c-robinson/iplib v1.0.3
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.2.1
github.com/spf13/viper v1.9.0
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420

View File

@ -1,10 +1,9 @@
package main
import (
"gocage/cmd"
"gocage/cmd"
)
func main () {
cmd.Execute()
func main() {
cmd.Execute()
}