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

Reply via email to