From f0e3b69f90278c71a45e978b833f64ae0b3dfcd9 Mon Sep 17 00:00:00 2001 From: meejah Date: Mon, 8 Apr 2019 23:33:40 -0600 Subject: [PATCH] switch around how we do config (avoid space-separated filenames) --- docs/proposed/grid-manager/managed-grid.rst | 7 ++- integration/test_grid_manager.py | 5 +- src/allmydata/client.py | 54 ++++++++++++--------- src/allmydata/scripts/admin.py | 11 ++--- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/docs/proposed/grid-manager/managed-grid.rst b/docs/proposed/grid-manager/managed-grid.rst index 10d0c142a..5c388ffa1 100644 --- a/docs/proposed/grid-manager/managed-grid.rst +++ b/docs/proposed/grid-manager/managed-grid.rst @@ -174,7 +174,7 @@ Enrolling a Storage Server: Config You may edit the ``[storage]`` section of the ``tahoe.cfg`` file to turn on grid-management with ``grid_management = true``. You then must -also provide a ``[grid_management_keys]]`` section in the config-file which +also provide a ``[grid_management_keys]`` section in the config-file which lists ``name = path/to/certificate`` pairs. These certificate files are issued by the ``tahoe grid-manager sign`` @@ -278,7 +278,10 @@ certificates into the grid. We do this by adding some configuration (in ``tahoe.cfg``):: [storage] - grid_manager_certificate_files = gridmanager.cert + grid_management = true + + [grid_manager_certificates] + default = gridmanager.cert Add the above bit to each node's ``tahoe.cfg`` and re-start the storage nodes. diff --git a/integration/test_grid_manager.py b/integration/test_grid_manager.py index 075a1004a..f25819092 100644 --- a/integration/test_grid_manager.py +++ b/integration/test_grid_manager.py @@ -115,7 +115,6 @@ def test_reject_storage_server(reactor, request, storage_nodes, temp_dir, introd ) assert sorted(json.loads(gm_config)['storage_servers'].keys()) == ['storage0', 'storage1'] - # XXX FIXME need to shut-down and nuke carol when we're done this # test (i.d. request.addfinalizer) carol = yield util._create_node( @@ -136,7 +135,9 @@ def test_reject_storage_server(reactor, request, storage_nodes, temp_dir, introd with open(join(storage._node_dir, "gridmanager.cert"), "w") as f: f.write(cert) config = configutil.get_config(join(storage._node_dir, "tahoe.cfg")) - config.set("storage", "grid_manager_certificate_files", "gridmanager.cert") + config.set("storage", "grid_management", "True") + config.add_section("grid_manager_certificates") + config.set("grid_manager_certificates", "default", "gridmanager.cert") config.write(open(join(storage._node_dir, "tahoe.cfg"), "w")) # re-start this storage server diff --git a/src/allmydata/client.py b/src/allmydata/client.py index 50ceb448f..35512d8f5 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -59,6 +59,7 @@ def _valid_config_sections(): "stats_gatherer.furl", ), "grid_managers": None, # means "any options valid" + "grid_manager_certificates": None, "drop_upload": ( # deprecated already? "enabled", ), @@ -81,7 +82,7 @@ def _valid_config_sections(): "readonly", "reserved_space", "storage_dir", - "grid_manager_certificate_files", + "grid_management", ), "sftpd": ( "accounts.file", @@ -409,6 +410,34 @@ def create_storage_farm_broker(config, default_connection_handlers, foolscap_con return sb +def _load_grid_manager_certificates(config): + """ + Load all Grid Manager certificates in the config in a list. An + empty list is returned if there are none. + """ + grid_manager_certificates = [] + + cert_fnames = list(config.enumerate_section("grid_manager_certificates").values()) + for fname in cert_fnames: + fname = config.get_config_path(fname.decode('ascii')) + if not os.path.exists(fname): + raise ValueError( + "Grid Manager certificate file '{}' doesn't exist".format( + fname + ) + ) + with open(fname, 'r') as f: + cert = json.load(f) + if set(cert.keys()) != {"certificate", "signature"}: + raise ValueError( + "Unknown key in Grid Manager certificate '{}'".format( + fname + ) + ) + grid_manager_certificates.append(cert) + return grid_manager_certificates + + @implementer(IStatsProducer) class _Client(node.Node, pollmixin.PollMixin): @@ -604,27 +633,8 @@ class _Client(node.Node, pollmixin.PollMixin): grid_manager_certificates = [] - # XXX this is probably a bad idea for multiple fnames -- what - # about spaces in filenames? - - cert_fnames = self.get_config("storage", "grid_manager_certificate_files", "") - for fname in cert_fnames.split(): - fname = self.config.get_config_path(fname.decode('ascii')) - if not os.path.exists(fname): - raise ValueError( - "Grid Manager certificate file '{}' doesn't exist".format( - fname - ) - ) - with open(fname, 'r') as f: - cert = json.load(f) - if set(cert.keys()) != {"certificate", "signature"}: - raise ValueError( - "Unknown key in Grid Manager certificate '{}'".format( - fname - ) - ) - grid_manager_certificates.append(cert) + if self.config.get_config("storage", "grid_management", default=False, boolean=True): + grid_manager_certificates = _load_grid_manager_certificates(self.config) # XXX we should probably verify that the certificates are # valid and not expired, as that could be confusing for the diff --git a/src/allmydata/scripts/admin.py b/src/allmydata/scripts/admin.py index 60d31cfb8..3ddbe8d22 100644 --- a/src/allmydata/scripts/admin.py +++ b/src/allmydata/scripts/admin.py @@ -118,18 +118,15 @@ def add_grid_manager_cert(options): cert_fname = "{}.cert".format(options['name']) cert_path = config.get_config_path(cert_fname) cert_bytes = json.dumps(options.certificate_data, indent=4) + '\n' - # cert_name = options['name'] + cert_name = options['name'] if exists(cert_path): print("Already have file '{}'".format(cert_path), file=options.parent.parent.stderr) return 1 - gm_certs = config.get_config("storage", "grid_manager_certificate_files", "").split() - if cert_fname not in gm_certs: - gm_certs.append(cert_fname) - config.set_config("storage", "grid_manager_certificate_files", " ".join(gm_certs)) - - # print("grid_manager_certificate_files in {}: {}".format(config_path, len(gm_certs))) + config.set_config("storage", "grid_management", "True") + config.add_section("grid_manager_certificates") + config.set_config("grid_manager_certificates", cert_name, cert_fname) # write all the data out