diff --git a/nodepool/molteniron/README.md b/nodepool/molteniron/README.md
index d648846..06dded2 100644
--- a/nodepool/molteniron/README.md
+++ b/nodepool/molteniron/README.md
@@ -1,130 +1,7 @@
-MoltenIron overview
-===================
+NOTE: MoltenIron is now an Open Stack project!
-MoltenIron maintains a pool of bare metal nodes.
+git clone git://git.openstack.org/openstack/molteniron.git
+https://git.openstack.org/cgit/openstack/molteniron/
+https://github.com/openstack/molteniron/
-Starting
---------
-
-Before starting the server for the first time, the createDB.py
-script must be run.
-
-To start the server:
-```bash
-moltenirond-helper start
-```
-
-To stop the server:
-```bash
-moltenirond-helper stop
-```
-
-MoltenIron client
------------------
-
-Use the molteniron client (molteniron) to communicate with the server. For
-usage information type:
-```bash
-molteniron -h
-```
-
-For usage of a specific command use:
-```bash
-molteniron [command] -h
-```
-
-MoltenIron commands
--------------------
-
-command | description
-------- | -----------
-add | Add a node
-allocate | Allocate a node
-release | Release a node
-get_field | Get a specific field in a node
-set_field | Set a specific field with a value in a node
-status | Return the status of every node
-delete_db | Delete every database entry
-
-Configuration of MoltenIron
----------------------------
-
-Configuration of MoltenIron is specified in the file conf.yaml.
-
-"B)" means that this configuration option is required for both the client and
-the server. "C)" means that it is required only for the client. "S)" means
-it is only required for the server.
-
-usage | key | description
------ | --- | -----------
-B) | mi_port | the port that the server uses to respond to commands.
-C) | serverIP | The IP address of the server. This is only used by
- | | clients.
-S) | maxTime | The maximum amount of time, in seconds, that a node
- | | is allowed to be allocated to a particular BM node.
-S) | logdir | The path to the directory where the logs should be
- | | stored.
-S) | maxLogDays | The amount of time, in days, to keep old logs.
-S) | sqlUser | The username to use for the MI server. This user
- | | will automatically be generated when createDB.py is run.
-S) | sqlPass | The password of sqlUser
-
-Running testcases
------------------
-
-The suite of testcases is checked by tox. But, before you can run tox, you
-need to change the local yaml configuration file to point to the log
-directory.
-
-```bash
-(LOG=$(pwd)/testenv/log; sed -i -r -e 's,^(logdir: )(.*)$,\1'${LOG}',' conf.yaml; rm -rf testenv/; tox -e testenv)
-```
-
-Running inside a Continuous Integration environment
----------------------------------------------------
-
-During the creation of a job, add the following snippet of bash code:
-
-```bash
-# Setup MoltenIron and all necessary prerequisites.
-# And then call the MI script to allocate a node.
-(
- REPO_DIR=/opt/stack/new/third-party-ci-tools
- MI_CONF_DIR=/usr/local/etc/molteniron/
- MI_IP=10.1.2.3 # @TODO - Replace with your IP addr here!
-
- # Grab molteniron and install it
- git clone https://git.openstack.org/openstack/third-party-ci-tools ${REPO_DIR} || exit 1
-
- cd ${REPO_DIR}/nodepool/molteniron
-
- # @BUG Install prerequisite before running pip to install the requisites
- hash mysql_config || sudo apt install -y libmysqlclient-dev
-
- # Install the requisites for this package
- sudo pip install --upgrade --force-reinstall --requirement requirements.txt
-
- # Run the python package installation program
- sudo python setup.py install
-
- if [ -n "${MI_IP}" ]
- then
- # Set the molteniron server IP in the conf file
- sudo sed -i "s/127.0.0.1/${MI_IP}/g" ${MI_CONF_DIR}/conf.yaml
- fi
-
- export dsvm_uuid
- # NOTE: dsvm_uuid used in the following script, hence the -E
- sudo -E ${REPO_DIR}/nodepool/molteniron/utils/test_hook_configure_mi.sh
-) || exit $?
-```
-
-and change the MI_IP environment variable to be your MoltenIron server!
-
-During the destruction of a job, add the following snippet of bash code:
-
-```bash
- DSVM_UUID="$(> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- mi = MoltenIron(conf, unknown_args)
-
- print(mi.get_response())
-
- try:
- rc = mi.get_response_map()['status']
- except KeyError:
- print("Error: Server returned: %s" % (mi.get_response_map(),))
- rc = 444
-
- if rc == 200:
- exit(0)
- else:
- exit(1)
diff --git a/nodepool/molteniron/molteniron/moltenirond-helper b/nodepool/molteniron/molteniron/moltenirond-helper
deleted file mode 100755
index 0cbc7e3..0000000
--- a/nodepool/molteniron/molteniron/moltenirond-helper
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-import sys
-import os
-import signal
-import yaml
-from daemonize import Daemonize
-from molteniron import moltenirond
-
-PID = "/var/run/moltenirond.pid"
-YAML_CONF = "/usr/local/etc/molteniron/conf.yaml"
-
-def get_moltenirond_pid():
- if not os.path.isfile(PID):
- return -1
-
- with open(PID) as fobj:
- lines = fobj.readlines()
- try:
- pid = int(lines[0])
-
- try:
- # Send harmless kill signal in order to test existance
- os.kill(pid, 0)
- except Exception:
- return -1
-
- return pid
- except Exception:
- return -1
-
-def moltenirond_main():
- with open(YAML_CONF, "r") as fobj:
- conf = yaml.load(fobj)
-
- moltenirond.listener(conf)
-
-if __name__ == "__main__":
-
- parser = argparse.ArgumentParser(description="Molteniron daemon helper")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
- parser.add_argument("-p",
- "--pid-dir",
- action="store",
- type=str,
- dest="pid_dir",
- help="The directory where PID information is stored")
- parser.add_argument("-v",
- "--verbose",
- action="store",
- type=bool,
- dest="verbose",
- help="Set a verbose information mode")
- parser.add_argument("command", type=str, nargs=1, help="the command")
-
- args = parser.parse_args ()
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- YAML_CONF = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
-
- if args.pid_dir:
- if not os.path.isdir (args.pid_dir):
- msg = "Error: %s is not a valid directory" % (args.pid_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- PID = os.path.realpath("%s/moltenirond.pid" % (args.pid_dir, ))
-
- if args.verbose:
- print "YAML_CONF = %s" % (YAML_CONF, )
- print "PID = %s" % (PID, )
-
- if len(args.command) != 1:
- msg = "Error: Expecting one command? Received: %s" % (args.command, )
- print >> sys.stderr, msg
- sys.exit (1)
-
- if args.command[0].upper().lower() == "start":
- pid = get_moltenirond_pid()
- if pid > 0:
- print >> sys.stderr, "Error: The daemon is already running"
- sys.exit(1)
- daemon = Daemonize(app="moltenirond",
- pid=PID,
- action=moltenirond_main)
- daemon.start()
- elif args.command[0].upper().lower() == "stop":
- pid = get_moltenirond_pid()
- if pid > 0:
- os.remove (PID)
- os.kill(pid, signal.SIGTERM)
- else:
- print >> sys.stderr, "Error: The daemon doesn't exist?"
- sys.exit(1)
- else:
- msg = "Error: Unknown command: %s" % (args.command[0], )
- print >> sys.stderr, msg
- sys.exit (1)
diff --git a/nodepool/molteniron/molteniron/moltenirond.py b/nodepool/molteniron/molteniron/moltenirond.py
deleted file mode 100755
index 395470b..0000000
--- a/nodepool/molteniron/molteniron/moltenirond.py
+++ /dev/null
@@ -1,1105 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
-import calendar
-from datetime import datetime
-import json
-import os
-import sys
-import time
-import traceback
-import yaml
-import argparse
-
-from contextlib import contextmanager
-
-from sqlalchemy import create_engine
-from sqlalchemy.orm import sessionmaker
-from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy import Column, Integer, String, ForeignKey
-from sqlalchemy.sql import insert, update, delete
-from sqlalchemy.sql import and_
-from sqlalchemy.types import TIMESTAMP
-from sqlalchemy.schema import MetaData, Table
-
-import sqlalchemy_utils
-from sqlalchemy.exc import OperationalError
-
-DEBUG = False
-
-metadata = MetaData()
-
-
-class JSON_encoder_with_DateTime(json.JSONEncoder):
- def default(self, o):
- if isinstance(o, datetime):
- return o.isoformat()
-
- return json.JSONEncoder.default(self, o)
-
-
-# We need to turn BaseHTTPRequestHandler into a "new-style" class for
-# Python 2.x
-# NOTE: URL is over two lines :(
-# http://stackoverflow.com/questions/1713038/super-fails-with-error-typeerror-
-# argument-1-must-be-type-not-classobj
-class OBaseHTTPRequestHandler(BaseHTTPRequestHandler, object):
- pass
-
-# We need to pass in conf into MoltenIronHandler, so make a class factory
-# to do that
-# NOTE: URL is over two lines :(
-# http://stackoverflow.com/questions/21631799/how-can-i-pass-parameters-to-a-
-# requesthandler
-def MakeMoltenIronHandlerWithConf(conf):
- class MoltenIronHandler(OBaseHTTPRequestHandler):
- def __init__(self, *args, **kwargs):
- # Note this *needs* to be done before call to super's class!
- self.conf = conf
- super(OBaseHTTPRequestHandler, self).__init__(*args, **kwargs)
-
- def do_POST(self):
- CL = 'Content-Length'
- self.data_string = self.rfile.read(int(self.headers[CL]))
- response = self.parse(self.data_string)
- self.send_reply(response)
-
- def send_reply(self, response):
- if DEBUG:
- print("send_reply: response = %s" % (response,))
- # get the status code off the response json and send it
- status_code = response['status']
- self.send_response(status_code)
- self.send_header('Content-type', 'application/json')
- self.end_headers()
- self.wfile.write(json.dumps(response,
- cls=JSON_encoder_with_DateTime))
-
- def parse(self, request_string):
- """Handle the request. Returns the response of the request """
- try:
- database = DataBase(self.conf)
- # Try to json-ify the request_string
- request = json.loads(request_string)
- method = request.pop('method')
- if method == 'add':
- response = database.addBMNode(request)
- elif method == 'allocate':
- response = database.allocateBM(request['owner_name'],
- request['number_of_nodes'])
- elif method == 'release':
- response = database.deallocateOwner(request['owner_name'])
- elif method == 'get_field':
- response = database.get_field(request['owner_name'],
- request['field_name'])
- elif method == 'set_field':
- response = database.set_field(request['id'],
- request['key'],
- request['value'])
- elif method == 'status':
- response = database.status()
- elif method == 'delete_db':
- response = database.delete_db()
- database.close()
- del database
- except Exception as e:
- response = {'status': 400, 'message': str(e)}
-
- if DEBUG:
- print("parse: response = %s" % (response,))
-
- return response
-
- return MoltenIronHandler
-
-
-class Nodes(declarative_base()):
-
- __tablename__ = 'Nodes'
-
- # from sqlalchemy.dialects.mysql import INTEGER
-
- # CREATE TABLE `Nodes` (
- # id INTEGER NOT NULL AUTO_INCREMENT, #@TODO UNSIGNED
- # name VARCHAR(50),
- # ipmi_ip VARCHAR(50),
- # ipmi_user VARCHAR(50),
- # ipmi_password VARCHAR(50),
- # port_hwaddr VARCHAR(50),
- # cpu_arch VARCHAR(50),
- # cpus INTEGER,
- # ram_mb INTEGER,
- # disk_gb INTEGER,
- # status VARCHAR(20),
- # provisioned VARCHAR(50),
- # timestamp TIMESTAMP NULL,
- # PRIMARY KEY (id)
- # )
-
- id = Column('id', Integer, primary_key=True)
- name = Column('name', String(50))
- ipmi_ip = Column('ipmi_ip', String(50))
- ipmi_user = Column('ipmi_user', String(50))
- ipmi_password = Column('ipmi_password', String(50))
- port_hwaddr = Column('port_hwaddr', String(50))
- cpu_arch = Column('cpu_arch', String(50))
- cpus = Column('cpus', Integer)
- ram_mb = Column('ram_mb', Integer)
- disk_gb = Column('disk_gb', Integer)
- status = Column('status', String(20))
- provisioned = Column('provisioned', String(50))
- timestamp = Column('timestamp', TIMESTAMP)
-
- __table__ = Table(__tablename__,
- metadata,
- id,
- name,
- ipmi_ip,
- ipmi_user,
- ipmi_password,
- port_hwaddr,
- cpu_arch,
- cpus,
- ram_mb,
- disk_gb,
- status,
- provisioned,
- timestamp)
-
- def map(self):
- return {key: value for key, value
- in self.__dict__.items()
- if not key.startswith('_') and not callable(key)}
-
- def __repr__(self):
- fmt = """"""
- fmt = fmt.replace('\n', ' ')
-
- return fmt % (self.name,
- self.ipmi_ip,
- self.ipmi_user,
- self.ipmi_password,
- self.port_hwaddr,
- self.cpu_arch,
- self.cpus,
- self.ram_mb,
- self.disk_gb,
- self.status,
- self.provisioned,
- self.timestamp)
-
-
-class IPs(declarative_base()):
-
- __tablename__ = 'IPs'
-
- # CREATE TABLE `IPs` (
- # id INTEGER NOT NULL AUTO_INCREMENT, #@TODO INTEGER(unsigned=True)
- # node_id INTEGER, #@TODO UNSIGNED
- # ip VARCHAR(50),
- # PRIMARY KEY (id),
- # FOREIGN KEY(node_id) REFERENCES `Nodes` (id)
- # )
-
- id = Column('id',
- Integer,
- primary_key=True)
- node_id = Column('node_id',
- Integer,
- ForeignKey("Nodes.id"))
- ip = Column('ip',
- String(50))
-
- __table__ = Table(__tablename__,
- metadata,
- id,
- node_id,
- ip)
-
- def __repr__(self):
-
- fmt = """"""
- fmt = fmt.replace('\n', ' ')
-
- return fmt % (self.id,
- self.node_id,
- self.ip)
-
-TYPE_MYSQL = 1
-# Is there a mysql memory path?
-TYPE_SQLITE = 3
-TYPE_SQLITE_MEMORY = 4
-
-
-class DataBase():
- """This class may be used access the molten iron database. """
-
- def __init__(self,
- config,
- db_type=TYPE_MYSQL):
- self.conf = config
-
- self.user = self.conf["sqlUser"]
- self.passwd = self.conf["sqlPass"]
- self.host = "127.0.0.1"
- self.database = "MoltenIron"
- self.db_type = db_type
-
- engine = None
- try:
- # Does the database exist?
- engine = self.create_engine()
- c = engine.connect()
- c.close()
- except OperationalError:
- sqlalchemy_utils.create_database(engine.url)
- engine = self.create_engine()
- c = engine.connect()
- c.close()
- self.engine = engine
-
- self.create_metadata()
-
- self.element_info = [
- # The following are returned from the query call
-
- # field_name length special_fmt skip
- ("id", 4, int, False),
- ("name", 6, str, False),
- ("ipmi_ip", 9, str, False),
- ("ipmi_user", 11, str, False),
- ("ipmi_password", 15, str, False),
- ("port_hwaddr", 19, str, False),
- ("cpu_arch", 10, str, False),
- ("cpus", 6, int, False),
- ("ram_mb", 8, int, False),
- ("disk_gb", 9, int, False),
- ("status", 8, str, False),
- ("provisioned", 13, str, False),
- # We add timeString
- ("time", 14, float, False),
- ]
- self.setup_status()
-
- def create_engine(self):
- engine = None
-
- if self.db_type == TYPE_MYSQL:
- engine = create_engine("mysql://%s:%s@%s/%s"
- % (self.user,
- self.passwd,
- self.host,
- self.database, ),
- echo=DEBUG)
- elif self.db_type == TYPE_SQLITE_MEMORY:
- engine = create_engine('sqlite:///:memory:',
- echo=DEBUG)
- elif self.db_type == TYPE_SQLITE:
- engine = create_engine("sqlite://%s:%s@%s/%s"
- % (self.user,
- self.passwd,
- self.host,
- self.database, ),
- echo=DEBUG)
-
- return engine
-
- def close(self):
- if DEBUG:
- print("close: Calling engine.dispose()")
- self.engine.dispose()
- if DEBUG:
- print("close: Finished")
-
- def get_session(self):
- """Get a SQL academy session from the pool """
- Session = sessionmaker(bind=self.engine)
- session = Session()
-
- return session
-
- def get_connection(self):
- """Get a SQL academy connection from the pool """
- conn = self.engine.connect()
-
- return conn
-
- @contextmanager
- def session_scope(self):
- """Provide a transactional scope around a series of operations. """
- session = self.get_session()
- try:
- yield session
- session.commit()
- except Exception as e:
- if DEBUG:
- print("Exception caught in session_scope: %s %s"
- % (e, traceback.format_exc(4), ))
- session.rollback()
- raise
- finally:
- session.close()
-
- @contextmanager
- def connection_scope(self):
- """Provide a transactional scope around a series of operations. """
- conn = self.get_connection()
- try:
- yield conn
- except Exception as e:
- if DEBUG:
- print("Exception caught in connection_scope: %s" % (e,))
- raise
- finally:
- conn.close()
-
- def delete_db(self):
- # Instead of:
- # IPs.__table__.drop(self.engine, checkfirst=True)
- # Nodes.__table__.drop(self.engine, checkfirst=True)
- metadata.drop_all(self.engine, checkfirst=True)
-
- return {'status': 200}
-
- def create_metadata(self):
- # Instead of:
- # Nodes.__table__.create(self.engine, checkfirst=True)
- # IPs.__table__.create(self.engine, checkfirst=True)
- if DEBUG:
- print("create_metadata: Calling metadata.create_all")
- metadata.create_all(self.engine, checkfirst=True)
- if DEBUG:
- print("create_metadata: Finished")
-
- def to_timestamp(self, ts):
- timestamp = None
- if self.db_type == TYPE_MYSQL:
- timestamp = time.strftime("%Y-%m-%d %H:%M:%S", ts)
- elif self.db_type in (TYPE_SQLITE, TYPE_SQLITE_MEMORY):
- c = calendar.timegm(ts)
- timestamp = datetime.fromtimestamp(c)
- return timestamp
-
- def from_timestamp(self, timestamp):
- ts = None
- if self.db_type == TYPE_MYSQL:
- ts = time.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
- elif self.db_type == TYPE_SQLITE:
- ts = timestamp.timetuple()
- return ts
-
- def allocateBM(self, owner_name, how_many):
- """Checkout machines from the database and return necessary info """
-
- try:
- with self.session_scope() as session, \
- self.connection_scope() as conn:
-
- # Get a list of IDs for nodes that are free
- count = session.query(Nodes).filter_by(status="ready").count()
-
- # If we don't have enough nodes return an error
- if (count < how_many):
- fmt = "Not enough available nodes found."
- fmt += " Found %d, requested %d"
- return {'status': 404,
- 'message': fmt % (count, how_many, )}
-
- nodes_allocated = {}
-
- for i in range(how_many):
- first_ready = session.query(Nodes)
- first_ready = first_ready.filter_by(status="ready")
- first_ready = first_ready.first()
-
- id = first_ready.id
- # We have everything we need from node
-
- log(self.conf,
- "allocating node id: %d for %s" % (id, owner_name, ))
-
- timestamp = self.to_timestamp(time.gmtime())
-
- # Update the node to the in use state
- stmt = update(Nodes)
- stmt = stmt.where(Nodes.id == id)
- stmt = stmt.values(status="dirty",
- provisioned=owner_name,
- timestamp=timestamp)
- conn.execute(stmt)
-
- # Refresh the data
- session.close()
- session = self.get_session()
-
- first_ready = session.query(Nodes).filter_by(id=id).one()
-
- first_ready_node = first_ready.map()
-
- # Query the associated IP table
- ips = session.query(IPs).filter_by(node_id=first_ready.id)
-
- allocation_pool = []
- for ip in ips:
- allocation_pool.append(ip.ip)
- first_ready_node['allocation_pool'] \
- = ','.join(allocation_pool)
-
- # Add the node to the nodes dict
- nodes_allocated['node_%d' % (id, )] = first_ready_node
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in deallocateBM: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200, 'nodes': nodes_allocated}
-
- def deallocateBM(self, id):
- """Given the ID of a node (or the IPMI IP), de-allocate that node.
-
- This changes the node status of that node from "used" to "ready."
- """
-
- try:
- with self.session_scope() as session, \
- self.connection_scope() as conn:
-
- query = session.query(Nodes.id, Nodes.ipmi_ip, Nodes.name)
-
- if (type(id) == str or type(id) == unicode) and ("." in id):
- # If an ipmi_ip was passed
- query = query.filter_by(ipmi_ip=id)
- else:
- query = query.filter_by(id=id)
-
- node = query.one()
-
- log(self.conf,
- "de-allocating node (%d, %s)" % (node.id, node.ipmi_ip,))
-
- stmt = update(Nodes)
- stmt = stmt.where(Nodes.id == node.id)
- stmt = stmt.values(status="ready",
- provisioned="",
- timestamp=None)
-
- conn.execute(stmt)
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in deallocateBM: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200}
-
- def deallocateOwner(self, owner_name):
- """Deallocate all nodes in use by a given BM owner. """
-
- try:
- with self.session_scope() as session:
- nodes = session.query(Nodes.id)
- nodes = nodes.filter_by(provisioned=owner_name)
-
- if nodes.count() == 0:
- message = "No nodes are owned by %s" % (owner_name,)
-
- return {'status': 400, 'message': message}
-
- for node in nodes:
- self.deallocateBM(node.id)
- except Exception as e:
- if DEBUG:
- print("Exception caught in deallocateOwner: %s" % (e,))
- message = "Failed to deallocate node with ID %d" % (node.id,)
- return {'status': 400, 'message': message}
-
- return {'status': 200}
-
- def addBMNode(self, node):
- """Add a new node to molten iron.
-
- ex:
- node = {u'name': u'test',
- u'ipmi_user': u'user',
- u'port_hwaddr': u'de:ad:be:ef:00:01',
- u'disk_gb': 32,
- u'cpu_arch': u'ppc64el',
- u'ram_mb': 2048,
- u'cpus': 8,
- u'allocation_pool': u'0.0.0.1,0.0.0.2',
- u'ipmi_password': u'password',
- u'ipmi_ip': u'0.0.0.0'}
- """
-
- try:
- if DEBUG:
- print("addBMNode: node = %s" % (node, ))
-
- with self.session_scope() as session, \
- self.connection_scope() as conn:
-
- # Check if it already exists
- query = session.query(Nodes)
- query = query.filter_by(name=node['name'])
- count = query.count()
-
- if count == 1:
- return {'status': 400, 'message': "Node already exists"}
-
- log(self.conf,
- "adding node %(name)s ipmi_ip: %(ipmi_ip)s" % node)
-
- # Add Node to database
- # Note: ID is always 0 as it is an auto-incrementing field
- stmt = insert(Nodes)
- stmt = stmt.values(name=node['name'])
- stmt = stmt.values(ipmi_ip=node['ipmi_ip'])
- stmt = stmt.values(ipmi_user=node['ipmi_user'])
- stmt = stmt.values(ipmi_password=node['ipmi_password'])
- stmt = stmt.values(port_hwaddr=node['port_hwaddr'])
- stmt = stmt.values(cpu_arch=node['cpu_arch'])
- stmt = stmt.values(cpus=node['cpus'])
- stmt = stmt.values(ram_mb=node['ram_mb'])
- stmt = stmt.values(disk_gb=node['disk_gb'])
- stmt = stmt.values(status='ready')
- if 'status' in node:
- stmt = stmt.values(status=node['status'])
- if 'provisioned' in node:
- stmt = stmt.values(provisioned=node['provisioned'])
- if 'timestamp' in node:
- timestamp_str = node['timestamp']
- if DEBUG:
- print("timestamp_str = %s" % (timestamp_str, ))
- if len(timestamp_str) != 0 and timestamp_str != "-1":
- ts = time.gmtime(float(timestamp_str))
- timestamp = self.to_timestamp(ts)
- if DEBUG:
- print("timestamp = %s" % (timestamp, ))
- stmt = stmt.values(timestamp=timestamp)
- if DEBUG:
- print(stmt.compile().params)
-
- conn.execute(stmt)
-
- # Refresh the data
- session.close()
- session = self.get_session()
-
- query = session.query(Nodes).filter_by(name=node['name'])
- new_node = query.one()
-
- # new_node is now a proper Node with an id
-
- # Add IPs to database
- # Note: id is always 0 as it is an auto-incrementing field
- ips = node['allocation_pool'].split(',')
- for ip in ips:
- stmt = insert(IPs)
- stmt = stmt.values(node_id=new_node.id, ip=ip)
-
- if DEBUG:
- print(stmt.compile().params)
-
- conn.execute(stmt)
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in addBMNode: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200}
-
- def removeBMNode(self, ID, force):
- """Remove a node from molten iron
-
- If force is False it will not remove nodes that are in use. If force
- is True then it will always remove the node.
- """
-
- try:
- with self.session_scope() as session, \
- self.connection_scope() as conn:
-
- query = session.query(Nodes.id, Nodes.ipmi_ip, Nodes.name)
- query = query.filter_by(id=int(ID))
- query = query.one()
-
- log(self.conf,
- ("deleting node (id=%d, ipmi_ip=%s, name=%s"
- % (query.id, query.ipmi_ip, query.name,)))
-
- ips = session.query(IPs).filter_by(node_id=int(ID))
- for ip in ips:
- stmt = delete(IPs)
- stmt = stmt.where(IPs.id == ip.id)
- conn.execute(stmt)
-
- stmt = delete(Nodes)
-
- if force:
- stmt = stmt.where(and_(Nodes.id == query.id,
- Nodes.status != "used"))
- else:
- stmt = stmt.where(Nodes.id == query.id)
-
- conn.execute(stmt)
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in removeBMNode: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200}
-
- def cull(self, maxSeconds):
- """If any node has been in use for longer than maxSeconds, deallocate
- that node.
-
- Nodes that are deallocated in this way get their state set to "dirty".
- They are also scheduled for cleaning.
- """
-
- if DEBUG:
- print("cull: maxSeconds = %s" % (maxSeconds, ))
-
- nodes_culled = {}
-
- try:
- with self.session_scope() as session:
-
- nodes = session.query(Nodes)
-
- if DEBUG:
- print("There are %d nodes" % (nodes.count(), ))
-
- for node in nodes:
-
- if DEBUG:
- print(node)
-
- if node.timestamp in ('', '-1', None):
- continue
-
- currentTime = self.to_timestamp(time.gmtime())
- elapsedTime = currentTime - node.timestamp
- if DEBUG:
- print("currentTime = %s"
- % (currentTime, ))
- print("node.timestamp = %s"
- % (node.timestamp, ))
- print("elapsedTime = %s"
- % (elapsedTime, ))
- print("elapsedTime.seconds = %s"
- % (elapsedTime.seconds, ))
-
- if elapsedTime.seconds < int(maxSeconds):
- continue
-
- logstring = ("node %d has been allocated for too long."
- % (node.id,))
- log(self.conf, logstring)
-
- if DEBUG:
- print(logstring)
-
- self.deallocateBM(node.id)
-
- # Add the node to the nodes dict
- nodes_culled['node_%d' % (node.id, )] = node.map()
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in cull: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200, 'nodes': nodes_culled}
-
- def doClean(self, node_id):
- """This function is used to clean a node. """
-
- try:
- with self.session_scope() as session, \
- self.connection_scope() as conn:
-
- query = session.query(Nodes)
- query = query.filter_by(id=node_id)
- node = query.one()
-
- if node.status in ('ready', ''):
- return {'status': 400,
- 'message': 'The node at %d has status %s'
- % (node.id, node.status,)}
-
- logstring = "The node at %s has been cleaned." % \
- (node.ipmi_ip,)
- log(self.conf, logstring)
-
- stmt = update(Nodes)
- stmt = stmt.where(Nodes.id == node_id)
- stmt = stmt.values(status="ready")
-
- conn.execute(stmt)
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in doClean: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200}
-
- # @TODO shouldn't it return allocation_pool rather than ipmi_ip?
- def get_ips(self, owner_name):
- """Return all IPs allocated to a given node owner
-
- IPs are returned as a list of strings
- """
-
- ips = []
-
- try:
- with self.session_scope() as session:
-
- query = session.query(Nodes)
- nodes = query.filter_by(provisioned=owner_name)
-
- for node in nodes:
- ips.append(node.ipmi_ip)
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in get_ips: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200, 'ips': ips}
-
- def get_field(self, owner_name, field):
- """Return entries list with id, field for a given owner, field. """
-
- if not hasattr(Nodes, field):
- return {'status': 400,
- 'message': 'field %s does not exist' % (field,)}
-
- results = []
-
- try:
- with self.session_scope() as session:
-
- query = session.query(Nodes)
- nodes = query.filter_by(provisioned=owner_name)
-
- if DEBUG:
- print("There are %d entries provisioned by %s"
- % (nodes.count(), owner_name,))
-
- if nodes.count() == 0:
- return {'status': 404,
- 'message': '%s does not own any nodes'
- % owner_name}
-
- for node in nodes:
- result = {'id': node.id}
- result['field'] = getattr(node, field)
-
- results.append(result)
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in get_field: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200, 'result': results}
-
- def set_field(self, id, key, value):
- """Given an identifying id, set specified key to the passed value. """
-
- if not hasattr(Nodes, key):
- return {'status': 400,
- 'message': 'field %s does not exist' % (key,)}
-
- try:
- with self.session_scope() as session, \
- self.connection_scope() as conn:
-
- query = session.query(Nodes)
- nodes = query.filter_by(id=id)
-
- if nodes.count() == 0:
- return {'status': 404,
- 'message': 'Node with id of %s does not exist!'
- % id}
-
- nodes.one()
-
- kv = {key: value}
-
- stmt = update(Nodes)
- stmt = stmt.where(Nodes.id == id)
- stmt = stmt.values(**kv)
-
- conn.execute(stmt)
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in set_field: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200}
-
- def setup_status(self):
- """Setup the status formatting strings depending on skipped elements,
- lengths, and types.
- """
-
- self.result_separator = "+"
- for (_, length, _, skip) in self.element_info:
- if skip:
- continue
- self.result_separator += '-' * (1 + length + 1) + "+"
-
- self.description_line = "+"
- for (field, length, _, skip) in self.element_info:
- if skip:
- continue
- self.description_line += (" " +
- field +
- ' ' * (length - len(field)) +
- " +")
-
- index = 0
- self.format_line = "|"
- for (_, length, special_fmt, skip) in self.element_info:
- if skip:
- continue
- if special_fmt is int:
- self.format_line += " {%d:<%d} |" % (index, length)
- elif special_fmt is str:
- self.format_line += " {%d:%d} |" % (index, length)
- elif special_fmt is float:
- self.format_line += " {%d:<%d.%d} |" \
- % (index, length, length - 2)
- index += 1
-
- def status(self):
- """Return a table that details the state of each bare metal node.
-
- Currently this table is being created manually, there is probably a
- better way to be doing this.
- """
-
- result = ""
-
- try:
- with self.session_scope() as session:
-
- query = session.query(Nodes)
-
- result += self.result_separator + "\n"
- result += self.description_line + "\n"
- result += self.result_separator + "\n"
-
- for node in query:
-
- timeString = ""
- try:
- if node.timestamp is not None:
- elapsedTime = datetime.utcnow() - node.timestamp
- timeString = str(elapsedTime)
- except Exception:
- pass
-
- elements = (node.id,
- node.name,
- node.ipmi_ip,
- node.ipmi_user,
- node.ipmi_password,
- node.port_hwaddr,
- node.cpu_arch,
- node.cpus,
- node.ram_mb,
- node.disk_gb,
- node.status,
- node.provisioned,
- timeString)
-
- new_elements = []
- index = 0
- for (_, _, _, skip) in self.element_info:
- if not skip:
- new_elements.append(elements[index])
- index += 1
-
- result += self.format_line.format(*new_elements) + "\n"
-
- result += self.result_separator + "\n"
-
- except Exception as e:
-
- if DEBUG:
- print("Exception caught in status: %s" % (e,))
-
- # Don't send the exception object as it is not json serializable!
- return {'status': 400, 'message': str(e)}
-
- return {'status': 200, 'result': result}
-
-
-def listener(conf):
- mi_addr = str(conf['serverIP'])
- mi_port = int(conf['mi_port'])
- handler_class = MakeMoltenIronHandlerWithConf(conf)
- print('Listening... to %s:%d' % (mi_addr, mi_port,))
- moltenirond = HTTPServer((mi_addr, mi_port), handler_class)
- moltenirond.serve_forever()
-
-
-def cleanup():
- """This function kills any running instances of molten iron.
-
- This should be called when starting a new instance of molten iron.
- """
- ps = os.popen("ps aux | grep python | grep moltenIronD.py").read()
- processes = ps.split("\n")
- pids = []
- for process in processes:
- if "grep" in process:
- continue
- words = process.split(" ")
- actual = []
- for word in words:
- if word != "":
- actual += [word]
- words = actual
- if len(words) > 1:
- pids += [words[1]]
- myPID = os.getpid()
-
- for pid in pids:
- if int(pid) == int(myPID):
- continue
- os.system("kill -9 " + pid)
-
-
-def log(conf, message):
- """Write a message to the log file. """
- cleanLogs(conf)
- logdir = conf["logdir"]
- now = datetime.today()
-
- fname = str(now.day) + "-" + str(now.month) \
- + "-" + str(now.year) + ".log"
-
- timestamp = "{0:0>2}".format(str(now.hour)) + ":" + \
- "{0:0>2}".format(str(now.minute)) \
- + ":" + "{0:0>2}".format(str(now.second))
-
- message = timestamp + " " + message + "\n"
-
- # check if logdir exists, if not create it
- if not os.path.isdir(logdir):
- os.popen("mkdir " + logdir)
-
- fobj = open(logdir + "/" + fname, "a")
- fobj.write(message)
- fobj.close()
-
-
-def cleanLogs(conf):
- """Find and delete log files that have been around for too long. """
- logdir = conf["logdir"]
- maxDays = conf["maxLogDays"]
- if not os.path.isdir(logdir):
- return
- now = datetime.today()
- logs = os.popen("ls " + logdir).read().split("\n")
- for log in logs:
- elements = log[:-1 * len(".log")].split("-")
- if len(elements) != 3:
- continue
- newDate = datetime(int(elements[2]),
- int(elements[1]),
- int(elements[0]))
- if (now - newDate).days > maxDays:
- os.popen("rm " + logdir + "/" + log)
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron daemon")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args ()
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- listener(conf)
diff --git a/nodepool/molteniron/requirements.txt b/nodepool/molteniron/requirements.txt
deleted file mode 100644
index 4a94692..0000000
--- a/nodepool/molteniron/requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-daemonize
-MySQL-python
-pyyaml
-sqlalchemy
-sqlalchemy_utils
diff --git a/nodepool/molteniron/setup.py b/nodepool/molteniron/setup.py
deleted file mode 100755
index 849d787..0000000
--- a/nodepool/molteniron/setup.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from distutils.core import setup
-
-setup(name="molteniron",
- version="1.0",
- description="database for Ironic Baremetal services",
- url="https://github.com/openstack/third-party-ci-tools",
- py_modules=["molteniron/__init__", "molteniron/moltenirond"],
- scripts=["molteniron/moltenirond-helper", "molteniron/molteniron"],
- data_files=[("etc/molteniron/", ["conf.yaml"])]
- )
diff --git a/nodepool/molteniron/tests/testAddBMNode.py b/nodepool/molteniron/tests/testAddBMNode.py
deleted file mode 100755
index e7a29ea..0000000
--- a/nodepool/molteniron/tests/testAddBMNode.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "2f024600fc5ef6f7",
- "port_hwaddr": "97:c3:b0:47:0c:0d",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "6cf0957c985b2deb",
- "port_hwaddr": "2d:9e:3c:83:8a:be",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "cc777c10196db585",
- "port_hwaddr": "47:b0:dc:d5:82:d9",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "ipmi_password": "a700a2d789075276",
- "port_hwaddr": "44:94:1a:c7:8a:9f",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node1)
- print ret
- assert ret['status'] == 400
- assert ret['message'] == "Node already exists"
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret['status'] == 400
- assert ret['message'] == "Node already exists"
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret['status'] == 400
- assert ret['message'] == "Node already exists"
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tests/testAllocateBM.py b/nodepool/molteniron/tests/testAllocateBM.py
deleted file mode 100755
index 337aff1..0000000
--- a/nodepool/molteniron/tests/testAllocateBM.py
+++ /dev/null
@@ -1,201 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-def compare_provisioned_nodes(lhs, rhs):
- lhs = lhs.copy()
- rhs = rhs.copy()
- rhs['provisioned'] = 'hamzy'
- del lhs['status']
- del lhs['timestamp']
- del rhs['status']
- del rhs['timestamp']
- del lhs['id']
- assert lhs == rhs
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "e05cc5f061426e34",
- "port_hwaddr": "f8:de:29:33:a4:ed",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "0614d63b6635ea3d",
- "port_hwaddr": "4c:c5:da:28:2c:2d",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "928b056134e4d770",
- "port_hwaddr": "53:76:c6:09:50:64",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "ipmi_password": "33f448a4fc176492",
- "port_hwaddr": "85:e0:73:e9:fc:ca",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.allocateBM("hamzy", 1)
- print ret
- assert ret['status'] == 200
- assert len(ret["nodes"]) == 1
- compare_provisioned_nodes (ret["nodes"]["node_1"], node1)
-
- 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 (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.allocateBM("hamzy", 2)
- print ret
- assert ret['status'] == 200
- assert len(ret["nodes"]) == 2
- compare_provisioned_nodes (ret["nodes"]["node_1"], node1)
- compare_provisioned_nodes (ret["nodes"]["node_2"], node2)
-
- 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 (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.allocateBM("hamzy", 3)
- print ret
- assert ret == {'status': 404,
- 'message': ('Not enough available nodes found. '
- 'Found 2, requested 3')}
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tests/testCull.py b/nodepool/molteniron/tests/testCull.py
deleted file mode 100755
index 70aa9dc..0000000
--- a/nodepool/molteniron/tests/testCull.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-import time
-from molteniron import moltenirond
-
-def compare_culled_nodes(lhs, rhs):
- lhs = lhs.copy()
- rhs = rhs.copy()
- del rhs['allocation_pool']
- # timestamp can be converted on the server
- del lhs['timestamp']
- del rhs['timestamp']
- del lhs['id']
- assert lhs == rhs
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "34118fd3509621ba",
- "port_hwaddr": "ff:2c:e1:cc:8e:7c",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "fa2125690a95b43c",
- "port_hwaddr": "f6:58:13:02:64:59",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "-1",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "3aee014d56425a6c",
- "port_hwaddr": "6e:d4:a5:ae:13:55",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- # NOTE: time() can return fractional values. Ex: 1460560140.47
- "timestamp": str (time.time() - 1000.0),
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "ipmi_password": "254dd9fb34ddcac7",
- "port_hwaddr": "a0:c9:22:23:22:9d",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d",
- "timestamp": str (time.time() - 2000.0),
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.cull (1000)
- print ret
- assert ret['status'] == 200
- assert len(ret['nodes']) == 2
-
- compare_culled_nodes (ret['nodes']['node_3'], node3)
- compare_culled_nodes (ret['nodes']['node_4'], node4)
-
- 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 (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.cull (2000)
- print ret
- assert ret['status'] == 200
- assert len(ret['nodes']) == 1
-
- compare_culled_nodes (ret['nodes']['node_4'], node4)
-
- 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 (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.cull (3000)
- print ret
- assert ret['status'] == 200
- assert len(ret['nodes']) == 0
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tests/testDeallocateBM.py b/nodepool/molteniron/tests/testDeallocateBM.py
deleted file mode 100755
index 8202b62..0000000
--- a/nodepool/molteniron/tests/testDeallocateBM.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-def compare_provisioned_nodes(lhs, rhs):
- lhs = lhs.copy()
- rhs = rhs.copy()
- rhs['provisioned'] = 'hamzy'
- del lhs['status']
- del lhs['timestamp']
- del rhs['status']
- del rhs['timestamp']
- del lhs['id']
- assert lhs == rhs
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "16f6954d347c4de2",
- "port_hwaddr": "28:5a:e7:e3:fe:75",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "3a23241cfa516699",
- "port_hwaddr": "7d:0a:e5:b9:41:9b",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "4f7e47c57f27ec55",
- "port_hwaddr": "5a:e8:11:e9:11:a2",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "ipmi_password": "aeff165ded2c2f9f",
- "port_hwaddr": "4d:18:82:dc:2c:d6",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.allocateBM("hamzy", 1)
- print ret
- assert ret['status'] == 200
- assert len(ret["nodes"]) == 1
- compare_provisioned_nodes (ret["nodes"]["node_1"], node1)
-
- session = database.get_session()
- n1 = session.query(moltenirond.Nodes).filter_by(name=node1["name"]).one()
- session.close()
- ret = database.deallocateBM(n1.id)
- print ret
- assert ret['status'] == 200
-
- 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 (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.allocateBM("hamzy", 1)
- print ret
- assert ret['status'] == 200
- assert len(ret["nodes"]) == 1
- compare_provisioned_nodes (ret["nodes"]["node_1"], node1)
-
- session = database.get_session()
- n1 = session.query(moltenirond.Nodes).filter_by(name=node1["name"]).one()
- session.close()
- ret = database.deallocateBM(n1.ipmi_ip)
- print ret
- assert ret['status'] == 200
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tests/testDeallocateOwner.py b/nodepool/molteniron/tests/testDeallocateOwner.py
deleted file mode 100755
index dd7e0df..0000000
--- a/nodepool/molteniron/tests/testDeallocateOwner.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-def compare_provisioned_nodes(lhs, rhs):
- lhs = lhs.copy()
- rhs = rhs.copy()
- rhs['provisioned'] = 'hamzy'
- del lhs['status']
- del lhs['timestamp']
- del rhs['status']
- del rhs['timestamp']
- del lhs['id']
- assert lhs == rhs
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "f367d07be07d6358",
- "port_hwaddr": "6d:9a:78:f3:ed:3a",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "1c6a27307f8fe79d",
- "port_hwaddr": "16:23:e8:07:b4:a9",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "1766d597a024dd8d",
- "port_hwaddr": "12:33:9f:04:07:9b",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "ipmi_password": "7c55be8b4ef42869",
- "port_hwaddr": "c2:31:e9:8a:75:96",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.allocateBM("hamzy", 1)
- print ret
- assert ret['status'] == 200
- assert len(ret["nodes"]) == 1
- compare_provisioned_nodes (ret["nodes"]["node_1"], node1)
-
- ret = database.deallocateOwner("hamzy")
- print ret
- assert ret['status'] == 200
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tests/testDoClean.py b/nodepool/molteniron/tests/testDoClean.py
deleted file mode 100755
index 8e9c676..0000000
--- a/nodepool/molteniron/tests/testDoClean.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "e23af1e52896cf02",
- "port_hwaddr": "5d:7e:05:dd:fe:65",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "57212373db56c76a",
- "port_hwaddr": "7e:41:89:e1:28:03",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "c2f4b0bfa31fe9de",
- "port_hwaddr": "4f:a7:48:59:6a:a7",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "ipmi_password": "f99d122fc129c1dd",
- "port_hwaddr": "a2:0d:bc:ca:c5:a5",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.doClean(1)
- print ret
- assert ret == {'status': 400, 'message': 'The node at 1 has status ready'}
-
- ret = database.doClean(2)
- print ret
- assert ret == {'status': 400, 'message': 'The node at 2 has status ready'}
-
- ret = database.doClean(3)
- print ret
- assert ret == {'status': 200}
-
- ret = database.doClean(4)
- print ret
- assert ret == {'status': 200}
diff --git a/nodepool/molteniron/tests/testGetField.py b/nodepool/molteniron/tests/testGetField.py
deleted file mode 100755
index 7813b74..0000000
--- a/nodepool/molteniron/tests/testGetField.py
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "7db1486ac9ea6533",
- "port_hwaddr": "ca:2c:ab:88:47:b0",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "hamzy",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "c3f8e3f3407e880b",
- "port_hwaddr": "90:24:5c:d5:0e:b3",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "mjturek",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "1bcbf739c7108291",
- "port_hwaddr": "9c:6b:1b:31:a5:2d",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "cpu_arch": "ppc64el",
- "ipmi_password": "0c200c858ac46280",
- "port_hwaddr": "64:49:12:c6:3f:bd",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "mjturek",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.get_field("hamzy", "cpus")
- print ret
- assert ret['status'] == 200
- assert len(ret['result']) ==1
- assert ret['result'][0]['field'] == node1["cpus"]
-
- ret = database.get_field("mjturek", "port_hwaddr")
- print ret
- assert ret['status'] == 200
- assert len(ret['result']) == 2
- assert ret['result'][0]['field'] == node2["port_hwaddr"]
- assert ret['result'][1]['field'] == node4["port_hwaddr"]
-
- ret = database.get_field("mmedvede", "candy")
- print ret
- assert ret == {'status': 400, 'message': 'field candy does not exist'}
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tests/testGetIps.py b/nodepool/molteniron/tests/testGetIps.py
deleted file mode 100755
index 2af8fd5..0000000
--- a/nodepool/molteniron/tests/testGetIps.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "1aa328d7767653ad",
- "port_hwaddr": "17:e7:f1:ab:a5:9f",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "hamzy",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "84b9d9ceb866f612",
- "port_hwaddr": "0b:f1:9c:9d:a6:eb",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "mjturek",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "ba60285a1fd69800",
- "port_hwaddr": "da:e0:86:2a:80:9c",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "cpu_arch": "ppc64el",
- "ipmi_password": "7810c66057ef4f2d",
- "port_hwaddr": "d6:bc:ca:83:95:e7",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "mjturek",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- ret = database.get_ips("hamzy")
- print ret
- assert ret['status'] == 200
- assert len(ret['ips']) == 1
- assert ret['ips'] == [ node1["ipmi_ip"] ]
-
- ret = database.get_ips("mjturek")
- print ret
- assert ret['status'] == 200
- assert len(ret['ips']) == 2
- assert ret['ips'] == [ node2["ipmi_ip"], node4["ipmi_ip"] ]
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tests/testRemoveBMNode.py b/nodepool/molteniron/tests/testRemoveBMNode.py
deleted file mode 100755
index bc8a778..0000000
--- a/nodepool/molteniron/tests/testRemoveBMNode.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import os
-import yaml
-import argparse
-from molteniron import moltenirond
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Molteniron command line tool")
- parser.add_argument("-c",
- "--conf-dir",
- action="store",
- type=str,
- dest="conf_dir",
- help="The directory where configuration is stored")
-
- args = parser.parse_args(sys.argv[1:])
-
- if args.conf_dir:
- if not os.path.isdir (args.conf_dir):
- msg = "Error: %s is not a valid directory" % (args.conf_dir, )
- print >> sys.stderr, msg
- sys.exit(1)
-
- yaml_file = os.path.realpath("%s/conf.yaml" % (args.conf_dir, ))
- else:
- yaml_file = "/usr/local/etc/molteniron/conf.yaml"
-
- with open(yaml_file, "r") as fobj:
- conf = yaml.load(fobj)
-
- node1 = {
- "name": "pkvmci816",
- "ipmi_ip": "10.228.219.134",
- "ipmi_user": "user",
- "ipmi_password": "2703f5fee17f2073",
- "port_hwaddr": "b1:71:dd:02:9e:20",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.10,10.228.112.11"
- }
- node2 = {
- "name": "pkvmci818",
- "ipmi_ip": "10.228.219.133",
- "ipmi_user": "user",
- "ipmi_password": "c3f06ff4b798a4ea",
- "port_hwaddr": "88:6e:9e:fa:65:d8",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "ready",
- "provisioned": "",
- "timestamp": "",
- "allocation_pool": "10.228.112.8,10.228.112.9"
- }
- node3 = {
- "name": "pkvmci851",
- "ipmi_ip": "10.228.118.129",
- "ipmi_user": "user",
- "ipmi_password": "2885d1af50781461",
- "port_hwaddr": "a2:a2:64:79:6b:69",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "7a72eccd-3153-4d08-9848-c6d3b1f18f9f",
- "timestamp": "1460489832",
- "allocation_pool": "10.228.112.12,10.228.112.13"
- }
- node4 = {
- "name": "pkvmci853",
- "ipmi_ip": "10.228.118.133",
- "ipmi_user": "user",
- "ipmi_password": "3e374dc88ca43b4f",
- "port_hwaddr": "50:4a:56:3c:e9:0f",
- "cpu_arch": "ppc64el",
- "cpus": 20L,
- "ram_mb": 51000L,
- "disk_gb": 500L,
- "status": "used",
- "provisioned": "6b8823ef-3e14-4811-98b9-32e27397540d",
- "timestamp": "1460491566",
- "allocation_pool": "10.228.112.14,10.228.112.15"
- }
-
- # 8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----
- database = moltenirond.DataBase(conf, moltenirond.TYPE_SQLITE_MEMORY)
- ret = database.addBMNode (node1)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node2)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node3)
- print ret
- assert ret == {'status': 200}
- ret = database.addBMNode (node4)
- print ret
- assert ret == {'status': 200}
-
- session = database.get_session()
- n1 = session.query(moltenirond.Nodes).filter_by(name=node1["name"]).one()
- session.close()
- ret = database.removeBMNode(n1.id, False)
- print ret
- assert ret['status'] == 200
-
- database.close()
- del database
diff --git a/nodepool/molteniron/tox.ini b/nodepool/molteniron/tox.ini
deleted file mode 100644
index 5a54ac7..0000000
--- a/nodepool/molteniron/tox.ini
+++ /dev/null
@@ -1,83 +0,0 @@
-[tox]
-envlist = py27
-
-[testenv:devenv]
-envdir = devenv
-basepython = python2.7
-# usedevelop = True
-# will create a devenv/lib/python2.7/site-packages/molteniron.egg-link which
-# will point back to the git directory.
-# Instead, we want the module installed in the virtual environment.
-usedevelop = False
-deps = -rrequirements.txt
-
-[testenv:testenv]
-envdir = testenv
-basepython = python2.7
-# usedevelop = True
-# will create a testenv/lib/python2.7/site-packages/molteniron.egg-link which
-# will point back to the git directory.
-# Instead, we want the module installed in the virtual environment.
-usedevelop = False
-# Skip automatic tarballing of source distribution. We will manually run
-# setup.py later...
-skipsdist = True
-# Don't worry about installing bash commands in the virtual environment.
-whitelist_externals = mkdir
-deps = -rrequirements.txt
-commands = mkdir -p testenv/var/run/
- python setup.py \
- install \
- --install-data=testenv/ \
- --install-scripts=testenv/bin/ \
- --install-purelib=testenv/lib/python2.7/site-packages/
- moltenirond-helper \
- --conf-dir=testenv/etc/molteniron/ \
- --pid-dir=testenv/var/run/ \
- start
- molteniron \
- --conf-dir=testenv/etc/molteniron/ \
- delete_db
- molteniron \
- --conf-dir=testenv/etc/molteniron/ \
- add test 10.1.2.1 user password 10.1.2.3,10.1.2.4 de:ad:be:ef:00:01 ppc64el 8 2048 32
- molteniron \
- --conf-dir=testenv/etc/molteniron/ \
- allocate hamzy 1
- molteniron \
- --conf-dir=testenv/etc/molteniron/ \
- get_field hamzy port_hwaddr
- molteniron \
- --conf-dir=testenv/etc/molteniron/ \
- release hamzy
- python \
- tests/testAllocateBM.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testAddBMNode.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testCull.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testDeallocateBM.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testDeallocateOwner.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testDoClean.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testGetField.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testGetIps.py \
- --conf-dir=testenv/etc/molteniron/
- python \
- tests/testRemoveBMNode.py \
- --conf-dir=testenv/etc/molteniron/
- moltenirond-helper \
- --conf-dir=testenv/etc/molteniron/ \
- --pid-dir=testenv/var/run/ \
- stop
diff --git a/nodepool/molteniron/utils/test_hook_configure_mi.sh b/nodepool/molteniron/utils/test_hook_configure_mi.sh
deleted file mode 100755
index 7c9f289..0000000
--- a/nodepool/molteniron/utils/test_hook_configure_mi.sh
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/bash
-
-# Copyright (c) 2016 IBM Corporation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-errcho()
-{
- # Redirect stdout to stderr for the echo command
- >&2 echo $@;
-}
-
-#
-# NOTE:
-#
-# This script expects the environment variable dsvm_uuid to be set!
-#
-
-if [ -z "${dsvm_uuid}" ]
-then
- errcho "Error: environment variable unset: dsvm_uuid"
- exit 1
-fi
-
-# Is the command-line JSON processor installed?
-hash jq || sudo apt-get install -y jq
-
-# Turn off Bash debugging temporarily to stop password being shown in log files
-set +x
-
-# allocate a BM node to a dsvm guest named dsvm_uuid, then amend the localrc
-# and hardware_info files.
-JSON_RSP=$(molteniron allocate $dsvm_uuid 1)
-
-if [ $? -gt 0 ]
-then
- # Save the response for local debugging
- echo "${JSON_RSP}" > /tmp/json.rsp
-
- errcho "Error: allocate $dsvm_uuid 1"
-
- MESSAGE=$(echo "${JSON_RSP}" | jq .message)
-
- # Is there a message response?
- # NOTE: jq not finding a message key returns null
- if [ $? -eq 0 -a "${MESSAGE}" != "null" ]
- then
- errcho "Error: ${MESSAGE}"
- fi
-
- exit 1
-fi
-
-# Convert from a JSON string into a Bash array
-declare -A NODE
-while IFS="=" read -r key value
-do
- NODE[$key]="$value"
-done < <(
- echo ${JSON_RSP} | jq --raw-output '.nodes[]|to_entries|map("\(.key)=\(.value|tostring)")|.[]'
- RC=$?
- if [ ${RC} -gt 0 ]
- then
- echo "error=${RC}"
- fi
-)
-
-if [ -n "${NODE[error]}" ]
-then
- errcho "Error: jq failed to parse response"
- errcho "jq .nodes:"
- errcho ${JSON_RSP} | jq '.nodes[]'
- errcho "jq .nodes|to_entries|map:"
- errcho ${JSON_RSP} | jq --raw-output '.nodes[]|to_entries|map("\(.key)=\(.value|tostring)")|.[]'
- exit 2
-elif [ -z "${NODE[ipmi_ip]}" \
- -o -z "${NODE[port_hwaddr]}" \
- -o -z "${NODE[ipmi_user]}" \
- -o -z "${NODE[ipmi_password]}" ]
-then
- echo "ERROR: One of NODE's ipmi_ip, port_hwaddr, ipmi_user, or ipmi_password is empty!"
- if [ -n "${NODE[ipmi_password]}" ]
- then
- SAFE_PASSWORD="*hidden*"
- else
- SAFE_PASSWORD=""
- fi
- echo "NODE[ipmi_ip] = ${NODE[ipmi_ip]}"
- echo "NODE[port_hwaddr] = ${NODE[port_hwaddr]}"
- echo "NODE[ipmi_user] = ${NODE[ipmi_user]}"
- echo "NODE[ipmi_password] = ${SAFE_PASSWORD}"
- echo "jq command returns:"
- echo ${JSON_RSP} | jq --raw-output '.nodes[]|to_entries|map("\(.key)=\(.value|tostring)")|.[]'
- exit 3
-fi
-
-# Set IPMI info file
-printf "${NODE[ipmi_ip]} ${NODE[port_hwaddr]} ${NODE[ipmi_user]} ${NODE[ipmi_password]}\\n" > "/opt/stack/new/devstack/files/hardware_info"
-
-set -x
-
-# Add the hardware properties to the localrc file
-printf "IRONIC_HW_ARCH=${NODE[cpu_arch]}\\nIRONIC_HW_NODE_CPU=${NODE[cpus]}\\nIRONIC_HW_NODE_RAM=${NODE[ram_mb]}\\nIRONIC_HW_NODE_DISK=${NODE[disk_gb]}\\n" >> "/opt/stack/new/devstack/localrc"
-
-# Add the allocation pools to the localrc
-IFS=',' read -r -a ALLOCATION_POOL <<< ${NODE[allocation_pool]}
-
-POOL=''
-for IP in ${ALLOCATION_POOL[@]}
-do
- echo "IP=${IP}"
- if [ -n "${POOL}" ]
- then
- POOL+=" --allocation-pool "
- fi
- POOL+="start=${IP},end=${IP}"
-done
-# append ip pools to the end of our localrc
-printf "ALLOCATION_POOL=\"${POOL}\"\n" >> "/opt/stack/new/devstack/localrc"