Add datastore list, filter and sort

This commit is contained in:
yo 2022-06-18 16:09:38 +02:00
parent 86e08ec0f7
commit d4f6b9ddc7

108
cmd/datastore.go Normal file
View File

@ -0,0 +1,108 @@
package cmd
import (
"fmt"
"errors"
"reflect"
"strconv"
"strings"
)
func ListDatastores(args []string, display bool) error {
/***************************************************************
/ Filter datastores by names given on command line
/**************************************************************/
for _, d := range args {
cmd := fmt.Sprintf("zfs list -p -H -o name,used,available,referenced %s", d)
out, err := executeCommand(cmd)
if err != nil {
if strings.HasSuffix(err.Error(), "No such file or directory") {
return errors.New(fmt.Sprintf("Datastore does not exist: %s", d))
} else {
return errors.New(fmt.Sprintf("Error executing command %s: %v; command returned: %s\n", cmd, err, out))
}
}
fields := strings.Fields(out)
if len(fields) < 4 {
return errors.New(fmt.Sprintf("Error parsing output of \"%s\": Not enough fields", cmd))
}
u, _ := strconv.ParseUint(fields[1], 10, 64)
a, _ := strconv.ParseUint(fields[2], 10, 64)
r, _ := strconv.ParseUint(fields[3], 10, 64)
ds := Datastore{Name: d[1:], Mountpoint: d, ZFSDataset: fields[0], Used: u, Referenced: r, Available: a}
err = loadDefaultsForDatastore(&ds)
if err != nil {
return err
}
gDatastores = append(gDatastores, ds)
}
fields := strings.Split(gDisplayDColumns, ",")
if true == display {
/***************************************************************
/ Sort datastores
/ We support 3 sort criteria max
/**************************************************************/
if len(gSortDSFields) > 0 && gSortDSFields != "none" {
ds := initDatastoreSortStruct()
// The way we manage criteria quantity is not very elegant...
var fct1, fct2, fct3 *reflect.Value
for i, c := range strings.Split(gSortDSFields, ",") {
var fctName string
if strings.HasPrefix(c, "-") {
fctName = fmt.Sprintf("%sDec", strings.Replace(c, "-", "", 1))
} else { // Par defaut (pas de prefix +/-) on considere un tri incremental
fctName = fmt.Sprintf("%sInc", strings.Replace(c, "+", "", 1))
}
// Get function by its name
fct, _, err := getStructFieldValue(ds, fctName)
if err != nil {
fieldName := strings.Replace(strings.Replace(c, "-", "", 1), "+", "", 1)
return errors.New(fmt.Sprintf("ERROR getting DatastoreSort struct field %s. Please check the field name: %s\n", fctName, fieldName))
}
switch i + 1 {
case 1:
fct1 = fct
case 2:
fct2 = fct
case 3:
fct3 = fct
}
}
switch len(strings.Split(gSortDSFields, ",")) {
case 1:
DatastoresOrderedBy(fct1.Interface().(datastoreLessFunc)).Sort(gDatastores)
case 2:
DatastoresOrderedBy(fct1.Interface().(datastoreLessFunc), fct2.Interface().(datastoreLessFunc)).Sort(gDatastores)
case 3:
DatastoresOrderedBy(fct1.Interface().(datastoreLessFunc), fct2.Interface().(datastoreLessFunc), fct3.Interface().(datastoreLessFunc)).Sort(gDatastores)
}
}
displayDatastoresFields(gDatastores, fields)
}
return nil
}
/********************************************************************************
* Load jails default config from $datastore/defaults.json
*******************************************************************************/
func loadDefaultsForDatastore(ds *Datastore) error {
jc, err := getJailConfig(fmt.Sprintf("%s/defaults.json", ds.Mountpoint))
if err != nil {
return err
}
ds.DefaultJailConfig = jc
//gDefaultConfig = append(gDefaultConfig, jc)
return nil
}