tahoe-lafs/integration/test_grid_manager.py

209 lines
7.1 KiB
Python
Raw Normal View History

2018-11-28 01:06:53 -07:00
import sys
import time
import json
import shutil
from os import mkdir, unlink, listdir, utime
from os.path import join, exists, getmtime
2020-05-07 20:57:06 -06:00
from allmydata.crypto import ed25519
2018-11-28 01:06:53 -07:00
from allmydata.util import base32
from allmydata.util import configutil
2018-11-28 01:06:53 -07:00
import util
2019-04-08 19:42:39 -06:00
import pytest_twisted
2018-11-28 01:06:53 -07:00
2019-04-08 19:42:39 -06:00
@pytest_twisted.inlineCallbacks
2020-05-07 22:29:04 -06:00
def test_create_certificate(reactor, request):
"""
The Grid Manager produces a valid, correctly-signed certificate.
"""
2018-11-28 01:06:53 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "create",
2018-11-28 01:06:53 -07:00
)
privkey_bytes = json.loads(gm_config)['private_key'].encode('ascii')
2020-05-07 20:57:06 -06:00
privkey, pubkey = ed25519.signing_keypair_from_string(privkey_bytes)
2018-11-28 01:06:53 -07:00
# Note that zara + her key here are arbitrary and don't match any
# "actual" clients in the test-grid; we're just checking that the
# Grid Manager signs this properly.
2018-11-28 01:06:53 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "add",
"zara", "pub-v0-kzug3ut2m7ziihf3ndpqlquuxeie4foyl36wn54myqc4wmiwe4ga",
2018-11-28 01:06:53 -07:00
stdin=gm_config,
)
zara_cert_bytes = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "sign", "zara",
2018-11-28 01:06:53 -07:00
stdin=gm_config,
)
zara_cert = json.loads(zara_cert_bytes)
2018-11-28 01:06:53 -07:00
# confirm that zara's certificate is made by the Grid Manager
2018-11-28 01:22:49 -07:00
# (.verify returns None on success, raises exception on error)
pubkey.verify(
base32.a2b(zara_cert['signature'].encode('ascii')),
zara_cert['certificate'].encode('ascii'),
2018-11-28 01:06:53 -07:00
)
2019-04-08 19:42:39 -06:00
@pytest_twisted.inlineCallbacks
2020-05-07 22:29:04 -06:00
def test_remove_client(reactor, request):
"""
A Grid Manager can add and successfully remove a client
"""
2018-11-28 01:06:53 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "create",
2018-11-28 01:06:53 -07:00
)
2018-11-28 01:20:51 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "add",
"zara", "pub-v0-kzug3ut2m7ziihf3ndpqlquuxeie4foyl36wn54myqc4wmiwe4ga",
2018-11-28 01:20:51 -07:00
stdin=gm_config,
)
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "add",
"yakov", "pub-v0-kvxhb3nexybmipkrar2ztfrwp4uxxsmrjzkpzafit3ket4u5yldq",
2018-11-28 01:20:51 -07:00
stdin=gm_config,
)
2020-05-07 14:40:10 -06:00
assert "zara" in json.loads(gm_config)['storage_servers']
assert "yakov" in json.loads(gm_config)['storage_servers']
2018-11-28 01:20:51 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "remove",
"zara",
2018-11-28 01:20:51 -07:00
stdin=gm_config,
)
2020-05-07 14:40:10 -06:00
assert "zara" not in json.loads(gm_config)['storage_servers']
assert "yakov" in json.loads(gm_config)['storage_servers']
2018-11-28 01:20:51 -07:00
2019-04-08 19:42:39 -06:00
@pytest_twisted.inlineCallbacks
2020-05-07 22:29:04 -06:00
def test_remove_last_client(reactor, request):
2020-05-07 14:50:10 -06:00
"""
A Grid Manager can remove all clients
"""
2018-11-28 01:20:51 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "create",
2018-11-28 01:20:51 -07:00
)
2018-11-28 01:06:53 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "add",
"zara", "pub-v0-kzug3ut2m7ziihf3ndpqlquuxeie4foyl36wn54myqc4wmiwe4ga",
2018-11-28 01:06:53 -07:00
stdin=gm_config,
)
2020-05-07 14:40:10 -06:00
assert "zara" in json.loads(gm_config)['storage_servers']
2018-11-28 01:06:53 -07:00
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "remove",
"zara",
2018-11-28 01:06:53 -07:00
stdin=gm_config,
)
# there are no storage servers left at all now
2020-05-07 14:40:10 -06:00
assert "storage_servers" not in json.loads(gm_config)
2019-04-08 19:42:39 -06:00
@pytest_twisted.inlineCallbacks
def test_reject_storage_server(reactor, request, temp_dir, flog_gatherer):
2020-05-07 14:50:10 -06:00
"""
A client with happines=2 fails to upload to a Grid when it is
using Grid Manager and there is only 1 storage server with a valid
certificate.
2020-05-07 14:50:10 -06:00
"""
import grid
introducer = yield grid.create_introducer(reactor, request, temp_dir, flog_gatherer)
storage0 = yield grid.create_storage_server(
reactor, request, temp_dir, introducer, flog_gatherer,
name="gm_storage0",
web_port="tcp:9995:interface=localhost",
needed=2,
happy=2,
total=2,
)
storage1 = yield grid.create_storage_server(
reactor, request, temp_dir, introducer, flog_gatherer,
name="gm_storage1",
web_port="tcp:9996:interface=localhost",
needed=2,
happy=2,
total=2,
)
gm_config = yield util.run_tahoe(
2020-05-07 22:29:04 -06:00
reactor, request, "grid-manager", "--config", "-", "create",
)
gm_privkey_bytes = json.loads(gm_config)['private_key'].encode('ascii')
gm_privkey, gm_pubkey = ed25519.signing_keypair_from_string(gm_privkey_bytes)
# create certificate for the first storage-server
pubkey_fname = join(storage0.process.node_dir, "node.pubkey")
with open(pubkey_fname, 'r') as f:
pubkey_str = f.read().strip()
gm_config = yield util.run_tahoe(
reactor, request, "grid-manager", "--config", "-", "add",
"storage0", pubkey_str,
stdin=gm_config,
)
assert json.loads(gm_config)['storage_servers'].keys() == ['storage0']
# XXX FIXME want a grid.create_client() or similar
diana = yield util._create_node(
reactor, request, temp_dir, introducer.furl, flog_gatherer, "diana",
web_port="tcp:9984:interface=localhost",
storage=False,
)
print("inserting certificate")
cert = yield util.run_tahoe(
reactor, request, "grid-manager", "--config", "-", "sign", "storage0",
stdin=gm_config,
)
with open(join(storage0.process.node_dir, "gridmanager.cert"), "w") as f:
f.write(cert)
config = configutil.get_config(join(storage0.process.node_dir, "tahoe.cfg"))
config.set("storage", "grid_management", "True")
config.add_section("grid_manager_certificates")
config.set("grid_manager_certificates", "default", "gridmanager.cert")
with open(join(storage0.process.node_dir, "tahoe.cfg"), "w") as f:
config.write(f)
# re-start this storage server
storage0.process.transport.signalProcess('TERM')
yield storage0.protocol.exited
yield util._run_node(
2020-05-10 22:05:47 -06:00
reactor, storage0.process.node_dir, request, None,
)
yield util.await_client_ready(diana, servers=2)
# now only one storage-server has the certificate .. configure
# diana to have the grid-manager certificate
config = configutil.get_config(join(diana.node_dir, "tahoe.cfg"))
config.add_section("grid_managers")
config.set("grid_managers", "test", ed25519.string_from_verifying_key(gm_pubkey))
with open(join(diana.node_dir, "tahoe.cfg"), "w") as f:
config.write(f)
diana.transport.signalProcess('TERM')
yield diana.transport._protocol.exited
2020-05-07 14:54:50 -06:00
diana = yield util._run_node(
2020-05-10 22:05:47 -06:00
reactor, diana._node_dir, request, None,
)
yield util.await_client_ready(diana, servers=2)
# try to put something into the grid, which should fail (because
# diana has happy=2 but should only find storage0 to be acceptable
# to upload to)
try:
yield util.run_tahoe(
reactor, request, "--node-directory", diana._node_dir,
"put", "-",
2020-05-07 22:29:04 -06:00
stdin="some content\n" * 200,
)
assert False, "Should get a failure"
except util.ProcessFailed as e:
assert 'UploadUnhappinessError' in e.output.getvalue()