coin_daemon_control.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2023 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen
  9. # https://gitlab.com/mmgen/mmgen
  10. """
  11. test.include.coin_daemon_control: Start and stop daemons for the MMGen test suite
  12. """
  13. from .tests_header import repo_root
  14. from mmgen.common import *
  15. action = g.prog_name.split('-')[0]
  16. opts_data = {
  17. 'sets': [('debug',True,'verbose',True)],
  18. 'text': {
  19. 'desc': f'{action.capitalize()} coin daemons for the MMGen test suite',
  20. 'usage':'[opts] <network IDs>',
  21. 'options': """
  22. -h, --help Print this help message
  23. --, --longhelp Print help message for long options (common options)
  24. -D, --debug Produce debugging output (implies --verbose)
  25. -d, --datadir= Override the default datadir
  26. -i, --daemon-ids Print all known daemon IDs
  27. -m, --mainnet-only Perform operations for mainnet daemons only
  28. -n, --no-daemonize Don't fork daemon to background
  29. -p, --port-shift= Shift the RPC port by this number
  30. -s, --get-state Get the state of the daemon(s) and exit
  31. -t, --testing Testing mode. Print commands but don't execute them
  32. -q, --quiet Produce quieter output
  33. -u, --usermode Run the daemon in user (non test-suite) mode
  34. -v, --verbose Produce more verbose output
  35. -V, --print-version Print version strings from exec’ed daemons (not RPC)
  36. -W, --no-wait Don't wait for daemons to change state before exiting
  37. """,
  38. 'notes': """
  39. Valid network IDs: {nid}, all, or no_xmr
  40. """
  41. },
  42. 'code': {
  43. 'options': lambda s: s.format(a=action.capitalize(),pn=g.prog_name),
  44. 'notes': lambda s,help_notes: s.format(nid=help_notes('coin_daemon_network_ids'))
  45. }
  46. }
  47. cmd_args = opts.init(opts_data)
  48. from mmgen.daemon import *
  49. class warn_missing_exec(oneshot_warning):
  50. color = 'nocolor'
  51. message = 'daemon executable {!r} not found on this system!'
  52. def run(network_id=None,proto=None,daemon_id=None,missing_exec_ok=True):
  53. d = CoinDaemon(
  54. network_id = network_id,
  55. proto = proto,
  56. test_suite = not opt.usermode,
  57. opts = ['no_daemonize'] if opt.no_daemonize else None,
  58. port_shift = int(opt.port_shift or 0),
  59. datadir = opt.datadir,
  60. daemon_id = daemon_id )
  61. if opt.mainnet_only and d.network != 'mainnet':
  62. return
  63. d.debug = d.debug or opt.debug
  64. d.wait = not opt.no_wait
  65. if missing_exec_ok:
  66. try:
  67. d.get_exec_version_str()
  68. except:
  69. if not opt.quiet:
  70. warn_missing_exec( div=d.exec_fn, fmt_args=(d.exec_fn,) )
  71. return
  72. if opt.print_version:
  73. msg('{:16} {}'.format( d.exec_fn+':', d.get_exec_version_str() ))
  74. elif opt.get_state:
  75. print(d.state_msg())
  76. elif opt.testing:
  77. for cmd in d.start_cmds if action == 'start' else [d.stop_cmd]:
  78. print(' '.join(cmd))
  79. else:
  80. if action == 'stop' and hasattr(d,'rpc'):
  81. async_run(d.rpc.stop_daemon(quiet=opt.quiet))
  82. else:
  83. d.cmd(action,quiet=opt.quiet)
  84. if opt.daemon_ids:
  85. print('\n'.join(CoinDaemon.all_daemon_ids()))
  86. elif 'all' in cmd_args or 'no_xmr' in cmd_args:
  87. if len(cmd_args) != 1:
  88. die(1,"'all' or 'no_xmr' must be the sole argument")
  89. from mmgen.protocol import init_proto
  90. for coin in CoinDaemon.coins:
  91. if coin == 'XMR' and cmd_args[0] == 'no_xmr':
  92. continue
  93. for daemon_id in CoinDaemon.get_daemon_ids(coin):
  94. for network in CoinDaemon.get_daemon(coin,daemon_id).networks:
  95. run(
  96. proto = init_proto(coin=coin,network=network),
  97. daemon_id = daemon_id,
  98. missing_exec_ok = True )
  99. else:
  100. ids = cmd_args
  101. network_ids = CoinDaemon.get_network_ids()
  102. if not ids:
  103. opts.usage()
  104. for i in ids:
  105. if i not in network_ids:
  106. die(1,f'{i!r}: invalid network ID')
  107. for network_id in ids:
  108. run(network_id=network_id.lower())