WIP on start, go fmt on *
This commit is contained in:
		@ -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}
 | 
				
			||||||
@ -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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										61
									
								
								cmd/list.go
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								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"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
@ -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
 | 
				
			||||||
	/**************************************************************/
 | 
						/**************************************************************/
 | 
				
			||||||
@ -124,9 +123,12 @@ func ListJails(args []string, display bool) {
 | 
				
			|||||||
				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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -148,25 +150,33 @@ 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 {
 | 
				
			||||||
@ -174,7 +184,9 @@ func listJailsFromDirectory(dir string) ([]Jail) {
 | 
				
			|||||||
			// 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
 | 
								// 2. Build jail object from config
 | 
				
			||||||
			jailRootPath := fmt.Sprintf("%s/%s/%s", dir, fi.Name(), "root")
 | 
								jailRootPath := fmt.Sprintf("%s/%s/%s", dir, fi.Name(), "root")
 | 
				
			||||||
@ -188,7 +200,9 @@ func listJailsFromDirectory(dir string) ([]Jail) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// 3. Add current running informations
 | 
								// 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
 | 
				
			||||||
@ -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,11 +1,11 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetJailProperties(args []string) {
 | 
					func GetJailProperties(args []string) {
 | 
				
			||||||
@ -120,5 +120,3 @@ func SetJailProperties(args []string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										16
									
								
								cmd/root.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								cmd/root.go
									
									
									
									
									
								
							@ -1,19 +1,21 @@
 | 
				
			|||||||
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 (
 | 
				
			||||||
@ -189,8 +191,7 @@ You can specify multiple jails.`,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO : Init log level and log output
 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	cobra.OnInitialize(initConfig)
 | 
						cobra.OnInitialize(initConfig)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -292,7 +293,6 @@ 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
 | 
				
			||||||
@ -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"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
@ -39,7 +39,6 @@ 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
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
@ -89,7 +88,6 @@ func listJailSnapshots(jail Jail) []Snapshot {
 | 
				
			|||||||
	return snapshots
 | 
						return snapshots
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
 * Create snapshot for jail(s)
 | 
					 * Create snapshot for jail(s)
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										314
									
								
								cmd/start.go
									
									
									
									
									
								
							
							
						
						
									
										314
									
								
								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?!
 | 
				
			||||||
@ -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
 | 
				
			||||||
@ -189,7 +191,6 @@ 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 {
 | 
				
			||||||
@ -281,6 +282,216 @@ func getNatForwardsArray(nat_forwards string, decompose_range bool) ([]NatDesc,
 | 
				
			|||||||
	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,6 +520,7 @@ 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)
 | 
				
			||||||
@ -344,8 +556,8 @@ func StartJail(args []string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		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))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -403,7 +615,48 @@ func StartJail(args []string) {
 | 
				
			|||||||
			// "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)
 | 
				
			||||||
@ -423,6 +676,46 @@ func StartJail(args []string) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// TODO : Check capabilites relative to FreeBSD Version when executing jail with all parameters
 | 
				
			||||||
 | 
							//        See l.335 of https://github.com/iocage/iocage/blob/e94863d4c54f02523fb09e62e48be7db9ac92eda/iocage_lib/ioc_start.py
 | 
				
			||||||
 | 
							//checkCapabilities(cj)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check NAT backend
 | 
				
			||||||
 | 
							if cj.Config.Nat > 0 {
 | 
				
			||||||
 | 
								log.Debug("Check NAT backend %s\n", cj.Config.Nat_backend)
 | 
				
			||||||
 | 
								err = checkNat(cj.Config.Nat_backend)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									fmt.Printf(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 {
 | 
				
			||||||
 | 
									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]
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// CONTINUE HERE
 | 
				
			||||||
 | 
							// See https://github.com/iocage/iocage/blob/e94863d4c54f02523fb09e62e48be7db9ac92eda/iocage_lib/ioc_start.py:401
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
			out, err := executeCommand(fmt.Sprintf("rctl jail:%s", cj.InternalName))
 | 
								out, err := executeCommand(fmt.Sprintf("rctl jail:%s", cj.InternalName))
 | 
				
			||||||
@ -495,4 +788,3 @@ func StartJail(args []string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,12 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	//	"log"
 | 
						//	"log"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
	//	"reflect"
 | 
						//	"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
 | 
				
			||||||
@ -79,7 +78,6 @@ func umountAndUnjailZFS(jail *Jail) error {
 | 
				
			|||||||
	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"
 | 
				
			||||||
@ -340,4 +336,3 @@ func StopJail(args []string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,11 @@ 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
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										95
									
								
								cmd/utils.go
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								cmd/utils.go
									
									
									
									
									
								
							@ -1,19 +1,23 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
	"bufio"
 | 
						"bufio"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"strings"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"io/ioutil"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						ipv4re         = `[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}`
 | 
				
			||||||
 | 
						ifconfigipv4re = `inet[[:space:]](` + ipv4re + `)`
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*****************************************************************************
 | 
					/*****************************************************************************
 | 
				
			||||||
 * Mandatory constructor for JailConfig type. It set default values
 | 
					 * Mandatory constructor for JailConfig type. It set default values
 | 
				
			||||||
@ -186,7 +190,6 @@ func executeCommand(cmdline string) (string, error) {
 | 
				
			|||||||
	return string(out), err
 | 
						return string(out), err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
func executeCommandInJail(jail *Jail, cmdline string) (string, error) {
 | 
					func executeCommandInJail(jail *Jail, cmdline string) (string, error) {
 | 
				
			||||||
	var cmd []string
 | 
						var cmd []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -251,7 +254,6 @@ func getFstab(path string) ([]Mount, error) {
 | 
				
			|||||||
	return mounts, nil
 | 
						return mounts, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
 * Get a specific jail source reference, to update properties after a range loop
 | 
					 * Get a specific jail source reference, to update properties after a range loop
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
@ -337,7 +339,8 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
 | 
				
			|||||||
	v := reflect.ValueOf(parentStruct)
 | 
						v := reflect.ValueOf(parentStruct)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get value while we're dealing with pointers
 | 
						// Get value while we're dealing with pointers
 | 
				
			||||||
	for ; v.Kind() == reflect.Ptr ; v = v.Elem() {}
 | 
						for ; v.Kind() == reflect.Ptr; v = v.Elem() {
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if v.Kind() != reflect.Struct {
 | 
						if v.Kind() != reflect.Struct {
 | 
				
			||||||
		return &v, fieldName, errors.New(fmt.Sprintf("parentStruct is not a struct! Kind: %s", v.Kind().String()))
 | 
							return &v, fieldName, errors.New(fmt.Sprintf("parentStruct is not a struct! Kind: %s", v.Kind().String()))
 | 
				
			||||||
@ -372,7 +375,8 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
 | 
				
			|||||||
			return &v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
 | 
								return &v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ; f.Kind() == reflect.Ptr ; f = f.Elem() {}
 | 
							for ; f.Kind() == reflect.Ptr; f = f.Elem() {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*fmt.Printf("v.kind() = %v\n", v.Kind().String())
 | 
							/*fmt.Printf("v.kind() = %v\n", v.Kind().String())
 | 
				
			||||||
		fmt.Printf("v = %v\n", v)
 | 
							fmt.Printf("v = %v\n", v)
 | 
				
			||||||
@ -397,7 +401,6 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V
 | 
				
			|||||||
	return &v, fieldName, nil
 | 
						return &v, fieldName, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/********************************************************************************
 | 
					/********************************************************************************
 | 
				
			||||||
 * TODO : Replace by getStructFieldValue
 | 
					 * TODO : Replace by getStructFieldValue
 | 
				
			||||||
 * Recurse into structure, returning reflect.Value of wanted field.
 | 
					 * Recurse into structure, returning reflect.Value of wanted field.
 | 
				
			||||||
@ -567,13 +570,16 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
 | 
				
			|||||||
	// Lets draw things on the screen!
 | 
						// Lets draw things on the screen!
 | 
				
			||||||
	// First, headers: 1st separator line
 | 
						// First, headers: 1st separator line
 | 
				
			||||||
	for i, f := range out[0] {
 | 
						for i, f := range out[0] {
 | 
				
			||||||
		if i == 0 {	fmt.Printf("+")	}
 | 
							if i == 0 {
 | 
				
			||||||
		for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("=")	}
 | 
								fmt.Printf("+")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
								fmt.Printf("=")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		fmt.Printf("+")
 | 
							fmt.Printf("+")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Printf("\n")
 | 
						fmt.Printf("\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	//  Column names
 | 
						//  Column names
 | 
				
			||||||
	for i, f := range out[0] {
 | 
						for i, f := range out[0] {
 | 
				
			||||||
		if i == 0 {
 | 
							if i == 0 {
 | 
				
			||||||
@ -591,8 +597,12 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
 | 
				
			|||||||
	//  Finally separator line
 | 
						//  Finally separator line
 | 
				
			||||||
	fmt.Printf("\n")
 | 
						fmt.Printf("\n")
 | 
				
			||||||
	for i, f := range out[0] {
 | 
						for i, f := range out[0] {
 | 
				
			||||||
		if i == 0 {	fmt.Printf("+")	}
 | 
							if i == 0 {
 | 
				
			||||||
		for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("=")	}
 | 
								fmt.Printf("+")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
								fmt.Printf("=")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		fmt.Printf("+")
 | 
							fmt.Printf("+")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Printf("\n")
 | 
						fmt.Printf("\n")
 | 
				
			||||||
@ -658,8 +668,12 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
 | 
				
			|||||||
		if !gNoLineSep {
 | 
							if !gNoLineSep {
 | 
				
			||||||
			fmt.Printf("\n")
 | 
								fmt.Printf("\n")
 | 
				
			||||||
			for i, f := range out[0] {
 | 
								for i, f := range out[0] {
 | 
				
			||||||
				if i == 0 {	fmt.Printf("+")	}
 | 
									if i == 0 {
 | 
				
			||||||
				for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("-")	}
 | 
										fmt.Printf("+")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
										fmt.Printf("-")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				fmt.Printf("+")
 | 
									fmt.Printf("+")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -667,8 +681,12 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if gNoLineSep {
 | 
						if gNoLineSep {
 | 
				
			||||||
		for i, f := range out[0] {
 | 
							for i, f := range out[0] {
 | 
				
			||||||
			if i == 0 {	fmt.Printf("+")	}
 | 
								if i == 0 {
 | 
				
			||||||
			for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("-")	}
 | 
									fmt.Printf("+")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
									fmt.Printf("-")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			fmt.Printf("+")
 | 
								fmt.Printf("+")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -777,13 +795,16 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
 | 
				
			|||||||
	// Lets draw things on the screen!
 | 
						// Lets draw things on the screen!
 | 
				
			||||||
	// First, headers: 1st separator line
 | 
						// First, headers: 1st separator line
 | 
				
			||||||
	for i, f := range out[0] {
 | 
						for i, f := range out[0] {
 | 
				
			||||||
		if i == 0 {	fmt.Printf("+")	}
 | 
							if i == 0 {
 | 
				
			||||||
		for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("=")	}
 | 
								fmt.Printf("+")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
								fmt.Printf("=")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		fmt.Printf("+")
 | 
							fmt.Printf("+")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Printf("\n")
 | 
						fmt.Printf("\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	//  Column names
 | 
						//  Column names
 | 
				
			||||||
	for i, f := range out[0] {
 | 
						for i, f := range out[0] {
 | 
				
			||||||
		if i == 0 {
 | 
							if i == 0 {
 | 
				
			||||||
@ -801,8 +822,12 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
 | 
				
			|||||||
	//  Finally separator line
 | 
						//  Finally separator line
 | 
				
			||||||
	fmt.Printf("\n")
 | 
						fmt.Printf("\n")
 | 
				
			||||||
	for i, f := range out[0] {
 | 
						for i, f := range out[0] {
 | 
				
			||||||
		if i == 0 {	fmt.Printf("+")	}
 | 
							if i == 0 {
 | 
				
			||||||
		for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("=")	}
 | 
								fmt.Printf("+")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
								fmt.Printf("=")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		fmt.Printf("+")
 | 
							fmt.Printf("+")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Printf("\n")
 | 
						fmt.Printf("\n")
 | 
				
			||||||
@ -868,8 +893,12 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
 | 
				
			|||||||
		if !gNoLineSep {
 | 
							if !gNoLineSep {
 | 
				
			||||||
			fmt.Printf("\n")
 | 
								fmt.Printf("\n")
 | 
				
			||||||
			for i, f := range out[0] {
 | 
								for i, f := range out[0] {
 | 
				
			||||||
				if i == 0 {	fmt.Printf("+")	}
 | 
									if i == 0 {
 | 
				
			||||||
				for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("-")	}
 | 
										fmt.Printf("+")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
										fmt.Printf("-")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				fmt.Printf("+")
 | 
									fmt.Printf("+")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -877,8 +906,12 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if gNoLineSep {
 | 
						if gNoLineSep {
 | 
				
			||||||
		for i, f := range out[0] {
 | 
							for i, f := range out[0] {
 | 
				
			||||||
			if i == 0 {	fmt.Printf("+")	}
 | 
								if i == 0 {
 | 
				
			||||||
			for i := 0 ; i < f.MaxLen+2 ; i++ {	fmt.Printf("-")	}
 | 
									fmt.Printf("+")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for i := 0; i < f.MaxLen+2; i++ {
 | 
				
			||||||
 | 
									fmt.Printf("-")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			fmt.Printf("+")
 | 
								fmt.Printf("+")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -886,7 +919,6 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
 | 
				
			|||||||
	fmt.Printf("\n")
 | 
						fmt.Printf("\n")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*****************************************************************************
 | 
					/*****************************************************************************
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
* Sorting jails
 | 
					* Sorting jails
 | 
				
			||||||
@ -1822,7 +1854,6 @@ func (js *jailSorter) Less(i, j int) bool {
 | 
				
			|||||||
	return js.less[k](p, q)
 | 
						return js.less[k](p, q)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*****************************************************************************
 | 
					/*****************************************************************************
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Sorting snapshots
 | 
					 * Sorting snapshots
 | 
				
			||||||
@ -1937,7 +1968,6 @@ func (ss *snapshotSorter) Less(i, j int) bool {
 | 
				
			|||||||
	return ss.less[k](p, q)
 | 
						return ss.less[k](p, q)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*****************************************************************************
 | 
					/*****************************************************************************
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Generic utilities
 | 
					 * Generic utilities
 | 
				
			||||||
@ -1951,4 +1981,3 @@ func isStringInArray(strarr []string, searched string) bool {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										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