WIP on rollback, started "gocage console", default values for jail properties to stay compatible with iocage
This commit is contained in:
parent
4aa1c81fea
commit
0053fd6c8b
@ -18,8 +18,9 @@ import (
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
func ListJailsProps(args []string) {
|
func ListJailsProps(args []string) {
|
||||||
var conf Jail
|
var conf Jail
|
||||||
var jailconf JailConfig
|
|
||||||
var result []string
|
var result []string
|
||||||
|
// Mandatory constructor to init default values
|
||||||
|
jailconf := NewJailConfig()
|
||||||
|
|
||||||
conf.Config = jailconf
|
conf.Config = jailconf
|
||||||
|
|
||||||
@ -213,7 +214,8 @@ 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)) }
|
||||||
|
|
||||||
var jc JailConfig
|
// Mandatory constructor to init default values
|
||||||
|
jc := NewJailConfig()
|
||||||
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())) }
|
||||||
|
|
||||||
|
27
cmd/root.go
27
cmd/root.go
@ -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 {
|
setCmd = &cobra.Command {
|
||||||
Use: "set",
|
Use: "set",
|
||||||
Short: "Set a jail property",
|
Short: "Set a jail property",
|
||||||
@ -147,7 +157,7 @@ You can specify multiple jails.`,
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotCreateCmd = &cobra.Command {
|
snapshotCreateCmd = &cobra.Command {
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "create snapshots",
|
Short: "create snapshots",
|
||||||
Long: `Create snapshot of a jail by specifying snapshot name and jail name.`,
|
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 {
|
snapshotDeleteCmd = &cobra.Command {
|
||||||
Use: "destroy",
|
Use: "destroy",
|
||||||
Short: "destroy snapshots",
|
Short: "destroy snapshots",
|
||||||
@ -195,6 +217,8 @@ func init() {
|
|||||||
snapshotCreateCmd.MarkFlagRequired("snapname")
|
snapshotCreateCmd.MarkFlagRequired("snapname")
|
||||||
snapshotDeleteCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to destroy")
|
snapshotDeleteCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to destroy")
|
||||||
snapshotDeleteCmd.MarkFlagRequired("snapname")
|
snapshotDeleteCmd.MarkFlagRequired("snapname")
|
||||||
|
snapshotRollbackCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to rollback to")
|
||||||
|
snapshotRollbackCmd.MarkFlagRequired("snapname")
|
||||||
|
|
||||||
// Now declare commands
|
// Now declare commands
|
||||||
rootCmd.AddCommand(versionCmd)
|
rootCmd.AddCommand(versionCmd)
|
||||||
@ -208,6 +232,7 @@ func init() {
|
|||||||
snapshotCmd.AddCommand(snapshotListCmd)
|
snapshotCmd.AddCommand(snapshotListCmd)
|
||||||
snapshotCmd.AddCommand(snapshotCreateCmd)
|
snapshotCmd.AddCommand(snapshotCreateCmd)
|
||||||
snapshotCmd.AddCommand(snapshotDeleteCmd)
|
snapshotCmd.AddCommand(snapshotDeleteCmd)
|
||||||
|
snapshotCmd.AddCommand(snapshotRollbackCmd)
|
||||||
|
|
||||||
// Get FreeBSD version
|
// Get FreeBSD version
|
||||||
out, err := executeCommand("freebsd-version")
|
out, err := executeCommand("freebsd-version")
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -186,3 +189,80 @@ func deleteJailSnapshot(jail Jail) error {
|
|||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
145
cmd/utils.go
145
cmd/utils.go
@ -11,8 +11,153 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"strconv"
|
"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
|
* Command execution
|
||||||
|
Loading…
Reference in New Issue
Block a user