diff --git a/cmd/list.go b/cmd/list.go index 831968f..988882b 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -14,6 +14,7 @@ import ( /******************************************************************************** * List all properties a jail have, with their internal name + * Only print properties name. To get name & values, use GetJailProperties() *******************************************************************************/ func ListJailsProps(args []string) { var conf Jail @@ -98,7 +99,7 @@ func ListJails(args []string, display bool) { / We support 3 sort criteria max /**************************************************************/ if len(gSortFields) > 0 && gSortFields != "none" { - js := initSortStruct() + js := initJailSortStruct() // The way we manage criteria quantity is not very elegant... var fct1, fct2, fct3 *reflect.Value @@ -126,11 +127,11 @@ func ListJails(args []string, display bool) { switch len(strings.Split(gSortFields, ",")) { case 1: - OrderedBy(fct1.Interface().(lessFunc)).Sort(jails) + JailsOrderedBy(fct1.Interface().(jailLessFunc)).Sort(jails) case 2: - OrderedBy(fct1.Interface().(lessFunc), fct2.Interface().(lessFunc)).Sort(jails) + JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc)).Sort(jails) case 3: - OrderedBy(fct1.Interface().(lessFunc), fct2.Interface().(lessFunc), fct3.Interface().(lessFunc)).Sort(jails) + JailsOrderedBy(fct1.Interface().(jailLessFunc), fct2.Interface().(jailLessFunc), fct3.Interface().(jailLessFunc)).Sort(jails) } } diff --git a/cmd/root.go b/cmd/root.go index b5a58ea..ed13cff 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,6 +5,7 @@ import ( "fmt" "strconv" "strings" + "io/ioutil" "encoding/json" "github.com/spf13/cobra" @@ -27,9 +28,11 @@ var ( gNoLineSep bool gHostVersion float64 + + gTimeZone string - rootCmd = & cobra.Command{ + rootCmd = & cobra.Command { Use: "gocage", Short: "GoCage is a FreeBSD Jail management tool", Long: `GoCage is a jail management tool. It support VNET, host-only, NAT networks. Provides snapshots and cloning. @@ -40,7 +43,7 @@ It support iocage jails and can coexist with iocage.`, }, } - versionCmd = &cobra.Command{ + versionCmd = &cobra.Command { Use: "version", Short: "Print the version number of GoCage", Long: `Let this show you how much fail I had to get this *cough* perfect`, @@ -50,7 +53,7 @@ It support iocage jails and can coexist with iocage.`, }, } - listCmd = &cobra.Command{ + listCmd = &cobra.Command { Use: "list", Short: "Print jails", Long: `Display jails, their IP and OS. @@ -62,7 +65,7 @@ ex: gocage list srv-db srv-web`, }, } - listPropsCmd = &cobra.Command{ + listPropsCmd = &cobra.Command { Use: "properties", Short: "Print jails properties", Long: "Display jails properties. You can use properties to filter, get or set them.", @@ -72,54 +75,77 @@ ex: gocage list srv-db srv-web`, }, } - stopCmd = &cobra.Command{ + stopCmd = &cobra.Command { Use: "stop", Short: "stop jail", Long: "shutdown jail", Run: func(cmd *cobra.Command, args []string) { - // Get the inventory + // Load inventory ListJails(args, false) StopJail(args) cleanAfterRun() }, } - startCmd = &cobra.Command{ + startCmd = &cobra.Command { Use: "start", Short: "start jail", Run: func(cmd *cobra.Command, args []string) { - // Get the inventory + // Load inventory ListJails(args, false) StartJail(args) cleanAfterRun() }, } - setCmd = &cobra.Command{ + setCmd = &cobra.Command { Use: "set", Short: "Set a jail property", Long: `Set jail property value. Specify property=value, end command with jail name. Multiples properties can be specified, separated with space (Ex: gocage set allow_mlock=1 boot=1 myjail)`, Run: func(cmd *cobra.Command, args []string) { - // Get the inventory + // Load inventory ListJails(args, false) SetJailProperties(args) cleanAfterRun() }, } - getCmd = &cobra.Command{ + getCmd = &cobra.Command { Use: "get", - Short: "Get a jail property", - Long: `Get jail property value. Specify property, end command with jail name. + Short: "Get a jail property", + Long: `Get jail property value. Specify property, end command with jail name. Multiples properties can be specified, separated with space (Ex: gocage get allow_mlock boot myjail) For all properties specify "all" (Ex: gocage get all myjail)`, - Run: func(cmd *cobra.Command, args []string) { - // Get the inventory - ListJails(args, false) - GetJailProperties(args) - cleanAfterRun() - }, + Run: func(cmd *cobra.Command, args []string) { + // Load inventory + ListJails(args, false) + GetJailProperties(args) + cleanAfterRun() + }, + } + + snapshotCmd = &cobra.Command { + Use: "snapshot", + Short: "snapshot jail", + Long: "Commands to manage jail snapshots. If no arguments given, ", + Run: func(cmd *cobra.Command, args []string) { + + }, + } + + snapshotListCmd = &cobra.Command { + Use: "list", + Short: "list snapshots", + Long: `List snapshots of a jail by specifying its name. +List all snapshots if no jail name specified. +You can specify multiple jails.`, + Run: func(cmd *cobra.Command, args []string) { + // Load inventory + ListJails(args, false) + ListJailsSnapshots(args) + cleanAfterRun() + }, } ) @@ -131,6 +157,7 @@ func init() { // Global switches rootCmd.PersistentFlags().StringVarP(&gConfigFile, "config", "c", "/usr/local/etc/gocage.conf.yml", "GoCage configuration file") rootCmd.PersistentFlags().BoolVarP(&gUseSudo, "sudo", "u", false, "Use sudo to run commands") + rootCmd.PersistentFlags().StringVarP(&gTimeZone, "timezone", "t", "", "Specify timezone. Will get from /var/db/zoneinfo if not set.") // Command dependant switches listCmd.PersistentFlags().StringVarP(&gDisplayColumns, "outcol", "o", "JID,Name,Config.Release,Config.Ip4_addr,Running", "Show these columns in output") @@ -146,6 +173,8 @@ func init() { rootCmd.AddCommand(startCmd) rootCmd.AddCommand(getCmd) rootCmd.AddCommand(setCmd) + rootCmd.AddCommand(snapshotCmd) + snapshotCmd.AddCommand(snapshotListCmd) // Get FreeBSD version out, err := executeCommand("freebsd-version") @@ -180,6 +209,18 @@ func initConfig() { if rootCmd.Flags().Lookup("sudo") != nil && false == rootCmd.Flags().Lookup("sudo").Changed { gUseSudo = viper.GetBool("sudo") } + if rootCmd.Flags().Lookup("timezone") != nil && false == rootCmd.Flags().Lookup("timezone").Changed { + gTimeZone = viper.GetString("timezone") + } + // If neither on cmdline nor config file, get from /var/db/zoneinfo + if len(gTimeZone) == 0 { + tz, err := ioutil.ReadFile("/var/db/zoneinfo") + if err != nil { + fmt.Println("Error reading /var/db/zoneinfo: %s\n", err.Error()) + os.Exit(1) + } + gTimeZone = strings.Trim(string(tz), "\n") + } if listCmd.Flags().Lookup("outcol") != nil && false == listCmd.Flags().Lookup("outcol").Changed { gDisplayColumns = viper.GetString("outcol") } diff --git a/cmd/struct.go b/cmd/struct.go index 9535d6a..3209072 100644 --- a/cmd/struct.go +++ b/cmd/struct.go @@ -1,5 +1,8 @@ package cmd +import ( + "time" +) // To allow sorting, just duplicate fields in JailSort below type Jail struct { @@ -174,303 +177,323 @@ type Mount struct { Fs_Passno int } - -// This struct hold "sort by jail fields" functions -type lessFunc func(j1 *Jail, j2 *Jail) bool +type Snapshot struct { + // snapshot name is stored after '@' in dataset name + Name string + Dsname string + Mountpoint string + Used string + Referenced string + Creation time.Time +} // 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 + NameInc jailLessFunc + NameDec jailLessFunc + InternalNameInc jailLessFunc + InternalNameDec jailLessFunc + JIDInc jailLessFunc + JIDDec jailLessFunc + RootPathInc jailLessFunc + RootPathDec jailLessFunc + ConfigPathInc jailLessFunc + ConfigPathDec jailLessFunc + RunningInc jailLessFunc + RunningDec jailLessFunc + ZpoolInc jailLessFunc + ZpoolDec jailLessFunc 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 + Config_versionInc jailLessFunc + Config_versionDec jailLessFunc + Allow_chflagsInc jailLessFunc + Allow_chflagsDec jailLessFunc + Allow_mlockInc jailLessFunc + Allow_mlockDec jailLessFunc + Allow_mountInc jailLessFunc + Allow_mountDec jailLessFunc + Allow_mount_devfsInc jailLessFunc + Allow_mount_devfsDec jailLessFunc + Allow_mount_fusefsInc jailLessFunc + Allow_mount_fusefsDec jailLessFunc + Allow_mount_nullfsInc jailLessFunc + Allow_mount_nullfsDec jailLessFunc + Allow_mount_procfsInc jailLessFunc + Allow_mount_procfsDec jailLessFunc + Allow_mount_tmpfsInc jailLessFunc + Allow_mount_tmpfsDec jailLessFunc + Allow_mount_zfsInc jailLessFunc + Allow_mount_zfsDec jailLessFunc + Allow_quotasInc jailLessFunc + Allow_quotasDec jailLessFunc + Allow_raw_socketsInc jailLessFunc + Allow_raw_socketsDec jailLessFunc + Allow_set_hostnameInc jailLessFunc + Allow_set_hostnameDec jailLessFunc + Allow_socket_afInc jailLessFunc + Allow_socket_afDec jailLessFunc + Allow_sysvipcInc jailLessFunc + Allow_sysvipcDec jailLessFunc + Allow_tunInc jailLessFunc + Allow_tunDec jailLessFunc + Allow_vmmInc jailLessFunc + Allow_vmmDec jailLessFunc + Assign_localhostInc jailLessFunc + Assign_localhostDec jailLessFunc + AvailableInc jailLessFunc + AvailableDec jailLessFunc + BasejailInc jailLessFunc + BasejailDec jailLessFunc + BootInc jailLessFunc + BootDec jailLessFunc + BpfInc jailLessFunc + BpfDec jailLessFunc + Children_maxInc jailLessFunc + Children_maxDec jailLessFunc + Cloned_releaseInc jailLessFunc + Cloned_releaseDec jailLessFunc + CommentInc jailLessFunc + CommentDec jailLessFunc + CompressionInc jailLessFunc + CompressionDec jailLessFunc + CompressratioInc jailLessFunc + CompressratioDec jailLessFunc + CoredumpsizeInc jailLessFunc + CoredumpsizeDec jailLessFunc + CountInc jailLessFunc + CountDec jailLessFunc + CpusetInc jailLessFunc + CpusetDec jailLessFunc + CputimeInc jailLessFunc + CputimeDec jailLessFunc + DatasizeInc jailLessFunc + DatasizeDec jailLessFunc + DedupInc jailLessFunc + DedupDec jailLessFunc + DefaultrouterInc jailLessFunc + DefaultrouterDec jailLessFunc + Defaultrouter6Inc jailLessFunc + Defaultrouter6Dec jailLessFunc + DependsInc jailLessFunc + DependsDec jailLessFunc + Devfs_rulesetInc jailLessFunc + Devfs_rulesetDec jailLessFunc + DhcpInc jailLessFunc + DhcpDec jailLessFunc + Enforce_statfsInc jailLessFunc + Enforce_statfsDec jailLessFunc + Exec_cleanInc jailLessFunc + Exec_cleanDec jailLessFunc + Exec_createdInc jailLessFunc + Exec_createdDec jailLessFunc + Exec_fibInc jailLessFunc + Exec_fibDec jailLessFunc + Exec_jail_userInc jailLessFunc + Exec_jail_userDec jailLessFunc + Exec_poststartInc jailLessFunc + Exec_poststartDec jailLessFunc + Exec_poststopInc jailLessFunc + Exec_poststopDec jailLessFunc + Exec_prestartInc jailLessFunc + Exec_prestartDec jailLessFunc + Exec_prestopInc jailLessFunc + Exec_prestopDec jailLessFunc + Exec_startInc jailLessFunc + Exec_startDec jailLessFunc + Exec_stopInc jailLessFunc + Exec_stopDec jailLessFunc + Exec_system_jail_userInc jailLessFunc + Exec_system_jail_userDec jailLessFunc + Exec_system_userInc jailLessFunc + Exec_system_userDec jailLessFunc + Exec_timeoutInc jailLessFunc + Exec_timeoutDec jailLessFunc + Host_domainnameInc jailLessFunc + Host_domainnameDec jailLessFunc + Host_hostnameInc jailLessFunc + Host_hostnameDec jailLessFunc + Host_hostuuidInc jailLessFunc + Host_hostuuidDec jailLessFunc + Host_timeInc jailLessFunc + Host_timeDec jailLessFunc + HostidInc jailLessFunc + HostidDec jailLessFunc + Hostid_strict_checkInc jailLessFunc + Hostid_strict_checkDec jailLessFunc + InterfacesInc jailLessFunc + InterfacesDec jailLessFunc + Ip4Inc jailLessFunc + Ip4Dec jailLessFunc + Ip4_addrInc jailLessFunc + Ip4_addrDec jailLessFunc + Ip4_saddrselInc jailLessFunc + Ip4_saddrselDec jailLessFunc + Ip6Inc jailLessFunc + Ip6Dec jailLessFunc + Ip6_addrInc jailLessFunc + Ip6_addrDec jailLessFunc + Ip6_saddrselInc jailLessFunc + Ip6_saddrselDec jailLessFunc + Ip_hostnameInc jailLessFunc + Ip_hostnameDec jailLessFunc + Jail_zfsInc jailLessFunc + Jail_zfsDec jailLessFunc + Jail_zfs_datasetInc jailLessFunc + Jail_zfs_datasetDec jailLessFunc + Jail_zfs_mountpointInc jailLessFunc + Jail_zfs_mountpointDec jailLessFunc + Last_startedInc jailLessFunc + Last_startedDec jailLessFunc + Localhost_ipInc jailLessFunc + Localhost_ipDec jailLessFunc + Login_flagsInc jailLessFunc + Login_flagsDec jailLessFunc + Mac_prefixInc jailLessFunc + Mac_prefixDec jailLessFunc + MaxprocInc jailLessFunc + MaxprocDec jailLessFunc + MemorylockedInc jailLessFunc + MemorylockedDec jailLessFunc + MemoryuseInc jailLessFunc + MemoryuseDec jailLessFunc + Min_dyn_devfs_rulesetInc jailLessFunc + Min_dyn_devfs_rulesetDec jailLessFunc + Mount_devfsInc jailLessFunc + Mount_devfsDec jailLessFunc + Mount_fdescfsInc jailLessFunc + Mount_fdescfsDec jailLessFunc + Mount_linprocfsInc jailLessFunc + Mount_linprocfsDec jailLessFunc + Mount_procfsInc jailLessFunc + Mount_procfsDec jailLessFunc + MountpointInc jailLessFunc + MountpointDec jailLessFunc + MsgqqueuedInc jailLessFunc + MsgqqueuedDec jailLessFunc + MsgqsizeInc jailLessFunc + MsgqsizeDec jailLessFunc + NatInc jailLessFunc + NatDec jailLessFunc + Nat_backendInc jailLessFunc + Nat_backendDec jailLessFunc + Nat_forwardsInc jailLessFunc + Nat_forwardsDec jailLessFunc + Nat_interfaceInc jailLessFunc + Nat_interfaceDec jailLessFunc + Nat_prefixInc jailLessFunc + Nat_prefixDec jailLessFunc + NmsgqInc jailLessFunc + NmsgqDec jailLessFunc + NotesInc jailLessFunc + NotesDec jailLessFunc + NsemInc jailLessFunc + NsemDec jailLessFunc + NsemopInc jailLessFunc + NsemopDec jailLessFunc + NshmInc jailLessFunc + NshmDec jailLessFunc + NthrInc jailLessFunc + NthrDec jailLessFunc + OpenfilesInc jailLessFunc + OpenfilesDec jailLessFunc + OriginInc jailLessFunc + OriginDec jailLessFunc + OwnerInc jailLessFunc + OwnerDec jailLessFunc + PcpuInc jailLessFunc + PcpuDec jailLessFunc + Plugin_nameInc jailLessFunc + Plugin_nameDec jailLessFunc + Plugin_repositoryInc jailLessFunc + Plugin_repositoryDec jailLessFunc + PriorityInc jailLessFunc + PriorityDec jailLessFunc + PseudoterminalsInc jailLessFunc + PseudoterminalsDec jailLessFunc + QuotaInc jailLessFunc + QuotaDec jailLessFunc + ReadbpsInc jailLessFunc + ReadbpsDec jailLessFunc + ReadiopsInc jailLessFunc + ReadiopsDec jailLessFunc + ReleaseInc jailLessFunc + ReleaseDec jailLessFunc + ReservationInc jailLessFunc + ReservationDec jailLessFunc + ResolverInc jailLessFunc + ResolverDec jailLessFunc + RlimitsInc jailLessFunc + RlimitsDec jailLessFunc + RtsoldInc jailLessFunc + RtsoldDec jailLessFunc + SecurelevelInc jailLessFunc + SecurelevelDec jailLessFunc + ShmsizeInc jailLessFunc + ShmsizeDec jailLessFunc + StacksizeInc jailLessFunc + StacksizeDec jailLessFunc + Stop_timeoutInc jailLessFunc + Stop_timeoutDec jailLessFunc + SwapuseInc jailLessFunc + SwapuseDec jailLessFunc + Sync_stateInc jailLessFunc + Sync_stateDec jailLessFunc + Sync_targetInc jailLessFunc + Sync_targetDec jailLessFunc + Sync_tgt_zpoolInc jailLessFunc + Sync_tgt_zpoolDec jailLessFunc + SysvmsgInc jailLessFunc + SysvmsgDec jailLessFunc + SysvsemInc jailLessFunc + SysvsemDec jailLessFunc + SysvshmInc jailLessFunc + SysvshmDec jailLessFunc + TemplateInc jailLessFunc + TemplateDec jailLessFunc + JailtypeInc jailLessFunc + JailtypeDec jailLessFunc + UsedInc jailLessFunc + UsedDec jailLessFunc + VmemoryuseInc jailLessFunc + VmemoryuseDec jailLessFunc + VnetInc jailLessFunc + VnetDec jailLessFunc + Vnet0_macInc jailLessFunc + Vnet0_macDec jailLessFunc + Vnet1_macInc jailLessFunc + Vnet1_macDec jailLessFunc + Vnet2_macInc jailLessFunc + Vnet2_macDec jailLessFunc + Vnet3_macInc jailLessFunc + Vnet3_macDec jailLessFunc + Vnet_default_interfaceInc jailLessFunc + Vnet_default_interfaceDec jailLessFunc + Vnet_interfacesInc jailLessFunc + Vnet_interfacesDec jailLessFunc + WallclockInc jailLessFunc + WallclockDec jailLessFunc + WritebpsInc jailLessFunc + WritebpsDec jailLessFunc + WriteiopsInc jailLessFunc + WriteiopsDec jailLessFunc +} + +type SnapshotSort struct { + NameInc snapshotLessFunc + NameDec snapshotLessFunc + DsNameInc snapshotLessFunc + DsNameDec snapshotLessFunc + MountpointInc snapshotLessFunc + MountpointDec snapshotLessFunc + UsedInc snapshotLessFunc + UsedDec snapshotLessFunc + ReferencedInc snapshotLessFunc + ReferencedDec snapshotLessFunc + CreationInc snapshotLessFunc + CreationDec snapshotLessFunc } diff --git a/cmd/utils.go b/cmd/utils.go index bd42762..8ee8560 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -503,9 +503,10 @@ func displayStructFields(jails []Jail, valsToDisplay []string) { * *****************************************************************************/ -// already defined in cmd/struct.go -//type lessFunc func(j1 *Jail, j2 *Jail) bool -func initSortStruct() JailSort { +// This struct hold "sort by jail fields" functions +type jailLessFunc func(j1 *Jail, j2 *Jail) bool + +func initJailSortStruct() JailSort { jcs := JailConfigSort{ Allow_chflagsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_chflags < j2.Config.Allow_chflags @@ -1374,34 +1375,34 @@ func initSortStruct() JailSort { return js } -// multiSorter implements the Sort interface, sorting the jails within. -type multiSorter struct { +// jailSorter implements the Sort interface, sorting the jails within. +type jailSorter struct { jails []Jail - less []lessFunc + less []jailLessFunc } -// 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) +// Sort sorts the argument slice according to the less functions passed to JailsOrderedBy. +func (js *jailSorter) Sort(jails []Jail) { + js.jails = jails + sort.Sort(js) } -// OrderedBy returns a Sorter that sorts using the less functions, in order. +// JailsOrderedBy 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{ +func JailsOrderedBy(less ...jailLessFunc) *jailSorter { + return &jailSorter{ less: less, } } // Len is part of sort.Interface. -func (ms *multiSorter) Len() int { - return len(ms.jails) +func (js *jailSorter) Len() int { + return len(js.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] +func (js *jailSorter) Swap(i, j int) { + js.jails[i], js.jails[j] = js.jails[j], js.jails[i] } // Less is part of sort.Interface. It is implemented by looping along the @@ -1410,12 +1411,12 @@ func (ms *multiSorter) Swap(i, j int) { // 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] +func (js *jailSorter) Less(i, j int) bool { + p, q := &js.jails[i], &js.jails[j] // Try all but the last comparison. var k int - for k = 0; k < len(ms.less)-1; k++ { - less := ms.less[k] + for k = 0; k < len(js.less)-1; k++ { + less := js.less[k] switch { case less(p, q): // p < q, so we have a decision. @@ -1428,9 +1429,119 @@ func (ms *multiSorter) Less(i, j int) bool { } // All comparisons to here said "equal", so just return whatever // the final comparison reports. - return ms.less[k](p, q) + return js.less[k](p, q) } + +/***************************************************************************** + * + * Sorting snapshots + * + *****************************************************************************/ + +// This struct hold "sort by jail fields" functions +type snapshotLessFunc func(s1 *Snapshot, s2 *Snapshot) bool + +func initSnapshotSortStruct() SnapshotSort { + ss := SnapshotSort{ + NameInc: func(s1, s2 *Snapshot) bool { + return s1.Name < s2.Name + }, + NameDec: func(s1, s2 *Snapshot) bool { + return s1.Name > s2.Name + }, + DsNameInc: func(s1, s2 *Snapshot) bool { + return s1.Dsname < s2.Dsname + }, + DsNameDec: func(s1, s2 *Snapshot) bool { + return s1.Dsname > s2.Dsname + }, + MountpointInc: func(s1, s2 *Snapshot) bool { + return s1.Mountpoint < s2.Mountpoint + }, + MountpointDec: func(s1, s2 *Snapshot) bool { + return s1.Mountpoint > s2.Mountpoint + }, + UsedInc: func(s1, s2 *Snapshot) bool { + return s1.Used < s2.Used + }, + UsedDec: func(s1, s2 *Snapshot) bool { + return s1.Used > s2.Used + }, + ReferencedInc: func(s1, s2 *Snapshot) bool { + return s1.Referenced < s2.Referenced + }, + ReferencedDec: func(s1, s2 *Snapshot) bool { + return s1.Referenced > s2.Referenced + }, + CreationInc: func(s1, s2 *Snapshot) bool { + return s1.Creation.Unix() < s2.Creation.Unix() + }, + CreationDec: func(s1, s2 *Snapshot) bool { + return s1.Creation.Unix() > s2.Creation.Unix() + }, + } + return ss +} + +// snapshotSorter implements the Sort interface, sorting the jails within. +type snapshotSorter struct { + snapshots []Snapshot + less []snapshotLessFunc +} + +// Sort sorts the argument slice according to the less functions passed to OrderedBy. +func (ss *snapshotSorter) Sort(snapshots []Snapshot) { + ss.snapshots = snapshots + sort.Sort(ss) +} + +// OrderedBy returns a Sorter that sorts using the less functions, in order. +// Call its Sort method to sort the data. +func SnapshotsOrderedBy(less ...snapshotLessFunc) *snapshotSorter { + return &snapshotSorter{ + less: less, + } +} + +// Len is part of sort.Interface. +func (ss *snapshotSorter) Len() int { + return len(ss.snapshots) +} + +// Swap is part of sort.Interface. +func (ss *snapshotSorter) Swap(i, j int) { + ss.snapshots[i], ss.snapshots[j] = ss.snapshots[j], ss.snapshots[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 (ss *snapshotSorter) Less(i, j int) bool { + p, q := &ss.snapshots[i], &ss.snapshots[j] + // Try all but the last comparison. + var k int + for k = 0; k < len(ss.less)-1; k++ { + less := ss.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 ss.less[k](p, q) +} + + /***************************************************************************** * * Generic utilities