141 lines
4.3 KiB
Go
141 lines
4.3 KiB
Go
package cmd
|
|
|
|
import (
|
|
"os"
|
|
"fmt"
|
|
"strings"
|
|
"bufio"
|
|
/* "errors"
|
|
"regexp"
|
|
"time"
|
|
*/
|
|
)
|
|
|
|
const (
|
|
// 1MB
|
|
BUFFER_SIZE = 512
|
|
)
|
|
|
|
/********************************************************************************
|
|
* Migrate jail to another zfs pool
|
|
*******************************************************************************/
|
|
func MigrateJail(args []string) {
|
|
var jailNames []string
|
|
|
|
if len(args) > 0 {
|
|
for _, a := range args {
|
|
jailNames = append(jailNames, a)
|
|
}
|
|
}
|
|
|
|
for _, jn := range jailNames {
|
|
// Check if destination dataset exist
|
|
cmd := fmt.Sprintf("zfs list %s/iocage/jails", gMigrateDestPool)
|
|
out, err := executeCommand(cmd)
|
|
if err != nil {
|
|
fmt.Printf("Error executing command %s: %v; command returned: %s\n", cmd, err, out)
|
|
return
|
|
}
|
|
|
|
cj, err := getJailFromArray(jn, gJails)
|
|
if cj == nil {
|
|
fmt.Printf("Error getting jail %s: Not found\n", jn)
|
|
return
|
|
}
|
|
|
|
if cj.Running == true {
|
|
fmt.Printf("WARNING: Jail %s is running\n", cj.Name)
|
|
fmt.Printf("Migration will stop it for data sync before starting on the new pool. You will be prompted for shutdown\n")
|
|
fmt.Printf("Continue? (y/n) ")
|
|
scanr := bufio.NewScanner(os.Stdin)
|
|
scanr.Scan()
|
|
if false == strings.EqualFold(scanr.Text(), "y") {
|
|
fmt.Printf("Migration aborted\n")
|
|
return
|
|
}
|
|
}
|
|
|
|
/* TODO : Check dest pool (gMigrateDestPool) existence
|
|
zfs snapshot /iocage/jails/$jail@gocage_mig_first_snap
|
|
zfs snapshot /iocage/jails/$jail/root@gocage_mig_first_snap
|
|
zfs send jail@gocage_mig_first_snap | zfs receive destpool/jails/jail_name
|
|
zfs send jail/root@@gocage_mig_first_snap | zfs receive destpool/jails/jail_name/root
|
|
shutdown jail if needed
|
|
if jail was shutdown
|
|
zfs snapshot /iocage/jails/$jail@gocage_mig_last_snap to get last data
|
|
zfs send jail/root@gocage_mig_last_snap | zfs receive -F destpool/jails/jail_name
|
|
start jail on new dest
|
|
zfs destroy destpool/jails/jail_name@gocage_mig_first_snap
|
|
zfs destroy destpool/jails/jail_name/root@gocage_mig_first_snap
|
|
*/
|
|
|
|
// Snapshot config
|
|
dsconf := strings.Join([]string{cj.Zpool, "iocage", "jails", jn}, "/")
|
|
fmt.Printf("Snapshot %s: ", dsconf)
|
|
if err = zfsSnapshot(dsconf, "gocage_mig_init"); err != nil {
|
|
fmt.Printf("Error: %v\n", err)
|
|
return
|
|
}
|
|
fmt.Printf("Done\n")
|
|
|
|
// Snapshot filesystem
|
|
dsdata := strings.Join([]string{cj.Zpool, "iocage", "jails", jn, "root"}, "/")
|
|
fmt.Printf("Snapshot %s: ", dsdata)
|
|
if err := zfsSnapshot(dsdata, "gocage_mig_init"); err != nil {
|
|
fmt.Printf("Error: %v\n", err)
|
|
return
|
|
}
|
|
fmt.Printf("Done\n")
|
|
|
|
dsconfdest := strings.Join([]string{gMigrateDestPool, "iocage", "jails", jn}, "/")
|
|
fmt.Printf("Migrate jail config dataset to %s: ", dsconfdest)
|
|
if err := zfsCopy(fmt.Sprintf("%s@gocage_mig_init", dsconf), dsconfdest); err != nil {
|
|
fmt.Printf("Error: %v\n", err)
|
|
}
|
|
fmt.Printf("Done\n")
|
|
|
|
dsdatadest := strings.Join([]string{gMigrateDestPool, "iocage", "jails", jn, "root"}, "/")
|
|
fmt.Printf("Migrate jail filesystem dataset to %s: ", dsdatadest)
|
|
if err := zfsCopy(fmt.Sprintf("%s@gocage_mig_init", dsdata), dsdatadest); err != nil {
|
|
fmt.Printf("Error: %v\n", err)
|
|
}
|
|
fmt.Printf("Done\n")
|
|
}
|
|
}
|
|
|
|
// Clean snapshots from an aborted migration
|
|
func CleanMigrateMess(args []string) {
|
|
var jailNames []string
|
|
|
|
if len(args) > 0 {
|
|
for _, a := range args {
|
|
jailNames = append(jailNames, a)
|
|
}
|
|
}
|
|
|
|
for _, jn := range jailNames {
|
|
cj, err := getJailFromArray(jn, gJails)
|
|
if cj == nil {
|
|
fmt.Printf("Error getting jail %s: Not found\n", jn)
|
|
return
|
|
}
|
|
|
|
cmd := fmt.Sprintf("zfs destroy %s@gocage_mig_init", strings.Join([]string{cj.Zpool, "iocage", "jails", jn}, "/"))
|
|
out, err := executeCommand(cmd)
|
|
if err != nil {
|
|
if false == strings.HasSuffix(out, "could not find any snapshots to destroy; check snapshot names.\n") {
|
|
fmt.Printf("Error executing command %s: %v; command returned: %s\n", cmd, err, out)
|
|
return
|
|
}
|
|
}
|
|
cmd = fmt.Sprintf("zfs destroy %s@gocage_mig_init", strings.Join([]string{cj.Zpool, "iocage", "jails", jn, "root"}, "/"))
|
|
out, err = executeCommand(cmd)
|
|
if err != nil {
|
|
if false == strings.HasSuffix(out, "could not find any snapshots to destroy; check snapshot names.\n") {
|
|
fmt.Printf("Error executing command %s: %v; command returned: %s\n", cmd, err, out)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|