Commit 908c2f67 authored by Thomas Thrainer's avatar Thomas Thrainer

Parse NIC data from allocation request in hail

Add a NIC type and extend the Instance type by a list of NIC's. Parse
the NIC's in allocation requests and store them for now. Later patches
will make use of this field in order to ensure that the requested
instance is only placed in node groups wich are connected to those
networks.
Signed-off-by: default avatarThomas Thrainer <thomasth@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent a0be8f1a
......@@ -549,6 +549,7 @@ HS_LIB_SRCS = \
src/Ganeti/HTools/Group.hs \
src/Ganeti/HTools/Instance.hs \
src/Ganeti/HTools/Loader.hs \
src/Ganeti/HTools/Nic.hs \
src/Ganeti/HTools/Node.hs \
src/Ganeti/HTools/PeerMap.hs \
src/Ganeti/HTools/Program/Hail.hs \
......
......@@ -44,6 +44,7 @@ import qualified Ganeti.HTools.Container as Container
import qualified Ganeti.HTools.Group as Group
import qualified Ganeti.HTools.Node as Node
import qualified Ganeti.HTools.Instance as Instance
import qualified Ganeti.HTools.Nic as Nic
import qualified Ganeti.Constants as C
import Ganeti.HTools.CLI
import Ganeti.HTools.Loader
......@@ -56,6 +57,22 @@ import Ganeti.Utils
-- | Type alias for the result of an IAllocator call.
type IAllocResult = (String, JSValue, Node.List, Instance.List)
-- | Parse a NIC within an instance (in a creation request)
parseNic :: String -> JSRecord -> Result Nic.Nic
parseNic n a = do
mac <- maybeFromObj a "mac"
ip <- maybeFromObj a "ip"
mode <- maybeFromObj a "mode" >>= \m -> case m of
Just "bridged" -> Ok $ Just Nic.Bridged
Just "routed" -> Ok $ Just Nic.Routed
Just "openvswitch" -> Ok $ Just Nic.OpenVSwitch
Nothing -> Ok Nothing
_ -> Bad $ "invalid NIC mode in instance " ++ n
link <- maybeFromObj a "link"
bridge <- maybeFromObj a "bridge"
network <- maybeFromObj a "network"
return (Nic.create mac ip mode link bridge network)
-- | Parse the basic specifications of an instance.
--
-- Instances in the cluster instance list and the instance in an
......@@ -75,7 +92,11 @@ parseBaseInstance n a = do
tags <- extract "tags"
dt <- extract "disk_template"
su <- extract "spindle_use"
return (n, Instance.create n mem disk disks vcpus Running tags True 0 0 dt su)
nics <- extract "nics" >>= toArray >>= asObjectList >>=
mapM (parseNic n . fromJSObject)
return
(n,
Instance.create n mem disk disks vcpus Running tags True 0 0 dt su nics)
-- | Parses an instance as found in the cluster instance list.
parseInstance :: NameAssoc -- ^ The node name-to-index association list
......
......@@ -173,7 +173,7 @@ parseInstance ktn [ name, disk, mem, vcpus
xdt <- convert "disk_template" disk_template
xsu <- convert "be/spindle_use" su
let inst = Instance.create xname xmem xdisk [xdisk] xvcpus
xrunning xtags xauto_balance xpnode snode xdt xsu
xrunning xtags xauto_balance xpnode snode xdt xsu []
return (xname, inst)
parseInstance _ v = fail ("Invalid instance query result: " ++ show v)
......
......@@ -140,7 +140,7 @@ parseInstance ktn a = do
dt <- extract "disk_template" a
su <- extract "spindle_use" beparams
let inst = Instance.create name mem disk disks vcpus running tags
auto_balance pnode snode dt su
auto_balance pnode snode dt su []
return (name, inst)
-- | Construct a node from a JSON object.
......@@ -231,7 +231,7 @@ parseData (group_body, node_body, inst_body, info_body) = do
let (node_names, node_idx) = assignIndices node_data
inst_data <- inst_body >>= getInstances node_names
let (_, inst_idx) = assignIndices inst_data
(tags, ipolicy, master) <-
(tags, ipolicy, master) <-
info_body >>=
(fromJResult "Parsing cluster info" . decodeStrict) >>=
parseCluster
......
......@@ -247,7 +247,7 @@ loadInst ktn [ name, mem, dsk, vcpus, status, auto_bal, pnode, snode
" has same primary and secondary node - " ++ pnode
let vtags = commaSplit tags
newinst = Instance.create name vmem vdsk [vdsk] vvcpus vstatus vtags
auto_balance pidx sidx disk_template spindle_use
auto_balance pidx sidx disk_template spindle_use []
return (name, newinst)
loadInst ktn [ name, mem, dsk, vcpus, status, auto_bal, pnode, snode
......
......@@ -60,6 +60,7 @@ module Ganeti.HTools.Instance
import Ganeti.BasicTypes
import qualified Ganeti.HTools.Types as T
import qualified Ganeti.HTools.Container as Container
import Ganeti.HTools.Nic (Nic)
import Ganeti.Utils
......@@ -85,6 +86,7 @@ data Instance = Instance
, allTags :: [String] -- ^ List of all instance tags
, exclTags :: [String] -- ^ List of instance exclusion tags
, arPolicy :: T.AutoRepairPolicy -- ^ Instance's auto-repair policy
, nics :: [Nic] -- ^ NICs of the instance
} deriving (Show, Eq)
instance T.Element Instance where
......@@ -165,9 +167,9 @@ type List = Container.Container Instance
-- later (via 'setIdx' for example).
create :: String -> Int -> Int -> [Int] -> Int -> T.InstanceStatus
-> [String] -> Bool -> T.Ndx -> T.Ndx -> T.DiskTemplate -> Int
-> Instance
-> [Nic] -> Instance
create name_init mem_init dsk_init disks_init vcpus_init run_init tags_init
auto_balance_init pn sn dt su =
auto_balance_init pn sn dt su nics_init =
Instance { name = name_init
, alias = name_init
, mem = mem_init
......@@ -186,6 +188,7 @@ create name_init mem_init dsk_init disks_init vcpus_init run_init tags_init
, allTags = tags_init
, exclTags = []
, arPolicy = T.ArNotEnabled
, nics = nics_init
}
-- | Changes the index.
......
{-| Module describing an NIC.
The NIC data type only holds data about a NIC, but does not provide any
logic.
-}
{-
Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
-}
module Ganeti.HTools.Nic
( Nic(..)
, Mode(..)
, List
, create
) where
import qualified Ganeti.HTools.Container as Container
import qualified Ganeti.HTools.Types as T
-- * Type declarations
data Mode = Bridged | Routed | OpenVSwitch deriving (Show, Eq)
-- | The NIC type.
--
-- It holds the data for a NIC as it is provided via the IAllocator protocol
-- for an instance creation request. All data in those request is optional,
-- that's why all fields are Maybe's.
--
-- TODO: Another name might be more appropriate for this type, as for example
-- RequestedNic. But this type is used as a field in the Instance type, which
-- is not named RequestedInstance, so such a name would be weird. PartialNic
-- already exists in Objects, but doesn't fit the bill here, as it contains
-- a required field (mac). Objects and the types therein are subject to being
-- reworked, so until then this type is left as is.
data Nic = Nic
{ mac :: Maybe String -- ^ MAC address of the NIC
, ip :: Maybe String -- ^ IP address of the NIC
, mode :: Maybe Mode -- ^ the mode the NIC operates in
, link :: Maybe String -- ^ the link of the NIC
, bridge :: Maybe String -- ^ the bridge this NIC is connected to if
-- the mode is Bridged
, network :: Maybe T.NetworkID -- ^ network UUID if this NIC is connected
-- to a network
} deriving (Show, Eq)
-- | A simple name for an instance map.
type List = Container.Container Nic
-- * Initialization
-- | Create a NIC.
--
create :: Maybe String
-> Maybe String
-> Maybe Mode
-> Maybe String
-> Maybe String
-> Maybe T.NetworkID
-> Nic
create mac_init ip_init mode_init link_init bridge_init network_init =
Nic { mac = mac_init
, ip = ip_init
, mode = mode_init
, link = link_init
, bridge = bridge_init
, network = network_init
}
......@@ -394,9 +394,9 @@ runAllocation cdata stop_allocation actual_result spec dt mode opts = do
-- of the disk space to individual disks), sensible defaults are guessed (e.g.,
-- having a single disk).
instFromSpec :: RSpec -> DiskTemplate -> Int -> Instance.Instance
instFromSpec spx =
instFromSpec spx dt su =
Instance.create "new" (rspecMem spx) (rspecDsk spx) [rspecDsk spx]
(rspecCpu spx) Running [] True (-1) (-1)
(rspecCpu spx) Running [] True (-1) (-1) dt su []
combineTiered :: Maybe Int -> Cluster.AllocNodes -> Cluster.AllocResult ->
Instance.Instance -> Result Cluster.AllocResult
......
......@@ -85,7 +85,8 @@
"spindle_use": 2,
"tags": [],
"type": "allocate",
"vcpus": 1
"vcpus": 1,
"nics": []
},
"version": 2
}
......@@ -85,7 +85,8 @@
"spindle_use": 2,
"tags": [],
"type": "allocate",
"vcpus": 1
"vcpus": 1,
"nics": []
},
"version": 2
}
......@@ -62,7 +62,7 @@ genInstanceSmallerThan lim_mem lim_dsk lim_cpu = do
sn <- arbitrary
vcpus <- choose (0, lim_cpu)
dt <- arbitrary
return $ Instance.create name mem dsk [dsk] vcpus run_st [] True pn sn dt 1
return $ Instance.create name mem dsk [dsk] vcpus run_st [] True pn sn dt 1 []
-- | Generates an instance smaller than a node.
genInstanceSmallerThanNode :: Node.Node -> Gen Instance.Instance
......
......@@ -100,7 +100,7 @@ defGroupAssoc = Map.singleton (Group.uuid defGroup) (Group.idx defGroup)
createInstance :: Int -> Int -> Int -> Instance.Instance
createInstance mem dsk vcpus =
Instance.create "inst-unnamed" mem dsk [dsk] vcpus Types.Running [] True (-1)
(-1) Types.DTDrbd8 1
(-1) Types.DTDrbd8 1 []
-- | Create a small cluster by repeating a node spec.
makeSmallCluster :: Node.Node -> Int -> Node.List
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment