1098 lines
35 KiB
Go
1098 lines
35 KiB
Go
package cmd
|
|
|
|
import (
|
|
"os"
|
|
"fmt"
|
|
"sort"
|
|
"bufio"
|
|
"errors"
|
|
"os/exec"
|
|
"reflect"
|
|
"strings"
|
|
"strconv"
|
|
)
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Command execution
|
|
*
|
|
*****************************************************************************/
|
|
func executeCommand(cmdline string) (string, error) {
|
|
var cmd []string
|
|
var out []byte
|
|
var err error
|
|
|
|
if gUseSudo {
|
|
cmd = append(cmd, "sudo")
|
|
}
|
|
cs := strings.Split(cmdline, " ")
|
|
|
|
cmd = append(cmd, cs...)
|
|
|
|
if len (cmd) > 1 {
|
|
out, err = exec.Command(cmd[0], cmd[1:]...).Output()
|
|
} else {
|
|
out, err = exec.Command(cmd[0]).Output()
|
|
}
|
|
|
|
return string(out), err
|
|
}
|
|
|
|
|
|
func executeCommandInJail(jail *Jail, cmdline string) (string, error) {
|
|
var cmd []string
|
|
|
|
if gUseSudo {
|
|
cmd = append(cmd, "sudo")
|
|
}
|
|
|
|
cmd = append(cmd, "setfib")
|
|
if len(jail.Config.Exec_fib) > 0 {
|
|
cmd = append(cmd, jail.Config.Exec_fib)
|
|
} else {
|
|
cmd = append(cmd, "0")
|
|
}
|
|
|
|
cmd = append(cmd, "jexec", jail.InternalName)
|
|
|
|
cs := strings.Split(cmdline, " ")
|
|
cmd = append(cmd, cs...)
|
|
|
|
out, err := exec.Command(cmd[0], cmd[1:]...).Output()
|
|
|
|
return string(out), err
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Parse an fstab file, returning an array of Mount
|
|
*****************************************************************************/
|
|
func getFstab(path string) ([]Mount, error) {
|
|
var mounts []Mount
|
|
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return mounts, err
|
|
}
|
|
defer f.Close()
|
|
|
|
scan := bufio.NewScanner(f)
|
|
for scan.Scan() {
|
|
res := strings.Fields(scan.Text())
|
|
if len(res) != 6 {
|
|
return mounts, fmt.Errorf("Incorrect format for fstab line %s", scan.Text())
|
|
}
|
|
freq, err := strconv.Atoi(res[4])
|
|
if err != nil {
|
|
return mounts, fmt.Errorf("Incorrect format for fstab line %s: Dump is not an integer\n", scan.Text())
|
|
}
|
|
pass, err := strconv.Atoi(res[5])
|
|
if err != nil {
|
|
return mounts, fmt.Errorf("Incorrect format for fstab line %s: Pass is not an integer\n", scan.Text())
|
|
}
|
|
m := Mount{
|
|
Device : res[0],
|
|
Mountpoint : res[1],
|
|
Type : res[2],
|
|
Options : strings.Split(res[3], ","),
|
|
Fs_Freq : freq,
|
|
Fs_Passno : pass,
|
|
}
|
|
mounts = append(mounts, m)
|
|
}
|
|
|
|
return mounts, nil
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* Get a specific jail source reference, to update properties after a range loop
|
|
*****************************************************************************/
|
|
func getJailFromArray(internalName string, jarray []Jail) (*Jail, error) {
|
|
for _, j := range jarray {
|
|
if internalName == j.InternalName {
|
|
return &j, nil
|
|
}
|
|
}
|
|
return &Jail{}, errors.New("Jail not found")
|
|
}
|
|
|
|
/*
|
|
|
|
*/
|
|
// Recurse into structure, returning reflect.Kind of named field.
|
|
// Nested fields are named with a dot (ex "MyStruct.MyField")
|
|
func getStructFieldKind(parentStruct interface{}, fieldName string) (reflect.Kind, string, error) {
|
|
v := reflect.ValueOf(parentStruct)
|
|
|
|
if v.Kind() == reflect.Ptr {
|
|
v = v.Elem()
|
|
}
|
|
|
|
// For debugging
|
|
if false {
|
|
for i := 0 ; i < v.NumField(); i++ {
|
|
f := v.Field(i)
|
|
if f.Kind() == reflect.String {
|
|
fmt.Printf("%v=%v\n", v.Type().Field(i).Name, f.Interface())
|
|
}
|
|
}
|
|
}
|
|
|
|
if strings.Contains(fieldName, ".") {
|
|
fs := strings.Split(fieldName, ".")
|
|
f := v.FieldByName(fs[0])
|
|
if f.Kind() == reflect.Struct {
|
|
return getStructFieldKind(f.Interface(), strings.Join(fs[1:], "."))
|
|
} else {
|
|
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("%s is not a struct: %s\n", fs[0], f.Kind().String()))
|
|
}
|
|
} else {
|
|
f := v.FieldByName(fieldName)
|
|
if f.IsValid() {
|
|
return f.Kind(), fieldName, nil
|
|
} else {
|
|
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
|
|
}
|
|
}
|
|
|
|
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Sorting jails
|
|
*
|
|
*****************************************************************************/
|
|
|
|
// already defined in cmd/struct.go
|
|
//type lessFunc func(j1 *Jail, j2 *Jail) bool
|
|
func initSortStruct() JailSort {
|
|
jcs := JailConfigSort{
|
|
Allow_chflagsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_chflags < j2.Config.Allow_chflags
|
|
},
|
|
Allow_chflagsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_chflags > j2.Config.Allow_chflags
|
|
},
|
|
Allow_mlockInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mlock < j2.Config.Allow_mlock
|
|
},
|
|
Allow_mlockDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mlock > j2.Config.Allow_mlock
|
|
},
|
|
Allow_mountInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount < j2.Config.Allow_mount
|
|
},
|
|
Allow_mountDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount > j2.Config.Allow_mount
|
|
},
|
|
Allow_mount_devfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_devfs < j2.Config.Allow_mount_devfs
|
|
},
|
|
Allow_mount_devfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_devfs > j2.Config.Allow_mount_devfs
|
|
},
|
|
Allow_mount_fusefsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_fusefs < j2.Config.Allow_mount_fusefs
|
|
},
|
|
Allow_mount_fusefsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_fusefs > j2.Config.Allow_mount_fusefs
|
|
},
|
|
Allow_mount_nullfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_nullfs < j2.Config.Allow_mount_nullfs
|
|
},
|
|
Allow_mount_nullfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_nullfs > j2.Config.Allow_mount_nullfs
|
|
},
|
|
Allow_mount_procfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_procfs < j2.Config.Allow_mount_procfs
|
|
},
|
|
Allow_mount_procfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_procfs > j2.Config.Allow_mount_procfs
|
|
},
|
|
Allow_mount_tmpfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_tmpfs < j2.Config.Allow_mount_tmpfs
|
|
},
|
|
Allow_mount_tmpfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_tmpfs > j2.Config.Allow_mount_tmpfs
|
|
},
|
|
Allow_mount_zfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_zfs < j2.Config.Allow_mount_zfs
|
|
},
|
|
Allow_mount_zfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_mount_zfs > j2.Config.Allow_mount_zfs
|
|
},
|
|
Allow_quotasInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_quotas < j2.Config.Allow_quotas
|
|
},
|
|
Allow_quotasDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_quotas > j2.Config.Allow_quotas
|
|
},
|
|
Allow_raw_socketsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_raw_sockets < j2.Config.Allow_raw_sockets
|
|
},
|
|
Allow_raw_socketsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_raw_sockets > j2.Config.Allow_raw_sockets
|
|
},
|
|
Allow_set_hostnameInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_set_hostname < j2.Config.Allow_set_hostname
|
|
},
|
|
Allow_set_hostnameDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_set_hostname > j2.Config.Allow_set_hostname
|
|
},
|
|
Allow_socket_afInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_socket_af < j2.Config.Allow_socket_af
|
|
},
|
|
Allow_socket_afDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_socket_af > j2.Config.Allow_socket_af
|
|
},
|
|
Allow_sysvipcInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_sysvipc < j2.Config.Allow_sysvipc
|
|
},
|
|
Allow_sysvipcDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_sysvipc > j2.Config.Allow_sysvipc
|
|
},
|
|
Allow_tunInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_tun < j2.Config.Allow_tun
|
|
},
|
|
Allow_tunDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_tun > j2.Config.Allow_tun
|
|
},
|
|
Allow_vmmInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_vmm < j2.Config.Allow_vmm
|
|
},
|
|
Allow_vmmDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Allow_vmm > j2.Config.Allow_vmm
|
|
},
|
|
Assign_localhostInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Assign_localhost < j2.Config.Assign_localhost
|
|
},
|
|
Assign_localhostDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Assign_localhost > j2.Config.Assign_localhost
|
|
},
|
|
AvailableInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Available < j2.Config.Available
|
|
},
|
|
AvailableDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Available > j2.Config.Available
|
|
},
|
|
BasejailInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Basejail < j2.Config.Basejail
|
|
},
|
|
BasejailDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Basejail > j2.Config.Basejail
|
|
},
|
|
BootInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Boot < j2.Config.Boot
|
|
},
|
|
BootDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Boot > j2.Config.Boot
|
|
},
|
|
BpfInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Bpf < j2.Config.Bpf
|
|
},
|
|
BpfDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Bpf > j2.Config.Bpf
|
|
},
|
|
Children_maxInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Children_max < j2.Config.Children_max
|
|
},
|
|
Children_maxDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Children_max > j2.Config.Children_max
|
|
},
|
|
Cloned_releaseInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Cloned_release < j2.Config.Cloned_release
|
|
},
|
|
Cloned_releaseDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Cloned_release > j2.Config.Cloned_release
|
|
},
|
|
CommentInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Comment < j2.Config.Comment
|
|
},
|
|
CommentDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Comment > j2.Config.Comment
|
|
},
|
|
CompressionInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Compression < j2.Config.Compression
|
|
},
|
|
CompressionDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Compression > j2.Config.Compression
|
|
},
|
|
CompressratioInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Compressratio < j2.Config.Compressratio
|
|
},
|
|
CompressratioDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Compressratio > j2.Config.Compressratio
|
|
},
|
|
Config_versionInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Config_version < j2.Config.Config_version
|
|
},
|
|
Config_versionDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Config_version > j2.Config.Config_version
|
|
},
|
|
CoredumpsizeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Coredumpsize < j2.Config.Coredumpsize
|
|
},
|
|
CoredumpsizeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Coredumpsize > j2.Config.Coredumpsize
|
|
},
|
|
CountInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Count < j2.Config.Count
|
|
},
|
|
CountDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Count > j2.Config.Count
|
|
},
|
|
CpusetInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Cpuset < j2.Config.Cpuset
|
|
},
|
|
CpusetDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Cpuset > j2.Config.Cpuset
|
|
},
|
|
CputimeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Cputime < j2.Config.Cputime
|
|
},
|
|
CputimeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Cputime > j2.Config.Cputime
|
|
},
|
|
DatasizeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Datasize < j2.Config.Datasize
|
|
},
|
|
DatasizeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Datasize > j2.Config.Datasize
|
|
},
|
|
DedupInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Dedup < j2.Config.Dedup
|
|
},
|
|
DedupDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Dedup > j2.Config.Dedup
|
|
},
|
|
DefaultrouterInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Defaultrouter < j2.Config.Defaultrouter
|
|
},
|
|
DefaultrouterDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Defaultrouter > j2.Config.Defaultrouter
|
|
},
|
|
Defaultrouter6Inc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Defaultrouter6 < j2.Config.Defaultrouter6
|
|
},
|
|
Defaultrouter6Dec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Defaultrouter6 > j2.Config.Defaultrouter6
|
|
},
|
|
DependsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Depends < j2.Config.Depends
|
|
},
|
|
DependsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Depends > j2.Config.Depends
|
|
},
|
|
Devfs_rulesetInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Devfs_ruleset < j2.Config.Devfs_ruleset
|
|
},
|
|
Devfs_rulesetDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Devfs_ruleset > j2.Config.Devfs_ruleset
|
|
},
|
|
DhcpInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Dhcp < j2.Config.Dhcp
|
|
},
|
|
DhcpDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Dhcp > j2.Config.Dhcp
|
|
},
|
|
Enforce_statfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Enforce_statfs < j2.Config.Enforce_statfs
|
|
},
|
|
Enforce_statfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Enforce_statfs > j2.Config.Enforce_statfs
|
|
},
|
|
Exec_cleanInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_clean < j2.Config.Exec_clean
|
|
},
|
|
Exec_cleanDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_clean > j2.Config.Exec_clean
|
|
},
|
|
Exec_createdInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_created < j2.Config.Exec_created
|
|
},
|
|
Exec_createdDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_created > j2.Config.Exec_created
|
|
},
|
|
Exec_fibInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_fib < j2.Config.Exec_fib
|
|
},
|
|
Exec_fibDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_fib > j2.Config.Exec_fib
|
|
},
|
|
Exec_jail_userInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_jail_user < j2.Config.Exec_jail_user
|
|
},
|
|
Exec_jail_userDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_jail_user > j2.Config.Exec_jail_user
|
|
},
|
|
Exec_poststartInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_poststart < j2.Config.Exec_poststart
|
|
},
|
|
Exec_poststartDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_poststart > j2.Config.Exec_poststart
|
|
},
|
|
Exec_poststopInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_poststop < j2.Config.Exec_poststop
|
|
},
|
|
Exec_poststopDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_poststop > j2.Config.Exec_poststop
|
|
},
|
|
Exec_prestartInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_prestart < j2.Config.Exec_prestart
|
|
},
|
|
Exec_prestartDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_prestart > j2.Config.Exec_prestart
|
|
},
|
|
Exec_prestopInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_prestop < j2.Config.Exec_prestop
|
|
},
|
|
Exec_prestopDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_prestop > j2.Config.Exec_prestop
|
|
},
|
|
Exec_startInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_start < j2.Config.Exec_start
|
|
},
|
|
Exec_startDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_start > j2.Config.Exec_start
|
|
},
|
|
Exec_stopInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_stop < j2.Config.Exec_stop
|
|
},
|
|
Exec_stopDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_stop > j2.Config.Exec_stop
|
|
},
|
|
Exec_system_jail_userInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_system_jail_user < j2.Config.Exec_system_jail_user
|
|
},
|
|
Exec_system_jail_userDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_system_jail_user > j2.Config.Exec_system_jail_user
|
|
},
|
|
Exec_system_userInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_system_user < j2.Config.Exec_system_user
|
|
},
|
|
Exec_system_userDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_system_user > j2.Config.Exec_system_user
|
|
},
|
|
Exec_timeoutInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_timeout < j2.Config.Exec_timeout
|
|
},
|
|
Exec_timeoutDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Exec_timeout > j2.Config.Exec_timeout
|
|
},
|
|
Host_domainnameInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_domainname < j2.Config.Host_domainname
|
|
},
|
|
Host_domainnameDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_domainname > j2.Config.Host_domainname
|
|
},
|
|
Host_hostnameInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_hostname < j2.Config.Host_hostname
|
|
},
|
|
Host_hostnameDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_hostname > j2.Config.Host_hostname
|
|
},
|
|
Host_hostuuidInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_hostuuid < j2.Config.Host_hostuuid
|
|
},
|
|
Host_hostuuidDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_hostuuid > j2.Config.Host_hostuuid
|
|
},
|
|
Host_timeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_time < j2.Config.Host_time
|
|
},
|
|
Host_timeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Host_time > j2.Config.Host_time
|
|
},
|
|
HostidInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Hostid < j2.Config.Hostid
|
|
},
|
|
HostidDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Hostid > j2.Config.Hostid
|
|
},
|
|
Hostid_strict_checkInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Hostid_strict_check < j2.Config.Hostid_strict_check
|
|
},
|
|
Hostid_strict_checkDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Hostid_strict_check > j2.Config.Hostid_strict_check
|
|
},
|
|
InterfacesInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Interfaces < j2.Config.Interfaces
|
|
},
|
|
InterfacesDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Interfaces > j2.Config.Interfaces
|
|
},
|
|
Ip_hostnameInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip_hostname < j2.Config.Ip_hostname
|
|
},
|
|
Ip_hostnameDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip_hostname > j2.Config.Ip_hostname
|
|
},
|
|
Ip4Inc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip4 < j2.Config.Ip4
|
|
},
|
|
Ip4Dec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip4 > j2.Config.Ip4
|
|
},
|
|
Ip4_addrInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip4_addr < j2.Config.Ip4_addr
|
|
},
|
|
Ip4_addrDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip4_addr > j2.Config.Ip4_addr
|
|
},
|
|
Ip4_saddrselInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip4_saddrsel < j2.Config.Ip4_saddrsel
|
|
},
|
|
Ip4_saddrselDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip4_saddrsel > j2.Config.Ip4_saddrsel
|
|
},
|
|
Ip6Inc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip6 < j2.Config.Ip6
|
|
},
|
|
Ip6Dec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip6 > j2.Config.Ip6
|
|
},
|
|
Ip6_addrInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip6_addr < j2.Config.Ip6_addr
|
|
},
|
|
Ip6_addrDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip6_addr > j2.Config.Ip6_addr
|
|
},
|
|
Ip6_saddrselInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip6_saddrsel < j2.Config.Ip6_saddrsel
|
|
},
|
|
Ip6_saddrselDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Ip6_saddrsel > j2.Config.Ip6_saddrsel
|
|
},
|
|
Jail_zfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jail_zfs < j2.Config.Jail_zfs
|
|
},
|
|
Jail_zfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jail_zfs > j2.Config.Jail_zfs
|
|
},
|
|
Jail_zfs_datasetInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jail_zfs_dataset < j2.Config.Jail_zfs_dataset
|
|
},
|
|
Jail_zfs_datasetDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jail_zfs_dataset > j2.Config.Jail_zfs_dataset
|
|
},
|
|
Jail_zfs_mountpointInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jail_zfs_mountpoint < j2.Config.Jail_zfs_mountpoint
|
|
},
|
|
Jail_zfs_mountpointDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jail_zfs_mountpoint > j2.Config.Jail_zfs_mountpoint
|
|
},
|
|
JailtypeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jailtype < j2.Config.Jailtype
|
|
},
|
|
JailtypeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Jailtype > j2.Config.Jailtype
|
|
},
|
|
Last_startedInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Last_started < j2.Config.Last_started
|
|
},
|
|
Last_startedDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Last_started > j2.Config.Last_started
|
|
},
|
|
Localhost_ipInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Localhost_ip < j2.Config.Localhost_ip
|
|
},
|
|
Localhost_ipDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Localhost_ip > j2.Config.Localhost_ip
|
|
},
|
|
Login_flagsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Login_flags < j2.Config.Login_flags
|
|
},
|
|
Login_flagsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Login_flags > j2.Config.Login_flags
|
|
},
|
|
Mac_prefixInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mac_prefix < j2.Config.Mac_prefix
|
|
},
|
|
Mac_prefixDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mac_prefix > j2.Config.Mac_prefix
|
|
},
|
|
MaxprocInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Maxproc < j2.Config.Maxproc
|
|
},
|
|
MaxprocDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Maxproc > j2.Config.Maxproc
|
|
},
|
|
MemorylockedInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Memorylocked < j2.Config.Memorylocked
|
|
},
|
|
MemorylockedDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Memorylocked > j2.Config.Memorylocked
|
|
},
|
|
MemoryuseInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Memoryuse < j2.Config.Memoryuse
|
|
},
|
|
MemoryuseDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Memoryuse > j2.Config.Memoryuse
|
|
},
|
|
Min_dyn_devfs_rulesetInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Min_dyn_devfs_ruleset < j2.Config.Min_dyn_devfs_ruleset
|
|
},
|
|
Min_dyn_devfs_rulesetDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Min_dyn_devfs_ruleset > j2.Config.Min_dyn_devfs_ruleset
|
|
},
|
|
Mount_devfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_devfs < j2.Config.Mount_devfs
|
|
},
|
|
Mount_devfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_devfs > j2.Config.Mount_devfs
|
|
},
|
|
Mount_fdescfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_fdescfs < j2.Config.Mount_fdescfs
|
|
},
|
|
Mount_fdescfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_fdescfs > j2.Config.Mount_fdescfs
|
|
},
|
|
Mount_linprocfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_linprocfs < j2.Config.Mount_linprocfs
|
|
},
|
|
Mount_linprocfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_linprocfs > j2.Config.Mount_linprocfs
|
|
},
|
|
Mount_procfsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_procfs < j2.Config.Mount_procfs
|
|
},
|
|
Mount_procfsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mount_procfs > j2.Config.Mount_procfs
|
|
},
|
|
MountpointInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mountpoint < j2.Config.Mountpoint
|
|
},
|
|
MountpointDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Mountpoint > j2.Config.Mountpoint
|
|
},
|
|
MsgqqueuedInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Msgqqueued < j2.Config.Msgqqueued
|
|
},
|
|
MsgqqueuedDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Msgqqueued > j2.Config.Msgqqueued
|
|
},
|
|
MsgqsizeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Msgqsize < j2.Config.Msgqsize
|
|
},
|
|
MsgqsizeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Msgqsize > j2.Config.Msgqsize
|
|
},
|
|
NatInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat < j2.Config.Nat
|
|
},
|
|
NatDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat > j2.Config.Nat
|
|
},
|
|
Nat_backendInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_backend < j2.Config.Nat_backend
|
|
},
|
|
Nat_backendDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_backend > j2.Config.Nat_backend
|
|
},
|
|
Nat_forwardsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_forwards < j2.Config.Nat_forwards
|
|
},
|
|
Nat_forwardsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_forwards > j2.Config.Nat_forwards
|
|
},
|
|
Nat_interfaceInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_interface < j2.Config.Nat_interface
|
|
},
|
|
Nat_interfaceDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_interface > j2.Config.Nat_interface
|
|
},
|
|
Nat_prefixInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_prefix < j2.Config.Nat_prefix
|
|
},
|
|
Nat_prefixDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nat_prefix > j2.Config.Nat_prefix
|
|
},
|
|
NmsgqInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nmsgq < j2.Config.Nmsgq
|
|
},
|
|
NmsgqDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nmsgq > j2.Config.Nmsgq
|
|
},
|
|
NotesInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Notes < j2.Config.Notes
|
|
},
|
|
NotesDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Notes > j2.Config.Notes
|
|
},
|
|
NsemInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nsem < j2.Config.Nsem
|
|
},
|
|
NsemDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nsem > j2.Config.Nsem
|
|
},
|
|
NsemopInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nsemop < j2.Config.Nsemop
|
|
},
|
|
NsemopDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nsemop > j2.Config.Nsemop
|
|
},
|
|
NshmInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nshm < j2.Config.Nshm
|
|
},
|
|
NshmDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nshm > j2.Config.Nshm
|
|
},
|
|
NthrInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nthr < j2.Config.Nthr
|
|
},
|
|
NthrDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Nthr > j2.Config.Nthr
|
|
},
|
|
OpenfilesInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Openfiles < j2.Config.Openfiles
|
|
},
|
|
OpenfilesDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Openfiles > j2.Config.Openfiles
|
|
},
|
|
OriginInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Origin < j2.Config.Origin
|
|
},
|
|
OriginDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Origin > j2.Config.Origin
|
|
},
|
|
OwnerInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Owner < j2.Config.Owner
|
|
},
|
|
OwnerDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Owner > j2.Config.Owner
|
|
},
|
|
PcpuInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Pcpu < j2.Config.Pcpu
|
|
},
|
|
PcpuDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Pcpu > j2.Config.Pcpu
|
|
},
|
|
Plugin_nameInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Plugin_name < j2.Config.Plugin_name
|
|
},
|
|
Plugin_nameDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Plugin_name > j2.Config.Plugin_name
|
|
},
|
|
Plugin_repositoryInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Plugin_repository < j2.Config.Plugin_repository
|
|
},
|
|
Plugin_repositoryDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Plugin_repository > j2.Config.Plugin_repository
|
|
},
|
|
PriorityInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Priority < j2.Config.Priority
|
|
},
|
|
PriorityDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Priority > j2.Config.Priority
|
|
},
|
|
PseudoterminalsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Pseudoterminals < j2.Config.Pseudoterminals
|
|
},
|
|
PseudoterminalsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Pseudoterminals > j2.Config.Pseudoterminals
|
|
},
|
|
QuotaInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Quota < j2.Config.Quota
|
|
},
|
|
QuotaDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Quota > j2.Config.Quota
|
|
},
|
|
ReadbpsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Readbps < j2.Config.Readbps
|
|
},
|
|
ReadbpsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Readbps > j2.Config.Readbps
|
|
},
|
|
ReadiopsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Readiops < j2.Config.Readiops
|
|
},
|
|
ReadiopsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Readiops > j2.Config.Readiops
|
|
},
|
|
ReleaseInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Release < j2.Config.Release
|
|
},
|
|
ReleaseDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Release > j2.Config.Release
|
|
},
|
|
ReservationInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Reservation < j2.Config.Reservation
|
|
},
|
|
ReservationDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Reservation > j2.Config.Reservation
|
|
},
|
|
ResolverInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Resolver < j2.Config.Resolver
|
|
},
|
|
ResolverDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Resolver > j2.Config.Resolver
|
|
},
|
|
RlimitsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Rlimits < j2.Config.Rlimits
|
|
},
|
|
RlimitsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Rlimits > j2.Config.Rlimits
|
|
},
|
|
RtsoldInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Rtsold < j2.Config.Rtsold
|
|
},
|
|
RtsoldDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Rtsold > j2.Config.Rtsold
|
|
},
|
|
SecurelevelInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Securelevel < j2.Config.Securelevel
|
|
},
|
|
SecurelevelDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Securelevel > j2.Config.Securelevel
|
|
},
|
|
ShmsizeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Shmsize < j2.Config.Shmsize
|
|
},
|
|
ShmsizeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Shmsize > j2.Config.Shmsize
|
|
},
|
|
StacksizeInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Stacksize < j2.Config.Stacksize
|
|
},
|
|
StacksizeDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Stacksize > j2.Config.Stacksize
|
|
},
|
|
Stop_timeoutInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Stop_timeout < j2.Config.Stop_timeout
|
|
},
|
|
Stop_timeoutDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Stop_timeout > j2.Config.Stop_timeout
|
|
},
|
|
SwapuseInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Swapuse < j2.Config.Swapuse
|
|
},
|
|
SwapuseDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Swapuse > j2.Config.Swapuse
|
|
},
|
|
Sync_stateInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sync_state < j2.Config.Sync_state
|
|
},
|
|
Sync_stateDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sync_state > j2.Config.Sync_state
|
|
},
|
|
Sync_targetInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sync_target < j2.Config.Sync_target
|
|
},
|
|
Sync_targetDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sync_target > j2.Config.Sync_target
|
|
},
|
|
Sync_tgt_zpoolInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sync_tgt_zpool < j2.Config.Sync_tgt_zpool
|
|
},
|
|
Sync_tgt_zpoolDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sync_tgt_zpool > j2.Config.Sync_tgt_zpool
|
|
},
|
|
SysvmsgInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sysvmsg < j2.Config.Sysvmsg
|
|
},
|
|
SysvmsgDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sysvmsg > j2.Config.Sysvmsg
|
|
},
|
|
SysvsemInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sysvsem < j2.Config.Sysvsem
|
|
},
|
|
SysvsemDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sysvsem > j2.Config.Sysvsem
|
|
},
|
|
SysvshmInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sysvshm < j2.Config.Sysvshm
|
|
},
|
|
SysvshmDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Sysvshm > j2.Config.Sysvshm
|
|
},
|
|
TemplateInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Template < j2.Config.Template
|
|
},
|
|
TemplateDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Template > j2.Config.Template
|
|
},
|
|
UsedInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Used < j2.Config.Used
|
|
},
|
|
UsedDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Used > j2.Config.Used
|
|
},
|
|
VmemoryuseInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vmemoryuse < j2.Config.Vmemoryuse
|
|
},
|
|
VmemoryuseDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vmemoryuse > j2.Config.Vmemoryuse
|
|
},
|
|
VnetInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet < j2.Config.Vnet
|
|
},
|
|
VnetDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet > j2.Config.Vnet
|
|
},
|
|
Vnet_default_interfaceInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet_default_interface < j2.Config.Vnet_default_interface
|
|
},
|
|
Vnet_default_interfaceDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet_default_interface > j2.Config.Vnet_default_interface
|
|
},
|
|
Vnet_interfacesInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet_interfaces < j2.Config.Vnet_interfaces
|
|
},
|
|
Vnet_interfacesDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet_interfaces > j2.Config.Vnet_interfaces
|
|
},
|
|
Vnet0_macInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet0_mac < j2.Config.Vnet0_mac
|
|
},
|
|
Vnet0_macDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet0_mac > j2.Config.Vnet0_mac
|
|
},
|
|
Vnet1_macInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet1_mac < j2.Config.Vnet1_mac
|
|
},
|
|
Vnet1_macDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet1_mac > j2.Config.Vnet1_mac
|
|
},
|
|
Vnet2_macInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet2_mac < j2.Config.Vnet2_mac
|
|
},
|
|
Vnet2_macDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet2_mac > j2.Config.Vnet2_mac
|
|
},
|
|
Vnet3_macInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet3_mac < j2.Config.Vnet3_mac
|
|
},
|
|
Vnet3_macDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Vnet3_mac > j2.Config.Vnet3_mac
|
|
},
|
|
WallclockInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Wallclock < j2.Config.Wallclock
|
|
},
|
|
WallclockDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Wallclock > j2.Config.Wallclock
|
|
},
|
|
WritebpsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Writebps < j2.Config.Writebps
|
|
},
|
|
WritebpsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Writebps > j2.Config.Writebps
|
|
},
|
|
WriteiopsInc: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Writeiops < j2.Config.Writeiops
|
|
},
|
|
WriteiopsDec: func(j1, j2 *Jail) bool {
|
|
return j1.Config.Writeiops > j2.Config.Writeiops
|
|
},
|
|
}
|
|
|
|
js := JailSort{
|
|
ConfigPathInc: func(j1, j2 *Jail) bool {
|
|
return j1.ConfigPath < j2.ConfigPath
|
|
},
|
|
ConfigPathDec: func(j1, j2 *Jail) bool {
|
|
return j1.ConfigPath > j2.ConfigPath
|
|
},
|
|
InternalNameInc: func(j1, j2 *Jail) bool {
|
|
return j1.InternalName < j2.InternalName
|
|
},
|
|
InternalNameDec: func(j1, j2 *Jail) bool {
|
|
return j1.InternalName > j2.InternalName
|
|
},
|
|
JIDInc: func(j1, j2 *Jail) bool {
|
|
return j1.JID < j2.JID
|
|
},
|
|
JIDDec: func(j1, j2 *Jail) bool {
|
|
return j1.JID > j2.JID
|
|
},
|
|
NameInc: func(j1, j2 *Jail) bool {
|
|
return j1.Name < j2.Name
|
|
},
|
|
NameDec: func(j1, j2 *Jail) bool {
|
|
return j1.Name > j2.Name
|
|
},
|
|
RootPathInc: func(j1, j2 *Jail) bool {
|
|
return j1.RootPath < j2.RootPath
|
|
},
|
|
RootPathDec: func(j1, j2 *Jail) bool {
|
|
return j1.RootPath > j2.RootPath
|
|
},
|
|
RunningInc: func(j1, j2 *Jail) bool {
|
|
return !j1.Running && j2.Running
|
|
},
|
|
RunningDec: func(j1, j2 *Jail) bool {
|
|
return j1.Running && !j2.Running
|
|
},
|
|
ZpoolInc: func(j1, j2 *Jail) bool {
|
|
return j1.Zpool < j2.Zpool
|
|
},
|
|
ZpoolDec: func(j1, j2 *Jail) bool {
|
|
return j1.Zpool > j2.Zpool
|
|
},
|
|
Config: jcs,
|
|
}
|
|
|
|
return js
|
|
}
|
|
|
|
// multiSorter implements the Sort interface, sorting the jails within.
|
|
type multiSorter struct {
|
|
jails []Jail
|
|
less []lessFunc
|
|
}
|
|
|
|
// Sort sorts the argument slice according to the less functions passed to OrderedBy.
|
|
func (ms *multiSorter) Sort(jails []Jail) {
|
|
ms.jails = jails
|
|
sort.Sort(ms)
|
|
}
|
|
|
|
// OrderedBy returns a Sorter that sorts using the less functions, in order.
|
|
// Call its Sort method to sort the data.
|
|
func OrderedBy(less ...lessFunc) *multiSorter {
|
|
return &multiSorter{
|
|
less: less,
|
|
}
|
|
}
|
|
|
|
// Len is part of sort.Interface.
|
|
func (ms *multiSorter) Len() int {
|
|
return len(ms.jails)
|
|
}
|
|
|
|
// Swap is part of sort.Interface.
|
|
func (ms *multiSorter) Swap(i, j int) {
|
|
ms.jails[i], ms.jails[j] = ms.jails[j], ms.jails[i]
|
|
}
|
|
|
|
// Less is part of sort.Interface. It is implemented by looping along the
|
|
// less functions until it finds a comparison that discriminates between
|
|
// the two items (one is less than the other). Note that it can call the
|
|
// less functions twice per call. We could change the functions to return
|
|
// -1, 0, 1 and reduce the number of calls for greater efficiency: an
|
|
// exercise for the reader.
|
|
func (ms *multiSorter) Less(i, j int) bool {
|
|
p, q := &ms.jails[i], &ms.jails[j]
|
|
// Try all but the last comparison.
|
|
var k int
|
|
for k = 0; k < len(ms.less)-1; k++ {
|
|
less := ms.less[k]
|
|
switch {
|
|
case less(p, q):
|
|
// p < q, so we have a decision.
|
|
return true
|
|
case less(q, p):
|
|
// p > q, so we have a decision.
|
|
return false
|
|
}
|
|
// p == q; try the next comparison.
|
|
}
|
|
// All comparisons to here said "equal", so just return whatever
|
|
// the final comparison reports.
|
|
return ms.less[k](p, q)
|
|
}
|
|
|
|
|