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

Add online help system #75

Draft
wants to merge 16 commits into
base: master
Choose a base branch
from
Draft
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,7 @@ dmypy.json
# Pyre type checker
.pyre/

\.DS_Store
\.DS_Store

# Dropped by noma?
public_html
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"sphinx.ext.coverage",
"sphinx.ext.viewcode",
"recommonmark",
"sphinx.ext.napoleon",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down
64 changes: 3 additions & 61 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,78 +13,20 @@ CLI utility and Python API to manage bitcoin lightning nodes.

Command-line Usage
==================
**node**::

noma (info|start|stop|restart|logs|check|status)
noma (temp|swap|ram)
noma (freq|memory|voltage) [<device>]
noma usb-setup
noma tunnel <port> <host>
noma (backup|restore|source|diff|devtools)
noma reinstall [--full]

**bitcoind**::

noma bitcoind (start|stop|info|fastsync|status|check)
noma bitcoind get <key>
noma bitcoind set <key> <value>
noma bitcoind logs [--tail]

**lnd**::

noma lnd (start|stop|info)
noma lnd logs [--tail]
noma lnd connect <address>
noma lnd (create|unlock|status|check)
noma lnd lncli [<command>...]
noma lnd get <key> [<section>] [<path>]
noma lnd set <key> <value> [<section>] [<path>]
noma lnd autounlock
noma lnd autoconnect [<path>]
noma lnd lndconnectapp <hostport>
noma lnd lndconnectstring <hostport>

**noma**::

noma (-h|--help)
noma --version

Options:
-h --help Show this screen.
--version Show version.
.. automodule:: noma.noma

API Modules
===========

node
----
.. automodule:: noma.node
:members:

bitcoind
--------
.. automodule:: noma.bitcoind
:members:
:members: start, stop, check, logs, info

lnd
---
.. automodule:: noma.lnd
:members:

install
-------
.. automodule:: noma.install
:members:

usb
---
.. automodule:: noma.usb
:members:

rpcauth
-------
.. automodule:: noma.rpcauth
:members:
:members: create, backup, autounlock, autoconnect, savepeers, connectapp, connectstring

Indices and tables
==================
Expand Down
45 changes: 45 additions & 0 deletions docs/install_manpage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/sh

# build and install manpage for noma
set -eu

MANPAGE="noma.1"
MAN_DIR="/usr/local/man/man1"
MAN_DIR_ALPINE="/usr/share/man/man1"


check_root() {
if [ "$(id -u)" != "0" ]; then
echo "Error: You must be root to install"
exit 1
fi
}

check_directory() {
if [ ! -d "docs" ]; then
echo "Error: must be run from the noma root directory (e.g 'docs/install_manpage.sh')"
exit 1
fi
}

alpine_os() {
if [ -f "/etc/alpine-release" ]; then
return
fi
}

check_root
check_directory

if [ alpine_os ]; then
MAN_DIR=$MAN_DIR_ALPINE
fi

cd docs
sphinx-build . _build -b man
install -g 0 -o 0 -m 0644 _build/$MANPAGE $MAN_DIR
gzip ${MAN_DIR}/${MANPAGE}

if [ ! alpine_os ]; then
mandb
fi
3 changes: 3 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ debian_install() {

# noma
python3 setup.py develop

# Install manpage
docs/install_manpage.sh
}

start_noma() {
Expand Down
69 changes: 17 additions & 52 deletions noma/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ def move_cache(cache_dir="/media/mmcblk0p1/cache", var_cache="/var/cache/apk"):
if setup.returncode == 0:
print("setup-apkcache was successful")
else:
raise OSError(
"setup-apkcache was not successful \n" + setup.stdout
)
raise OSError("setup-apkcache was not successful \n" + setup.stdout)
return setup.returncode


Expand Down Expand Up @@ -79,18 +77,14 @@ def install_apk_deps():
def mnt_ext4(device, path):
"""Mount device at path using ext4"""
exitcode = call(
["mount", "-t ext4", "/dev/" + device, path],
stdout=DEVNULL,
stdin=DEVNULL,
["mount", "-t ext4", "/dev/" + device, path], stdout=DEVNULL, stdin=DEVNULL
)
return exitcode


def mnt_any(device, path):
"""Mount device at path using any filesystem"""
exitcode = call(
["mount", "/dev/" + device, path], stdout=DEVNULL, stdin=DEVNULL
)
exitcode = call(["mount", "/dev/" + device, path], stdout=DEVNULL, stdin=DEVNULL)
return exitcode


Expand Down Expand Up @@ -118,21 +112,15 @@ def check_for_destruction(device, path):
destroy = Path(path + "/DESTROY_ALL_DATA_ON_THIS_DEVICE/").is_dir()
if destroy:
print("Destruction flag found!")
print(
"Going to destroy all data on /dev/{} in 3 seconds...".format(
device
)
)
print("Going to destroy all data on /dev/{} in 3 seconds...".format(device))
sleep(3)
unmounted = call(["umount", "/dev/" + device])
if unmounted and not usb.is_mounted(device):
print("Going to format {d} with ext4 now".format(d=device))
call(["mkfs.ext4", "-F", "/dev/" + device])
if mnt_ext4(device, path) == 0 and usb.is_mounted(device):
print(
"{d} formatted with ext4 successfully and mounted.".format(
d=device
)
"{d} formatted with ext4 successfully and mounted.".format(d=device)
)
return True
else:
Expand Down Expand Up @@ -176,17 +164,9 @@ def fallback_mount(partition, path):
print("Attempting to mount with any filesystem...")

if mnt_any(partition, path) == 0 and usb.is_mounted(partition):
print(
"{d} mounted at {p} with any filesystem".format(
d=partition, p=path
)
)
print("{d} mounted at {p} with any filesystem".format(d=partition, p=path))
return True
print(
"Error: {} usb is not mountable with any supported format".format(
partition
)
)
print("Error: {} usb is not mountable with any supported format".format(partition))
print("Cannot continue without all USB storage devices")
return False

Expand All @@ -201,9 +181,7 @@ def setup_fstab(device, mount):
)
file.write(fstab)
else:
print(
"Warning: {} usb does not seem to be ext4 formatted".format(device)
)
print("Warning: {} usb does not seem to be ext4 formatted".format(device))
print("{} will not be added to /etc/fstab".format(device))


