Create and delete snapshot OK + version bump to 0.25
This commit is contained in:
parent
966a3d57c1
commit
4aa1c81fea
41
cmd/root.go
41
cmd/root.go
@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
gVersion = "0.24"
|
gVersion = "0.25"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -30,7 +30,7 @@ var (
|
|||||||
gHostVersion float64
|
gHostVersion float64
|
||||||
|
|
||||||
gTimeZone string
|
gTimeZone string
|
||||||
|
gSnapshotName string
|
||||||
|
|
||||||
rootCmd = & cobra.Command {
|
rootCmd = & cobra.Command {
|
||||||
Use: "gocage",
|
Use: "gocage",
|
||||||
@ -144,7 +144,30 @@ You can specify multiple jails.`,
|
|||||||
// Load inventory
|
// Load inventory
|
||||||
ListJails(args, false)
|
ListJails(args, false)
|
||||||
ListJailsSnapshots(args)
|
ListJailsSnapshots(args)
|
||||||
cleanAfterRun()
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshotCreateCmd = &cobra.Command {
|
||||||
|
Use: "create",
|
||||||
|
Short: "create snapshots",
|
||||||
|
Long: `Create snapshot of a jail by specifying snapshot name and jail name.`,
|
||||||
|
// You can specify multiple jails.`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// Load inventory
|
||||||
|
ListJails(args, false)
|
||||||
|
CreateJailSnapshot(args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshotDeleteCmd = &cobra.Command {
|
||||||
|
Use: "destroy",
|
||||||
|
Short: "destroy snapshots",
|
||||||
|
Long: `Destroy snapshot of a jail by specifying snapshot name and jail name.`,
|
||||||
|
// You can specify multiple jails.`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// Load inventory
|
||||||
|
ListJails(args, false)
|
||||||
|
DeleteJailSnapshot(args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -160,10 +183,18 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().StringVarP(&gTimeZone, "timezone", "t", "", "Specify timezone. Will get from /var/db/zoneinfo if not set.")
|
rootCmd.PersistentFlags().StringVarP(&gTimeZone, "timezone", "t", "", "Specify timezone. Will get from /var/db/zoneinfo if not set.")
|
||||||
|
|
||||||
// Command dependant switches
|
// Command dependant switches
|
||||||
|
|
||||||
|
// These are persistent so we can reuse them in "gocage list snapshot myjail" command (TODO)
|
||||||
listCmd.PersistentFlags().StringVarP(&gDisplayColumns, "outcol", "o", "JID,Name,Config.Release,Config.Ip4_addr,Running", "Show these columns in output")
|
listCmd.PersistentFlags().StringVarP(&gDisplayColumns, "outcol", "o", "JID,Name,Config.Release,Config.Ip4_addr,Running", "Show these columns in output")
|
||||||
listCmd.PersistentFlags().BoolVarP(&gNoLineSep, "nolinesep", "l", false, "Do not display line separator between jails")
|
listCmd.PersistentFlags().BoolVarP(&gNoLineSep, "nolinesep", "l", false, "Do not display line separator between jails")
|
||||||
listCmd.PersistentFlags().StringVarP(&gFilterJails, "filter", "f", "none", "Only display jails with these values. Ex: \"gocage list -f Config.Boot=1\" will only list started on boot jails")
|
listCmd.PersistentFlags().StringVarP(&gFilterJails, "filter", "f", "none", "Only display jails with these values. Ex: \"gocage list -f Config.Boot=1\" will only list started on boot jails")
|
||||||
listCmd.PersistentFlags().StringVarP(&gSortFields, "sort", "s", "none", "Display jails sorted by field values. Ex: \"gocage list -s +Name,-Config.Priority\" will sort jails by their decreasing name, then increasing start priority. 3 critera max supported.")
|
listCmd.PersistentFlags().StringVarP(&gSortFields, "sort", "s", "none", "Display jails sorted by field values. Ex: \"gocage list -s +Name,-Config.Priority\" will sort jails by their decreasing name, then increasing start priority. 3 critera max supported.")
|
||||||
|
|
||||||
|
// This is local flag : Only available to gocage snapshot create command
|
||||||
|
snapshotCreateCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to create")
|
||||||
|
snapshotCreateCmd.MarkFlagRequired("snapname")
|
||||||
|
snapshotDeleteCmd.Flags().StringVarP(&gSnapshotName, "snapname", "n", "", "Name of the snapshot to destroy")
|
||||||
|
snapshotDeleteCmd.MarkFlagRequired("snapname")
|
||||||
|
|
||||||
// Now declare commands
|
// Now declare commands
|
||||||
rootCmd.AddCommand(versionCmd)
|
rootCmd.AddCommand(versionCmd)
|
||||||
@ -175,7 +206,9 @@ func init() {
|
|||||||
rootCmd.AddCommand(setCmd)
|
rootCmd.AddCommand(setCmd)
|
||||||
rootCmd.AddCommand(snapshotCmd)
|
rootCmd.AddCommand(snapshotCmd)
|
||||||
snapshotCmd.AddCommand(snapshotListCmd)
|
snapshotCmd.AddCommand(snapshotListCmd)
|
||||||
|
snapshotCmd.AddCommand(snapshotCreateCmd)
|
||||||
|
snapshotCmd.AddCommand(snapshotDeleteCmd)
|
||||||
|
|
||||||
// Get FreeBSD version
|
// Get FreeBSD version
|
||||||
out, err := executeCommand("freebsd-version")
|
out, err := executeCommand("freebsd-version")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
107
cmd/snapshots.go
107
cmd/snapshots.go
@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ func listJailSnapshots(jail Jail) []Snapshot {
|
|||||||
// 1. List all datasets
|
// 1. List all datasets
|
||||||
// TODO : Include mounted filesystems?
|
// TODO : Include mounted filesystems?
|
||||||
rs := strings.Split(jail.RootPath, "/")
|
rs := strings.Split(jail.RootPath, "/")
|
||||||
rootDataset := strings.Join(rs[:len(rs)-1], "/")
|
rootDataset := fmt.Sprintf("%s%s", jail.Zpool, strings.Join(rs[:len(rs)-1], "/"))
|
||||||
cmd := fmt.Sprintf("zfs list -r -H -o name,mountpoint,used,referenced,creation -t snapshot %s", rootDataset)
|
cmd := fmt.Sprintf("zfs list -r -H -o name,mountpoint,used,referenced,creation -t snapshot %s", rootDataset)
|
||||||
out, err := executeCommand(cmd)
|
out, err := executeCommand(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -66,8 +67,7 @@ func listJailSnapshots(jail Jail) []Snapshot {
|
|||||||
return snapshots
|
return snapshots
|
||||||
}
|
}
|
||||||
// Get subdir to append to snapshot name
|
// Get subdir to append to snapshot name
|
||||||
subdir := strings.Replace(strings.Split(ls[0], "@")[0],
|
subdir := strings.Replace(strings.Split(ls[0], "@")[0], rootDataset, "", 1)
|
||||||
fmt.Sprintf("%s%s", jail.Zpool, rootDataset), "", 1)
|
|
||||||
|
|
||||||
snapshots = append(snapshots, Snapshot{Dsname: ls[0],
|
snapshots = append(snapshots, Snapshot{Dsname: ls[0],
|
||||||
Name: fmt.Sprintf("%s%s", strings.Split(ls[0], "@")[1], subdir),
|
Name: fmt.Sprintf("%s%s", strings.Split(ls[0], "@")[1], subdir),
|
||||||
@ -85,3 +85,104 @@ func listJailSnapshots(jail Jail) []Snapshot {
|
|||||||
|
|
||||||
return snapshots
|
return snapshots
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
* Create snapshot for jail(s)
|
||||||
|
*******************************************************************************/
|
||||||
|
func CreateJailSnapshot(args []string) {
|
||||||
|
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) {
|
||||||
|
createJailSnapshot(cj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
* Create snapshot for a jail
|
||||||
|
*******************************************************************************/
|
||||||
|
func createJailSnapshot(jail Jail) error {
|
||||||
|
rs := strings.Split(jail.RootPath, "/")
|
||||||
|
rootDataset := fmt.Sprintf("%s%s", jail.Zpool, strings.Join(rs[:len(rs)-1], "/"))
|
||||||
|
cmd := fmt.Sprintf("zfs snapshot -r %s@%s", rootDataset, gSnapshotName)
|
||||||
|
|
||||||
|
_, err := executeCommand(cmd)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error creating snapshot %s@%s: %s\n", rootDataset, gSnapshotName, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Snapshot %s@%s created\n", rootDataset, gSnapshotName)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
* Delete snapshot for jail(s)
|
||||||
|
*******************************************************************************/
|
||||||
|
func DeleteJailSnapshot(args []string) {
|
||||||
|
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) {
|
||||||
|
deleteJailSnapshot(cj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
* Delete snapshot for a jail
|
||||||
|
*******************************************************************************/
|
||||||
|
func deleteJailSnapshot(jail Jail) error {
|
||||||
|
var snaptodel []string
|
||||||
|
|
||||||
|
// 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 nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
snaptodel = append(snaptodel, strings.Join(ls, "@"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range snaptodel {
|
||||||
|
cmd := fmt.Sprintf("zfs destroy %s", s)
|
||||||
|
_, err := executeCommand(cmd)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error deleting snapshot %s: %s\n", s, err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fmt.Printf("Snapshot %s deleted\n", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user