Add sort support, can use every field

This commit is contained in:
yo 2021-12-20 22:10:38 +01:00
parent 9af50111f3
commit c36cf9511a
4 changed files with 1299 additions and 3 deletions

View File

@ -357,6 +357,50 @@ func ListJails(args []string, display bool) {
jails = js
}
/************************************************************************************
/ Sort jails
/ We support 3 sort criteria max
/***********************************************************************************/
if len(gSortFields) > 0 {
js := initSortStruct()
// The way we manage criteria quantity is not very elegant...
var fct1, fct2, fct3 reflect.Value
for i, c := range strings.Split(gSortFields, ",") {
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(js, fctName)
if err != nil {
fieldName := strings.Replace(strings.Replace(c, "-", "", 1), "+", "", 1)
fmt.Printf("ERROR getting JailSort struct field %s. Please check the field name: %s\n", fctName, fieldName)
return
}
switch i+1 {
case 1: fct1 = fct
case 2: fct2 = fct
case 3: fct3 = fct
}
}
switch len(strings.Split(gSortFields, ",")) {
case 1:
OrderedBy(fct1.Interface().(lessFunc)).Sort(jails)
case 2:
OrderedBy(fct1.Interface().(lessFunc), fct2.Interface().(lessFunc)).Sort(jails)
case 3:
OrderedBy(fct1.Interface().(lessFunc), fct2.Interface().(lessFunc), fct3.Interface().(lessFunc)).Sort(jails)
}
}
/************************************************************************************
/ Finally, display jails
/***********************************************************************************/
if display {
displayStructFields(jails, fields)
}

View File

@ -3,14 +3,14 @@ package cmd
import (
"os"
"fmt"
// "strings"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
const (
version = "0.001"
version = "0.02"
)
var (
@ -81,7 +81,7 @@ func init() {
listCmd.PersistentFlags().StringVarP(&gDisplayColumns, "outcol", "o", "JID,Name,Config.Release,Config.Ip4_addr,Running", "Show these columns in output")
listCmd.PersistentFlags().BoolVarP(&gNoLineSep, "nolinesep", "l", false, "Do not display line separator between jails")
listCmd.PersistentFlags().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.PersistentFlags().StringVarP(&gSortFields, "sort", "s", "none", "Display jails sorted by field values. Ex: \"gocage list -s Config.Priority\" will sort jails by their start priority. NOT IMPLEMENTED YET")
listCmd.PersistentFlags().StringVarP(&gSortFields, "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.")
// Now declare commands
rootCmd.AddCommand(versionCmd)
@ -124,6 +124,10 @@ func initConfig() {
if listCmd.Flags().Lookup("sort") != nil && false == listCmd.Flags().Lookup("sort").Changed {
gSortFields = viper.GetString("sort")
}
if len(strings.Split(gSortFields, ",")) > 3 {
fmt.Printf("More than 3 sort criteria, this is not supported!\n")
os.Exit(1)
}
}
func Execute() {

View File

@ -1,5 +1,7 @@
package cmd
// To allow sorting, just duplicate fields in JailSort below
type Jail struct {
Name string
InternalName string
@ -15,6 +17,11 @@ type Jail struct {
// iocage struct as stored in config.json
// CONFIG_VERSION = 27
//
// Fields in this struct are acquired by their name using reflection
// So these char are forbidden for field name: -+.
//
// To allow sorting, just duplicate fields in JailConfigSort below
type JailConfig struct {
Config_version string `json:"CONFIG_VERSION"`
Allow_chflags int `json:"allow_chflags"`
@ -155,3 +162,302 @@ type JailConfig struct {
Writeiops string `json:"writeiops"`
}
// This struct hold "sort by jail fields" functions
type lessFunc func(j1 *Jail, j2 *Jail) bool
// Fields in this struct are acquired by their name using reflection
// So these char are forbidden for field name: -+.
//
type JailSort struct {
NameInc lessFunc
NameDec lessFunc
InternalNameInc lessFunc
InternalNameDec lessFunc
JIDInc lessFunc
JIDDec lessFunc
RootPathInc lessFunc
RootPathDec lessFunc
ConfigPathInc lessFunc
ConfigPathDec lessFunc
RunningInc lessFunc
RunningDec lessFunc
ZpoolInc lessFunc
ZpoolDec lessFunc
Config JailConfigSort
}
type JailConfigSort struct {
Config_versionInc lessFunc
Config_versionDec lessFunc
Allow_chflagsInc lessFunc
Allow_chflagsDec lessFunc
Allow_mlockInc lessFunc
Allow_mlockDec lessFunc
Allow_mountInc lessFunc
Allow_mountDec lessFunc
Allow_mount_devfsInc lessFunc
Allow_mount_devfsDec lessFunc
Allow_mount_fusefsInc lessFunc
Allow_mount_fusefsDec lessFunc
Allow_mount_nullfsInc lessFunc
Allow_mount_nullfsDec lessFunc
Allow_mount_procfsInc lessFunc
Allow_mount_procfsDec lessFunc
Allow_mount_tmpfsInc lessFunc
Allow_mount_tmpfsDec lessFunc
Allow_mount_zfsInc lessFunc
Allow_mount_zfsDec lessFunc
Allow_quotasInc lessFunc
Allow_quotasDec lessFunc
Allow_raw_socketsInc lessFunc
Allow_raw_socketsDec lessFunc
Allow_set_hostnameInc lessFunc
Allow_set_hostnameDec lessFunc
Allow_socket_afInc lessFunc
Allow_socket_afDec lessFunc
Allow_sysvipcInc lessFunc
Allow_sysvipcDec lessFunc
Allow_tunInc lessFunc
Allow_tunDec lessFunc
Allow_vmmInc lessFunc
Allow_vmmDec lessFunc
Assign_localhostInc lessFunc
Assign_localhostDec lessFunc
AvailableInc lessFunc
AvailableDec lessFunc
BasejailInc lessFunc
BasejailDec lessFunc
BootInc lessFunc
BootDec lessFunc
BpfInc lessFunc
BpfDec lessFunc
Children_maxInc lessFunc
Children_maxDec lessFunc
Cloned_releaseInc lessFunc
Cloned_releaseDec lessFunc
CommentInc lessFunc
CommentDec lessFunc
CompressionInc lessFunc
CompressionDec lessFunc
CompressratioInc lessFunc
CompressratioDec lessFunc
CoredumpsizeInc lessFunc
CoredumpsizeDec lessFunc
CountInc lessFunc
CountDec lessFunc
CpusetInc lessFunc
CpusetDec lessFunc
CputimeInc lessFunc
CputimeDec lessFunc
DatasizeInc lessFunc
DatasizeDec lessFunc
DedupInc lessFunc
DedupDec lessFunc
DefaultrouterInc lessFunc
DefaultrouterDec lessFunc
Defaultrouter6Inc lessFunc
Defaultrouter6Dec lessFunc
DependsInc lessFunc
DependsDec lessFunc
Devfs_rulesetInc lessFunc
Devfs_rulesetDec lessFunc
DhcpInc lessFunc
DhcpDec lessFunc
Enforce_statfsInc lessFunc
Enforce_statfsDec lessFunc
Exec_cleanInc lessFunc
Exec_cleanDec lessFunc
Exec_createdInc lessFunc
Exec_createdDec lessFunc
Exec_fibInc lessFunc
Exec_fibDec lessFunc
Exec_jail_userInc lessFunc
Exec_jail_userDec lessFunc
Exec_poststartInc lessFunc
Exec_poststartDec lessFunc
Exec_poststopInc lessFunc
Exec_poststopDec lessFunc
Exec_prestartInc lessFunc
Exec_prestartDec lessFunc
Exec_prestopInc lessFunc
Exec_prestopDec lessFunc
Exec_startInc lessFunc
Exec_startDec lessFunc
Exec_stopInc lessFunc
Exec_stopDec lessFunc
Exec_system_jail_userInc lessFunc
Exec_system_jail_userDec lessFunc
Exec_system_userInc lessFunc
Exec_system_userDec lessFunc
Exec_timeoutInc lessFunc
Exec_timeoutDec lessFunc
Host_domainnameInc lessFunc
Host_domainnameDec lessFunc
Host_hostnameInc lessFunc
Host_hostnameDec lessFunc
Host_hostuuidInc lessFunc
Host_hostuuidDec lessFunc
Host_timeInc lessFunc
Host_timeDec lessFunc
HostidInc lessFunc
HostidDec lessFunc
Hostid_strict_checkInc lessFunc
Hostid_strict_checkDec lessFunc
InterfacesInc lessFunc
InterfacesDec lessFunc
Ip4Inc lessFunc
Ip4Dec lessFunc
Ip4_addrInc lessFunc
Ip4_addrDec lessFunc
Ip4_saddrselInc lessFunc
Ip4_saddrselDec lessFunc
Ip6Inc lessFunc
Ip6Dec lessFunc
Ip6_addrInc lessFunc
Ip6_addrDec lessFunc
Ip6_saddrselInc lessFunc
Ip6_saddrselDec lessFunc
Ip_hostnameInc lessFunc
Ip_hostnameDec lessFunc
Jail_zfsInc lessFunc
Jail_zfsDec lessFunc
Jail_zfs_datasetInc lessFunc
Jail_zfs_datasetDec lessFunc
Jail_zfs_mountpointInc lessFunc
Jail_zfs_mountpointDec lessFunc
Last_startedInc lessFunc
Last_startedDec lessFunc
Localhost_ipInc lessFunc
Localhost_ipDec lessFunc
Login_flagsInc lessFunc
Login_flagsDec lessFunc
Mac_prefixInc lessFunc
Mac_prefixDec lessFunc
MaxprocInc lessFunc
MaxprocDec lessFunc
MemorylockedInc lessFunc
MemorylockedDec lessFunc
MemoryuseInc lessFunc
MemoryuseDec lessFunc
Min_dyn_devfs_rulesetInc lessFunc
Min_dyn_devfs_rulesetDec lessFunc
Mount_devfsInc lessFunc
Mount_devfsDec lessFunc
Mount_fdescfsInc lessFunc
Mount_fdescfsDec lessFunc
Mount_linprocfsInc lessFunc
Mount_linprocfsDec lessFunc
Mount_procfsInc lessFunc
Mount_procfsDec lessFunc
MountpointInc lessFunc
MountpointDec lessFunc
MsgqqueuedInc lessFunc
MsgqqueuedDec lessFunc
MsgqsizeInc lessFunc
MsgqsizeDec lessFunc
NatInc lessFunc
NatDec lessFunc
Nat_backendInc lessFunc
Nat_backendDec lessFunc
Nat_forwardsInc lessFunc
Nat_forwardsDec lessFunc
Nat_interfaceInc lessFunc
Nat_interfaceDec lessFunc
Nat_prefixInc lessFunc
Nat_prefixDec lessFunc
NmsgqInc lessFunc
NmsgqDec lessFunc
NotesInc lessFunc
NotesDec lessFunc
NsemInc lessFunc
NsemDec lessFunc
NsemopInc lessFunc
NsemopDec lessFunc
NshmInc lessFunc
NshmDec lessFunc
NthrInc lessFunc
NthrDec lessFunc
OpenfilesInc lessFunc
OpenfilesDec lessFunc
OriginInc lessFunc
OriginDec lessFunc
OwnerInc lessFunc
OwnerDec lessFunc
PcpuInc lessFunc
PcpuDec lessFunc
Plugin_nameInc lessFunc
Plugin_nameDec lessFunc
Plugin_repositoryInc lessFunc
Plugin_repositoryDec lessFunc
PriorityInc lessFunc
PriorityDec lessFunc
PseudoterminalsInc lessFunc
PseudoterminalsDec lessFunc
QuotaInc lessFunc
QuotaDec lessFunc
ReadbpsInc lessFunc
ReadbpsDec lessFunc
ReadiopsInc lessFunc
ReadiopsDec lessFunc
ReleaseInc lessFunc
ReleaseDec lessFunc
ReservationInc lessFunc
ReservationDec lessFunc
ResolverInc lessFunc
ResolverDec lessFunc
RlimitsInc lessFunc
RlimitsDec lessFunc
RtsoldInc lessFunc
RtsoldDec lessFunc
SecurelevelInc lessFunc
SecurelevelDec lessFunc
ShmsizeInc lessFunc
ShmsizeDec lessFunc
StacksizeInc lessFunc
StacksizeDec lessFunc
Stop_timeoutInc lessFunc
Stop_timeoutDec lessFunc
SwapuseInc lessFunc
SwapuseDec lessFunc
Sync_stateInc lessFunc
Sync_stateDec lessFunc
Sync_targetInc lessFunc
Sync_targetDec lessFunc
Sync_tgt_zpoolInc lessFunc
Sync_tgt_zpoolDec lessFunc
SysvmsgInc lessFunc
SysvmsgDec lessFunc
SysvsemInc lessFunc
SysvsemDec lessFunc
SysvshmInc lessFunc
SysvshmDec lessFunc
TemplateInc lessFunc
TemplateDec lessFunc
JailtypeInc lessFunc
JailtypeDec lessFunc
UsedInc lessFunc
UsedDec lessFunc
VmemoryuseInc lessFunc
VmemoryuseDec lessFunc
VnetInc lessFunc
VnetDec lessFunc
Vnet0_macInc lessFunc
Vnet0_macDec lessFunc
Vnet1_macInc lessFunc
Vnet1_macDec lessFunc
Vnet2_macInc lessFunc
Vnet2_macDec lessFunc
Vnet3_macInc lessFunc
Vnet3_macDec lessFunc
Vnet_default_interfaceInc lessFunc
Vnet_default_interfaceDec lessFunc
Vnet_interfacesInc lessFunc
Vnet_interfacesDec lessFunc
WallclockInc lessFunc
WallclockDec lessFunc
WritebpsInc lessFunc
WritebpsDec lessFunc
WriteiopsInc lessFunc
WriteiopsDec lessFunc
}

View File

@ -1,10 +1,16 @@
package cmd
import (
"sort"
"os/exec"
"strings"
)
/*****************************************************************************
*
* Command execution
*
*****************************************************************************/
func executeCommand(cmdline string) (string, error) {
var cmd []string
var out []byte
@ -51,3 +57,939 @@ func executeCommandInJail(jail *Jail, cmdline string) (string, error) {
return string(out), err
}
/*****************************************************************************
*
* 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)
}