Merge pull request #472 from exarkun/2045.configurable-storage-path

Introduce storage path configurable item to tahoe.cfg

Refs ticket:2045
This commit is contained in:
Jean-Paul Calderone 2018-03-19 16:38:06 -04:00 committed by GitHub
commit ee20a694a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 6 deletions

View File

@ -784,6 +784,15 @@ Storage Server Configuration
.. _#390: https://tahoe-lafs.org/trac/tahoe-lafs/ticket/390
``storage_dir = (string, optional)``
This specifies a directory where share files and other state pertaining to
storage servers will be kept.
The default value is the ``storage`` directory in the node's base directory
(i.e. ``BASEDIR/storage``), but it can be placed elsewhere. Relative paths
will be interpreted relative to the node's base directory.
Running A Helper
================
@ -849,7 +858,7 @@ This section describes these other files.
files on behalf of other clients. There will be a directory underneath it
for each StorageIndex for which this node is holding shares. There is also
an "incoming" directory where partially-completed shares are held while
they are being received.
they are being received. This location may be overridden in ``tahoe.cfg``.
``tahoe-client.tac``
@ -1105,16 +1114,16 @@ a legal one.
log_gatherer.furl = pb://soklj4y7eok5c3xkmjeqpw@192.168.69.247:44801/eqpwqtzm
timeout.keepalive = 240
timeout.disconnect = 1800
[client]
introducer.furl = pb://ok45ssoklj4y7eok5c3xkmj@tcp:tahoe.example:44801/ii3uumo
helper.furl = pb://ggti5ssoklj4y7eok5c3xkmj@tcp:helper.tahoe.example:7054/kk8lhr
[storage]
enabled = True
readonly = True
reserved_space = 10000000000
[helper]
enabled = True

View File

@ -350,7 +350,10 @@ class _Client(node.Node, pollmixin.PollMixin):
"is not listening ('tub.port=' is empty)")
readonly = self.get_config("storage", "readonly", False, boolean=True)
storedir = os.path.join(self.basedir, self.STOREDIR)
config_storedir = self.get_config(
"storage", "storage_dir", self.STOREDIR,
).decode('utf-8')
storedir = os.path.join(self.basedir, config_storedir)
data = self.get_config("storage", "reserved_space", None)
try:

View File

@ -177,7 +177,8 @@ class CreateClientOptions(_CreateBaseOptions):
class CreateNodeOptions(CreateClientOptions):
optFlags = [
("no-storage", None, "Do not offer storage service to other nodes."),
] + TOR_FLAGS + I2P_FLAGS
("storage-dir", None, "Path where the storage will be placed."),
] + TOR_FLAGS + I2P_FLAGS
synopsis = "[options] [NODEDIR]"
description = "Create a full Tahoe-LAFS node (client+server)."
@ -320,6 +321,11 @@ def write_client_config(c, config):
c.write("enabled = %s\n" % boolstr[storage_enabled])
c.write("#readonly =\n")
c.write("reserved_space = 1G\n")
storage_dir = config.get("storage-dir")
if storage_dir:
c.write("storage_dir = %s\n" % (storage_dir,))
else:
c.write("#storage_dir =\n")
c.write("#expire.enabled =\n")
c.write("#expire.mode =\n")
c.write("\n")

View File

@ -12,6 +12,7 @@ from allmydata.frontends.auth import NeedRootcapLookupScheme
from allmydata import client
from allmydata.storage_client import StorageFarmBroker
from allmydata.util import base32, fileutil
from allmydata.util.fileutil import abspath_expanduser_unicode
from allmydata.interfaces import IFilesystemNode, IFileNode, \
IImmutableFileNode, IMutableFileNode, IDirectoryNode
from foolscap.api import flushEventualQueue
@ -251,6 +252,84 @@ class Basic(testutil.ReallyEqualMixin, testutil.NonASCIIPathMixin, unittest.Test
"port = tcp:0:interface=127.0.0.1\n"))
self.failUnlessRaises(NeedRootcapLookupScheme, client.create_client, basedir)
def _storage_dir_test(self, basedir, storage_path, expected_path):
os.mkdir(basedir)
cfg_path = os.path.join(basedir, "tahoe.cfg")
fileutil.write(
cfg_path,
BASECONFIG +
"[storage]\n"
"enabled = true\n",
)
if storage_path is not None:
fileutil.write(
cfg_path,
"storage_dir = %s\n" % (storage_path,),
mode="ab",
)
c = client.create_client(basedir)
self.assertEqual(
c.getServiceNamed("storage").storedir,
expected_path,
)
def test_default_storage_dir(self):
"""
If no value is given for ``storage_dir`` in the ``storage`` section of
``tahoe.cfg`` then the ``storage`` directory beneath the node
directory is used.
"""
basedir = u"client.Basic.test_default_storage_dir"
config_path = None
expected_path = os.path.join(
abspath_expanduser_unicode(basedir),
u"storage",
)
self._storage_dir_test(
basedir,
config_path,
expected_path,
)
def test_relative_storage_dir(self):
"""
A storage node can be directed to use a particular directory for share
file storage by setting ``storage_dir`` in the ``storage`` section of
``tahoe.cfg``. If the path is relative, it is interpreted relative to
the node's basedir.
"""
basedir = u"client.Basic.test_relative_storage_dir"
config_path = b"myowndir"
expected_path = os.path.join(
abspath_expanduser_unicode(basedir),
u"myowndir",
)
self._storage_dir_test(
basedir,
config_path,
expected_path,
)
def test_absolute_storage_dir(self):
"""
If the ``storage_dir`` item in the ``storage`` section of the
configuration gives an absolute path then exactly that path is used.
"""
basedir = u"client.Basic.test_absolute_storage_dir"
# create_client is going to try to make the storage directory so we
# don't want a literal absolute path like /myowndir which we won't
# have write permission to. So construct an absolute path that we
# should be able to write to.
expected_path = abspath_expanduser_unicode(
u"client.Basic.test_absolute_storage_dir_myowndir/\N{SNOWMAN}"
)
config_path = expected_path.encode("utf-8")
self._storage_dir_test(
basedir,
config_path,
expected_path,
)
def _permute(self, sb, key):
return [ s.get_longname() for s in sb.get_servers_for_psi(key) ]