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
|
https://launchpad.net/molteniron
|
||||||
--------
|
|
||||||
|
|
||||||
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}
|
|
||||||
```
|
|
||||||
|
@ -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