From c3535e6ed3829a728cf4744bef6d5901324a293e Mon Sep 17 00:00:00 2001 From: Fabio Cigliano Date: Sat, 16 Jun 2018 22:55:42 +1200 Subject: [PATCH] Lamassu update script changes (#126) * lamassu-migrate-config script added + lamassu-default.json * lamassu update script changes * lamassu-update unit test added --- bin/lamassu-migrate-config | 13 +++++++++ bin/lamassu-update | 52 +++++++++++++++++++++++++++++++----- install | 4 ++- lamassu-default.json | 17 ++++++++++++ lib/migrate-options.js | 51 +++++++++++++++++++++++++++++++++++ lib/options-loader.js | 46 +++++++++++++++++++++++++++++++ lib/options.js | 31 ++------------------- test/unit/migrate-options.js | 35 ++++++++++++++++++++++++ 8 files changed, 213 insertions(+), 36 deletions(-) create mode 100755 bin/lamassu-migrate-config mode change 100644 => 100755 bin/lamassu-update create mode 100644 lamassu-default.json create mode 100644 lib/migrate-options.js create mode 100644 lib/options-loader.js create mode 100644 test/unit/migrate-options.js diff --git a/bin/lamassu-migrate-config b/bin/lamassu-migrate-config new file mode 100755 index 00000000..2344c454 --- /dev/null +++ b/bin/lamassu-migrate-config @@ -0,0 +1,13 @@ +#!/usr/bin/env node + +const migrate = require('../lib/migrate-options') + +migrate.run() + .then(() => { + console.log('lamassu.json Migration succeeded.') + process.exit(0) + }) + .catch(err => { + console.error('lamassu.json Migration failed: %s', err) + process.exit(1) + }) diff --git a/bin/lamassu-update b/bin/lamassu-update old mode 100644 new mode 100755 index df6848ac..985f9dd8 --- a/bin/lamassu-update +++ b/bin/lamassu-update @@ -1,10 +1,50 @@ #!/usr/bin/env bash set -e -supervisorctl stop lamassu-server -supervisorctl stop lamassu-admin-server -npm -g install lamassu/lamassu-server#v5 --unsafe-perm -lamassu-migrate -supervisorctl start lamassu-server -supervisorctl start lamassu-admin-server +export LOG_FILE=/tmp/update.$(date +"%Y%m%d").log +rm -f ${LOG_FILE} + +decho () { + echo `date +"%H:%M:%S"` $1 + echo `date +"%H:%M:%S"` $1 >> ${LOG_FILE} +} + +cat <<'FIG' + _ +| | __ _ _ __ ___ __ _ ___ ___ _ _ ___ ___ _ ____ _____ _ __ +| |/ _` | '_ ` _ \ / _` / __/ __| | | |_____/ __|/ _ \ '__\ \ / / _ \ '__| +| | (_| | | | | | | (_| \__ \__ \ |_| |_____\__ \ __/ | \ V / __/ | +|_|\__,_|_| |_| |_|\__,_|___/___/\__,_| |___/\___|_| \_/ \___|_| +FIG + +echo -e "\nStarting \033[1mlamassu-server\033[0m update. This will take a few minutes...\n" + +if [ "$(whoami)" != "root" ]; then + echo -e "This script has to be run as \033[1mroot\033[0m user" + exit 3 +fi + +decho "stopping lamassu-server" +supervisorctl stop lamassu-server >> ${LOG_FILE} 2>&1 +supervisorctl stop lamassu-admin-server >> ${LOG_FILE} 2>&1 + +decho "updating node" +npm install n -g >> ${LOG_FILE} 2>&1 +n lts >> ${LOG_FILE} 2>&1 +node -v + +decho "updating lamassu-server" +npm -g install lamassu/lamassu-server#v5 --unsafe-perm >> ${LOG_FILE} 2>&1 + +decho "rebuilding npm deps" +cd /usr/local/lib/node_modules/lamassu-server/ >> ${LOG_FILE} 2>&1 +npm rebuild >> ${LOG_FILE} 2>&1 + +decho "running migration" +lamassu-migrate >> ${LOG_FILE} 2>&1 +lamassu-migrate-config >> ${LOG_FILE} 2>&1 + +decho "starting lamassu-server" +supervisorctl start lamassu-server >> ${LOG_FILE} 2>&1 +supervisorctl start lamassu-admin-server >> ${LOG_FILE} 2>&1 diff --git a/install b/install index cdf75a03..4c54fa7d 100644 --- a/install +++ b/install @@ -16,7 +16,7 @@ SEEDS_DIR=$HOME/seeds SEED_FILE=$SEEDS_DIR/seed.txt BACKUP_DIR=/var/backups/postgresql BLOCKCHAIN_DIR=/mnt/blockchains -OFAC_DATA_DIR=/var/lamassu/ofac +OFAC_DATA_DIR=/opt/lamassu-server/sanctions # Look into http://unix.stackexchange.com/questions/140734/configure-localtime-dpkg-reconfigure-tzdata @@ -148,6 +148,7 @@ rm /tmp/Lamassu_OP.csr.pem mkdir -p $OFAC_DATA_DIR +decho "Setting up lamassu.json..." cat < $CONFIG_DIR/lamassu.json { "postgresql": "postgres://lamassu_pg:$POSTGRES_PW@localhost/lamassu", @@ -169,6 +170,7 @@ cat < $CONFIG_DIR/lamassu.json } } EOF +lamassu-migrate-config >> $LOG_FILE 2>&1 decho "Setting up database tables..." lamassu-migrate >> $LOG_FILE 2>&1 diff --git a/lamassu-default.json b/lamassu-default.json new file mode 100644 index 00000000..daa9ca8e --- /dev/null +++ b/lamassu-default.json @@ -0,0 +1,17 @@ +{ + "seedPath": "/etc/lamassu/seeds/seed.txt", + "caPath": "/etc/ssl/certs/Lamassu_OP_Root_CA.pem", + "certPath": "/etc/ssl/certs/Lamassu_OP.pem", + "keyPath": "/etc/ssl/private/Lamassu_OP.key", + "logLevel": "info", + "lamassuServerPath": "/usr/local/share/.config/yarn/global/node_modules/lamassu-server", + "migrateStatePath": "/etc/lamassu/.migrate", + "blockchainDir": "/mnt/blockchains", + "ofacDataDir": "/opt/lamassu-server/sanctions", + "coinAtmRadar": { + "url": "https://coinatmradar.info/api/lamassu/" + }, + "strike": { + "baseUrl": "https://api.strike.acinq.co/api/" + } +} diff --git a/lib/migrate-options.js b/lib/migrate-options.js new file mode 100644 index 00000000..5eb3f843 --- /dev/null +++ b/lib/migrate-options.js @@ -0,0 +1,51 @@ +const _ = require('lodash/fp') +const fs = require('fs') +const makeDir = require('make-dir') + +const load = require('./options-loader') + +module.exports = {run, mapKeyValuesDeep} + +function mapKeyValuesDeep (cb, obj, key) { + if (_.isArray(obj)) { + return _.mapValues((val, key) => mapKeyValuesDeep(cb, val, key), obj) + } else if (_.isObject(obj)) { + return _.pickBy((val, key) => mapKeyValuesDeep(cb, val, key), obj) + } else { + return cb(obj, key) + } +} + +async function run () { + // load defaults + const defaultOpts = require('../lamassu-default') + + // load current opts + const options = load() + const currentOpts = options.opts + + // check if there are new options to add + const result = _.mergeAll([defaultOpts, currentOpts]) + const shouldMigrate = !_.isEqual(result, currentOpts) + + // write the resulting lamassu.json + if (shouldMigrate) { + const newOpts = _.pick(_.difference(_.keys(result), _.keys(currentOpts)), result) + console.log('Adding options', newOpts) + + // store new lamassu.json file + fs.writeFileSync(options.path, JSON.stringify(result, null, ' ')) + } + + // get all the new options + // that ends with "Dir" suffix + mapKeyValuesDeep((v, k) => { + if (_.endsWith('Dir', k)) { + const path = _.attempt(() => makeDir.sync(v)) + + if (_.isError(path)) { + console.error(`Error while creating folder ${v}`, path) + } + } + }, result) +} diff --git a/lib/options-loader.js b/lib/options-loader.js new file mode 100644 index 00000000..970076b1 --- /dev/null +++ b/lib/options-loader.js @@ -0,0 +1,46 @@ +const fs = require('fs') +const path = require('path') +const os = require('os') +const argv = require('minimist')(process.argv.slice(2)) + +/** + * @return {{path: string, opts: any}} + */ +function load () { + if (process.env.LAMASSU_CONFIG) { + const configPath = process.env.LAMASSU_CONFIG + return { + path: configPath, + opts: JSON.parse(fs.readFileSync(configPath)) + } + } + + if (argv.f) { + const configPath = argv.f + return { + path: configPath, + opts: JSON.parse(fs.readFileSync(configPath)) + } + } + + try { + const globalConfigPath = path.resolve('/etc', 'lamassu', 'lamassu.json') + return { + path: globalConfigPath, + opts: JSON.parse(fs.readFileSync(globalConfigPath)) + } + } catch (_) { + try { + const homeConfigPath = path.resolve(os.homedir(), '.lamassu', 'lamassu.json') + return { + path: homeConfigPath, + opts: JSON.parse(fs.readFileSync(homeConfigPath)) + } + } catch (_) { + console.error("Couldn't open lamassu.json config file.") + process.exit(1) + } + } +} + +module.exports = load diff --git a/lib/options.js b/lib/options.js index 4ba090de..9f777234 100644 --- a/lib/options.js +++ b/lib/options.js @@ -1,35 +1,8 @@ -const fs = require('fs') -const path = require('path') -const os = require('os') const _ = require('lodash/fp') const argv = require('minimist')(process.argv.slice(2)) +const load = require('./options-loader') -function load () { - if (process.env.LAMASSU_CONFIG) { - const configPath = process.env.LAMASSU_CONFIG - return JSON.parse(fs.readFileSync(configPath)) - } - - if (argv.f) { - const configPath = argv.f - return JSON.parse(fs.readFileSync(configPath)) - } - - try { - const globalConfigPath = path.resolve('/etc', 'lamassu', 'lamassu.json') - return JSON.parse(fs.readFileSync(globalConfigPath)) - } catch (_) { - try { - const homeConfigPath = path.resolve(os.homedir(), '.lamassu', 'lamassu.json') - return JSON.parse(fs.readFileSync(homeConfigPath)) - } catch (_) { - console.error("Couldn't open lamassu.json config file.") - process.exit(1) - } - } -} - -const serverConfig = load() +const serverConfig = load().opts const defaults = {logLevel: 'info'} const commandLine = {logLevel: argv.logLevel} diff --git a/test/unit/migrate-options.js b/test/unit/migrate-options.js new file mode 100644 index 00000000..396da464 --- /dev/null +++ b/test/unit/migrate-options.js @@ -0,0 +1,35 @@ +import test from 'ava' +import _ from 'lodash/fp' + +import {mapKeyValuesDeep} from '../../lib/migrate-options' + +test('mapKeyValuesDeep', t => { + const test = { + a: { + b: 1 + }, + c: [ + { + d: 2, + e: 3 + } + ], + f: { + g: { + h: [ + { + i: 4 + } + ] + } + } + } + const expected = [{b: 1}, {d: 2}, {e: 3}, {i: 4}] + + const result = [] + mapKeyValuesDeep((v, k) => { + result.push(_.fromPairs([[k, v]])) + }, test) + + t.deepEqual(result, expected) +})