MoltenIron is now an Open Stack project!
Change-Id: I74065793294f53d39cb5405b17781b5fb97a05eb
This commit is contained in:
parent
dc37d424c7
commit
f09fbb4348
@ -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="$(</etc/nodepool/uuid)"
|
||||
echo "Cleaning up resources associated with node: ${DSVM_UUID}"
|
||||
molteniron release ${DSVM_UUID}
|
||||
```
|
||||
https://launchpad.net/molteniron
|
||||
|
@ -1,9 +0,0 @@
|
||||
mi_port: 5656
|
||||
serverIP: 127.0.0.1
|
||||
timeout: 5
|
||||
retry: 5
|
||||
maxTime: 6000
|
||||
logdir: "./logs"
|
||||
maxLogDays: 15
|
||||
sqlUser: "root"
|
||||
sqlPass: "password"
|
@ -1,41 +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 os
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
|
||||
def SQL(query):
|
||||
print(os.popen("mysql -u root -p --execute=\"" + query + "\"").read())
|
||||
|
||||
|
||||
def main():
|
||||
path = sys.argv[0]
|
||||
dirs = path.split("/")
|
||||
newPath = "/".join(dirs[:-1]) + "/"
|
||||
fobj = open(newPath + "conf.yaml", "r")
|
||||
conf = yaml.load(fobj)
|
||||
|
||||
# Create the SQL User
|
||||
SQL("CREATE USER '"+conf["sqlUser"]+"'@'localhost' "
|
||||
"IDENTIFIED BY '"+conf["sqlPass"]+"';")
|
||||
SQL("GRANT ALL ON MoltenIron.* TO '"+conf["sqlUser"]+"'@'localhost';")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,237 +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 httplib
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import yaml
|
||||
import argparse
|
||||
|
||||
DEBUG = False
|
||||
|
||||
def split_commandline_args(argv):
|
||||
front = []
|
||||
back = []
|
||||
command_found = False
|
||||
|
||||
for elm in argv:
|
||||
if command_found:
|
||||
back.append(elm)
|
||||
else:
|
||||
front.append(elm)
|
||||
|
||||
if elm[0] != '-':
|
||||
command_found = True
|
||||
|
||||
return (front, back)
|
||||
|
||||
|
||||
class MoltenIron(object):
|
||||
|
||||
def __init__(self, conf, argv):
|
||||
self.conf = conf
|
||||
|
||||
(argv, rest_argv) = split_commandline_args(argv)
|
||||
|
||||
# Parse the arguments and generate a request
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('command', help='Subcommand to run')
|
||||
|
||||
(args, unknown_args) = parser.parse_known_args (argv)
|
||||
unknown_args += rest_argv
|
||||
|
||||
request = getattr(self, args.command)(unknown_args)
|
||||
|
||||
# Send the request and print the response
|
||||
self.response_str = self.send(request)
|
||||
self.response_json = json.loads(self.response_str)
|
||||
|
||||
def send(self, request):
|
||||
"""Send the generated request """
|
||||
connection = httplib.HTTPConnection(str(self.conf['serverIP']),
|
||||
int(self.conf['mi_port']))
|
||||
connection.request('POST', '/', json.dumps(request))
|
||||
|
||||
response = connection.getresponse()
|
||||
|
||||
return response.read()
|
||||
|
||||
def get_response(self):
|
||||
"""Returns the response from the server """
|
||||
return self.response_str
|
||||
|
||||
def get_response_map(self):
|
||||
"""Returns the response from the server """
|
||||
return self.response_json
|
||||
|
||||
def add(self, argv):
|
||||
"""Generate a request to add a node to the MoltenIron database """
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Add a node to the micli')
|
||||
parser.add_argument('name', help="Name of the baremetal node")
|
||||
parser.add_argument('ipmi_ip', help="IP for issuing IPMI commands to"
|
||||
" this node")
|
||||
parser.add_argument('ipmi_user', help="IPMI username used when issuing"
|
||||
" IPMI commands to this node")
|
||||
parser.add_argument('ipmi_password', help="IPMI password used when"
|
||||
" issuing IPMI commands to this node")
|
||||
parser.add_argument('allocation_pool', help="Comma separated list of"
|
||||
" IPs to be used in deployment")
|
||||
parser.add_argument('port_hwaddr', help="MAC address of port on"
|
||||
" machine to use during deployment")
|
||||
parser.add_argument('cpu_arch', help="Architecture of the node")
|
||||
parser.add_argument('cpus', type=int, help="Number of CPUs on the"
|
||||
" node")
|
||||
parser.add_argument('ram_mb', type=int, help="Amount of RAM (in MiB)"
|
||||
" that the node has")
|
||||
parser.add_argument('disk_gb', type=int, help="Amount of disk (in GiB)"
|
||||
" that the node has")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
request = vars(args)
|
||||
request['method'] = 'add'
|
||||
return request
|
||||
|
||||
def allocate(self, argv):
|
||||
"""Generate request to checkout a node from the MoltenIron database """
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Checkout a node in molteniron. Returns the node's"
|
||||
" info")
|
||||
parser.add_argument('owner_name', help="Name of the requester")
|
||||
parser.add_argument('number_of_nodes', type=int, help="How many nodes"
|
||||
" to reserve")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
request = vars(args)
|
||||
request['method'] = 'allocate'
|
||||
return request
|
||||
|
||||
def release(self, argv):
|
||||
"""Generate a request to release an allocated node from the MoltenIron
|
||||
database
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Given an owner name, release allocated node,"
|
||||
" returning it to the available state")
|
||||
parser.add_argument('owner_name', help="Name of the owner who"
|
||||
" currently owns the nodes to be released")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
request = vars(args)
|
||||
request['method'] = 'release'
|
||||
return request
|
||||
|
||||
def get_field(self, argv):
|
||||
"""Generate a request to return a field of data from an owned node from
|
||||
the MoltenIron database
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Given an owner name and the name of a field, get the"
|
||||
" value of the field")
|
||||
|
||||
parser.add_argument('owner_name', help="Name of the owner who"
|
||||
" currently owns the nodes to get the field from")
|
||||
parser.add_argument('field_name', help="Name of the field to retrieve"
|
||||
" the value from")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
request = vars(args)
|
||||
request['method'] = 'get_field'
|
||||
return request
|
||||
|
||||
def set_field(self, argv):
|
||||
"""Generate request to set a field of data from an id in the MoltenIron
|
||||
database
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Given an id, set a field with a value')
|
||||
|
||||
parser.add_argument('id', help='Id of the entry')
|
||||
parser.add_argument('key', help='Field name to set')
|
||||
parser.add_argument('value', help='Field value to set')
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
request = vars(args)
|
||||
request['method'] = 'set_field'
|
||||
return request
|
||||
|
||||
def status(self, argv):
|
||||
"""Return status """
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Return a list of current MoltenIron Node database"
|
||||
" entries")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
request = vars(args)
|
||||
request['method'] = 'status'
|
||||
return request
|
||||
|
||||
def delete_db(self, argv):
|
||||
"""Delete all database entries"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Delete every entry in the MoltenIron Node database")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
request = vars(args)
|
||||
request['method'] = 'delete_db'
|
||||
return request
|
||||
|
||||
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")
|
||||
|
||||
# We want individual command help later. So we need to remove a --help
|
||||
# found at the end of the command line as long as there is at least
|
||||
# one argument that doesn't start with '-'.
|
||||
(argv, rest_argv) = split_commandline_args(list(sys.argv[1:]))
|
||||
(args, unknown_args) = parser.parse_known_args (argv)
|
||||
unknown_args += rest_argv
|
||||
|
||||
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)
|
||||
|
||||
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)
|
@ -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)
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
||||
daemonize
|
||||
MySQL-python
|
||||
pyyaml
|
||||
sqlalchemy
|
||||
sqlalchemy_utils
|
@ -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"])]
|
||||
)
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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}
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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"
|
Loading…
Reference in New Issue
Block a user