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

@ -12,7 +12,7 @@ func ShellJail(args []string) error {
jailnames = append(jailnames, a)
}
}
for _, cj := range gJails {
for _, jn := range jailnames {
if strings.EqualFold(cj.Name, jn) {
@ -23,7 +23,7 @@ func ShellJail(args []string) error {
}
}
}
return nil
}
@ -34,6 +34,6 @@ func shellJail(jail Jail) error {
fmt.Errorf("Error executing %s: %s", cmd, err.Error())
return err
}
return nil
}

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}
@ -15,9 +15,9 @@ 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])
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])
}
/*****************************************************************************
@ -29,28 +29,28 @@ func (jh *JailHost) InitNetworkProperties() {
if err != nil {
panic(err)
}
for _, message := range messages {
route_message := message.(*route.RouteMessage)
addresses := route_message.Addrs
card_index := route_message.Index
if addresses[0].Family() == 2 {
var destination4, gateway4 *route.Inet4Addr
ok := false
if destination4, ok = addresses[0].(*route.Inet4Addr); !ok {
continue
}
if gateway4, ok = addresses[1].(*route.Inet4Addr); !ok {
continue
}
if destination4 == nil || gateway4 == nil {
continue
}
if destination4.IP == defaultRoute4 {
card, _ := net.InterfaceByIndex(card_index)
//fmt.Printf("Default IPv4 gateway is %v on card %s\n", Inet4AddrToString(*gateway4), card.Name)
@ -60,19 +60,19 @@ func (jh *JailHost) InitNetworkProperties() {
} else if addresses[0].Family() == 28 {
var destination6, gateway6 *route.Inet6Addr
ok := false
if destination6, ok = addresses[0].(*route.Inet6Addr); !ok {
continue
}
if gateway6, ok = addresses[1].(*route.Inet6Addr); !ok {
continue
}
if destination6 == nil || gateway6 == nil {
continue
}
if destination6.IP == defaultRoute6 && gateway6.IP != local6 {
card, _ := net.InterfaceByIndex(card_index)
//fmt.Printf("Default IPv6 gateway is %v on card %s\n", Inet6AddrToString(*gateway6), card.Name)
@ -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"
)
/********************************************************************************
@ -25,18 +25,18 @@ func ListJailsProps(args []string) {
fmt.Printf("Error allocating JailConfig: %s\n", err.Error())
return
}
conf.Config = jailconf
result = getStructFieldNames(conf, result, "")
for _, f := range result {
fmt.Printf("%s\n", f)
}
}
/********************************************************************************
* Get Jails from datastores. Store config and running metadata
* Get Jails from datastores. Store config and running metadata
* into gJails global var
*******************************************************************************/
func ListJails(args []string, display bool) {
@ -82,7 +82,6 @@ func ListJails(args []string, display bool) {
jails = gJails
}
/***************************************************************
/ Filter jails by names given on command line
/**************************************************************/
@ -112,10 +111,10 @@ 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))
}
// Get function by its name
fct, _, err := getStructFieldValue(js, fctName)
if err != nil {
@ -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
@ -197,8 +211,8 @@ func listJailsFromDirectory(dir string) ([]Jail) {
break
}
}
/* 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,17 +1,17 @@
package cmd
import (
"fmt"
"errors"
"fmt"
"reflect"
"strings"
"strconv"
"strings"
)
func GetJailProperties(args []string) {
var props []string
var jail Jail
if len(args) > 0 {
for i, a := range args {
// Last arg is the jail name
@ -21,20 +21,20 @@ func GetJailProperties(args []string) {
props = append(props, a)
}
}
}
}
if len(jail.Name) == 0 || len(args) == 0 {
// TODO : Show help
fmt.Printf("Error\n")
return
}
if isStringInArray(props, "all") {
var result []string
result = getStructFieldNames(jail, result, "")
props = result
}
for _, p := range props {
v, err := getJailProperty(&jail, p)
if err != nil {
@ -53,32 +53,32 @@ func getJailProperty(jail *Jail, propName string) (string, error) {
if err != nil {
return "", err
}
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()))
}
}
}
return "", errors.New(fmt.Sprintf("Jail not found: %s", jail.Name))
}
func SetJailProperties(args []string) {
type properties struct {
name string
value string
name string
value string
}
var jail Jail
var props []properties
if len(args) > 0 {
for i, a := range args {
// This is the jail name
@ -96,14 +96,14 @@ func SetJailProperties(args []string) {
}
}
}
}
}
if len(jail.Name) == 0 || len(args) == 0 {
// TODO : Show help
fmt.Printf("Error\n")
return
}
// Get jail by index to modify it
for i, _ := range gJails {
if gJails[i].Name == jail.Name {
@ -120,5 +120,3 @@ func SetJailProperties(args []string) {
}
}
}

View File

@ -1,69 +1,71 @@
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
gTimeZone string
gSnapshotName string
gHostVersion float64
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.
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.
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)
fmt.Printf("Use -h flag to display help\n")
},
}
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) {
ListJails(args, true)
},
}
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.",
@ -71,8 +73,8 @@ ex: gocage list srv-db srv-web`,
ListJailsProps(args)
},
}
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) {
@ -93,21 +95,21 @@ ex: gocage list srv-db srv-web`,
WriteConfigToDisk(false)
},
}
/* 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
@ -116,11 +118,11 @@ Multiples properties can be specified, separated with space (Ex: gocage set allo
WriteConfigToDisk(true)
},
}
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) {
@ -129,8 +131,8 @@ For all properties specify "all" (Ex: gocage get all myjail)`,
GetJailProperties(args)
},
}
snapshotCmd = &cobra.Command {
snapshotCmd = &cobra.Command{
Use: "snapshot",
Short: "snapshot jail",
Long: "Commands to manage jail snapshots. If no arguments given, ",
@ -138,11 +140,11 @@ 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) {
@ -151,32 +153,32 @@ You can specify multiple jails.`,
ListJailsSnapshots(args)
},
}
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)
CreateJailSnapshot(args)
},
}
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)
RollbackJailSnapshot(args)
},
}
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,24 +191,23 @@ 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")
listCmd.PersistentFlags().BoolVarP(&gNoLineSep, "nolinesep", "l", false, "Do not display line separator between jails")
listCmd.PersistentFlags().StringVarP(&gFilterJails, "filter", "f", "none", "Only display jails with these values. Ex: \"gocage list -f Config.Boot=1\" will only list started on boot jails")
listCmd.PersistentFlags().StringVarP(&gSortFields, "sort", "s", "none", "Display jails sorted by field values. Ex: \"gocage list -s +Name,-Config.Priority\" will sort jails by their decreasing name, then increasing start priority. 3 critera max supported.")
// This is local flag : Only available to gocage snapshot create command
snapshotCreateCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to create")
snapshotCreateCmd.MarkFlagRequired("snapname")
@ -214,8 +215,8 @@ func init() {
snapshotDeleteCmd.MarkFlagRequired("snapname")
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)
@ -228,7 +229,7 @@ func init() {
snapshotCmd.AddCommand(snapshotCreateCmd)
snapshotCmd.AddCommand(snapshotDeleteCmd)
snapshotCmd.AddCommand(snapshotRollbackCmd)
// Get FreeBSD version
out, err := executeCommand("freebsd-version")
if err != nil {
@ -236,7 +237,7 @@ func init() {
os.Exit(1)
}
gHostVersion, _ = strconv.ParseFloat(strings.Split(out, "-")[0], 32)
}
func initConfig() {
@ -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,10 +255,10 @@ 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 {
gUseSudo = viper.GetBool("sudo")
@ -292,21 +293,20 @@ func initConfig() {
}
}
/********************************************************************************
* Write jails config which been updated to disk.
* If changeauto not set, values which are in "auto" mode on disk
* won't be overwritten (p.ex defaultrouter wont be overwritten with current
* If changeauto not set, values which are in "auto" mode on disk
* won't be overwritten (p.ex defaultrouter wont be overwritten with current
* default route, so if route change on jailhost this will reflect on jail next
* start)
*******************************************************************************/
func WriteConfigToDisk(changeauto bool) {
for _, j := range gJails {
if j.ConfigUpdated {
// we will manipulate properties so get a copy
jc := j.Config
if changeauto == false {
// Overwrite "auto" properties
ondiskjc, err := getJailConfig(j.ConfigPath)
@ -317,7 +317,7 @@ func WriteConfigToDisk(changeauto bool) {
// If "auto" then keep it that way before writing ondiskjc to disk
var properties []string
properties = getStructFieldNames(ondiskjc, properties, "")
for _, p := range properties {
v, _, err := getStructFieldValue(ondiskjc, p)
if err != nil {
@ -332,7 +332,7 @@ func WriteConfigToDisk(changeauto bool) {
}
}
}
marshaled, err := json.MarshalIndent(jc, "", " ")
if err != nil {
fmt.Printf("ERROR marshaling config: %s\n", err.Error())
@ -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"
)
/********************************************************************************
@ -16,13 +16,13 @@ import (
func ListJailsSnapshots(args []string) {
var jailNames []string
var snapshots []Snapshot
if len(args) > 0 {
for _, a := range args {
jailNames = append(jailNames, a)
}
}
}
if len(jailNames) == 0 || len(args) == 0 {
for _, j := range gJails {
snapshots = append(snapshots, listJailSnapshots(j)...)
@ -36,16 +36,15 @@ 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
*******************************************************************************/
func listJailSnapshots(jail Jail) []Snapshot {
var snapshots []Snapshot
// 1. List all datasets
// TODO : Include mounted filesystems?
rs := strings.Split(jail.RootPath, "/")
@ -56,10 +55,10 @@ func listJailSnapshots(jail Jail) []Snapshot {
fmt.Printf("Error: %s\n", err.Error())
return snapshots
}
dateLayout := "Mon Jan _2 15:04 2006"
loc, _ := time.LoadLocation(gTimeZone)
for _, line := range strings.Split(out, "\n") {
if len(line) > 0 {
ls := strings.Split(line, "\t")
@ -71,37 +70,36 @@ func listJailSnapshots(jail Jail) []Snapshot {
}
// Get subdir to append to snapshot name
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})
}
}
// Sort snapshots by creation date
ss := initSnapshotSortStruct()
SnapshotsOrderedBy(ss.CreationInc).Sort(snapshots)
return snapshots
}
/********************************************************************************
* Create snapshot for jail(s)
*******************************************************************************/
func CreateJailSnapshot(args []string) {
var jailNames []string
if len(args) > 0 {
for _, a := range args {
jailNames = append(jailNames, a)
}
}
}
for _, cj := range gJails {
for _, jn := range jailNames {
if strings.EqualFold(cj.Name, jn) {
@ -125,7 +123,7 @@ func createJailSnapshot(jail Jail) error {
return err
}
fmt.Printf("Snapshot %s@%s created\n", rootDataset, gSnapshotName)
return nil
}
@ -134,13 +132,13 @@ func createJailSnapshot(jail Jail) error {
*******************************************************************************/
func DeleteJailSnapshot(args []string) {
var jailNames []string
if len(args) > 0 {
for _, a := range args {
jailNames = append(jailNames, a)
}
}
}
for _, cj := range gJails {
for _, jn := range jailNames {
if strings.EqualFold(cj.Name, jn) {
@ -155,7 +153,7 @@ func DeleteJailSnapshot(args []string) {
*******************************************************************************/
func deleteJailSnapshot(jail Jail) error {
var snaptodel []string
// Get all recursive snapshots
rs := strings.Split(jail.RootPath, "/")
rootDataset := fmt.Sprintf("%s%s", jail.Zpool, strings.Join(rs[:len(rs)-1], "/"))
@ -165,18 +163,18 @@ func deleteJailSnapshot(jail Jail) error {
fmt.Printf("Error: listing snapshots: %s\n", err.Error())
return nil
}
for _, line := range strings.Split(out, "\n") {
if len(line) > 0 {
ls := strings.Split(line, "@")
matched, _ := regexp.Match(fmt.Sprintf("^%s(\\/.*)?$", gSnapshotName), []byte(ls[1]))
if matched {
snaptodel = append(snaptodel, strings.Join(ls, "@"))
}
}
}
for _, s := range snaptodel {
cmd := fmt.Sprintf("zfs destroy %s", s)
_, err := executeCommand(cmd)
@ -186,19 +184,19 @@ func deleteJailSnapshot(jail Jail) error {
}
fmt.Printf("Snapshot %s deleted\n", s)
}
return nil
}
func RollbackJailSnapshot(args []string) error {
var jailNames []string
if len(args) > 0 {
for _, a := range args {
jailNames = append(jailNames, a)
}
}
}
for _, cj := range gJails {
for _, jn := range jailNames {
if strings.EqualFold(cj.Name, jn) {
@ -206,7 +204,7 @@ func RollbackJailSnapshot(args []string) error {
}
}
}
return nil
}
@ -216,7 +214,7 @@ func RollbackJailSnapshot(args []string) error {
*******************************************************************************/
func rollbackJailSnapshot(jail Jail) error {
var snaptorb []string
if jail.Running {
fmt.Printf("Jail should be stoped to rollback, should we stop and rollback? (y/n)\n")
scanr := bufio.NewScanner(os.Stdin)
@ -231,7 +229,7 @@ func rollbackJailSnapshot(jail Jail) error {
}
}
}
// We need to rollback parent and childs
// Get all recursive snapshots
rs := strings.Split(jail.RootPath, "/")
@ -242,18 +240,18 @@ func rollbackJailSnapshot(jail Jail) error {
fmt.Printf("Error: listing snapshots: %s\n", err.Error())
return err
}
for _, line := range strings.Split(out, "\n") {
if len(line) > 0 {
ls := strings.Split(line, "@")
matched, _ := regexp.Match(fmt.Sprintf("^%s(\\/.*)?$", gSnapshotName), []byte(ls[1]))
if matched {
snaptorb = append(snaptorb, strings.Join(ls, "@"))
}
}
}
for _, s := range snaptorb {
cmd := fmt.Sprintf("zfs rollback -r %s", s)
_, err := executeCommand(cmd)
@ -263,6 +261,6 @@ func rollbackJailSnapshot(jail Jail) error {
}
}
fmt.Printf("Jail is back to %s\n", gSnapshotName)
return nil
}

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?!
@ -34,7 +37,7 @@ func mountProcFs(jail *Jail) error {
if err != nil {
return errors.New(fmt.Sprintf("Error mounting procfs on %s/proc: %s", jail.RootPath, err.Error()))
}
return nil
}
@ -52,7 +55,7 @@ func mountLinProcFs(jail *Jail) error {
if err != nil {
return errors.New(fmt.Sprintf("Error mounting linprocfs on %s: %s", ldir, err.Error()))
}
return nil
}
@ -62,7 +65,7 @@ func mountDevFs(jail *Jail) error {
if err != nil {
return errors.New(fmt.Sprintf("Error mounting devfs on %s/dev: %s", jail.RootPath, err.Error()))
}
return nil
}
@ -73,17 +76,17 @@ func mountFdescFs(jail *Jail) error {
jail.Config.Mount_fdescfs = 0
// Tag config so it will be synced on disk
jail.ConfigUpdated = true
// Should we consider this an error?
return nil
}
cmd := fmt.Sprintf("mount -t fdescfs descfs %s/dev/fd", jail.RootPath)
_, err := executeCommand(cmd)
if err != nil {
return errors.New(fmt.Sprintf("Error mounting fdescfs on %s/dev/fd: %s", jail.RootPath, err.Error()))
}
return nil
}
@ -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
@ -172,7 +174,7 @@ func mountAllJailFsFromHost(jail *Jail) error {
if gHostVersion < 12 {
if jail.Config.Allow_mlock > 0 {
jail.Config.Allow_mlock = 0
jail.Config.Allow_mlock = 0
jail.ConfigUpdated = true
/* WIP
err = setJailProperty(jail, "Config.Allow_mlock", "0")
@ -186,11 +188,10 @@ func mountAllJailFsFromHost(jail *Jail) error {
}
}
return nil
return nil
}
// TODO
// TODO
func prepareJailedZfsDatasets(jail *Jail) error {
if jail.Config.Jail_zfs > 0 {
// For jail to mount filesystem, enforce_statfs should be 1 or lower (2 is the default)
@ -229,18 +230,18 @@ 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)
func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc, error) {
var res []NatDesc
regx := `(tcp|udp)\(([0-9]{1,5}(?:-[0-9]{1,5})?):([0-9]{1,5}(?:-[0-9]{1,5})?)\)`
re := regexp.MustCompile(regx)
for _, match := range re.FindAllStringSubmatch(nat_forwards, -1) {
if strings.Contains(match[2], "-") == true && decompose_range == true {
sjrange, err := strconv.Atoi(strings.Split(match[2], "-")[0])
@ -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,16 +272,226 @@ 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)
}
}
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,10 +520,11 @@ 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)
for i, rj := range gJails {
if rj.Name == j {
// Get jail reference, not a copy of it; So we can modify attributes
@ -324,12 +536,12 @@ func StartJail(args []string) {
fmt.Printf("Jail not found: %s\n", j)
continue
}
if cj.Running == true {
fmt.Printf("Jail %s is already running!\n", cj.Name)
continue
}
if len(cj.Config.Hostid) > 0 && cj.Config.Hostid_strict_check > 0 {
hostid, err := ioutil.ReadFile("/etc/hostid")
if err != nil {
@ -342,10 +554,10 @@ func StartJail(args []string) {
return
}
}
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))
}
@ -353,10 +565,10 @@ func StartJail(args []string) {
props_missing = append(props_missing, fmt.Sprintf("%s: dhcp requires vnet", cj.Name))
}
}
// tcp(80:8080),tcp(3300-3310:33000-33010)
if cj.Config.Nat > 0 && strings.EqualFold(cj.Config.Nat_forwards, "none") == false {
// If NAT && port forwarding is enabled, check that port does not conflict
// If NAT && port forwarding is enabled, check that port does not conflict
// with another running jail
for _, j := range gJails {
if j.Running == false || strings.EqualFold(j.Config.Nat_forwards, "none") == false || j.Config.Nat != 1 {
@ -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
}
}
@ -384,27 +596,68 @@ func StartJail(args []string) {
}
}
}
if cj.Config.Nat > 0 && strings.EqualFold(cj.Config.Nat_interface, "none") == true {
var jhost JailHost
cj.Config.Nat_interface = jhost.GetDefaultInterface()
cj.ConfigUpdated = true
}
if cj.Config.Vnet > 0 && strings.EqualFold(cj.Config.Defaultrouter, "auto") == true {
var jhost JailHost
cj.Config.Defaultrouter = jhost.GetDefaultGateway4()
// "auto" default Gateway should not be updated to support jailhost route change
}
if cj.Config.Vnet > 0 && strings.EqualFold(cj.Config.Defaultrouter6, "auto") == true {
var jhost JailHost
cj.Config.Defaultrouter6 = jhost.GetDefaultGateway6()
// "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)
if err != nil {
@ -412,7 +665,7 @@ func StartJail(args []string) {
} else {
fmt.Printf(" > Mount special filesystems: OK\n")
}
if cj.Config.Jail_zfs > 0 {
fmt.Printf(" > Prepare ZFS Datasets:\n")
err := prepareJailedZfsDatasets(cj)
@ -422,77 +675,116 @@ func StartJail(args []string) {
fmt.Printf(" > Prepare ZFS Datasets: OK\n")
}
}
/*
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{""})
// 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)
// 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)
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")
}
}
// CONTINUE HERE
// See https://github.com/iocage/iocage/blob/e94863d4c54f02523fb09e62e48be7db9ac92eda/iocage_lib/ioc_start.py:401
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")
/*
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 cj.Config.Vnet > 0 && len(cj.Config.Ip4_addr) > 0 {
fmt.Printf(" > Destroy VNet interfaces:\n")
err := destroyVNetInterfaces(cj)
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(" > Destroy VNet interfaces: OK\n")
fmt.Printf(" > Remove devfsruleset %s: OK\n", cj.Config.Devfs_ruleset)
}
}
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)
}
*/
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
@ -75,11 +74,10 @@ func umountAndUnjailZFS(jail *Jail) error {
fmt.Printf("ERROR unjailing %s/%s: %s\n", jail.Zpool, ds[len(ds)-1], err.Error())
return err
}
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 {
@ -230,8 +226,8 @@ func StopJail(args []string) {
fmt.Printf(" > Execute prestop: OK\n")
}
}
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 {
@ -260,7 +256,7 @@ func StopJail(args []string) {
fmt.Printf(" > Destroy VNet interfaces: OK\n")
}
}
/*fmt.Printf(" > Remove devfsruleset %s:\n", cj.Config.Devfs_ruleset)
err = deleteDevfsRuleset(cj)
if err != nil {
@ -268,7 +264,7 @@ func StopJail(args []string) {
} 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 {
@ -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
}

File diff suppressed because it is too large Load Diff

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