Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept config args before and after the command #1530

Merged
merged 3 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions counterparty-cli/counterpartycli/server.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
#! /usr/bin/env python3

import os
import sys
import argparse
import logging


from termcolor import cprint

from counterpartylib.lib import log
from counterpartylib import server
from counterpartylib.lib import config
from counterpartycli.util import add_config_arguments
from counterpartycli.util import add_config_arguments, read_config_file
from counterpartycli.setup import generate_config_files
from counterpartycli import APP_VERSION

Expand Down Expand Up @@ -75,36 +73,54 @@ def main():
generate_config_files()

# Parse command-line arguments.
parser = argparse.ArgumentParser(prog=APP_NAME, description=f'Server for the {config.XCP_NAME} protocol', add_help=False)
parser = argparse.ArgumentParser(
prog=APP_NAME,
description=f'Server for the {config.XCP_NAME} protocol',
add_help=False,
exit_on_error=False
)
parser.add_argument('-h', '--help', dest='help', action='store_true', help='show this help message and exit')
parser.add_argument('-V', '--version', action='version', version=f"{APP_NAME} v{APP_VERSION}; counterparty-lib v{config.VERSION_STRING}")
parser.add_argument('--config-file', help='the path to the configuration file')

add_config_arguments(parser, CONFIG_ARGS, 'server.conf')
cmd_args = parser.parse_known_args()[0]
config_file_path = getattr(cmd_args, 'config_file', None)
configfile = read_config_file('server.conf', config_file_path)

add_config_arguments(parser, CONFIG_ARGS, configfile, add_default=True)

subparsers = parser.add_subparsers(dest='action', help='the action to be taken')

parser_server = subparsers.add_parser('start', help='run the server')
parser_server.add_argument('--config-file', help='the path to the configuration file')
parser_server.add_argument('--catch-up', choices=['normal', 'bootstrap'], default='normal', help='Catch up mode (default: normal)')
add_config_arguments(parser_server, CONFIG_ARGS, configfile)

parser_reparse = subparsers.add_parser('reparse', help='reparse all transactions in the database')
parser_reparse.add_argument('block_index', type=int, help='the index of the last known good block')
add_config_arguments(parser_reparse, CONFIG_ARGS, configfile)

parser_vacuum = subparsers.add_parser('vacuum', help='VACUUM the database (to improve performance)')
add_config_arguments(parser_vacuum, CONFIG_ARGS, configfile)

parser_rollback = subparsers.add_parser('rollback', help='rollback database')
parser_rollback.add_argument('block_index', type=int, help='the index of the last known good block')
add_config_arguments(parser_rollback, CONFIG_ARGS, configfile)

parser_kickstart = subparsers.add_parser('kickstart', help='rapidly build database by reading from Bitcoin Core blockchain')
parser_kickstart.add_argument('--bitcoind-dir', help='Bitcoin Core data directory')
parser_kickstart.add_argument('--max-queue-size', type=int, help='Size of the multiprocessing.Queue for parsing blocks')
parser_kickstart.add_argument('--debug-block', type=int, help='Rollback and run kickstart for a single block;')
add_config_arguments(parser_kickstart, CONFIG_ARGS, configfile)

subparsers.add_parser('bootstrap', help='bootstrap database with hosted snapshot')
parser_bootstrap = subparsers.add_parser('bootstrap', help='bootstrap database with hosted snapshot')
add_config_arguments(parser_bootstrap, CONFIG_ARGS, configfile)

subparsers.add_parser('check-db', help='do an integrity check on the database')
parser_checkdb = subparsers.add_parser('check-db', help='do an integrity check on the database')
add_config_arguments(parser_checkdb, CONFIG_ARGS, configfile)

subparsers.add_parser('show-config', help='Show counterparty-server configuration')
parser_show_config = subparsers.add_parser('show-config', help='Show counterparty-server configuration')
add_config_arguments(parser_show_config, CONFIG_ARGS, configfile)

args = parser.parse_args()

Expand Down
59 changes: 23 additions & 36 deletions counterparty-cli/counterpartycli/util.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
#! /usr/bin/python3

import sys
import os
import threading
import decimal
import time
import json
import re
import requests
import collections
import logging
import binascii
from datetime import datetime
from dateutil.tz import tzlocal
import argparse
import configparser
import appdirs
import tarfile
import urllib.request
import shutil
import codecs
import tempfile

from halo import Halo
from termcolor import colored, cprint
Expand Down Expand Up @@ -122,21 +109,17 @@
return value_output(quantity, asset, divisible)


# Set default values of command line arguments with config file
def add_config_arguments(arg_parser, config_args, default_config_file, config_file_arg_name='config_file'):
cmd_args = arg_parser.parse_known_args()[0]

config_file = getattr(cmd_args, config_file_arg_name, None)
if not config_file:
def read_config_file(default_config_file, config_file_path=None):
if not config_file_path:
config_dir = appdirs.user_config_dir(appauthor=config.XCP_NAME, appname=config.APP_NAME, roaming=True)
if not os.path.isdir(config_dir):
os.makedirs(config_dir, mode=0o755)
config_file = os.path.join(config_dir, default_config_file)
config_file_path = os.path.join(config_dir, default_config_file)

# clean BOM
bufsize = 4096
bomlen = len(codecs.BOM_UTF8)
with codecs.open(config_file, 'r+b') as fp:
with codecs.open(config_file_path, 'r+b') as fp:
chunk = fp.read(bufsize)
if chunk.startswith(codecs.BOM_UTF8):
i = 0
Expand All @@ -150,23 +133,27 @@
fp.seek(-bomlen, os.SEEK_CUR)
fp.truncate()

logger.debug(f'Loading configuration file: `{config_file}`')
logger.debug(f'Loading configuration file: `{config_file_path}`')
configfile = configparser.SafeConfigParser(allow_no_value=True, inline_comment_prefixes=('#', ';'))
with codecs.open(config_file, 'r', encoding='utf8') as fp:
with codecs.open(config_file_path, 'r', encoding='utf8') as fp:
configfile.readfp(fp)

if not 'Default' in configfile:
configfile['Default'] = {}

# Initialize default values with the config file.
for arg in config_args:
key = arg[0][-1].replace('--', '')
if 'action' in arg[1] and arg[1]['action'] == 'store_true' and key in configfile['Default']:
arg[1]['default'] = configfile['Default'].getboolean(key)
elif key in configfile['Default'] and configfile['Default'][key]:
arg[1]['default'] = configfile['Default'][key]
elif key in configfile['Default'] and arg[1].get('nargs', '') == '?' and 'const' in arg[1]:
arg[1]['default'] = arg[1]['const'] # bit of a hack
arg_parser.add_argument(*arg[0], **arg[1])

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

Fixed Show fixed Hide fixed

Check warning

Code scanning / pylint

Trailing whitespace. Warning

Trailing whitespace.
return configfile


def add_config_arguments(parser, args, configfile, add_default=False):
for arg in args:
if add_default:
key = arg[0][-1].replace('--', '')
if 'action' in arg[1] and arg[1]['action'] == 'store_true' and key in configfile['Default']:
arg[1]['default'] = configfile['Default'].getboolean(key)
elif key in configfile['Default'] and configfile['Default'][key]:
arg[1]['default'] = configfile['Default'][key]
elif key in configfile['Default'] and arg[1].get('nargs', '') == '?' and 'const' in arg[1]:
arg[1]['default'] = arg[1]['const'] # bit of a hack
else:
arg[1]['default'] = argparse.SUPPRESS
parser.add_argument(*arg[0], **arg[1])
Loading