From 6eb00df34c25e156197b9b03f428cc5ef028b649 Mon Sep 17 00:00:00 2001 From: kesper Date: Wed, 26 Apr 2017 06:04:21 +0000 Subject: [PATCH] Adding node_pool as a optional argument This commit add node_pool options which allow user to create different pools of hardware depends of their type. Change-Id: If35158e35c405afcc1158e7f4015dea6048ce59f --- molteniron/molteniron.py | 20 ++++++++++ molteniron/moltenirond.py | 41 ++++++++++++++++----- molteniron/tests/testAddBMNode.py | 25 +++++++++++++ molteniron/tests/testAllocateBM.py | 49 +++++++++++++++++++++++-- molteniron/tests/testCull.py | 12 ++++-- molteniron/tests/testDeallocateBM.py | 12 ++++-- molteniron/tests/testDeallocateOwner.py | 12 ++++-- utils/test_hook_mi_ipmiblob.py | 6 +++ 8 files changed, 152 insertions(+), 25 deletions(-) diff --git a/molteniron/molteniron.py b/molteniron/molteniron.py index 5c50da0..31394f7 100644 --- a/molteniron/molteniron.py +++ b/molteniron/molteniron.py @@ -162,6 +162,11 @@ class MoltenIron(object): type=int, help="Amount of disk (in GiB)" " that the node has") + sp.add_argument("node_pool", + type=str, + default="default", + nargs='?', + help="Node pool name") sp.set_defaults(func=self.add_baremetal) return @@ -190,6 +195,11 @@ class MoltenIron(object): sp.add_argument("args", nargs=argparse.REMAINDER, help="Architecture of the node") + sp.add_argument("node_pool", + type=str, + default="default", + nargs='?', + help="Node pool name") sp.set_defaults(func=self.add_keyvalue_pairs) return @@ -217,6 +227,11 @@ class MoltenIron(object): " IPs to be used in deployment") sp.add_argument("blob", help="JSON encoded string") + sp.add_argument("node_pool", + type=str, + default="default", + nargs='?', + help="Node pool name") sp.set_defaults(func=self.add_json_blob) return @@ -236,6 +251,11 @@ class MoltenIron(object): sp.add_argument("number_of_nodes", type=int, help="How many nodes to reserve") + sp.add_argument("node_pool", + type=str, + default="default", + nargs='?', + help="Node pool name") sp.set_defaults(func=self.allocate) return diff --git a/molteniron/moltenirond.py b/molteniron/moltenirond.py index de15648..1180898 100755 --- a/molteniron/moltenirond.py +++ b/molteniron/moltenirond.py @@ -158,7 +158,8 @@ def MakeMoltenIronHandlerWithConf(conf): response = database.addBMNode(request, node) elif method == 'allocate': response = database.allocateBM(request['owner_name'], - request['number_of_nodes']) + request['number_of_nodes'], + request['node_pool']) elif method == 'release': response = database.deallocateOwner(request['owner_name']) elif method == 'get_field': @@ -213,6 +214,7 @@ class Nodes(declarative_base()): status = Column('status', String(20)) provisioned = Column('provisioned', String(50)) timestamp = Column('timestamp', TIMESTAMP) + node_pool = Column('node_pool', String(20)) __table__ = Table(__tablename__, metadata, @@ -222,7 +224,8 @@ class Nodes(declarative_base()): blob, status, provisioned, - timestamp) + timestamp, + node_pool) def map(self): """Returns a map of the database row contents""" @@ -237,7 +240,8 @@ ipmi_ip='%s', blob='%s', status='%s', provisioned='%s', -timestamp='%s'/>""" +timestamp='%s', +node_pool='%s'/>""" fmt = fmt.replace('\n', ' ') return fmt % (self.name, @@ -245,7 +249,8 @@ timestamp='%s'/>""" self.blob, self.status, self.provisioned, - self.timestamp) + self.timestamp, + self.node_pool) class IPs(declarative_base()): @@ -348,6 +353,7 @@ class DataBase(object): ("provisioned", 40, str, False), # We add timeString ("time", 14, float, False), + ("node_pool", 19, str, False), ] } self.baremetal_status = { @@ -369,6 +375,7 @@ class DataBase(object): ("provisioned", 40, str, False), # We add timeString ("time", 14, float, False), + ("node_pool", 19, str, False), ] } @@ -489,16 +496,21 @@ class DataBase(object): ts = timestamp.timetuple() return ts - def allocateBM(self, owner_name, how_many): + def allocateBM(self, owner_name, how_many, node_pool="Default"): """Checkout machines from the database and return necessary info """ try: with self.session_scope() as session, \ self.connection_scope() as conn: + count_with_pool = 0 # Get a list of IDs for nodes that are free count = session.query(Nodes).filter_by(status="ready").count() - + # Get a list of IDs for nodes that are free and with specific + # node_pool + if node_pool != "Default": + count_with_pool = session.query(Nodes).filter_by( + status="ready", node_pool=node_pool).count() # If we don't have enough nodes return an error if count < how_many: fmt = "Not enough available nodes found." @@ -510,7 +522,12 @@ class DataBase(object): for _ in range(how_many): first_ready = session.query(Nodes) - first_ready = first_ready.filter_by(status="ready") + if count_with_pool > 0: + first_ready = first_ready.filter_by( + status="ready", node_pool=node_pool) + count_with_pool = count_with_pool - 1 + else: + first_ready = first_ready.filter_by(status="ready") first_ready = first_ready.first() node_id = first_ready.id @@ -693,6 +710,10 @@ class DataBase(object): if DEBUG: print("timestamp = %s" % (timestamp, )) stmt = stmt.values(timestamp=timestamp) + if 'node_pool' in request: + stmt = stmt.values(node_pool=request['node_pool']) + else: + stmt = stmt.values(node_pool="Default") if DEBUG: print(stmt.compile().params) @@ -1107,7 +1128,8 @@ class DataBase(object): blob, node.status, node.provisioned, - timeString) + timeString, + node.node_pool) def baremetal_status_elements(self, node, timeString): @@ -1125,7 +1147,8 @@ class DataBase(object): blob["disk_gb"], node.status, node.provisioned, - timeString) + timeString, + node.node_pool) def status_csv(self, get_status_elements, **status_map): """Return a comma separated list of values""" diff --git a/molteniron/tests/testAddBMNode.py b/molteniron/tests/testAddBMNode.py index ac87244..1fca2f6 100755 --- a/molteniron/tests/testAddBMNode.py +++ b/molteniron/tests/testAddBMNode.py @@ -122,6 +122,24 @@ if __name__ == "__main__": "ram_mb": 51000, "disk_gb": 500 } + request5 = { + "name": "pkvmci854", + "ipmi_ip": "10.228.119.134", + "status": "used", + "provisioned": "6b8823df-4e14-4811-98b9-32e27397540d", + "timestamp": "1460491533", + "allocation_pool": "10.228.112.16,10.228.112.17", + "node_pool": "test" + } + node5 = { + "ipmi_user": "user", + "ipmi_password": "33f448a4fc176492", + "port_hwaddr": "85:e0:73:e9:fc:ca", + "cpu_arch": "ppc64el", + "cpus": 20, + "ram_mb": 51000, + "disk_gb": 500 + } # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) @@ -146,6 +164,13 @@ if __name__ == "__main__": print(ret) assert ret['status'] == 400 assert ret['message'] == "Node already exists" + ret = database.addBMNode(request5, node5) + print(ret) + assert ret == {'status': 200} + ret = database.addBMNode(request5, node5) + print(ret) + assert ret['status'] == 400 + assert ret['message'] == "Node already exists" database.close() del database diff --git a/molteniron/tests/testAllocateBM.py b/molteniron/tests/testAllocateBM.py index dcc31cd..862c1b2 100755 --- a/molteniron/tests/testAllocateBM.py +++ b/molteniron/tests/testAllocateBM.py @@ -102,7 +102,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "", - "allocation_pool": "10.228.112.10,10.228.112.11" + "allocation_pool": "10.228.112.10,10.228.112.11", + "node_pool": "Default" } node1 = { "ipmi_user": "user", @@ -119,7 +120,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "", - "allocation_pool": "10.228.112.8,10.228.112.9" + "allocation_pool": "10.228.112.8,10.228.112.9", + "node_pool": "Default" } node2 = { "ipmi_user": "user", @@ -136,7 +138,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", "timestamp": "1460489832", - "allocation_pool": "10.228.112.12,10.228.112.13" + "allocation_pool": "10.228.112.12,10.228.112.13", + "node_pool": "Default" } node3 = { "ipmi_user": "user", @@ -153,7 +156,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", "timestamp": "1460491566", - "allocation_pool": "10.228.112.14,10.228.112.15" + "allocation_pool": "10.228.112.14,10.228.112.15", + "node_pool": "Default" } node4 = { "ipmi_user": "user", @@ -164,6 +168,24 @@ if __name__ == "__main__": "ram_mb": 51000, "disk_gb": 500 } + request5 = { + "name": "vmci854", + "ipmi_ip": "10.228.118.133", + "status": "ready", + "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", + "timestamp": "1460491566", + "allocation_pool": "10.228.112.14,10.228.112.15", + "node_pool": "test" + } + node5 = { + "ipmi_user": "user", + "ipmi_password": "33f448a4fc176492", + "port_hwaddr": "85:e0:73:e9:fc:ca", + "cpu_arch": "ppc64el", + "cpus": 20, + "ram_mb": 51000, + "disk_gb": 500 + } # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) @@ -247,3 +269,22 @@ if __name__ == "__main__": database.close() del database + + # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----- + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + database.delete_db() + database.close() + del database + + database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY) + ret = database.addBMNode(request5, node5) + print(ret) + assert ret == {'status': 200} + ret = database.allocateBM("hamzy", 1, "test") + print(ret) + assert ret['status'] == 200 + assert len(ret["nodes"]) == 1 + compare_provisioned_nodes(ret["nodes"]["node_1"], request5, node5) + + database.close() + del database diff --git a/molteniron/tests/testCull.py b/molteniron/tests/testCull.py index 7be5b66..0226539 100755 --- a/molteniron/tests/testCull.py +++ b/molteniron/tests/testCull.py @@ -100,7 +100,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "", - "allocation_pool": "10.228.112.10,10.228.112.11" + "allocation_pool": "10.228.112.10,10.228.112.11", + "node_pool": "Default" } node1 = { "ipmi_user": "user", @@ -117,7 +118,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "-1", - "allocation_pool": "10.228.112.8,10.228.112.9" + "allocation_pool": "10.228.112.8,10.228.112.9", + "node_pool": "Default" } node2 = { "ipmi_user": "user", @@ -134,7 +136,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", "timestamp": str(time.time() - 1000.0), - "allocation_pool": "10.228.112.12,10.228.112.13" + "allocation_pool": "10.228.112.12,10.228.112.13", + "node_pool": "Default" } node3 = { "ipmi_user": "user", @@ -151,7 +154,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", "timestamp": str(time.time() - 2000.0), - "allocation_pool": "10.228.112.14,10.228.112.15" + "allocation_pool": "10.228.112.14,10.228.112.15", + "node_pool": "Default" } node4 = { "ipmi_user": "user", diff --git a/molteniron/tests/testDeallocateBM.py b/molteniron/tests/testDeallocateBM.py index 0e7ea36..d523791 100755 --- a/molteniron/tests/testDeallocateBM.py +++ b/molteniron/tests/testDeallocateBM.py @@ -102,7 +102,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "", - "allocation_pool": "10.228.112.10,10.228.112.11" + "allocation_pool": "10.228.112.10,10.228.112.11", + "node_pool": "Default" } node1 = { "ipmi_user": "user", @@ -119,7 +120,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "", - "allocation_pool": "10.228.112.8,10.228.112.9" + "allocation_pool": "10.228.112.8,10.228.112.9", + "node_pool": "Default" } node2 = { "ipmi_user": "user", @@ -136,7 +138,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", "timestamp": "1460489832", - "allocation_pool": "10.228.112.12,10.228.112.13" + "allocation_pool": "10.228.112.12,10.228.112.13", + "node_pool": "Default" } node3 = { "ipmi_user": "user", @@ -153,7 +156,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", "timestamp": "1460491566", - "allocation_pool": "10.228.112.14,10.228.112.15" + "allocation_pool": "10.228.112.14,10.228.112.15", + "node_pool": "Default" } node4 = { "ipmi_user": "user", diff --git a/molteniron/tests/testDeallocateOwner.py b/molteniron/tests/testDeallocateOwner.py index a91976a..c469602 100755 --- a/molteniron/tests/testDeallocateOwner.py +++ b/molteniron/tests/testDeallocateOwner.py @@ -102,7 +102,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "", - "allocation_pool": "10.228.112.10,10.228.112.11" + "allocation_pool": "10.228.112.10,10.228.112.11", + "node_pool": "Default" } node1 = { "ipmi_user": "user", @@ -119,7 +120,8 @@ if __name__ == "__main__": "status": "ready", "provisioned": "", "timestamp": "", - "allocation_pool": "10.228.112.8,10.228.112.9" + "allocation_pool": "10.228.112.8,10.228.112.9", + "node_pool": "Default" } node2 = { "ipmi_user": "user", @@ -136,7 +138,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f", "timestamp": "1460489832", - "allocation_pool": "10.228.112.12,10.228.112.13" + "allocation_pool": "10.228.112.12,10.228.112.13", + "node_pool": "Default" } node3 = { "ipmi_user": "user", @@ -153,7 +156,8 @@ if __name__ == "__main__": "status": "used", "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d", "timestamp": "1460491566", - "allocation_pool": "10.228.112.14,10.228.112.15" + "allocation_pool": "10.228.112.14,10.228.112.15", + "node_pool": "Default" } node4 = { "ipmi_user": "user", diff --git a/utils/test_hook_mi_ipmiblob.py b/utils/test_hook_mi_ipmiblob.py index 88589fb..0976b31 100755 --- a/utils/test_hook_mi_ipmiblob.py +++ b/utils/test_hook_mi_ipmiblob.py @@ -64,6 +64,11 @@ if __name__ == "__main__": parser.add_argument("number_of_nodes", type=int, help="How many nodes to reserve") + parser.add_argument("node_pool", + type=str, + default="default", + nargs='?', + help="Name of node_pool") args = parser.parse_args() @@ -91,6 +96,7 @@ if __name__ == "__main__": args_map = {"output": "json", "owner_name": args.owner_name, "number_of_nodes": args.number_of_nodes, + "node_pool": args.node_pool, "func": getattr(mi, "allocate"), "conf_dir": "testenv/etc/molteniron/"}