memory-ratio ipolicy is a part of future memory over-commitment support. This ipolicy will regulate the memory pressure (maximum allowed over-commitment ratio) soon.
Signed-off-by: Oleg Ponomarev <[email protected]> --- doc/rapi.rst | 5 ++++- lib/cli.py | 3 +++ lib/cli_opts.py | 9 +++++++++ lib/client/gnt_cluster.py | 3 +++ lib/client/gnt_group.py | 5 ++++- src/Ganeti/ConstantUtils.hs | 6 ++++++ src/Ganeti/Constants.hs | 7 ++++++- src/Ganeti/HTools/Backend/Text.hs | 12 +++++++++--- src/Ganeti/HTools/Types.hs | 4 ++++ src/Ganeti/Objects.hs | 14 ++++++++++++-- test/hs/Test/Ganeti/HTools/Types.hs | 2 ++ test/hs/Test/Ganeti/TestCommon.hs | 5 +++++ test/hs/Test/Ganeti/TestHTools.hs | 3 +++ 13 files changed, 70 insertions(+), 8 deletions(-) diff --git a/doc/rapi.rst b/doc/rapi.rst index dc7784a..d6cab78 100644 --- a/doc/rapi.rst +++ b/doc/rapi.rst @@ -232,7 +232,8 @@ The instance policy specification is a dict with the following fields: constants.ISPECS_STD, constants.IPOLICY_DTS, constants.IPOLICY_VCPU_RATIO, - constants.IPOLICY_SPINDLE_RATIO]) + constants.IPOLICY_SPINDLE_RATIO, + constants.IPOLICY_MEMORY_RATIO]) .. pyassert:: @@ -280,6 +281,8 @@ The instance policy specification is a dict with the following fields: Maximum ratio of virtual to physical CPUs (`float`) :pyeval:`constants.IPOLICY_SPINDLE_RATIO` Maximum ratio of instances to their node's ``spindle_count`` (`float`) +:pyeval:`constants.IPOLICY_MEMORY_RATIO` + Maximum ratio of memory overcommitment (`float`) Usage examples -------------- diff --git a/lib/cli.py b/lib/cli.py index 06daabe..366d6c8 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -2837,6 +2837,7 @@ def CreateIPolicyFromOpts(ispecs_mem_size=None, ipolicy_disk_templates=None, ipolicy_vcpu_ratio=None, ipolicy_spindle_ratio=None, + ipolicy_memory_ratio=None, group_ipolicy=False, allowed_values=None, fill_all=False): @@ -2874,6 +2875,8 @@ def CreateIPolicyFromOpts(ispecs_mem_size=None, ipolicy_out[constants.IPOLICY_VCPU_RATIO] = ipolicy_vcpu_ratio if ipolicy_spindle_ratio is not None: ipolicy_out[constants.IPOLICY_SPINDLE_RATIO] = ipolicy_spindle_ratio + if ipolicy_memory_ratio is not None: + ipolicy_out[constants.IPOLICY_MEMORY_RATIO] = ipolicy_memory_ratio assert not (frozenset(ipolicy_out.keys()) - constants.IPOLICY_ALL_KEYS) diff --git a/lib/cli_opts.py b/lib/cli_opts.py index 5d28f5e..bf7f9f7 100644 --- a/lib/cli_opts.py +++ b/lib/cli_opts.py @@ -136,6 +136,7 @@ __all__ = [ "IPOLICY_STD_SPECS_OPT", "IPOLICY_STD_SPECS_STR", "IPOLICY_VCPU_RATIO", + "IPOLICY_MEMORY_RATIO", "LONG_SLEEP_OPT", "MAC_PREFIX_OPT", "MAINT_BALANCE_OPT", @@ -810,6 +811,13 @@ IPOLICY_SPINDLE_RATIO = cli_option("--ipolicy-spindle-ratio", help=("The maximum allowed instances to" " spindle ratio")) +IPOLICY_MEMORY_RATIO = cli_option("--ipolicy-memory-ratio", + dest="ipolicy_memory_ratio", + type="maybefloat", default=None, + help=("The maximum allowed used memory to" + " physicall memory ratio (in terms of" + " memory overcommitment)")) + HYPERVISOR_OPT = cli_option("-H", "--hypervisor-parameters", dest="hypervisor", help="Hypervisor and hypervisor options, in the" " format hypervisor:option=value,option=value,...", @@ -1676,6 +1684,7 @@ INSTANCE_POLICY_OPTS = [ IPOLICY_DISK_TEMPLATES, IPOLICY_VCPU_RATIO, IPOLICY_SPINDLE_RATIO, + IPOLICY_MEMORY_RATIO, ] # instance policy split specs options diff --git a/lib/client/gnt_cluster.py b/lib/client/gnt_cluster.py index 9eca4b3..c57c916 100644 --- a/lib/client/gnt_cluster.py +++ b/lib/client/gnt_cluster.py @@ -241,6 +241,7 @@ def InitCluster(opts, args): ipolicy_disk_templates=opts.ipolicy_disk_templates, ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, + ipolicy_memory_ratio=opts.ipolicy_memory_ratio, fill_all=True) if opts.candidate_pool_size is None: @@ -1352,6 +1353,7 @@ def SetClusterParams(opts, args): opts.ipolicy_disk_templates is not None or opts.ipolicy_vcpu_ratio is not None or opts.ipolicy_spindle_ratio is not None or + opts.ipolicy_memory_ratio is not None or opts.modify_etc_hosts is not None or opts.file_storage_dir is not None or opts.install_image is not None or @@ -1409,6 +1411,7 @@ def SetClusterParams(opts, args): ipolicy_disk_templates=opts.ipolicy_disk_templates, ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, + ipolicy_memory_ratio=opts.ipolicy_memory_ratio, ) mnh = opts.maintain_node_health diff --git a/lib/client/gnt_group.py b/lib/client/gnt_group.py index 5f44001..8b3c9e5 100644 --- a/lib/client/gnt_group.py +++ b/lib/client/gnt_group.py @@ -63,6 +63,7 @@ def AddGroup(opts, args): minmax_ispecs=opts.ipolicy_bounds_specs, ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, + ipolicy_memory_ratio=opts.ipolicy_memory_ratio, ipolicy_disk_templates=opts.ipolicy_disk_templates, group_ipolicy=True) @@ -170,7 +171,8 @@ def SetGroupParams(opts, args): allmods = [opts.ndparams, opts.alloc_policy, opts.diskparams, opts.hv_state, opts.disk_state, opts.ipolicy_bounds_specs, opts.ipolicy_vcpu_ratio, opts.ipolicy_spindle_ratio, - opts.diskparams, opts.ipolicy_disk_templates] + opts.ipolicy_memory_ratio, opts.diskparams, + opts.ipolicy_disk_templates] if allmods.count(None) == len(allmods): ToStderr("Please give at least one of the parameters.") return 1 @@ -190,6 +192,7 @@ def SetGroupParams(opts, args): ipolicy_disk_templates=opts.ipolicy_disk_templates, ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, + ipolicy_memory_ratio=opts.ipolicy_memory_ratio, group_ipolicy=True, allowed_values=[constants.VALUE_DEFAULT]) diff --git a/src/Ganeti/ConstantUtils.hs b/src/Ganeti/ConstantUtils.hs index 3f43ea1..ddbbd75 100644 --- a/src/Ganeti/ConstantUtils.hs +++ b/src/Ganeti/ConstantUtils.hs @@ -206,8 +206,14 @@ ipolicyVcpuRatio = "vcpu-ratio" ipolicySpindleRatio :: String ipolicySpindleRatio = "spindle-ratio" +ipolicyMemoryRatio :: String +ipolicyMemoryRatio = "memory-ratio" + ipolicyDefaultsVcpuRatio :: Double ipolicyDefaultsVcpuRatio = 4.0 ipolicyDefaultsSpindleRatio :: Double ipolicyDefaultsSpindleRatio = 32.0 + +ipolicyDefaultsMemoryRatio :: Double +ipolicyDefaultsMemoryRatio = 1.0 diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs index c13ecd1..038b2f3 100644 --- a/src/Ganeti/Constants.hs +++ b/src/Ganeti/Constants.hs @@ -2186,13 +2186,17 @@ ipolicyVcpuRatio = ConstantUtils.ipolicyVcpuRatio ipolicySpindleRatio :: String ipolicySpindleRatio = ConstantUtils.ipolicySpindleRatio +ipolicyMemoryRatio :: String +ipolicyMemoryRatio = ConstantUtils.ipolicyMemoryRatio + ispecsMinmaxKeys :: FrozenSet String ispecsMinmaxKeys = ConstantUtils.mkSet [ispecsMax, ispecsMin] ipolicyParameters :: FrozenSet String ipolicyParameters = ConstantUtils.mkSet [ConstantUtils.ipolicyVcpuRatio, - ConstantUtils.ipolicySpindleRatio] + ConstantUtils.ipolicySpindleRatio, + ConstantUtils.ipolicyMemoryRatio] ipolicyAllKeys :: FrozenSet String ipolicyAllKeys = @@ -4271,6 +4275,7 @@ ipolicyDefaults = , (ipolicyDts, PyValueEx (ConstantUtils.toList diskTemplates)) , (ipolicyVcpuRatio, PyValueEx ConstantUtils.ipolicyDefaultsVcpuRatio) , (ipolicySpindleRatio, PyValueEx ConstantUtils.ipolicyDefaultsSpindleRatio) + , (ipolicyMemoryRatio, PyValueEx ConstantUtils.ipolicyDefaultsMemoryRatio) ] masterPoolSizeDefault :: Int diff --git a/src/Ganeti/HTools/Backend/Text.hs b/src/Ganeti/HTools/Backend/Text.hs index 5aaa784..4929f74 100644 --- a/src/Ganeti/HTools/Backend/Text.hs +++ b/src/Ganeti/HTools/Backend/Text.hs @@ -168,13 +168,14 @@ serializeMultipleMinMaxISpecs minmaxes = -- | Generate policy data from a given policy object. serializeIPolicy :: String -> IPolicy -> String serializeIPolicy owner ipol = - let IPolicy minmax stdspec dts vcpu_ratio spindle_ratio = ipol + let IPolicy minmax stdspec dts vcpu_ratio spindle_ratio memory_ratio = ipol strings = [ owner , serializeISpec stdspec , serializeMultipleMinMaxISpecs minmax , serializeDiskTemplates dts , show vcpu_ratio , show spindle_ratio + , show memory_ratio ] in intercalate "|" strings @@ -370,16 +371,21 @@ loadMultipleMinMaxISpecs owner ispecs = do -- | Loads an ipolicy from a field list. loadIPolicy :: [String] -> Result (String, IPolicy) loadIPolicy (owner:stdspec:minmaxspecs:dtemplates: - vcpu_ratio:spindle_ratio:_) = do + vcpu_ratio:spindle_ratio:memory_ratio:_) = do xstdspec <- loadISpec (owner ++ "/stdspec") (commaSplit stdspec) xminmaxspecs <- loadMultipleMinMaxISpecs owner $ sepSplit iSpecsSeparator minmaxspecs xdts <- mapM diskTemplateFromRaw $ commaSplit dtemplates xvcpu_ratio <- tryRead (owner ++ "/vcpu_ratio") vcpu_ratio xspindle_ratio <- tryRead (owner ++ "/spindle_ratio") spindle_ratio + xmemory_ratio <- tryRead (owner ++ "/memory_ratio") memory_ratio return (owner, IPolicy xminmaxspecs xstdspec - xdts xvcpu_ratio xspindle_ratio) + xdts xvcpu_ratio xspindle_ratio xmemory_ratio) +loadIPolicy (owner:stdspec:minmaxspecs:dtemplates: + vcpu_ratio:spindle_ratio:_) = + loadIPolicy (owner:stdspec:minmaxspecs:dtemplates: + vcpu_ratio:spindle_ratio:["1.0"]) loadIPolicy s = fail $ "Invalid ipolicy data: '" ++ show s ++ "'" loadOnePolicy :: (IPolicy, Group.List) -> String diff --git a/src/Ganeti/HTools/Types.hs b/src/Ganeti/HTools/Types.hs index c8881a9..d683e1b 100644 --- a/src/Ganeti/HTools/Types.hs +++ b/src/Ganeti/HTools/Types.hs @@ -254,6 +254,9 @@ $(THH.buildObject "IPolicy" "iPolicy" THH.simpleField ConstantUtils.ipolicyVcpuRatio [t| Double |] , THH.renameField "SpindleRatio" $ THH.simpleField ConstantUtils.ipolicySpindleRatio [t| Double |] + , THH.renameField "MemoryRatio" . + THH.defaultField [| ConstantUtils.ipolicyDefaultsMemoryRatio |] $ + THH.simpleField ConstantUtils.ipolicyMemoryRatio [t| Double |] ]) -- | Converts an ISpec type to a RSpec one. @@ -275,6 +278,7 @@ defIPolicy = , iPolicyDiskTemplates = [minBound..maxBound] , iPolicyVcpuRatio = ConstantUtils.ipolicyDefaultsVcpuRatio , iPolicySpindleRatio = ConstantUtils.ipolicyDefaultsSpindleRatio + , iPolicyMemoryRatio = ConstantUtils.ipolicyDefaultsMemoryRatio } -- | The dynamic resource specs of a machine (i.e. load or load diff --git a/src/Ganeti/Objects.hs b/src/Ganeti/Objects.hs index 667d5b4..98f0ac9 100644 --- a/src/Ganeti/Objects.hs +++ b/src/Ganeti/Objects.hs @@ -321,6 +321,8 @@ $(buildObject "PartialIPolicy" "ipolicy" simpleField "std" [t| PartialISpecParams |] , optionalField . renameField "SpindleRatioP" $ simpleField "spindle-ratio" [t| Double |] + , optionalField . renameField "MemoryRatioP" $ + simpleField "memory-ratio" [t| Double |] , optionalField . renameField "VcpuRatioP" $ simpleField "vcpu-ratio" [t| Double |] , optionalField . renameField "DiskTemplatesP" $ @@ -334,6 +336,8 @@ $(buildObject "FilledIPolicy" "ipolicy" simpleField ConstantUtils.ispecsMinmax [t| [MinMaxISpecs] |] , renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |] , simpleField "spindle-ratio" [t| Double |] + , defaultField [| ConstantUtils.ipolicyDefaultsMemoryRatio |] $ + simpleField "memory-ratio" [t| Double |] , simpleField "vcpu-ratio" [t| Double |] , simpleField "disk-templates" [t| [DiskTemplate] |] ]) @@ -344,17 +348,20 @@ instance PartialParams FilledIPolicy PartialIPolicy where (FilledIPolicy { ipolicyMinMaxISpecs = fminmax , ipolicyStdSpec = fstd , ipolicySpindleRatio = fspindleRatio + , ipolicyMemoryRatio = fmemoryRatio , ipolicyVcpuRatio = fvcpuRatio , ipolicyDiskTemplates = fdiskTemplates}) (PartialIPolicy { ipolicyMinMaxISpecsP = pminmax , ipolicyStdSpecP = pstd , ipolicySpindleRatioP = pspindleRatio + , ipolicyMemoryRatioP = pmemoryRatio , ipolicyVcpuRatioP = pvcpuRatio , ipolicyDiskTemplatesP = pdiskTemplates}) = FilledIPolicy { ipolicyMinMaxISpecs = fromMaybe fminmax pminmax , ipolicyStdSpec = maybe fstd (fillParams fstd) pstd , ipolicySpindleRatio = fromMaybe fspindleRatio pspindleRatio + , ipolicyMemoryRatio = fromMaybe fmemoryRatio pmemoryRatio , ipolicyVcpuRatio = fromMaybe fvcpuRatio pvcpuRatio , ipolicyDiskTemplates = fromMaybe fdiskTemplates pdiskTemplates @@ -362,22 +369,25 @@ instance PartialParams FilledIPolicy PartialIPolicy where toPartial (FilledIPolicy { ipolicyMinMaxISpecs = fminmax , ipolicyStdSpec = fstd , ipolicySpindleRatio = fspindleRatio + , ipolicyMemoryRatio = fmemoryRatio , ipolicyVcpuRatio = fvcpuRatio , ipolicyDiskTemplates = fdiskTemplates}) = PartialIPolicy { ipolicyMinMaxISpecsP = Just fminmax , ipolicyStdSpecP = Just $ toPartial fstd , ipolicySpindleRatioP = Just fspindleRatio + , ipolicyMemoryRatioP = Just fmemoryRatio , ipolicyVcpuRatioP = Just fvcpuRatio , ipolicyDiskTemplatesP = Just fdiskTemplates } toFilled (PartialIPolicy { ipolicyMinMaxISpecsP = pminmax , ipolicyStdSpecP = pstd , ipolicySpindleRatioP = pspindleRatio + , ipolicyMemoryRatioP = pmemoryRatio , ipolicyVcpuRatioP = pvcpuRatio , ipolicyDiskTemplatesP = pdiskTemplates}) = - FilledIPolicy <$> pminmax <*> (toFilled =<< pstd) <*> pspindleRatio - <*> pvcpuRatio <*> pdiskTemplates + FilledIPolicy <$> pminmax <*> (toFilled =<< pstd) <*> pspindleRatio + <*> pmemoryRatio <*> pvcpuRatio <*> pdiskTemplates -- * Node definitions diff --git a/test/hs/Test/Ganeti/HTools/Types.hs b/test/hs/Test/Ganeti/HTools/Types.hs index f643f3b..4136308 100644 --- a/test/hs/Test/Ganeti/HTools/Types.hs +++ b/test/hs/Test/Ganeti/HTools/Types.hs @@ -148,11 +148,13 @@ instance Arbitrary Types.IPolicy where dts <- genUniquesList num_tmpl arbitrary vcpu_ratio <- choose (1.0, maxVcpuRatio) spindle_ratio <- choose (1.0, maxSpindleRatio) + memory_ratio <- choose (1.0, maxMemoryRatio) return Types.IPolicy { Types.iPolicyMinMaxISpecs = iminmax , Types.iPolicyStdSpec = istd , Types.iPolicyDiskTemplates = dts , Types.iPolicyVcpuRatio = vcpu_ratio , Types.iPolicySpindleRatio = spindle_ratio + , Types.iPolicyMemoryRatio = memory_ratio } -- * Test cases diff --git a/test/hs/Test/Ganeti/TestCommon.hs b/test/hs/Test/Ganeti/TestCommon.hs index a3f8740..43595df 100644 --- a/test/hs/Test/Ganeti/TestCommon.hs +++ b/test/hs/Test/Ganeti/TestCommon.hs @@ -41,6 +41,7 @@ module Test.Ganeti.TestCommon , maxCpu , maxSpindles , maxVcpuRatio + , maxMemoryRatio , maxSpindleRatio , maxNodes , maxOpCodes @@ -156,6 +157,10 @@ maxVcpuRatio = 1024.0 maxSpindleRatio :: Double maxSpindleRatio = 1024.0 +-- | Max memory ratio (random value). +maxMemoryRatio :: Double +maxMemoryRatio = 1024.0 + -- | Max nodes, used just to limit arbitrary instances for smaller -- opcode definitions (e.g. list of nodes in OpTestDelay). maxNodes :: Int diff --git a/test/hs/Test/Ganeti/TestHTools.hs b/test/hs/Test/Ganeti/TestHTools.hs index e2ec6a5..92fef8d 100644 --- a/test/hs/Test/Ganeti/TestHTools.hs +++ b/test/hs/Test/Ganeti/TestHTools.hs @@ -94,6 +94,9 @@ nullIPolicy = Types.IPolicy , Types.iPolicyVcpuRatio = maxVcpuRatio -- somewhat random value, high -- enough to not impact us , Types.iPolicySpindleRatio = maxSpindleRatio + , Types.iPolicyMemoryRatio = 1 -- because there are several test which + -- become senseless in case of memory + -- over-commitment } -- | Default group definition. -- 2.6.0.rc2.230.g3dd15c0
