Compare commits

..

3 Commits

4 changed files with 29 additions and 23 deletions

View File

@ -6,7 +6,13 @@ Support iocage jails, so they can coexist.
Gocage is meant to be a complete jail management tool with network, snapshots, jail cloning support and a web interface. This is the hypothetic future.
Gocage can handle multiple datastores, so you can have jails on HDD storage and jails on SSD storage.
From v0.33b, due to multi ZFS pool support, gocage is no longer 100% compatible with iocage.
Zfs datasets now should be specified with the ZFS pool. e.g. :
<code>
Config.Jail_zfs = 1
Config.Jail_zfs_dataset = myzfspool/poudriere
Config.Jail_zfs_mountpoint = none
</code>
List jails
----------

View File

@ -14,7 +14,7 @@ import (
)
const (
gVersion = "0.33a"
gVersion = "0.33b"
// TODO : Get from $jail_zpool/defaults.json
MIN_DYN_DEVFS_RULESET = 1000
@ -518,10 +518,8 @@ func WriteConfigToDisk(jailName string, changeauto bool, forceWrite bool) {
fmt.Printf("ERROR marshaling config: %s\n", err.Error())
}
fmt.Printf("DEBUG: Will write config to disk, with content:\n")
fmt.Printf(string(marshaled))
//fmt.Printf("DEBUG: Will write config to disk, with content:\n")
//fmt.Printf(string(marshaled))
if os.WriteFile(j.ConfigPath, []byte(marshaled), 0644); err != nil {
fmt.Printf("Error writing config file %s: %v\n", j.ConfigPath, err)

View File

@ -190,24 +190,26 @@ func prepareJailedZfsDatasets(jail *Jail) error {
}
for _, d := range strings.Split(jail.Config.Jail_zfs_dataset, " ") {
// Check if dataset exist, create if necessary
cmd := fmt.Sprintf("zfs get -H creation %s/%s", jail.Zpool, d)
// Support jailing datasets on differents pools : dataset should be specified with pool name
cmd := fmt.Sprintf("zfs get -H creation %s", d)
out, err := executeCommand(cmd)
if err != nil {
if strings.HasSuffix(out, "dataset does not exist") {
cmd = fmt.Sprintf("zfs create -o compression=lz4 -o mountpoint=none %s/%s", jail.Zpool, d)
// Support jailing datasets on differents pools : dataset should be specified with pool name
cmd = fmt.Sprintf("zfs create -o compression=lz4 -o mountpoint=none %s", d)
_, err = executeCommand(cmd)
if err != nil {
return errors.New(fmt.Sprintf("Error creating dataset %s/%s: %s", jail.Zpool, d, err.Error()))
return errors.New(fmt.Sprintf("Error creating dataset %s: %s", d, err.Error()))
}
} else {
return errors.New(fmt.Sprintf("Error getting zfs dataset %s: %s", d, err.Error()))
}
}
cmd = fmt.Sprintf("zfs set jailed=on %s/%s", jail.Zpool, d)
cmd = fmt.Sprintf("zfs set jailed=on %s", d)
out, err = executeCommand(cmd)
if err != nil {
return errors.New(fmt.Sprintf("Error executing \"zfs set jailed=on %s/%s\": %s", jail.Zpool, d, err.Error()))
return errors.New(fmt.Sprintf("Error executing \"zfs set jailed=on %s\": %s", d, err.Error()))
}
}
}
@ -218,27 +220,27 @@ func jailZfsDatasets(jail *Jail) error {
if jail.Config.Jail_zfs > 0 {
for _, d := range strings.Split(jail.Config.Jail_zfs_dataset, " ") {
// Jail dataset
cmd := fmt.Sprintf("zfs jail %d %s/%s", jail.JID, jail.Zpool, d)
// Support jailing datasets on differents pools : dataset should be specified with pool name
cmd := fmt.Sprintf("zfs jail %d %s", jail.JID, d)
out, err := executeCommand(cmd)
if err != nil {
return errors.New(fmt.Sprintf("Error jailling zfs dataset %s: %v: out", d, err, out))
}
// Mount from inside jail if mountpoint is set
cmd = fmt.Sprintf("zfs get -H -o value mountpoint %s/%s", jail.Zpool, d)
cmd = fmt.Sprintf("zfs get -H -o value mountpoint %s", d)
out, err = executeCommand(cmd)
if err != nil {
return errors.New(fmt.Sprintf("Error getting zfs dataset %s/%s mountpoint: %v: %s", jail.Zpool, d, err, out))
return errors.New(fmt.Sprintf("Error getting zfs dataset %s mountpoint: %v: %s", d, err, out))
}
if len(out) > 0 && out != "-" && (false == strings.EqualFold(out, "none")) {
//cmd = fmt.Sprintf("zfs mount %s/%s", jail.Zpool, d)
cmd = fmt.Sprintf("zfs mount -a")
// Should we "mount -a" ? cmd = fmt.Sprintf("zfs mount -a")
cmd = fmt.Sprintf("zfs mount %s", d)
out, err = executeCommandInJail(jail, cmd)
if err != nil {
// If already mounted, continue processing
if ! strings.HasSuffix(out, "filesystem already mounted\n") {
//return errors.New(fmt.Sprintf("Error mounting zfs dataset %s/%s: %v: %s", jail.Zpool, d, err, out))
return errors.New(fmt.Sprintf("Error executing \"zfs mount -a\" from inside jail: %v: %s", err, out))
return errors.New(fmt.Sprintf("Error mounting zfs dataset %s from inside jail: %v: %s", d, err, out))
}
}
}
@ -1011,7 +1013,7 @@ func generateResolvConf(jail *Jail) error {
for _, l := range strings.Split(jail.Config.Resolver, ";") {
f.WriteString(fmt.Sprintf("%s\n", l))
}
} else if jail.Config.Resolver == "none" {
} else if jail.Config.Resolver == "none" || jail.Config.Resolver == "/etc/resolv.conf" {
read, err := ioutil.ReadFile("/etc/resolv.conf")
if err != nil {
return fmt.Errorf("Error opening /etc/resolv.conf: %v", err)

View File

@ -50,10 +50,10 @@ func umountAndUnjailZFS(jail *Jail) error {
for _, zd := range ds {
// 1. Get dataset and childs
cmd := fmt.Sprintf("zfs list -H -r -o name -S name %s/%s", jail.Zpool, zd)
cmd := fmt.Sprintf("zfs list -H -r -o name -S name %s", zd)
out, err := executeCommand(cmd)
if err != nil {
fmt.Printf(fmt.Sprintf("ERROR listing dataset %s/%s\n", jail.Zpool, zd))
fmt.Printf(fmt.Sprintf("ERROR listing dataset %s\n", zd))
os.Exit(1)
}
for _, c := range strings.Split(out, "\n") {
@ -71,10 +71,10 @@ func umountAndUnjailZFS(jail *Jail) error {
}
// 2. Unjail dataset from the host
cmd := fmt.Sprintf("zfs unjail %s %s/%s", jail.InternalName, jail.Zpool, ds[len(ds)-1])
cmd := fmt.Sprintf("zfs unjail %s %s", jail.InternalName, ds[len(ds)-1])
_, err := executeCommand(cmd)
if err != nil {
fmt.Printf("ERROR unjailing %s/%s: %s\n", jail.Zpool, ds[len(ds)-1], err.Error())
fmt.Printf("ERROR unjailing %s: %s\n", ds[len(ds)-1], err.Error())
return err
}