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
import time
import errno
import socket
import pwd
from six.moves import urllib
from six.moves import http_client
......@@ -207,6 +208,15 @@ class SlapOSConfigWriter(ConfigWriter):
pidfile_report = {standalone_slapos._report_pid}
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]
host = {standalone_slapos._server_ip}
port = {standalone_slapos._server_port}
......@@ -256,6 +266,33 @@ class SlapOSNodeAutoWriter(ConfigWriter):
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):
"""Specification of request forwarding to another master, requested as user.
"""
......@@ -312,12 +349,16 @@ class StandaloneSlapOS(object):
base_directory,
server_ip,
server_port,
computer_addr,
computer_id='local',
shared_part_list=(),
software_root=None,
instance_root=None,
shared_part_root=None,
partition_forward_configuration=(),
partition_count=20,
partition_base_name='slappart',
partition_addr_list=(),
slapos_bin='slapos',
local_software_release_root=os.sep,
):
......@@ -327,12 +368,16 @@ class StandaloneSlapOS(object):
Arguments:
* `base_directory` -- the directory which will contain softwares and instances.
* `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.
* `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`
* `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`.
* `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).
* `local_software_release_root` -- root for local Software Releases paths in the SlapOS proxy, default to `/`.
......@@ -355,6 +400,13 @@ class StandaloneSlapOS(object):
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 = {
'slapos-node-software': {
'command':
......@@ -424,6 +476,8 @@ class StandaloneSlapOS(object):
ensureDirectoryExists(etc_directory)
self._supervisor_config = os.path.join(etc_directory, 'supervisord.conf')
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')
ensureDirectoryExists(var_directory)
......@@ -453,6 +507,7 @@ class StandaloneSlapOS(object):
SlapOSConfigWriter(self).writeConfig(self._slapos_config)
SlapOSCommandWriter(self).writeConfig(self._slapos_wrapper)
SlapOSNodeAutoWriter(self).writeConfig(self._slapos_node_auto_bin)
SlapformatDefinitionWriter(self).writeConfig(self._slapformat_definition)
self.start()
......
......@@ -140,7 +140,9 @@ def makeModuleSetUpAndTestCaseClass(
base_directory=base_directory,
server_ip=ipv4_address,
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:
raise RuntimeError(
'base directory ( {} ) is too deep, try setting '
......
......@@ -35,6 +35,7 @@ import hashlib
import socket
import errno
import time
import subprocess
import multiprocessing
from contextlib import closing
from six.moves.configparser import ConfigParser
......@@ -80,7 +81,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
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)
standalone.format(3, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
......@@ -96,11 +98,38 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
os.path.exists(
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):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
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)
standalone.format(2, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
......@@ -115,7 +144,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
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)
standalone.format(2, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
# removing this directory should not be a problem
......@@ -132,7 +162,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
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)
standalone.format(
1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6, partition_base_name="a")
......@@ -152,7 +183,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
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)
standalone.format(1, SLAPOS_TEST_IPV4, SLAPOS_TEST_IPV6)
with mock.patch("slapos.slap.ComputerPartition.getState", return_value="busy"),\
......@@ -163,7 +195,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
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():
# try to stop anyway, not to leak processes if test fail
......@@ -176,7 +209,8 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
# create another class instance, will control the same standanlone slapos.
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()
# stopping standalone2 stops everything
......@@ -219,6 +253,7 @@ class TestSlapOSStandaloneSetup(unittest.TestCase):
working_dir,
SLAPOS_TEST_IPV4,
SLAPOS_TEST_PORT,
'%s/255.255.255.255' % SLAPOS_TEST_IPV4,
partition_forward_configuration=partition_forward_config,
)
self.addCleanup(standalone.stop)
......@@ -280,7 +315,8 @@ class SlapOSStandaloneTestCase(unittest.TestCase):
working_dir = tempfile.mkdtemp(prefix=__name__)
self.addCleanup(shutil.rmtree, working_dir)
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:
self.addCleanup(self.standalone.stop)
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