Commit f23b4032 authored by Marco Mariani's avatar Marco Mariani

Merge remote-tracking branch 'origin/cliff'

parents 40d958a6 23e24e19
...@@ -6,7 +6,7 @@ SlapOS command line usage ...@@ -6,7 +6,7 @@ SlapOS command line usage
Notes: Notes:
------ ------
* Default SlapOS Master is http://www.slapos.org. It can be changed by altering configuration files or with the ``--master-url`` * Default SlapOS Master is https://slap.vifib.com. It can be changed by altering configuration files or with the ``--master-url``
argument for commands that support it. argument for commands that support it.
* Most commands take a configuration file parameter, provided as ``--cfg /path/to/file.cfg``. * Most commands take a configuration file parameter, provided as ``--cfg /path/to/file.cfg``.
...@@ -20,7 +20,8 @@ Notes: ...@@ -20,7 +20,8 @@ Notes:
XXX TODO document 'alias' for software_url, software_group?, computer_group? ..
XXX TODO document 'alias' for software_url, software_group?, computer_group?
...@@ -59,7 +60,8 @@ Examples ...@@ -59,7 +60,8 @@ Examples
$ slapos request mykvm kvm --node id=COMP-12345 --configuration \ $ slapos request mykvm kvm --node id=COMP-12345 --configuration \
nbd-host=debian.nbd.vifib.net nbd-port=1024 nbd-host=debian.nbd.vifib.net nbd-port=1024
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. ..
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.
.. ..
...@@ -93,7 +95,8 @@ remove ...@@ -93,7 +95,8 @@ remove
Ask Removal of a software from a specific node or group of nodes. Existing instances won't work anymore. Ask Removal of a software from a specific node or group of nodes. Existing instances won't work anymore.
XXX "slapos autounsupply a.k.a slapos cleanup" ..
XXX "slapos autounsupply a.k.a slapos cleanup"
Examples Examples
...@@ -160,24 +163,14 @@ If login is not provided, asks for user's SlapOS Master account then password. ...@@ -160,24 +163,14 @@ If login is not provided, asks for user's SlapOS Master 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. 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.slapos.org) 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.slapos.org)
If Node is already registered (slapos.cfg and certificate already present), issues a warning, backups original configuration and creates new one. 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 ..
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.
Notes: Notes:
...@@ -217,7 +210,7 @@ node software ...@@ -217,7 +210,7 @@ node software
Return values: Return values:
************** **************
(Among other standard Python return values) (among other standard Python return values)
* 0 Everything went fine * 0 Everything went fine
* 1 At least one software was not correctly installed. * 1 At least one software was not correctly installed.
...@@ -232,7 +225,7 @@ node instance ...@@ -232,7 +225,7 @@ node instance
Return values: Return values:
************** **************
(Among other standard Python return values) (among other standard Python return values)
* 0 Everything went fine * 0 Everything went fine
* 1 At least one instance was not correctly processed. * 1 At least one instance was not correctly processed.
...@@ -250,7 +243,7 @@ Run instance reports and garbage collection. ...@@ -250,7 +243,7 @@ Run instance reports and garbage collection.
Return values: Return values:
************** **************
(Among other standard Python return values) (among other standard Python return values)
* 0 Everything went fine * 0 Everything went fine
* 1 At least one instance hasn't correctly been processed. * 1 At least one instance hasn't correctly been processed.
...@@ -267,8 +260,9 @@ node start|stop|restart|tail|status ...@@ -267,8 +260,9 @@ node start|stop|restart|tail|status
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
--cfg CFG SlapOS configuration file - defaults to --cfg CFG SlapOS configuration file (default: $SLAPOS_CONFIGURATION
$SLAPOS_CONFIGURATION or /etc/opt/slapos/slapos.cfg or /etc/opt/slapos/slapos.cfg)
Examples Examples
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import logging import logging
from slapos.cli.command import must_be_root
from slapos.cli.config import ConfigCommand from slapos.cli.config import ConfigCommand
from slapos.bang import do_bang from slapos.bang import do_bang
...@@ -19,6 +20,7 @@ class BangCommand(ConfigCommand): ...@@ -19,6 +20,7 @@ class BangCommand(ConfigCommand):
help='Message for bang') help='Message for bang')
return ap return ap
@must_be_root
def take_action(self, args): def take_action(self, args):
configp = self.fetch_config(args) configp = self.fetch_config(args)
do_bang(configp, args.message) do_bang(configp, args.message)
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import argparse import argparse
import functools
import os
import sys
import cliff import cliff
class Command(cliff.command.Command): class Command(cliff.command.Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description=self.get_description(), description=self.get_description(),
...@@ -14,3 +18,13 @@ class Command(cliff.command.Command): ...@@ -14,3 +18,13 @@ class Command(cliff.command.Command):
) )
return parser return parser
def must_be_root(func):
@functools.wraps(func)
def inner(self, *args, **kw):
if os.getuid() != 0:
self.app.log.error('This slapos command must be run as root.')
sys.exit(5)
return func(self, *args, **kw)
return inner
...@@ -22,39 +22,20 @@ class ConfigCommand(Command): ...@@ -22,39 +22,20 @@ class ConfigCommand(Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
ap = super(ConfigCommand, self).get_parser(prog_name) ap = super(ConfigCommand, self).get_parser(prog_name)
ap.add_argument('--cfg', help='SlapOS configuration file - ' + ap.add_argument('--cfg',
'defaults to $%s ' % self.default_config_var + help='SlapOS configuration file'
'or %s' % self.default_config_path) ' (default: $%s or %s)' %
(self.default_config_var, self.default_config_path))
return ap return ap
def _get_config(self, cfg_path, required=False): def fetch_config(self, args):
""" """
Returns a configuration object if file exists/readable/valid, Returns a configuration object if file exists/readable/valid,
None otherwise. will raise an error otherwise. The exception may come from the
Will raise an error instead of returning None if required is True. configparser itself if the configuration content is very broken,
Even if required is False, may still raise an exception from the and will clearly show what is wrong with the file.
configparser if the configuration content is very broken.
We don't catch that exception as it will clearly show what is
wrong with the file.
""" """
if not os.path.exists(cfg_path):
if required:
raise ConfigError('Configuration file does not exist: %s' % cfg_path)
else:
return None
configp = ConfigParser.SafeConfigParser()
if configp.read(cfg_path) != [cfg_path]:
# bad permission, etc.
if required:
raise ConfigError('Cannot parse configuration file: %s' % cfg_path)
else:
return None
return configp
def fetch_config(self, args):
if args.cfg: if args.cfg:
cfg_path = args.cfg cfg_path = args.cfg
else: else:
...@@ -64,7 +45,15 @@ class ConfigCommand(Command): ...@@ -64,7 +45,15 @@ class ConfigCommand(Command):
self.log.debug('Loading config: %s' % cfg_path) self.log.debug('Loading config: %s' % cfg_path)
return self._get_config(cfg_path, required=True) if not os.path.exists(cfg_path):
raise ConfigError('Configuration file does not exist: %s' % cfg_path)
configp = ConfigParser.SafeConfigParser()
if configp.read(cfg_path) != [cfg_path]:
# bad permission, etc.
raise ConfigError('Cannot parse configuration file: %s' % cfg_path)
return configp
class ClientConfigCommand(ConfigCommand): class ClientConfigCommand(ConfigCommand):
......
...@@ -72,7 +72,7 @@ class SlapOSApp(cliff.app.App): ...@@ -72,7 +72,7 @@ class SlapOSApp(cliff.app.App):
'--log-file', '--logfile', '--log_file', '--log-file', '--logfile', '--log_file',
action='store', action='store',
default=None, default=None,
help='Specify a file to log output. Only console by default.', help='Specify a file to log output (default: console only)',
) )
# always show tracebacks on errors # always show tracebacks on errors
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
import logging import logging
import sys import sys
from slapos.cli.command import must_be_root
from slapos.cli.config import ConfigCommand from slapos.cli.config import ConfigCommand
from slapos.format import do_format, FormatConfig, tracing_monkeypatch, UsageError from slapos.format import do_format, FormatConfig, tracing_monkeypatch, UsageError
...@@ -18,12 +19,10 @@ class FormatCommand(ConfigCommand): ...@@ -18,12 +19,10 @@ class FormatCommand(ConfigCommand):
ap = super(FormatCommand, self).get_parser(prog_name) ap = super(FormatCommand, self).get_parser(prog_name)
ap.add_argument('-x', '--computer_xml', ap.add_argument('-x', '--computer_xml',
help="Path to file with computer's XML. If does not exists, will be created", help="Path to file with computer's XML. If does not exists, will be created")
default=None)
ap.add_argument('--computer_json', ap.add_argument('--computer_json',
help="Path to a JSON version of the computer's XML (for development only).", help="Path to a JSON version of the computer's XML (for development only)")
default=None)
ap.add_argument('-i', '--input_definition_file', ap.add_argument('-i', '--input_definition_file',
help="Path to file to read definition of computer instead of " help="Path to file to read definition of computer instead of "
...@@ -35,26 +34,33 @@ class FormatCommand(ConfigCommand): ...@@ -35,26 +34,33 @@ class FormatCommand(ConfigCommand):
help="Path to file to write definition of computer from " help="Path to file to write definition of computer from "
"declaration.") "declaration.")
ap.add_argument('-n', '--dry_run',
help="Don't actually do anything.",
default=False,
action="store_true")
ap.add_argument('--alter_user', ap.add_argument('--alter_user',
choices=['True', 'False'], choices=['True', 'False'],
help="Shall slapformat alter user database [default: True]") default='True',
help='Shall slapformat alter user database'
' (default: %(default)s)')
ap.add_argument('--alter_network', ap.add_argument('--alter_network',
choices=['True', 'False'], choices=['True', 'False'],
help="Shall slapformat alter network configuration [default: True]") default='True',
help='Shall slapformat alter network configuration'
' (default: %(default)s)')
ap.add_argument('--now', ap.add_argument('--now',
help="Launch slapformat without delay",
default=False, default=False,
action="store_true") action="store_true",
help='Launch slapformat without delay'
' (default: %(default)s)')
ap.add_argument('-n', '--dry_run',
default=False,
action="store_true",
help="Don't actually do anything"
" (default: %(default)s)")
return ap return ap
@must_be_root
def take_action(self, args): def take_action(self, args):
configp = self.fetch_config(args) configp = self.fetch_config(args)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import logging import logging
from slapos.cli.command import must_be_root
from slapos.cli.config import ConfigCommand from slapos.cli.config import ConfigCommand
from slapos.proxy import do_proxy, ProxyConfig from slapos.proxy import do_proxy, ProxyConfig
...@@ -21,6 +22,7 @@ class ProxyStartCommand(ConfigCommand): ...@@ -21,6 +22,7 @@ class ProxyStartCommand(ConfigCommand):
return ap return ap
@must_be_root
def take_action(self, args): def take_action(self, args):
configp = self.fetch_config(args) configp = self.fetch_config(args)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
import logging import logging
import sys import sys
from slapos.cli.command import Command from slapos.cli.command import Command, must_be_root
from slapos.register.register import do_register, RegisterConfig from slapos.register.register import do_register, RegisterConfig
...@@ -21,51 +21,63 @@ class RegisterCommand(Command): ...@@ -21,51 +21,63 @@ class RegisterCommand(Command):
help='Name of the node') help='Name of the node')
ap.add_argument('--interface-name', ap.add_argument('--interface-name',
help='Interface name to access internet', default='eth0',
default='eth0') help='Primary network interface. IP of Partitions '
'will be added to it'
' (default: %(default)s)')
ap.add_argument('--master-url', ap.add_argument('--master-url',
help='URL of SlapOS master', default='https://slap.vifib.com',
default='https://slap.vifib.com') help='URL of SlapOS Master REST API'
' (default: %(default)s)')
ap.add_argument('--master-url-web', ap.add_argument('--master-url-web',
help='URL of SlapOS Master webservice to register certificates', default='https://www.slapos.org',
default='https://www.slapos.org') help='URL of SlapOS Master webservice to register certificates'
' (default: %(default)s)')
ap.add_argument('--partition-number', ap.add_argument('--partition-number',
help='Number of partition on computer', default=10,
default='10', type=int,
type=int) help='Number of partitions to create in the SlapOS Node'
' (default: %(default)s)')
ap.add_argument('--ipv4-local-network', ap.add_argument('--ipv4-local-network',
help='Base of ipv4 local network', default='10.0.0.0/16',
default='10.0.0.0/16') help='Subnetwork used to assign local IPv4 addresses. '
'It should be a not used network in order to avoid conflicts'
' (default: %(default)s)')
ap.add_argument('--ipv6-interface', ap.add_argument('--ipv6-interface',
help='Interface name to get ipv6', help='Interface name to get ipv6')
default='')
ap.add_argument('--login', ap.add_argument('--login',
help='User login on SlapOS Master webservice') help="Your SlapOS Master login. If not provided, "
"asks it interactively, then password.")
ap.add_argument('--password', ap.add_argument('--password',
help='User password on SlapOs Master webservice') help='Your SlapOS Master password. If not provided, '
'asks it interactively. NOTE: giving password as parameter '
'should be avoided for security reasons.')
ap.add_argument('-t', '--create-tap', ap.add_argument('-t', '--create-tap',
default=False,
action='store_true',
help='Will trigger creation of one virtual "tap" interface per ' help='Will trigger creation of one virtual "tap" interface per '
'Partition and attach it to primary interface. Requires ' 'Partition and attach it to primary interface. Requires '
'primary interface to be a bridge. defaults to false. ' 'primary interface to be a bridge. '
'Needed to host virtual machines.', 'Needed to host virtual machines'
default=False, ' (default: %(default)s)')
action='store_true')
ap.add_argument('-n', '--dry-run', ap.add_argument('-n', '--dry-run',
help='Simulate the execution steps',
default=False, default=False,
action='store_true') action='store_true',
help='Simulate the execution steps'
' (default: %(default)s)')
return ap return ap
@must_be_root
def take_action(self, args): def take_action(self, args):
try: try:
conf = RegisterConfig(logger=self.log) conf = RegisterConfig(logger=self.log)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import logging import logging
from slapos.cli.command import must_be_root
from slapos.cli.config import ConfigCommand from slapos.cli.config import ConfigCommand
from slapos.grid.utils import setRunning, setFinished from slapos.grid.utils import setRunning, setFinished
...@@ -33,7 +34,7 @@ class SlapgridCommand(ConfigCommand): ...@@ -33,7 +34,7 @@ class SlapgridCommand(ConfigCommand):
help='The socket supervisor will use.') help='The socket supervisor will use.')
ap.add_argument('--supervisord-configuration-path', ap.add_argument('--supervisord-configuration-path',
help='The location where supervisord configuration will be stored.') help='The location where supervisord configuration will be stored.')
ap.add_argument('--buildout', default=None, ap.add_argument('--buildout',
help='Location of buildout binary.') help='Location of buildout binary.')
ap.add_argument('--pidfile', ap.add_argument('--pidfile',
help='The location where pidfile will be created. ' help='The location where pidfile will be created. '
...@@ -49,14 +50,20 @@ class SlapgridCommand(ConfigCommand): ...@@ -49,14 +50,20 @@ class SlapgridCommand(ConfigCommand):
help='Root certificate of SlapOS master key.') help='Root certificate of SlapOS master key.')
ap.add_argument('--certificate_repository_path', ap.add_argument('--certificate_repository_path',
help='Path to directory where downloaded certificates would be stored.') help='Path to directory where downloaded certificates would be stored.')
ap.add_argument('--maximum-periodicity', type=int, default=None, ap.add_argument('--maximum-periodicity',
type=int,
help='Periodicity at which buildout should be run in instance.') help='Periodicity at which buildout should be run in instance.')
ap.add_argument('--promise-timeout', type=int, default=3, ap.add_argument('--promise-timeout',
help='Promise timeout in seconds.') default=3,
ap.add_argument('--now', action='store_true', type=int,
help='Promise timeout in seconds'
' (default: %(default)s)')
ap.add_argument('--now',
action='store_true',
help='Launch slapgrid without delay. Default behavior.') help='Launch slapgrid without delay. Default behavior.')
return ap return ap
@must_be_root
def take_action(self, args): def take_action(self, args):
configp = self.fetch_config(args) configp = self.fetch_config(args)
options = merged_options(args, configp) options = merged_options(args, configp)
......
...@@ -4,6 +4,7 @@ import argparse ...@@ -4,6 +4,7 @@ import argparse
import logging import logging
import os import os
from slapos.cli.command import must_be_root
from slapos.cli.config import ConfigCommand from slapos.cli.config import ConfigCommand
from slapos.grid.svcbackend import launchSupervisord from slapos.grid.svcbackend import launchSupervisord
...@@ -22,6 +23,7 @@ class SupervisorctlCommand(ConfigCommand): ...@@ -22,6 +23,7 @@ class SupervisorctlCommand(ConfigCommand):
help='parameters passed to supervisorctl') help='parameters passed to supervisorctl')
return ap return ap
@must_be_root
def take_action(self, args): def take_action(self, args):
configp = self.fetch_config(args) configp = self.fetch_config(args)
instance_root = configp.get('slapos', 'instance_root') instance_root = configp.get('slapos', 'instance_root')
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
import logging import logging
import os import os
from slapos.cli.command import must_be_root
from slapos.cli.config import ConfigCommand from slapos.cli.config import ConfigCommand
from slapos.grid.svcbackend import launchSupervisord from slapos.grid.svcbackend import launchSupervisord
...@@ -12,6 +13,7 @@ class SupervisordCommand(ConfigCommand): ...@@ -12,6 +13,7 @@ class SupervisordCommand(ConfigCommand):
log = logging.getLogger('supervisord') log = logging.getLogger('supervisord')
@must_be_root
def take_action(self, args): def take_action(self, args):
configp = self.fetch_config(args) configp = self.fetch_config(args)
instance_root = configp.get('slapos', 'instance_root') instance_root = configp.get('slapos', 'instance_root')
......
...@@ -20,7 +20,7 @@ class SupplyCommand(ClientConfigCommand): ...@@ -20,7 +20,7 @@ class SupplyCommand(ClientConfigCommand):
help='Your software url') help='Your software url')
ap.add_argument('node', ap.add_argument('node',
help="Target node") help='Target node')
return ap return ap
......
...@@ -294,7 +294,7 @@ class Computer(object): ...@@ -294,7 +294,7 @@ class Computer(object):
except: except:
# might be a corrupted zip file. let's move it out of the way and retry. # might be a corrupted zip file. let's move it out of the way and retry.
shutil.move(path_to_archive, shutil.move(path_to_archive,
path_to_archive+time.strftime('_broken_%Y%m%d-%H:%M')) path_to_archive + time.strftime('_broken_%Y%m%d-%H:%M'))
try: try:
self.backup_xml(path_to_archive, path_to_xml) self.backup_xml(path_to_archive, path_to_xml)
except: except:
...@@ -376,9 +376,9 @@ class Computer(object): ...@@ -376,9 +376,9 @@ class Computer(object):
for path in self.instance_root, self.software_root: for path in self.instance_root, self.software_root:
if not os.path.exists(path): if not os.path.exists(path):
os.makedirs(path, 0755) os.makedirs(path, 0o755)
else: else:
os.chmod(path, 0755) os.chmod(path, 0o755)
# own self.software_root by software user # own self.software_root by software user
slapsoft = User(self.software_user) slapsoft = User(self.software_user)
...@@ -387,7 +387,7 @@ class Computer(object): ...@@ -387,7 +387,7 @@ class Computer(object):
slapsoft.create() slapsoft.create()
slapsoft_pw = pwd.getpwnam(slapsoft.name) slapsoft_pw = pwd.getpwnam(slapsoft.name)
os.chown(self.software_root, slapsoft_pw.pw_uid, slapsoft_pw.pw_gid) os.chown(self.software_root, slapsoft_pw.pw_uid, slapsoft_pw.pw_gid)
os.chmod(self.software_root, 0755) os.chmod(self.software_root, 0o755)
# Speed hack: # Speed hack:
# Blindly add all IPs from existing configuration, just to speed up actual # Blindly add all IPs from existing configuration, just to speed up actual
...@@ -442,7 +442,7 @@ class Computer(object): ...@@ -442,7 +442,7 @@ class Computer(object):
# There should be two addresses on each Computer Partition: # There should be two addresses on each Computer Partition:
# * global IPv6 # * global IPv6
# * local IPv4, took from slapformat:ipv4_local_network # * local IPv4, took from slapformat:ipv4_local_network
if len(partition.address_list) == 0: if not partition.address_list:
# regenerate # regenerate
partition.address_list.append(self.interface.addIPv4LocalAddress()) partition.address_list.append(self.interface.addIPv4LocalAddress())
partition.address_list.append(self.interface.addAddr()) partition.address_list.append(self.interface.addAddr())
...@@ -454,11 +454,11 @@ class Computer(object): ...@@ -454,11 +454,11 @@ class Computer(object):
raise ValueError( raise ValueError(
'There should be exactly 2 stored addresses. Got: %r' % 'There should be exactly 2 stored addresses. Got: %r' %
(old_partition_address_list,)) (old_partition_address_list,))
if not any([netaddr.valid_ipv6(q['addr']) if not any(netaddr.valid_ipv6(q['addr'])
for q in old_partition_address_list]): for q in old_partition_address_list):
raise ValueError('Not valid ipv6 addresses loaded') raise ValueError('Not valid ipv6 addresses loaded')
if not any([netaddr.valid_ipv4(q['addr']) if not any(netaddr.valid_ipv4(q['addr'])
for q in old_partition_address_list]): for q in old_partition_address_list):
raise ValueError('Not valid ipv6 addresses loaded') raise ValueError('Not valid ipv6 addresses loaded')
for address in old_partition_address_list: for address in old_partition_address_list:
...@@ -510,11 +510,11 @@ class Partition(object): ...@@ -510,11 +510,11 @@ class Partition(object):
self.path = os.path.abspath(self.path) self.path = os.path.abspath(self.path)
owner = self.user if self.user else User('root') owner = self.user if self.user else User('root')
if not os.path.exists(self.path): if not os.path.exists(self.path):
os.mkdir(self.path, 0750) os.mkdir(self.path, 0o750)
if alter_user: if alter_user:
owner_pw = pwd.getpwnam(owner.name) owner_pw = pwd.getpwnam(owner.name)
os.chown(self.path, owner_pw.pw_uid, owner_pw.pw_gid) os.chown(self.path, owner_pw.pw_uid, owner_pw.pw_gid)
os.chmod(self.path, 0750) os.chmod(self.path, 0o750)
class User(object): class User(object):
...@@ -705,10 +705,15 @@ class Interface(object): ...@@ -705,10 +705,15 @@ class Interface(object):
""" """
if not socket.AF_INET in netifaces.ifaddresses(self.name): if not socket.AF_INET in netifaces.ifaddresses(self.name):
return [] return []
return [dict(addr=q['addr'], netmask=q['netmask']) for q in return [
netifaces.ifaddresses(self.name)[socket.AF_INET] if netaddr.IPAddress( {
q['addr'], 4) in netaddr.glob_to_iprange( 'addr': q['addr'],
netaddr.cidr_to_glob(self.ipv4_local_network))] 'netmask': q['netmask']
}
for q in netifaces.ifaddresses(self.name)[socket.AF_INET]
if netaddr.IPAddress(q['addr'], 4) in netaddr.glob_to_iprange(
netaddr.cidr_to_glob(self.ipv4_local_network))
]
def getGlobalScopeAddressList(self): def getGlobalScopeAddressList(self):
"""Returns currently configured global scope IPv6 addresses""" """Returns currently configured global scope IPv6 addresses"""
...@@ -717,9 +722,11 @@ class Interface(object): ...@@ -717,9 +722,11 @@ class Interface(object):
else: else:
interface_name = self.name interface_name = self.name
try: try:
address_list = [q address_list = [
q
for q in netifaces.ifaddresses(interface_name)[socket.AF_INET6] for q in netifaces.ifaddresses(interface_name)[socket.AF_INET6]
if isGlobalScopeAddress(q['addr'].split('%')[0])] if isGlobalScopeAddress(q['addr'].split('%')[0])
]
except KeyError: except KeyError:
raise ValueError("%s must have at least one IPv6 address assigned" % \ raise ValueError("%s must have at least one IPv6 address assigned" % \
interface_name) interface_name)
...@@ -856,7 +863,7 @@ class Interface(object): ...@@ -856,7 +863,7 @@ class Interface(object):
# confirmed to be configured # confirmed to be configured
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
def addAddr(self, addr = None, netmask = None): def addAddr(self, addr=None, netmask=None):
""" """
Adds IP address to interface. Adds IP address to interface.
...@@ -940,8 +947,10 @@ def parse_computer_definition(conf, definition_path): ...@@ -940,8 +947,10 @@ def parse_computer_definition(conf, definition_path):
address, netmask = computer_definition.get('computer', 'address').split('/') address, netmask = computer_definition.get('computer', 'address').split('/')
if conf.alter_network and conf.interface_name is not None \ if conf.alter_network and conf.interface_name is not None \
and conf.ipv4_local_network is not None: and conf.ipv4_local_network is not None:
interface = Interface(conf.logger, conf.interface_name, conf.ipv4_local_network, interface = Interface(logger=conf.logger,
conf.ipv6_interface) name=conf.interface_name,
ipv4_local_network=conf.ipv4_local_network,
ipv6_interface=conf.ipv6_interface)
computer = Computer( computer = Computer(
reference=conf.computer_id, reference=conf.computer_id,
interface=interface, interface=interface,
...@@ -971,21 +980,24 @@ def parse_computer_definition(conf, definition_path): ...@@ -971,21 +980,24 @@ def parse_computer_definition(conf, definition_path):
def parse_computer_xml(conf, xml_path): def parse_computer_xml(conf, xml_path):
interface = Interface(logger=conf.logger,
name=conf.interface_name,
ipv4_local_network=conf.ipv4_local_network,
ipv6_interface=conf.ipv6_interface)
if os.path.exists(xml_path): if os.path.exists(xml_path):
conf.logger.info('Loading previous computer data from %r' % xml_path) conf.logger.info('Loading previous computer data from %r' % xml_path)
computer = Computer.load(xml_path, computer = Computer.load(xml_path,
reference=conf.computer_id, reference=conf.computer_id,
ipv6_interface=conf.ipv6_interface) ipv6_interface=conf.ipv6_interface)
# Connect to the interface defined by the configuration # Connect to the interface defined by the configuration
computer.interface = Interface(conf.logger, conf.interface_name, conf.ipv4_local_network, computer.interface = interface
conf.ipv6_interface)
else: else:
# If no pre-existent configuration found, create a new computer object # If no pre-existent configuration found, create a new computer object
conf.logger.warning('Creating new data computer with id %r' % conf.computer_id) conf.logger.warning('Creating new data computer with id %r' % conf.computer_id)
computer = Computer( computer = Computer(
reference=conf.computer_id, reference=conf.computer_id,
interface=Interface(conf.logger, conf.interface_name, conf.ipv4_local_network, interface=interface,
conf.ipv6_interface),
addr=None, addr=None,
netmask=None, netmask=None,
ipv6_interface=conf.ipv6_interface, ipv6_interface=conf.ipv6_interface,
...@@ -994,29 +1006,25 @@ def parse_computer_xml(conf, xml_path): ...@@ -994,29 +1006,25 @@ def parse_computer_xml(conf, xml_path):
partition_amount = int(conf.partition_amount) partition_amount = int(conf.partition_amount)
existing_partition_amount = len(computer.partition_list) existing_partition_amount = len(computer.partition_list)
if existing_partition_amount > partition_amount: if partition_amount < existing_partition_amount:
raise ValueError('Requested amount of computer partitions (%s) is lower ' raise ValueError('Requested amount of computer partitions (%s) is lower '
'then already configured (%s), cannot continue' % (partition_amount, 'then already configured (%s), cannot continue' % (partition_amount,
len(computer.partition_list))) existing_partition_amount))
conf.logger.info('Adding %s new partitions' % conf.logger.info('Adding %s new partitions' %
(partition_amount - existing_partition_amount)) (partition_amount - existing_partition_amount))
for nb_iter in range(existing_partition_amount, partition_amount):
# add new ones for i in range(existing_partition_amount, partition_amount):
user = User("%s%s" % (conf.user_base_name, nb_iter)) # add new partitions
partition = Partition(
tap = Tap("%s%s" % (conf.tap_base_name, nb_iter)) reference='%s%s' % (conf.partition_base_name, i),
path=os.path.join(conf.instance_root, '%s%s' % (
path = os.path.join(conf.instance_root, "%s%s" % ( conf.partition_base_name, i)),
conf.partition_base_name, nb_iter)) user=User('%s%s' % (conf.user_base_name, i)),
computer.partition_list.append(
Partition(
reference="%s%s" % (conf.partition_base_name, nb_iter),
path=path,
user=user,
address_list=None, address_list=None,
tap=tap, tap=Tap('%s%s' % (conf.tap_base_name, i))
)) )
computer.partition_list.append(partition)
return computer return computer
...@@ -1047,8 +1055,8 @@ def random_delay(conf): ...@@ -1047,8 +1055,8 @@ def random_delay(conf):
# --maximal-delay=3600 # --maximal-delay=3600
if not conf.now: if not conf.now:
duration = float(60 * 60) * random.random() duration = float(60 * 60) * random.random()
print("Sleeping for %s seconds. To disable this feature, " \ conf.logger.info('Sleeping for %s seconds. To disable this feature, '
"use with --now parameter in manual." % duration) 'use with --now parameter in manual.' % duration)
time.sleep(duration) time.sleep(duration)
...@@ -1170,17 +1178,17 @@ class FormatConfig(object): ...@@ -1170,17 +1178,17 @@ class FormatConfig(object):
self.create_tap = True self.create_tap = True
# Convert strings to booleans # Convert strings to booleans
for o in ['alter_network', 'alter_user', 'create_tap']: for option in ['alter_network', 'alter_user', 'create_tap']:
attr = getattr(self, o) attr = getattr(self, option)
if isinstance(attr, str): if isinstance(attr, str):
if attr.lower() == 'true': if attr.lower() == 'true':
root_needed = True root_needed = True
setattr(self, o, True) setattr(self, option, True)
elif attr.lower() == 'false': elif attr.lower() == 'false':
setattr(self, o, False) setattr(self, option, False)
else: else:
message = 'Option %r needs to be "True" or "False", wrong value: ' \ message = 'Option %r needs to be "True" or "False", wrong value: ' \
'%r' % (o, getattr(self, o)) '%r' % (option, getattr(self, option))
self.logger.error(message) self.logger.error(message)
raise UsageError(message) raise UsageError(message)
...@@ -1203,6 +1211,7 @@ class FormatConfig(object): ...@@ -1203,6 +1211,7 @@ class FormatConfig(object):
root_needed = False root_needed = False
# check root # check root
# XXX in the new CLI, this is checked by the @must_be_root decorator.
if root_needed and os.getuid() != 0: if root_needed and os.getuid() != 0:
message = "Root rights are needed" message = "Root rights are needed"
self.logger.error(message) self.logger.error(message)
......
...@@ -294,19 +294,33 @@ class Partition(object): ...@@ -294,19 +294,33 @@ class Partition(object):
self._updateCertificate() self._updateCertificate()
def _updateCertificate(self): def _updateCertificate(self):
if not os.path.exists(self.key_file) or not os.path.exists(self.cert_file):
self.logger.info('Certificate and key not found, downloading to %r and '
'%r' % (self.cert_file, self.key_file))
try: try:
partition_certificate = self.computer_partition.getCertificate() partition_certificate = self.computer_partition.getCertificate()
except NotFoundError: except NotFoundError:
raise NotFoundError('Partition %s is not known from SlapOS Master.' % raise NotFoundError('Partition %s is not known by SlapOS Master.' %
self.partition_id) self.partition_id)
open(self.key_file, 'w').write(partition_certificate['key'])
open(self.cert_file, 'w').write(partition_certificate['certificate']) uid, gid = self.getUserGroupId()
for f in [self.key_file, self.cert_file]:
os.chmod(f, 0o400) for name, path in [
os.chown(f, *self.getUserGroupId()) ('certificate', self.cert_file),
('key', self.key_file),
]:
new_content = partition_certificate[name]
old_content = None
if os.path.exists(path):
old_content = open(path).read()
if old_content != new_content:
if old_content is None:
self.logger.info('Missing %s file. Creating %r' % (name, path))
else:
self.logger.info('Changed %s content. Updating %r' % (name, path))
with os.fdopen(os.open(path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o400), 'wb') as fout:
fout.write(new_content)
os.chown(path, uid, gid)
def getUserGroupId(self): def getUserGroupId(self):
"""Returns tuple of (uid, gid) of partition""" """Returns tuple of (uid, gid) of partition"""
...@@ -338,7 +352,7 @@ class Partition(object): ...@@ -338,7 +352,7 @@ class Partition(object):
def updateSymlink(self, sr_symlink, software_path): def updateSymlink(self, sr_symlink, software_path):
if os.path.lexists(sr_symlink): if os.path.lexists(sr_symlink):
if not os.path.islink(sr_symlink): if not os.path.islink(sr_symlink):
self.logger.debug('Not a symlink: %s, has been ignored' % (sr_symlink)) self.logger.debug('Not a symlink: %s, has been ignored' % sr_symlink)
return return
os.unlink(sr_symlink) os.unlink(sr_symlink)
os.symlink(software_path, sr_symlink) os.symlink(software_path, sr_symlink)
......
...@@ -228,6 +228,13 @@ def create_slapgrid_object(options, logger): ...@@ -228,6 +228,13 @@ def create_slapgrid_object(options, logger):
computer_partition_filter_list=op.get('only-cp', op.get('only_cp'))) computer_partition_filter_list=op.get('only-cp', op.get('only_cp')))
def check_required_only_partitions(existing, required):
missing = set(required) - set(existing)
if missing:
plural = ['s', ''][len(missing)==1]
raise ValueError('Unknown partition%s: %s' % (plural, ', '.join(sorted(missing))))
class Slapgrid(object): class Slapgrid(object):
""" Main class for SlapGrid. Fetches and processes informations from master """ Main class for SlapGrid. Fetches and processes informations from master
server and pushes usage information to master server. server and pushes usage information to master server.
...@@ -737,6 +744,9 @@ class Slapgrid(object): ...@@ -737,6 +744,9 @@ class Slapgrid(object):
# Boolean to know if every promises correctly passed # Boolean to know if every promises correctly passed
clean_run_promise = True clean_run_promise = True
check_required_only_partitions([cp.getId() for cp in self.getComputerPartitionList()],
self.computer_partition_filter_list)
# Filter all dummy / empty partitions # Filter all dummy / empty partitions
computer_partition_list = self.FilterComputerPartitionList( computer_partition_list = self.FilterComputerPartitionList(
self.getComputerPartitionList()) self.getComputerPartitionList())
......
...@@ -258,6 +258,9 @@ def supplySupply(): ...@@ -258,6 +258,9 @@ def supplySupply():
url = request.form['url'] url = request.form['url']
computer_id = request.form['computer_id'] computer_id = request.form['computer_id']
if app.config['computer_id'] == computer_id: if app.config['computer_id'] == computer_id:
if request.form['state'] == 'destroyed':
execute_db('software', 'DELETE FROM %s WHERE url = ?', [url])
else:
execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?)', [url]) execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?)', [url])
else: else:
raise UnauthorizedError, "Only accept request for: %s" % \ raise UnauthorizedError, "Only accept request for: %s" % \
......
...@@ -36,12 +36,14 @@ __all__ = ["slap", "ComputerPartition", "Computer", "SoftwareRelease", ...@@ -36,12 +36,14 @@ __all__ = ["slap", "ComputerPartition", "Computer", "SoftwareRelease",
import httplib import httplib
import logging import logging
import re
import socket import socket
import ssl import ssl
import traceback import traceback
import urllib import urllib
import urlparse import urlparse
from xml.sax import saxutils
import zope.interface import zope.interface
from interface import slap as interface from interface import slap as interface
from xml_marshaller import xml_marshaller from xml_marshaller import xml_marshaller
...@@ -339,6 +341,19 @@ class Computer(SlapDocument): ...@@ -339,6 +341,19 @@ class Computer(SlapDocument):
return xml_marshaller.loads(xml) return xml_marshaller.loads(xml)
def parsed_error_message(status, body, path):
m = re.search('(Error Value:\n.*)', body, re.MULTILINE)
if m:
match = ' '.join(line.strip() for line in m.group(0).split('\n'))
return '%s (status %s while calling %s)' % (
saxutils.unescape(match),
status,
path
)
else:
return 'Server responded with wrong code %s with %s' % (status, path)
class ComputerPartition(SlapRequester): class ComputerPartition(SlapRequester):
zope.interface.implements(interface.IComputerPartition) zope.interface.implements(interface.IComputerPartition)
...@@ -594,8 +609,9 @@ class ConnectionHelper: ...@@ -594,8 +609,9 @@ class ConnectionHelper:
elif self.response.status == httplib.FORBIDDEN: elif self.response.status == httplib.FORBIDDEN:
raise Unauthorized(path) raise Unauthorized(path)
elif self.response.status != httplib.OK: elif self.response.status != httplib.OK:
message = 'Server responded with wrong code %s with %s' % \ message = parsed_error_message(self.response.status,
(self.response.status, path) self.response.read(),
path)
raise ServerError(message) raise ServerError(message)
finally: finally:
socket.setdefaulttimeout(default_timeout) socket.setdefaulttimeout(default_timeout)
...@@ -625,8 +641,9 @@ class ConnectionHelper: ...@@ -625,8 +641,9 @@ class ConnectionHelper:
elif self.response.status == httplib.FORBIDDEN: elif self.response.status == httplib.FORBIDDEN:
raise Unauthorized("%s - %s" % (path, parameter_dict)) raise Unauthorized("%s - %s" % (path, parameter_dict))
elif self.response.status != httplib.OK: elif self.response.status != httplib.OK:
message = 'Server responded with wrong code %s with %s' % \ message = parsed_error_message(self.response.status,
(self.response.status, path) self.response.read(),
path)
raise ServerError(message) raise ServerError(message)
finally: finally:
socket.setdefaulttimeout(default_timeout) socket.setdefaulttimeout(default_timeout)
......
...@@ -107,7 +107,7 @@ class TestcheckOption (BasicMixin, unittest.TestCase): ...@@ -107,7 +107,7 @@ class TestcheckOption (BasicMixin, unittest.TestCase):
option = "--logfile /opt/slapgrid/slapformat.log" option = "--logfile /opt/slapgrid/slapformat.log"
entry.checkOption(option) entry.checkOption(option)
self.assertNotEqual(original_sysargv, sys.argv) self.assertNotEqual(original_sysargv, sys.argv)
self.assertTrue(option in " ".join(sys.argv)) self.assertIn(option, ' '.join(sys.argv))
class TestCall (BasicMixin, unittest.TestCase): class TestCall (BasicMixin, unittest.TestCase):
...@@ -133,7 +133,7 @@ class TestCall (BasicMixin, unittest.TestCase): ...@@ -133,7 +133,7 @@ class TestCall (BasicMixin, unittest.TestCase):
self.assertEqual(e[0], 0) self.assertEqual(e[0], 0)
self.assertNotEqual(original_sysargv, sys.argv) self.assertNotEqual(original_sysargv, sys.argv)
for x in options: for x in options:
self.assertTrue(x in " ".join(sys.argv)) self.assertIn(x, ' '.join(sys.argv))
self.assertEqual(config_path, sys.argv[1]) self.assertEqual(config_path, sys.argv[1])
def test_config_and_missing_option_are_added(self): def test_config_and_missing_option_are_added(self):
...@@ -158,7 +158,7 @@ class TestCall (BasicMixin, unittest.TestCase): ...@@ -158,7 +158,7 @@ class TestCall (BasicMixin, unittest.TestCase):
self.assertEqual(e[0], 0) self.assertEqual(e[0], 0)
self.assertNotEqual(original_sysargv, sys.argv) self.assertNotEqual(original_sysargv, sys.argv)
for x in (missing_option, present_option): for x in (missing_option, present_option):
self.assertTrue(x in " ".join(sys.argv)) self.assertIn(x, ' '.join(sys.argv))
self.assertFalse(default_present_option in " ".join(sys.argv)) self.assertFalse(default_present_option in " ".join(sys.argv))
self.assertEqual(config_path, sys.argv[1]) self.assertEqual(config_path, sys.argv[1])
......
...@@ -91,10 +91,8 @@ class TestSlap(SlapMixin): ...@@ -91,10 +91,8 @@ class TestSlap(SlapMixin):
""" """
slap_instance = slapos.slap.slap() slap_instance = slapos.slap.slap()
slap_instance.initializeConnection(self.server_url) slap_instance.initializeConnection(self.server_url)
self.assertTrue( self.assertIn(slap_instance._connection_helper.host, self.server_url)
slap_instance._connection_helper.host in self.server_url) self.assertIn(slap_instance._connection_helper.path, self.server_url)
self.assertTrue(
slap_instance._connection_helper.path in self.server_url)
def test_slap_initialisation_wrong_url(self): def test_slap_initialisation_wrong_url(self):
""" """
...@@ -785,7 +783,7 @@ class TestOpenOrder(SlapMixin): ...@@ -785,7 +783,7 @@ class TestOpenOrder(SlapMixin):
computer_partition = open_order.request(software_release_uri, 'myrefe') computer_partition = open_order.request(software_release_uri, 'myrefe')
self.assertTrue(isinstance(computer_partition, self.assertTrue(isinstance(computer_partition,
slapos.slap.ComputerPartition)) slapos.slap.ComputerPartition))
self.assertTrue(requested_partition_id, computer_partition.getId()) self.assertEqual(requested_partition_id, computer_partition.getId())
if __name__ == '__main__': if __name__ == '__main__':
print 'You can point to any SLAP server by setting TEST_SLAP_SERVER_URL '\ print 'You can point to any SLAP server by setting TEST_SLAP_SERVER_URL '\
......
...@@ -99,9 +99,6 @@ touch worked ...@@ -99,9 +99,6 @@ touch worked
""" """
class BasicMixin: class BasicMixin:
def assertSortedListEqual(self, list1, list2, msg=None):
self.assertListEqual(sorted(list1), sorted(list2), msg)
def setUp(self): def setUp(self):
self._tempdir = tempfile.mkdtemp() self._tempdir = tempfile.mkdtemp()
self.software_root = os.path.join(self._tempdir, 'software') self.software_root = os.path.join(self._tempdir, 'software')
...@@ -132,11 +129,11 @@ class BasicMixin: ...@@ -132,11 +129,11 @@ class BasicMixin:
pass pass
slapos.grid.utils.bootstrapBuildout = dummy slapos.grid.utils.bootstrapBuildout = dummy
def launchSlapgrid(self,develop=False): def launchSlapgrid(self, develop=False):
self.setSlapgrid(develop=develop) self.setSlapgrid(develop=develop)
return self.grid.processComputerPartitionList() return self.grid.processComputerPartitionList()
def launchSlapgridSoftware(self,develop=False): def launchSlapgridSoftware(self, develop=False):
self.setSlapgrid(develop=develop) self.setSlapgrid(develop=develop)
return self.grid.processSoftwareReleaseList() return self.grid.processSoftwareReleaseList()
...@@ -153,6 +150,29 @@ class BasicMixin: ...@@ -153,6 +150,29 @@ class BasicMixin:
shutil.rmtree(self._tempdir, True) shutil.rmtree(self._tempdir, True)
class TestRequiredOnlyPartitions(unittest2.TestCase):
def test_no_errors(self):
required = ['one', 'three']
existing = ['one', 'two', 'three']
slapgrid.check_required_only_partitions(existing, required)
def test_one_missing(self):
required = ['foobar', 'two', 'one']
existing = ['one', 'two', 'three']
self.assertRaisesRegexp(ValueError,
'Unknown partition: foobar',
slapgrid.check_required_only_partitions,
existing, required)
def test_several_missing(self):
required = ['foobar', 'barbaz']
existing = ['one', 'two', 'three']
self.assertRaisesRegexp(ValueError,
'Unknown partitions: barbaz, foobar',
slapgrid.check_required_only_partitions,
existing, required)
class TestBasicSlapgridCP(BasicMixin, unittest2.TestCase): class TestBasicSlapgridCP(BasicMixin, unittest2.TestCase):
def test_no_software_root(self): def test_no_software_root(self):
self.assertRaises(OSError, self.grid.processComputerPartitionList) self.assertRaises(OSError, self.grid.processComputerPartitionList)
...@@ -172,7 +192,7 @@ class MasterMixin(BasicMixin): ...@@ -172,7 +192,7 @@ class MasterMixin(BasicMixin):
"""Overrides httplib""" """Overrides httplib"""
import mock.httplib import mock.httplib
self.saved_httplib = dict() self.saved_httplib = {}
for fake in vars(mock.httplib): for fake in vars(mock.httplib):
self.saved_httplib[fake] = getattr(httplib, fake, None) self.saved_httplib[fake] = getattr(httplib, fake, None)
...@@ -239,38 +259,38 @@ class ComputerForTest: ...@@ -239,38 +259,38 @@ class ComputerForTest:
""" """
Will set requested amount of software Will set requested amount of software
""" """
self.software_list = range(0,self.software_amount) self.software_list = [
for i in self.software_list: SoftwareForTest(self.software_root, name=str(i))
name = str(i) for i in range(self.software_amount)
self.software_list[i] = SoftwareForTest(self.software_root, name=name) ]
def setInstances(self): def setInstances(self):
""" """
Will set requested amount of instance giving them by default first software Will set requested amount of instance giving them by default first software
""" """
self.instance_list = range(0, self.instance_amount) if self.software_list:
for i in self.instance_list:
name = str(i)
if len(self.software_list) is not 0:
software = self.software_list[0] software = self.software_list[0]
else: else:
software = None software = None
self.instance_list[i] = InstanceForTest(self.instance_root, name=name,
software=software)
def getComputer (self, computer_id): self.instance_list = [
InstanceForTest(self.instance_root, name=str(i), software=software)
for i in range(self.instance_amount)
]
def getComputer(self, computer_id):
""" """
Will return current requested state of computer Will return current requested state of computer
""" """
slap_computer = slapos.slap.Computer(computer_id) slap_computer = slapos.slap.Computer(computer_id)
slap_computer._software_release_list = [] slap_computer._software_release_list = [
slap_computer._computer_partition_list = [] software.getSoftware(computer_id)
for instance in self.instance_list: for software in self.software_list
slap_computer._computer_partition_list.append( ]
instance.getInstance(computer_id)) slap_computer._computer_partition_list = [
for software in self.software_list: instance.getInstance(computer_id)
slap_computer._software_release_list.append( for instance in self.instance_list
software.getSoftware(computer_id)) ]
return slap_computer return slap_computer
def setServerResponse(self): def setServerResponse(self):
...@@ -351,10 +371,10 @@ class InstanceForTest: ...@@ -351,10 +371,10 @@ class InstanceForTest:
self.header_list = [] self.header_list = []
self.name = name self.name = name
self.partition_path = os.path.join(self.instance_root, self.name) self.partition_path = os.path.join(self.instance_root, self.name)
os.mkdir(self.partition_path, 0750) os.mkdir(self.partition_path, 0o750)
self.timestamp = None self.timestamp = None
def getInstance (self, computer_id): def getInstance(self, computer_id):
""" """
Will return current requested state of instance Will return current requested state of instance
""" """
...@@ -366,7 +386,7 @@ class InstanceForTest: ...@@ -366,7 +386,7 @@ class InstanceForTest:
partition._parameter_dict = {'timestamp': self.timestamp} partition._parameter_dict = {'timestamp': self.timestamp}
return partition return partition
def getSoftwareRelease (self): def getSoftwareRelease(self):
""" """
Return software release for Instance Return software release for Instance
""" """
...@@ -376,7 +396,7 @@ class InstanceForTest: ...@@ -376,7 +396,7 @@ class InstanceForTest:
return sr return sr
else: return None else: return None
def setPromise (self, promise_name, promise_content): def setPromise(self, promise_name, promise_content):
""" """
This function will set promise and return its path This function will set promise and return its path
""" """
...@@ -385,7 +405,7 @@ class InstanceForTest: ...@@ -385,7 +405,7 @@ class InstanceForTest:
os.makedirs(promise_path) os.makedirs(promise_path)
promise = os.path.join(promise_path, promise_name) promise = os.path.join(promise_path, promise_name)
open(promise, 'w').write(promise_content) open(promise, 'w').write(promise_content)
os.chmod(promise, 0777) os.chmod(promise, 0o777)
def setCertificate(self, certificate_repository_path): def setCertificate(self, certificate_repository_path):
if not os.path.exists(certificate_repository_path): if not os.path.exists(certificate_repository_path):
...@@ -420,7 +440,7 @@ class SoftwareForTest: ...@@ -420,7 +440,7 @@ class SoftwareForTest:
os.mkdir(self.srbindir) os.mkdir(self.srbindir)
self.setBuildout() self.setBuildout()
def getSoftware (self, computer_id): def getSoftware(self, computer_id):
""" """
Will return current requested state of software Will return current requested state of software
""" """
...@@ -429,21 +449,21 @@ class SoftwareForTest: ...@@ -429,21 +449,21 @@ class SoftwareForTest:
return software return software
def setTemplateCfg (self,template="""[buildout]"""): def setTemplateCfg(self, template="""[buildout]"""):
""" """
Set template.cfg Set template.cfg
""" """
open(os.path.join(self.srdir, 'template.cfg'), 'w').write(template) open(os.path.join(self.srdir, 'template.cfg'), 'w').write(template)
def setBuildout (self, buildout="""#!/bin/sh def setBuildout(self, buildout="""#!/bin/sh
touch worked"""): touch worked"""):
""" """
Set a buildout exec in bin Set a buildout exec in bin
""" """
open(os.path.join(self.srbindir, 'buildout'), 'w').write(buildout) open(os.path.join(self.srbindir, 'buildout'), 'w').write(buildout)
os.chmod(os.path.join(self.srbindir, 'buildout'), 0755) os.chmod(os.path.join(self.srbindir, 'buildout'), 0o755)
def setPeriodicity(self,periodicity): def setPeriodicity(self, periodicity):
""" """
Set a periodicity file Set a periodicity file
""" """
...@@ -456,23 +476,20 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase): ...@@ -456,23 +476,20 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase):
def test_nothing_to_do(self): def test_nothing_to_do(self):
ComputerForTest(self.software_root,self.instance_root, 0, 0) ComputerForTest(self.software_root, self.instance_root, 0, 0)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['etc', 'var']) self.assertItemsEqual(os.listdir(self.instance_root), ['etc', 'var'])
self.assertSortedListEqual(os.listdir(self.software_root), []) self.assertItemsEqual(os.listdir(self.software_root), [])
def test_one_partition(self): def test_one_partition(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition), ['buildout.cfg', 'software_release', 'worked'])
['buildout.cfg', 'software_release', 'worked']) self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
self.assertSortedListEqual(os.listdir(self.software_root),
[instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'stoppedComputerPartition']) 'stoppedComputerPartition'])
...@@ -482,16 +499,13 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase): ...@@ -482,16 +499,13 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase):
Check that slapgrid processes instance is profile is not named Check that slapgrid processes instance is profile is not named
"template.cfg" but "instance.cfg". "template.cfg" but "instance.cfg".
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition), ['buildout.cfg', 'software_release', 'worked'])
['buildout.cfg', 'software_release', 'worked']) self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
self.assertSortedListEqual(os.listdir(self.software_root),
[instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'stoppedComputerPartition']) 'stoppedComputerPartition'])
...@@ -500,25 +514,25 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase): ...@@ -500,25 +514,25 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase):
""" """
Test if slapgrid cp don't process "free" partition Test if slapgrid cp don't process "free" partition
""" """
computer = ComputerForTest(self.software_root,self.instance_root, computer = ComputerForTest(self.software_root,
software_amount = 0) self.instance_root,
software_amount=0)
partition = computer.instance_list[0] partition = computer.instance_list[0]
partition.requested_state = 'destroyed' partition.requested_state = 'destroyed'
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0','etc', 'var']) self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
self.assertSortedListEqual(os.listdir(partition.partition_path), []) self.assertItemsEqual(os.listdir(partition.partition_path), [])
self.assertSortedListEqual(os.listdir(self.software_root), []) self.assertItemsEqual(os.listdir(self.software_root), [])
self.assertEqual(partition.sequence, []) self.assertEqual(partition.sequence, [])
def test_one_partition_started(self): def test_one_partition_started(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
partition = computer.instance_list[0] partition = computer.instance_list[0]
partition.requested_state = 'started' partition.requested_state = 'started'
partition.software.setBuildout(WRAPPER_CONTENT) partition.software.setBuildout(WRAPPER_CONTENT)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var']) self.assertItemsEqual(os.listdir(partition.partition_path),
self.assertSortedListEqual(os.listdir(partition.partition_path),
['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 50 tries = 50
wrapper_log = os.path.join(partition.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(partition.partition_path, '.0_wrapper.log')
...@@ -527,17 +541,16 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase): ...@@ -527,17 +541,16 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest2.TestCase):
if os.path.getsize(wrapper_log) > 0: if os.path.getsize(wrapper_log) > 0:
break break
time.sleep(0.1) time.sleep(0.1)
self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertIn('Working', open(wrapper_log).read())
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root), [partition.software.software_hash])
[partition.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'startedComputerPartition']) 'startedComputerPartition'])
self.assertEqual(partition.state,'started') self.assertEqual(partition.state, 'started')
def test_one_partition_started_stopped(self): def test_one_partition_started_stopped(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
...@@ -558,11 +571,10 @@ while True: ...@@ -558,11 +571,10 @@ while True:
HEREDOC HEREDOC
)> etc/run/wrapper && )> etc/run/wrapper &&
chmod 755 etc/run/wrapper chmod 755 etc/run/wrapper
""" % dict(python = sys.executable)) """ % {'python': sys.executable})
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var']) self.assertItemsEqual(os.listdir(instance.partition_path),
self.assertSortedListEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
tries = 50 tries = 50
...@@ -572,26 +584,24 @@ chmod 755 etc/run/wrapper ...@@ -572,26 +584,24 @@ chmod 755 etc/run/wrapper
break break
time.sleep(0.1) time.sleep(0.1)
os.path.getsize(wrapper_log) os.path.getsize(wrapper_log)
self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertIn('Working', open(wrapper_log).read())
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
[instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'startedComputerPartition']) 'startedComputerPartition'])
self.assertEqual(instance.state,'started') self.assertEqual(instance.state, 'started')
computer.sequence = [] computer.sequence = []
instance.requested_state = 'stopped' instance.requested_state = 'stopped'
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(instance.partition_path),
self.assertSortedListEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', '.0_wrapper.log.1', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', '.0_wrapper.log.1', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 50 tries = 50
expected_text = 'Signal handler called with signal 15' expected_text = 'Signal handler called with signal 15'
while tries > 0: while tries > 0:
tries -= 1 tries -= 1
found = expected_text in open(wrapper_log, 'r').read() found = expected_text in open(wrapper_log).read()
if found: if found:
break break
time.sleep(0.1) time.sleep(0.1)
...@@ -599,7 +609,7 @@ chmod 755 etc/run/wrapper ...@@ -599,7 +609,7 @@ chmod 755 etc/run/wrapper
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'stoppedComputerPartition']) 'stoppedComputerPartition'])
self.assertEqual(instance.state,'stopped') self.assertEqual(instance.state, 'stopped')
def test_one_broken_partition_stopped(self): def test_one_broken_partition_stopped(self):
""" """
...@@ -607,7 +617,7 @@ chmod 755 etc/run/wrapper ...@@ -607,7 +617,7 @@ chmod 755 etc/run/wrapper
processes will be stopped even if instance is broken (buildout fails processes will be stopped even if instance is broken (buildout fails
to run) but status is still started. to run) but status is still started.
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
...@@ -628,11 +638,10 @@ while True: ...@@ -628,11 +638,10 @@ while True:
HEREDOC HEREDOC
)> etc/run/wrapper && )> etc/run/wrapper &&
chmod 755 etc/run/wrapper chmod 755 etc/run/wrapper
""" % dict(python = sys.executable)) """ % {'python': sys.executable})
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var']) self.assertItemsEqual(os.listdir(instance.partition_path),
self.assertSortedListEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
tries = 50 tries = 50
...@@ -642,13 +651,13 @@ chmod 755 etc/run/wrapper ...@@ -642,13 +651,13 @@ chmod 755 etc/run/wrapper
break break
time.sleep(0.1) time.sleep(0.1)
os.path.getsize(wrapper_log) os.path.getsize(wrapper_log)
self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertIn('Working', open(wrapper_log).read())
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root),
[instance.software.software_hash]) [instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'startedComputerPartition']) 'startedComputerPartition'])
self.assertEqual(instance.state,'started') self.assertEqual(instance.state, 'started')
computer.sequence = [] computer.sequence = []
instance.requested_state = 'stopped' instance.requested_state = 'stopped'
...@@ -656,15 +665,15 @@ chmod 755 etc/run/wrapper ...@@ -656,15 +665,15 @@ chmod 755 etc/run/wrapper
exit 1 exit 1
""") """)
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_FAIL) self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_FAIL)
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root),
['0', 'etc', 'var']) ['0', 'etc', 'var'])
self.assertSortedListEqual(os.listdir(instance.partition_path), self.assertItemsEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', '.0_wrapper.log.1', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', '.0_wrapper.log.1', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 50 tries = 50
expected_text = 'Signal handler called with signal 15' expected_text = 'Signal handler called with signal 15'
while tries > 0: while tries > 0:
tries -= 1 tries -= 1
found = expected_text in open(wrapper_log, 'r').read() found = expected_text in open(wrapper_log).read()
if found: if found:
break break
time.sleep(0.1) time.sleep(0.1)
...@@ -676,33 +685,31 @@ exit 1 ...@@ -676,33 +685,31 @@ exit 1
def test_one_partition_stopped_started(self): def test_one_partition_stopped_started(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'stopped' instance.requested_state = 'stopped'
instance.software.setBuildout(WRAPPER_CONTENT) instance.software.setBuildout(WRAPPER_CONTENT)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition),
['buildout.cfg', 'etc', 'software_release', 'worked']) ['buildout.cfg', 'etc', 'software_release', 'worked'])
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root),
[instance.software.software_hash]) [instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'stoppedComputerPartition']) 'stoppedComputerPartition'])
self.assertEqual('stopped',instance.state) self.assertEqual('stopped', instance.state)
instance.requested_state = 'started' instance.requested_state = 'started'
computer.sequence = [] computer.sequence = []
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition),
['.0_wrapper.log', 'etc', 'buildout.cfg', 'software_release', 'worked']) ['.0_wrapper.log', 'etc', 'buildout.cfg', 'software_release', 'worked'])
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root),
[instance.software.software_hash]) [instance.software.software_hash])
tries = 50 tries = 50
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
...@@ -711,11 +718,11 @@ exit 1 ...@@ -711,11 +718,11 @@ exit 1
if os.path.getsize(wrapper_log) > 0: if os.path.getsize(wrapper_log) > 0:
break break
time.sleep(0.1) time.sleep(0.1)
self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertIn('Working', open(wrapper_log).read())
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'startedComputerPartition']) 'startedComputerPartition'])
self.assertEqual('started',instance.state) self.assertEqual('started', instance.state)
def test_one_partition_destroyed(self): def test_one_partition_destroyed(self):
""" """
...@@ -725,21 +732,17 @@ exit 1 ...@@ -725,21 +732,17 @@ exit 1
computer = ComputerForTest(self.software_root, self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'destroyed' instance.requested_state = 'destroyed'
dummy_file_name = 'dummy_file' dummy_file_name = 'dummy_file'
dummy_file = open( with open(os.path.join(instance.partition_path, dummy_file_name), 'w') as dummy_file:
os.path.join(instance.partition_path, dummy_file_name),
'w')
dummy_file.write('dummy') dummy_file.write('dummy')
dummy_file.close()
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), [dummy_file_name]) self.assertItemsEqual(os.listdir(partition), [dummy_file_name])
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
[instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', ['getFullComputerInformation',
'stoppedComputerPartition']) 'stoppedComputerPartition'])
...@@ -754,10 +757,11 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -754,10 +757,11 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
self.watchdog_banged = os.path.join(self._tempdir, 'watchdog_banged') self.watchdog_banged = os.path.join(self._tempdir, 'watchdog_banged')
watchdog_path = os.path.join(self._tempdir, 'watchdog') watchdog_path = os.path.join(self._tempdir, 'watchdog')
open(watchdog_path, 'w').write( open(watchdog_path, 'w').write(
WATCHDOG_TEMPLATE % dict(python_path=sys.executable, WATCHDOG_TEMPLATE % {
sys_path=sys.path, 'python_path': sys.executable,
watchdog_banged=self.watchdog_banged)) 'sys_path': sys.path,
os.chmod(watchdog_path, 0755) 'watchdog_banged': self.watchdog_banged})
os.chmod(watchdog_path, 0o755)
self.grid.watchdog_path = watchdog_path self.grid.watchdog_path = watchdog_path
slapos.grid.slapgrid.WATCHDOG_PATH = watchdog_path slapos.grid.slapgrid.WATCHDOG_PATH = watchdog_path
...@@ -779,9 +783,8 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -779,9 +783,8 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
partition.software.setBuildout(DAEMON_CONTENT) partition.software.setBuildout(DAEMON_CONTENT)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(partition.partition_path),
self.assertSortedListEqual(os.listdir(partition.partition_path),
['.0_daemon.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_daemon.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 200 tries = 200
daemon_log = os.path.join(partition.partition_path, '.0_daemon.log') daemon_log = os.path.join(partition.partition_path, '.0_daemon.log')
...@@ -791,7 +794,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -791,7 +794,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
break break
time.sleep(0.1) time.sleep(0.1)
time.sleep(0.1) time.sleep(0.1)
self.assertTrue('Failing' in open(daemon_log, 'r').read()) self.assertIn('Failing', open(daemon_log).read())
tries = 200 tries = 200
while tries > 0: while tries > 0:
tries -= 1 tries -= 1
...@@ -799,7 +802,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -799,7 +802,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
break break
time.sleep(0.1) time.sleep(0.1)
self.assertTrue(os.path.exists(self.watchdog_banged)) self.assertTrue(os.path.exists(self.watchdog_banged))
self.assertTrue('daemon' in open(self.watchdog_banged, 'r').read()) self.assertIn('daemon', open(self.watchdog_banged).read())
def test_one_failing_daemon_in_run_will_not_bang_with_watchdog(self): def test_one_failing_daemon_in_run_will_not_bang_with_watchdog(self):
""" """
...@@ -813,7 +816,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -813,7 +816,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
4.Wait for it to fail 4.Wait for it to fail
5.Check that file generated by monkeypacthed bang do not appear 5.Check that file generated by monkeypacthed bang do not appear
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
partition = computer.instance_list[0] partition = computer.instance_list[0]
partition.requested_state = 'started' partition.requested_state = 'started'
...@@ -831,9 +834,9 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -831,9 +834,9 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
partition.software.setBuildout(RUN_CONTENT) partition.software.setBuildout(RUN_CONTENT)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root),
['0', 'etc', 'var']) ['0', 'etc', 'var'])
self.assertSortedListEqual(os.listdir(partition.partition_path), self.assertItemsEqual(os.listdir(partition.partition_path),
['.0_daemon.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_daemon.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 200 tries = 200
daemon_log = os.path.join(partition.partition_path, '.0_daemon.log') daemon_log = os.path.join(partition.partition_path, '.0_daemon.log')
...@@ -843,7 +846,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -843,7 +846,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
break break
time.sleep(0.1) time.sleep(0.1)
time.sleep(0.1) time.sleep(0.1)
self.assertTrue('Failing' in open(daemon_log, 'r').read()) self.assertIn('Failing', open(daemon_log).read())
tries = 200 tries = 200
while tries > 0: while tries > 0:
tries -= 1 tries -= 1
...@@ -860,22 +863,24 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -860,22 +863,24 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
Certificates used for the bang are also checked Certificates used for the bang are also checked
(ie: watchdog id in process name) (ie: watchdog id in process name)
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
certificate_repository_path = os.path.join(self._tempdir, 'partition_pki') certificate_repository_path = os.path.join(self._tempdir, 'partition_pki')
instance.setCertificate(certificate_repository_path) instance.setCertificate(certificate_repository_path)
watchdog = Watchdog(dict(master_url='https://127.0.0.1/', watchdog = Watchdog({
computer_id=self.computer_id, 'master_url': 'https://127.0.0.1/',
certificate_repository_path=certificate_repository_path)) 'computer_id': self.computer_id,
'certificate_repository_path': certificate_repository_path
})
for event in watchdog.process_state_events: for event in watchdog.process_state_events:
instance.sequence = [] instance.sequence = []
instance.header_list = [] instance.header_list = []
headers = dict(eventname=event) headers = {'eventname': event}
payload = "processname:%s groupname:%s from_state:RUNNING"\ payload = "processname:%s groupname:%s from_state:RUNNING"\
% ('daemon'+getWatchdogID(),instance.name) % ('daemon'+getWatchdogID(), instance.name)
watchdog.handle_event(headers,payload) watchdog.handle_event(headers, payload)
self.assertEqual(instance.sequence,['softwareInstanceBang']) self.assertEqual(instance.sequence, ['softwareInstanceBang'])
self.assertEqual(instance.header_list[0]['key'], instance.key) self.assertEqual(instance.header_list[0]['key'], instance.key)
self.assertEqual(instance.header_list[0]['certificate'], instance.certificate) self.assertEqual(instance.header_list[0]['certificate'], instance.certificate)
...@@ -884,20 +889,22 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -884,20 +889,22 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
Test that a process going to a mode not watched by watchdog Test that a process going to a mode not watched by watchdog
in supervisord is not banged if watched by watchdog in supervisord is not banged if watched by watchdog
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
watchdog = Watchdog(dict(master_url=self.master_url, watchdog = Watchdog({
computer_id=self.computer_id, 'master_url': self.master_url,
certificate_repository_path=None)) 'computer_id': self.computer_id,
'certificate_repository_path': None
})
for event in ['EVENT', 'PROCESS_STATE', 'PROCESS_STATE_RUNNING', for event in ['EVENT', 'PROCESS_STATE', 'PROCESS_STATE_RUNNING',
'PROCESS_STATE_BACKOFF', 'PROCESS_STATE_STOPPED']: 'PROCESS_STATE_BACKOFF', 'PROCESS_STATE_STOPPED']:
computer.sequence = [] computer.sequence = []
headers = dict(eventname=event) headers = {'eventname': event}
payload = "processname:%s groupname:%s from_state:RUNNING"\ payload = "processname:%s groupname:%s from_state:RUNNING"\
% ('daemon'+getWatchdogID(),instance.name) % ('daemon'+getWatchdogID(), instance.name)
watchdog.handle_event(headers,payload) watchdog.handle_event(headers, payload)
self.assertEqual(instance.sequence,[]) self.assertEqual(instance.sequence, [])
def test_not_watched_by_watchdog_do_not_bang(self): def test_not_watched_by_watchdog_do_not_bang(self):
...@@ -906,59 +913,57 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase): ...@@ -906,59 +913,57 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest2.TestCase):
is not banged if not watched by watchdog is not banged if not watched by watchdog
(ie: no watchdog id in process name) (ie: no watchdog id in process name)
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
watchdog = Watchdog(dict(master_url=self.master_url, watchdog = Watchdog({
computer_id=self.computer_id, 'master_url': self.master_url,
certificate_repository_path=None)) 'computer_id': self.computer_id,
'certificate_repository_path': None
})
for event in watchdog.process_state_events: for event in watchdog.process_state_events:
computer.sequence = [] computer.sequence = []
headers = dict(eventname=event) headers = {'eventname': event}
payload = "processname:%s groupname:%s from_state:RUNNING"\ payload = "processname:%s groupname:%s from_state:RUNNING"\
% ('daemon',instance.name) % ('daemon', instance.name)
watchdog.handle_event(headers,payload) watchdog.handle_event(headers, payload)
self.assertEqual(computer.sequence,[]) self.assertEqual(computer.sequence, [])
class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): class TestSlapgridCPPartitionProcessing(MasterMixin, unittest2.TestCase):
def test_partition_timestamp(self): def test_partition_timestamp(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
timestamp = str(int(time.time())) timestamp = str(int(time.time()))
instance.timestamp = timestamp instance.timestamp = timestamp
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition),
['.timestamp', 'buildout.cfg', 'software_release', 'worked']) ['.timestamp', 'buildout.cfg', 'software_release', 'worked'])
self.assertSortedListEqual( self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
os.listdir(self.software_root), [instance.software.software_hash])
timestamp_path = os.path.join(instance.partition_path, '.timestamp') timestamp_path = os.path.join(instance.partition_path, '.timestamp')
self.setSlapgrid() self.setSlapgrid()
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertTrue(timestamp in open(timestamp_path,'r').read()) self.assertIn(timestamp, open(timestamp_path).read())
self.assertEqual(instance.sequence, self.assertEqual(instance.sequence,
['availableComputerPartition', 'stoppedComputerPartition']) ['availableComputerPartition', 'stoppedComputerPartition'])
def test_partition_timestamp_develop(self): def test_partition_timestamp_develop(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
timestamp = str(int(time.time())) timestamp = str(int(time.time()))
instance.timestamp = timestamp instance.timestamp = timestamp
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition),
['.timestamp', 'buildout.cfg', 'software_release', 'worked']) ['.timestamp', 'buildout.cfg', 'software_release', 'worked'])
self.assertSortedListEqual( self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
os.listdir(self.software_root), [instance.software.software_hash])
self.assertEqual(self.launchSlapgrid(develop=True), self.assertEqual(self.launchSlapgrid(develop=True),
slapgrid.SLAPGRID_SUCCESS) slapgrid.SLAPGRID_SUCCESS)
...@@ -966,22 +971,20 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -966,22 +971,20 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
self.assertEqual(instance.sequence, self.assertEqual(instance.sequence,
['availableComputerPartition', 'stoppedComputerPartition', ['availableComputerPartition', 'stoppedComputerPartition',
'availableComputerPartition','stoppedComputerPartition']) 'availableComputerPartition', 'stoppedComputerPartition'])
def test_partition_old_timestamp(self): def test_partition_old_timestamp(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
timestamp = str(int(time.time())) timestamp = str(int(time.time()))
instance.timestamp = timestamp instance.timestamp = timestamp
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition),
['.timestamp', 'buildout.cfg', 'software_release', 'worked']) ['.timestamp', 'buildout.cfg', 'software_release', 'worked'])
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
[instance.software.software_hash])
instance.timestamp = str(int(timestamp) - 1) instance.timestamp = str(int(timestamp) - 1)
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(instance.sequence, self.assertEqual(instance.sequence,
...@@ -989,48 +992,45 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -989,48 +992,45 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
def test_partition_timestamp_new_timestamp(self): def test_partition_timestamp_new_timestamp(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
timestamp = str(int(time.time())) timestamp = str(int(time.time()))
instance.timestamp = timestamp instance.timestamp = timestamp
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition),
['.timestamp', 'buildout.cfg', 'software_release', 'worked']) ['.timestamp', 'buildout.cfg', 'software_release', 'worked'])
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
[instance.software.software_hash])
instance.timestamp = str(int(timestamp)+1) instance.timestamp = str(int(timestamp)+1)
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'stoppedComputerPartition', 'getFullComputerInformation', 'stoppedComputerPartition', 'getFullComputerInformation',
'availableComputerPartition','stoppedComputerPartition', 'availableComputerPartition', 'stoppedComputerPartition',
'getFullComputerInformation']) 'getFullComputerInformation'])
def test_partition_timestamp_no_timestamp(self): def test_partition_timestamp_no_timestamp(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
timestamp = str(int(time.time())) timestamp = str(int(time.time()))
instance.timestamp = timestamp instance.timestamp = timestamp
self.launchSlapgrid() self.launchSlapgrid()
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var'])
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual(os.listdir(partition), self.assertItemsEqual(os.listdir(partition),
['.timestamp', 'buildout.cfg', 'software_release', 'worked']) ['.timestamp', 'buildout.cfg', 'software_release', 'worked'])
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root),
[instance.software.software_hash]) [instance.software.software_hash])
instance.timestamp = None instance.timestamp = None
self.launchSlapgrid() self.launchSlapgrid()
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'stoppedComputerPartition', 'getFullComputerInformation', 'stoppedComputerPartition', 'getFullComputerInformation',
'availableComputerPartition','stoppedComputerPartition',]) 'availableComputerPartition', 'stoppedComputerPartition'])
def test_partition_periodicity_remove_timestamp(self): def test_partition_periodicity_remove_timestamp(self):
...@@ -1038,7 +1038,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1038,7 +1038,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
Check that if periodicity forces run of buildout for a partition, it Check that if periodicity forces run of buildout for a partition, it
removes the .timestamp file. removes the .timestamp file.
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
timestamp = str(int(time.time())) timestamp = str(int(time.time()))
...@@ -1049,8 +1049,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1049,8 +1049,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
self.launchSlapgrid() self.launchSlapgrid()
partition = os.path.join(self.instance_root, '0') partition = os.path.join(self.instance_root, '0')
self.assertSortedListEqual( self.assertItemsEqual(os.listdir(partition),
os.listdir(partition),
['.timestamp', 'buildout.cfg', 'software_release', 'worked']) ['.timestamp', 'buildout.cfg', 'software_release', 'worked'])
time.sleep(2) time.sleep(2)
...@@ -1059,8 +1058,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1059,8 +1058,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
instance.install = lambda: None instance.install = lambda: None
self.launchSlapgrid() self.launchSlapgrid()
self.assertSortedListEqual( self.assertItemsEqual(os.listdir(partition),
os.listdir(partition),
['.timestamp', 'buildout.cfg', 'software_release', 'worked']) ['.timestamp', 'buildout.cfg', 'software_release', 'worked'])
...@@ -1074,7 +1072,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1074,7 +1072,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
3. We process partition list and wait more than unwanted periodicity 3. We process partition list and wait more than unwanted periodicity
4. We relaunch, partition should not be processed 4. We relaunch, partition should not be processed
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
timestamp = str(int(time.time())) timestamp = str(int(time.time()))
...@@ -1090,7 +1088,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1090,7 +1088,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
self.setSlapgrid() self.setSlapgrid()
self.grid.force_periodicity = True self.grid.force_periodicity = True
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertNotEqual(unwanted_periodicity,self.grid.maximum_periodicity) self.assertNotEqual(unwanted_periodicity, self.grid.maximum_periodicity)
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', 'availableComputerPartition', ['getFullComputerInformation', 'availableComputerPartition',
'startedComputerPartition', 'getFullComputerInformation']) 'startedComputerPartition', 'getFullComputerInformation'])
...@@ -1109,7 +1107,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1109,7 +1107,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
software with periodicity was runned and not the other software with periodicity was runned and not the other
5. We check that modification time of .timestamp was modified 5. We check that modification time of .timestamp was modified
""" """
computer = ComputerForTest(self.software_root,self.instance_root,20,20) computer = ComputerForTest(self.software_root, self.instance_root, 20, 20)
instance0 = computer.instance_list[0] instance0 = computer.instance_list[0]
timestamp = str(int(time.time()-5)) timestamp = str(int(time.time()-5))
instance0.timestamp = timestamp instance0.timestamp = timestamp
...@@ -1140,9 +1138,9 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1140,9 +1138,9 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
self.assertEqual(instance.sequence, self.assertEqual(instance.sequence,
['availableComputerPartition', 'stoppedComputerPartition']) ['availableComputerPartition', 'stoppedComputerPartition'])
self.assertGreater( self.assertGreater(
os.path.getmtime(os.path.join(instance0.partition_path,'.timestamp')), os.path.getmtime(os.path.join(instance0.partition_path, '.timestamp')),
last_runtime) last_runtime)
self.assertNotEqual(wanted_periodicity,self.grid.maximum_periodicity) self.assertNotEqual(wanted_periodicity, self.grid.maximum_periodicity)
def test_one_partition_stopped_is_not_processed_after_periodicity(self): def test_one_partition_stopped_is_not_processed_after_periodicity(self):
...@@ -1150,7 +1148,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1150,7 +1148,7 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
Check that periodicity doesn't force processing a partition if it is not Check that periodicity doesn't force processing a partition if it is not
started. started.
""" """
computer = ComputerForTest(self.software_root,self.instance_root,20,20) computer = ComputerForTest(self.software_root, self.instance_root, 20, 20)
instance0 = computer.instance_list[0] instance0 = computer.instance_list[0]
timestamp = str(int(time.time()-5)) timestamp = str(int(time.time()-5))
instance0.timestamp = timestamp instance0.timestamp = timestamp
...@@ -1179,16 +1177,16 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1179,16 +1177,16 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
self.assertEqual(instance.sequence, self.assertEqual(instance.sequence,
['availableComputerPartition', 'stoppedComputerPartition']) ['availableComputerPartition', 'stoppedComputerPartition'])
self.assertEqual( self.assertEqual(
os.path.getmtime(os.path.join(instance0.partition_path,'.timestamp')), os.path.getmtime(os.path.join(instance0.partition_path, '.timestamp')),
last_runtime) last_runtime)
self.assertNotEqual(wanted_periodicity,self.grid.maximum_periodicity) self.assertNotEqual(wanted_periodicity, self.grid.maximum_periodicity)
def test_one_partition_destroyed_is_not_processed_after_periodicity(self): def test_one_partition_destroyed_is_not_processed_after_periodicity(self):
""" """
Check that periodicity doesn't force processing a partition if it is not Check that periodicity doesn't force processing a partition if it is not
started. started.
""" """
computer = ComputerForTest(self.software_root,self.instance_root,20,20) computer = ComputerForTest(self.software_root, self.instance_root, 20, 20)
instance0 = computer.instance_list[0] instance0 = computer.instance_list[0]
timestamp = str(int(time.time()-5)) timestamp = str(int(time.time()-5))
instance0.timestamp = timestamp instance0.timestamp = timestamp
...@@ -1219,16 +1217,16 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase): ...@@ -1219,16 +1217,16 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest2.TestCase):
self.assertEqual(instance.sequence, self.assertEqual(instance.sequence,
['availableComputerPartition', 'stoppedComputerPartition']) ['availableComputerPartition', 'stoppedComputerPartition'])
self.assertEqual( self.assertEqual(
os.path.getmtime(os.path.join(instance0.partition_path,'.timestamp')), os.path.getmtime(os.path.join(instance0.partition_path, '.timestamp')),
last_runtime) last_runtime)
self.assertNotEqual(wanted_periodicity,self.grid.maximum_periodicity) self.assertNotEqual(wanted_periodicity, self.grid.maximum_periodicity)
def test_one_partition_buildout_fail_does_not_disturb_others(self): def test_one_partition_buildout_fail_does_not_disturb_others(self):
""" """
1. We set up two instance one using a corrupted buildout 1. We set up two instance one using a corrupted buildout
2. One will fail but the other one will be processed correctly 2. One will fail but the other one will be processed correctly
""" """
computer = ComputerForTest(self.software_root,self.instance_root,2,2) computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
instance0 = computer.instance_list[0] instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1] instance1 = computer.instance_list[1]
instance1.software = computer.software_list[1] instance1.software = computer.software_list[1]
...@@ -1245,7 +1243,7 @@ exit 42""") ...@@ -1245,7 +1243,7 @@ exit 42""")
1. We set up two instance but remove software path of one 1. We set up two instance but remove software path of one
2. One will fail but the other one will be processed correctly 2. One will fail but the other one will be processed correctly
""" """
computer = ComputerForTest(self.software_root,self.instance_root,2,2) computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
instance0 = computer.instance_list[0] instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1] instance1 = computer.instance_list[1]
instance1.software = computer.software_list[1] instance1.software = computer.software_list[1]
...@@ -1261,7 +1259,7 @@ exit 42""") ...@@ -1261,7 +1259,7 @@ exit 42""")
1. We set up two instance but remove software bin path of one 1. We set up two instance but remove software bin path of one
2. One will fail but the other one will be processed correctly 2. One will fail but the other one will be processed correctly
""" """
computer = ComputerForTest(self.software_root,self.instance_root,2,2) computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
instance0 = computer.instance_list[0] instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1] instance1 = computer.instance_list[1]
instance1.software = computer.software_list[1] instance1.software = computer.software_list[1]
...@@ -1277,7 +1275,7 @@ exit 42""") ...@@ -1277,7 +1275,7 @@ exit 42""")
1. We set up two instances but remove path of one 1. We set up two instances but remove path of one
2. One will fail but the other one will be processed correctly 2. One will fail but the other one will be processed correctly
""" """
computer = ComputerForTest(self.software_root,self.instance_root, 2, 2) computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
instance0 = computer.instance_list[0] instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1] instance1 = computer.instance_list[1]
instance1.software = computer.software_list[1] instance1.software = computer.software_list[1]
...@@ -1303,9 +1301,9 @@ echo %s; echo %s; exit 42""" % (line1, line2)) ...@@ -1303,9 +1301,9 @@ echo %s; echo %s; exit 42""" % (line1, line2))
self.launchSlapgrid() self.launchSlapgrid()
self.assertEqual(instance.sequence, ['softwareInstanceError']) self.assertEqual(instance.sequence, ['softwareInstanceError'])
# We don't care of actual formatting, we just want to have full log # We don't care of actual formatting, we just want to have full log
self.assertTrue(line1 in instance.error_log) self.assertIn(line1, instance.error_log)
self.assertTrue(line2 in instance.error_log) self.assertIn(line2, instance.error_log)
self.assertTrue("Failed to run buildout" in instance.error_log) self.assertIn('Failed to run buildout', instance.error_log)
class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
...@@ -1317,14 +1315,13 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1317,14 +1315,13 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
""" """
Test than an instance in "destroyed" state is correctly destroyed Test than an instance in "destroyed" state is correctly destroyed
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
instance.software.setBuildout(WRAPPER_CONTENT) instance.software.setBuildout(WRAPPER_CONTENT)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(instance.partition_path),
self.assertSortedListEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 50 tries = 50
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
...@@ -1333,24 +1330,22 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1333,24 +1330,22 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
if os.path.getsize(wrapper_log) > 0: if os.path.getsize(wrapper_log) > 0:
break break
time.sleep(0.1) time.sleep(0.1)
self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertIn('Working', open(wrapper_log).read())
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
[instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', ['getFullComputerInformation',
'availableComputerPartition', 'availableComputerPartition',
'startedComputerPartition']) 'startedComputerPartition'])
self.assertEqual(instance.state,'started') self.assertEqual(instance.state, 'started')
# Then destroy the instance # Then destroy the instance
computer.sequence = [] computer.sequence = []
instance.requested_state = 'destroyed' instance.requested_state = 'destroyed'
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty # Assert partition directory is empty
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(instance.partition_path), [])
self.assertSortedListEqual(os.listdir(instance.partition_path), []) self.assertItemsEqual(os.listdir(self.software_root),
self.assertSortedListEqual(os.listdir(self.software_root),
[instance.software.software_hash]) [instance.software.software_hash])
# Assert supervisor stopped process # Assert supervisor stopped process
tries = 50 tries = 50
...@@ -1368,7 +1363,7 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1368,7 +1363,7 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
['getFullComputerInformation', ['getFullComputerInformation',
'stoppedComputerPartition', 'stoppedComputerPartition',
'destroyedComputerPartition']) 'destroyedComputerPartition'])
self.assertEqual(instance.state,'destroyed') self.assertEqual(instance.state, 'destroyed')
def test_partition_list_is_complete_if_empty_destroyed_partition(self): def test_partition_list_is_complete_if_empty_destroyed_partition(self):
...@@ -1387,10 +1382,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1387,10 +1382,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
instance.requested_state = 'destroyed' instance.requested_state = 'destroyed'
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty # Assert partition directory is empty
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(instance.partition_path), [])
self.assertSortedListEqual(os.listdir(instance.partition_path), []) self.assertItemsEqual(os.listdir(self.software_root),
self.assertSortedListEqual(os.listdir(self.software_root),
[instance.software.software_hash]) [instance.software.software_hash])
# Assert supervisor stopped process # Assert supervisor stopped process
tries = 50 tries = 50
...@@ -1412,14 +1406,13 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1412,14 +1406,13 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
""" """
Checks that slapgrid-ur don't destroy instance not to be destroyed. Checks that slapgrid-ur don't destroy instance not to be destroyed.
""" """
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
instance.software.setBuildout(WRAPPER_CONTENT) instance.software.setBuildout(WRAPPER_CONTENT)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(instance.partition_path),
self.assertSortedListEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 50 tries = 50
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
...@@ -1428,21 +1421,19 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1428,21 +1421,19 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
if os.path.getsize(wrapper_log) > 0: if os.path.getsize(wrapper_log) > 0:
break break
time.sleep(0.1) time.sleep(0.1)
self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertIn('Working', open(wrapper_log).read())
self.assertSortedListEqual(os.listdir(self.software_root), self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
[instance.software.software_hash])
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation', ['getFullComputerInformation',
'availableComputerPartition', 'availableComputerPartition',
'startedComputerPartition']) 'startedComputerPartition'])
self.assertEqual('started',instance.state) self.assertEqual('started', instance.state)
# Then run usage report and see if it is still working # Then run usage report and see if it is still working
computer.sequence = [] computer.sequence = []
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var']) self.assertItemsEqual(os.listdir(instance.partition_path),
self.assertSortedListEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 50 tries = 50
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
...@@ -1451,10 +1442,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1451,10 +1442,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
if os.path.getsize(wrapper_log) > 0: if os.path.getsize(wrapper_log) > 0:
break break
time.sleep(0.1) time.sleep(0.1)
self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertIn('Working', open(wrapper_log).read())
self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
'var']) self.assertItemsEqual(os.listdir(instance.partition_path),
self.assertSortedListEqual(os.listdir(instance.partition_path),
['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked']) ['.0_wrapper.log', 'buildout.cfg', 'etc', 'software_release', 'worked'])
tries = 50 tries = 50
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
...@@ -1465,7 +1455,7 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1465,7 +1455,7 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
time.sleep(0.1) time.sleep(0.1)
self.assertEqual(computer.sequence, self.assertEqual(computer.sequence,
['getFullComputerInformation']) ['getFullComputerInformation'])
self.assertEqual('started',instance.state) self.assertEqual('started', instance.state)
def test_slapgrid_instance_ignore_free_instance(self): def test_slapgrid_instance_ignore_free_instance(self):
...@@ -1481,11 +1471,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1481,11 +1471,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
instance.requested_state = 'destroyed' instance.requested_state = 'destroyed'
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty # Assert partition directory is empty
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(instance.partition_path), [])
self.assertSortedListEqual(os.listdir(instance.partition_path), []) self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
self.assertSortedListEqual(os.listdir(self.software_root),
[instance.software.software_hash])
self.assertEqual(computer.sequence, ['getFullComputerInformation']) self.assertEqual(computer.sequence, ['getFullComputerInformation'])
def test_slapgrid_report_ignore_free_instance(self): def test_slapgrid_report_ignore_free_instance(self):
...@@ -1501,11 +1489,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase): ...@@ -1501,11 +1489,9 @@ class TestSlapgridUsageReport(MasterMixin, unittest2.TestCase):
instance.requested_state = 'destroyed' instance.requested_state = 'destroyed'
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty # Assert partition directory is empty
self.assertSortedListEqual(os.listdir(self.instance_root), self.assertItemsEqual(os.listdir(self.instance_root), ['0', 'etc', 'var'])
['0', 'etc', 'var']) self.assertItemsEqual(os.listdir(instance.partition_path), [])
self.assertSortedListEqual(os.listdir(instance.partition_path), []) self.assertItemsEqual(os.listdir(self.software_root), [instance.software.software_hash])
self.assertSortedListEqual(os.listdir(self.software_root),
[instance.software.software_hash])
self.assertEqual(computer.sequence, ['getFullComputerInformation']) self.assertEqual(computer.sequence, ['getFullComputerInformation'])
...@@ -1527,9 +1513,9 @@ echo %s; echo %s; exit 42""" % (line1, line2)) ...@@ -1527,9 +1513,9 @@ echo %s; echo %s; exit 42""" % (line1, line2))
self.assertEqual(software.sequence, self.assertEqual(software.sequence,
['buildingSoftwareRelease', 'softwareReleaseError']) ['buildingSoftwareRelease', 'softwareReleaseError'])
# We don't care of actual formatting, we just want to have full log # We don't care of actual formatting, we just want to have full log
self.assertTrue(line1 in software.error_log) self.assertIn(line1, software.error_log)
self.assertTrue(line2 in software.error_log) self.assertIn(line2, software.error_log)
self.assertTrue("Failed to run buildout" in software.error_log) self.assertIn('Failed to run buildout', software.error_log)
class SlapgridInitialization(unittest2.TestCase): class SlapgridInitialization(unittest2.TestCase):
""" """
...@@ -1551,7 +1537,7 @@ instance_root = /srv/slapgrid ...@@ -1551,7 +1537,7 @@ instance_root = /srv/slapgrid
master_url = https://slap.vifib.com/ master_url = https://slap.vifib.com/
computer_id = your computer id computer_id = your computer id
buildout = /path/to/buildout/binary buildout = /path/to/buildout/binary
""" % dict(fake_file=self.fake_file_descriptor.name)) """)
self.slapos_config_descriptor.seek(0) self.slapos_config_descriptor.seek(0)
self.default_arg_tuple = ( self.default_arg_tuple = (
'--cert_file', self.fake_file_descriptor.name, '--cert_file', self.fake_file_descriptor.name,
...@@ -1624,8 +1610,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization): ...@@ -1624,8 +1610,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization):
Check if giving --all triggers "develop" option. Check if giving --all triggers "develop" option.
""" """
parser = parseArgumentTupleAndReturnSlapgridObject parser = parseArgumentTupleAndReturnSlapgridObject
argument_tuple = ("--all",) + self.default_arg_tuple slapgrid_object = parser('--all', *self.default_arg_tuple)[0]
slapgrid_object = parser(*argument_tuple)[0]
self.assertTrue(slapgrid_object.develop) self.assertTrue(slapgrid_object.develop)
def test_backward_compatibility_not_all(self): def test_backward_compatibility_not_all(self):
...@@ -1634,8 +1619,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization): ...@@ -1634,8 +1619,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization):
option to be False. option to be False.
""" """
parser = parseArgumentTupleAndReturnSlapgridObject parser = parseArgumentTupleAndReturnSlapgridObject
argument_tuple = self.default_arg_tuple slapgrid_object = parser(*self.default_arg_tuple)[0]
slapgrid_object = parser(*argument_tuple)[0]
self.assertFalse(slapgrid_object.develop) self.assertFalse(slapgrid_object.develop)
def test_force_periodicity_if_periodicity_not_given(self): def test_force_periodicity_if_periodicity_not_given(self):
...@@ -1644,8 +1628,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization): ...@@ -1644,8 +1628,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization):
option to be false. option to be false.
""" """
parser = parseArgumentTupleAndReturnSlapgridObject parser = parseArgumentTupleAndReturnSlapgridObject
argument_tuple = self.default_arg_tuple slapgrid_object = parser(*self.default_arg_tuple)[0]
slapgrid_object = parser(*argument_tuple)[0]
self.assertFalse(slapgrid_object.force_periodicity) self.assertFalse(slapgrid_object.force_periodicity)
def test_force_periodicity_if_periodicity_given(self): def test_force_periodicity_if_periodicity_given(self):
...@@ -1653,8 +1636,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization): ...@@ -1653,8 +1636,7 @@ class TestSlapgridArgumentTuple(SlapgridInitialization):
Check if giving --maximum-periodicity triggers "force_periodicity" option. Check if giving --maximum-periodicity triggers "force_periodicity" option.
""" """
parser = parseArgumentTupleAndReturnSlapgridObject parser = parseArgumentTupleAndReturnSlapgridObject
argument_tuple = ("--maximum-periodicity","40") + self.default_arg_tuple slapgrid_object = parser('--maximum-periodicity', '40', *self.default_arg_tuple)[0]
slapgrid_object = parser(*argument_tuple)[0]
self.assertTrue(slapgrid_object.force_periodicity) self.assertTrue(slapgrid_object.force_periodicity)
class TestSlapgridConfigurationFile(SlapgridInitialization): class TestSlapgridConfigurationFile(SlapgridInitialization):
...@@ -1674,7 +1656,7 @@ buildout = /path/to/buildout/binary ...@@ -1674,7 +1656,7 @@ buildout = /path/to/buildout/binary
upload-to-binary-cache-url-blacklist = upload-to-binary-cache-url-blacklist =
http://1 http://1
http://2/bla http://2/bla
""" % dict(fake_file=self.fake_file_descriptor.name)) """)
self.slapos_config_descriptor.seek(0) self.slapos_config_descriptor.seek(0)
slapgrid_object = parseArgumentTupleAndReturnSlapgridObject( slapgrid_object = parseArgumentTupleAndReturnSlapgridObject(
*self.default_arg_tuple)[0] *self.default_arg_tuple)[0]
...@@ -1702,7 +1684,7 @@ buildout = /path/to/buildout/binary ...@@ -1702,7 +1684,7 @@ buildout = /path/to/buildout/binary
download-from-binary-cache-url-blacklist = download-from-binary-cache-url-blacklist =
http://1 http://1
http://2/bla http://2/bla
""" % dict(fake_file=self.fake_file_descriptor.name)) """)
self.slapos_config_descriptor.seek(0) self.slapos_config_descriptor.seek(0)
slapgrid_object = parseArgumentTupleAndReturnSlapgridObject( slapgrid_object = parseArgumentTupleAndReturnSlapgridObject(
*self.default_arg_tuple)[0] *self.default_arg_tuple)[0]
...@@ -1734,7 +1716,7 @@ upload-to-binary-cache-url-blacklist = ...@@ -1734,7 +1716,7 @@ upload-to-binary-cache-url-blacklist =
download-from-binary-cache-url-blacklist = download-from-binary-cache-url-blacklist =
http://3 http://3
http://4/bla http://4/bla
""" % dict(fake_file=self.fake_file_descriptor.name)) """)
self.slapos_config_descriptor.seek(0) self.slapos_config_descriptor.seek(0)
slapgrid_object = parseArgumentTupleAndReturnSlapgridObject( slapgrid_object = parseArgumentTupleAndReturnSlapgridObject(
*self.default_arg_tuple)[0] *self.default_arg_tuple)[0]
...@@ -1763,7 +1745,7 @@ buildout = /path/to/buildout/binary ...@@ -1763,7 +1745,7 @@ buildout = /path/to/buildout/binary
binary-cache-url-blacklist = binary-cache-url-blacklist =
http://1 http://1
http://2/bla http://2/bla
""" % dict(fake_file=self.fake_file_descriptor.name)) """)
self.slapos_config_descriptor.seek(0) self.slapos_config_descriptor.seek(0)
slapgrid_object = parseArgumentTupleAndReturnSlapgridObject( slapgrid_object = parseArgumentTupleAndReturnSlapgridObject(
*self.default_arg_tuple)[0] *self.default_arg_tuple)[0]
...@@ -1779,7 +1761,7 @@ binary-cache-url-blacklist = ...@@ -1779,7 +1761,7 @@ binary-cache-url-blacklist =
class TestSlapgridCPWithMasterPromise(MasterMixin, unittest2.TestCase): class TestSlapgridCPWithMasterPromise(MasterMixin, unittest2.TestCase):
def test_one_failing_promise(self): def test_one_failing_promise(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
worked_file = os.path.join(instance.partition_path, 'fail_worked') worked_file = os.path.join(instance.partition_path, 'fail_worked')
...@@ -1800,9 +1782,10 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest2.TestCase): ...@@ -1800,9 +1782,10 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest2.TestCase):
instance.requested_state = 'started' instance.requested_state = 'started'
self.fake_waiting_time = 0.1 self.fake_waiting_time = 0.1
worked_file = os.path.join(instance.partition_path, 'succeed_worked') worked_file = os.path.join(instance.partition_path, 'succeed_worked')
succeed = ("""#!/usr/bin/env sh succeed = textwrap.dedent("""\
touch "%(worked_file)s" #!/usr/bin/env sh
exit 0""" % {'worked_file': worked_file}) touch "%s"
exit 0""" % worked_file)
instance.setPromise('succeed', succeed) instance.setPromise('succeed', succeed)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertTrue(os.path.isfile(worked_file)) self.assertTrue(os.path.isfile(worked_file))
...@@ -1811,7 +1794,7 @@ exit 0""" % {'worked_file': worked_file}) ...@@ -1811,7 +1794,7 @@ exit 0""" % {'worked_file': worked_file})
self.assertEqual(instance.state, 'started') self.assertEqual(instance.state, 'started')
def test_stderr_has_been_sent(self): def test_stderr_has_been_sent(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
httplib.HTTPConnection._callback = computer.getServerResponse() httplib.HTTPConnection._callback = computer.getServerResponse()
...@@ -1823,11 +1806,12 @@ exit 0""" % {'worked_file': worked_file}) ...@@ -1823,11 +1806,12 @@ exit 0""" % {'worked_file': worked_file})
succeed = os.path.join(promise_path, 'stderr_writer') succeed = os.path.join(promise_path, 'stderr_writer')
worked_file = os.path.join(instance.partition_path, 'stderr_worked') worked_file = os.path.join(instance.partition_path, 'stderr_worked')
with open(succeed, 'w') as f: with open(succeed, 'w') as f:
f.write("""#!/usr/bin/env sh f.write(textwrap.dedent("""\
touch "%(worked_file)s" #!/usr/bin/env sh
echo Error 1>&2 touch "%s"
exit 127""" % {'worked_file': worked_file}) echo Error 1>&2
os.chmod(succeed, 0777) exit 127""" % worked_file))
os.chmod(succeed, 0o777)
self.assertEqual(self.grid.processComputerPartitionList(), self.assertEqual(self.grid.processComputerPartitionList(),
slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL) slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL)
self.assertTrue(os.path.isfile(worked_file)) self.assertTrue(os.path.isfile(worked_file))
...@@ -1838,7 +1822,7 @@ exit 127""" % {'worked_file': worked_file}) ...@@ -1838,7 +1822,7 @@ exit 127""" % {'worked_file': worked_file})
def test_timeout_works(self): def test_timeout_works(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
...@@ -1849,11 +1833,12 @@ exit 127""" % {'worked_file': worked_file}) ...@@ -1849,11 +1833,12 @@ exit 127""" % {'worked_file': worked_file})
succeed = os.path.join(promise_path, 'timed_out_promise') succeed = os.path.join(promise_path, 'timed_out_promise')
worked_file = os.path.join(instance.partition_path, 'timed_out_worked') worked_file = os.path.join(instance.partition_path, 'timed_out_worked')
with open(succeed, 'w') as f: with open(succeed, 'w') as f:
f.write("""#!/usr/bin/env sh f.write(textwrap.dedent("""\
touch "%(worked_file)s" #!/usr/bin/env sh
sleep 5 touch "%s"
exit 0""" % {'worked_file': worked_file}) sleep 5
os.chmod(succeed, 0777) exit 0""" % worked_file))
os.chmod(succeed, 0o777)
self.assertEqual(self.grid.processComputerPartitionList(), self.assertEqual(self.grid.processComputerPartitionList(),
slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL) slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL)
self.assertTrue(os.path.isfile(worked_file)) self.assertTrue(os.path.isfile(worked_file))
...@@ -1862,28 +1847,29 @@ exit 0""" % {'worked_file': worked_file}) ...@@ -1862,28 +1847,29 @@ exit 0""" % {'worked_file': worked_file})
self.assertIsNone(instance.state) self.assertIsNone(instance.state)
def test_two_succeeding_promises(self): def test_two_succeeding_promises(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
self.fake_waiting_time = 0.1 self.fake_waiting_time = 0.1
for i in range (0,2): for i in range(2):
worked_file = os.path.join(instance.partition_path, 'succeed_%s_worked' % i) worked_file = os.path.join(instance.partition_path, 'succeed_%s_worked' % i)
succeed = ("""#!/usr/bin/env sh succeed = textwrap.dedent("""\
touch "%(worked_file)s" #!/usr/bin/env sh
exit 0""" % {'worked_file': worked_file}) touch "%s"
exit 0""" % worked_file)
instance.setPromise('succeed_%s' % i, succeed) instance.setPromise('succeed_%s' % i, succeed)
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS) self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
for i in range(0,2): for i in range(2):
worked_file = os.path.join(instance.partition_path, 'succeed_%s_worked' % i) worked_file = os.path.join(instance.partition_path, 'succeed_%s_worked' % i)
self.assertTrue(os.path.isfile(worked_file)) self.assertTrue(os.path.isfile(worked_file))
self.assertFalse(instance.error) self.assertFalse(instance.error)
self.assertEqual(instance.state, 'started') self.assertEqual(instance.state, 'started')
def test_one_succeeding_one_failing_promises(self): def test_one_succeeding_one_failing_promises(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
self.fake_waiting_time = 0.1 self.fake_waiting_time = 0.1
...@@ -1891,42 +1877,50 @@ exit 0""" % {'worked_file': worked_file}) ...@@ -1891,42 +1877,50 @@ exit 0""" % {'worked_file': worked_file})
for i in range(2): for i in range(2):
worked_file = os.path.join(instance.partition_path, 'promise_worked_%d' % i) worked_file = os.path.join(instance.partition_path, 'promise_worked_%d' % i)
lockfile = os.path.join(instance.partition_path, 'lock') lockfile = os.path.join(instance.partition_path, 'lock')
promise=("""#!/usr/bin/env sh promise = textwrap.dedent("""\
touch "%(worked_file)s" #!/usr/bin/env sh
if [ ! -f %(lockfile)s ] touch "%(worked_file)s"
then if [ ! -f %(lockfile)s ]
then
touch "%(lockfile)s" touch "%(lockfile)s"
exit 0 exit 0
else else
exit 127 exit 127
fi""" % {'worked_file': worked_file, 'lockfile': lockfile}) fi""" % {
instance.setPromise('promise_%s'%i,promise) 'worked_file': worked_file,
'lockfile': lockfile
})
instance.setPromise('promise_%s' % i, promise)
self.assertEqual(self.grid.processComputerPartitionList(), self.assertEqual(self.grid.processComputerPartitionList(),
slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL) slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL)
self.assertEquals(instance.error, 1) self.assertEquals(instance.error, 1)
self.assertNotEqual('started',instance.state) self.assertNotEqual('started', instance.state)
def test_one_succeeding_one_timing_out_promises(self): def test_one_succeeding_one_timing_out_promises(self):
computer = ComputerForTest(self.software_root,self.instance_root) computer = ComputerForTest(self.software_root, self.instance_root)
instance = computer.instance_list[0] instance = computer.instance_list[0]
instance.requested_state = 'started' instance.requested_state = 'started'
self.fake_waiting_time = 0.1 self.fake_waiting_time = 0.1
for i in range(2): for i in range(2):
worked_file = os.path.join(instance.partition_path, 'promise_worked_%d' % i) worked_file = os.path.join(instance.partition_path, 'promise_worked_%d' % i)
lockfile = os.path.join(instance.partition_path, 'lock') lockfile = os.path.join(instance.partition_path, 'lock')
promise = ("""#!/usr/bin/env sh promise = textwrap.dedent("""\
touch "%(worked_file)s" #!/usr/bin/env sh
if [ ! -f %(lockfile)s ] touch "%(worked_file)s"
then if [ ! -f %(lockfile)s ]
then
touch "%(lockfile)s" touch "%(lockfile)s"
else else
sleep 5 sleep 5
fi fi
exit 0""" % {'worked_file': worked_file, 'lockfile': lockfile}) exit 0""" % {
'worked_file': worked_file,
'lockfile': lockfile
})
instance.setPromise('promise_%d' % i, promise) instance.setPromise('promise_%d' % i, promise)
self.assertEqual(self.grid.processComputerPartitionList(), self.assertEqual(self.grid.processComputerPartitionList(),
slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL) slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL)
self.assertEquals(instance.error, 1) self.assertEquals(instance.error, 1)
self.assertNotEqual(instance.state,'started') self.assertNotEqual(instance.state, 'started')
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
import logging import logging
import os import os
import unittest import unittest2
from slapos.grid import SlapObject from slapos.grid import SlapObject
from slapos.grid import utils from slapos.grid import utils
...@@ -53,7 +53,7 @@ originalBootstrapBuildout = utils.bootstrapBuildout ...@@ -53,7 +53,7 @@ originalBootstrapBuildout = utils.bootstrapBuildout
originalLaunchBuildout = utils.launchBuildout originalLaunchBuildout = utils.launchBuildout
originalUploadSoftwareRelease = SlapObject.Software.uploadSoftwareRelease originalUploadSoftwareRelease = SlapObject.Software.uploadSoftwareRelease
class TestSoftwareSlapObject(BasicMixin, unittest.TestCase): class TestSoftwareSlapObject(BasicMixin, unittest2.TestCase):
""" """
Test for Software class. Test for Software class.
""" """
...@@ -107,22 +107,14 @@ class TestSoftwareSlapObject(BasicMixin, unittest.TestCase): ...@@ -107,22 +107,14 @@ class TestSoftwareSlapObject(BasicMixin, unittest.TestCase):
software.install() software.install()
command_list = FakeCallAndRead.external_command_list command_list = FakeCallAndRead.external_command_list
self.assertTrue('buildout:networkcache-section=networkcache' self.assertIn('buildout:networkcache-section=networkcache', command_list)
in command_list) self.assertIn('networkcache:signature-private-key-file=%s' % self.signature_private_key_file, command_list)
self.assertTrue('networkcache:signature-private-key-file=%s' % self.assertIn('networkcache:upload-cache-url=%s' % self.upload_cache_url, command_list)
self.signature_private_key_file in command_list) self.assertIn('networkcache:upload-dir-url=%s' % self.upload_dir_url, command_list)
self.assertTrue('networkcache:upload-cache-url=%s' % self.upload_cache_url self.assertIn('networkcache:shacache-cert-file=%s' % self.shacache_cert_file, command_list)
in command_list) self.assertIn('networkcache:shacache-key-file=%s' % self.shacache_key_file, command_list)
self.assertTrue('networkcache:upload-dir-url=%s' % self.upload_dir_url self.assertIn('networkcache:shadir-cert-file=%s' % self.shadir_cert_file, command_list)
in command_list) self.assertIn('networkcache:shadir-key-file=%s' % self.shadir_key_file, command_list)
self.assertTrue('networkcache:shacache-cert-file=%s' % self.shacache_cert_file
in command_list)
self.assertTrue('networkcache:shacache-key-file=%s' % self.shacache_key_file
in command_list)
self.assertTrue('networkcache:shadir-cert-file=%s' % self.shadir_cert_file
in command_list)
self.assertTrue('networkcache:shadir-key-file=%s' % self.shadir_key_file
in command_list)
def test_software_install_without_networkcache(self): def test_software_install_without_networkcache(self):
""" """
......
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