Merge pull request #27 from uggla/properinstall
Review of installation process
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -41,6 +41,8 @@ htmlcov/
|
|||||||
.cache
|
.cache
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
coverage.xml
|
coverage.xml
|
||||||
|
redfish-client/tests/Dockerfile
|
||||||
|
redfish-client/tests/python-redfish.src.tar.gz
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
|
@@ -15,6 +15,7 @@ Contents:
|
|||||||
installation
|
installation
|
||||||
usage
|
usage
|
||||||
develsetup
|
develsetup
|
||||||
|
testing
|
||||||
classesdoc
|
classesdoc
|
||||||
contributing
|
contributing
|
||||||
help
|
help
|
||||||
|
@@ -10,9 +10,11 @@ Use::
|
|||||||
|
|
||||||
Pip will install :
|
Pip will install :
|
||||||
|
|
||||||
1. The library and all dependencies into your site-packages directory
|
1. The library and all dependencies into prefix/lib/pythonX.Y/site-packages directory
|
||||||
2. Redfish client master conf file into /etc/redfish_client.conf
|
2. Redfish client master conf file into prefix/etc/redfish_client.conf
|
||||||
3. Data file (templates) into /usr/share/redfish-client/templates
|
Unless if prefix = '/usr', in that case force configuration file to be in /etc
|
||||||
|
|
||||||
|
3. Data file (templates) into prefix/share/redfish-client/templates
|
||||||
|
|
||||||
Point 2 and 3 above need root access to your system. If you don't have root
|
Point 2 and 3 above need root access to your system. If you don't have root
|
||||||
access on your system, please follow `Using pip and virtualenv`_ section.
|
access on your system, please follow `Using pip and virtualenv`_ section.
|
||||||
@@ -45,7 +47,7 @@ Using pip and virtualenv
|
|||||||
|
|
||||||
4. Install using pip::
|
4. Install using pip::
|
||||||
|
|
||||||
pip install python-virtualenv
|
pip install python-redfish
|
||||||
|
|
||||||
All files are installed under your virtualenv.
|
All files are installed under your virtualenv.
|
||||||
|
|
||||||
@@ -55,7 +57,7 @@ Using the sources
|
|||||||
#. Follow `get the sources <http://pythonhosted.org/python-redfish/readme.html#get-the-sources>`_ section to retrieve the sources.
|
#. Follow `get the sources <http://pythonhosted.org/python-redfish/readme.html#get-the-sources>`_ section to retrieve the sources.
|
||||||
#. Install from the source using::
|
#. Install from the source using::
|
||||||
|
|
||||||
python setup.py install
|
python setup.py install --prefix="/usr/local"
|
||||||
|
|
||||||
|
|
||||||
Using rpm package
|
Using rpm package
|
||||||
|
25
doc/source/testing.rst
Normal file
25
doc/source/testing.rst
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
=============
|
||||||
|
Running tests
|
||||||
|
=============
|
||||||
|
|
||||||
|
|
||||||
|
redfish module tests
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Tests are not functional for the redfish module yet.
|
||||||
|
|
||||||
|
refish-client tests
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
#. Create your development environment following `Developer setup <develsetup.html>`_.
|
||||||
|
#. Install docker using the `procedure <https://docs.docker.com/engine/installation/>`_.
|
||||||
|
#. Ensure you can use docker with your current user.
|
||||||
|
#. Jump into redfish-python directory containing the sources.
|
||||||
|
#. Install required modules for testings::
|
||||||
|
|
||||||
|
pip install -t test-requirements.txt
|
||||||
|
|
||||||
|
#. Run the test::
|
||||||
|
|
||||||
|
py.test redfish-client
|
||||||
|
|
@@ -1,2 +1,2 @@
|
|||||||
[redfish-client]
|
[redfish-client]
|
||||||
templates_path = /usr/share/redfish-client/templates
|
templates_path = PBTEMPLATEPATH
|
||||||
|
@@ -19,7 +19,8 @@ redfish-client ::
|
|||||||
Options:
|
Options:
|
||||||
-h --help Show this screen.
|
-h --help Show this screen.
|
||||||
--version Show version.
|
--version Show version.
|
||||||
--conf_file FILE Configuration file [default: ~/.redfish.conf]
|
-c --config FILE Configuration file
|
||||||
|
-i --inventory FILE Configuration file [default: $HOME/.redfish.conf]
|
||||||
--insecure Ignore SSL certificates
|
--insecure Ignore SSL certificates
|
||||||
--debug LEVEL Run in debug mode, LEVEL from 1 to 3 increase verbosity
|
--debug LEVEL Run in debug mode, LEVEL from 1 to 3 increase verbosity
|
||||||
Security warning LEVEL > 1 could reveal password into the logs
|
Security warning LEVEL > 1 could reveal password into the logs
|
||||||
@@ -42,24 +43,25 @@ import jinja2
|
|||||||
import requests.packages.urllib3
|
import requests.packages.urllib3
|
||||||
import redfish
|
import redfish
|
||||||
|
|
||||||
class ConfigFile(object):
|
|
||||||
'''redfisht-client configuration file management'''
|
class InventoryFile(object):
|
||||||
def __init__(self, config_file):
|
'''redfisht-client inventory file management'''
|
||||||
'''Initialize the configuration file
|
def __init__(self, inventory_file):
|
||||||
|
'''Initialize the inventory file
|
||||||
|
|
||||||
Open and load configuration file data.
|
Open and load configuration file data.
|
||||||
If the file does not exist create an empty one ready to receive data
|
If the file does not exist create an empty one ready to receive data
|
||||||
|
|
||||||
:param config_file: File name of the configuration file
|
:param inventory_file: File name of the configuration file
|
||||||
default: ~/.redfish.conf
|
default: ~/.redfish.conf
|
||||||
:type config-file: str
|
:type config-file: str
|
||||||
:returns: Nothing
|
:returns: Nothing
|
||||||
|
|
||||||
'''
|
'''
|
||||||
self._config_file = config_file
|
self._inventory_file = inventory_file
|
||||||
# read json file
|
# read json file
|
||||||
try:
|
try:
|
||||||
with open(self._config_file) as json_data:
|
with open(self._inventory_file) as json_data:
|
||||||
self.data = json.load(json_data)
|
self.data = json.load(json_data)
|
||||||
json_data.close()
|
json_data.close()
|
||||||
except (ValueError, IOError):
|
except (ValueError, IOError):
|
||||||
@@ -68,7 +70,7 @@ class ConfigFile(object):
|
|||||||
def save(self):
|
def save(self):
|
||||||
'''Save the configuration file data'''
|
'''Save the configuration file data'''
|
||||||
try:
|
try:
|
||||||
with open(self._config_file, 'w') as json_data:
|
with open(self._inventory_file, 'w') as json_data:
|
||||||
json.dump(self.data, json_data)
|
json.dump(self.data, json_data)
|
||||||
json_data.close()
|
json_data.close()
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
@@ -141,7 +143,8 @@ class ConfigFile(object):
|
|||||||
self.manager_incorect(e)
|
self.manager_incorect(e)
|
||||||
elif parameter == 'password':
|
elif parameter == 'password':
|
||||||
try:
|
try:
|
||||||
self.data['Managers'][manager_name]['password'] = parameter_value
|
self.data['Managers'][manager_name]['password'] \
|
||||||
|
= parameter_value
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
self.manager_incorect(e)
|
self.manager_incorect(e)
|
||||||
elif parameter == 'manager_name':
|
elif parameter == 'manager_name':
|
||||||
@@ -209,7 +212,6 @@ class RedfishClientException(Exception):
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
'''Main application redfish-client'''
|
'''Main application redfish-client'''
|
||||||
# Functions
|
# Functions
|
||||||
|
|
||||||
def show_manager(all=False):
|
def show_manager(all=False):
|
||||||
'''Display manager info
|
'''Display manager info
|
||||||
|
|
||||||
@@ -219,16 +221,19 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
print('Managers configured :')
|
print('Managers configured :')
|
||||||
for manager in conf_file.get_managers():
|
if(not inventory.get_managers()):
|
||||||
|
print("None")
|
||||||
|
else:
|
||||||
|
for manager in inventory.get_managers():
|
||||||
print(manager)
|
print(manager)
|
||||||
if all is True:
|
if all is True:
|
||||||
info = conf_file.get_manager_info(manager)
|
info = inventory.get_manager_info(manager)
|
||||||
print('\tUrl : {}'.format(info['url']))
|
print('\tUrl : {}'.format(info['url']))
|
||||||
print('\tLogin : {}'.format(info['login']))
|
print('\tLogin : {}'.format(info['login']))
|
||||||
print('\tPassword : {}'.format(info['password']))
|
print('\tPassword : {}'.format(info['password']))
|
||||||
|
|
||||||
def get_manager_info(manager_name, check_SSL):
|
def get_manager_info(manager_name, check_SSL):
|
||||||
connection_parameters = conf_file.get_manager_info(manager_name)
|
connection_parameters = inventory.get_manager_info(manager_name)
|
||||||
if not connection_parameters['login']:
|
if not connection_parameters['login']:
|
||||||
simulator = True
|
simulator = True
|
||||||
enforceSSL = False
|
enforceSSL = False
|
||||||
@@ -256,14 +261,17 @@ if __name__ == '__main__':
|
|||||||
try:
|
try:
|
||||||
template = jinja2_env.get_template("manager_info.template")
|
template = jinja2_env.get_template("manager_info.template")
|
||||||
except jinja2.exceptions.TemplateNotFound as e:
|
except jinja2.exceptions.TemplateNotFound as e:
|
||||||
print('Template "{}" not found in {}.'.format(e.message, jinja2_env.loader.searchpath[0]))
|
print('Template "{}" not found in {}.'
|
||||||
logger.debug('Template "%s" not found in %s.' % (e.message, jinja2_env.loader.searchpath[0]))
|
.format(e.message, jinja2_env.loader.searchpath[0]))
|
||||||
|
logger.debug('Template "%s" not found in %s.'
|
||||||
|
% (e.message, jinja2_env.loader.searchpath[0]))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print template.render(r=remote_mgmt)
|
print template.render(r=remote_mgmt)
|
||||||
|
|
||||||
|
#################################################################
|
||||||
# Main program
|
# Main program
|
||||||
|
#################################################################
|
||||||
redfishclient_version = "redfish-client PBVER"
|
redfishclient_version = "redfish-client PBVER"
|
||||||
|
|
||||||
# Parse and manage arguments
|
# Parse and manage arguments
|
||||||
@@ -320,46 +328,42 @@ if __name__ == '__main__':
|
|||||||
logger.info("Arguments parsed")
|
logger.info("Arguments parsed")
|
||||||
logger.debug(arguments)
|
logger.debug(arguments)
|
||||||
|
|
||||||
# Get $HOME and $VIRTUAL_ENV environment variables.
|
# Get $HOME environment variables.
|
||||||
HOME = os.getenv('HOME')
|
HOME = os.getenv('HOME')
|
||||||
VIRTUAL_ENV = os.getenv('VIRTUAL_ENV')
|
|
||||||
|
|
||||||
if not HOME:
|
if(not HOME):
|
||||||
print('$HOME environment variable not set, please check your system')
|
print('$HOME environment variable not set, please check your system')
|
||||||
logger.error('$HOME environment variable not set')
|
logger.error('$HOME environment variable not set')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
logger.debug("Home directory : %s" % HOME)
|
logger.debug("Home directory : %s" % HOME)
|
||||||
|
|
||||||
if VIRTUAL_ENV:
|
# Load config
|
||||||
logger.debug("Virtual env : %s" % VIRTUAL_ENV)
|
|
||||||
|
|
||||||
# Load master conf file
|
|
||||||
config = ConfigParser.ConfigParser(allow_no_value=True)
|
config = ConfigParser.ConfigParser(allow_no_value=True)
|
||||||
logger.debug("Read master configuration file")
|
logger.debug("Read configuration file")
|
||||||
master_conf_file_path = "/etc/redfish-client.conf"
|
configfile = 'PBCONFFILE'
|
||||||
|
|
||||||
if VIRTUAL_ENV:
|
if(arguments['--config']):
|
||||||
logger.debug("Read master configuration file from virtual environment")
|
configfile = [arguments['--config']]
|
||||||
master_conf_file_path = VIRTUAL_ENV + master_conf_file_path
|
logger.debug("Overwrite configuration specified by user at %s"
|
||||||
|
% configfile)
|
||||||
|
|
||||||
if not os.path.isfile(master_conf_file_path):
|
if(os.path.isfile(configfile)):
|
||||||
print('Master configuration file not found at {}.'.format(master_conf_file_path))
|
logger.debug('Configuration found at %s.' % configfile)
|
||||||
logger.error('Master configuration file not found at %s.' % master_conf_file_path)
|
config.read(configfile)
|
||||||
|
else:
|
||||||
|
print('Configuration file not found at {}.'.format(configfile))
|
||||||
|
logger.error('Configuration file not found at %s.' % configfile)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
config.read(master_conf_file_path)
|
arguments['--inventory'] = arguments['--inventory'].replace('~', HOME)
|
||||||
|
arguments['--inventory'] = arguments['--inventory'].replace('$HOME', HOME)
|
||||||
arguments['--conf_file'] = arguments['--conf_file'].replace('~', HOME)
|
inventory = InventoryFile(arguments['--inventory'])
|
||||||
conf_file = ConfigFile(arguments['--conf_file'])
|
|
||||||
|
|
||||||
# Initialize Template system (jinja2)
|
# Initialize Template system (jinja2)
|
||||||
# TODO : set the template file location into cmd line default to /usr/share/python-redfish/templates ?
|
|
||||||
templates_path = config.get("redfish-client", "templates_path")
|
templates_path = config.get("redfish-client", "templates_path")
|
||||||
logger.debug("Initialize template system")
|
logger.debug("Initialize template system")
|
||||||
if VIRTUAL_ENV:
|
jinja2_env = jinja2.Environment(
|
||||||
logger.debug("Read templates file from virtual environment")
|
loader=jinja2.FileSystemLoader(templates_path))
|
||||||
templates_path = VIRTUAL_ENV + templates_path
|
|
||||||
jinja2_env = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_path))
|
|
||||||
|
|
||||||
# Check cmd line parameters
|
# Check cmd line parameters
|
||||||
if arguments['config'] is True:
|
if arguments['config'] is True:
|
||||||
@@ -372,37 +376,37 @@ if __name__ == '__main__':
|
|||||||
show_manager(True)
|
show_manager(True)
|
||||||
elif arguments['add'] is True:
|
elif arguments['add'] is True:
|
||||||
logger.debug('add command')
|
logger.debug('add command')
|
||||||
conf_file.add_manager(arguments['<manager_name>'],
|
inventory.add_manager(arguments['<manager_name>'],
|
||||||
arguments['<manager_url>'],
|
arguments['<manager_url>'],
|
||||||
arguments['<login>'],
|
arguments['<login>'],
|
||||||
arguments['<password>'])
|
arguments['<password>'])
|
||||||
logger.debug(conf_file.data)
|
logger.debug(inventory.data)
|
||||||
conf_file.save()
|
inventory.save()
|
||||||
elif arguments['del'] is True:
|
elif arguments['del'] is True:
|
||||||
logger.debug('del command')
|
logger.debug('del command')
|
||||||
conf_file.delete_manager(arguments['<manager_name>'])
|
inventory.delete_manager(arguments['<manager_name>'])
|
||||||
logger.debug(conf_file.data)
|
logger.debug(inventory.data)
|
||||||
conf_file.save()
|
inventory.save()
|
||||||
elif arguments['modify'] is True:
|
elif arguments['modify'] is True:
|
||||||
logger.debug('modify command')
|
logger.debug('modify command')
|
||||||
if arguments['url'] is not False:
|
if arguments['url'] is not False:
|
||||||
conf_file.modify_manager(arguments['<manager_name>'],
|
inventory.modify_manager(arguments['<manager_name>'],
|
||||||
'url',
|
'url',
|
||||||
arguments['<changed_value>'])
|
arguments['<changed_value>'])
|
||||||
elif arguments['login'] is not False:
|
elif arguments['login'] is not False:
|
||||||
conf_file.modify_manager(arguments['<manager_name>'],
|
inventory.modify_manager(arguments['<manager_name>'],
|
||||||
'login',
|
'login',
|
||||||
arguments['<changed_value>'])
|
arguments['<changed_value>'])
|
||||||
elif arguments['password'] is not False:
|
elif arguments['password'] is not False:
|
||||||
conf_file.modify_manager(arguments['<manager_name>'],
|
inventory.modify_manager(arguments['<manager_name>'],
|
||||||
'password',
|
'password',
|
||||||
arguments['<changed_value>'])
|
arguments['<changed_value>'])
|
||||||
elif arguments['manager_name'] is not False:
|
elif arguments['manager_name'] is not False:
|
||||||
conf_file.modify_manager(arguments['<manager_name>'],
|
inventory.modify_manager(arguments['<manager_name>'],
|
||||||
'manager_name',
|
'manager_name',
|
||||||
arguments['<changed_value>'])
|
arguments['<changed_value>'])
|
||||||
logger.debug(conf_file.data)
|
logger.debug(inventory.data)
|
||||||
conf_file.save()
|
inventory.save()
|
||||||
if arguments['manager'] is True:
|
if arguments['manager'] is True:
|
||||||
logger.debug("Manager commands")
|
logger.debug("Manager commands")
|
||||||
if arguments['getinfo'] is True:
|
if arguments['getinfo'] is True:
|
||||||
@@ -413,7 +417,7 @@ if __name__ == '__main__':
|
|||||||
else:
|
else:
|
||||||
manager_name = arguments['<manager_name>']
|
manager_name = arguments['<manager_name>']
|
||||||
# Check if the default section is available in our conf file
|
# Check if the default section is available in our conf file
|
||||||
conf_file.check_manager(manager_name)
|
inventory.check_manager(manager_name)
|
||||||
if arguments['--insecure'] is True:
|
if arguments['--insecure'] is True:
|
||||||
get_manager_info(manager_name, False)
|
get_manager_info(manager_name, False)
|
||||||
else:
|
else:
|
||||||
|
@@ -1 +1 @@
|
|||||||
redfish-client.py
|
redfish-client
|
13
redfish-client/tests/Dockerfile.debian
Normal file
13
redfish-client/tests/Dockerfile.debian
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FROM debian:jessie
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y apt-utils && \
|
||||||
|
apt-get install -y python-pip
|
||||||
|
COPY python-redfish.src.tar.gz /python-redfish.src.tar.gz
|
||||||
|
RUN mkdir /var/log/python-redfish
|
||||||
|
RUN tar xvvf python-redfish.src.tar.gz
|
||||||
|
RUN cd python-redfish* && \
|
||||||
|
pip install -r requirements.txt && \
|
||||||
|
python setup.py install
|
||||||
|
CMD ["/bin/bash"]
|
||||||
|
|
11
redfish-client/tests/Dockerfile.fedora
Normal file
11
redfish-client/tests/Dockerfile.fedora
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
FROM fedora:23
|
||||||
|
RUN dnf install -y python-pip && \
|
||||||
|
dnf install -y git && \
|
||||||
|
dnf install -y tar
|
||||||
|
COPY python-redfish.src.tar.gz /python-redfish.src.tar.gz
|
||||||
|
RUN mkdir /var/log/python-redfish
|
||||||
|
RUN tar xvvf python-redfish.src.tar.gz
|
||||||
|
RUN cd python-redfish* && \
|
||||||
|
pip install -r requirements.txt && \
|
||||||
|
python setup.py install
|
||||||
|
CMD ["/bin/bash"]
|
7
redfish-client/tests/Dockerfile.fedorapip
Normal file
7
redfish-client/tests/Dockerfile.fedorapip
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FROM fedora:23
|
||||||
|
RUN dnf install -y python-pip && \
|
||||||
|
dnf install -y git
|
||||||
|
RUN mkdir /var/log/python-redfish
|
||||||
|
RUN pip install python-redfish
|
||||||
|
CMD ["/bin/bash"]
|
||||||
|
|
13
redfish-client/tests/Dockerfile.ubuntu
Normal file
13
redfish-client/tests/Dockerfile.ubuntu
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FROM ubuntu:wily
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y apt-utils && \
|
||||||
|
apt-get install -y python-pip
|
||||||
|
COPY python-redfish.src.tar.gz /python-redfish.src.tar.gz
|
||||||
|
RUN mkdir /var/log/python-redfish
|
||||||
|
RUN tar xvvf python-redfish.src.tar.gz
|
||||||
|
RUN cd python-redfish* && \
|
||||||
|
pip install -r requirements.txt && \
|
||||||
|
python setup.py install
|
||||||
|
CMD ["/bin/bash"]
|
||||||
|
|
89
redfish-client/tests/test_client.py
Normal file
89
redfish-client/tests/test_client.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
import os
|
||||||
|
import stat
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
from docker import Client
|
||||||
|
from path import Path
|
||||||
|
|
||||||
|
|
||||||
|
class DockerTest():
|
||||||
|
def __init__(self):
|
||||||
|
self.cli = Client(base_url='unix://var/run/docker.sock')
|
||||||
|
|
||||||
|
def build(self, dockerfile):
|
||||||
|
dockerfile = Path(dockerfile)
|
||||||
|
tag = 'rf' + dockerfile.basename().replace('Dockerfile.', '')
|
||||||
|
dockerfile.copy('redfish-client/tests/Dockerfile')
|
||||||
|
response = [line for line in self.cli.build(
|
||||||
|
path='redfish-client/tests',
|
||||||
|
tag=tag,
|
||||||
|
rm=True)]
|
||||||
|
return(response)
|
||||||
|
|
||||||
|
def run(self, image, command):
|
||||||
|
container = self.cli.create_container(image=image,
|
||||||
|
command=command,
|
||||||
|
tty=True,
|
||||||
|
stdin_open=True)
|
||||||
|
self.cli.start(container=container.get('Id'))
|
||||||
|
self.cli.wait(container=container.get('Id'))
|
||||||
|
response = self.cli.logs(container=container.get('Id'),
|
||||||
|
stdout=True)
|
||||||
|
return(response)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dockersocket():
|
||||||
|
mode = os.stat('/var/run/docker.sock').st_mode
|
||||||
|
isSocket = stat.S_ISSOCK(mode)
|
||||||
|
assert isSocket, 'Make sure docker services are running'
|
||||||
|
|
||||||
|
|
||||||
|
def test_docker():
|
||||||
|
cli = Client(base_url='unix://var/run/docker.sock')
|
||||||
|
response = cli.containers()
|
||||||
|
assert isinstance(response, list), 'Ensure you have sufficiant' + \
|
||||||
|
'credentials to use docker with' + \
|
||||||
|
'your current user'
|
||||||
|
|
||||||
|
|
||||||
|
def test_sources():
|
||||||
|
output = subprocess.check_output(["python", "setup.py", "sdist"])
|
||||||
|
search = re.search(r"removing '(\S+)'", output)
|
||||||
|
filename = Path('dist/' + search.group(1) + '.tar.gz')
|
||||||
|
filename.copy('redfish-client/tests/python-redfish.src.tar.gz')
|
||||||
|
assert Path('redfish-client/tests/python-redfish.src.tar.gz').isfile()
|
||||||
|
|
||||||
|
|
||||||
|
def test_dockerbuild():
|
||||||
|
docker = DockerTest()
|
||||||
|
dockerfiles = ('redfish-client/tests/Dockerfile.ubuntu',
|
||||||
|
'redfish-client/tests/Dockerfile.debian',
|
||||||
|
'redfish-client/tests/Dockerfile.fedora',
|
||||||
|
'redfish-client/tests/Dockerfile.fedorapip')
|
||||||
|
for dockerfile in dockerfiles:
|
||||||
|
print('Testing : {}'.format(dockerfile))
|
||||||
|
response = docker.build(dockerfile)
|
||||||
|
status = response.pop()
|
||||||
|
assert 'Successfully built' in status
|
||||||
|
|
||||||
|
|
||||||
|
def test_install():
|
||||||
|
docker = DockerTest()
|
||||||
|
images = ('rfubuntu', 'rfdebian', 'rffedora', 'rffedorapip')
|
||||||
|
for img in images:
|
||||||
|
print('Testing : {}'.format(img))
|
||||||
|
response = docker.run(img, 'redfish-client config showall')
|
||||||
|
print(response)
|
||||||
|
assert ('Managers configured' in response and 'None' in response)
|
||||||
|
|
||||||
|
|
||||||
|
def test_versionformat():
|
||||||
|
docker = DockerTest()
|
||||||
|
images = ('rfubuntu', 'rfdebian', 'rffedora', 'rffedorapip')
|
||||||
|
for img in images:
|
||||||
|
print('Testing : {}'.format(img))
|
||||||
|
response = docker.run(img, 'redfish-client --version')
|
||||||
|
print(response)
|
||||||
|
assert (re.match('redfish-client \d+\.\d+', response))
|
||||||
|
|
@@ -18,7 +18,7 @@ from redfish.main import *
|
|||||||
#import redfish.types
|
#import redfish.types
|
||||||
|
|
||||||
try:
|
try:
|
||||||
__version__ = pbr.version.VersionInfo('redfish').version_string()
|
__version__ = pbr.version.VersionInfo('redfish').release_string()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
if "Versioning for this project requires either an sdist tarball" in e.message:
|
if "Versioning for this project requires either an sdist tarball" in e.message:
|
||||||
pass
|
pass
|
||||||
|
@@ -2,9 +2,7 @@
|
|||||||
# of appearance. Changing the order has an impact on the overall integration
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
|
|
||||||
pbr>=0.6,!=0.7,<1.0
|
pbr>=0.8
|
||||||
#oslo.log>=1.0,<2.0
|
|
||||||
Babel>=1.3
|
|
||||||
tortilla>=0.4.1
|
tortilla>=0.4.1
|
||||||
Jinja2>=2.7.3
|
Jinja2>=2.7.3
|
||||||
Sphinx>=1.2.3
|
Sphinx>=1.2.3
|
||||||
|
@@ -27,10 +27,9 @@ packages =
|
|||||||
scripts =
|
scripts =
|
||||||
redfish-client/redfish-client
|
redfish-client/redfish-client
|
||||||
|
|
||||||
data_files =
|
[data_files_helper]
|
||||||
usr/share/redfish-client/templates = redfish-client/templates/*
|
conf = 'redfish-client/etc/redfish-client.conf', 'etc'
|
||||||
etc/ = redfish-client/etc/*
|
templates = 'redfish-client/templates/*', 'share/redfish-client/templates'
|
||||||
|
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
source-dir = doc/source
|
source-dir = doc/source
|
||||||
|
203
setup.py
203
setup.py
@@ -1,21 +1,28 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
# implied.
|
# implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import fileinput
|
||||||
|
import re
|
||||||
|
import pprint
|
||||||
|
import distutils
|
||||||
|
import ConfigParser
|
||||||
import setuptools
|
import setuptools
|
||||||
|
from setuptools import Distribution
|
||||||
|
from setuptools.command.install import install
|
||||||
|
|
||||||
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||||
# setuptools if some other modules registered functions in `atexit`.
|
# setuptools if some other modules registered functions in `atexit`.
|
||||||
@@ -25,6 +32,192 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class OnlyGetScriptPath(install):
|
||||||
|
'''Extend setuptools install class and replace run method to go through
|
||||||
|
setuptool installation and retrieve the script path
|
||||||
|
'''
|
||||||
|
def run(self):
|
||||||
|
# does not call install.run() by design
|
||||||
|
self.distribution.install_scripts = self.install_scripts
|
||||||
|
|
||||||
|
|
||||||
|
class DataFilesHelper():
|
||||||
|
'''Class to help manage data files'''
|
||||||
|
def __init__(self):
|
||||||
|
'''Read setup.cfg and build the required data'''
|
||||||
|
self.data = {}
|
||||||
|
self.setupstruc = []
|
||||||
|
config = ConfigParser.ConfigParser()
|
||||||
|
config.read('setup.cfg')
|
||||||
|
for datafile in config.options('data_files_helper'):
|
||||||
|
src, dst = config.get('data_files_helper', datafile).split(',')
|
||||||
|
src = self.refinesrc(src)
|
||||||
|
dst = self.refinedst(dst)
|
||||||
|
self.data[datafile] = {'src': src,
|
||||||
|
'dst': dst,
|
||||||
|
'fdst': self.calculatedst(src, dst)}
|
||||||
|
self.update_setupstruc(src, dst)
|
||||||
|
try:
|
||||||
|
# Create an entry for scripts if available
|
||||||
|
src = config.get('files', 'scripts').split('\n')
|
||||||
|
src = [self.refinesrc(file)[0] for file in src if file]
|
||||||
|
self.data['script'] = {'src': src,
|
||||||
|
'dst': 'bin',
|
||||||
|
'fdst': self.calculatedst(src, 'bin')}
|
||||||
|
except ConfigParser.NoOptionError:
|
||||||
|
pass
|
||||||
|
pp = pprint.PrettyPrinter(indent=4)
|
||||||
|
pp.pprint(self.data)
|
||||||
|
|
||||||
|
def trim(self, string):
|
||||||
|
string = string.strip()
|
||||||
|
string = string.strip("'")
|
||||||
|
string = string.strip('"')
|
||||||
|
return(string)
|
||||||
|
|
||||||
|
def refinesrc(self, file):
|
||||||
|
'''Refine source:
|
||||||
|
Expend source file if needed
|
||||||
|
|
||||||
|
:param file: source files
|
||||||
|
:type file: string
|
||||||
|
:returns: source files refined
|
||||||
|
:rtype: list
|
||||||
|
'''
|
||||||
|
file = self.trim(file)
|
||||||
|
if(file.endswith('/*')):
|
||||||
|
return(self.getfiles(file.replace('/*', '')))
|
||||||
|
else:
|
||||||
|
return([file])
|
||||||
|
|
||||||
|
def refinedst(self, file):
|
||||||
|
'''Refine destination:
|
||||||
|
Check if destination needs an exception
|
||||||
|
|
||||||
|
:param file: destination
|
||||||
|
:type path: string
|
||||||
|
:returns: destination refined
|
||||||
|
:rtype: string
|
||||||
|
'''
|
||||||
|
file = self.trim(file)
|
||||||
|
if('etc' in file and self.getprefix() == '/usr'):
|
||||||
|
return('/etc')
|
||||||
|
else:
|
||||||
|
return(file)
|
||||||
|
|
||||||
|
def calculatedst(self, src, dst):
|
||||||
|
'''Calculate the full destination path accordind to source and
|
||||||
|
destination
|
||||||
|
|
||||||
|
:param src: source files
|
||||||
|
:type path: list
|
||||||
|
:param dst: destination path
|
||||||
|
:type path: string
|
||||||
|
:returns: files with full destination
|
||||||
|
:rtype: list
|
||||||
|
'''
|
||||||
|
destination = []
|
||||||
|
for file in src:
|
||||||
|
if(dst.startswith('/')):
|
||||||
|
destination.append(os.path.join(dst,
|
||||||
|
os.path.basename(file)))
|
||||||
|
else:
|
||||||
|
destination.append(os.path.join(self.getprefix(),
|
||||||
|
dst,
|
||||||
|
os.path.basename(file)))
|
||||||
|
return(destination)
|
||||||
|
|
||||||
|
def getfiles(self, path):
|
||||||
|
'''Retrieve file list within a directory
|
||||||
|
|
||||||
|
:param path: directory path
|
||||||
|
:type path: string
|
||||||
|
:returns: file list
|
||||||
|
:rtype: list
|
||||||
|
'''
|
||||||
|
for root, dirs, files in os.walk(path):
|
||||||
|
file_list = [os.path.join(root, file) for file in files]
|
||||||
|
return(file_list)
|
||||||
|
|
||||||
|
def getprefix(self):
|
||||||
|
'''Retrieve setup tool calculated prefix
|
||||||
|
|
||||||
|
:returns: prefix
|
||||||
|
:rtype: string
|
||||||
|
'''
|
||||||
|
dist = Distribution({'cmdclass': {'install': OnlyGetScriptPath}})
|
||||||
|
dist.dry_run = True # not sure if necessary, but to be safe
|
||||||
|
dist.parse_config_files()
|
||||||
|
try:
|
||||||
|
dist.parse_command_line()
|
||||||
|
except (distutils.errors.DistutilsArgError, AttributeError):
|
||||||
|
pass
|
||||||
|
command = dist.get_command_obj('install')
|
||||||
|
command.ensure_finalized()
|
||||||
|
command.run()
|
||||||
|
prefix = dist.install_scripts.replace('/bin', '')
|
||||||
|
return prefix
|
||||||
|
|
||||||
|
def update_setupstruc(self, src, dst):
|
||||||
|
'''Create/update structure for setuptools.setup()
|
||||||
|
like the following example.
|
||||||
|
|
||||||
|
[('etc/', ['redfish-client/etc/redfish-client.conf']),
|
||||||
|
('share/redfish-client/templates',
|
||||||
|
['redfish-client/templates/manager_info.template',
|
||||||
|
'redfish-client/templates/bla.template'])]
|
||||||
|
'''
|
||||||
|
self.setupstruc.append((dst, src))
|
||||||
|
|
||||||
|
def getsetupstruc(self):
|
||||||
|
'''Retrieve setup structure compatible with setuptools.setup()
|
||||||
|
This is only to encapsulatate setupstruc property
|
||||||
|
|
||||||
|
:returns: datafiles source and destination
|
||||||
|
:rtype: setuptools structure
|
||||||
|
'''
|
||||||
|
return(self.setupstruc)
|
||||||
|
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# Functions
|
||||||
|
##########################################
|
||||||
|
def replaceAll(file, searchExp, replaceExp):
|
||||||
|
for line in fileinput.input(file, inplace=1):
|
||||||
|
if searchExp in line:
|
||||||
|
line = line.replace(searchExp, replaceExp)
|
||||||
|
sys.stdout.write(line)
|
||||||
|
|
||||||
|
|
||||||
|
def getversion():
|
||||||
|
with open("python_redfish.egg-info/PKG-INFO", "r") as f:
|
||||||
|
output = f.read()
|
||||||
|
s = re.search(r'\nVersion:\s+(\S+)', output)
|
||||||
|
return(s.group(1))
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# START
|
||||||
|
##########################################
|
||||||
|
|
||||||
|
datafiles = DataFilesHelper()
|
||||||
|
|
||||||
|
# Install software
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
setup_requires=['pbr'],
|
setup_requires=['pbr'],
|
||||||
pbr=True)
|
pbr=True,
|
||||||
|
data_files=datafiles.getsetupstruc())
|
||||||
|
|
||||||
|
|
||||||
|
if('install' in sys.argv):
|
||||||
|
# Update conf files
|
||||||
|
for file in datafiles.data['conf']['fdst']:
|
||||||
|
print('Update : {}'.format(file))
|
||||||
|
replaceAll(file, 'PBTEMPLATEPATH',
|
||||||
|
os.path.dirname(datafiles.data['templates']['fdst'][0]))
|
||||||
|
# Update script files
|
||||||
|
for file in datafiles.data['script']['fdst']:
|
||||||
|
print('Update : {}'.format(file))
|
||||||
|
replaceAll(file, 'PBCONFFILE', datafiles.data['conf']['fdst'][0])
|
||||||
|
replaceAll(file, 'PBVER', getversion())
|
||||||
|
|
||||||
|
@@ -2,14 +2,8 @@
|
|||||||
# of appearance. Changing the order has an impact on the overall integration
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
|
|
||||||
hacking<0.11,>=0.10.0
|
pytest>=2.6.4
|
||||||
|
|
||||||
coverage>=3.6
|
coverage>=3.6
|
||||||
discover
|
mock>=1.0.1
|
||||||
python-subunit>=0.0.18
|
docker-py>=1.1.0
|
||||||
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
|
path.py>=5.2
|
||||||
#oslosphinx>=2.2.0 # Apache-2.0
|
|
||||||
#oslotest>=1.2.0 # Apache-2.0
|
|
||||||
testrepository>=0.0.18
|
|
||||||
testscenarios>=0.4
|
|
||||||
testtools>=0.9.36,!=1.2.0
|
|
||||||
|
Reference in New Issue
Block a user