Commit a3a69655 authored by Xavier Thompson's avatar Xavier Thompson

slap/standalone: Add slapformat configuration

This enables calling `slapos node format` from the command line.

In the future the StandaloneSlapOS.format() method should be unified
with the slapformat configuration and the `slapos node format` command.
parent 42e233e2
...@@ -33,6 +33,7 @@ import logging ...@@ -33,6 +33,7 @@ import logging
import time import time
import errno import errno
import socket import socket
import pwd
from six.moves import urllib from six.moves import urllib
from six.moves import http_client from six.moves import http_client
...@@ -207,6 +208,15 @@ class SlapOSConfigWriter(ConfigWriter): ...@@ -207,6 +208,15 @@ class SlapOSConfigWriter(ConfigWriter):
pidfile_report = {standalone_slapos._report_pid} pidfile_report = {standalone_slapos._report_pid}
forbid_supervisord_automatic_launch = true forbid_supervisord_automatic_launch = true
[slapformat]
input_definition_file = {standalone_slapos._slapformat_definition}
partition_amount = {standalone_slapos._partition_count}
alter_user = false
alter_network = false
create_tap = false
create_tun = false
computer_xml = {standalone_slapos._slapos_xml}
[slapproxy] [slapproxy]
host = {standalone_slapos._server_ip} host = {standalone_slapos._server_ip}
port = {standalone_slapos._server_port} port = {standalone_slapos._server_port}
...@@ -256,6 +266,33 @@ class SlapOSNodeAutoWriter(ConfigWriter): ...@@ -256,6 +266,33 @@ class SlapOSNodeAutoWriter(ConfigWriter):
os.chmod(path, 0o755) os.chmod(path, 0o755)
class SlapformatDefinitionWriter(ConfigWriter):
"""Write slapformat-definition.cfg configuration.
"""
def writeConfig(self, path):
_computer_addr = self._standalone_slapos._computer_addr
_partition_base_name = self._standalone_slapos._partition_base_name
_partition_addr = ' '.join(self._standalone_slapos._partition_addr_list)
_user = pwd.getpwuid(os.getuid()).pw_name
with open(path, 'w') as f:
f.write(
textwrap.dedent(
"""
[computer]
address = {_computer_addr}\n
""").format(**locals()))
for _partition_index in range(self._standalone_slapos._partition_count):
f.write(
textwrap.dedent(
"""
[partition_{_partition_index}]
address = {_partition_addr}
pathname = {_partition_base_name}{_partition_index}
user = {_user}
network_interface =\n
""").format(**locals()))
class PartitionForwardConfiguration(object): class PartitionForwardConfiguration(object):
"""Specification of request forwarding to another master, requested as user. """Specification of request forwarding to another master, requested as user.
""" """
...@@ -312,12 +349,16 @@ class StandaloneSlapOS(object): ...@@ -312,12 +349,16 @@ class StandaloneSlapOS(object):
base_directory, base_directory,
server_ip, server_ip,
server_port, server_port,
computer_addr,
computer_id='local', computer_id='local',
shared_part_list=(), shared_part_list=(),
software_root=None, software_root=None,
instance_root=None, instance_root=None,
shared_part_root=None, shared_part_root=None,
partition_forward_configuration=(), partition_forward_configuration=(),
partition_count=20,
partition_base_name='slappart',
partition_addr_list=(),
slapos_bin='slapos', slapos_bin='slapos',
local_software_release_root=os.sep, local_software_release_root=os.sep,
): ):
...@@ -327,12 +368,16 @@ class StandaloneSlapOS(object): ...@@ -327,12 +368,16 @@ class StandaloneSlapOS(object):
Arguments: Arguments:
* `base_directory` -- the directory which will contain softwares and instances. * `base_directory` -- the directory which will contain softwares and instances.
* `server_ip`, `server_port` -- the address this SlapOS proxy will listen to. * `server_ip`, `server_port` -- the address this SlapOS proxy will listen to.
* `computer_addr` -- the network address range for this computer.
* `computer_id` -- the id of this computer. * `computer_id` -- the id of this computer.
* `shared_part_list` -- list of extra paths to use as read-only ${buildout:shared-part-list}. * `shared_part_list` -- list of extra paths to use as read-only ${buildout:shared-part-list}.
* `software_root` -- directory to install software, default to "soft" in `base_directory` * `software_root` -- directory to install software, default to "soft" in `base_directory`
* `instance_root` -- directory to create instances, default to "inst" in `base_directory` * `instance_root` -- directory to create instances, default to "inst" in `base_directory`
* `shared_part_root` -- directory to hold shared parts software, default to "shared" in `base_directory`. * `shared_part_root` -- directory to hold shared parts software, default to "shared" in `base_directory`.
* `partition_forward_configuration` -- configuration of partition request forwarding to external SlapOS master. * `partition_forward_configuration` -- configuration of partition request forwarding to external SlapOS master.
* `partition_count` -- number of instance partitions.
* `partition_base_name` -- base name for the instance partitions.
* `partition_addr_list` -- network address ranges for the instance partitions.
* `slapos_bin` -- slapos executable to use, default to "slapos" (thus depending on the runtime PATH). * `slapos_bin` -- slapos executable to use, default to "slapos" (thus depending on the runtime PATH).
* `local_software_release_root` -- root for local Software Releases paths in the SlapOS proxy, default to `/`. * `local_software_release_root` -- root for local Software Releases paths in the SlapOS proxy, default to `/`.
...@@ -355,6 +400,13 @@ class StandaloneSlapOS(object): ...@@ -355,6 +400,13 @@ class StandaloneSlapOS(object):
self._slapos_bin = slapos_bin self._slapos_bin = slapos_bin
# partitions configuration
self._partition_count = partition_count
self._partition_base_name = partition_base_name
self._partition_addr_list = partition_addr_list
self._computer_addr = computer_addr
self._slapos_commands = { self._slapos_commands = {
'slapos-node-software': { 'slapos-node-software': {
'command': 'command':
...@@ -424,6 +476,8 @@ class StandaloneSlapOS(object): ...@@ -424,6 +476,8 @@ class StandaloneSlapOS(object):
ensureDirectoryExists(etc_directory) ensureDirectoryExists(etc_directory)
self._supervisor_config = os.path.join(etc_directory, 'supervisord.conf') self._supervisor_config = os.path.join(etc_directory, 'supervisord.conf')
self._slapos_config = os.path.join(etc_directory, 'slapos.cfg') self._slapos_config = os.path.join(etc_directory, 'slapos.cfg')
self._slapformat_definition = os.path.join(etc_directory, 'slapformat-definition.cfg')
self._slapos_xml = os.path.join(etc_directory, 'slapos.xml')
var_directory = os.path.join(base_directory, 'var') var_directory = os.path.join(base_directory, 'var')
ensureDirectoryExists(var_directory) ensureDirectoryExists(var_directory)
...@@ -453,6 +507,7 @@ class StandaloneSlapOS(object): ...@@ -453,6 +507,7 @@ class StandaloneSlapOS(object):
SlapOSConfigWriter(self).writeConfig(self._slapos_config) SlapOSConfigWriter(self).writeConfig(self._slapos_config)
SlapOSCommandWriter(self).writeConfig(self._slapos_wrapper) SlapOSCommandWriter(self).writeConfig(self._slapos_wrapper)
SlapOSNodeAutoWriter(self).writeConfig(self._slapos_node_auto_bin) SlapOSNodeAutoWriter(self).writeConfig(self._slapos_node_auto_bin)
SlapformatDefinitionWriter(self).writeConfig(self._slapformat_definition)
self.start() self.start()
......
...@@ -140,7 +140,9 @@ def makeModuleSetUpAndTestCaseClass( ...@@ -140,7 +140,9 @@ def makeModuleSetUpAndTestCaseClass(
base_directory=base_directory, base_directory=base_directory,
server_ip=ipv4_address, server_ip=ipv4_address,
server_port=getPortFromPath(base_directory), server_port=getPortFromPath(base_directory),
shared_part_list=shared_part_list) computer_addr='%s/255.255.255.255' % ipv4_address,
shared_part_list=shared_part_list,
partition_addr_list=['%s/64' % ipv6_address, '%s/255.255.255.255' % ipv4_address])
except PathTooDeepError: except PathTooDeepError:
raise RuntimeError( raise RuntimeError(
'base directory ( {} ) is too deep, try setting ' 'base directory ( {} ) is too deep, try setting '
......
...@@ -35,6 +35,7 @@ import hashlib ...@@ -35,6 +35,7 @@ import hashlib
import socket import socket
import errno import errno
import time import time
import subprocess
import multiprocessing import multiprocessing
from contextlib import closing from contextlib import closing
from six.moves.configparser import ConfigParser from six.moves.configparser import ConfigParser
...@@ -80,7 +81,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -80,7 +81,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__) working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir) self.addCleanup(shutil.rmtree, working_dir)
standalone = StandaloneSlapOS( standalone = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
self.addCleanup(standalone.stop) self.addCleanup(standalone.stop)
standalone.format(3, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6) standalone.format(3, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
...@@ -96,11 +98,38 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -96,11 +98,38 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
os.path.exists( os.path.exists(
os.path.join(standalone.instance_directory, 'slappart2'))) os.path.join(standalone.instance_directory, 'slappart2')))
def test_slapos_node_format(self):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
standalone = StandaloneSlapOS(
working_dir,
SLAPOS_TEST_IPV4,
SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4,
partition_count=3,
partition_addr_list=['%s/64' % SLAPOS_TEST_IPV6, '%s/255.255.255.255' % SLAPOS_TEST_IPV4],
)
self.addCleanup(standalone.stop)
slapos_wrapper = standalone._slapos_wrapper
subprocess.check_call((slapos_wrapper, 'node', 'format', '--now'))
self.assertTrue(os.path.exists(standalone.software_directory))
self.assertTrue(os.path.exists(standalone.instance_directory))
self.assertTrue(
os.path.exists(
os.path.join(standalone.instance_directory, 'slappart0')))
self.assertTrue(
os.path.exists(
os.path.join(standalone.instance_directory, 'slappart1')))
self.assertTrue(
os.path.exists(
os.path.join(standalone.instance_directory, 'slappart2')))
def test_reformat_less_partitions(self): def test_reformat_less_partitions(self):
working_dir = tempfile.mkdtemp(prefix=__name__) working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir) self.addCleanup(shutil.rmtree, working_dir)
standalone = StandaloneSlapOS( standalone = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
self.addCleanup(standalone.stop) self.addCleanup(standalone.stop)
standalone.format(2, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6) standalone.format(2, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6) standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
...@@ -115,7 +144,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -115,7 +144,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__) working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir) self.addCleanup(shutil.rmtree, working_dir)
standalone = StandaloneSlapOS( standalone = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
self.addCleanup(standalone.stop) self.addCleanup(standalone.stop)
standalone.format(2, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6) standalone.format(2, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
# removing this directory should not be a problem # removing this directory should not be a problem
...@@ -132,7 +162,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -132,7 +162,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__) working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir) self.addCleanup(shutil.rmtree, working_dir)
standalone = StandaloneSlapOS( standalone = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
self.addCleanup(standalone.stop) self.addCleanup(standalone.stop)
standalone.format( standalone.format(
1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6, partition_base_name="a") 1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6, partition_base_name="a")
...@@ -152,7 +183,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -152,7 +183,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__) working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir) self.addCleanup(shutil.rmtree, working_dir)
standalone = StandaloneSlapOS( standalone = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
self.addCleanup(standalone.stop) self.addCleanup(standalone.stop)
standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6) standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
with mock.patch("slapos.slap.ComputerPartition.getState", return_value="busy"),\ with mock.patch("slapos.slap.ComputerPartition.getState", return_value="busy"),\
...@@ -163,7 +195,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -163,7 +195,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__) working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir) self.addCleanup(shutil.rmtree, working_dir)
standalone1 = StandaloneSlapOS( standalone1 = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
def maybestop(): def maybestop():
# try to stop anyway, not to leak processes if test fail # try to stop anyway, not to leak processes if test fail
...@@ -176,7 +209,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -176,7 +209,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
# create another class instance, will control the same standanlone slapos. # create another class instance, will control the same standanlone slapos.
standalone2 = StandaloneSlapOS( standalone2 = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
standalone2.stop() standalone2.stop()
# stopping standalone2 stops everything # stopping standalone2 stops everything
...@@ -219,6 +253,7 @@ class TestSlapOSStandaloneSetup(unittest.TestCase): ...@@ -219,6 +253,7 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir, working_dir,
SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV4,
SLAPOS_TEST_PORT, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4,
partition_forward_configuration=partition_forward_config, partition_forward_configuration=partition_forward_config,
) )
self.addCleanup(standalone.stop) self.addCleanup(standalone.stop)
...@@ -280,7 +315,8 @@ class SlapOSStandaloneTestCase(unittest.TestCase): ...@@ -280,7 +315,8 @@ class SlapOSStandaloneTestCase(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__) working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir) self.addCleanup(shutil.rmtree, working_dir)
self.standalone = StandaloneSlapOS( self.standalone = StandaloneSlapOS(
working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT) working_dir, SLAPOS_TEST_IPV4, SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4)
if self._auto_stop_standalone: if self._auto_stop_standalone:
self.addCleanup(self.standalone.stop) self.addCleanup(self.standalone.stop)
self.standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6) self.standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
......
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