add init command files
This commit is contained in:
parent
5b2f3a2f0a
commit
48a0357a3f
153
cmd/init.go
Normal file
153
cmd/init.go
Normal file
@ -0,0 +1,153 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
/********************************************************************************
|
||||
* Initialize datastore(s) /iocage, /iocage/jails
|
||||
* Put defaults.json,
|
||||
* Update it with hostid, interfaces, and maybe other necessary fields
|
||||
* Initialize bridge
|
||||
*******************************************************************************/
|
||||
func InitGoCage(args []string) {
|
||||
// Create datastores
|
||||
for _, dstore := range viper.GetStringSlice("datastore") {
|
||||
log.Debugf("Ranging over %v\n", dstore)
|
||||
dset, err := zfsGetDatasetByMountpoint(dstore)
|
||||
if err != nil && strings.HasSuffix(err.Error(), "No such file or directory\"") {
|
||||
if len(gZPool) == 0 {
|
||||
log.Errorf("Datastore mountpoint \"%s\" does not exist. Specify a pool if you want to create it.", dstore)
|
||||
return
|
||||
}
|
||||
// Create dataset /iocage
|
||||
rootDSName := fmt.Sprintf("%s%s", gZPool, dstore)
|
||||
log.Debugf("Creating dataset %s mounted on %s\n", rootDSName, dstore)
|
||||
if err = zfsCreateDataset(rootDSName, dstore, ""); err != nil {
|
||||
log.Errorf("Error creating dataset %s: %v\n", rootDSName, err)
|
||||
return
|
||||
}
|
||||
// Create /iocage/jail, releases, templates
|
||||
for _, l := range []string{"jails","releases","templates"} {
|
||||
cds := fmt.Sprintf("%s/%s", rootDSName, l)
|
||||
cmp := fmt.Sprintf("%s/%s", dstore, l)
|
||||
log.Debugf("Creating dataset %s mounted on %s\n", cds, cmp)
|
||||
if err = zfsCreateDataset(cds, cmp, ""); err != nil {
|
||||
log.Errorf("Error creating dataset %s: %v\n", cds, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Create /iocage/defaults.json
|
||||
exists, err := doFileExist(fmt.Sprintf("%s/defaults.json", dstore))
|
||||
if err != nil {
|
||||
log.Errorf("Error checking defaults.json: %v\n", err)
|
||||
return
|
||||
}
|
||||
if !exists {
|
||||
if err = createDefaultsJson(dstore, gBridge); err != nil {
|
||||
log.Errorf("%v\n", err)
|
||||
}
|
||||
}
|
||||
} else if err != nil {
|
||||
log.Errorf("Error checking datastore existence: %v\n", err)
|
||||
return
|
||||
} else {
|
||||
log.Debugf("Datastore dataset exist: %s\n", dset)
|
||||
}
|
||||
}
|
||||
// Check and create bridge
|
||||
// FIXME: What if bridge name is invalid, as we already wrote it in defaults.json in dstore loop?
|
||||
if len(gBridge) > 0 && len(gInterface) > 0 {
|
||||
if err := initBridge(); err != nil {
|
||||
log.Errorf("%v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createDefaultsJson(rootDirectory string, bridge string) error {
|
||||
hostid, err := os.ReadFile("/etc/hostid")
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to read /etc/hostid: %v\n", err)
|
||||
}
|
||||
json := strings.Replace(gDefaultsJson, "TO-BE-REPLACED-WITH-HOSTID", strings.Trim(string(hostid), "\n"), 1)
|
||||
json = strings.Replace(json, "TO-BE-REPLACED-WITH-BRIDGE", bridge, 1)
|
||||
if err := os.WriteFile(fmt.Sprintf("%s/defaults.json", rootDirectory), []byte(json), 0640); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createInterface(iface string) error {
|
||||
log.Debugf("creating interface \"%s\"\n", iface)
|
||||
cmd := fmt.Sprintf("/sbin/ifconfig %s create", iface)
|
||||
_, err := executeCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func bringUpInterface(iface string) error {
|
||||
log.Debugf("bringing up interface \"%s\"\n", iface)
|
||||
cmd := fmt.Sprintf("/sbin/ifconfig %s up", iface)
|
||||
_, err := executeCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addMemberToBridge(bridge string, iface string) error {
|
||||
log.Debugf("adding member interface \"%s\" to bridge \"%s\"\n", iface, bridge)
|
||||
cmd := fmt.Sprintf("/sbin/ifconfig %s addm %s", bridge, iface)
|
||||
_, err := executeCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initBridge() error {
|
||||
hostInt, err := gJailHost.GetInterfaces()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error listing interfaces: %v\n", err)
|
||||
}
|
||||
if !isStringInArray(hostInt, gInterface) {
|
||||
return fmt.Errorf("Interface not found: %s\n", gInterface)
|
||||
}
|
||||
if !isStringInArray(hostInt, gBridge) {
|
||||
if err := createInterface(gBridge); err != nil {
|
||||
return fmt.Errorf("Error creating bridge: %v\n", err)
|
||||
}
|
||||
if err := bringUpInterface(gBridge); err != nil {
|
||||
return fmt.Errorf("Error bringing up bridge: %v\n", err)
|
||||
}
|
||||
log.Infof("bridge was created, but it won't persist reboot. Configure rc.conf to persist. See https://docs.freebsd.org/en/books/handbook/advanced-networking/#network-bridging\n")
|
||||
log.Infof("It is strongly suggested you move interface %s IP to bridge %s\n", gInterface, gBridge)
|
||||
}
|
||||
// FIXME: Need to check if not already member
|
||||
members, err := getBridgeMembers(gBridge)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting bridge members: %v\n", err)
|
||||
}
|
||||
|
||||
// Return if interface already member of the bridge
|
||||
for _, m := range members {
|
||||
log.Debugf("Bridge member: %s\n", m)
|
||||
if strings.EqualFold(m, gInterface) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err := addMemberToBridge(gBridge, gInterface); err != nil {
|
||||
return fmt.Errorf("Error adding interface to bridge: %v\n", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user