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 ...@@ -32,6 +32,7 @@ import slapos.slap
from slapos.recipe.librecipe import unwrap from slapos.recipe.librecipe import unwrap
from ConfigParser import RawConfigParser from ConfigParser import RawConfigParser
from netaddr import valid_ipv4, valid_ipv6 from netaddr import valid_ipv4, valid_ipv6
from slapos.util import mkdir_p
class Recipe(object): class Recipe(object):
""" """
...@@ -61,6 +62,10 @@ class Recipe(object): ...@@ -61,6 +62,10 @@ class Recipe(object):
Partition identifier. Partition identifier.
Example: Example:
${slap-connection:partition-id} ${slap-connection:partition-id}
storage-home
Path of folder configured for data storage
Example:
${storage-configuration:storage-home}
Output: Output:
slap-software-type slap-software-type
...@@ -75,8 +80,20 @@ class Recipe(object): ...@@ -75,8 +80,20 @@ class Recipe(object):
One of the IPv6 addresses. One of the IPv6 addresses.
tap tap
Set of TAP interfaces. 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 configuration
Dict of all parameters. Dict of all parameters.
storage-dict
Dict of partition data path when it is configured
configuration.<key> configuration.<key>
One key per partition parameter. One key per partition parameter.
Partition parameter whose name cannot be represented unambiguously in Partition parameter whose name cannot be represented unambiguously in
...@@ -91,7 +108,8 @@ class Recipe(object): ...@@ -91,7 +108,8 @@ class Recipe(object):
OPTCRE_match = RawConfigParser.OPTCRE.match OPTCRE_match = RawConfigParser.OPTCRE.match
def __init__(self, buildout, name, options): 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 match = self.OPTCRE_match
for key, value in parameter_dict.iteritems(): for key, value in parameter_dict.iteritems():
...@@ -99,7 +117,7 @@ class Recipe(object): ...@@ -99,7 +117,7 @@ class Recipe(object):
continue continue
options['configuration.' + key] = value options['configuration.' + key] = value
def fetch_parameter_dict(self, options): def fetch_parameter_dict(self, options, instance_root):
slap = slapos.slap.slap() slap = slapos.slap.slap()
slap.initializeConnection( slap.initializeConnection(
options['url'], options['url'],
...@@ -187,6 +205,21 @@ class Recipe(object): ...@@ -187,6 +205,21 @@ class Recipe(object):
if route_network_set: if route_network_set:
options['tap-network'] = list(route_network_set)[0].encode('UTF-8') 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 options['tap'] = tap_set
return self._expandParameterDict(options, parameter_dict) return self._expandParameterDict(options, parameter_dict)
......
...@@ -34,6 +34,7 @@ import subprocess ...@@ -34,6 +34,7 @@ import subprocess
import slapos.slap import slapos.slap
import netaddr import netaddr
import logging import logging
import errno
import zc.buildout import zc.buildout
...@@ -89,6 +90,20 @@ class Recipe: ...@@ -89,6 +90,20 @@ class Recipe:
if name: if name:
return name return name
raise AttributeError, "Not network interface found" 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): def install(self):
slap = slapos.slap.slap() slap = slapos.slap.slap()
...@@ -98,6 +113,8 @@ class Recipe: ...@@ -98,6 +113,8 @@ class Recipe:
server_url = slap_connection['server_url'] server_url = slap_connection['server_url']
key_file = slap_connection.get('key_file') key_file = slap_connection.get('key_file')
cert_file = slap_connection.get('cert_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) slap.initializeConnection(server_url, key_file, cert_file)
self.computer_partition = slap.registerComputerPartition( self.computer_partition = slap.registerComputerPartition(
computer_id, computer_id,
...@@ -162,6 +179,27 @@ class Recipe: ...@@ -162,6 +179,27 @@ class Recipe:
# XXX: Needed for lxc. Use non standard API # XXX: Needed for lxc. Use non standard API
buildout.set('slap-connection', 'requested', self.computer_partition._requested_state) 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'][ work_directory = os.path.abspath(self.buildout['buildout'][
'directory']) 'directory'])
buildout_filename = os.path.join(work_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