Commit 00e07d7e authored by Alain Takoudjou's avatar Alain Takoudjou

Configure external data folder in partition if defined and return the list

If disk is mounted in folder like /data/data* and formated by slapformat
as /data/data*/slappart* for each partition, create a symlink
instance_root/DATA/data* to allow process of partition to write in
in the mounted disk.
parent 3348a7ce
......@@ -32,6 +32,7 @@ import slapos.slap
from slapos.recipe.librecipe import unwrap
from ConfigParser import RawConfigParser
from netaddr import valid_ipv4, valid_ipv6
from slapos.util import mkdir_p
class Recipe(object):
"""
......@@ -61,6 +62,10 @@ class Recipe(object):
Partition identifier.
Example:
${slap-connection:partition-id}
storage-home
Path of folder configured for data storage
Example:
${storage-configuration:storage-home}
Output:
slap-software-type
......@@ -75,8 +80,20 @@ class Recipe(object):
One of the IPv6 addresses.
tap
Set of TAP interfaces.
tap-network-information-dict
Dict of set of all TAP network information
tap-ipv4
ipv4 allowed for this TAP
tap-gateway
ipv4 of gateway interface of this TAP
tap-netmask
ipv4 netmask address of this TAP
tap-network
ipv4 network address of this TAP
configuration
Dict of all parameters.
storage-dict
Dict of partition data path when it is configured
configuration.<key>
One key per partition parameter.
Partition parameter whose name cannot be represented unambiguously in
......@@ -91,7 +108,8 @@ class Recipe(object):
OPTCRE_match = RawConfigParser.OPTCRE.match
def __init__(self, buildout, name, options):
parameter_dict = self.fetch_parameter_dict(options)
parameter_dict = self.fetch_parameter_dict(options,
buildout['buildout']['directory'])
match = self.OPTCRE_match
for key, value in parameter_dict.iteritems():
......@@ -99,7 +117,7 @@ class Recipe(object):
continue
options['configuration.' + key] = value
def fetch_parameter_dict(self, options):
def fetch_parameter_dict(self, options, instance_root):
slap = slapos.slap.slap()
slap.initializeConnection(
options['url'],
......@@ -187,6 +205,21 @@ class Recipe(object):
if route_network_set:
options['tap-network'] = list(route_network_set)[0].encode('UTF-8')
storage_home = options.get('storage-home')
storage_dict = {}
if storage_home and os.path.exists(storage_home) and \
os.path.isdir(storage_home):
for filename in os.listdir(storage_home):
storage_path = os.path.join(storage_home, filename,
options['slap-computer-partition-id'])
if os.path.exists(storage_path) and os.path.isdir(storage_path):
storage_link = os.path.join(instance_root, 'DATA', filename)
mkdir_p(os.path.join(instance_root, 'DATA'))
if not os.path.lexists(storage_link):
os.symlink(storage_path, storage_link)
storage_dict[filename] = storage_link
options['storage-dict'] = storage_dict
options['tap'] = tap_set
return self._expandParameterDict(options, parameter_dict)
......
......@@ -34,6 +34,7 @@ import subprocess
import slapos.slap
import netaddr
import logging
import errno
import zc.buildout
......@@ -89,6 +90,20 @@ class Recipe:
if name:
return name
raise AttributeError, "Not network interface found"
def mkdir_p(self, path, mode=0700):
"""
Creates a directory and its parents, if needed.
NB: If the directory already exists, it does not change its permission.
"""
try:
os.makedirs(path, mode)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise
def install(self):
slap = slapos.slap.slap()
......@@ -98,6 +113,8 @@ class Recipe:
server_url = slap_connection['server_url']
key_file = slap_connection.get('key_file')
cert_file = slap_connection.get('cert_file')
storage_home = self.buildout['storage-configuration'].get('storage-home')
instance_root = self.buildout['buildout']['directory']
slap.initializeConnection(server_url, key_file, cert_file)
self.computer_partition = slap.registerComputerPartition(
computer_id,
......@@ -162,6 +179,27 @@ class Recipe:
# XXX: Needed for lxc. Use non standard API
buildout.set('slap-connection', 'requested', self.computer_partition._requested_state)
# setup storage directory
buildout.add_section('storage-configuration')
buildout.set('storage-configuration', 'storage-home', storage_home)
if storage_home and os.path.exists(storage_home) and \
os.path.isdir(storage_home):
# Create folder instance_root/DATA/ if not exist
data_home = os.path.join(instance_root, 'DATA')
self.mkdir_p(data_home)
for filename in os.listdir(storage_home):
storage_path = os.path.join(storage_home, filename, computer_partition_id)
if os.path.exists(storage_path) and os.path.isdir(storage_path):
storage_link = os.path.join(data_home, filename)
if os.path.lexists(storage_link):
if not os.path.islink(storage_link):
raise zc.buildout.UserError(
'Target %r already exists but is not a link' % storage_link)
#os.unlink(storage_link)
else:
os.symlink(storage_path, storage_link)
buildout.set('storage-configuration', filename, storage_link)
work_directory = os.path.abspath(self.buildout['buildout'][
'directory'])
buildout_filename = os.path.join(work_directory,
......
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