197 lines
5.9 KiB
Go
197 lines
5.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"os"
|
|
"fmt"
|
|
//"log"
|
|
"time"
|
|
"strings"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// TODO : Add a flag to specify which parts of freebsd base we want : Slim jail only need base.txz, neither lib32 nor src.txz
|
|
func CreateJail(args []string) {
|
|
var err error
|
|
var jtype []string
|
|
|
|
if len(gCreateArgs.JailType) > 0 {
|
|
jtype = []string{gCreateArgs.JailType}
|
|
}
|
|
|
|
for _, jname := range args {
|
|
// Check if jail exist and is distinctly named
|
|
_, err = getJailFromArray(jname, jtype, gJails)
|
|
if err != nil {
|
|
if strings.EqualFold(err.Error(), "Jail not found") {
|
|
|
|
} else {
|
|
fmt.Printf("ERROR: %s\n", err.Error())
|
|
return
|
|
}
|
|
} else {
|
|
fmt.Printf("Jail exist: %s\n", jname)
|
|
continue
|
|
}
|
|
|
|
fmt.Printf(" > create jail %s\n", jname)
|
|
|
|
var ds *Datastore
|
|
if len(gCreateArgs.Datastore) > 0 {
|
|
fmt.Printf("DEBUG: Use %s datastore\n", gCreateArgs.Datastore)
|
|
ds, err = getDatastoreFromArray(gCreateArgs.Datastore, gDatastores)
|
|
if err != nil {
|
|
fmt.Printf("ERROR Getting datastore: %s\n", gCreateArgs.Datastore, err.Error())
|
|
return
|
|
}
|
|
} else {
|
|
ds = &gDatastores[0]
|
|
}
|
|
|
|
/*
|
|
// Create and populate datasets
|
|
err = zfsCreateDataset(fmt.Sprintf("%s/jails/%s", ds.ZFSDataset, jname), fmt.Sprintf("%s/jails/%s", ds.Mountpoint, jname), "lz4")
|
|
if err != nil {
|
|
fmt.Printf("ERROR: %s\n", err.Error())
|
|
return
|
|
}
|
|
err = zfsCreateDataset(fmt.Sprintf("%s/jails/%s/root", ds.ZFSDataset, jname), fmt.Sprintf("%s/jails/%s/root", ds.Mountpoint, jname), "lz4")
|
|
if err != nil {
|
|
fmt.Printf("ERROR: %s\n", err.Error())
|
|
return
|
|
}
|
|
*/
|
|
|
|
// Get base template if specified
|
|
if len(gCreateArgs.BaseTemplate) > 0 {
|
|
log.Debugf("Jail will be created from a base template\n")
|
|
/*bj, err := getJailFromArray(jname, []string{"template"}, gJails)
|
|
if err != nil {
|
|
if strings.EqualFold(err.Error(), "Jail not found") {
|
|
|
|
} else {
|
|
fmt.Printf("ERROR: %s\n", err.Error())
|
|
return
|
|
}
|
|
} else {
|
|
fmt.Printf("Jail exist: %s\n", jname)
|
|
continue
|
|
}*/
|
|
} else {
|
|
// Normal jail with its own freebsd base
|
|
log.Debugf("Creating jail with its own freebsd base\n")
|
|
|
|
// First check if we got release on the same datastore
|
|
_, err := os.Stat(fmt.Sprintf("%s/releases/%s/root", ds.Mountpoint, gCreateArgs.Release))
|
|
if os.IsNotExist(err) {
|
|
fmt.Printf("ERROR: Release locally not available. Run \"gocage fetch\"\n")
|
|
return
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Create and populate jail filesystem
|
|
dstDset := fmt.Sprintf("%s/jails/%s", ds.ZFSDataset, jname)
|
|
fmt.Printf(" > Initialize dataset %s\n", dstDset)
|
|
sNow := time.Now().Format("20060102150405")
|
|
reldset := fmt.Sprintf("%s/releases/%s", ds.ZFSDataset, gCreateArgs.Release)
|
|
err = zfsSnapshot(reldset, sNow)
|
|
if err != nil {
|
|
fmt.Printf("ERROR Creating snapshot of %s: %s\n", reldset, err.Error())
|
|
return
|
|
}
|
|
|
|
err = zfsCopy(fmt.Sprintf("%s@%s", reldset, sNow), dstDset)
|
|
if err != nil {
|
|
fmt.Printf("ERROR sending snapshot to %s: %s\n", dstDset, err.Error())
|
|
return
|
|
}
|
|
// Remove snapshot of release, then snapshot of destination dataset
|
|
err = zfsDestroy(fmt.Sprintf("%s@%s", reldset, sNow))
|
|
if err != nil {
|
|
fmt.Printf("ERROR destroying snapshot %s: %s\n", reldset, err.Error())
|
|
return
|
|
}
|
|
err = zfsDestroy(fmt.Sprintf("%s@%s", dstDset, sNow))
|
|
if err != nil {
|
|
fmt.Printf("ERROR destroying snapshot %s: %s\n", dstDset, err.Error())
|
|
return
|
|
}
|
|
|
|
dstRootDset := fmt.Sprintf("%s/jails/%s/root", ds.ZFSDataset, jname)
|
|
fmt.Printf(" > Initialize dataset %s\n", dstRootDset)
|
|
relrootdset := fmt.Sprintf("%s/releases/%s/root", ds.ZFSDataset, gCreateArgs.Release)
|
|
err = zfsSnapshot(relrootdset, sNow)
|
|
if err != nil {
|
|
fmt.Printf("ERROR Creating snapshot of %s: %s\n", relrootdset, err.Error())
|
|
return
|
|
}
|
|
err = zfsCopy(fmt.Sprintf("%s@%s", relrootdset, sNow), dstRootDset)
|
|
if err != nil {
|
|
fmt.Printf("ERROR sending snapshot to %s: %s\n", dstRootDset, err.Error())
|
|
return
|
|
}
|
|
// Remove snapshot of release, then snapshot of destination dataset
|
|
err = zfsDestroy(fmt.Sprintf("%s@%s", relrootdset, sNow))
|
|
if err != nil {
|
|
fmt.Printf("ERROR destroying snapshot %s: %s\n", relrootdset, err.Error())
|
|
return
|
|
}
|
|
err = zfsDestroy(fmt.Sprintf("%s@%s", dstRootDset, sNow))
|
|
if err != nil {
|
|
fmt.Printf("ERROR destroying snapshot %s: %s\n", dstRootDset, err.Error())
|
|
return
|
|
}
|
|
|
|
fmt.Printf("Jail filesystem successfuly initalized\n")
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copy defaults.json...
|
|
jailConfPath := fmt.Sprintf("%s/jails/%s/config.json", ds.Mountpoint, jname)
|
|
err = copyFile(fmt.Sprintf("%s/defaults.json", ds.Mountpoint),
|
|
jailConfPath)
|
|
if err != nil {
|
|
fmt.Printf("ERROR creating config.json: %s\n", err.Error())
|
|
return
|
|
}
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ... and update it
|
|
// Get conf from config.json
|
|
jailConf, err := getJailConfig(jailConfPath)
|
|
if err != nil {
|
|
log.Println("ERROR reading jail config from %s", jailConfPath)
|
|
}
|
|
|
|
// 2. Build jail object from config
|
|
jailRootPath := fmt.Sprintf("%s/jails/%s/%s", ds.Mountpoint, jname, "root")
|
|
j := Jail{
|
|
Name: jailConf.Host_hostuuid,
|
|
Config: jailConf,
|
|
ConfigPath: jailConfPath,
|
|
Datastore: ds.Name,
|
|
RootPath: jailRootPath,
|
|
Running: false,
|
|
}
|
|
|
|
j.Config.Release = gCreateArgs.Release
|
|
j.Config.Host_hostname = jname
|
|
j.Config.Host_hostuuid = jname
|
|
|
|
j.WriteConfigToDisk(false)
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Create fstab
|
|
fstabHandle, err := os.Create(fmt.Sprintf("%s/jails/%s/fstab", ds.Mountpoint, jname))
|
|
if err != nil {
|
|
fmt.Printf("ERROR creating fstab: %s", err.Error())
|
|
return
|
|
}
|
|
defer fstabHandle.Close()
|
|
}
|
|
|
|
// TODO : Set JailType
|
|
}
|
|
}
|