WIP on rollback, started "gocage console", default values for jail properties to stay compatible with iocage

This commit is contained in:
yo 2022-04-05 20:58:11 +02:00
parent 4aa1c81fea
commit 0053fd6c8b
4 changed files with 255 additions and 3 deletions

View File

@ -18,8 +18,9 @@ import (
*******************************************************************************/
func ListJailsProps(args []string) {
var conf Jail
var jailconf JailConfig
var result []string
// Mandatory constructor to init default values
jailconf := NewJailConfig()
conf.Config = jailconf
@ -213,7 +214,8 @@ func getJailConfig(jailConfigPath string) (JailConfig, error) {
content, err := ioutil.ReadFile(jailConfigPath)
if err != nil { log.Fatalln(fmt.Sprintf("Unable to read %s, check path and/or rights", jailConfigPath)) }
var jc JailConfig
// Mandatory constructor to init default values
jc := NewJailConfig()
err = json.Unmarshal([]byte(content), &jc)
if err != nil { log.Fatalln(fmt.Sprintf("Error occured during unmarshaling %s: %s", jailConfigPath, err.Error())) }

View File

@ -98,6 +98,16 @@ ex: gocage list srv-db srv-web`,
},
}
/* shellCmd = &cobra.Command {
Use: "console",
Short: "Execute shell on jail",
Run: func(cmd *cobra.Command, args []string) {
// Load inventory
ListJails(args, false)
ShellJail(args)
},
}
*/
setCmd = &cobra.Command {
Use: "set",
Short: "Set a jail property",
@ -147,7 +157,7 @@ You can specify multiple jails.`,
},
}
snapshotCreateCmd = &cobra.Command {
snapshotCreateCmd = &cobra.Command {
Use: "create",
Short: "create snapshots",
Long: `Create snapshot of a jail by specifying snapshot name and jail name.`,
@ -159,6 +169,18 @@ You can specify multiple jails.`,
},
}
snapshotRollbackCmd = &cobra.Command {
Use: "rollback",
Short: "Rollback snapshots",
Long: `Rollback jail to specifyed snapshot.`,
// You can specify multiple jails.`,
Run: func(cmd *cobra.Command, args []string) {
// Load inventory
ListJails(args, false)
RollbackJailSnapshot(args)
},
}
snapshotDeleteCmd = &cobra.Command {
Use: "destroy",
Short: "destroy snapshots",
@ -195,6 +217,8 @@ func init() {
snapshotCreateCmd.MarkFlagRequired("snapname")
snapshotDeleteCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to destroy")
snapshotDeleteCmd.MarkFlagRequired("snapname")
snapshotRollbackCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to rollback to")
snapshotRollbackCmd.MarkFlagRequired("snapname")
// Now declare commands
rootCmd.AddCommand(versionCmd)
@ -208,6 +232,7 @@ func init() {
snapshotCmd.AddCommand(snapshotListCmd)
snapshotCmd.AddCommand(snapshotCreateCmd)
snapshotCmd.AddCommand(snapshotDeleteCmd)
snapshotCmd.AddCommand(snapshotRollbackCmd)
// Get FreeBSD version
out, err := executeCommand("freebsd-version")

View File

@ -1,8 +1,11 @@
package cmd
import (
"os"
"fmt"
"time"
"bufio"
"errors"
"regexp"
"strings"
)
@ -186,3 +189,80 @@ func deleteJailSnapshot(jail Jail) error {
return nil
}
func RollbackJailSnapshot(args []string) error {
var jailNames []string
if len(args) > 0 {
for _, a := range args {
jailNames = append(jailNames, a)
}
}
for _, cj := range gJails {
for _, jn := range jailNames {
if strings.EqualFold(cj.Name, jn) {
rollbackJailSnapshot(cj)
}
}
}
return nil
}
/********************************************************************************
* rollback jail to snapshot gSnapshotName, destroy this snapshots and more
* recents snapshots and bookmarks
*******************************************************************************/
func rollbackJailSnapshot(jail Jail) error {
var snaptorb []string
if jail.Running {
fmt.Printf("Jail should be stoped to rollback, should we stop and rollback? (y/n)\n")
scanr := bufio.NewScanner(os.Stdin)
if scanr.Scan() {
if !strings.EqualFold(scanr.Text(), "y") {
return errors.New("Jail is running")
} else {
err := stopJail(&jail)
if err != nil {
return err
}
}
}
}
// We need to rollback parent and childs
// Get all recursive snapshots
rs := strings.Split(jail.RootPath, "/")
rootDataset := fmt.Sprintf("%s%s", jail.Zpool, strings.Join(rs[:len(rs)-1], "/"))
cmd := fmt.Sprintf("zfs list -r -H -o name -t snapshot %s", rootDataset)
out, err := executeCommand(cmd)
if err != nil {
fmt.Printf("Error: listing snapshots: %s\n", err.Error())
return err
}
for _, line := range strings.Split(out, "\n") {
if len(line) > 0 {
ls := strings.Split(line, "@")
matched, _ := regexp.Match(fmt.Sprintf("^%s(\\/.*)?$", gSnapshotName), []byte(ls[1]))
if matched {
snaptorb = append(snaptorb, strings.Join(ls, "@"))
}
}
}
for _, s := range snaptorb {
cmd := fmt.Sprintf("zfs rollback -r %s", s)
_, err := executeCommand(cmd)
if err != nil {
fmt.Printf("Error rolling back snapshot %s: %s\n", s, err.Error())
return err
}
}
fmt.Printf("Jail is back to %s\n", gSnapshotName)
return nil
}

View File

@ -11,8 +11,153 @@ import (
"reflect"
"strings"
"strconv"
"io/ioutil"
)
/*****************************************************************************
* Mandatory constructor for JailConfig type. It set default values
*****************************************************************************/
func NewJailConfig() JailConfig {
var jc JailConfig
hostid, err := ioutil.ReadFile("/etc/hostid")
if err != nil {
hostid = []byte("12345678-abcd-ef98-7654-321012345678")
}
jc.Allow_chflags = 0
jc.Allow_mlock = 0
jc.Allow_mount = 0
jc.Allow_mount_devfs = 0
jc.Allow_mount_fusefs = 0
jc.Allow_mount_nullfs = 0
jc.Allow_mount_procfs = 0
jc.Allow_mount_tmpfs = 0
jc.Allow_mount_zfs = 0
jc.Allow_quotas = 0
jc.Allow_raw_sockets = 0
jc.Allow_socket_af = 0
jc.Allow_set_hostname = 1
jc.Allow_sysvipc = 0
jc.Allow_tun = 0
jc.Allow_vmm = 0
jc.Assign_localhost = 0
jc.Available = "readonly"
jc.Basejail = 0
jc.Bpf = 0
jc.Boot = 0
jc.Children_max = "0"
jc.Comment = "none"
jc.Compression = "lz4"
jc.Compressratio = "readonly"
jc.Coredumpsize = "off"
jc.Count = "1"
jc.Cpuset = "off"
jc.Cputime = "off"
jc.Datasize = "off"
jc.Dedup = "off"
jc.Defaultrouter = "auto"
jc.Defaultrouter6 = "auto"
jc.Depends = "none"
jc.Devfs_ruleset = "4"
jc.Dhcp = 0
jc.Enforce_statfs = "2"
jc.Exec_clean = 1
jc.Exec_created = "/usr/bin/true"
jc.Exec_jail_user = "root"
jc.Exec_fib = "0"
jc.Exec_poststart = "/usr/bin/true"
jc.Exec_poststop = "/usr/bin/true"
jc.Exec_prestart = "/usr/bin/true"
jc.Exec_prestop = "/usr/bin/true"
jc.Exec_system_jail_user = "0"
jc.Exec_system_user = "root"
jc.Exec_start = "/bin/sh /etc/rc"
jc.Exec_stop = "/bin/sh /etc/rc.shutdown"
jc.Exec_timeout = "60"
jc.Hostid = string(hostid)
jc.Hostid_strict_check = 0
jc.Host_time = 1
jc.Interfaces = "vnet0:bridge0"
jc.Ip4_addr = "none"
jc.Ip4_saddrsel = "1"
jc.Ip4 = "new"
jc.Ip6_addr = "none"
jc.Ip6_saddrsel = "1"
jc.Ip6 = "new"
jc.Ip_hostname = 0
jc.Jailtype = "jail"
jc.Jail_zfs = 0
jc.Jail_zfs_mountpoint = "none"
jc.Last_started = "none"
jc.Localhost_ip = "none"
jc.Login_flags = "-f root"
jc.Maxproc = "off"
jc.Min_dyn_devfs_ruleset = "1000"
jc.Memoryuse = "off"
jc.Memorylocked = "off"
jc.Mountpoint = "readonly"
jc.Mount_devfs = 1
jc.Mount_fdescfs = 1
jc.Mount_procfs = 0
jc.Mount_linprocfs = 0
jc.Msgqqueued = "off"
jc.Msgqsize = "off"
jc.Nat = 0
jc.Nat_backend = "ipfw"
jc.Nat_forwards = "none"
jc.Nat_interface = "none"
jc.Nat_prefix = "172.16"
jc.Nmsgq = "off"
jc.Notes = "none"
jc.Nsem = "off"
jc.Nsemop = "off"
jc.Nshm = "off"
jc.Nthr = "off"
jc.Openfiles = "off"
jc.Origin = "readonly"
jc.Owner = "root"
jc.Pcpu = "off"
jc.Plugin_name = "none"
jc.Plugin_repository = "none"
jc.Priority = "99"
jc.Pseudoterminals = "off"
jc.Quota = "none"
jc.Readbps = "off"
jc.Readiops = "off"
jc.Reservation = "none"
jc.Resolver = "/etc/resolv.conf"
jc.Rlimits = "off"
jc.Rtsold = 0
jc.Securelevel = "2"
jc.Shmsize = "off"
jc.Stacksize = "off"
jc.Stop_timeout = "30"
jc.Sync_state = "none"
jc.Sync_target = "none"
jc.Sync_tgt_zpool = "none"
jc.Sysvmsg = "new"
jc.Sysvsem = "new"
jc.Sysvshm = "new"
jc.Swapuse = "off"
jc.Template = 0
jc.Used = "readonly"
jc.Vmemoryuse = "off"
jc.Vnet = 0
jc.Vnet0_mac = "none"
jc.Vnet1_mac = "none"
jc.Vnet2_mac = "none"
jc.Vnet3_mac = "none"
jc.Vnet_default_interface = "auto"
jc.Vnet_interfaces = "none"
jc.Wallclock = "off"
jc.Writebps = "off"
jc.Writeiops = "off"
return jc
}
/*****************************************************************************
*
* Command execution