Expand Down Expand Up @@ -237,23 +215,18 @@ def create_file():

if dd.returncode != 0:
# dd has non-zero exit code
raise OSError(
"Warning: dd cannot create swap file \n" + str(dd.stdout)
)
raise OSError("Warning: dd cannot create swap file \n" + str(dd.stdout))
return True

def mk_swap():
mkswap = run(
["mkswap", "/media/volatile/volatile/swap"],
stdout=PIPE,
stderr=STDOUT,
["mkswap", "/media/volatile/volatile/swap"], stdout=PIPE, stderr=STDOUT
)

if mkswap.returncode != 0:
# mkswap has non-zero exit code
raise OSError(
"Warning: mkswap could not create swap file \n"
+ str(mkswap.stdout)
"Warning: mkswap could not create swap file \n" + str(mkswap.stdout)
)
return True

Expand Down Expand Up @@ -343,16 +316,10 @@ def usb_setup():
# We confirmed device is mountable, readable, writable
setup_fstab(device, mountpoints[num])
else:
print(
"Mounting {d} with any filesystem unsuccessful".format(
d=device
)
)
print("Mounting {d} with any filesystem unsuccessful".format(d=device))
exit(1)
else:
print(
"Error: {p} directory not available".format(p=mountpoints[num])
)
print("Error: {p} directory not available".format(p=mountpoints[num]))
exit(1)

def setup_volatile():
Expand All @@ -371,14 +338,12 @@ def setup_important():
noma.bitcoind.create()
if noma.bitcoind.check():
noma.bitcoind.set_prune("550")
noma.bitcoind.set_rpcauth(
"/media/archive/archive/bitcoin/bitcoin.conf"
)
noma.bitcoind.set_rpcauth("/media/archive/archive/bitcoin/bitcoin.conf")

import noma.lnd

print("Creating lnd files")
noma.lnd.check_wallet()
noma.lnd.create()
if noma.lnd.check():
noma.lnd.setup_tor()

Expand Down Expand Up @@ -461,8 +426,8 @@ def install_box():
noma.node.start()
install_crontab()
if noma.lnd.check():
print("Checking lnd wallet")
noma.lnd.check_wallet()
print("Creating lnd wallet")
noma.lnd.create()

print("Removing post-install from default runlevel")
call(["rc-update", "del", "lncm-post", "default"])
Expand Down
37 changes: 18 additions & 19 deletions noma/lnd.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import noma.config as cfg


def check_wallet():
def create():
"""
This will either import an existing seed (or our own generated one),
or use LND to create one.
Expand Down Expand Up @@ -51,19 +51,13 @@ def encodemacaroons(macaroonfile=cfg.MACAROON_PATH, tlsfile=cfg.TLS_CERT_PATH):
)
tlsencoded = tlstrim.encode("utf-8")

return {
"status": "OK",
"certificate": tlsencoded,
"macaroon": macaroonencoded,
}
return {"status": "OK", "certificate": tlsencoded, "macaroon": macaroonencoded}
else:
return {"status": "File Not Found"}


def connectstring(
hostname=cfg.URL_GRPC,
macaroonfile=cfg.MACAROON_PATH,
tlsfile=cfg.TLS_CERT_PATH,
hostname=cfg.URL_GRPC, macaroonfile=cfg.MACAROON_PATH, tlsfile=cfg.TLS_CERT_PATH
):
"""Show lndconnect string for remote wallets such as Zap"""
result = encodemacaroons(macaroonfile, tlsfile)
Expand Down Expand Up @@ -223,13 +217,17 @@ def backup():
# scp options:
# -B for non-interactive batch mode
# -p to preserve modification & access time, modes
complete = run(["scp",
"-B",
"-i {}".format(cfg.SSH_IDENTITY),
"-p",
"-P {}".format(cfg.SSH_PORT),
"{}".format(cfg.CHANNEL_BACKUP),
"{}".format(cfg.SSH_TARGET)])
complete = run(
[
"scp",
"-B",
"-i {}".format(cfg.SSH_IDENTITY),
"-p",
"-P {}".format(cfg.SSH_PORT),
"{}".format(cfg.CHANNEL_BACKUP),
"{}".format(cfg.SSH_TARGET),
]
)
return complete.returncode
print("Error: channel.backup not found")
return exit(1)
Expand Down Expand Up @@ -331,12 +329,13 @@ def create_wallet():
1. Check if there's already a wallet. If there is, then exit.
2. Check for password.txt
3. If doesn't exist then check for whether we should save the password
(SAVE_PASSWORD_CONTROL_FILE exists) or not
(SAVE_PASSWORD_CONTROL_FILE exists) or not
4. If password.txt exists import password in.
5. If password.txt doesn't exist and we don't save the password, create a
password and save it in temporary path as defined in PASSWORD_FILE_PATH
password and save it in temporary path as defined in PASSWORD_FILE_PATH
6. Now start the wallet creation. Look for a seed defined in SEED_FILENAME,
if not existing then generate a wallet based on the seed by LND.
if not existing then generate a wallet based on the seed by LND.

"""
password_str = _wallet_password()

Expand Down
Loading