The [[ https://github.com/Whonix/proposals/blob/master/635-listen-port-convention.txt | Listen Port Convention proposal ]] depends on the parsing of specific files within specific directories. A config parser with the following features should be implemented:
- Provide a Python package
- Provide a command-line interface for non-Python apps
- Provide json and eval serializers
- Allow different parts of it to be customized
I will create a repo and post it here once I start working on this. Here is the initial code:
def parse_global(cls, filepath):
"""Read `filepath`, parse it and return all directory paths found.
The directories in the list are in the order they are intended to be
def is_config_file(cls, filename):
"""Return `True` if `filename` is a config file. `False` otherwise."""
def find_config_files(cls, dirpath):
"""Walk through the directory and return all file paths found.
Depending on `is_config_file`, each file is prepended by the
directory's path and added to the list. The files in the list are in
the order they are intended to be read.
def parse_file(cls, filepath, configs=None):
"""Read `filepath`, parse it and return a `config: value` dict.
If no configs are provided, a new dict is created. As the file is read,
values are added to the configs with
`add_config(configs, config, value)`."""
def add_config(cls, configs, config, value):
"""Add `config: value` to the configs dict and return it.
In case the config did not exist, it is added to the dict. Otherwise,
it replaces or merges to the existing one.
def parse(cls, name):
"""Read the name of the config and return a `config: value` dict.
The name defaults to a `/etc/<name>.conf` file path but can optionally
specify a different path and extension. Its format should be something
cfgs = dict()
for dirpath in cls.parse_global(name):
for filepath in cls.find_config_files(dirpath):
cfgs = cls.parse_file(filepath, cfgs)
def serialize(cls, configs):
"""Serialize the configs dict into a convenient format."""
def parse_to_serialized(cls, name):
"""Parse configs and return them serialized."""
"""Read a config name and print the serialized configs.
This function should be accessed through an entry point. The name is passed
via a command-line call and returns the configs in a format that
applications are able to read in the language they use.
argparser = argparse.ArgumentParser()
args = argparser.parse_args()
A Python app would use the parser to retrieve the `listen_ip` config of the `listen` convention with the following code:
cfgs = Parser.parse('listen')
listen_ip = cfgs['listen_ip']
# bind on `listen_ip`
A non-Python app would receive the serialized configs with the following call:
$ configparser listen
P.S. We need a good name for this.
This is a follow-up ticket to https://phabricator.whonix.org/T635