Add datastore to snapshots, force Datastore display when jail exist on multi datastores
This commit is contained in:
parent
1c04f62ed8
commit
9218ffafe1
36
cmd/list.go
36
cmd/list.go
@ -3,7 +3,6 @@ package cmd
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
"gocage/jail"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@ -40,12 +39,12 @@ func ListJailsProps(args []string) {
|
||||
* into gJails global var
|
||||
*******************************************************************************/
|
||||
func ListJails(args []string, display bool) {
|
||||
fields := strings.Split(gDisplayJColumns, ",")
|
||||
|
||||
for _, d := range viper.GetStringSlice("datastore") {
|
||||
listJailsFromDatastore(d)
|
||||
for _, ds := range gDatastores {
|
||||
listJailsFromDatastore(ds)
|
||||
}
|
||||
|
||||
|
||||
fields := strings.Split(gDisplayJColumns, ",")
|
||||
|
||||
// This is the structure we will filter, then display
|
||||
var jails []Jail
|
||||
|
||||
@ -91,7 +90,6 @@ func ListJails(args []string, display bool) {
|
||||
for _, j := range jails {
|
||||
if j.Name == a {
|
||||
js = append(js, j)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,17 +148,17 @@ func ListJails(args []string, display bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func listJailsFromDatastore(datastore string) {
|
||||
fileInfo, err := os.Stat(datastore)
|
||||
func listJailsFromDatastore(ds Datastore) {
|
||||
fileInfo, err := os.Stat(ds.Mountpoint)
|
||||
if err != nil {
|
||||
log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", datastore))
|
||||
log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", ds.Mountpoint))
|
||||
}
|
||||
if fileInfo.IsDir() == false {
|
||||
log.Fatalln(fmt.Sprintf("%s is not a directory", datastore))
|
||||
log.Fatalln(fmt.Sprintf("%s is not a directory", ds.Mountpoint))
|
||||
}
|
||||
|
||||
// A datastore have to contain a "jails" directory
|
||||
jailsDir := fmt.Sprintf("%s/jails", datastore)
|
||||
jailsDir := fmt.Sprintf("%s/jails", ds.Mountpoint)
|
||||
fileInfo, err = os.Stat(jailsDir)
|
||||
if err != nil {
|
||||
log.Fatalln(fmt.Sprintf("Unable to access %s, check path and/or rights", jailsDir))
|
||||
@ -169,10 +167,10 @@ func listJailsFromDatastore(datastore string) {
|
||||
log.Fatalln(fmt.Sprintf("%s is not a directory", jailsDir))
|
||||
}
|
||||
|
||||
listJailsFromDirectory(jailsDir)
|
||||
listJailsFromDirectory(jailsDir, ds.Name)
|
||||
}
|
||||
|
||||
func listJailsFromDirectory(dir string) []Jail {
|
||||
func listJailsFromDirectory(dir string, dsname string) []Jail {
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
log.Fatalln(fmt.Sprintf("Unable to browse %s, check path and/or rights", dir))
|
||||
@ -194,6 +192,7 @@ func listJailsFromDirectory(dir string) []Jail {
|
||||
Name: jailConf.Host_hostname,
|
||||
Config: jailConf,
|
||||
ConfigPath: jailConfPath,
|
||||
Datastore: dsname,
|
||||
RootPath: jailRootPath,
|
||||
Running: false,
|
||||
}
|
||||
@ -223,9 +222,12 @@ func listJailsFromDirectory(dir string) []Jail {
|
||||
// Check if jail with the same name already exist on another DS
|
||||
for _, jj := range gJails {
|
||||
if strings.EqualFold(jj.Name, j.Name) {
|
||||
fmt.Printf("ERROR: A jail with name %s already exist on datastore %s!\n", j.Name, jj.Zpool)
|
||||
fmt.Printf("Jail %s on datastore %s wont be handled\n", j.Name, j.Zpool)
|
||||
return gJails
|
||||
fmt.Printf(" ---------------------------------------------- \n")
|
||||
fmt.Printf("Warning: A jail with name %s already exist on datastore %s!\n", j.Name, jj.Datastore)
|
||||
fmt.Printf(" ---------------------------------------------- \n")
|
||||
// Add Datastore to avoid confusion
|
||||
gDisplayJColumns += ",Datastore"
|
||||
gDisplaySColumns += ",Datastore"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ const (
|
||||
*******************************************************************************/
|
||||
func MigrateJail(args []string) {
|
||||
var jailNames []string
|
||||
var destDS Datastore
|
||||
|
||||
if len(args) > 0 {
|
||||
for _, a := range args {
|
||||
@ -27,26 +26,24 @@ func MigrateJail(args []string) {
|
||||
}
|
||||
|
||||
for _, jn := range jailNames {
|
||||
// Check if destination datastore exist
|
||||
found := false
|
||||
for _, ds := range gDatastores {
|
||||
if strings.EqualFold(gMigrateDestDatastore, ds.Name) {
|
||||
found = true
|
||||
destDS = ds
|
||||
break
|
||||
}
|
||||
}
|
||||
if false == found {
|
||||
fmt.Printf("Unkown datastore: %s\n", gMigrateDestDatastore)
|
||||
return
|
||||
}
|
||||
|
||||
cj, err := getJailFromArray(jn, gJails)
|
||||
if cj == nil {
|
||||
fmt.Printf("Error getting jail %s: Not found\n", jn)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if destination datastore exist & get current DS
|
||||
destDS, err := getDatastoreFromArray(gMigrateDestDatastore, gDatastores)
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting datastore \"%s\": %v\n", gMigrateDestDatastore, err)
|
||||
return
|
||||
}
|
||||
curDS, err := getDatastoreFromArray(cj.Datastore, gDatastores)
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting datastore \"%s\": %v\n", gMigrateDestDatastore, err)
|
||||
return
|
||||
}
|
||||
|
||||
if cj.Running == true && gYesToAll == false {
|
||||
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")
|
||||
@ -74,7 +71,7 @@ func MigrateJail(args []string) {
|
||||
*/
|
||||
|
||||
// Snapshot config
|
||||
dsconf := strings.Join([]string{cj.Zpool, "iocage", "jails", jn}, "/")
|
||||
dsconf := strings.Join([]string{curDS.ZFSDataset, "jails", jn}, "/")
|
||||
fmt.Printf("Snapshot %s: ", dsconf)
|
||||
if err = zfsSnapshot(dsconf, "gocage_mig_init"); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
@ -83,7 +80,7 @@ func MigrateJail(args []string) {
|
||||
fmt.Printf("Done\n")
|
||||
|
||||
// Snapshot filesystem
|
||||
dsdata := strings.Join([]string{cj.Zpool, "iocage", "jails", jn, "root"}, "/")
|
||||
dsdata := strings.Join([]string{curDS.ZFSDataset, "iocage", "jails", jn, "root"}, "/")
|
||||
fmt.Printf("Snapshot %s: ", dsdata)
|
||||
if err := zfsSnapshot(dsdata, "gocage_mig_init"); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
@ -178,11 +175,14 @@ func CleanMigrateMess(args []string) error {
|
||||
for _, jn := range jailNames {
|
||||
cj, err := getJailFromArray(jn, gJails)
|
||||
if cj == nil {
|
||||
fmt.Printf("Error getting jail %s: Not found\n", jn)
|
||||
return errors.New(fmt.Sprintf("Error getting jail %s: Not found\n", jn))
|
||||
}
|
||||
curDS, err := getDatastoreFromArray(cj.Datastore, gDatastores)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Error getting datastore \"%s\": %v\n", cj.Datastore, err))
|
||||
}
|
||||
|
||||
cmd := fmt.Sprintf("zfs destroy %s@gocage_mig_init", strings.Join([]string{cj.Zpool, "iocage", "jails", jn}, "/"))
|
||||
cmd := fmt.Sprintf("zfs destroy %s@gocage_mig_init", strings.Join([]string{curDS.ZFSDataset, "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") {
|
||||
@ -190,7 +190,7 @@ func CleanMigrateMess(args []string) error {
|
||||
return errors.New(fmt.Sprintf("Error executing command %s: %v; command returned: %s\n", cmd, err, out))
|
||||
}
|
||||
}
|
||||
cmd = fmt.Sprintf("zfs destroy %s@gocage_mig_init", strings.Join([]string{cj.Zpool, "iocage", "jails", jn, "root"}, "/"))
|
||||
cmd = fmt.Sprintf("zfs destroy %s@gocage_mig_init", strings.Join([]string{curDS.ZFSDataset, "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") {
|
||||
@ -198,7 +198,7 @@ func CleanMigrateMess(args []string) error {
|
||||
return errors.New(fmt.Sprintf("Error executing command %s: %v; command returned: %s\n", cmd, err, out))
|
||||
}
|
||||
}
|
||||
cmd = fmt.Sprintf("zfs destroy %s@gocage_mig_last_sync", strings.Join([]string{cj.Zpool, "iocage", "jails", jn}, "/"))
|
||||
cmd = fmt.Sprintf("zfs destroy %s@gocage_mig_last_sync", strings.Join([]string{curDS.ZFSDataset, "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") {
|
||||
@ -206,7 +206,7 @@ func CleanMigrateMess(args []string) error {
|
||||
return errors.New(fmt.Sprintf("Error executing command %s: %v; command returned: %s\n", cmd, err, out))
|
||||
}
|
||||
}
|
||||
cmd = fmt.Sprintf("zfs destroy %s@gocage_mig_last_sync", strings.Join([]string{cj.Zpool, "iocage", "jails", jn, "root"}, "/"))
|
||||
cmd = fmt.Sprintf("zfs destroy %s@gocage_mig_last_sync", strings.Join([]string{curDS.ZFSDataset, "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") {
|
||||
|
@ -225,7 +225,10 @@ You can specify multiple jails.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Load inventory
|
||||
ListJails(args, false)
|
||||
CleanMigrateMess(args)
|
||||
err := CleanMigrateMess(args)
|
||||
if err != nil {
|
||||
fmt.Printf("%v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@ -262,8 +265,8 @@ func init() {
|
||||
|
||||
// Command dependant switches
|
||||
|
||||
// We reuse these in "gocage snapshot list myjail" and 'gocage datastore list" commands (TODO)
|
||||
listCmd.Flags().StringVarP(&gDisplayJColumns, "outcol", "o", "JID,Name,Config.Release,Config.Ip4_addr,Running", "Show these columns in output")
|
||||
// We reuse these flags in "gocage snapshot list myjail" and 'gocage datastore list" commands
|
||||
listCmd.Flags().StringVarP(&gDisplayJColumns, "outcol", "o", "JID,Name,Datastore,Config.Release,Config.Ip4_addr,Running", "Show these columns in output")
|
||||
listCmd.Flags().BoolVarP(&gNoJailLineSep, "nolinesep", "l", false, "Do not display line separator between jails")
|
||||
listCmd.Flags().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.Flags().StringVarP(&gSortJailFields, "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.")
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"reflect"
|
||||
"time"
|
||||
@ -23,6 +24,10 @@ func ListJailsSnapshots(args []string) {
|
||||
/**************************************************************/
|
||||
if len(args) > 0 {
|
||||
for _, a := range args {
|
||||
/*if countOfJailsWithThisName(a) > 1 {
|
||||
fmt.Printf("Nope")
|
||||
return
|
||||
}*/
|
||||
jailNames = append(jailNames, a)
|
||||
}
|
||||
}
|
||||
@ -99,23 +104,27 @@ func listJailSnapshots(jail Jail) []Snapshot {
|
||||
|
||||
// 1. List all datasets
|
||||
// TODO : Include mounted filesystems?
|
||||
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,mountpoint,used,referenced,creation -t snapshot %s", rootDataset)
|
||||
|
||||
curDS, err := getDatastoreFromArray(jail.Datastore, gDatastores)
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting datastore \"%s\": %v\n", jail.Datastore, err)
|
||||
return snapshots
|
||||
}
|
||||
|
||||
rootDataset := fmt.Sprintf("%s/%s/%s", curDS.ZFSDataset, "jails", jail.Name)
|
||||
cmd := fmt.Sprintf("zfs list -p -r -H -o name,mountpoint,used,referenced,creation -t snapshot %s", rootDataset)
|
||||
out, err := executeCommand(cmd)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n", err.Error())
|
||||
return snapshots
|
||||
}
|
||||
|
||||
dateLayout := "Mon Jan _2 15:04 2006"
|
||||
loc, _ := time.LoadLocation(gTimeZone)
|
||||
|
||||
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
if len(line) > 0 {
|
||||
ls := strings.Split(line, "\t")
|
||||
// Parse creation date so we can use it to sort snapshots
|
||||
creationts, err := time.ParseInLocation(dateLayout, ls[4], loc)
|
||||
//creationts, err := time.ParseInLocation(dateLayout, ls[4], loc)
|
||||
creationts, err := strconv.ParseInt(ls[4], 10, 64)
|
||||
if err != nil {
|
||||
fmt.Println("Error while parsing date %s:", ls[4], err)
|
||||
return snapshots
|
||||
@ -123,13 +132,15 @@ func listJailSnapshots(jail Jail) []Snapshot {
|
||||
// Get subdir to append to snapshot name
|
||||
subdir := strings.Replace(strings.Split(ls[0], "@")[0], rootDataset, "", 1)
|
||||
|
||||
snapshots = append(snapshots, Snapshot{Dsname: ls[0],
|
||||
u, _ := strconv.ParseUint(ls[2], 10, 64)
|
||||
r, _ := strconv.ParseUint(ls[3], 10, 64)
|
||||
snapshots = append(snapshots, Snapshot{Datastore: curDS.Name,
|
||||
Name: fmt.Sprintf("%s%s", strings.Split(ls[0], "@")[1], subdir),
|
||||
Jailname: jail.Name,
|
||||
Mountpoint: ls[1],
|
||||
Used: ls[2],
|
||||
Referenced: ls[3],
|
||||
Creation: creationts})
|
||||
Used: u,
|
||||
Referenced: r,
|
||||
Creation: time.Unix(creationts, 0)})
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,8 +176,8 @@ func CreateJailSnapshot(args []string) {
|
||||
* 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], "/"))
|
||||
curDS, _ := getDatastoreFromArray(jail.Datastore, gDatastores)
|
||||
rootDataset := fmt.Sprintf("%s/%s/%s", curDS.ZFSDataset, "jails", jail.Name)
|
||||
cmd := fmt.Sprintf("zfs snapshot -r %s@%s", rootDataset, gSnapshotName)
|
||||
|
||||
_, err := executeCommand(cmd)
|
||||
@ -207,8 +218,8 @@ 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], "/"))
|
||||
curDS, _ := getDatastoreFromArray(jail.Datastore, gDatastores)
|
||||
rootDataset := fmt.Sprintf("%s/%s/%s", curDS.ZFSDataset, "jails", jail.Name)
|
||||
cmd := fmt.Sprintf("zfs list -r -H -o name -t snapshot %s", rootDataset)
|
||||
out, err := executeCommand(cmd)
|
||||
if err != nil {
|
||||
@ -284,8 +295,8 @@ func rollbackJailSnapshot(jail Jail) error {
|
||||
|
||||
// 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], "/"))
|
||||
curDS, _ := getDatastoreFromArray(jail.Datastore, gDatastores)
|
||||
rootDataset := fmt.Sprintf("%s/%s/%s", curDS.ZFSDataset, "jails", jail.Name)
|
||||
cmd := fmt.Sprintf("zfs list -r -H -o name -t snapshot %s", rootDataset)
|
||||
out, err := executeCommand(cmd)
|
||||
if err != nil {
|
||||
|
@ -27,7 +27,8 @@ type Jail struct {
|
||||
Running bool
|
||||
// No need, Config.Release always represent what is running (plus it know release for non-running jails)
|
||||
//Release string
|
||||
Zpool string
|
||||
Zpool string
|
||||
Datastore string
|
||||
}
|
||||
|
||||
// iocage struct as stored in config.json
|
||||
@ -191,11 +192,11 @@ type Mount struct {
|
||||
type Snapshot struct {
|
||||
// snapshot name is stored after '@' in dataset name
|
||||
Name string
|
||||
Dsname string
|
||||
Datastore string
|
||||
Jailname string
|
||||
Mountpoint string
|
||||
Used string
|
||||
Referenced string
|
||||
Used uint64
|
||||
Referenced uint64
|
||||
Creation time.Time
|
||||
}
|
||||
|
||||
@ -215,6 +216,8 @@ type JailSort struct {
|
||||
ConfigPathDec jailLessFunc
|
||||
RunningInc jailLessFunc
|
||||
RunningDec jailLessFunc
|
||||
DatastoreInc jailLessFunc
|
||||
DatastoreDec jailLessFunc
|
||||
ZpoolInc jailLessFunc
|
||||
ZpoolDec jailLessFunc
|
||||
Config JailConfigSort
|
||||
@ -498,8 +501,8 @@ type JailConfigSort struct {
|
||||
type SnapshotSort struct {
|
||||
NameInc snapshotLessFunc
|
||||
NameDec snapshotLessFunc
|
||||
DsnameInc snapshotLessFunc
|
||||
DsnameDec snapshotLessFunc
|
||||
DatastoreInc snapshotLessFunc
|
||||
DatastoreDec snapshotLessFunc
|
||||
JailnameInc snapshotLessFunc
|
||||
JailnameDec snapshotLessFunc
|
||||
MountpointInc snapshotLessFunc
|
||||
|
86
cmd/utils.go
86
cmd/utils.go
@ -391,7 +391,7 @@ func getJailFromArray(name string, jarray []Jail) (*Jail, error) {
|
||||
return &Jail{}, errors.New("Jail not found")
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
/******************************************************************************
|
||||
*
|
||||
* Generic utilities
|
||||
*
|
||||
@ -405,6 +405,28 @@ func isStringInArray(strarr []string, searched string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func getDatastoreFromArray(name string, dsa []Datastore) (*Datastore, error) {
|
||||
for _, d := range dsa {
|
||||
if name == d.Name {
|
||||
return &d, nil
|
||||
}
|
||||
}
|
||||
return &Datastore{}, errors.New("Datastore not found")
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Return the quantity of jails with the name passed as parameter
|
||||
*****************************************************************************/
|
||||
func countOfJailsWithThisName(name string) int {
|
||||
count := 0
|
||||
for _, j := range gJails {
|
||||
if strings.EqualFold(j.Name, name) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Recurse into structure, returning reflect.Kind of named field.
|
||||
* Nested fields are named with a dot (ex "MyStruct.MyField")
|
||||
@ -836,7 +858,7 @@ func displayJailsFields(jails []Jail, valsToDisplay []string) {
|
||||
/********************************************************************************
|
||||
* Pretty display of snapshots field
|
||||
* Fields to show are given in a string array parameter
|
||||
* Ex. : displaySnapshotsFields(snapshots, ["Name", "Dsname", "Used"])
|
||||
* Ex. : displaySnapshotsFields(snapshots, ["Name", "Datastore", "Used"])
|
||||
*******************************************************************************/
|
||||
func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
|
||||
/* A line is defined by :
|
||||
@ -878,7 +900,14 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
|
||||
itnr := len(strings.Split(string(a.FieldByName(f).Interface().(string)), ","))
|
||||
field.MaxLen = len(fmt.Sprintf("%v", a.FieldByName(f).Interface())) / itnr
|
||||
} else {
|
||||
field.MaxLen = len(fmt.Sprintf("%v", a.FieldByName(f).Interface()))
|
||||
// Special case of disk size : We will print human readable values
|
||||
if field.Name == "Used" || field.Name == "Referenced" || field.Name == "Available" {
|
||||
var v datasize.ByteSize
|
||||
v.UnmarshalText([]byte(fmt.Sprintf("%v", a.FieldByName(f).Interface())))
|
||||
field.MaxLen = len(fmt.Sprintf("%v", v.HumanReadable()))
|
||||
} else {
|
||||
field.MaxLen = len(fmt.Sprintf("%v", a.FieldByName(f).Interface()))
|
||||
}
|
||||
}
|
||||
field.Value = fmt.Sprintf("%v", a.FieldByName(f).Interface())
|
||||
} else {
|
||||
@ -983,25 +1012,24 @@ func displaySnapshotsFields(snaps []Snapshot, valsToDisplay []string) {
|
||||
fmt.Printf("|")
|
||||
}
|
||||
// Special cases of value displaying
|
||||
/* if f.Name == "JID" && f.Value == "0" {
|
||||
fmt.Printf(" ")
|
||||
} else if f.Name == "Ip4_addr" {
|
||||
ia := strings.Split(f.Value, ",")
|
||||
// If we have more than 1 value we need to finish this line, and store value for writing at the end of line loop
|
||||
for i, inter := range ia {
|
||||
if i > 0 {
|
||||
supplines[f.Name] = inter
|
||||
} else {
|
||||
fmt.Printf(" %s", inter)
|
||||
}
|
||||
}
|
||||
//fmt.Printf(" %s", strings.Split(strings.Split(f.Value, "|")[1], "/")[0])
|
||||
} else {*/
|
||||
fmt.Printf(" %s", f.Value)
|
||||
/*}*/
|
||||
// Complete with spaces to the max length
|
||||
for i := len(f.Value) + 1; i < f.MaxLen+1; i++ {
|
||||
fmt.Printf(" ")
|
||||
// Pretty print of sizes
|
||||
if f.Name == "Used" || f.Name == "Referenced" || f.Name == "Available" {
|
||||
var v datasize.ByteSize
|
||||
err := v.UnmarshalText([]byte(f.Value))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Printf(" %s", v.HumanReadable())
|
||||
// Complete with spaces to the max length
|
||||
for i := len(v.HumanReadable()) + 1; i < f.MaxLen+1; i++ {
|
||||
fmt.Printf(" ")
|
||||
}
|
||||
} else {
|
||||
fmt.Printf(" %s", f.Value)
|
||||
// Complete with spaces to the max length
|
||||
for i := len(f.Value) + 1; i < f.MaxLen+1; i++ {
|
||||
fmt.Printf(" ")
|
||||
}
|
||||
}
|
||||
fmt.Printf(" |")
|
||||
}
|
||||
@ -2125,6 +2153,12 @@ func initJailSortStruct() JailSort {
|
||||
ConfigPathDec: func(j1, j2 *Jail) bool {
|
||||
return j1.ConfigPath > j2.ConfigPath
|
||||
},
|
||||
DatastoreInc: func(j1, j2 *Jail) bool {
|
||||
return j1.Datastore < j2.Datastore
|
||||
},
|
||||
DatastoreDec: func(j1, j2 *Jail) bool {
|
||||
return j1.Datastore > j2.Datastore
|
||||
},
|
||||
InternalNameInc: func(j1, j2 *Jail) bool {
|
||||
return j1.InternalName < j2.InternalName
|
||||
},
|
||||
@ -2241,11 +2275,11 @@ func initSnapshotSortStruct() SnapshotSort {
|
||||
NameDec: func(s1, s2 *Snapshot) bool {
|
||||
return s1.Name > s2.Name
|
||||
},
|
||||
DsnameInc: func(s1, s2 *Snapshot) bool {
|
||||
return s1.Dsname < s2.Dsname
|
||||
DatastoreInc: func(s1, s2 *Snapshot) bool {
|
||||
return s1.Datastore < s2.Datastore
|
||||
},
|
||||
DsnameDec: func(s1, s2 *Snapshot) bool {
|
||||
return s1.Dsname > s2.Dsname
|
||||
DatastoreDec: func(s1, s2 *Snapshot) bool {
|
||||
return s1.Datastore > s2.Datastore
|
||||
},
|
||||
JailnameInc: func(s1, s2 *Snapshot) bool {
|
||||
return s1.Jailname < s2.Jailname
|
||||
|
Loading…
Reference in New Issue
Block a user