Commit 1546d0cd authored by Cédric de Saint Martin's avatar Cédric de Saint Martin

Merge branch 'slaprename'

Conflicts:
	slapos/grid/slapgrid.py
parents ab134d2e 2f696152
=========================
SlapOS command line usage
=========================
Note:
-----
* Default configuration file of "Node" commands (slapos node, slapos supervisor) is:
/etc/opt/slapos/slapos.cfg
* Default configuration file of "Client" commands (slapos request, slapos supply, ...) is:
~/.slapos/slapos.cfg
* Default log file for Node commands is /var/log/[slapos-node-software.log | slapos-node-instance.log | slapos-node-report.log]. This one requires working log in slapgrid, currently log/console is a total mess.
* Default pid file for Node commands is: /var/run/[slapos-node-software.pid | slapos-node-instance.pid | slapos-node-report.pid].
* Default SlapOS Master is http://www.vifib.net. It can be changed by altering configuration files.
General commands
----------------
slapos
~~~~~~
Display help/usage.
SlapOS Client commands
----------------------
Those commands are used by clients (as human beings or programs) to manage their own instances.
slapos request
~~~~~~~~~~~~~~
Usage:
slapos request [slapos_configuration] <reference> <software_alias | software-url> [--node id=<computer guid>,region=<region>,network-type=<newtork> | location/to/node.json] [--configuration foo=value1,bar=value2 | location/to/configuration.json ] [--type type] [--slave]
Request an instance and get status and parameters of instance.
Examples:
* Request a wordpress instance named "mybeautifulinstance" on Node named "COMP-12345":
slapos request wordpress mybeautifulinstance --node id=COMP-12345
XXX Change in slaplib: allow to fetch instance params without changing anything. i.e we should do "slapos request myalreadyrequestedinstance" to fetch connection parameters without erasing previously defined instance parameters.
slapos search
~~~~~~~~~~~~~
Usage:
slapos search <search parameters ex. computer region, instance reference, source_section, etc.>
Returns visible instances matching search parameters.
slapos supply
~~~~~~~~~~~~~
Usage:
slapos supply <software | software_group> <computer_guid | commputer_group>
Ask installation of a software on a specific node or group of nodes. Nodes will then be ready to accept instances of specified software.
Examples:
* Ask installation of wordpress Software Release on COMP-12345:
slapos supply wordpress COMP-12345
slapos autosupply
~~~~~~~~~~~~~~~~~
Usage:
slapos autosupply <software | software_group> <computer_guid | computer_group>
Like "slapos suppply", but on-demand. Software will be (re)installed only when at least one instance of this software is requested. When no instance of this software is deployed on the node, it will be uninstalled.
slapos console
~~~~~~~~~~~~~~
Enter in a python console with slap library imported. See "Slapconsole" section to have detailed documentation.
slapos <stop|start|destroy>
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Usage:
slapos <stop|start|destroy> <instance reference>
Ask start/stop/destruction of selected instance.
Example:
* Ask to stop "mywordpressinstance":
slapos stop mywordpressinstance
SlapOS Node commands
--------------------
This kind of commands are used to control the current SlapOS Node. Those commands are only useful for administrators of Nodes.
slapos node
~~~~~~~~~~~
Display status of Node and if not started, launch supervisor daemon.
Temporary note: equivalent of old slapgrid-supervisord + slapgrid-supervisorctl.
slapos node register
~~~~~~~~~~~~~~~~~~~~
Usage:
******
::
slapos node register <DESIRED NODE NAME> [--login LOGIN [--password PASSWORD]] [--interface-name INTERFACE] [--master-url URL <--master-url-web URL>] [--partition-number NUMBER] [--ipv4-local-network NETWORK] [--ipv6-interface INTERFACE] [--create-tap] [--dry-run]
If login is not provided, asks for user's vifib account then password.
Node will register itself, if not already done, to the SlapOS Master defined in configuration file, and will generate SlapOS configuration file.
XXX-Cedric should be like this: If desired node name is already taken, will raise an error.
XXX-Cedric: --master-url-web url will disappear in REST API. Currently, "register" uses SlapOS master web URL to register computer, so it needs the web URL (like http://www.vifib.net)
If Node is already registered (slapos.cfg and certificate already present), issues a warning, backups original configuration and creates new one.
XXX-Cedric should check for IPv6 in selected interface
Parameters:
***********
--login LOGIN Your SlapOS Master login. If not provided, asks it interactively.
--password PASSWORD Your SlapOS Master password. If not provided, asks it interactively. NOTE: giving password as parameter should be avoided for security reasons.
--interface-name INTERFACE Use interface as primary interface. IP of Partitions will be added to it. Defaults to "eth0".
--master-url URL URL of SlapOS Master REST API. defaults to "https://slap.vifib.com".
--master-url-web URL URL of SlapOS Master web access. defaults to "https://www.vifib.com".
--partition-number NUMBER Number of partitions that will have your SlapOS Node. defaults to "10".
--ipv4-local-network NETWORK Subnetwork used to assign local IPv4 addresses. It should be a not used network in order to avoid conflicts. defaults to 10.0.0.0/16.
-t, --create-tap Will trigger creation of one virtual "tap" interface per Partition and attach it to primary interface. Requires primary interface to be a bridge. defaults to false. Needed to host virtual machines.
-n, --dry-run Don't touch to anything in the filesystem. Used to debug.
Notes:
******
* "IPv6 interface" and "create tap" won't be put at all in the SlapOS Node configuration file if not explicitly written.
Examples:
*********
* Register computer named "mycomputer" to vifib::
slapos node register mycomputer
* Register computer named "mycomputer" to vifib using br0 as primary interface, tap0 as IPv6 interface and different local ipv4 subnet::
slapos node register mycomputer --interface-name br0 --ipv6-interface tap0 --ipv4-local-network 11.0.0.0/16
* Register computer named "mycomputer" to another SlapOS master accessible via https://www.myownslaposmaster.com, and SLAP webservice accessible via https://slap.myownslaposmaster.com (Note that this address should be the "slap" webservice URL, not web URL)::
slapos node register mycomputer --master-url https://slap.myownslaposmaster.com --master-url-web https://www.myownslaposmaster.com
XXX-Cedric : To be implemented
* Register computer named "mycomputer" to vifib, and ask to create tap interface to be able to host KVMs::
slapos node register mycomputer --create-tap
slapos node software
~~~~~~~~~~~~~~~~~~~~
Run software installation/deletion.
Temporary note: equivalent of old slapgrid-sr.
slapos node instance
~~~~~~~~~~~~~~~~~~~~
Run instance deployment
Temporary note: equivalent of old slapgrid-cp.
slapos node report
~~~~~~~~~~~~~~~~~~
Run instance reports and garbage collection.
Temporary note: equivalent of old slapgrid-cp.
slapos node <start|stop|tail|status>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Usage:
slapos node <start|stop|tail|status> <instance>:[process]
Start/Stop/Show stdout/stderr of instance and/or process.
Examples:
* Start all processes of slappart3:
slapos node start slappart3:
* Stop only apache in slappart1:
slapos node stop slappart1:apache
* Show stdout/stderr of mysqld in slappart2:
slapos node tail slappart2:mysqld
slapos node log
~~~~~~~~~~~~~~~
Usage:
slapos node log <software|instance|report>
Display log.
...@@ -47,8 +47,11 @@ setup(name=name, ...@@ -47,8 +47,11 @@ setup(name=name,
# accessing templates # accessing templates
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'slapconsole = slapos.console:run', # One entry point to control them all
'slapos-request = slapos.console:request', 'slapos = slapos.entry:main',
# Deprecated entry points
'slapconsole = slapos.client:run',
'slapos-watchdog = slapos.grid.watchdog:main',
'slapformat = slapos.format:main', 'slapformat = slapos.format:main',
'slapgrid = slapos.grid.slapgrid:run', 'slapgrid = slapos.grid.slapgrid:run',
'slapgrid-sr = slapos.grid.slapgrid:runSoftwareRelease', 'slapgrid-sr = slapos.grid.slapgrid:runSoftwareRelease',
...@@ -58,8 +61,6 @@ setup(name=name, ...@@ -58,8 +61,6 @@ setup(name=name,
'slapgrid-supervisord = slapos.grid.svcbackend:supervisord', 'slapgrid-supervisord = slapos.grid.svcbackend:supervisord',
'slapproxy = slapos.proxy:main', 'slapproxy = slapos.proxy:main',
'bang = slapos.bang:main', 'bang = slapos.bang:main',
'slapos = slapos.entry:main',
'slapos-watchdog = slapos.grid.watchdog:main',
] ]
}, },
test_suite="slapos.tests", test_suite="slapos.tests",
......
console console
======= -------
The slapconsole tool allows to interact with a SlapOS Master throught the SLAP The slapconsole tool allows to interact with a SlapOS Master throught the SLAP
library. library.
For more information about SlapOS or slapconsole usages, please go to For more information about SlapOS or slapconsole usages, please go to
http://www.slapos.org. http://community.slapos.org.
The slapconsole tool is only a bare Python console with several global variables The slapconsole tool is only a bare Python console with several global variables
defined and initialized. defined and initialized.
Initialization and configuration file Initialization and configuration file
===== ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Slapconsole allows to automatically connect to a Master using URL and SSL Slapconsole allows to automatically connect to a Master using URL and SSL
certificate from given slapos.cfg. certificate from given slapos.cfg.
Certificate has to be *USER* certificate, manually obtained from SlapOS master Certificate has to be *USER* certificate, manually obtained from SlapOS master
...@@ -20,6 +21,7 @@ web interface. ...@@ -20,6 +21,7 @@ web interface.
Slapconsole tools reads the given slapos.cfg configuration file and use the Slapconsole tools reads the given slapos.cfg configuration file and use the
following informations : following informations :
* Master URL is read from [slapos] in the "master_url" parameter. * Master URL is read from [slapos] in the "master_url" parameter.
* SSL Certificate is read from [slapconsole] in the "cert_file" parameter. * SSL Certificate is read from [slapconsole] in the "cert_file" parameter.
* SSL Key is read from [slapconsole] in the "key_file" parameter. * SSL Key is read from [slapconsole] in the "key_file" parameter.
...@@ -28,7 +30,8 @@ See slapos.cfg.example for examples. ...@@ -28,7 +30,8 @@ See slapos.cfg.example for examples.
Global functions Global functions
===== ~~~~~~~~~~~~~~~~
* request() is a shorthand for slap.registerOpenOrder().request() allowing * request() is a shorthand for slap.registerOpenOrder().request() allowing
to request instances. to request instances.
* supply() is a shorthand for slap.registerSupply().supply() allowing to * supply() is a shorthand for slap.registerSupply().supply() allowing to
...@@ -39,33 +42,44 @@ documentation. ...@@ -39,33 +42,44 @@ documentation.
Global aliases Global aliases
===== ~~~~~~~~~~~~~~
"software_list" is a list containing all the Software Release URLs defined in "software_list" is a list containing all the Software Release URLs defined in
client slapos.cfg configuration file. client slapos.cfg configuration file.
Also, each Software Release defined in this configuration file is translated Also, each Software Release defined in this configuration file is translated
into a global variable to ease the request of those Sofware Releases. into a global variable to ease the request of those Sofware Releases.
This allows to request instances in a few words, i.e This allows to request instances in a few words, i.e::
request("http://www.url.com/path/to/kvm/software.cfg", "mykvm")
can be simplified into : request("http://www.url.com/path/to/kvm/software.cfg", "mykvm")
request(kvm, "mykvm")
If the slapos.cfg file contains : can be simplified into ::
alias =
request(kvm, "mykvm")
If the slapos.cfg file contains ::
alias =
kvm http://www.url.com/path/to/kvm/software.cfg kvm http://www.url.com/path/to/kvm/software.cfg
Global objects Global objects
===== ~~~~~~~~~~~~~~
"slap" is an instance of the SLAP library. It is only used for advanced usages. "slap" is an instance of the SLAP library. It is only used for advanced usages.
"slap" instance is obtained by doing : "slap" instance is obtained by doing ::
slap = slapos.slap.slap()
slap.initializeConnection(config.master_url, slap = slapos.slap.slap()
slap.initializeConnection(config.master_url,
key_file=config.key_file, cert_file=config.cert_file) key_file=config.key_file, cert_file=config.cert_file)
Examples Examples
===== ~~~~~~~~
::
>>> # Request instance >>> # Request instance
>>> request(kvm, "myuniquekvm") >>> request(kvm, "myuniquekvm")
......
...@@ -27,13 +27,14 @@ ...@@ -27,13 +27,14 @@
# #
############################################################################## ##############################################################################
import slapos.slap.slap import argparse
import ConfigParser
import pprint
from optparse import OptionParser, Option
import os
from slapos.slap import ResourceNotReady from slapos.slap import ResourceNotReady
import slapos.slap.slap
import sys import sys
import os
from optparse import OptionParser, Option
import ConfigParser
class Parser(OptionParser): class Parser(OptionParser):
""" """
...@@ -69,16 +70,49 @@ class Parser(OptionParser): ...@@ -69,16 +70,49 @@ class Parser(OptionParser):
return options, args return options, args
class RequestParser(Parser):
def check_args(self): def argToDict(element):
""" """
Check arguments convert a table of string 'key=value' to dict
""" """
(options, args) = Parser.check_args(self) if element is not None:
if len(args) < 3: element_dict = dict([arg.split('=') for arg in element])
self.error("Incorrect number of arguments") return element_dict
def check_request_args():
"""
Parser for request
"""
parser = argparse.ArgumentParser()
parser.add_argument("configuration_file",
nargs=1,
help="SlapOS configuration file.")
parser.add_argument("reference",
help="Your instance reference")
parser.add_argument("software_url",
help="Your software url")
parser.add_argument("--node",
nargs = '*',
help = "Node request option "
"'option1=value1 option2=value2'")
parser.add_argument("--type",
type = str,
help = "Define software type to be requested")
parser.add_argument("--slave",
action = "store_true", default=False,
help = "Ask for a slave instance")
parser.add_argument("--configuration",
nargs = '*',
help = "Give your configuration "
"'option1=value1 option2=value2'")
args = parser.parse_args()
# Convert to dict
if args.configuration is not None:
args.configuration = argToDict(args.configuration)
if args.node is not None:
args.node = argToDict(args.node)
return args
return options, args
class Config: class Config:
def setConfig(self, option_dict, configuration_file_path): def setConfig(self, option_dict, configuration_file_path):
...@@ -103,11 +137,17 @@ class Config: ...@@ -103,11 +137,17 @@ class Config:
setattr(self, key, configuration_dict[key]) setattr(self, key, configuration_dict[key])
configuration_dict = dict(configuration_parser.items('slapos')) configuration_dict = dict(configuration_parser.items('slapos'))
master_url = configuration_dict.get('master_url', None) master_url = configuration_dict.get('master_url', None)
# Backward compatibility, if no key and certificate given in option
# take one from slapos configuration
if not getattr(self, 'key_file', None) and \
not getattr(self, 'cert_file', None):
self.key_file = configuration_dict.get('key_file')
self.cert_file = configuration_dict.get('cert_file')
if not master_url: if not master_url:
raise ValueError("No option 'master_url'") raise ValueError("No option 'master_url'")
elif master_url.startswith('https') and \ elif master_url.startswith('https') and \
not getattr(self, 'key_file', None) and \ self.key_file is None and \
not getattr(self, 'cert_file', None): self.cert_file is None:
raise ValueError("No option 'key_file' and/or 'cert_file'") raise ValueError("No option 'key_file' and/or 'cert_file'")
else: else:
setattr(self, 'master_url', master_url) setattr(self, 'master_url', master_url)
...@@ -134,15 +174,10 @@ def init(config): ...@@ -134,15 +174,10 @@ def init(config):
# Create global variable too see available aliases # Create global variable too see available aliases
local['software_list'] = software_list local['software_list'] = software_list
# Create global shortcut functions to request instance and software # Create global shortcut functions to request instance and software
# XXX-Cedric : can we change given parameters to something like def shorthandRequest(*args, **kwargs):
# *args, **kwargs, but without the bad parts, in order to be generic? return slap.registerOpenOrder().request(*args, **kwargs)
def shorthandRequest(software_release, partition_reference, def shorthandSupply(*args, **kwargs):
partition_parameter_kw=None, software_type=None, filter_kw=None, return slap.registerSupply().supply(*args, **kwargs)
state=None):
return slap.registerOpenOrder().request(software_release, partition_reference,
partition_parameter_kw, software_type, filter_kw, state)
def shorthandSupply(software_release, computer_guid=None, state='available'):
return slap.registerSupply().supply(software_release, computer_guid, state)
local['request'] = shorthandRequest local['request'] = shorthandRequest
local['supply'] = shorthandSupply local['supply'] = shorthandSupply
...@@ -150,31 +185,30 @@ def init(config): ...@@ -150,31 +185,30 @@ def init(config):
def request(): def request():
"""Ran when invoking slapos-request""" """Ran when invoking slapos-request"""
# Parse arguments # Parse arguments and inititate needed parameters
usage = """usage: %s [options] CONFIGURATION_FILE SOFTWARE_INSTANCE INSTANCE_REFERENCE usage = """usage: %s [options] CONFIGURATION_FILE INSTANCE_REFERENCE SOFTWARE_INSTANCE
slapos-request allows you to request slapos instances.""" % sys.argv[0] slapos-request allows you to request slapos instances.""" % sys.argv[0]
config = Config() config = Config()
options, arguments = RequestParser(usage=usage).check_args() options = check_request_args()
config.setConfig(options, arguments[0]) config.setConfig(options, options.configuration_file)
local = init(config) local = init(config)
# Request instance # Request instance
# XXX-Cedric : support things like : print("Requesting %s..." % config.software_url)
# --instance-type std --configuration-size 23 --computer-region europe/france if config.software_url in local:
# XXX-Cedric : add support for xml_parameter config.software_url = local[config.software_url]
software_url = arguments[1]
partition_reference = arguments[2]
print("Requesting %s..." % software_url)
if software_url in local:
software_url = local[software_url]
try: try:
partition = local['slap'].registerOpenOrder().request(software_url, partition = local['slap'].registerOpenOrder().request(
partition_reference) software_release = config.software_url,
print("Instance requested.\nState is : %s.\nYou can " partition_reference = config.reference,
"rerun to get up-to-date informations." % ( partition_parameter_kw = config.configuration,
partition.getState())) software_type = config.type,
# XXX-Cedric : provide a way for user to fetch parameter, url, object, etc filter_kw = config.node,
shared = config.slave
)
print "Instance requested.\nState is : %s." % partition.getState()
print "Connection parameters of instance are:"
pprint.pprint(partition.getConnectionParameterDict())
print "You can rerun command to get up-to-date informations."
except ResourceNotReady: except ResourceNotReady:
print("Instance requested. Master is provisionning it. Please rerun in a " print("Instance requested. Master is provisionning it. Please rerun in a "
"couple of minutes to get connection informations") "couple of minutes to get connection informations")
......
...@@ -26,19 +26,145 @@ ...@@ -26,19 +26,145 @@
# #
############################################################################## ##############################################################################
import argparse
import ConfigParser
import os
import sys import sys
from register.register import main as node_register from slapos.bang import main as bang
from slapos.client import run as console
from slapos.client import request as request
from slapos.format import main as format
from slapos.grid.slapgrid import runComputerPartition as instance
from slapos.grid.slapgrid import runSoftwareRelease as software
from slapos.grid.slapgrid import runUsageReport as report
from slapos.grid.svcbackend import supervisord
from slapos.grid.svcbackend import supervisorctl
from slapos.register.register import main as register
GLOBAL_SLAPOS_CONFIGURATION = '/etc/opt/slapos/slapos.cfg'
USER_SLAPOS_CONFIGURATION = '~/.slapos/slapos.cfg'
class EntryPointNotImplementedError(NotImplementedError):
def __init__(self, *args, **kw_args):
NotImplementedError.__init__(self, *args, **kw_args)
def checkSlaposCfg ():
"""
Check if a slapos configuration file was given as a argument.
If a slapos configuration file is given it return True else False
"""
# XXX-Cedric: dangerous but quick way to achieve way to not provide
# configuration file for each command without changing underlying code.
# It the long term, it should be done in a better way (no guessing).
for element in sys.argv:
if '.cfg' in element:
if os.path.exists(element):
configuration = ConfigParser.SafeConfigParser()
configuration.read(element)
if configuration.has_section('slapos'):
return True
return False
def checkOption(option):
"""
Check if a given option is already in call line
Add it and its values if missing
"""
option = option.split()
key = option[0]
for element in sys.argv:
if key in element:
return True
sys.argv.append(key)
if len(option) > 1 :
sys.argv = sys.argv + option[1:]
return True
def call(fun, config=False, option=[]):
"""
Add missing options to sys.argv
Add config if asked and it is missing
Call function fun
"""
for element in option:
checkOption(element)
if config:
if not checkSlaposCfg():
sys.argv = [sys.argv[0]] + [config] + sys.argv[1:]
fun()
sys.exit(0)
def dispatch(command, is_node_command):
""" Dispatch to correct SlapOS module.
Here we could use introspection to get rid of the big "if" statements,
but we want to control every input.
Here we give default option and configuration file if they are needed, i.e
If configuration file is not given: define it arbitrarily, and so on.
"""
if is_node_command:
if command == 'register':
call(register)
elif command == 'software':
call(software, config=GLOBAL_SLAPOS_CONFIGURATION,
option=['--pidfile /opt/slapos/slapgrid-sr.pid', '-c'])
elif command == 'instance':
call(instance, config=GLOBAL_SLAPOS_CONFIGURATION,
option=['--pidfile /opt/slapos/slapgrid-cp.pid', '-c'])
elif command == 'report':
call(report, config=GLOBAL_SLAPOS_CONFIGURATION,
option=['--pidfile /opt/slapos/slapgrid-ur.pid', '-c'])
elif command == 'bang':
call(bang, config=True)
elif command == 'format':
call(format, config=GLOBAL_SLAPOS_CONFIGURATION,
option=['--log_file /opt/slapos/slapformat.log'])
elif command in ['start', 'stop', 'status', 'tail']:
supervisord()
supervisorctl()
else:
return False
elif command == 'request':
call(request, config=USER_SLAPOS_CONFIGURATION)
elif command == 'supply':
raise EntryPointNotImplementedError(command)
elif command == 'start':
raise EntryPointNotImplementedError(command)
elif command == 'stop':
raise EntryPointNotImplementedError(command)
elif command == 'console':
console()
else:
return False
def main(): def main():
if len(sys.argv) < 3: """
print "Usage: slapos node register NODE_NAME [options]" Main entry point of SlapOS Node. Used to dispatch commands to python
print "%s: error: Incorrect number of arguments" % sys.argv[0] module responsible of the operation.
return 0 """
"Run default configuration." # XXX-Cedric: add "description" for parser.
if sys.argv[1] == "node" and sys.argv[2] == "register": # Parse arguments
sys.argv=sys.argv[2:] parser = argparse.ArgumentParser()
node_register() parser.add_argument('command')
else : # XXX-Cedric: "slapos node" should display "supervisorctl status".
print "Usage: slapos node register NODE_NAME [options]" # Currently it does nothing
print "%s: error: Incorrect arguments" % sys.argv[0] parser.add_argument('argument_list', nargs=argparse.REMAINDER)
# If "node" arg is the first: we strip it and set a switch
if len(sys.argv) > 1 and sys.argv[1] == "node":
sys.argv = sys.argv[1:]
is_node = True
else:
is_node = False
namespace = parser.parse_args()
# Set sys.argv for the sub-entry point that we will call
command_line = [namespace.command]
command_line.extend(namespace.argument_list)
sys.argv = command_line
try:
if not dispatch(namespace.command, is_node):
parser.print_help()
sys.exit(1)
except EntryPointNotImplementedError, exception:
print 'Not yet implemented: %s. Please use old-style commands.' % exception
...@@ -70,6 +70,9 @@ MANDATORY_PARAMETER_LIST = [ ...@@ -70,6 +70,9 @@ MANDATORY_PARAMETER_LIST = [
COMPUTER_PARTITION_DESTROYED_STATE = 'destroyed' COMPUTER_PARTITION_DESTROYED_STATE = 'destroyed'
# XXX hardcoded watchdog_path
WATCHDOG_PATH = '/opt/slapos/bin/watchdog'
def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple): def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple):
"""Parses arguments either from command line, from method parameters or from """Parses arguments either from command line, from method parameters or from
config file. Then returns a new instance of slapgrid.Slapgrid with those config file. Then returns a new instance of slapgrid.Slapgrid with those
...@@ -451,11 +454,9 @@ class Slapgrid(object): ...@@ -451,11 +454,9 @@ class Slapgrid(object):
computer_partition_filter_list.split(",") computer_partition_filter_list.split(",")
self.maximum_periodicity = maximum_periodicity self.maximum_periodicity = maximum_periodicity
self.force_periodicity = force_periodicity self.force_periodicity = force_periodicity
# XXX hardcoded watchdog_path
self.watchdog_path = '/opt/slapos/bin/slapos-watchdog'
def getWatchdogLine(self): def getWatchdogLine(self):
invocation_list = [self.watchdog_path] invocation_list = [WATCHDOG_PATH]
invocation_list.append("--master-url '%s' " % self.master_url) invocation_list.append("--master-url '%s' " % self.master_url)
if self.key_file is not None and self.cert_file is not None: if self.key_file is not None and self.cert_file is not None:
invocation_list.append("--cert-file %s" % self.cert_file) invocation_list.append("--cert-file %s" % self.cert_file)
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import os
import shutil
import slapos.entry as entry
import sys
import tempfile
import unittest
class BasicMixin:
def setUp(self):
self._tempdir = tempfile.mkdtemp()
self._original_sys_argv = sys.argv
sys.argv = ['entry']
def tearDown(self):
shutil.rmtree(self._tempdir, True)
sys.argv = self._original_sys_argv
class TestcheckSlaposCfg (BasicMixin, unittest.TestCase):
"""
Tests on checkSlaposCfg function
"""
def test_slapos_cfg_detection_when_no_configuration_given(self):
"""
If no configuration file is given then False is return
"""
sys.argv = ['entry', '--logfile', '/log/file']
self.assertFalse(entry.checkSlaposCfg())
def test_slapos_cfg_detection_when_file_does_not_exists(self):
"""
If given configuration file does not exists then False is return
"""
slapos_cfg = os.path.join(self._tempdir, 'slapos.cfg')
sys.argv = ['entry', slapos_cfg]
self.assertFalse(entry.checkSlaposCfg())
def test_slapos_cfg_detection_when_no_slapos_section(self):
"""
If given configuration file does not have slapos section
then False is return
"""
slapos_cfg = os.path.join(self._tempdir, 'slapos.cfg')
open(slapos_cfg, 'w').write('[slapformat]')
sys.argv = ['entry', slapos_cfg]
self.assertFalse(entry.checkSlaposCfg())
def test_slapos_cfg_detection_when_correct(self):
"""
If given configuration file have slapos section
then True is return
"""
slapos_cfg = os.path.join(self._tempdir, 'slapos.cfg')
open(slapos_cfg, 'w').write('[slapos]')
sys.argv.append(slapos_cfg)
self.assertTrue(entry.checkSlaposCfg())
class TestcheckOption (BasicMixin, unittest.TestCase):
def test_present_option_is_not_added(self):
"""
If the option is already there do not add it
"""
sys.argv += ['-vc', '--logfile', '/opt/slapos/slapos.log']
original_sysargv = sys.argv
entry.checkOption("--logfile /opt/slapos/format.log")
self.assertEqual(original_sysargv, sys.argv)
def test_missing_option_is_added(self):
"""
If the option is not there add it
"""
sys.argv += ['-vc', '--pidfile', '/opt/slapos/slapos.pid']
original_sysargv = sys.argv
option = "--logfile /opt/slapgrid/slapformat.log"
entry.checkOption(option)
self.assertNotEqual(original_sysargv, sys.argv)
self.assertTrue(option in " ".join(sys.argv))
class TestCall (BasicMixin, unittest.TestCase):
"""
Testing call function
"""
def test_config_and_option_are_added(self):
"""
Test missing options and config are added
"""
sys.argv += ['-vc']
original_sysargv = sys.argv
def fun():
return 0
options = ["--logfile /opt/slapos/logfile",
"--pidfile /opt/slapos/pidfile"]
config = '/etc/opt/slapos/slapos.cfg'
entry.call(fun, config=config, option=options)
self.assertNotEqual(original_sysargv, sys.argv)
for x in options:
self.assertTrue(x in " ".join(sys.argv))
self.assertEqual(config, sys.argv[len(sys.argv) - 1])
def test_config_and_missing_option_are_added(self):
"""
Test missing options and config are added but do not replace
already present option
"""
missing_option = "--logfile /opt/slapos/logfile"
present_option = "--pidfile /opt/slapos/pidfile"
default_present_option = "--pidfile /opt/slapos/pidfile.default"
sys.argv += ['-vc', present_option]
original_sysargv = sys.argv
def fun():
return 0
options = [default_present_option, missing_option]
config = '/etc/opt/slapos/slapos.cfg'
entry.call(fun, config=config, option=options)
self.assertNotEqual(original_sysargv, sys.argv)
for x in (missing_option, present_option):
self.assertTrue(x in " ".join(sys.argv))
self.assertFalse(default_present_option in " ".join(sys.argv))
self.assertEqual(config, sys.argv[len(sys.argv) - 1])
def test_present_config_and_option_are_not_added(self):
"""
Test already present options and config are not added
"""
present_option = "--pidfile /opt/slapos/pidfile"
default_present_option = "--pidfile /opt/slapos/pidfile.default"
slapos_cfg = os.path.join(self._tempdir, 'slapos.cfg')
open(slapos_cfg, 'w').write('[slapos]')
sys.argv += ['-vc', slapos_cfg, present_option.split()[0],
present_option.split()[1]]
original_sysargv = sys.argv
def fun():
return 0
options = [default_present_option]
config = '/etc/opt/slapos/slapos.cfg'
entry.call(fun, config=config, option=options)
self.assertEqual(original_sysargv, sys.argv)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment