109 lines
3.4 KiB
Go
109 lines
3.4 KiB
Go
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
|
|
}
|