WIP on start, go fmt on *
This commit is contained in:
		@ -12,7 +12,7 @@ func ShellJail(args []string) error {
 | 
				
			|||||||
			jailnames = append(jailnames, a)
 | 
								jailnames = append(jailnames, a)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, cj := range gJails {
 | 
						for _, cj := range gJails {
 | 
				
			||||||
		for _, jn := range jailnames {
 | 
							for _, jn := range jailnames {
 | 
				
			||||||
			if strings.EqualFold(cj.Name, jn) {
 | 
								if strings.EqualFold(cj.Name, jn) {
 | 
				
			||||||
@ -23,7 +23,7 @@ func ShellJail(args []string) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -34,6 +34,6 @@ func shellJail(jail Jail) error {
 | 
				
			|||||||
		fmt.Errorf("Error executing %s: %s", cmd, err.Error())
 | 
							fmt.Errorf("Error executing %s: %s", cmd, err.Error())
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,8 @@ package cmd
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"golang.org/x/net/route"
 | 
						"golang.org/x/net/route"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var defaultRoute4 = [4]byte{0, 0, 0, 0}
 | 
					var defaultRoute4 = [4]byte{0, 0, 0, 0}
 | 
				
			||||||
@ -15,9 +15,9 @@ func Inet4AddrToString(ip4 route.Inet4Addr) string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Inet6AddrToString(ip6 route.Inet6Addr) 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", 
 | 
						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[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[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 {
 | 
						if err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, message := range messages {
 | 
						for _, message := range messages {
 | 
				
			||||||
		route_message := message.(*route.RouteMessage)
 | 
							route_message := message.(*route.RouteMessage)
 | 
				
			||||||
		addresses := route_message.Addrs
 | 
							addresses := route_message.Addrs
 | 
				
			||||||
		card_index := route_message.Index
 | 
							card_index := route_message.Index
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if addresses[0].Family() == 2 {
 | 
							if addresses[0].Family() == 2 {
 | 
				
			||||||
			var destination4, gateway4 *route.Inet4Addr
 | 
								var destination4, gateway4 *route.Inet4Addr
 | 
				
			||||||
			ok := false
 | 
								ok := false
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if destination4, ok = addresses[0].(*route.Inet4Addr); !ok {
 | 
								if destination4, ok = addresses[0].(*route.Inet4Addr); !ok {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if gateway4, ok = addresses[1].(*route.Inet4Addr); !ok {
 | 
								if gateway4, ok = addresses[1].(*route.Inet4Addr); !ok {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if destination4 == nil || gateway4 == nil {
 | 
								if destination4 == nil || gateway4 == nil {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if destination4.IP == defaultRoute4 {
 | 
								if destination4.IP == defaultRoute4 {
 | 
				
			||||||
				card, _ := net.InterfaceByIndex(card_index)
 | 
									card, _ := net.InterfaceByIndex(card_index)
 | 
				
			||||||
				//fmt.Printf("Default IPv4 gateway is %v on card %s\n", Inet4AddrToString(*gateway4), card.Name)
 | 
									//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 {
 | 
							} else if addresses[0].Family() == 28 {
 | 
				
			||||||
			var destination6, gateway6 *route.Inet6Addr
 | 
								var destination6, gateway6 *route.Inet6Addr
 | 
				
			||||||
			ok := false
 | 
								ok := false
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if destination6, ok = addresses[0].(*route.Inet6Addr); !ok {
 | 
								if destination6, ok = addresses[0].(*route.Inet6Addr); !ok {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if gateway6, ok = addresses[1].(*route.Inet6Addr); !ok {
 | 
								if gateway6, ok = addresses[1].(*route.Inet6Addr); !ok {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if destination6 == nil || gateway6 == nil {
 | 
								if destination6 == nil || gateway6 == nil {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if destination6.IP == defaultRoute6 && gateway6.IP != local6 {
 | 
								if destination6.IP == defaultRoute6 && gateway6.IP != local6 {
 | 
				
			||||||
				card, _ := net.InterfaceByIndex(card_index)
 | 
									card, _ := net.InterfaceByIndex(card_index)
 | 
				
			||||||
				//fmt.Printf("Default IPv6 gateway is %v on card %s\n", Inet6AddrToString(*gateway6), card.Name)
 | 
									//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 {
 | 
					func (jh *JailHost) GetDefaultInterface() string {
 | 
				
			||||||
	if len(jh.default_interface) == 0 {
 | 
						if len(jh.default_interface) == 0 {
 | 
				
			||||||
		jh.InitNetworkProperties()
 | 
							jh.InitNetworkProperties()
 | 
				
			||||||
@ -91,7 +90,6 @@ func (jh *JailHost) GetDefaultInterface() string {
 | 
				
			|||||||
	return jh.default_interface
 | 
						return jh.default_interface
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
func (jh *JailHost) GetDefaultGateway4() string {
 | 
					func (jh *JailHost) GetDefaultGateway4() string {
 | 
				
			||||||
	if len(jh.default_gateway4) == 0 {
 | 
						if len(jh.default_gateway4) == 0 {
 | 
				
			||||||
		jh.InitNetworkProperties()
 | 
							jh.InitNetworkProperties()
 | 
				
			||||||
@ -99,11 +97,9 @@ func (jh *JailHost) GetDefaultGateway4() string {
 | 
				
			|||||||
	return jh.default_gateway4
 | 
						return jh.default_gateway4
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (jh *JailHost) GetDefaultGateway6() string {
 | 
				
			||||||
func(jh *JailHost) GetDefaultGateway6() string {
 | 
					 | 
				
			||||||
	if len(jh.default_gateway6) == 0 {
 | 
						if len(jh.default_gateway6) == 0 {
 | 
				
			||||||
		jh.InitNetworkProperties()
 | 
							jh.InitNetworkProperties()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return jh.default_gateway6
 | 
						return jh.default_gateway6
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										113
									
								
								cmd/list.go
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								cmd/list.go
									
									
									
									
									
								
							@ -1,15 +1,15 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/spf13/viper"
 | 
				
			||||||
 | 
						"gocage/jail"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"strings"
 | 
						"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())
 | 
							fmt.Printf("Error allocating JailConfig: %s\n", err.Error())
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	conf.Config = jailconf
 | 
						conf.Config = jailconf
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	result = getStructFieldNames(conf, result, "")
 | 
						result = getStructFieldNames(conf, result, "")
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, f := range result {
 | 
						for _, f := range result {
 | 
				
			||||||
		fmt.Printf("%s\n", f)
 | 
							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
 | 
					 *   into gJails global var
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
func ListJails(args []string, display bool) {
 | 
					func ListJails(args []string, display bool) {
 | 
				
			||||||
@ -82,7 +82,6 @@ func ListJails(args []string, display bool) {
 | 
				
			|||||||
		jails = gJails
 | 
							jails = gJails
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/***************************************************************
 | 
						/***************************************************************
 | 
				
			||||||
	/   Filter jails by names given on command line
 | 
						/   Filter jails by names given on command line
 | 
				
			||||||
	/**************************************************************/
 | 
						/**************************************************************/
 | 
				
			||||||
@ -112,10 +111,10 @@ func ListJails(args []string, display bool) {
 | 
				
			|||||||
			var fctName string
 | 
								var fctName string
 | 
				
			||||||
			if strings.HasPrefix(c, "-") {
 | 
								if strings.HasPrefix(c, "-") {
 | 
				
			||||||
				fctName = fmt.Sprintf("%sDec", strings.Replace(c, "-", "", 1))
 | 
									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))
 | 
									fctName = fmt.Sprintf("%sInc", strings.Replace(c, "+", "", 1))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			// Get function by its name
 | 
								// Get function by its name
 | 
				
			||||||
			fct, _, err := getStructFieldValue(js, fctName)
 | 
								fct, _, err := getStructFieldValue(js, fctName)
 | 
				
			||||||
			if err != nil {
 | 
								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)
 | 
									fmt.Printf("ERROR getting JailSort struct field %s. Please check the field name: %s\n", fctName, fieldName)
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			switch i+1 {
 | 
								switch i + 1 {
 | 
				
			||||||
				case 1:	fct1 = fct
 | 
								case 1:
 | 
				
			||||||
				case 2: fct2 = fct
 | 
									fct1 = fct
 | 
				
			||||||
				case 3: fct3 = fct
 | 
								case 2:
 | 
				
			||||||
 | 
									fct2 = fct
 | 
				
			||||||
 | 
								case 3:
 | 
				
			||||||
 | 
									fct3 = fct
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch len(strings.Split(gSortFields, ",")) {
 | 
							switch len(strings.Split(gSortFields, ",")) {
 | 
				
			||||||
			case 1:
 | 
							case 1:
 | 
				
			||||||
				JailsOrderedBy(fct1.Interface().(jailLessFunc)).Sort(jails)
 | 
								JailsOrderedBy(fct1.Interface().(jailLessFunc)).Sort(jails)
 | 
				
			||||||
			case 2:
 | 
							case 2:
 | 
				
			||||||
				JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc)).Sort(jails)
 | 
								JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc)).Sort(jails)
 | 
				
			||||||
			case 3:
 | 
							case 3:
 | 
				
			||||||
				JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc), fct3.Interface().(jailLessFunc)).Sort(jails)
 | 
								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) {
 | 
					func listJailsFromDatastore(datastore string) {
 | 
				
			||||||
	fileInfo, err := os.Stat(datastore)
 | 
						fileInfo, err := os.Stat(datastore)
 | 
				
			||||||
	if err != nil { log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", datastore)) }
 | 
						if err != nil {
 | 
				
			||||||
	if fileInfo.IsDir() == false { log.Fatalln(fmt.Sprintf("%s is not a directory", datastore)) }
 | 
							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
 | 
						// A datastore have to contain a "jails" directory
 | 
				
			||||||
	jailsDir := fmt.Sprintf("%s/jails", datastore)
 | 
						jailsDir := fmt.Sprintf("%s/jails", datastore)
 | 
				
			||||||
	fileInfo, err = os.Stat(jailsDir)
 | 
						fileInfo, err = os.Stat(jailsDir)
 | 
				
			||||||
	if err != nil { log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", jailsDir)) }
 | 
						if err != nil {
 | 
				
			||||||
	if fileInfo.IsDir() == false { log.Fatalln(fmt.Sprintf("%s is not a directory", jailsDir)) }
 | 
							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)
 | 
						listJailsFromDirectory(jailsDir)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func listJailsFromDirectory(dir string) []Jail {
 | 
				
			||||||
func listJailsFromDirectory(dir string) ([]Jail) {
 | 
					 | 
				
			||||||
	files, err := ioutil.ReadDir(dir)
 | 
						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 {
 | 
						for _, fi := range files {
 | 
				
			||||||
		if fi.IsDir() == true {
 | 
							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")
 | 
								jailConfPath := fmt.Sprintf("%s/%s/%s", dir, fi.Name(), "config.json")
 | 
				
			||||||
			jailConf, err := getJailConfig(jailConfPath)
 | 
								jailConf, err := getJailConfig(jailConfPath)
 | 
				
			||||||
			if err != nil { log.Println("ERROR reading jail config for %s", 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,
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 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()
 | 
								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 {
 | 
								for _, rj := range rjails {
 | 
				
			||||||
				if rj.Path == j.RootPath {
 | 
									if rj.Path == j.RootPath {
 | 
				
			||||||
					j.JID = rj.Jid
 | 
										j.JID = rj.Jid
 | 
				
			||||||
@ -197,8 +211,8 @@ func listJailsFromDirectory(dir string) ([]Jail) {
 | 
				
			|||||||
					break
 | 
										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))
 | 
								out, err := executeCommand(fmt.Sprintf("zfs list -H -o name %s", j.RootPath))
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				fmt.Printf("ERROR getting dataset from %s: %s\n", j.RootPath, err.Error())
 | 
									fmt.Printf("ERROR getting dataset from %s: %s\n", j.RootPath, err.Error())
 | 
				
			||||||
@ -213,10 +227,11 @@ func listJailsFromDirectory(dir string) ([]Jail) {
 | 
				
			|||||||
	return gJails
 | 
						return gJails
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
func getJailConfig(jailConfigPath string) (JailConfig, error) {
 | 
					func getJailConfig(jailConfigPath string) (JailConfig, error) {
 | 
				
			||||||
	content, err := ioutil.ReadFile(jailConfigPath)
 | 
						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
 | 
						// Mandatory constructor to init default values
 | 
				
			||||||
	jc, err := NewJailConfig()
 | 
						jc, err := NewJailConfig()
 | 
				
			||||||
@ -224,7 +239,9 @@ func getJailConfig(jailConfigPath string) (JailConfig, error) {
 | 
				
			|||||||
		return jc, err
 | 
							return jc, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = json.Unmarshal([]byte(content), &jc)
 | 
						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
 | 
						return jc, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,17 +1,17 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetJailProperties(args []string) {
 | 
					func GetJailProperties(args []string) {
 | 
				
			||||||
	var props []string
 | 
						var props []string
 | 
				
			||||||
	var jail Jail
 | 
						var jail Jail
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
		for i, a := range args {
 | 
							for i, a := range args {
 | 
				
			||||||
			// Last arg is the jail name
 | 
								// Last arg is the jail name
 | 
				
			||||||
@ -21,20 +21,20 @@ func GetJailProperties(args []string) {
 | 
				
			|||||||
				props = append(props, a)
 | 
									props = append(props, a)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} 
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(jail.Name) == 0 || len(args) == 0 {
 | 
						if len(jail.Name) == 0 || len(args) == 0 {
 | 
				
			||||||
		// TODO : Show help
 | 
							// TODO : Show help
 | 
				
			||||||
		fmt.Printf("Error\n")
 | 
							fmt.Printf("Error\n")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if isStringInArray(props, "all") {
 | 
						if isStringInArray(props, "all") {
 | 
				
			||||||
		var result []string
 | 
							var result []string
 | 
				
			||||||
		result = getStructFieldNames(jail, result, "")
 | 
							result = getStructFieldNames(jail, result, "")
 | 
				
			||||||
		props = result
 | 
							props = result
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, p := range props {
 | 
						for _, p := range props {
 | 
				
			||||||
		v, err := getJailProperty(&jail, p)
 | 
							v, err := getJailProperty(&jail, p)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@ -53,32 +53,32 @@ func getJailProperty(jail *Jail, propName string) (string, error) {
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return "", err
 | 
									return "", err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			switch val.Kind() {
 | 
								switch val.Kind() {
 | 
				
			||||||
				case reflect.String:
 | 
								case reflect.String:
 | 
				
			||||||
					return val.String(), nil
 | 
									return val.String(), nil
 | 
				
			||||||
				case reflect.Int:
 | 
								case reflect.Int:
 | 
				
			||||||
					return strconv.FormatInt(val.Int(), 10), nil
 | 
									return strconv.FormatInt(val.Int(), 10), nil
 | 
				
			||||||
				case reflect.Bool:
 | 
								case reflect.Bool:
 | 
				
			||||||
					return strconv.FormatBool(val.Bool()), nil
 | 
									return strconv.FormatBool(val.Bool()), nil
 | 
				
			||||||
				default:
 | 
								default:
 | 
				
			||||||
					return "", errors.New(fmt.Sprintf("Error: Unknown type for property %s: %s\n", propName, val.Kind()))
 | 
									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))
 | 
						return "", errors.New(fmt.Sprintf("Jail not found: %s", jail.Name))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SetJailProperties(args []string) {
 | 
					func SetJailProperties(args []string) {
 | 
				
			||||||
	type properties struct {
 | 
						type properties struct {
 | 
				
			||||||
		name	string
 | 
							name  string
 | 
				
			||||||
		value	string
 | 
							value string
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	var jail Jail
 | 
						var jail Jail
 | 
				
			||||||
	var props []properties
 | 
						var props []properties
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
		for i, a := range args {
 | 
							for i, a := range args {
 | 
				
			||||||
			// This is the jail name
 | 
								// This is the jail name
 | 
				
			||||||
@ -96,14 +96,14 @@ func SetJailProperties(args []string) {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} 
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(jail.Name) == 0 || len(args) == 0 {
 | 
						if len(jail.Name) == 0 || len(args) == 0 {
 | 
				
			||||||
		// TODO : Show help
 | 
							// TODO : Show help
 | 
				
			||||||
		fmt.Printf("Error\n")
 | 
							fmt.Printf("Error\n")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// Get jail by index to modify it
 | 
						// Get jail by index to modify it
 | 
				
			||||||
	for i, _ := range gJails {
 | 
						for i, _ := range gJails {
 | 
				
			||||||
		if gJails[i].Name == jail.Name {
 | 
							if gJails[i].Name == jail.Name {
 | 
				
			||||||
@ -120,5 +120,3 @@ func SetJailProperties(args []string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										166
									
								
								cmd/root.go
									
									
									
									
									
								
							
							
						
						
									
										166
									
								
								cmd/root.go
									
									
									
									
									
								
							@ -1,69 +1,71 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
	"github.com/spf13/viper"
 | 
						"github.com/spf13/viper"
 | 
				
			||||||
 | 
						// TODO : Use log
 | 
				
			||||||
 | 
						//log "github.com/sirupsen/logrus"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	gVersion = "0.25"
 | 
						gVersion = "0.26a"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	gJails			[]Jail
 | 
						gJails []Jail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gUseSudo		bool
 | 
						gUseSudo bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gConfigFile		string
 | 
						gConfigFile     string
 | 
				
			||||||
	gDisplayColumns	string
 | 
						gDisplayColumns string
 | 
				
			||||||
	gFilterJails	string
 | 
						gFilterJails    string
 | 
				
			||||||
	gSortFields		string
 | 
						gSortFields     string
 | 
				
			||||||
	gNoLineSep		bool
 | 
						gNoLineSep      bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gHostVersion	float64
 | 
						gHostVersion float64
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	gTimeZone		string
 | 
					 | 
				
			||||||
	gSnapshotName	string
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rootCmd = & cobra.Command {
 | 
						gTimeZone     string
 | 
				
			||||||
		Use:    "gocage",
 | 
						gSnapshotName string
 | 
				
			||||||
		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.`,
 | 
					It support iocage jails and can coexist with iocage.`,
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
			fmt.Printf("GoCage v.%s on FreeBSD %.1f\n", gVersion, gHostVersion)
 | 
								fmt.Printf("GoCage v.%s on FreeBSD %.1f\n", gVersion, gHostVersion)
 | 
				
			||||||
			fmt.Printf("Use -h flag to display help\n")
 | 
								fmt.Printf("Use -h flag to display help\n")
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	versionCmd = &cobra.Command {
 | 
						versionCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "version",
 | 
							Use:   "version",
 | 
				
			||||||
		Short: "Print the version number of GoCage",
 | 
							Short: "Print the version number of GoCage",
 | 
				
			||||||
		Long:  `Let this show you how much fail I had to get this *cough* perfect`,
 | 
							Long:  `Let this show you how much fail I had to get this *cough* perfect`,
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
			fmt.Printf("GoCage v.%s on FreeBSD %.1f\n", gVersion, gHostVersion)
 | 
								fmt.Printf("GoCage v.%s on FreeBSD %.1f\n", gVersion, gHostVersion)
 | 
				
			||||||
	    },
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	listCmd = &cobra.Command {
 | 
						listCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "list",
 | 
							Use:   "list",
 | 
				
			||||||
		Short: "Print jails",
 | 
							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
 | 
					Jail list can be restricted by adding name on command line
 | 
				
			||||||
ex: gocage list srv-db srv-web`,
 | 
					ex: gocage list srv-db srv-web`,
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
			ListJails(args, true)
 | 
								ListJails(args, true)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	listPropsCmd = &cobra.Command {
 | 
						listPropsCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "properties",
 | 
							Use:   "properties",
 | 
				
			||||||
		Short: "Print jails properties",
 | 
							Short: "Print jails properties",
 | 
				
			||||||
		Long:  "Display jails properties. You can use properties to filter, get or set them.",
 | 
							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)
 | 
								ListJailsProps(args)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	stopCmd = &cobra.Command {
 | 
						stopCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "stop",
 | 
							Use:   "stop",
 | 
				
			||||||
		Short: "stop jail",
 | 
							Short: "stop jail",
 | 
				
			||||||
		Long:  "shutdown jail",
 | 
							Long:  "shutdown jail",
 | 
				
			||||||
@ -83,7 +85,7 @@ ex: gocage list srv-db srv-web`,
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	startCmd = &cobra.Command {
 | 
						startCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "start",
 | 
							Use:   "start",
 | 
				
			||||||
		Short: "start jail",
 | 
							Short: "start jail",
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
@ -93,21 +95,21 @@ ex: gocage list srv-db srv-web`,
 | 
				
			|||||||
			WriteConfigToDisk(false)
 | 
								WriteConfigToDisk(false)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
/*	shellCmd = &cobra.Command {
 | 
						/*	shellCmd = &cobra.Command {
 | 
				
			||||||
		Use:   "console",
 | 
								Use:   "console",
 | 
				
			||||||
		Short: "Execute shell on jail",
 | 
								Short: "Execute shell on jail",
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
								Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
			// Load inventory
 | 
									// Load inventory
 | 
				
			||||||
			ListJails(args, false)
 | 
									ListJails(args, false)
 | 
				
			||||||
			ShellJail(args)
 | 
									ShellJail(args)
 | 
				
			||||||
		},
 | 
								},
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
*/	
 | 
						*/
 | 
				
			||||||
	setCmd = &cobra.Command {
 | 
						setCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "set",
 | 
							Use:   "set",
 | 
				
			||||||
		Short: "Set a jail property",
 | 
							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)`,
 | 
					Multiples properties can be specified, separated with space (Ex: gocage set allow_mlock=1 boot=1 myjail)`,
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
			// Load inventory
 | 
								// Load inventory
 | 
				
			||||||
@ -116,11 +118,11 @@ Multiples properties can be specified, separated with space (Ex: gocage set allo
 | 
				
			|||||||
			WriteConfigToDisk(true)
 | 
								WriteConfigToDisk(true)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	getCmd = &cobra.Command {
 | 
						getCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "get",
 | 
							Use:   "get",
 | 
				
			||||||
		Short: "Get a jail property",
 | 
							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)
 | 
					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)`,
 | 
					For all properties specify "all" (Ex: gocage get all myjail)`,
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
@ -129,8 +131,8 @@ For all properties specify "all" (Ex: gocage get all myjail)`,
 | 
				
			|||||||
			GetJailProperties(args)
 | 
								GetJailProperties(args)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	snapshotCmd = &cobra.Command {
 | 
						snapshotCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "snapshot",
 | 
							Use:   "snapshot",
 | 
				
			||||||
		Short: "snapshot jail",
 | 
							Short: "snapshot jail",
 | 
				
			||||||
		Long:  "Commands to manage jail snapshots. If no arguments given, ",
 | 
							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",
 | 
							Use:   "list",
 | 
				
			||||||
		Short: "list snapshots",
 | 
							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.
 | 
					List all snapshots if no jail name specified.
 | 
				
			||||||
You can specify multiple jails.`,
 | 
					You can specify multiple jails.`,
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
@ -151,32 +153,32 @@ You can specify multiple jails.`,
 | 
				
			|||||||
			ListJailsSnapshots(args)
 | 
								ListJailsSnapshots(args)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	 
 | 
					
 | 
				
			||||||
	snapshotCreateCmd = &cobra.Command {
 | 
						snapshotCreateCmd = &cobra.Command{
 | 
				
			||||||
		 Use:   "create",
 | 
							Use:   "create",
 | 
				
			||||||
		Short: "create snapshots",
 | 
							Short: "create snapshots",
 | 
				
			||||||
		Long:  `Create snapshot of a jail by specifying snapshot name and jail name.`,
 | 
							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) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
			// Load inventory
 | 
								// Load inventory
 | 
				
			||||||
			ListJails(args, false)
 | 
								ListJails(args, false)
 | 
				
			||||||
			CreateJailSnapshot(args)
 | 
								CreateJailSnapshot(args)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	snapshotRollbackCmd = &cobra.Command {
 | 
						snapshotRollbackCmd = &cobra.Command{
 | 
				
			||||||
		 Use:   "rollback",
 | 
							Use:   "rollback",
 | 
				
			||||||
		Short: "Rollback snapshots",
 | 
							Short: "Rollback snapshots",
 | 
				
			||||||
		Long:  `Rollback jail to specifyed snapshot.`,
 | 
							Long:  `Rollback jail to specifyed snapshot.`,
 | 
				
			||||||
//		You can specify multiple jails.`,
 | 
							//		You can specify multiple jails.`,
 | 
				
			||||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
							Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
			// Load inventory
 | 
								// Load inventory
 | 
				
			||||||
			ListJails(args, false)
 | 
								ListJails(args, false)
 | 
				
			||||||
			RollbackJailSnapshot(args)
 | 
								RollbackJailSnapshot(args)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	snapshotDeleteCmd = &cobra.Command {
 | 
						snapshotDeleteCmd = &cobra.Command{
 | 
				
			||||||
		Use:   "destroy",
 | 
							Use:   "destroy",
 | 
				
			||||||
		Short: "destroy snapshots",
 | 
							Short: "destroy snapshots",
 | 
				
			||||||
		Long:  `Destroy snapshot of a jail by specifying snapshot name and jail name.`,
 | 
							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() {
 | 
					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().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().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.")
 | 
						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)
 | 
						// 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().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().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(&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.")
 | 
						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
 | 
						// This is local flag : Only available to gocage snapshot create command
 | 
				
			||||||
	snapshotCreateCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to create")
 | 
						snapshotCreateCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to create")
 | 
				
			||||||
	snapshotCreateCmd.MarkFlagRequired("snapname")
 | 
						snapshotCreateCmd.MarkFlagRequired("snapname")
 | 
				
			||||||
@ -214,8 +215,8 @@ func init() {
 | 
				
			|||||||
	snapshotDeleteCmd.MarkFlagRequired("snapname")
 | 
						snapshotDeleteCmd.MarkFlagRequired("snapname")
 | 
				
			||||||
	snapshotRollbackCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to rollback to")
 | 
						snapshotRollbackCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to rollback to")
 | 
				
			||||||
	snapshotRollbackCmd.MarkFlagRequired("snapname")
 | 
						snapshotRollbackCmd.MarkFlagRequired("snapname")
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
// Now declare commands
 | 
						// Now declare commands
 | 
				
			||||||
	rootCmd.AddCommand(versionCmd)
 | 
						rootCmd.AddCommand(versionCmd)
 | 
				
			||||||
	rootCmd.AddCommand(listCmd)
 | 
						rootCmd.AddCommand(listCmd)
 | 
				
			||||||
	listCmd.AddCommand(listPropsCmd)
 | 
						listCmd.AddCommand(listPropsCmd)
 | 
				
			||||||
@ -228,7 +229,7 @@ func init() {
 | 
				
			|||||||
	snapshotCmd.AddCommand(snapshotCreateCmd)
 | 
						snapshotCmd.AddCommand(snapshotCreateCmd)
 | 
				
			||||||
	snapshotCmd.AddCommand(snapshotDeleteCmd)
 | 
						snapshotCmd.AddCommand(snapshotDeleteCmd)
 | 
				
			||||||
	snapshotCmd.AddCommand(snapshotRollbackCmd)
 | 
						snapshotCmd.AddCommand(snapshotRollbackCmd)
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// Get FreeBSD version
 | 
						// Get FreeBSD version
 | 
				
			||||||
	out, err := executeCommand("freebsd-version")
 | 
						out, err := executeCommand("freebsd-version")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@ -236,7 +237,7 @@ func init() {
 | 
				
			|||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	gHostVersion, _ = strconv.ParseFloat(strings.Split(out, "-")[0], 32)
 | 
						gHostVersion, _ = strconv.ParseFloat(strings.Split(out, "-")[0], 32)
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func initConfig() {
 | 
					func initConfig() {
 | 
				
			||||||
@ -245,7 +246,7 @@ func initConfig() {
 | 
				
			|||||||
		os.Exit(1)
 | 
							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)
 | 
						viper.SetConfigFile(gConfigFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -254,10 +255,10 @@ func initConfig() {
 | 
				
			|||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//	fmt.Println("Using config file:", viper.ConfigFileUsed())
 | 
						//	fmt.Println("Using config file:", viper.ConfigFileUsed())
 | 
				
			||||||
//	fmt.Printf("datastore in config : %s\n", viper.GetStringSlice("datastore"))
 | 
						//	fmt.Printf("datastore in config : %s\n", viper.GetStringSlice("datastore"))
 | 
				
			||||||
//	fmt.Printf("datastore.0 in config : %s\n", viper.GetStringSlice("datastore.0"))
 | 
						//	fmt.Printf("datastore.0 in config : %s\n", viper.GetStringSlice("datastore.0"))
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// Command line flags have priority on config file
 | 
						// Command line flags have priority on config file
 | 
				
			||||||
	if rootCmd.Flags().Lookup("sudo") != nil && false == rootCmd.Flags().Lookup("sudo").Changed {
 | 
						if rootCmd.Flags().Lookup("sudo") != nil && false == rootCmd.Flags().Lookup("sudo").Changed {
 | 
				
			||||||
		gUseSudo = viper.GetBool("sudo")
 | 
							gUseSudo = viper.GetBool("sudo")
 | 
				
			||||||
@ -292,21 +293,20 @@ func initConfig() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
 * Write jails config which been updated to disk.
 | 
					 * Write jails config which been updated to disk.
 | 
				
			||||||
 * If changeauto not set, values which are in "auto" mode on 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 
 | 
					 *  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
 | 
					 *  default route, so if route change on jailhost this will reflect on jail next
 | 
				
			||||||
 *  start)
 | 
					 *  start)
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
func WriteConfigToDisk(changeauto bool) {
 | 
					func WriteConfigToDisk(changeauto bool) {
 | 
				
			||||||
	for _, j := range gJails {
 | 
						for _, j := range gJails {
 | 
				
			||||||
		if j.ConfigUpdated {
 | 
							if j.ConfigUpdated {
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			// we will manipulate properties so get a copy
 | 
								// we will manipulate properties so get a copy
 | 
				
			||||||
			jc := j.Config
 | 
								jc := j.Config
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			if changeauto == false {
 | 
								if changeauto == false {
 | 
				
			||||||
				// Overwrite "auto" properties
 | 
									// Overwrite "auto" properties
 | 
				
			||||||
				ondiskjc, err := getJailConfig(j.ConfigPath)
 | 
									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
 | 
									// If "auto" then keep it that way before writing ondiskjc to disk
 | 
				
			||||||
				var properties []string
 | 
									var properties []string
 | 
				
			||||||
				properties = getStructFieldNames(ondiskjc, properties, "")
 | 
									properties = getStructFieldNames(ondiskjc, properties, "")
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
				for _, p := range properties {
 | 
									for _, p := range properties {
 | 
				
			||||||
					v, _, err := getStructFieldValue(ondiskjc, p)
 | 
										v, _, err := getStructFieldValue(ondiskjc, p)
 | 
				
			||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
@ -332,7 +332,7 @@ func WriteConfigToDisk(changeauto bool) {
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			marshaled, err := json.MarshalIndent(jc, "", "    ")
 | 
								marshaled, err := json.MarshalIndent(jc, "", "    ")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				fmt.Printf("ERROR marshaling config: %s\n", err.Error())
 | 
									fmt.Printf("ERROR marshaling config: %s\n", err.Error())
 | 
				
			||||||
@ -352,5 +352,3 @@ func Execute() {
 | 
				
			|||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,13 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
	"bufio"
 | 
						"bufio"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
@ -16,13 +16,13 @@ import (
 | 
				
			|||||||
func ListJailsSnapshots(args []string) {
 | 
					func ListJailsSnapshots(args []string) {
 | 
				
			||||||
	var jailNames []string
 | 
						var jailNames []string
 | 
				
			||||||
	var snapshots []Snapshot
 | 
						var snapshots []Snapshot
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
		for _, a := range args {
 | 
							for _, a := range args {
 | 
				
			||||||
			jailNames = append(jailNames, a)
 | 
								jailNames = append(jailNames, a)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} 
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(jailNames) == 0 || len(args) == 0 {
 | 
						if len(jailNames) == 0 || len(args) == 0 {
 | 
				
			||||||
		for _, j := range gJails {
 | 
							for _, j := range gJails {
 | 
				
			||||||
			snapshots = append(snapshots, listJailSnapshots(j)...)
 | 
								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
 | 
					 * List all snapshots a jail have
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
func listJailSnapshots(jail Jail) []Snapshot {
 | 
					func listJailSnapshots(jail Jail) []Snapshot {
 | 
				
			||||||
	var snapshots []Snapshot
 | 
						var snapshots []Snapshot
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// 1. List all datasets
 | 
						// 1. List all datasets
 | 
				
			||||||
	// TODO : Include mounted filesystems?
 | 
						// TODO : Include mounted filesystems?
 | 
				
			||||||
	rs := strings.Split(jail.RootPath, "/")
 | 
						rs := strings.Split(jail.RootPath, "/")
 | 
				
			||||||
@ -56,10 +55,10 @@ func listJailSnapshots(jail Jail) []Snapshot {
 | 
				
			|||||||
		fmt.Printf("Error: %s\n", err.Error())
 | 
							fmt.Printf("Error: %s\n", err.Error())
 | 
				
			||||||
		return snapshots
 | 
							return snapshots
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	dateLayout := "Mon Jan _2 15:04 2006"
 | 
						dateLayout := "Mon Jan _2 15:04 2006"
 | 
				
			||||||
	loc, _ := time.LoadLocation(gTimeZone)
 | 
						loc, _ := time.LoadLocation(gTimeZone)
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, line := range strings.Split(out, "\n") {
 | 
						for _, line := range strings.Split(out, "\n") {
 | 
				
			||||||
		if len(line) > 0 {
 | 
							if len(line) > 0 {
 | 
				
			||||||
			ls := strings.Split(line, "\t")
 | 
								ls := strings.Split(line, "\t")
 | 
				
			||||||
@ -71,37 +70,36 @@ func listJailSnapshots(jail Jail) []Snapshot {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			// Get subdir to append to snapshot name
 | 
								// Get subdir to append to snapshot name
 | 
				
			||||||
			subdir := strings.Replace(strings.Split(ls[0], "@")[0], rootDataset, "", 1)
 | 
								subdir := strings.Replace(strings.Split(ls[0], "@")[0], rootDataset, "", 1)
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			snapshots = append(snapshots, Snapshot{Dsname: ls[0],
 | 
								snapshots = append(snapshots, Snapshot{Dsname: ls[0],
 | 
				
			||||||
				Name: fmt.Sprintf("%s%s", strings.Split(ls[0], "@")[1], subdir),
 | 
									Name:       fmt.Sprintf("%s%s", strings.Split(ls[0], "@")[1], subdir),
 | 
				
			||||||
				Jailname: jail.Name,
 | 
									Jailname:   jail.Name,
 | 
				
			||||||
				Mountpoint: ls[1],
 | 
									Mountpoint: ls[1],
 | 
				
			||||||
				Used: ls[2],
 | 
									Used:       ls[2],
 | 
				
			||||||
				Referenced: ls[3],
 | 
									Referenced: ls[3],
 | 
				
			||||||
				Creation: creationts})
 | 
									Creation:   creationts})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// Sort snapshots by creation date
 | 
						// Sort snapshots by creation date
 | 
				
			||||||
	ss := initSnapshotSortStruct()
 | 
						ss := initSnapshotSortStruct()
 | 
				
			||||||
	SnapshotsOrderedBy(ss.CreationInc).Sort(snapshots)
 | 
						SnapshotsOrderedBy(ss.CreationInc).Sort(snapshots)
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return snapshots
 | 
						return snapshots
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
 * Create snapshot for jail(s)
 | 
					 * Create snapshot for jail(s)
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
func CreateJailSnapshot(args []string) {
 | 
					func CreateJailSnapshot(args []string) {
 | 
				
			||||||
	var jailNames []string
 | 
						var jailNames []string
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
		for _, a := range args {
 | 
							for _, a := range args {
 | 
				
			||||||
			jailNames = append(jailNames, a)
 | 
								jailNames = append(jailNames, a)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} 
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, cj := range gJails {
 | 
						for _, cj := range gJails {
 | 
				
			||||||
		for _, jn := range jailNames {
 | 
							for _, jn := range jailNames {
 | 
				
			||||||
			if strings.EqualFold(cj.Name, jn) {
 | 
								if strings.EqualFold(cj.Name, jn) {
 | 
				
			||||||
@ -125,7 +123,7 @@ func createJailSnapshot(jail Jail) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Printf("Snapshot %s@%s created\n", rootDataset, gSnapshotName)
 | 
						fmt.Printf("Snapshot %s@%s created\n", rootDataset, gSnapshotName)
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -134,13 +132,13 @@ func createJailSnapshot(jail Jail) error {
 | 
				
			|||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
func DeleteJailSnapshot(args []string) {
 | 
					func DeleteJailSnapshot(args []string) {
 | 
				
			||||||
	var jailNames []string
 | 
						var jailNames []string
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
		for _, a := range args {
 | 
							for _, a := range args {
 | 
				
			||||||
			jailNames = append(jailNames, a)
 | 
								jailNames = append(jailNames, a)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} 
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, cj := range gJails {
 | 
						for _, cj := range gJails {
 | 
				
			||||||
		for _, jn := range jailNames {
 | 
							for _, jn := range jailNames {
 | 
				
			||||||
			if strings.EqualFold(cj.Name, jn) {
 | 
								if strings.EqualFold(cj.Name, jn) {
 | 
				
			||||||
@ -155,7 +153,7 @@ func DeleteJailSnapshot(args []string) {
 | 
				
			|||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
func deleteJailSnapshot(jail Jail) error {
 | 
					func deleteJailSnapshot(jail Jail) error {
 | 
				
			||||||
	var snaptodel []string
 | 
						var snaptodel []string
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// Get all recursive snapshots
 | 
						// Get all recursive snapshots
 | 
				
			||||||
	rs := strings.Split(jail.RootPath, "/")
 | 
						rs := strings.Split(jail.RootPath, "/")
 | 
				
			||||||
	rootDataset := fmt.Sprintf("%s%s", jail.Zpool, strings.Join(rs[:len(rs)-1], "/"))
 | 
						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())
 | 
							fmt.Printf("Error: listing snapshots: %s\n", err.Error())
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, line := range strings.Split(out, "\n") {
 | 
						for _, line := range strings.Split(out, "\n") {
 | 
				
			||||||
		if len(line) > 0 {
 | 
							if len(line) > 0 {
 | 
				
			||||||
			ls := strings.Split(line, "@")
 | 
								ls := strings.Split(line, "@")
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			matched, _ := regexp.Match(fmt.Sprintf("^%s(\\/.*)?$", gSnapshotName), []byte(ls[1]))
 | 
								matched, _ := regexp.Match(fmt.Sprintf("^%s(\\/.*)?$", gSnapshotName), []byte(ls[1]))
 | 
				
			||||||
			if matched {
 | 
								if matched {
 | 
				
			||||||
				snaptodel = append(snaptodel, strings.Join(ls, "@"))
 | 
									snaptodel = append(snaptodel, strings.Join(ls, "@"))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, s := range snaptodel {
 | 
						for _, s := range snaptodel {
 | 
				
			||||||
		cmd := fmt.Sprintf("zfs destroy %s", s)
 | 
							cmd := fmt.Sprintf("zfs destroy %s", s)
 | 
				
			||||||
		_, err := executeCommand(cmd)
 | 
							_, err := executeCommand(cmd)
 | 
				
			||||||
@ -186,19 +184,19 @@ func deleteJailSnapshot(jail Jail) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		fmt.Printf("Snapshot %s deleted\n", s)
 | 
							fmt.Printf("Snapshot %s deleted\n", s)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RollbackJailSnapshot(args []string) error {
 | 
					func RollbackJailSnapshot(args []string) error {
 | 
				
			||||||
	var jailNames []string
 | 
						var jailNames []string
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if len(args) > 0 {
 | 
						if len(args) > 0 {
 | 
				
			||||||
		for _, a := range args {
 | 
							for _, a := range args {
 | 
				
			||||||
			jailNames = append(jailNames, a)
 | 
								jailNames = append(jailNames, a)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} 
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, cj := range gJails {
 | 
						for _, cj := range gJails {
 | 
				
			||||||
		for _, jn := range jailNames {
 | 
							for _, jn := range jailNames {
 | 
				
			||||||
			if strings.EqualFold(cj.Name, jn) {
 | 
								if strings.EqualFold(cj.Name, jn) {
 | 
				
			||||||
@ -206,7 +204,7 @@ func RollbackJailSnapshot(args []string) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -216,7 +214,7 @@ func RollbackJailSnapshot(args []string) error {
 | 
				
			|||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
func rollbackJailSnapshot(jail Jail) error {
 | 
					func rollbackJailSnapshot(jail Jail) error {
 | 
				
			||||||
	var snaptorb []string
 | 
						var snaptorb []string
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if jail.Running {
 | 
						if jail.Running {
 | 
				
			||||||
		fmt.Printf("Jail should be stoped to rollback, should we stop and rollback? (y/n)\n")
 | 
							fmt.Printf("Jail should be stoped to rollback, should we stop and rollback? (y/n)\n")
 | 
				
			||||||
		scanr := bufio.NewScanner(os.Stdin)
 | 
							scanr := bufio.NewScanner(os.Stdin)
 | 
				
			||||||
@ -231,7 +229,7 @@ func rollbackJailSnapshot(jail Jail) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// We need to rollback parent and childs
 | 
						// We need to rollback parent and childs
 | 
				
			||||||
	// Get all recursive snapshots
 | 
						// Get all recursive snapshots
 | 
				
			||||||
	rs := strings.Split(jail.RootPath, "/")
 | 
						rs := strings.Split(jail.RootPath, "/")
 | 
				
			||||||
@ -242,18 +240,18 @@ func rollbackJailSnapshot(jail Jail) error {
 | 
				
			|||||||
		fmt.Printf("Error: listing snapshots: %s\n", err.Error())
 | 
							fmt.Printf("Error: listing snapshots: %s\n", err.Error())
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, line := range strings.Split(out, "\n") {
 | 
						for _, line := range strings.Split(out, "\n") {
 | 
				
			||||||
		if len(line) > 0 {
 | 
							if len(line) > 0 {
 | 
				
			||||||
			ls := strings.Split(line, "@")
 | 
								ls := strings.Split(line, "@")
 | 
				
			||||||
			
 | 
					
 | 
				
			||||||
			matched, _ := regexp.Match(fmt.Sprintf("^%s(\\/.*)?$", gSnapshotName), []byte(ls[1]))
 | 
								matched, _ := regexp.Match(fmt.Sprintf("^%s(\\/.*)?$", gSnapshotName), []byte(ls[1]))
 | 
				
			||||||
			if matched {
 | 
								if matched {
 | 
				
			||||||
				snaptorb = append(snaptorb, strings.Join(ls, "@"))
 | 
									snaptorb = append(snaptorb, strings.Join(ls, "@"))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, s := range snaptorb {
 | 
						for _, s := range snaptorb {
 | 
				
			||||||
		cmd := fmt.Sprintf("zfs rollback -r %s", s)
 | 
							cmd := fmt.Sprintf("zfs rollback -r %s", s)
 | 
				
			||||||
		_, err := executeCommand(cmd)
 | 
							_, err := executeCommand(cmd)
 | 
				
			||||||
@ -263,6 +261,6 @@ func rollbackJailSnapshot(jail Jail) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Printf("Jail is back to %s\n", gSnapshotName)
 | 
						fmt.Printf("Jail is back to %s\n", gSnapshotName)
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										530
									
								
								cmd/start.go
									
									
									
									
									
								
							
							
						
						
									
										530
									
								
								cmd/start.go
									
									
									
									
									
								
							@ -1,13 +1,16 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"regexp"
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
						"github.com/c-robinson/iplib"
 | 
				
			||||||
	"strconv"
 | 
						log "github.com/sirupsen/logrus"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FIXME : Do not work?!
 | 
					// FIXME : Do not work?!
 | 
				
			||||||
@ -34,7 +37,7 @@ func mountProcFs(jail *Jail) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.New(fmt.Sprintf("Error mounting procfs on %s/proc: %s", jail.RootPath, err.Error()))
 | 
							return errors.New(fmt.Sprintf("Error mounting procfs on %s/proc: %s", jail.RootPath, err.Error()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -52,7 +55,7 @@ func mountLinProcFs(jail *Jail) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.New(fmt.Sprintf("Error mounting linprocfs on %s: %s", ldir, err.Error()))
 | 
							return errors.New(fmt.Sprintf("Error mounting linprocfs on %s: %s", ldir, err.Error()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -62,7 +65,7 @@ func mountDevFs(jail *Jail) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.New(fmt.Sprintf("Error mounting devfs on %s/dev: %s", jail.RootPath, err.Error()))
 | 
							return errors.New(fmt.Sprintf("Error mounting devfs on %s/dev: %s", jail.RootPath, err.Error()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -73,17 +76,17 @@ func mountFdescFs(jail *Jail) error {
 | 
				
			|||||||
		jail.Config.Mount_fdescfs = 0
 | 
							jail.Config.Mount_fdescfs = 0
 | 
				
			||||||
		// Tag config so it will be synced on disk
 | 
							// Tag config so it will be synced on disk
 | 
				
			||||||
		jail.ConfigUpdated = true
 | 
							jail.ConfigUpdated = true
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
		// Should we consider this an error?
 | 
							// Should we consider this an error?
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	cmd := fmt.Sprintf("mount -t fdescfs descfs %s/dev/fd", jail.RootPath)
 | 
						cmd := fmt.Sprintf("mount -t fdescfs descfs %s/dev/fd", jail.RootPath)
 | 
				
			||||||
	_, err := executeCommand(cmd)
 | 
						_, err := executeCommand(cmd)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return errors.New(fmt.Sprintf("Error mounting fdescfs on %s/dev/fd: %s", jail.RootPath, err.Error()))
 | 
							return errors.New(fmt.Sprintf("Error mounting fdescfs on %s/dev/fd: %s", jail.RootPath, err.Error()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,22 +96,22 @@ func mountAllJailFsFromHost(jail *Jail) error {
 | 
				
			|||||||
	devfsFound := false
 | 
						devfsFound := false
 | 
				
			||||||
	fdescfsFound := false
 | 
						fdescfsFound := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd := "mount -p"
 | 
						cmd := "mount -p"
 | 
				
			||||||
    out, err := executeCommand(cmd)
 | 
						out, err := executeCommand(cmd)
 | 
				
			||||||
    if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
        return errors.New(fmt.Sprintf("Error executing mount: %s", err.Error()))
 | 
							return errors.New(fmt.Sprintf("Error executing mount: %s", err.Error()))
 | 
				
			||||||
    }   
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var outclean []string
 | 
						var outclean []string
 | 
				
			||||||
    remSpPtrn := regexp.MustCompile(`\s+`)
 | 
						remSpPtrn := regexp.MustCompile(`\s+`)
 | 
				
			||||||
    for _, l := range strings.Split(out, "\n") {
 | 
						for _, l := range strings.Split(out, "\n") {
 | 
				
			||||||
		outclean = append(outclean, remSpPtrn.ReplaceAllString(l, " "))
 | 
							outclean = append(outclean, remSpPtrn.ReplaceAllString(l, " "))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check if these FS are already mounted
 | 
						// Check if these FS are already mounted
 | 
				
			||||||
	for _, l := range outclean {
 | 
						for _, l := range outclean {
 | 
				
			||||||
        f := strings.Split(l, " ")
 | 
							f := strings.Split(l, " ")
 | 
				
			||||||
        if len(f) > 2 {
 | 
							if len(f) > 2 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if strings.EqualFold(f[1], fmt.Sprintf("%s/proc", jail.RootPath)) {
 | 
								if strings.EqualFold(f[1], fmt.Sprintf("%s/proc", jail.RootPath)) {
 | 
				
			||||||
				procfsFound = true
 | 
									procfsFound = true
 | 
				
			||||||
@ -128,22 +131,22 @@ func mountAllJailFsFromHost(jail *Jail) error {
 | 
				
			|||||||
	// Mount wanted FS
 | 
						// Mount wanted FS
 | 
				
			||||||
	if jail.Config.Mount_procfs > 0 && procfsFound == false {
 | 
						if jail.Config.Mount_procfs > 0 && procfsFound == false {
 | 
				
			||||||
		err := mountProcFs(jail)
 | 
							err := mountProcFs(jail)
 | 
				
			||||||
        if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
	        return err
 | 
								return err
 | 
				
			||||||
        }   
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if jail.Config.Mount_linprocfs > 0 && linProcfsFound == false {
 | 
						if jail.Config.Mount_linprocfs > 0 && linProcfsFound == false {
 | 
				
			||||||
		err = mountLinProcFs(jail)
 | 
							err = mountLinProcFs(jail)
 | 
				
			||||||
        if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
	        return err
 | 
								return err
 | 
				
			||||||
        }
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	if jail.Config.Mount_devfs > 0 && devfsFound == false {
 | 
						if jail.Config.Mount_devfs > 0 && devfsFound == false {
 | 
				
			||||||
		err := mountDevFs(jail)
 | 
							err := mountDevFs(jail)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
	        return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if jail.Config.Mount_fdescfs > 0 && fdescfsFound == false {
 | 
						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é?
 | 
						// Ces montages doivent-ils etre effectués une fois le jail démarré?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// FreeBSD <= 9.3 do not support fdescfs
 | 
						// FreeBSD <= 9.3 do not support fdescfs
 | 
				
			||||||
@ -172,7 +174,7 @@ func mountAllJailFsFromHost(jail *Jail) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if gHostVersion < 12 {
 | 
						if gHostVersion < 12 {
 | 
				
			||||||
		if jail.Config.Allow_mlock > 0 {
 | 
							if jail.Config.Allow_mlock > 0 {
 | 
				
			||||||
			jail.Config.Allow_mlock = 0		
 | 
								jail.Config.Allow_mlock = 0
 | 
				
			||||||
			jail.ConfigUpdated = true
 | 
								jail.ConfigUpdated = true
 | 
				
			||||||
			/* WIP
 | 
								/* WIP
 | 
				
			||||||
			err = setJailProperty(jail, "Config.Allow_mlock", "0")
 | 
								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 {
 | 
					func prepareJailedZfsDatasets(jail *Jail) error {
 | 
				
			||||||
	if jail.Config.Jail_zfs > 0 {
 | 
						if jail.Config.Jail_zfs > 0 {
 | 
				
			||||||
		// For jail to mount filesystem, enforce_statfs should be 1 or lower (2 is the default)
 | 
							// 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 {
 | 
					type NatDesc struct {
 | 
				
			||||||
	Proto		string
 | 
						Proto    string
 | 
				
			||||||
	JailPort	string
 | 
						JailPort string
 | 
				
			||||||
	HostPort	string
 | 
						HostPort string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// tcp(80:8080),tcp(3300-3310:33060-33070)
 | 
					// tcp(80:8080),tcp(3300-3310:33060-33070)
 | 
				
			||||||
func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc, error) {
 | 
					func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc, error) {
 | 
				
			||||||
	var res []NatDesc
 | 
						var res []NatDesc
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	regx := `(tcp|udp)\(([0-9]{1,5}(?:-[0-9]{1,5})?):([0-9]{1,5}(?:-[0-9]{1,5})?)\)`
 | 
						regx := `(tcp|udp)\(([0-9]{1,5}(?:-[0-9]{1,5})?):([0-9]{1,5}(?:-[0-9]{1,5})?)\)`
 | 
				
			||||||
	re := regexp.MustCompile(regx)
 | 
						re := regexp.MustCompile(regx)
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	for _, match := range re.FindAllStringSubmatch(nat_forwards, -1) {
 | 
						for _, match := range re.FindAllStringSubmatch(nat_forwards, -1) {
 | 
				
			||||||
		if strings.Contains(match[2], "-") == true && decompose_range == true {
 | 
							if strings.Contains(match[2], "-") == true && decompose_range == true {
 | 
				
			||||||
			sjrange, err := strconv.Atoi(strings.Split(match[2], "-")[0])
 | 
								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) {
 | 
								if (ejrange - sjrange) != (ehrange - shrange) {
 | 
				
			||||||
				return res, errors.New(fmt.Sprintf("Invalid port range in nat_forwards: %s", match[0]))
 | 
									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],
 | 
									nd := NatDesc{Proto: match[1],
 | 
				
			||||||
					JailPort: strconv.Itoa(i),
 | 
										JailPort: strconv.Itoa(i),
 | 
				
			||||||
					HostPort: strconv.Itoa(shrange + (i - sjrange)),
 | 
										HostPort: strconv.Itoa(shrange + (i - sjrange)),
 | 
				
			||||||
@ -271,16 +272,226 @@ func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc,
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			nd := NatDesc{Proto: match[1],
 | 
								nd := NatDesc{Proto: match[1],
 | 
				
			||||||
							JailPort: match[2],
 | 
									JailPort: match[2],
 | 
				
			||||||
							HostPort: match[3],
 | 
									HostPort: match[3],
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			res = append(res, nd)
 | 
								res = append(res, nd)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return res, nil
 | 
						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:
 | 
						Start jail:
 | 
				
			||||||
		Check jail fstab?
 | 
							Check jail fstab?
 | 
				
			||||||
@ -309,10 +520,11 @@ func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc,
 | 
				
			|||||||
func StartJail(args []string) {
 | 
					func StartJail(args []string) {
 | 
				
			||||||
	// jail we have to start
 | 
						// jail we have to start
 | 
				
			||||||
	var cj *Jail
 | 
						var cj *Jail
 | 
				
			||||||
	
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, j := range args {
 | 
						for _, j := range args {
 | 
				
			||||||
		fmt.Printf("> Starting jail %s\n", j)
 | 
							fmt.Printf("> Starting jail %s\n", j)
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		for i, rj := range gJails {
 | 
							for i, rj := range gJails {
 | 
				
			||||||
			if rj.Name == j {
 | 
								if rj.Name == j {
 | 
				
			||||||
				// Get jail reference, not a copy of it; So we can modify attributes
 | 
									// 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)
 | 
								fmt.Printf("Jail not found: %s\n", j)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if cj.Running == true {
 | 
							if cj.Running == true {
 | 
				
			||||||
			fmt.Printf("Jail %s is already running!\n", cj.Name)
 | 
								fmt.Printf("Jail %s is already running!\n", cj.Name)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if len(cj.Config.Hostid) > 0 && cj.Config.Hostid_strict_check > 0 {
 | 
							if len(cj.Config.Hostid) > 0 && cj.Config.Hostid_strict_check > 0 {
 | 
				
			||||||
			hostid, err := ioutil.ReadFile("/etc/hostid")
 | 
								hostid, err := ioutil.ReadFile("/etc/hostid")
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
@ -342,10 +554,10 @@ func StartJail(args []string) {
 | 
				
			|||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		var props_missing []string
 | 
							var props_missing []string
 | 
				
			||||||
		// DHCP can also be set with "DHCP" value in ip4_addr
 | 
							// DHCP can also be set with "dhcp" value in ip4_addr (Eg: "vnet0|dhcp")
 | 
				
			||||||
		if cj.Config.Dhcp > 0 || strings.EqualFold(cj.Config.Ip4_addr, "DHCP") == true {
 | 
							if cj.Config.Dhcp > 0 || strings.Contains(strings.ToLower(cj.Config.Ip4_addr), "dhcp") == true {
 | 
				
			||||||
			if cj.Config.Bpf == 0 {
 | 
								if cj.Config.Bpf == 0 {
 | 
				
			||||||
				props_missing = append(props_missing, fmt.Sprintf("%s: dhcp requires bpf", cj.Name))
 | 
									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))
 | 
									props_missing = append(props_missing, fmt.Sprintf("%s: dhcp requires vnet", cj.Name))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		// tcp(80:8080),tcp(3300-3310:33000-33010)
 | 
							// tcp(80:8080),tcp(3300-3310:33000-33010)
 | 
				
			||||||
		if cj.Config.Nat > 0 && strings.EqualFold(cj.Config.Nat_forwards, "none") == false {
 | 
							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
 | 
								//   with another running jail
 | 
				
			||||||
			for _, j := range gJails {
 | 
								for _, j := range gJails {
 | 
				
			||||||
				if j.Running == false || strings.EqualFold(j.Config.Nat_forwards, "none") == false || j.Config.Nat != 1 {
 | 
									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 {
 | 
											for _, cjn := range cjnd {
 | 
				
			||||||
							if jn == cjn {
 | 
												if jn == cjn {
 | 
				
			||||||
								fmt.Printf("nat_forwards rule \"%s\" is in conflict with jail %s, won't start\n",
 | 
													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
 | 
													return
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
@ -384,27 +596,68 @@ func StartJail(args []string) {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if cj.Config.Nat > 0 && strings.EqualFold(cj.Config.Nat_interface, "none") == true {
 | 
							if cj.Config.Nat > 0 && strings.EqualFold(cj.Config.Nat_interface, "none") == true {
 | 
				
			||||||
			var jhost JailHost
 | 
								var jhost JailHost
 | 
				
			||||||
			cj.Config.Nat_interface = jhost.GetDefaultInterface()
 | 
								cj.Config.Nat_interface = jhost.GetDefaultInterface()
 | 
				
			||||||
			cj.ConfigUpdated = true
 | 
								cj.ConfigUpdated = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if cj.Config.Vnet > 0 && strings.EqualFold(cj.Config.Defaultrouter, "auto") == true {
 | 
							if cj.Config.Vnet > 0 && strings.EqualFold(cj.Config.Defaultrouter, "auto") == true {
 | 
				
			||||||
			var jhost JailHost
 | 
								var jhost JailHost
 | 
				
			||||||
			cj.Config.Defaultrouter = jhost.GetDefaultGateway4()
 | 
								cj.Config.Defaultrouter = jhost.GetDefaultGateway4()
 | 
				
			||||||
			// "auto" default Gateway should not be updated to support jailhost route change
 | 
								// "auto" default Gateway should not be updated to support jailhost route change
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if cj.Config.Vnet > 0 && strings.EqualFold(cj.Config.Defaultrouter6, "auto") == true {
 | 
							if cj.Config.Vnet > 0 && strings.EqualFold(cj.Config.Defaultrouter6, "auto") == true {
 | 
				
			||||||
			var jhost JailHost
 | 
								var jhost JailHost
 | 
				
			||||||
			cj.Config.Defaultrouter6 = jhost.GetDefaultGateway6()
 | 
								cj.Config.Defaultrouter6 = jhost.GetDefaultGateway6()
 | 
				
			||||||
			// "auto" default Gateway should not be updated to support jailhost route change
 | 
								// "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")
 | 
							fmt.Printf("  > Mount special filesystems:\n")
 | 
				
			||||||
		err := mountAllJailFsFromHost(cj)
 | 
							err := mountAllJailFsFromHost(cj)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@ -412,7 +665,7 @@ func StartJail(args []string) {
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			fmt.Printf("  > Mount special filesystems: OK\n")
 | 
								fmt.Printf("  > Mount special filesystems: OK\n")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		if cj.Config.Jail_zfs > 0 {
 | 
							if cj.Config.Jail_zfs > 0 {
 | 
				
			||||||
			fmt.Printf("  > Prepare ZFS Datasets:\n")
 | 
								fmt.Printf("  > Prepare ZFS Datasets:\n")
 | 
				
			||||||
			err := prepareJailedZfsDatasets(cj)
 | 
								err := prepareJailedZfsDatasets(cj)
 | 
				
			||||||
@ -422,77 +675,116 @@ func StartJail(args []string) {
 | 
				
			|||||||
				fmt.Printf("  > Prepare ZFS Datasets: OK\n")
 | 
									fmt.Printf("  > Prepare ZFS Datasets: OK\n")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		
 | 
							// 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
 | 
				
			||||||
		out, err := executeCommand(fmt.Sprintf("rctl jail:%s", cj.InternalName))
 | 
							//checkCapabilities(cj)
 | 
				
			||||||
		if err == nil && len(out) > 0 {
 | 
					
 | 
				
			||||||
			fmt.Printf("  > Remove RCTL rules:\n")
 | 
							// Check NAT backend
 | 
				
			||||||
			err := removeRctlRules(cj.InternalName, []string{""})
 | 
							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 {
 | 
								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 {
 | 
								} 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 {
 | 
							// CONTINUE HERE
 | 
				
			||||||
			fmt.Printf("  > Execute prestop:\n")
 | 
							// See https://github.com/iocage/iocage/blob/e94863d4c54f02523fb09e62e48be7db9ac92eda/iocage_lib/ioc_start.py:401
 | 
				
			||||||
			_, 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")
 | 
								out, err := executeCommand(fmt.Sprintf("rctl jail:%s", cj.InternalName))
 | 
				
			||||||
			err := umountAndUnjailZFS(cj)
 | 
								if err == nil && len(out) > 0 {
 | 
				
			||||||
			if err != nil {
 | 
									fmt.Printf("  > Remove RCTL rules:\n")
 | 
				
			||||||
				fmt.Printf("ERROR: %s\n", err.Error())
 | 
									err := removeRctlRules(cj.InternalName, []string{""})
 | 
				
			||||||
			} else {
 | 
									if err != nil {
 | 
				
			||||||
				fmt.Printf("  > Umount jailed ZFS: OK\n")
 | 
										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 {
 | 
								if len (cj.Config.Exec_prestop) > 0 {
 | 
				
			||||||
			fmt.Printf("  > Destroy VNet interfaces:\n")
 | 
									fmt.Printf("  > Execute prestop:\n")
 | 
				
			||||||
			err := destroyVNetInterfaces(cj)
 | 
									_, 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 {
 | 
								if err != nil {
 | 
				
			||||||
				fmt.Printf("ERROR: %s\n", err.Error())
 | 
									fmt.Printf("ERROR: %s\n", err.Error())
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				fmt.Printf("  > Destroy VNet interfaces: OK\n")
 | 
									fmt.Printf("  > Remove devfsruleset %s: OK\n", cj.Config.Devfs_ruleset)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
					
 | 
				
			||||||
		
 | 
								fmt.Printf("  > Stop jail %s:\n", cj.Name)
 | 
				
			||||||
		fmt.Printf("  > Remove devfsruleset %s:\n", cj.Config.Devfs_ruleset)
 | 
								err = stopJail(cj)
 | 
				
			||||||
		err = deleteDevfsRuleset(cj)
 | 
								if err != nil {
 | 
				
			||||||
		if err != nil {
 | 
									fmt.Printf("ERROR: %s\n", err.Error())
 | 
				
			||||||
			fmt.Printf("ERROR: %s\n", err.Error())
 | 
								} else {
 | 
				
			||||||
		} else {
 | 
									fmt.Printf("  > Stop jail %s: OK\n", cj.Name)
 | 
				
			||||||
			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)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										25
									
								
								cmd/stop.go
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								cmd/stop.go
									
									
									
									
									
								
							@ -1,13 +1,13 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
//	"log"
 | 
						"os"
 | 
				
			||||||
 | 
						//	"log"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
//	"reflect"
 | 
						"regexp"
 | 
				
			||||||
 | 
						//	"reflect"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -38,7 +38,6 @@ func removeRctlRules(jail string, rules []string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO: Validate with  >1 dataset
 | 
					// TODO: Validate with  >1 dataset
 | 
				
			||||||
func umountAndUnjailZFS(jail *Jail) error {
 | 
					func umountAndUnjailZFS(jail *Jail) error {
 | 
				
			||||||
	var ds []string
 | 
						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())
 | 
							fmt.Printf("ERROR unjailing %s/%s: %s\n", jail.Zpool, ds[len(ds)-1], err.Error())
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
func destroyVNetInterfaces(jail *Jail) error {
 | 
					func destroyVNetInterfaces(jail *Jail) error {
 | 
				
			||||||
	for _, i := range strings.Split(jail.Config.Ip4_addr, ",") {
 | 
						for _, i := range strings.Split(jail.Config.Ip4_addr, ",") {
 | 
				
			||||||
		iname := fmt.Sprintf("%s.%d", strings.Split(i, "|")[0], jail.JID)
 | 
							iname := fmt.Sprintf("%s.%d", strings.Split(i, "|")[0], jail.JID)
 | 
				
			||||||
@ -119,7 +117,6 @@ func deleteDevfsRuleset(jail *Jail) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
func umountJailFsFromHost(jail *Jail, mountpoint string) error {
 | 
					func umountJailFsFromHost(jail *Jail, mountpoint string) error {
 | 
				
			||||||
	cmd := "mount -p"
 | 
						cmd := "mount -p"
 | 
				
			||||||
	out, err := executeCommand(cmd)
 | 
						out, err := executeCommand(cmd)
 | 
				
			||||||
@ -145,7 +142,6 @@ func umountJailFsFromHost(jail *Jail, mountpoint string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Internal usage only
 | 
					// Internal usage only
 | 
				
			||||||
func stopJail(jail *Jail) error {
 | 
					func stopJail(jail *Jail) error {
 | 
				
			||||||
	cmd := "jail -q"
 | 
						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")
 | 
								fmt.Printf("  > Execute prestop:\n")
 | 
				
			||||||
			_, err := executeCommand(cj.Config.Exec_prestop)
 | 
								_, err := executeCommand(cj.Config.Exec_prestop)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
@ -230,8 +226,8 @@ func StopJail(args []string) {
 | 
				
			|||||||
				fmt.Printf("  > Execute prestop: OK\n")
 | 
									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")
 | 
								fmt.Printf("  > Execute stop:\n")
 | 
				
			||||||
			_, err := executeCommandInJail(cj, cj.Config.Exec_stop)
 | 
								_, err := executeCommandInJail(cj, cj.Config.Exec_stop)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
@ -260,7 +256,7 @@ func StopJail(args []string) {
 | 
				
			|||||||
				fmt.Printf("  > Destroy VNet interfaces: OK\n")
 | 
									fmt.Printf("  > Destroy VNet interfaces: OK\n")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		/*fmt.Printf("  > Remove devfsruleset %s:\n", cj.Config.Devfs_ruleset)
 | 
							/*fmt.Printf("  > Remove devfsruleset %s:\n", cj.Config.Devfs_ruleset)
 | 
				
			||||||
		err = deleteDevfsRuleset(cj)
 | 
							err = deleteDevfsRuleset(cj)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@ -268,7 +264,7 @@ func StopJail(args []string) {
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			fmt.Printf("  > Remove devfsruleset %s: OK\n", cj.Config.Devfs_ruleset)
 | 
								fmt.Printf("  > Remove devfsruleset %s: OK\n", cj.Config.Devfs_ruleset)
 | 
				
			||||||
		}*/
 | 
							}*/
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		fmt.Printf("  > Stop jail %s:\n", cj.Name)
 | 
							fmt.Printf("  > Stop jail %s:\n", cj.Name)
 | 
				
			||||||
		err = stopJail(cj)
 | 
							err = stopJail(cj)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@ -340,4 +336,3 @@ func StopJail(args []string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										933
									
								
								cmd/struct.go
									
									
									
									
									
								
							
							
						
						
									
										933
									
								
								cmd/struct.go
									
									
									
									
									
								
							@ -4,19 +4,24 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPv4 = 0
 | 
				
			||||||
 | 
						IPv6 = 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// To allow sorting, just duplicate fields in JailSort below
 | 
					// To allow sorting, just duplicate fields in JailSort below
 | 
				
			||||||
type Jail struct {
 | 
					type Jail struct {
 | 
				
			||||||
	Name					string
 | 
						Name          string
 | 
				
			||||||
	InternalName			string
 | 
						InternalName  string
 | 
				
			||||||
	JID						int
 | 
						JID           int
 | 
				
			||||||
	Config					JailConfig
 | 
						Config        JailConfig
 | 
				
			||||||
	RootPath				string
 | 
						RootPath      string
 | 
				
			||||||
	ConfigPath				string
 | 
						ConfigPath    string
 | 
				
			||||||
	ConfigUpdated			bool
 | 
						ConfigUpdated bool
 | 
				
			||||||
	Running					bool
 | 
						Running       bool
 | 
				
			||||||
	// No need, Config.Release always represent what is running (plus it know release for non-running jails)
 | 
						// No need, Config.Release always represent what is running (plus it know release for non-running jails)
 | 
				
			||||||
	//Release					string
 | 
						//Release					string
 | 
				
			||||||
	Zpool					string
 | 
						Zpool string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// iocage struct as stored in config.json
 | 
					// iocage struct as stored in config.json
 | 
				
			||||||
@ -28,483 +33,483 @@ type Jail struct {
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// To allow sorting, just duplicate fields in JailConfigSort below
 | 
					// To allow sorting, just duplicate fields in JailConfigSort below
 | 
				
			||||||
type JailConfig struct {
 | 
					type JailConfig struct {
 | 
				
			||||||
	Config_version			string	`json:"CONFIG_VERSION"`
 | 
						Config_version        string `json:"CONFIG_VERSION"`
 | 
				
			||||||
	Allow_chflags			int		`json:"allow_chflags"`
 | 
						Allow_chflags         int    `json:"allow_chflags"`
 | 
				
			||||||
	Allow_mlock				int		`json:"allow_mlock"`
 | 
						Allow_mlock           int    `json:"allow_mlock"`
 | 
				
			||||||
	Allow_mount				int		`json:"allow_mount"`
 | 
						Allow_mount           int    `json:"allow_mount"`
 | 
				
			||||||
	Allow_mount_devfs		int		`json:"allow_mount_devfs"`
 | 
						Allow_mount_devfs     int    `json:"allow_mount_devfs"`
 | 
				
			||||||
	Allow_mount_fusefs		int		`json:"allow_mount_fusefs"`
 | 
						Allow_mount_fusefs    int    `json:"allow_mount_fusefs"`
 | 
				
			||||||
	Allow_mount_nullfs		int		`json:"allow_mount_nullfs"`
 | 
						Allow_mount_nullfs    int    `json:"allow_mount_nullfs"`
 | 
				
			||||||
	Allow_mount_procfs		int		`json:"allow_mount_procfs"`
 | 
						Allow_mount_procfs    int    `json:"allow_mount_procfs"`
 | 
				
			||||||
	Allow_mount_tmpfs		int		`json:"allow_mount_tmpfs"`
 | 
						Allow_mount_tmpfs     int    `json:"allow_mount_tmpfs"`
 | 
				
			||||||
	Allow_mount_zfs			int		`json:"allow_mount_zfs"`
 | 
						Allow_mount_zfs       int    `json:"allow_mount_zfs"`
 | 
				
			||||||
	Allow_quotas			int		`json:"allow_quotas"`
 | 
						Allow_quotas          int    `json:"allow_quotas"`
 | 
				
			||||||
	Allow_raw_sockets		int		`json:"allow_raw_sockets"`
 | 
						Allow_raw_sockets     int    `json:"allow_raw_sockets"`
 | 
				
			||||||
	Allow_set_hostname		int		`json:"allow_set_hostname"`
 | 
						Allow_set_hostname    int    `json:"allow_set_hostname"`
 | 
				
			||||||
	Allow_socket_af			int		`json:"allow_socket_af"`
 | 
						Allow_socket_af       int    `json:"allow_socket_af"`
 | 
				
			||||||
	Allow_sysvipc			int		`json:"allow_sysvipc"`
 | 
						Allow_sysvipc         int    `json:"allow_sysvipc"`
 | 
				
			||||||
	Allow_tun				int		`json:"allow_tun"`
 | 
						Allow_tun             int    `json:"allow_tun"`
 | 
				
			||||||
	Allow_vmm				int		`json:"allow_vmm"`
 | 
						Allow_vmm             int    `json:"allow_vmm"`
 | 
				
			||||||
	Assign_localhost		int		`json:"assign_localhost"`
 | 
						Assign_localhost      int    `json:"assign_localhost"`
 | 
				
			||||||
	Available				string	`json:"available"`
 | 
						Available             string `json:"available"`
 | 
				
			||||||
	Basejail				int		`json:"basejail"`
 | 
						Basejail              int    `json:"basejail"`
 | 
				
			||||||
	Boot					int		`json:"boot"`
 | 
						Boot                  int    `json:"boot"`
 | 
				
			||||||
	Bpf						int		`json:"bpf"`
 | 
						Bpf                   int    `json:"bpf"`
 | 
				
			||||||
	Children_max			string	`json:"children_max"`
 | 
						Children_max          string `json:"children_max"`
 | 
				
			||||||
	Cloned_release			string	`json:"cloned_release"`
 | 
						Cloned_release        string `json:"cloned_release"`
 | 
				
			||||||
	Comment					string	`json:"comment"`
 | 
						Comment               string `json:"comment"`
 | 
				
			||||||
	Compression				string	`json:"compression"`
 | 
						Compression           string `json:"compression"`
 | 
				
			||||||
	Compressratio			string	`json:"compressratio"`
 | 
						Compressratio         string `json:"compressratio"`
 | 
				
			||||||
	Coredumpsize			string	`json:"coredumpsize"`
 | 
						Coredumpsize          string `json:"coredumpsize"`
 | 
				
			||||||
	Count					string	`json:"count"`
 | 
						Count                 string `json:"count"`
 | 
				
			||||||
	Cpuset					string	`json:"cpuset"`
 | 
						Cpuset                string `json:"cpuset"`
 | 
				
			||||||
	Cputime					string	`json:"cputime"`
 | 
						Cputime               string `json:"cputime"`
 | 
				
			||||||
	Datasize				string	`json:"datasize"`
 | 
						Datasize              string `json:"datasize"`
 | 
				
			||||||
	Dedup					string	`json:"dedup"`
 | 
						Dedup                 string `json:"dedup"`
 | 
				
			||||||
	Defaultrouter			string	`json:"defaultrouter"`
 | 
						Defaultrouter         string `json:"defaultrouter"`
 | 
				
			||||||
	Defaultrouter6			string	`json:"defaultrouter6"`
 | 
						Defaultrouter6        string `json:"defaultrouter6"`
 | 
				
			||||||
	Depends					string	`json:"depends"`
 | 
						Depends               string `json:"depends"`
 | 
				
			||||||
	Devfs_ruleset			string	`json:"devfs_ruleset"`
 | 
						Devfs_ruleset         string `json:"devfs_ruleset"`
 | 
				
			||||||
	Dhcp					int		`json:"dhcp"`
 | 
						Dhcp                  int    `json:"dhcp"`
 | 
				
			||||||
	Enforce_statfs			string	`json:"enforce_statfs"`
 | 
						Enforce_statfs        string `json:"enforce_statfs"`
 | 
				
			||||||
	Exec_clean				int		`json:"exec_clean"`
 | 
						Exec_clean            int    `json:"exec_clean"`
 | 
				
			||||||
	Exec_created			string	`json:"exec_created"`
 | 
						Exec_created          string `json:"exec_created"`
 | 
				
			||||||
	Exec_fib				string	`json:"exec_fib"`
 | 
						Exec_fib              string `json:"exec_fib"`
 | 
				
			||||||
	Exec_jail_user			string	`json:"exec_jail_user"`
 | 
						Exec_jail_user        string `json:"exec_jail_user"`
 | 
				
			||||||
	Exec_poststart			string	`json:"exec_poststart"`
 | 
						Exec_poststart        string `json:"exec_poststart"`
 | 
				
			||||||
	Exec_poststop			string	`json:"exec_poststop"`
 | 
						Exec_poststop         string `json:"exec_poststop"`
 | 
				
			||||||
	Exec_prestart			string	`json:"exec_prestart"`
 | 
						Exec_prestart         string `json:"exec_prestart"`
 | 
				
			||||||
	Exec_prestop			string	`json:"exec_prestop"`
 | 
						Exec_prestop          string `json:"exec_prestop"`
 | 
				
			||||||
	Exec_start				string	`json:"exec_start"`
 | 
						Exec_start            string `json:"exec_start"`
 | 
				
			||||||
	Exec_stop				string	`json:"exec_stop"`
 | 
						Exec_stop             string `json:"exec_stop"`
 | 
				
			||||||
	Exec_system_jail_user	string	`json:"exec_system_jail_user"`
 | 
						Exec_system_jail_user string `json:"exec_system_jail_user"`
 | 
				
			||||||
	Exec_system_user		string	`json:"exec_system_user"`
 | 
						Exec_system_user      string `json:"exec_system_user"`
 | 
				
			||||||
	Exec_timeout			string	`json:"exec_timeout"`
 | 
						Exec_timeout          string `json:"exec_timeout"`
 | 
				
			||||||
	Host_domainname			string	`json:"host_domainname"`
 | 
						Host_domainname       string `json:"host_domainname"`
 | 
				
			||||||
	Host_hostname			string	`json:"host_hostname"`
 | 
						Host_hostname         string `json:"host_hostname"`
 | 
				
			||||||
	Host_hostuuid			string	`json:"host_hostuuid"`
 | 
						Host_hostuuid         string `json:"host_hostuuid"`
 | 
				
			||||||
	Host_time				int		`json:"host_time"`
 | 
						Host_time             int    `json:"host_time"`
 | 
				
			||||||
	Hostid					string	`json:"hostid"`
 | 
						Hostid                string `json:"hostid"`
 | 
				
			||||||
	Hostid_strict_check		int		`json:"hostid_strict_check"`
 | 
						Hostid_strict_check   int    `json:"hostid_strict_check"`
 | 
				
			||||||
	Interfaces				string	`json:"interfaces"`
 | 
						Interfaces            string `json:"interfaces"`
 | 
				
			||||||
	Ip4						string	`json:"ip4"`
 | 
						Ip4                   string `json:"ip4"`
 | 
				
			||||||
	Ip4_addr				string	`json:"ip4_addr"`
 | 
						Ip4_addr              string `json:"ip4_addr"`
 | 
				
			||||||
	Ip4_saddrsel			string	`json:"ip4_saddrsel"`
 | 
						Ip4_saddrsel          string `json:"ip4_saddrsel"`
 | 
				
			||||||
	Ip6						string	`json:"ip6"`
 | 
						Ip6                   string `json:"ip6"`
 | 
				
			||||||
	Ip6_addr				string	`json:"ip6_addr"`
 | 
						Ip6_addr              string `json:"ip6_addr"`
 | 
				
			||||||
	Ip6_saddrsel			string	`json:"ip4_saddrsel"`
 | 
						Ip6_saddrsel          string `json:"ip4_saddrsel"`
 | 
				
			||||||
	Ip_hostname				int		`json:"ip_hostname"`
 | 
						Ip_hostname           int    `json:"ip_hostname"`
 | 
				
			||||||
	Jail_zfs				int		`json:"jail_zfs"`
 | 
						Jail_zfs              int    `json:"jail_zfs"`
 | 
				
			||||||
	Jail_zfs_dataset		string	`json:"jail_zfs_dataset"`
 | 
						Jail_zfs_dataset      string `json:"jail_zfs_dataset"`
 | 
				
			||||||
	Jail_zfs_mountpoint		string	`json:"jail_zfs_mountpoint"`
 | 
						Jail_zfs_mountpoint   string `json:"jail_zfs_mountpoint"`
 | 
				
			||||||
	Last_started			string	`json:"last_started"`
 | 
						Last_started          string `json:"last_started"`
 | 
				
			||||||
	Localhost_ip			string	`json:"localhost_ip"`
 | 
						Localhost_ip          string `json:"localhost_ip"`
 | 
				
			||||||
	Login_flags				string	`json:"login_flags"`
 | 
						Login_flags           string `json:"login_flags"`
 | 
				
			||||||
	Mac_prefix				string	`json:"mac_prefix"`
 | 
						Mac_prefix            string `json:"mac_prefix"`
 | 
				
			||||||
	Maxproc					string	`json:"maxproc"`
 | 
						Maxproc               string `json:"maxproc"`
 | 
				
			||||||
	Memorylocked			string	`json:"memorylocked"`
 | 
						Memorylocked          string `json:"memorylocked"`
 | 
				
			||||||
	Memoryuse				string	`json:"memoryuse"`
 | 
						Memoryuse             string `json:"memoryuse"`
 | 
				
			||||||
	Min_dyn_devfs_ruleset	string	`json:"min_dyn_devfs_ruleset"`
 | 
						Min_dyn_devfs_ruleset string `json:"min_dyn_devfs_ruleset"`
 | 
				
			||||||
	Mount_devfs				int		`json:"mount_devfs"`
 | 
						Mount_devfs           int    `json:"mount_devfs"`
 | 
				
			||||||
	Mount_fdescfs			int		`json:"mount_fdescfs"`
 | 
						Mount_fdescfs         int    `json:"mount_fdescfs"`
 | 
				
			||||||
	Mount_linprocfs			int		`json:"mount_linprocfs"`
 | 
						Mount_linprocfs       int    `json:"mount_linprocfs"`
 | 
				
			||||||
	Mount_procfs			int		`json:"mount_procfs"`
 | 
						Mount_procfs          int    `json:"mount_procfs"`
 | 
				
			||||||
	Mountpoint				string	`json:"mountpoint"`
 | 
						Mountpoint            string `json:"mountpoint"`
 | 
				
			||||||
	Msgqqueued				string	`json:"msgqqueued"`
 | 
						Msgqqueued            string `json:"msgqqueued"`
 | 
				
			||||||
	Msgqsize				string	`json:"msgqsize"`
 | 
						Msgqsize              string `json:"msgqsize"`
 | 
				
			||||||
	Nat						int		`json:"nat"`
 | 
						Nat                   int    `json:"nat"`
 | 
				
			||||||
	Nat_backend				string	`json:"nat_backend"`
 | 
						Nat_backend           string `json:"nat_backend"`
 | 
				
			||||||
	Nat_forwards			string	`json:"nat_forwards"`
 | 
						Nat_forwards          string `json:"nat_forwards"`
 | 
				
			||||||
	Nat_interface			string	`json:"nat_interface"`
 | 
						Nat_interface         string `json:"nat_interface"`
 | 
				
			||||||
	Nat_prefix				string	`json:"nat_prefix"`
 | 
						Nat_prefix            string `json:"nat_prefix"`
 | 
				
			||||||
	Nmsgq					string	`json:"nmsgq"`
 | 
						Nmsgq                 string `json:"nmsgq"`
 | 
				
			||||||
	Notes					string	`json:"notes"`
 | 
						Notes                 string `json:"notes"`
 | 
				
			||||||
	Nsem					string	`json:"nsem"`
 | 
						Nsem                  string `json:"nsem"`
 | 
				
			||||||
	Nsemop					string	`json:"nsemop"`
 | 
						Nsemop                string `json:"nsemop"`
 | 
				
			||||||
	Nshm					string	`json:"nshm"`
 | 
						Nshm                  string `json:"nshm"`
 | 
				
			||||||
	Nthr					string	`json:"nthr"`
 | 
						Nthr                  string `json:"nthr"`
 | 
				
			||||||
	Openfiles				string	`json:"openfiles"`
 | 
						Openfiles             string `json:"openfiles"`
 | 
				
			||||||
	Origin					string	`json:"origin"`
 | 
						Origin                string `json:"origin"`
 | 
				
			||||||
	Owner					string	`json:"owner"`
 | 
						Owner                 string `json:"owner"`
 | 
				
			||||||
	Pcpu					string	`json:"pcpu"`
 | 
						Pcpu                  string `json:"pcpu"`
 | 
				
			||||||
	Plugin_name				string	`json:"plugin_name"`
 | 
						Plugin_name           string `json:"plugin_name"`
 | 
				
			||||||
	Plugin_repository		string	`json:"plugin_repository"`
 | 
						Plugin_repository     string `json:"plugin_repository"`
 | 
				
			||||||
	Priority				string	`json:"priority"`
 | 
						Priority              string `json:"priority"`
 | 
				
			||||||
	Pseudoterminals			string	`json:"pseudoterminals"`
 | 
						Pseudoterminals       string `json:"pseudoterminals"`
 | 
				
			||||||
	Quota					string	`json:"quota"`
 | 
						Quota                 string `json:"quota"`
 | 
				
			||||||
	Readbps					string	`json:"readbps"`
 | 
						Readbps               string `json:"readbps"`
 | 
				
			||||||
	Readiops				string	`json:"readiops"`
 | 
						Readiops              string `json:"readiops"`
 | 
				
			||||||
	Release					string	`json:"release"`
 | 
						Release               string `json:"release"`
 | 
				
			||||||
	Reservation				string	`json:"reservation"`
 | 
						Reservation           string `json:"reservation"`
 | 
				
			||||||
	Resolver				string	`json:"resolver"`
 | 
						Resolver              string `json:"resolver"`
 | 
				
			||||||
	Rlimits					string	`json:"rlimits"`
 | 
						Rlimits               string `json:"rlimits"`
 | 
				
			||||||
	Rtsold					int		`json:"rtsold"`
 | 
						Rtsold                int    `json:"rtsold"`
 | 
				
			||||||
	Securelevel				string	`json:"securelevel"`
 | 
						Securelevel           string `json:"securelevel"`
 | 
				
			||||||
	Shmsize					string	`json:"shmsize"`
 | 
						Shmsize               string `json:"shmsize"`
 | 
				
			||||||
	Stacksize				string	`json:"stacksize"`
 | 
						Stacksize             string `json:"stacksize"`
 | 
				
			||||||
	Stop_timeout			string	`json:"stop_timeout"`
 | 
						Stop_timeout          string `json:"stop_timeout"`
 | 
				
			||||||
	Swapuse					string	`json:"swapuse"`
 | 
						Swapuse               string `json:"swapuse"`
 | 
				
			||||||
	Sync_state				string	`json:"sync_state"`
 | 
						Sync_state            string `json:"sync_state"`
 | 
				
			||||||
	Sync_target				string	`json:"sync_target"`
 | 
						Sync_target           string `json:"sync_target"`
 | 
				
			||||||
	Sync_tgt_zpool			string	`json:"sync_tgt_zpool"`
 | 
						Sync_tgt_zpool        string `json:"sync_tgt_zpool"`
 | 
				
			||||||
	Sysvmsg					string	`json:"sysvmsg"`
 | 
						Sysvmsg               string `json:"sysvmsg"`
 | 
				
			||||||
	Sysvsem					string	`json:"sysvsem"`
 | 
						Sysvsem               string `json:"sysvsem"`
 | 
				
			||||||
	Sysvshm					string	`json:"sysvshm"`
 | 
						Sysvshm               string `json:"sysvshm"`
 | 
				
			||||||
	Template				int		`json:"template"`
 | 
						Template              int    `json:"template"`
 | 
				
			||||||
	// Go don't like a variable named "type" (And i dont care about finding a cleaner way)
 | 
						// Go don't like a variable named "type" (And i dont care about finding a cleaner way)
 | 
				
			||||||
	Jailtype				string	`json:"type"`
 | 
						Jailtype               string `json:"type"`
 | 
				
			||||||
	Used					string	`json:"used"`
 | 
						Used                   string `json:"used"`
 | 
				
			||||||
	Vmemoryuse				string	`json:"vmemoryuse"`
 | 
						Vmemoryuse             string `json:"vmemoryuse"`
 | 
				
			||||||
	Vnet					int		`json:"vnet"`
 | 
						Vnet                   int    `json:"vnet"`
 | 
				
			||||||
	Vnet0_mac				string	`json:"vnet0_mac"`
 | 
						Vnet0_mac              string `json:"vnet0_mac"`
 | 
				
			||||||
	Vnet1_mac				string	`json:"vnet1_mac"`
 | 
						Vnet1_mac              string `json:"vnet1_mac"`
 | 
				
			||||||
	Vnet2_mac				string	`json:"vnet2_mac"`
 | 
						Vnet2_mac              string `json:"vnet2_mac"`
 | 
				
			||||||
	Vnet3_mac				string	`json:"vnet3_mac"`
 | 
						Vnet3_mac              string `json:"vnet3_mac"`
 | 
				
			||||||
	Vnet_default_interface	string	`json:"vnet_default_interface"`
 | 
						Vnet_default_interface string `json:"vnet_default_interface"`
 | 
				
			||||||
	Vnet_interfaces			string	`json:"vnet_interfaces"`
 | 
						Vnet_interfaces        string `json:"vnet_interfaces"`
 | 
				
			||||||
	Wallclock				string	`json:"wallclock"`
 | 
						Wallclock              string `json:"wallclock"`
 | 
				
			||||||
	Writebps				string	`json:"writebps"`
 | 
						Writebps               string `json:"writebps"`
 | 
				
			||||||
	Writeiops				string	`json:"writeiops"`
 | 
						Writeiops              string `json:"writeiops"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Represent an fstab line
 | 
					// Represent an fstab line
 | 
				
			||||||
type Mount struct {
 | 
					type Mount struct {
 | 
				
			||||||
	Device		string
 | 
						Device     string
 | 
				
			||||||
	Mountpoint	string
 | 
						Mountpoint string
 | 
				
			||||||
	Type		string
 | 
						Type       string
 | 
				
			||||||
	Options		[]string
 | 
						Options    []string
 | 
				
			||||||
	Fs_Freq		int
 | 
						Fs_Freq    int
 | 
				
			||||||
	Fs_Passno	int
 | 
						Fs_Passno  int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Snapshot struct {
 | 
					type Snapshot struct {
 | 
				
			||||||
	// snapshot name is stored after '@' in dataset name
 | 
						// snapshot name is stored after '@' in dataset name
 | 
				
			||||||
	Name		string
 | 
						Name       string
 | 
				
			||||||
	Dsname		string
 | 
						Dsname     string
 | 
				
			||||||
	Jailname	string
 | 
						Jailname   string
 | 
				
			||||||
	Mountpoint	string
 | 
						Mountpoint string
 | 
				
			||||||
	Used		string
 | 
						Used       string
 | 
				
			||||||
	Referenced	string
 | 
						Referenced string
 | 
				
			||||||
	Creation	time.Time
 | 
						Creation   time.Time
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fields in this struct are acquired by their name using reflection
 | 
					// Fields in this struct are acquired by their name using reflection
 | 
				
			||||||
//  So these char are forbidden for field name: -+.
 | 
					//  So these char are forbidden for field name: -+.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
type JailSort struct {
 | 
					type JailSort struct {
 | 
				
			||||||
	NameInc					jailLessFunc
 | 
						NameInc         jailLessFunc
 | 
				
			||||||
	NameDec					jailLessFunc
 | 
						NameDec         jailLessFunc
 | 
				
			||||||
	InternalNameInc			jailLessFunc
 | 
						InternalNameInc jailLessFunc
 | 
				
			||||||
	InternalNameDec			jailLessFunc
 | 
						InternalNameDec jailLessFunc
 | 
				
			||||||
	JIDInc					jailLessFunc 
 | 
						JIDInc          jailLessFunc
 | 
				
			||||||
	JIDDec					jailLessFunc 
 | 
						JIDDec          jailLessFunc
 | 
				
			||||||
	RootPathInc				jailLessFunc
 | 
						RootPathInc     jailLessFunc
 | 
				
			||||||
	RootPathDec				jailLessFunc
 | 
						RootPathDec     jailLessFunc
 | 
				
			||||||
	ConfigPathInc			jailLessFunc
 | 
						ConfigPathInc   jailLessFunc
 | 
				
			||||||
	ConfigPathDec			jailLessFunc
 | 
						ConfigPathDec   jailLessFunc
 | 
				
			||||||
	RunningInc				jailLessFunc
 | 
						RunningInc      jailLessFunc
 | 
				
			||||||
	RunningDec				jailLessFunc
 | 
						RunningDec      jailLessFunc
 | 
				
			||||||
    ZpoolInc				jailLessFunc
 | 
						ZpoolInc        jailLessFunc
 | 
				
			||||||
    ZpoolDec				jailLessFunc
 | 
						ZpoolDec        jailLessFunc
 | 
				
			||||||
	Config					JailConfigSort
 | 
						Config          JailConfigSort
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type JailConfigSort struct {
 | 
					type JailConfigSort struct {
 | 
				
			||||||
	Config_versionInc		jailLessFunc
 | 
						Config_versionInc         jailLessFunc
 | 
				
			||||||
	Config_versionDec		jailLessFunc
 | 
						Config_versionDec         jailLessFunc
 | 
				
			||||||
	Allow_chflagsInc		jailLessFunc
 | 
						Allow_chflagsInc          jailLessFunc
 | 
				
			||||||
	Allow_chflagsDec		jailLessFunc
 | 
						Allow_chflagsDec          jailLessFunc
 | 
				
			||||||
	Allow_mlockInc			jailLessFunc
 | 
						Allow_mlockInc            jailLessFunc
 | 
				
			||||||
	Allow_mlockDec			jailLessFunc
 | 
						Allow_mlockDec            jailLessFunc
 | 
				
			||||||
	Allow_mountInc			jailLessFunc
 | 
						Allow_mountInc            jailLessFunc
 | 
				
			||||||
	Allow_mountDec			jailLessFunc
 | 
						Allow_mountDec            jailLessFunc
 | 
				
			||||||
	Allow_mount_devfsInc	jailLessFunc
 | 
						Allow_mount_devfsInc      jailLessFunc
 | 
				
			||||||
	Allow_mount_devfsDec	jailLessFunc
 | 
						Allow_mount_devfsDec      jailLessFunc
 | 
				
			||||||
	Allow_mount_fusefsInc	jailLessFunc
 | 
						Allow_mount_fusefsInc     jailLessFunc
 | 
				
			||||||
	Allow_mount_fusefsDec	jailLessFunc
 | 
						Allow_mount_fusefsDec     jailLessFunc
 | 
				
			||||||
	Allow_mount_nullfsInc	jailLessFunc
 | 
						Allow_mount_nullfsInc     jailLessFunc
 | 
				
			||||||
	Allow_mount_nullfsDec	jailLessFunc
 | 
						Allow_mount_nullfsDec     jailLessFunc
 | 
				
			||||||
	Allow_mount_procfsInc	jailLessFunc
 | 
						Allow_mount_procfsInc     jailLessFunc
 | 
				
			||||||
	Allow_mount_procfsDec	jailLessFunc
 | 
						Allow_mount_procfsDec     jailLessFunc
 | 
				
			||||||
	Allow_mount_tmpfsInc	jailLessFunc
 | 
						Allow_mount_tmpfsInc      jailLessFunc
 | 
				
			||||||
	Allow_mount_tmpfsDec	jailLessFunc
 | 
						Allow_mount_tmpfsDec      jailLessFunc
 | 
				
			||||||
	Allow_mount_zfsInc		jailLessFunc
 | 
						Allow_mount_zfsInc        jailLessFunc
 | 
				
			||||||
	Allow_mount_zfsDec		jailLessFunc
 | 
						Allow_mount_zfsDec        jailLessFunc
 | 
				
			||||||
	Allow_quotasInc			jailLessFunc
 | 
						Allow_quotasInc           jailLessFunc
 | 
				
			||||||
	Allow_quotasDec			jailLessFunc
 | 
						Allow_quotasDec           jailLessFunc
 | 
				
			||||||
	Allow_raw_socketsInc	jailLessFunc
 | 
						Allow_raw_socketsInc      jailLessFunc
 | 
				
			||||||
	Allow_raw_socketsDec	jailLessFunc
 | 
						Allow_raw_socketsDec      jailLessFunc
 | 
				
			||||||
	Allow_set_hostnameInc	jailLessFunc
 | 
						Allow_set_hostnameInc     jailLessFunc
 | 
				
			||||||
	Allow_set_hostnameDec	jailLessFunc
 | 
						Allow_set_hostnameDec     jailLessFunc
 | 
				
			||||||
	Allow_socket_afInc		jailLessFunc
 | 
						Allow_socket_afInc        jailLessFunc
 | 
				
			||||||
	Allow_socket_afDec		jailLessFunc
 | 
						Allow_socket_afDec        jailLessFunc
 | 
				
			||||||
	Allow_sysvipcInc		jailLessFunc
 | 
						Allow_sysvipcInc          jailLessFunc
 | 
				
			||||||
	Allow_sysvipcDec		jailLessFunc
 | 
						Allow_sysvipcDec          jailLessFunc
 | 
				
			||||||
	Allow_tunInc			jailLessFunc
 | 
						Allow_tunInc              jailLessFunc
 | 
				
			||||||
	Allow_tunDec			jailLessFunc
 | 
						Allow_tunDec              jailLessFunc
 | 
				
			||||||
	Allow_vmmInc			jailLessFunc
 | 
						Allow_vmmInc              jailLessFunc
 | 
				
			||||||
	Allow_vmmDec			jailLessFunc
 | 
						Allow_vmmDec              jailLessFunc
 | 
				
			||||||
	Assign_localhostInc		jailLessFunc
 | 
						Assign_localhostInc       jailLessFunc
 | 
				
			||||||
	Assign_localhostDec		jailLessFunc
 | 
						Assign_localhostDec       jailLessFunc
 | 
				
			||||||
	AvailableInc			jailLessFunc
 | 
						AvailableInc              jailLessFunc
 | 
				
			||||||
	AvailableDec			jailLessFunc
 | 
						AvailableDec              jailLessFunc
 | 
				
			||||||
	BasejailInc				jailLessFunc
 | 
						BasejailInc               jailLessFunc
 | 
				
			||||||
	BasejailDec				jailLessFunc
 | 
						BasejailDec               jailLessFunc
 | 
				
			||||||
	BootInc					jailLessFunc
 | 
						BootInc                   jailLessFunc
 | 
				
			||||||
	BootDec					jailLessFunc
 | 
						BootDec                   jailLessFunc
 | 
				
			||||||
	BpfInc					jailLessFunc
 | 
						BpfInc                    jailLessFunc
 | 
				
			||||||
	BpfDec					jailLessFunc
 | 
						BpfDec                    jailLessFunc
 | 
				
			||||||
	Children_maxInc			jailLessFunc
 | 
						Children_maxInc           jailLessFunc
 | 
				
			||||||
	Children_maxDec			jailLessFunc
 | 
						Children_maxDec           jailLessFunc
 | 
				
			||||||
	Cloned_releaseInc		jailLessFunc
 | 
						Cloned_releaseInc         jailLessFunc
 | 
				
			||||||
	Cloned_releaseDec		jailLessFunc
 | 
						Cloned_releaseDec         jailLessFunc
 | 
				
			||||||
	CommentInc				jailLessFunc
 | 
						CommentInc                jailLessFunc
 | 
				
			||||||
	CommentDec				jailLessFunc
 | 
						CommentDec                jailLessFunc
 | 
				
			||||||
	CompressionInc			jailLessFunc
 | 
						CompressionInc            jailLessFunc
 | 
				
			||||||
	CompressionDec			jailLessFunc
 | 
						CompressionDec            jailLessFunc
 | 
				
			||||||
	CompressratioInc		jailLessFunc
 | 
						CompressratioInc          jailLessFunc
 | 
				
			||||||
	CompressratioDec		jailLessFunc
 | 
						CompressratioDec          jailLessFunc
 | 
				
			||||||
	CoredumpsizeInc			jailLessFunc
 | 
						CoredumpsizeInc           jailLessFunc
 | 
				
			||||||
	CoredumpsizeDec			jailLessFunc
 | 
						CoredumpsizeDec           jailLessFunc
 | 
				
			||||||
	CountInc				jailLessFunc
 | 
						CountInc                  jailLessFunc
 | 
				
			||||||
	CountDec				jailLessFunc
 | 
						CountDec                  jailLessFunc
 | 
				
			||||||
	CpusetInc				jailLessFunc
 | 
						CpusetInc                 jailLessFunc
 | 
				
			||||||
	CpusetDec				jailLessFunc
 | 
						CpusetDec                 jailLessFunc
 | 
				
			||||||
	CputimeInc				jailLessFunc
 | 
						CputimeInc                jailLessFunc
 | 
				
			||||||
	CputimeDec				jailLessFunc
 | 
						CputimeDec                jailLessFunc
 | 
				
			||||||
	DatasizeInc				jailLessFunc
 | 
						DatasizeInc               jailLessFunc
 | 
				
			||||||
	DatasizeDec				jailLessFunc
 | 
						DatasizeDec               jailLessFunc
 | 
				
			||||||
	DedupInc				jailLessFunc
 | 
						DedupInc                  jailLessFunc
 | 
				
			||||||
	DedupDec				jailLessFunc
 | 
						DedupDec                  jailLessFunc
 | 
				
			||||||
	DefaultrouterInc		jailLessFunc
 | 
						DefaultrouterInc          jailLessFunc
 | 
				
			||||||
	DefaultrouterDec		jailLessFunc
 | 
						DefaultrouterDec          jailLessFunc
 | 
				
			||||||
	Defaultrouter6Inc		jailLessFunc
 | 
						Defaultrouter6Inc         jailLessFunc
 | 
				
			||||||
	Defaultrouter6Dec		jailLessFunc
 | 
						Defaultrouter6Dec         jailLessFunc
 | 
				
			||||||
	DependsInc				jailLessFunc
 | 
						DependsInc                jailLessFunc
 | 
				
			||||||
	DependsDec				jailLessFunc
 | 
						DependsDec                jailLessFunc
 | 
				
			||||||
	Devfs_rulesetInc		jailLessFunc
 | 
						Devfs_rulesetInc          jailLessFunc
 | 
				
			||||||
	Devfs_rulesetDec		jailLessFunc
 | 
						Devfs_rulesetDec          jailLessFunc
 | 
				
			||||||
	DhcpInc					jailLessFunc
 | 
						DhcpInc                   jailLessFunc
 | 
				
			||||||
	DhcpDec					jailLessFunc
 | 
						DhcpDec                   jailLessFunc
 | 
				
			||||||
	Enforce_statfsInc		jailLessFunc
 | 
						Enforce_statfsInc         jailLessFunc
 | 
				
			||||||
	Enforce_statfsDec		jailLessFunc
 | 
						Enforce_statfsDec         jailLessFunc
 | 
				
			||||||
	Exec_cleanInc			jailLessFunc
 | 
						Exec_cleanInc             jailLessFunc
 | 
				
			||||||
	Exec_cleanDec			jailLessFunc
 | 
						Exec_cleanDec             jailLessFunc
 | 
				
			||||||
	Exec_createdInc			jailLessFunc
 | 
						Exec_createdInc           jailLessFunc
 | 
				
			||||||
	Exec_createdDec			jailLessFunc
 | 
						Exec_createdDec           jailLessFunc
 | 
				
			||||||
	Exec_fibInc				jailLessFunc
 | 
						Exec_fibInc               jailLessFunc
 | 
				
			||||||
	Exec_fibDec				jailLessFunc
 | 
						Exec_fibDec               jailLessFunc
 | 
				
			||||||
	Exec_jail_userInc		jailLessFunc
 | 
						Exec_jail_userInc         jailLessFunc
 | 
				
			||||||
	Exec_jail_userDec		jailLessFunc
 | 
						Exec_jail_userDec         jailLessFunc
 | 
				
			||||||
	Exec_poststartInc		jailLessFunc
 | 
						Exec_poststartInc         jailLessFunc
 | 
				
			||||||
	Exec_poststartDec		jailLessFunc
 | 
						Exec_poststartDec         jailLessFunc
 | 
				
			||||||
	Exec_poststopInc		jailLessFunc
 | 
						Exec_poststopInc          jailLessFunc
 | 
				
			||||||
	Exec_poststopDec		jailLessFunc
 | 
						Exec_poststopDec          jailLessFunc
 | 
				
			||||||
	Exec_prestartInc		jailLessFunc
 | 
						Exec_prestartInc          jailLessFunc
 | 
				
			||||||
	Exec_prestartDec		jailLessFunc
 | 
						Exec_prestartDec          jailLessFunc
 | 
				
			||||||
	Exec_prestopInc			jailLessFunc
 | 
						Exec_prestopInc           jailLessFunc
 | 
				
			||||||
	Exec_prestopDec			jailLessFunc
 | 
						Exec_prestopDec           jailLessFunc
 | 
				
			||||||
	Exec_startInc			jailLessFunc
 | 
						Exec_startInc             jailLessFunc
 | 
				
			||||||
	Exec_startDec			jailLessFunc
 | 
						Exec_startDec             jailLessFunc
 | 
				
			||||||
	Exec_stopInc			jailLessFunc
 | 
						Exec_stopInc              jailLessFunc
 | 
				
			||||||
	Exec_stopDec			jailLessFunc
 | 
						Exec_stopDec              jailLessFunc
 | 
				
			||||||
	Exec_system_jail_userInc	jailLessFunc
 | 
						Exec_system_jail_userInc  jailLessFunc
 | 
				
			||||||
	Exec_system_jail_userDec	jailLessFunc
 | 
						Exec_system_jail_userDec  jailLessFunc
 | 
				
			||||||
	Exec_system_userInc		jailLessFunc
 | 
						Exec_system_userInc       jailLessFunc
 | 
				
			||||||
	Exec_system_userDec		jailLessFunc
 | 
						Exec_system_userDec       jailLessFunc
 | 
				
			||||||
	Exec_timeoutInc			jailLessFunc
 | 
						Exec_timeoutInc           jailLessFunc
 | 
				
			||||||
	Exec_timeoutDec			jailLessFunc
 | 
						Exec_timeoutDec           jailLessFunc
 | 
				
			||||||
	Host_domainnameInc		jailLessFunc
 | 
						Host_domainnameInc        jailLessFunc
 | 
				
			||||||
	Host_domainnameDec		jailLessFunc
 | 
						Host_domainnameDec        jailLessFunc
 | 
				
			||||||
	Host_hostnameInc		jailLessFunc
 | 
						Host_hostnameInc          jailLessFunc
 | 
				
			||||||
	Host_hostnameDec		jailLessFunc
 | 
						Host_hostnameDec          jailLessFunc
 | 
				
			||||||
	Host_hostuuidInc		jailLessFunc
 | 
						Host_hostuuidInc          jailLessFunc
 | 
				
			||||||
	Host_hostuuidDec		jailLessFunc
 | 
						Host_hostuuidDec          jailLessFunc
 | 
				
			||||||
	Host_timeInc			jailLessFunc
 | 
						Host_timeInc              jailLessFunc
 | 
				
			||||||
	Host_timeDec			jailLessFunc
 | 
						Host_timeDec              jailLessFunc
 | 
				
			||||||
	HostidInc				jailLessFunc
 | 
						HostidInc                 jailLessFunc
 | 
				
			||||||
	HostidDec				jailLessFunc
 | 
						HostidDec                 jailLessFunc
 | 
				
			||||||
	Hostid_strict_checkInc	jailLessFunc
 | 
						Hostid_strict_checkInc    jailLessFunc
 | 
				
			||||||
	Hostid_strict_checkDec	jailLessFunc
 | 
						Hostid_strict_checkDec    jailLessFunc
 | 
				
			||||||
	InterfacesInc			jailLessFunc
 | 
						InterfacesInc             jailLessFunc
 | 
				
			||||||
	InterfacesDec			jailLessFunc
 | 
						InterfacesDec             jailLessFunc
 | 
				
			||||||
	Ip4Inc					jailLessFunc
 | 
						Ip4Inc                    jailLessFunc
 | 
				
			||||||
	Ip4Dec					jailLessFunc
 | 
						Ip4Dec                    jailLessFunc
 | 
				
			||||||
	Ip4_addrInc				jailLessFunc
 | 
						Ip4_addrInc               jailLessFunc
 | 
				
			||||||
	Ip4_addrDec				jailLessFunc
 | 
						Ip4_addrDec               jailLessFunc
 | 
				
			||||||
	Ip4_saddrselInc			jailLessFunc
 | 
						Ip4_saddrselInc           jailLessFunc
 | 
				
			||||||
	Ip4_saddrselDec			jailLessFunc
 | 
						Ip4_saddrselDec           jailLessFunc
 | 
				
			||||||
	Ip6Inc					jailLessFunc
 | 
						Ip6Inc                    jailLessFunc
 | 
				
			||||||
	Ip6Dec					jailLessFunc
 | 
						Ip6Dec                    jailLessFunc
 | 
				
			||||||
	Ip6_addrInc				jailLessFunc
 | 
						Ip6_addrInc               jailLessFunc
 | 
				
			||||||
	Ip6_addrDec				jailLessFunc
 | 
						Ip6_addrDec               jailLessFunc
 | 
				
			||||||
	Ip6_saddrselInc			jailLessFunc
 | 
						Ip6_saddrselInc           jailLessFunc
 | 
				
			||||||
	Ip6_saddrselDec			jailLessFunc
 | 
						Ip6_saddrselDec           jailLessFunc
 | 
				
			||||||
	Ip_hostnameInc			jailLessFunc
 | 
						Ip_hostnameInc            jailLessFunc
 | 
				
			||||||
	Ip_hostnameDec			jailLessFunc
 | 
						Ip_hostnameDec            jailLessFunc
 | 
				
			||||||
	Jail_zfsInc				jailLessFunc
 | 
						Jail_zfsInc               jailLessFunc
 | 
				
			||||||
	Jail_zfsDec				jailLessFunc
 | 
						Jail_zfsDec               jailLessFunc
 | 
				
			||||||
	Jail_zfs_datasetInc		jailLessFunc
 | 
						Jail_zfs_datasetInc       jailLessFunc
 | 
				
			||||||
	Jail_zfs_datasetDec		jailLessFunc
 | 
						Jail_zfs_datasetDec       jailLessFunc
 | 
				
			||||||
	Jail_zfs_mountpointInc	jailLessFunc
 | 
						Jail_zfs_mountpointInc    jailLessFunc
 | 
				
			||||||
	Jail_zfs_mountpointDec	jailLessFunc
 | 
						Jail_zfs_mountpointDec    jailLessFunc
 | 
				
			||||||
	Last_startedInc			jailLessFunc
 | 
						Last_startedInc           jailLessFunc
 | 
				
			||||||
	Last_startedDec			jailLessFunc
 | 
						Last_startedDec           jailLessFunc
 | 
				
			||||||
	Localhost_ipInc			jailLessFunc
 | 
						Localhost_ipInc           jailLessFunc
 | 
				
			||||||
	Localhost_ipDec			jailLessFunc
 | 
						Localhost_ipDec           jailLessFunc
 | 
				
			||||||
	Login_flagsInc			jailLessFunc
 | 
						Login_flagsInc            jailLessFunc
 | 
				
			||||||
	Login_flagsDec			jailLessFunc
 | 
						Login_flagsDec            jailLessFunc
 | 
				
			||||||
	Mac_prefixInc			jailLessFunc
 | 
						Mac_prefixInc             jailLessFunc
 | 
				
			||||||
	Mac_prefixDec			jailLessFunc
 | 
						Mac_prefixDec             jailLessFunc
 | 
				
			||||||
	MaxprocInc				jailLessFunc
 | 
						MaxprocInc                jailLessFunc
 | 
				
			||||||
	MaxprocDec				jailLessFunc
 | 
						MaxprocDec                jailLessFunc
 | 
				
			||||||
	MemorylockedInc			jailLessFunc
 | 
						MemorylockedInc           jailLessFunc
 | 
				
			||||||
	MemorylockedDec			jailLessFunc
 | 
						MemorylockedDec           jailLessFunc
 | 
				
			||||||
	MemoryuseInc			jailLessFunc
 | 
						MemoryuseInc              jailLessFunc
 | 
				
			||||||
	MemoryuseDec			jailLessFunc
 | 
						MemoryuseDec              jailLessFunc
 | 
				
			||||||
	Min_dyn_devfs_rulesetInc	jailLessFunc
 | 
						Min_dyn_devfs_rulesetInc  jailLessFunc
 | 
				
			||||||
	Min_dyn_devfs_rulesetDec	jailLessFunc
 | 
						Min_dyn_devfs_rulesetDec  jailLessFunc
 | 
				
			||||||
	Mount_devfsInc			jailLessFunc
 | 
						Mount_devfsInc            jailLessFunc
 | 
				
			||||||
	Mount_devfsDec			jailLessFunc
 | 
						Mount_devfsDec            jailLessFunc
 | 
				
			||||||
	Mount_fdescfsInc		jailLessFunc
 | 
						Mount_fdescfsInc          jailLessFunc
 | 
				
			||||||
	Mount_fdescfsDec		jailLessFunc
 | 
						Mount_fdescfsDec          jailLessFunc
 | 
				
			||||||
	Mount_linprocfsInc		jailLessFunc
 | 
						Mount_linprocfsInc        jailLessFunc
 | 
				
			||||||
	Mount_linprocfsDec		jailLessFunc
 | 
						Mount_linprocfsDec        jailLessFunc
 | 
				
			||||||
	Mount_procfsInc			jailLessFunc
 | 
						Mount_procfsInc           jailLessFunc
 | 
				
			||||||
	Mount_procfsDec			jailLessFunc
 | 
						Mount_procfsDec           jailLessFunc
 | 
				
			||||||
	MountpointInc			jailLessFunc
 | 
						MountpointInc             jailLessFunc
 | 
				
			||||||
	MountpointDec			jailLessFunc
 | 
						MountpointDec             jailLessFunc
 | 
				
			||||||
	MsgqqueuedInc			jailLessFunc
 | 
						MsgqqueuedInc             jailLessFunc
 | 
				
			||||||
	MsgqqueuedDec			jailLessFunc
 | 
						MsgqqueuedDec             jailLessFunc
 | 
				
			||||||
	MsgqsizeInc				jailLessFunc
 | 
						MsgqsizeInc               jailLessFunc
 | 
				
			||||||
	MsgqsizeDec				jailLessFunc
 | 
						MsgqsizeDec               jailLessFunc
 | 
				
			||||||
	NatInc					jailLessFunc
 | 
						NatInc                    jailLessFunc
 | 
				
			||||||
	NatDec					jailLessFunc
 | 
						NatDec                    jailLessFunc
 | 
				
			||||||
	Nat_backendInc			jailLessFunc
 | 
						Nat_backendInc            jailLessFunc
 | 
				
			||||||
	Nat_backendDec			jailLessFunc
 | 
						Nat_backendDec            jailLessFunc
 | 
				
			||||||
	Nat_forwardsInc			jailLessFunc
 | 
						Nat_forwardsInc           jailLessFunc
 | 
				
			||||||
	Nat_forwardsDec			jailLessFunc
 | 
						Nat_forwardsDec           jailLessFunc
 | 
				
			||||||
	Nat_interfaceInc		jailLessFunc
 | 
						Nat_interfaceInc          jailLessFunc
 | 
				
			||||||
	Nat_interfaceDec		jailLessFunc
 | 
						Nat_interfaceDec          jailLessFunc
 | 
				
			||||||
	Nat_prefixInc			jailLessFunc
 | 
						Nat_prefixInc             jailLessFunc
 | 
				
			||||||
	Nat_prefixDec			jailLessFunc
 | 
						Nat_prefixDec             jailLessFunc
 | 
				
			||||||
	NmsgqInc				jailLessFunc
 | 
						NmsgqInc                  jailLessFunc
 | 
				
			||||||
	NmsgqDec				jailLessFunc
 | 
						NmsgqDec                  jailLessFunc
 | 
				
			||||||
	NotesInc				jailLessFunc
 | 
						NotesInc                  jailLessFunc
 | 
				
			||||||
	NotesDec				jailLessFunc
 | 
						NotesDec                  jailLessFunc
 | 
				
			||||||
	NsemInc					jailLessFunc
 | 
						NsemInc                   jailLessFunc
 | 
				
			||||||
	NsemDec					jailLessFunc
 | 
						NsemDec                   jailLessFunc
 | 
				
			||||||
	NsemopInc				jailLessFunc
 | 
						NsemopInc                 jailLessFunc
 | 
				
			||||||
	NsemopDec				jailLessFunc
 | 
						NsemopDec                 jailLessFunc
 | 
				
			||||||
	NshmInc					jailLessFunc
 | 
						NshmInc                   jailLessFunc
 | 
				
			||||||
	NshmDec					jailLessFunc
 | 
						NshmDec                   jailLessFunc
 | 
				
			||||||
	NthrInc					jailLessFunc
 | 
						NthrInc                   jailLessFunc
 | 
				
			||||||
	NthrDec					jailLessFunc
 | 
						NthrDec                   jailLessFunc
 | 
				
			||||||
	OpenfilesInc			jailLessFunc
 | 
						OpenfilesInc              jailLessFunc
 | 
				
			||||||
	OpenfilesDec			jailLessFunc
 | 
						OpenfilesDec              jailLessFunc
 | 
				
			||||||
	OriginInc				jailLessFunc
 | 
						OriginInc                 jailLessFunc
 | 
				
			||||||
	OriginDec				jailLessFunc
 | 
						OriginDec                 jailLessFunc
 | 
				
			||||||
	OwnerInc				jailLessFunc
 | 
						OwnerInc                  jailLessFunc
 | 
				
			||||||
	OwnerDec				jailLessFunc
 | 
						OwnerDec                  jailLessFunc
 | 
				
			||||||
	PcpuInc					jailLessFunc
 | 
						PcpuInc                   jailLessFunc
 | 
				
			||||||
	PcpuDec					jailLessFunc
 | 
						PcpuDec                   jailLessFunc
 | 
				
			||||||
	Plugin_nameInc			jailLessFunc
 | 
						Plugin_nameInc            jailLessFunc
 | 
				
			||||||
	Plugin_nameDec			jailLessFunc
 | 
						Plugin_nameDec            jailLessFunc
 | 
				
			||||||
	Plugin_repositoryInc	jailLessFunc
 | 
						Plugin_repositoryInc      jailLessFunc
 | 
				
			||||||
	Plugin_repositoryDec	jailLessFunc
 | 
						Plugin_repositoryDec      jailLessFunc
 | 
				
			||||||
	PriorityInc				jailLessFunc
 | 
						PriorityInc               jailLessFunc
 | 
				
			||||||
	PriorityDec				jailLessFunc
 | 
						PriorityDec               jailLessFunc
 | 
				
			||||||
	PseudoterminalsInc		jailLessFunc
 | 
						PseudoterminalsInc        jailLessFunc
 | 
				
			||||||
	PseudoterminalsDec		jailLessFunc
 | 
						PseudoterminalsDec        jailLessFunc
 | 
				
			||||||
	QuotaInc				jailLessFunc
 | 
						QuotaInc                  jailLessFunc
 | 
				
			||||||
	QuotaDec				jailLessFunc
 | 
						QuotaDec                  jailLessFunc
 | 
				
			||||||
	ReadbpsInc				jailLessFunc
 | 
						ReadbpsInc                jailLessFunc
 | 
				
			||||||
	ReadbpsDec				jailLessFunc
 | 
						ReadbpsDec                jailLessFunc
 | 
				
			||||||
	ReadiopsInc				jailLessFunc
 | 
						ReadiopsInc               jailLessFunc
 | 
				
			||||||
	ReadiopsDec				jailLessFunc
 | 
						ReadiopsDec               jailLessFunc
 | 
				
			||||||
	ReleaseInc				jailLessFunc
 | 
						ReleaseInc                jailLessFunc
 | 
				
			||||||
	ReleaseDec				jailLessFunc
 | 
						ReleaseDec                jailLessFunc
 | 
				
			||||||
	ReservationInc			jailLessFunc
 | 
						ReservationInc            jailLessFunc
 | 
				
			||||||
	ReservationDec			jailLessFunc
 | 
						ReservationDec            jailLessFunc
 | 
				
			||||||
	ResolverInc				jailLessFunc
 | 
						ResolverInc               jailLessFunc
 | 
				
			||||||
	ResolverDec				jailLessFunc
 | 
						ResolverDec               jailLessFunc
 | 
				
			||||||
	RlimitsInc				jailLessFunc
 | 
						RlimitsInc                jailLessFunc
 | 
				
			||||||
	RlimitsDec				jailLessFunc
 | 
						RlimitsDec                jailLessFunc
 | 
				
			||||||
	RtsoldInc				jailLessFunc
 | 
						RtsoldInc                 jailLessFunc
 | 
				
			||||||
	RtsoldDec				jailLessFunc
 | 
						RtsoldDec                 jailLessFunc
 | 
				
			||||||
	SecurelevelInc			jailLessFunc	
 | 
						SecurelevelInc            jailLessFunc
 | 
				
			||||||
	SecurelevelDec			jailLessFunc	
 | 
						SecurelevelDec            jailLessFunc
 | 
				
			||||||
	ShmsizeInc				jailLessFunc	
 | 
						ShmsizeInc                jailLessFunc
 | 
				
			||||||
	ShmsizeDec				jailLessFunc	
 | 
						ShmsizeDec                jailLessFunc
 | 
				
			||||||
	StacksizeInc			jailLessFunc
 | 
						StacksizeInc              jailLessFunc
 | 
				
			||||||
	StacksizeDec			jailLessFunc
 | 
						StacksizeDec              jailLessFunc
 | 
				
			||||||
	Stop_timeoutInc			jailLessFunc
 | 
						Stop_timeoutInc           jailLessFunc
 | 
				
			||||||
	Stop_timeoutDec			jailLessFunc
 | 
						Stop_timeoutDec           jailLessFunc
 | 
				
			||||||
	SwapuseInc				jailLessFunc
 | 
						SwapuseInc                jailLessFunc
 | 
				
			||||||
	SwapuseDec				jailLessFunc
 | 
						SwapuseDec                jailLessFunc
 | 
				
			||||||
	Sync_stateInc			jailLessFunc
 | 
						Sync_stateInc             jailLessFunc
 | 
				
			||||||
	Sync_stateDec			jailLessFunc
 | 
						Sync_stateDec             jailLessFunc
 | 
				
			||||||
	Sync_targetInc			jailLessFunc
 | 
						Sync_targetInc            jailLessFunc
 | 
				
			||||||
	Sync_targetDec			jailLessFunc
 | 
						Sync_targetDec            jailLessFunc
 | 
				
			||||||
	Sync_tgt_zpoolInc		jailLessFunc
 | 
						Sync_tgt_zpoolInc         jailLessFunc
 | 
				
			||||||
	Sync_tgt_zpoolDec		jailLessFunc
 | 
						Sync_tgt_zpoolDec         jailLessFunc
 | 
				
			||||||
	SysvmsgInc				jailLessFunc
 | 
						SysvmsgInc                jailLessFunc
 | 
				
			||||||
	SysvmsgDec				jailLessFunc
 | 
						SysvmsgDec                jailLessFunc
 | 
				
			||||||
	SysvsemInc				jailLessFunc	
 | 
						SysvsemInc                jailLessFunc
 | 
				
			||||||
	SysvsemDec				jailLessFunc	
 | 
						SysvsemDec                jailLessFunc
 | 
				
			||||||
	SysvshmInc				jailLessFunc	
 | 
						SysvshmInc                jailLessFunc
 | 
				
			||||||
	SysvshmDec				jailLessFunc	
 | 
						SysvshmDec                jailLessFunc
 | 
				
			||||||
	TemplateInc				jailLessFunc
 | 
						TemplateInc               jailLessFunc
 | 
				
			||||||
	TemplateDec				jailLessFunc
 | 
						TemplateDec               jailLessFunc
 | 
				
			||||||
	JailtypeInc				jailLessFunc
 | 
						JailtypeInc               jailLessFunc
 | 
				
			||||||
	JailtypeDec				jailLessFunc
 | 
						JailtypeDec               jailLessFunc
 | 
				
			||||||
	UsedInc					jailLessFunc
 | 
						UsedInc                   jailLessFunc
 | 
				
			||||||
	UsedDec					jailLessFunc
 | 
						UsedDec                   jailLessFunc
 | 
				
			||||||
	VmemoryuseInc			jailLessFunc
 | 
						VmemoryuseInc             jailLessFunc
 | 
				
			||||||
	VmemoryuseDec			jailLessFunc
 | 
						VmemoryuseDec             jailLessFunc
 | 
				
			||||||
	VnetInc					jailLessFunc
 | 
						VnetInc                   jailLessFunc
 | 
				
			||||||
	VnetDec					jailLessFunc
 | 
						VnetDec                   jailLessFunc
 | 
				
			||||||
	Vnet0_macInc			jailLessFunc
 | 
						Vnet0_macInc              jailLessFunc
 | 
				
			||||||
	Vnet0_macDec			jailLessFunc
 | 
						Vnet0_macDec              jailLessFunc
 | 
				
			||||||
	Vnet1_macInc			jailLessFunc
 | 
						Vnet1_macInc              jailLessFunc
 | 
				
			||||||
	Vnet1_macDec			jailLessFunc
 | 
						Vnet1_macDec              jailLessFunc
 | 
				
			||||||
	Vnet2_macInc			jailLessFunc
 | 
						Vnet2_macInc              jailLessFunc
 | 
				
			||||||
	Vnet2_macDec			jailLessFunc
 | 
						Vnet2_macDec              jailLessFunc
 | 
				
			||||||
	Vnet3_macInc			jailLessFunc
 | 
						Vnet3_macInc              jailLessFunc
 | 
				
			||||||
	Vnet3_macDec			jailLessFunc
 | 
						Vnet3_macDec              jailLessFunc
 | 
				
			||||||
	Vnet_default_interfaceInc	jailLessFunc
 | 
						Vnet_default_interfaceInc jailLessFunc
 | 
				
			||||||
	Vnet_default_interfaceDec	jailLessFunc
 | 
						Vnet_default_interfaceDec jailLessFunc
 | 
				
			||||||
	Vnet_interfacesInc		jailLessFunc
 | 
						Vnet_interfacesInc        jailLessFunc
 | 
				
			||||||
	Vnet_interfacesDec		jailLessFunc
 | 
						Vnet_interfacesDec        jailLessFunc
 | 
				
			||||||
	WallclockInc			jailLessFunc
 | 
						WallclockInc              jailLessFunc
 | 
				
			||||||
	WallclockDec			jailLessFunc
 | 
						WallclockDec              jailLessFunc
 | 
				
			||||||
	WritebpsInc				jailLessFunc
 | 
						WritebpsInc               jailLessFunc
 | 
				
			||||||
	WritebpsDec				jailLessFunc
 | 
						WritebpsDec               jailLessFunc
 | 
				
			||||||
	WriteiopsInc			jailLessFunc
 | 
						WriteiopsInc              jailLessFunc
 | 
				
			||||||
	WriteiopsDec			jailLessFunc
 | 
						WriteiopsDec              jailLessFunc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SnapshotSort struct {
 | 
					type SnapshotSort struct {
 | 
				
			||||||
	NameInc					snapshotLessFunc
 | 
						NameInc       snapshotLessFunc
 | 
				
			||||||
	NameDec					snapshotLessFunc
 | 
						NameDec       snapshotLessFunc
 | 
				
			||||||
	DsnameInc				snapshotLessFunc
 | 
						DsnameInc     snapshotLessFunc
 | 
				
			||||||
	DsnameDec				snapshotLessFunc
 | 
						DsnameDec     snapshotLessFunc
 | 
				
			||||||
	JailnameInc				snapshotLessFunc
 | 
						JailnameInc   snapshotLessFunc
 | 
				
			||||||
	JailnameDec				snapshotLessFunc
 | 
						JailnameDec   snapshotLessFunc
 | 
				
			||||||
	MountpointInc			snapshotLessFunc 
 | 
						MountpointInc snapshotLessFunc
 | 
				
			||||||
	MountpointDec			snapshotLessFunc 
 | 
						MountpointDec snapshotLessFunc
 | 
				
			||||||
	UsedInc					snapshotLessFunc
 | 
						UsedInc       snapshotLessFunc
 | 
				
			||||||
	UsedDec					snapshotLessFunc
 | 
						UsedDec       snapshotLessFunc
 | 
				
			||||||
	ReferencedInc			snapshotLessFunc
 | 
						ReferencedInc snapshotLessFunc
 | 
				
			||||||
	ReferencedDec			snapshotLessFunc
 | 
						ReferencedDec snapshotLessFunc
 | 
				
			||||||
	CreationInc				snapshotLessFunc
 | 
						CreationInc   snapshotLessFunc
 | 
				
			||||||
	CreationDec				snapshotLessFunc
 | 
						CreationDec   snapshotLessFunc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type JailHost struct {
 | 
					type JailHost struct {
 | 
				
			||||||
	hostname			string
 | 
						hostname          string
 | 
				
			||||||
	hostid				string
 | 
						hostid            string
 | 
				
			||||||
	default_gateway4	string
 | 
						default_gateway4  string
 | 
				
			||||||
	default_gateway6	string
 | 
						default_gateway6  string
 | 
				
			||||||
	default_interface	string
 | 
						default_interface string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										721
									
								
								cmd/utils.go
									
									
									
									
									
								
							
							
						
						
									
										721
									
								
								cmd/utils.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@ -3,6 +3,8 @@ module gocage
 | 
				
			|||||||
go 1.17
 | 
					go 1.17
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					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/cobra v1.2.1
 | 
				
			||||||
	github.com/spf13/viper v1.9.0
 | 
						github.com/spf13/viper v1.9.0
 | 
				
			||||||
	golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420
 | 
						golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user