From b5eb8ecfa562e3584062d8a135bcef939940d4cd Mon Sep 17 00:00:00 2001 From: Alex Bosworth Date: Sat, 5 Sep 2020 22:25:27 -0700 Subject: [PATCH] improve docker support, handle no nodes case in nodes command --- .gitignore | 3 +- CHANGELOG.md | 6 +++ Dockerfile | 3 +- README.md | 60 ++++++++++++++++++++++-- nodes/adjust_saved_nodes.js | 14 +++++- nodes/get_saved_nodes.js | 10 ++-- nodes/put_saved_credentials.js | 13 ++++- package-lock.json | 45 ++++++++++++++++-- package.json | 5 +- test/nodes/test_put_saved_credentials.js | 10 +++- 10 files changed, 149 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 4d42079..1313030 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ +*~ +*.gz .env .nyc_output -*~ node_modules diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c15f2..219d63e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Versions +## Version 5.46.2 + +Added additional instructions for Docker usage in README.md + +- `nodes`: Show empty nodes list if there is no home directory + ## Version 5.46.1 - `fees`: Tolerate LND setting fees inaccurately by 1 ppm diff --git a/Dockerfile b/Dockerfile index 66bda2a..603e936 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM node:latest AS build -# UID / GID 1000 is default for user `node` in the `node:latest` image, this way the process wil run as a non-root user +# UID / GID 1000 is default for user `node` in the `node:latest` image, this +# way the process will run as a non-root user ARG USER_ID=1000 ARG GROUP_ID=1000 ENV USER_ID=$USER_ID diff --git a/README.md b/README.md index 4c6c3ad..defd8e1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Commands for working with LND balances. [![Coverage Status](https://coveralls.io/repos/github/alexbosworth/balanceofsatoshis/badge.svg?branch=master)](https://coveralls.io/github/alexbosworth/balanceofsatoshis?branch=master) [![Build Status](https://travis-ci.org/alexbosworth/balanceofsatoshis.svg?branch=master)](https://travis-ci.org/alexbosworth/balanceofsatoshis) -## Install +## Install - Requires an [installation of Node v10.12.0+](https://gist.github.com/alexbosworth/8fad3d51f9e1ff67995713edf2d20126) - Have a RaspiBlitz? Check out [this install guide](https://gist.github.com/openoms/823f99d1ab6e1d53285e489f7ba38602) @@ -14,6 +14,9 @@ Commands for working with LND balances. If you want to try out any command without npm install, you can also do `npx balanceofsatoshis` to run a command directly. +If you have [Docker](https://docs.docker.com/get-docker/) installed, you can +[run through Docker](#Docker) instead. + ```shell npm install -g balanceofsatoshis ``` @@ -287,9 +290,55 @@ Examples of shell scripts that could be executed by crontab: # sends email if the inbound liquidity drops below a 1,000,000 sats ``` -## Docker Usage +## Docker -Potentially this can be used with Docker with a simple docker file +### Docker Load + +Install the Docker image: + +``` +docker pull alexbosworth/balanceofatoshis +``` + +You can also build the image yourself: `npm run build-docker`, this will make +`balanceofsatoshis.tar.gz` that you can rsync or scp somewhere else and then +do `docker load < balanceofsatoshis.tar.gz`. + +Once the image is installed, you can "docker run" commands for all the commands: + +``` +# Make sure you have a home directory created to give Docker access to +mkdir $HOME/.bos + +docker run -it --rm -v $HOME/.bos:/home/node/.bos alexbosworth/balanceofsatoshis --version +# Should output the version +``` + +This maps your home directory to the docker home directory to enable +persistence of credentials. + +If you want it to automatically detect your local node, also pass the LND home +dir as an additional -v argument to docker run: + +If you are on MacOS: + +``` +-v $HOME/Library/Application\ Support/Lnd/:/home/node/.lnd +``` + +Or on Linux: + +``` +-v $HOME/.lnd:/home/node/.lnd +``` + +Otherwise you can just pass the local node credentials as shown above using the +saved nodes. + +### Build Your Own + +If you don't want to use the Dockerfile, you can build a docker file for +yourself ```dockerfile FROM node:latest @@ -297,6 +346,11 @@ RUN npm install balanceofsatoshis ENTRYPOINT [ "/node_modules/balanceofsatoshis/bos" ] ``` +### Run Shell Script + +If you don't want to type out "docker run", and don't have an alias for it, you +can create a simple shell script to fill that part in: + ```shell #! /usr/bin/env bash docker run -it --rm -v=$HOME/.bos:/root/.bos bos:latest ${@:1} diff --git a/nodes/adjust_saved_nodes.js b/nodes/adjust_saved_nodes.js index 92606d6..b402c6a 100644 --- a/nodes/adjust_saved_nodes.js +++ b/nodes/adjust_saved_nodes.js @@ -1,3 +1,6 @@ +const {homedir} = require('os'); +const {join} = require('path'); + const asyncAuto = require('async/auto'); const {generateKeyPair} = require('crypto'); const {privateDecrypt} = require('crypto'); @@ -8,6 +11,7 @@ const deleteNodeCredentials = require('./delete_node_credentials'); const encryptSavedMacaroons = require('./encrypt_saved_macaroons'); const getSavedCredentials = require('./get_saved_credentials'); const getSavedNodes = require('./get_saved_nodes'); +const {home} = require('./constants'); const registerNode = require('./register_node'); const {isArray} = Array; @@ -87,8 +91,16 @@ module.exports = (args, cbk) => { return cbk(); }, + // Make sure the home directory is there + registerHomeDir: ['validate', ({}, cbk) => { + return args.fs.makeDirectory(join(...[homedir(), home]), err => { + // Ignore errors, the directory may already be there + return cbk(); + }); + }], + // Register node - register: ['validate', ({}, cbk) => { + register: ['registerHomeDir', ({}, cbk) => { if (!args.is_registering) { return cbk(); } diff --git a/nodes/get_saved_nodes.js b/nodes/get_saved_nodes.js index b80d0c7..e73a34e 100644 --- a/nodes/get_saved_nodes.js +++ b/nodes/get_saved_nodes.js @@ -1,5 +1,5 @@ -const {join} = require('path'); const {homedir} = require('os'); +const {join} = require('path'); const asyncAuto = require('async/auto'); const asyncFilter = require('async/filter'); @@ -32,9 +32,6 @@ const {home} = require('./constants'); module.exports = ({fs}, cbk) => { return new Promise((resolve, reject) => { return asyncAuto({ - // Data directory - dataDir: cbk => cbk(null, join(...[homedir(), home])), - // Check arguments validate: cbk => { if (!fs) { @@ -56,6 +53,11 @@ module.exports = ({fs}, cbk) => { return cbk(); }, + // Data directory + dataDir: ['validate', ({}, cbk) => { + return cbk(null, join(...[homedir(), home])); + }], + // Check that the data directory exists checkDataDir: ['dataDir', ({dataDir}, cbk) => { return fs.getFileStatus(dataDir, (err, res) => { diff --git a/nodes/put_saved_credentials.js b/nodes/put_saved_credentials.js index 61db274..5319c98 100644 --- a/nodes/put_saved_credentials.js +++ b/nodes/put_saved_credentials.js @@ -17,6 +17,7 @@ const stringify = obj => JSON.stringify(obj, null, 2); [encrypted_macaroon]: [encrypted_to]: [] fs: { + makeDirectory: writeFile: (path, contents, cbk) => {} } [macaroon]: @@ -58,8 +59,18 @@ module.exports = (args, cbk) => { return cbk(); }, + // Make sure the node directory is there + registerDirectory: ['validate', ({}, cbk) => { + const nodeDirectory = join(...[homedir(), home, args.node]); + + return args.fs.makeDirectory(nodeDirectory, err => { + // Ignore errors, the directory may already be there + return cbk(); + }); + }], + // Write credentials - writeCredentials: ['validate', ({}, cbk) => { + writeCredentials: ['registerDirectory', ({}, cbk) => { const file = stringify({ cert: args.cert || undefined, encrypted_macaroon: args.encrypted_macaroon || undefined, diff --git a/package-lock.json b/package-lock.json index 1118a83..efb7907 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "balanceofsatoshis", - "version": "5.46.1", + "version": "5.46.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3227,9 +3227,9 @@ } }, "ln-service": { - "version": "49.9.1", - "resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.9.1.tgz", - "integrity": "sha512-CppZ2hqkvW9m3dymV7GZ8aDwh28Q86Rb4OIFo/Y9zkmpE1Ow0SSVQAHG6+quJspS8koz5Jnhtht9eFmzivWVZg==", + "version": "49.9.2", + "resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.9.2.tgz", + "integrity": "sha512-dcKtOQcfFfRMq+A/+SoGMwhD1JACUnybd9/SJyy2M8NQBcr9Yoku1+dpIJ32EW7er7jrMCwtAyb8euePnOOFig==", "requires": { "@datastructures-js/priority-queue": "4.1.1", "async": "3.2.0", @@ -3240,7 +3240,7 @@ "bolt09": "0.1.1", "cors": "2.8.5", "express": "4.17.1", - "invoices": "1.1.2", + "invoices": "1.1.3", "is-base64": "1.1.0", "lightning": "2.0.40", "macaroon": "3.0.4", @@ -3253,6 +3253,19 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==" }, + "invoices": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/invoices/-/invoices-1.1.3.tgz", + "integrity": "sha512-+RZmDmgVXvn6hAzGUqdl+1q8lEm9Th5XO/yg2aAIHpxhBc+BrrdCaMjjsk+weoZp9jm6LA92Dt2bzo+4ou1SVw==", + "requires": { + "bech32": "1.1.4", + "bitcoinjs-lib": "5.1.10", + "bn.js": "5.1.3", + "bolt07": "1.5.2", + "bolt09": "0.1.1", + "secp256k1": "4.0.2" + } + }, "lightning": { "version": "2.0.40", "resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.40.tgz", @@ -3270,6 +3283,28 @@ "express": "4.17.1", "grpc": "1.24.3", "invoices": "1.1.2" + }, + "dependencies": { + "invoices": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/invoices/-/invoices-1.1.2.tgz", + "integrity": "sha512-SKLHrWndT6weOZTFeAT8w37GBn05pFhEBJn9NTxUaCh10eW4Nf1KuhDWuYGuIsT5Tw/ltSSa78RYOYVgr/werA==", + "requires": { + "bech32": "1.1.4", + "bitcoinjs-lib": "5.1.10", + "bn.js": "5.1.2", + "bolt07": "1.5.2", + "bolt09": "0.1.1", + "secp256k1": "4.0.2" + }, + "dependencies": { + "bn.js": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==" + } + } + } } } } diff --git a/package.json b/package.json index 6cb5477..9f8e63e 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "ini": "1.3.5", "inquirer": "7.3.3", "ln-accounting": "4.1.7", - "ln-service": "49.9.1", + "ln-service": "49.9.2", "ln-sync": "0.0.9", "moment": "2.27.0", "probing": "1.2.0", @@ -65,7 +65,8 @@ "url": "https://github.com/alexbosworth/balanceofsatoshis.git" }, "scripts": { + "build-docker": "docker build -t alexbosworth/balanceofsatoshis . && docker save alexbosworth/balanceofsatoshis > balanceofsatoshis.tar && gzip balanceofsatoshis.tar", "test": "tap test/arrays/*.js test/balances/*.js test/chain/*.js test/display/*.js test/encryption/*.js test/fiat/*.js test/lnd/*.js test/network/*.js test/nodes/*.js test/responses/*.js test/routing/*.js test/swaps/*.js test/telegram/*.js test/wallets/*.js" }, - "version": "5.46.1" + "version": "5.46.2" } diff --git a/test/nodes/test_put_saved_credentials.js b/test/nodes/test_put_saved_credentials.js index c42b824..5a39ad8 100644 --- a/test/nodes/test_put_saved_credentials.js +++ b/test/nodes/test_put_saved_credentials.js @@ -40,7 +40,10 @@ const tests = [ }, { args: { - fs: {writeFile: (path, file, cbk) => cbk('err')}, + fs: { + makeDirectory: (path, cbk) => cbk(), + writeFile: (path, file, cbk) => cbk('err'), + }, macaroon: 'macaroon', node: 'node', socket: 'socket', @@ -50,7 +53,10 @@ const tests = [ }, { args: { - fs: {writeFile: (path, file, cbk) => cbk()}, + fs: { + makeDirectory: (path, cbk) => cbk(), + writeFile: (path, file, cbk) => cbk(), + }, encrypted_macaroon: 'encrypted_macaroon', encrypted_to: [], node: 'node',