On Fri, Jun 6, 2014 at 10:51 AM, 'Jose A. Lopes' via ganeti-devel < [email protected]> wrote:
> Add list of enabled hypervisors, cluster wide parameter for user > shutdown, and a list of nodes and their respective vm capable > attributes to Ssconf. This will be needed by the KVM daemon to > determine whether it should start on a particular node. > > Signed-off-by: Jose A. Lopes <[email protected]> > --- > lib/config.py | 5 +++++ > lib/ssconf.py | 22 ++++++++++++++++++++++ > src/Ganeti/Constants.hs | 6 ++++++ > src/Ganeti/Ssconf.hs | 40 +++++++++++++++++++++++++++++++++++++++- > src/Ganeti/Types.hs | 1 + > 5 files changed, 73 insertions(+), 1 deletion(-) > > diff --git a/lib/config.py b/lib/config.py > index dd38a22..6ea2083 100644 > --- a/lib/config.py > +++ b/lib/config.py > @@ -2614,6 +2614,8 @@ class ConfigWriter(object): > for ninfo in node_infos] > node_snd_ips = ["%s %s" % (ninfo.name, ninfo.secondary_ip) > for ninfo in node_infos] > + node_vm_capable = ["%s=%s" % (ninfo.name, str(ninfo.vm_capable)) > + for ninfo in node_infos] > > instance_data = fn(instance_names) > off_data = fn(node.name for node in node_infos if node.offline) > @@ -2624,6 +2626,7 @@ class ConfigWriter(object): > node_data = fn(node_names) > node_pri_ips_data = fn(node_pri_ips) > node_snd_ips_data = fn(node_snd_ips) > + node_vm_capable_data = fn(node_vm_capable) > > cluster = self._config_data.cluster > cluster_tags = fn(cluster.GetTags()) > @@ -2660,6 +2663,7 @@ class ConfigWriter(object): > constants.SS_NODE_LIST: node_data, > constants.SS_NODE_PRIMARY_IPS: node_pri_ips_data, > constants.SS_NODE_SECONDARY_IPS: node_snd_ips_data, > + constants.SS_NODE_VM_CAPABLE: node_vm_capable_data, > constants.SS_OFFLINE_NODES: off_data, > constants.SS_ONLINE_NODES: on_data, > constants.SS_PRIMARY_IP_FAMILY: str(cluster.primary_ip_family), > @@ -2670,6 +2674,7 @@ class ConfigWriter(object): > constants.SS_UID_POOL: uid_pool, > constants.SS_NODEGROUPS: nodegroups_data, > constants.SS_NETWORKS: networks_data, > + constants.SS_ENABLED_USER_SHUTDOWN: > str(cluster.enabled_user_shutdown), > } > ssconf_values = self._ExtendByAllHvparamsStrings(ssconf_values, > all_hvparams) > diff --git a/lib/ssconf.py b/lib/ssconf.py > index a2a660f..55f9df1 100644 > --- a/lib/ssconf.py > +++ b/lib/ssconf.py > @@ -57,6 +57,7 @@ _VALID_KEYS = compat.UniqueFrozenset([ > constants.SS_NODE_LIST, > constants.SS_NODE_PRIMARY_IPS, > constants.SS_NODE_SECONDARY_IPS, > + constants.SS_NODE_VM_CAPABLE, > constants.SS_OFFLINE_NODES, > constants.SS_ONLINE_NODES, > constants.SS_PRIMARY_IP_FAMILY, > @@ -73,6 +74,7 @@ _VALID_KEYS = compat.UniqueFrozenset([ > constants.SS_HVPARAMS_XEN_KVM, > constants.SS_HVPARAMS_XEN_CHROOT, > constants.SS_HVPARAMS_XEN_LXC, > + constants.SS_ENABLED_USER_SHUTDOWN, > ]) > > #: Maximum size for ssconf files > @@ -321,6 +323,20 @@ class SimpleStore(object): > nl = data.splitlines(False) > return nl > > + def GetNodesVmCapable(self): > + """Return the cluster nodes' vm capable value. > + > + @rtype: dict of string to bool > + @return: mapping of node names to vm capable values > + > + """ > + data = self._ReadFile(constants.SS_NODE_VM_CAPABLE) > + vm_capable = {} > + for line in data.splitlines(False): > + (node_uuid, node_vm_capable) = line.split("=") > + vm_capable[node_uuid] = node_vm_capable > This will get you a str to str map that might be interpreted as all True later. > + return vm_capable > + > def GetNodegroupList(self): > """Return the list of nodegroups. > > @@ -415,6 +431,12 @@ class SimpleStore(object): > raise errors.ConfigurationError("Error while trying to parse > primary IP" > " family: %s" % err) > > + def GetEnabledUserShutdown(self): > + """Return whether user shutdown is enabled. > + > + """ > + return self._ReadFile(constants.SS_ENABLED_USER_SHUTDOWN) == "True" > Why not a cast to bool here? > + > > def WriteSsconfFiles(values, dry_run=False): > """Update all ssconf files. > diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs > index c13d6d6..c87510b 100644 > --- a/src/Ganeti/Constants.hs > +++ b/src/Ganeti/Constants.hs > @@ -3570,6 +3570,9 @@ ssNodePrimaryIps = "node_primary_ips" > ssNodeSecondaryIps :: String > ssNodeSecondaryIps = "node_secondary_ips" > > +ssNodeVmCapable :: String > +ssNodeVmCapable = "node_vm_capable" > + > ssOfflineNodes :: String > ssOfflineNodes = "offline_nodes" > > @@ -3637,6 +3640,9 @@ validSsHvparamsKeys = > ssFilePerms :: Int > ssFilePerms = 0o444 > > +ssEnabledUserShutdown :: String > +ssEnabledUserShutdown = "enabled_user_shutdown" > + > -- | Cluster wide default parameters > defaultEnabledHypervisor :: String > defaultEnabledHypervisor = htXenPvm > diff --git a/src/Ganeti/Ssconf.hs b/src/Ganeti/Ssconf.hs > index 3f7a64b..3704c36 100644 > --- a/src/Ganeti/Ssconf.hs > +++ b/src/Ganeti/Ssconf.hs > @@ -30,8 +30,11 @@ module Ganeti.Ssconf > , sSKeyToRaw > , sSKeyFromRaw > , getPrimaryIPFamily > + , getNodesVmCapable > , getMasterCandidatesIps > , getMasterNode > + , getHypervisorList > + , getEnabledUserShutdown > , keyToFilename > , sSFilePrefix > ) where > @@ -48,6 +51,8 @@ import Ganeti.BasicTypes > import qualified Ganeti.Constants as C > import qualified Ganeti.Path as Path > import Ganeti.THH > +import Ganeti.Types (Hypervisor) > +import qualified Ganeti.Types as Types > import Ganeti.Utils > > -- | Maximum ssconf file size we support. > @@ -73,6 +78,7 @@ $(declareSADT "SSKey" > , ("SSNodeList", 'C.ssNodeList) > , ("SSNodePrimaryIps", 'C.ssNodePrimaryIps) > , ("SSNodeSecondaryIps", 'C.ssNodeSecondaryIps) > + , ("SSNodeVmCapable", 'C.ssNodeVmCapable) > , ("SSOfflineNodes", 'C.ssOfflineNodes) > , ("SSOnlineNodes", 'C.ssOnlineNodes) > , ("SSPrimaryIpFamily", 'C.ssPrimaryIpFamily) > @@ -82,6 +88,7 @@ $(declareSADT "SSKey" > , ("SSMaintainNodeHealth", 'C.ssMaintainNodeHealth) > , ("SSUidPool", 'C.ssUidPool) > , ("SSNodegroups", 'C.ssNodegroups) > + , ("SSEnabledUserShutdown", 'C.ssEnabledUserShutdown) > ]) > > -- | Convert a ssconf key into a (full) file path. > @@ -118,6 +125,14 @@ readSSConfFile optpath def key = do > keyToFilename (fromMaybe dpath optpath) $ key > return (liftM (take maxFileSize) result) > > +-- | Parses a key-value pair of the form "key=value" from 'str', fails > +-- with 'desc' otherwise. > +parseKeyValue :: Monad m => String -> String -> m (String, String) > +parseKeyValue desc str = > + case sepSplit '=' str of > + [key, value] -> return (key, value) > + _ -> fail $ "Failed to parse key-value pair for " ++ desc > + > -- | Parses a string containing an IP family > parseIPFamily :: Int -> Result Socket.Family > parseIPFamily fam | fam == AutoConf.pyAfInet4 = Ok Socket.AF_INET > @@ -133,6 +148,17 @@ getPrimaryIPFamily optpath = do > return (liftM rStripSpace result >>= > tryRead "Parsing af_family" >>= parseIPFamily) > > +-- | Read the nodes vm capable value. > +getNodesVmCapable :: Maybe FilePath -> IO (Result [(String, Bool)]) > +getNodesVmCapable optPath = do > + result <- readSSConfFile optPath Nothing SSNodeVmCapable > + return $ > + liftM lines result >>= > + mapM (parseKeyValue "Parsing node_vm_capable") >>= > + mapM (\(x, y) -> > + do val <- tryRead "Parsing value of node_vm_capable" y > + return (x, val)) > + > -- | Read the list of IP addresses of the master candidates of the > cluster. > getMasterCandidatesIps :: Maybe FilePath -> IO (Result [String]) > getMasterCandidatesIps optPath = do > @@ -143,4 +169,16 @@ getMasterCandidatesIps optPath = do > getMasterNode :: Maybe FilePath -> IO (Result String) > getMasterNode optPath = do > result <- readSSConfFile optPath Nothing SSMasterNode > - return (liftM rStripSpace result) > + return $ liftM rStripSpace result > + > +-- | Read the list of enabled hypervisors > +getHypervisorList :: Maybe FilePath -> IO (Result [Hypervisor]) > +getHypervisorList optPath = do > + result <- readSSConfFile optPath Nothing SSHypervisorList > + return $ mapM Types.hypervisorFromRaw =<< liftM lines result > + > +-- | Read whether user shutdown is enabled > +getEnabledUserShutdown :: Maybe FilePath -> IO (Result Bool) > +getEnabledUserShutdown optPath = do > + result <- readSSConfFile optPath Nothing SSEnabledUserShutdown > + return $ tryRead "Parsing enabled_user_shutdown" =<< liftM rStripSpace > result > diff --git a/src/Ganeti/Types.hs b/src/Ganeti/Types.hs > index 38d71b3..e61b983 100644 > --- a/src/Ganeti/Types.hs > +++ b/src/Ganeti/Types.hs > @@ -75,6 +75,7 @@ module Ganeti.Types > , CVErrorCode(..) > , cVErrorCodeToRaw > , Hypervisor(..) > + , hypervisorFromRaw > , hypervisorToRaw > , OobCommand(..) > , oobCommandToRaw > -- > 2.0.0.526.g5318336 > >
