add lamassu-coins script
This commit is contained in:
parent
44ea450ec5
commit
ab58908de0
5 changed files with 254 additions and 34 deletions
5
bin/lamassu-coins
Executable file
5
bin/lamassu-coins
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const install = require('../lib/blockchain/install')
|
||||||
|
|
||||||
|
install.run()
|
||||||
205
install
Normal file
205
install
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export LOG_FILE=/tmp/install.log
|
||||||
|
|
||||||
|
NODE_MODULES=/usr/local/share/.config/yarn/global/node_modules
|
||||||
|
CERT_DIR=/etc/ssl/certs
|
||||||
|
KEY_DIR=/etc/ssl/private
|
||||||
|
CONFIG_DIR=/etc/lamassu
|
||||||
|
MIGRATE_STATE_PATH=$CONFIG_DIR/.migrate
|
||||||
|
CA_KEY_PATH=$KEY_DIR/Lamassu_OP_Root_CA.key
|
||||||
|
CA_PATH=$CERT_DIR/Lamassu_OP_Root_CA.pem
|
||||||
|
SERVER_KEY_PATH=$KEY_DIR/Lamassu_OP.key
|
||||||
|
SERVER_CERT_PATH=$CERT_DIR/Lamassu_OP.pem
|
||||||
|
SEEDS_DIR=$HOME/seeds
|
||||||
|
SEED_FILE=$SEEDS_DIR/seed.txt
|
||||||
|
BACKUP_DIR=/var/backups/postgresql
|
||||||
|
BLOCKCHAIN_DIR=/mnt/blockchains
|
||||||
|
|
||||||
|
# Look into http://unix.stackexchange.com/questions/140734/configure-localtime-dpkg-reconfigure-tzdata
|
||||||
|
|
||||||
|
decho () {
|
||||||
|
echo `date +"%H:%M:%S"` $1
|
||||||
|
echo `date +"%H:%M:%S"` $1 >> $LOG_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
retry() {
|
||||||
|
local -r -i max_attempts="$1"; shift
|
||||||
|
local -r cmd="$@"
|
||||||
|
local -i attempt_num=1
|
||||||
|
|
||||||
|
until $cmd
|
||||||
|
do
|
||||||
|
if (( attempt_num == max_attempts ))
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo "****************************************************************"
|
||||||
|
echo "Attempt $attempt_num failed and there are no more attempts left!"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "****************************************************************"
|
||||||
|
echo "Attempt $attempt_num failed! Trying again in $attempt_num seconds..."
|
||||||
|
sleep $(( attempt_num++ ))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -f $LOG_FILE
|
||||||
|
|
||||||
|
cat <<'FIG'
|
||||||
|
_
|
||||||
|
| | __ _ _ __ ___ __ _ ___ ___ _ _ ___ ___ _ ____ _____ _ __
|
||||||
|
| |/ _` | '_ ` _ \ / _` / __/ __| | | |_____/ __|/ _ \ '__\ \ / / _ \ '__|
|
||||||
|
| | (_| | | | | | | (_| \__ \__ \ |_| |_____\__ \ __/ | \ V / __/ |
|
||||||
|
|_|\__,_|_| |_| |_|\__,_|___/___/\__,_| |___/\___|_| \_/ \___|_|
|
||||||
|
FIG
|
||||||
|
|
||||||
|
echo -e "\nStarting \033[1mlamassu-server\033[0m install. 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
|
||||||
|
|
||||||
|
# So we don't run out of memory
|
||||||
|
decho "Enabling swap file for install only..."
|
||||||
|
fallocate -l 1G /swapfile >> $LOG_FILE 2>&1
|
||||||
|
chmod 600 /swapfile >> $LOG_FILE 2>&1
|
||||||
|
mkswap /swapfile >> $LOG_FILE 2>&1
|
||||||
|
swapon /swapfile >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
IP=$(ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}')
|
||||||
|
|
||||||
|
decho "Updating system..."
|
||||||
|
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - >> $LOG_FILE 2>&1
|
||||||
|
apt update >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Installing necessary packages..."
|
||||||
|
apt install nodejs python-minimal build-essential postgresql libpq-dev -y -q >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Generating seed..."
|
||||||
|
mkdir -p $SEEDS_DIR >> $LOG_FILE 2>&1
|
||||||
|
SEED=$(openssl rand -hex 32)
|
||||||
|
echo $SEED > $SEED_FILE
|
||||||
|
|
||||||
|
decho "Installing yarn package manager for node..."
|
||||||
|
npm -g --unsafe-perm install yarn >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Installing lamassu-server..."
|
||||||
|
retry 3 yarn global add pm2 >> $LOG_FILE 2>&1
|
||||||
|
retry 3 yarn global add lamassu/lamassu-server#v5 >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Creating postgres user..."
|
||||||
|
POSTGRES_PW=$(hkdf postgres-pw $SEED)
|
||||||
|
su -l postgres >> $LOG_FILE 2>&1 <<EOF
|
||||||
|
psql -c "CREATE ROLE lamassu_pg WITH LOGIN SUPERUSER PASSWORD '$POSTGRES_PW';"
|
||||||
|
createdb lamassu
|
||||||
|
EOF
|
||||||
|
|
||||||
|
mkdir -p $CERT_DIR >> $LOG_FILE 2>&1
|
||||||
|
mkdir -p $CONFIG_DIR >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Generating SSL certificates..."
|
||||||
|
|
||||||
|
openssl genrsa \
|
||||||
|
-out $CA_KEY_PATH \
|
||||||
|
4096 >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
openssl req \
|
||||||
|
-x509 \
|
||||||
|
-sha256 \
|
||||||
|
-new \
|
||||||
|
-nodes \
|
||||||
|
-key $CA_KEY_PATH \
|
||||||
|
-days 3560 \
|
||||||
|
-out $CA_PATH \
|
||||||
|
-subj "/C=IS/ST=/L=Reykjavik/O=Lamassu Operator CA/CN=lamassu-operator.is" \
|
||||||
|
>> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
openssl genrsa \
|
||||||
|
-out $SERVER_KEY_PATH \
|
||||||
|
4096 >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
openssl req -new \
|
||||||
|
-key $SERVER_KEY_PATH \
|
||||||
|
-out /tmp/Lamassu_OP.csr.pem \
|
||||||
|
-subj "/C=IS/ST=/L=Reykjavik/O=Lamassu Operator/CN=$IP" \
|
||||||
|
-reqexts SAN \
|
||||||
|
-sha256 \
|
||||||
|
-config <(cat /etc/ssl/openssl.cnf \
|
||||||
|
<(printf "[SAN]\nsubjectAltName=IP.1:$IP")) \
|
||||||
|
>> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
openssl x509 \
|
||||||
|
-req -in /tmp/Lamassu_OP.csr.pem \
|
||||||
|
-CA $CA_PATH \
|
||||||
|
-CAkey $CA_KEY_PATH \
|
||||||
|
-CAcreateserial \
|
||||||
|
-out $SERVER_CERT_PATH \
|
||||||
|
-extfile <(cat /etc/ssl/openssl.cnf \
|
||||||
|
<(printf "[SAN]\nsubjectAltName=IP.1:$IP")) \
|
||||||
|
-extensions SAN \
|
||||||
|
-days 3650 >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
rm /tmp/Lamassu_OP.csr.pem
|
||||||
|
|
||||||
|
cat <<EOF > $CONFIG_DIR/lamassu.json
|
||||||
|
{
|
||||||
|
"postgresql": "postgres://lamassu_pg:$POSTGRES_PW@localhost/lamassu",
|
||||||
|
"seedPath": "$SEED_FILE",
|
||||||
|
"caPath": "$CA_PATH",
|
||||||
|
"certPath": "$SERVER_CERT_PATH",
|
||||||
|
"keyPath": "$SERVER_KEY_PATH",
|
||||||
|
"hostname": "$IP",
|
||||||
|
"logLevel": "info",
|
||||||
|
"lamassuServerPath": "$NODE_MODULES/lamassu-server",
|
||||||
|
"migrateStatePath": "$MIGRATE_STATE_PATH",
|
||||||
|
"blockchainDir": "$BLOCKCHAIN_DIR"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
decho "Setting up database tables..."
|
||||||
|
lamassu-migrate >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Setting up lamassu-admin..."
|
||||||
|
ADMIN_REGISTRATION_URL=`lamassu-register admin 2>> $LOG_FILE`
|
||||||
|
lamassu-apply-defaults >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Starting lamassu-admin..."
|
||||||
|
pm2 start lamassu-admin-server >> $LOG_FILE 2>&1
|
||||||
|
pm2 start lamassu-server --restart-delay 3000 >> $LOG_FILE 2>&1
|
||||||
|
pm2 save >> $LOG_FILE 2>&1
|
||||||
|
pm2 startup >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Setting up backups..."
|
||||||
|
BIN=$(yarn global bin)
|
||||||
|
BACKUP_CMD=$BIN/lamassu-backup-pg
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
BACKUP_CRON="@daily $BACKUP_CMD > /dev/null"
|
||||||
|
echo $BACKUP_CRON | crontab - >> $LOG_FILE 2>&1
|
||||||
|
$BACKUP_CMD >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Setting up firewall..."
|
||||||
|
ufw allow ssh >> $LOG_FILE 2>&1
|
||||||
|
ufw allow 443/tcp >> $LOG_FILE 2>&1 # Admin
|
||||||
|
ufw allow 3000/tcp >> $LOG_FILE 2>&1 # Server
|
||||||
|
ufw -f enable >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
decho "Disabling swap file..."
|
||||||
|
swapoff /swapfile >> $LOG_FILE 2>&1
|
||||||
|
|
||||||
|
echo
|
||||||
|
decho "Done! Now it's time to configure Lamassu stack."
|
||||||
|
echo
|
||||||
|
echo -e "\n*** IMPORTANT ***"
|
||||||
|
echo "In a private space, run lamassu-mnemonic, write down the words"
|
||||||
|
echo "and keep them in a safe place."
|
||||||
|
echo
|
||||||
|
echo "This secret will allow you to retrieve system passwords, including "
|
||||||
|
echo "the keys to some of your crypto accounts."
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "Activation URL for lamassu-admin:"
|
||||||
|
echo $ADMIN_REGISTRATION_URL
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const options = require('../options')
|
||||||
|
|
||||||
const common = require('./common')
|
const common = require('./common')
|
||||||
|
|
||||||
const MOUNT_POINT = '/mnt/blockchains'
|
const MOUNT_POINT = options.blockchainDir
|
||||||
|
|
||||||
module.exports = {prepareVolume}
|
module.exports = {prepareVolume}
|
||||||
|
|
||||||
|
|
@ -13,7 +15,7 @@ function isMounted () {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isFormatted (volumePath) {
|
function isFormatted (volumePath) {
|
||||||
const res = common.es(`file --dereference -s ${volumePath}`)
|
const res = common.es(`file --dereference -s ${volumePath}`).trim()
|
||||||
return res !== `${volumePath}: data`
|
return res !== `${volumePath}: data`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ const PLUGINS = {
|
||||||
ZEC: require('./zcash.js')
|
ZEC: require('./zcash.js')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = {run}
|
||||||
|
|
||||||
function installedFilePath (crypto) {
|
function installedFilePath (crypto) {
|
||||||
return path.resolve(options.blockchainDir, crypto.code, '.installed')
|
return path.resolve(options.blockchainDir, crypto.code, '.installed')
|
||||||
}
|
}
|
||||||
|
|
@ -32,32 +34,18 @@ function isInstalled (crypto) {
|
||||||
return fs.existsSync(installedFilePath(crypto))
|
return fs.existsSync(installedFilePath(crypto))
|
||||||
}
|
}
|
||||||
|
|
||||||
const choices = _.map(c => {
|
|
||||||
const checked = isInstalled(c)
|
|
||||||
return {
|
|
||||||
name: c.display,
|
|
||||||
value: c.code,
|
|
||||||
checked,
|
|
||||||
disabled: checked && 'Installed'
|
|
||||||
}
|
|
||||||
}, cryptos)
|
|
||||||
|
|
||||||
const questions = []
|
|
||||||
|
|
||||||
questions.push({
|
|
||||||
type: 'checkbox',
|
|
||||||
name: 'crypto',
|
|
||||||
message: 'Which cryptocurrencies would you like to install?',
|
|
||||||
choices
|
|
||||||
})
|
|
||||||
|
|
||||||
function processCryptos (codes) {
|
function processCryptos (codes) {
|
||||||
if (_.isEmpty(codes)) {
|
if (_.isEmpty(codes)) {
|
||||||
logger.info('No cryptos selected. Exiting.')
|
logger.info('No cryptos selected. Exiting.')
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
doVolume.prepareVolume()
|
const goodVolume = doVolume.prepareVolume()
|
||||||
|
|
||||||
|
if (!goodVolume) {
|
||||||
|
logger.error('There was an error preparing the disk volume. Exiting.')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
logger.info('Thanks! Installing: %s. Will take a while...', _.join(', ', codes))
|
logger.info('Thanks! Installing: %s. Will take a while...', _.join(', ', codes))
|
||||||
|
|
||||||
|
|
@ -67,15 +55,6 @@ function processCryptos (codes) {
|
||||||
logger.info('Installation complete.')
|
logger.info('Installation complete.')
|
||||||
}
|
}
|
||||||
|
|
||||||
inquirer.prompt(questions)
|
|
||||||
.then(answers => processCryptos(answers.crypto))
|
|
||||||
|
|
||||||
function plugin (crypto) {
|
|
||||||
const plugin = PLUGINS[crypto.cryptoCode]
|
|
||||||
if (!plugin) throw new Error(`No such plugin: ${crypto.cryptoCode}`)
|
|
||||||
return plugin
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupCrypto (crypto) {
|
function setupCrypto (crypto) {
|
||||||
logger.info(`Installing ${crypto.display}...`)
|
logger.info(`Installing ${crypto.display}...`)
|
||||||
const cryptoDir = path.resolve(options.blockchainDir, crypto.code)
|
const cryptoDir = path.resolve(options.blockchainDir, crypto.code)
|
||||||
|
|
@ -93,3 +72,33 @@ function setupCrypto (crypto) {
|
||||||
process.chdir(oldDir)
|
process.chdir(oldDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function plugin (crypto) {
|
||||||
|
const plugin = PLUGINS[crypto.cryptoCode]
|
||||||
|
if (!plugin) throw new Error(`No such plugin: ${crypto.cryptoCode}`)
|
||||||
|
return plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
function run () {
|
||||||
|
const choices = _.map(c => {
|
||||||
|
const checked = isInstalled(c)
|
||||||
|
return {
|
||||||
|
name: c.display,
|
||||||
|
value: c.code,
|
||||||
|
checked,
|
||||||
|
disabled: checked && 'Installed'
|
||||||
|
}
|
||||||
|
}, cryptos)
|
||||||
|
|
||||||
|
const questions = []
|
||||||
|
|
||||||
|
questions.push({
|
||||||
|
type: 'checkbox',
|
||||||
|
name: 'crypto',
|
||||||
|
message: 'Which cryptocurrencies would you like to install?',
|
||||||
|
choices
|
||||||
|
})
|
||||||
|
|
||||||
|
inquirer.prompt(questions)
|
||||||
|
.then(answers => processCryptos(answers.crypto))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,11 +64,10 @@
|
||||||
"lamassu-apply-defaults": "./bin/lamassu-apply-defaults",
|
"lamassu-apply-defaults": "./bin/lamassu-apply-defaults",
|
||||||
"hkdf": "./bin/hkdf",
|
"hkdf": "./bin/hkdf",
|
||||||
"lamassu-backup-pg": "./bin/lamassu-backup-pg",
|
"lamassu-backup-pg": "./bin/lamassu-backup-pg",
|
||||||
"lamassu-install-bitcoind": "./bin/lamassu-install-bitcoind",
|
|
||||||
"lamassu-install-geth": "./bin/lamassu-install-geth",
|
|
||||||
"lamassu-mnemonic": "./bin/lamassu-mnemonic",
|
"lamassu-mnemonic": "./bin/lamassu-mnemonic",
|
||||||
"lamassu-cancel": "./bin/lamassu-cancel",
|
"lamassu-cancel": "./bin/lamassu-cancel",
|
||||||
"lamassu-nuke-db": "./bin/lamassu-nuke-db"
|
"lamassu-nuke-db": "./bin/lamassu-nuke-db",
|
||||||
|
"lamassu-coins": "./bin/lamassu-coins"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node bin/lamassu-server",
|
"start": "node bin/lamassu-server",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue