mirror of https://github.com/lukechilds/umbrel.git
Browse Source
Co-authored-by: Mayank <mayankchhabra9@gmail.com> Co-authored-by: Luke Childs <lukechilds123@gmail.com>tor-0.4.4.7
committed by
GitHub
21 changed files with 1296 additions and 0 deletions
@ -0,0 +1,137 @@ |
|||
version: "3.7" |
|||
|
|||
x-logging: |
|||
&default-logging |
|||
driver: journald |
|||
options: |
|||
tag: "umbrel-app {{.Name}}" |
|||
|
|||
services: |
|||
db: |
|||
image: mariadb:10.5.8@sha256:8040983db146f729749081c6b216a19d52e0973134e2e34c0b4fd87f48bc15b0 |
|||
init: true |
|||
logging: *default-logging |
|||
restart: on-failure |
|||
stop_grace_period: 5m |
|||
user: "1000:1000" |
|||
environment: |
|||
MYSQL_DATABASE: samourai-main |
|||
MYSQL_ROOT_PASSWORD: rootpassword |
|||
MYSQL_USER: samourai |
|||
MYSQL_PASSWORD: password |
|||
volumes: |
|||
- ${APP_DATA_DIR}/mysql/data:/var/lib/mysql |
|||
- ${APP_DATA_DIR}/mysql/db-scripts:/docker-entrypoint-initdb.d |
|||
- ${APP_DATA_DIR}/mysql/mysql-dojo.cnf:/etc/mysql/conf.d/mysql-dojo.cnf |
|||
- ${APP_DATA_DIR}/mysql/update-db.sh:/update-db.sh |
|||
networks: |
|||
default: |
|||
ipv4_address: $APP_SAMOURAI_SERVER_DB_IP |
|||
|
|||
node: |
|||
image: louneskmt/dojo-nodejs:1.8.0@sha256:6643de76267e3a2cfd4f6d593d560a8dd001a54a7e5f9cc8df77d4cab5f1e1bf |
|||
init: true |
|||
logging: *default-logging |
|||
restart: on-failure |
|||
command: "/home/node/app/wait-for-it.sh db:3306 --timeout=720 --strict -- /home/node/app/restart.sh" |
|||
user: "1000:1000" |
|||
environment: |
|||
# GLOBAL |
|||
COMMON_BTC_NETWORK: $BITCOIN_NETWORK |
|||
DOJO_NODEJS_VERSION_TAG: 1.8.0 |
|||
TOR_PROXY_IP: $TOR_PROXY_IP |
|||
TOR_PROXY_PORT: $TOR_PROXY_PORT |
|||
|
|||
# MYSQL |
|||
MYSQL_DATABASE: samourai-main |
|||
MYSQL_USER: samourai |
|||
MYSQL_PASSWORD: password |
|||
|
|||
# NODEJS |
|||
NODE_GAP_EXTERNAL: 100 |
|||
NODE_GAP_INTERNAL: 100 |
|||
NODE_ADDR_FILTER_THRESHOLD: 1000 |
|||
NODE_ADDR_DERIVATION_MIN_CHILD: 2 |
|||
NODE_ADDR_DERIVATION_MAX_CHILD: 2 |
|||
NODE_ADDR_DERIVATION_THRESHOLD: 10 |
|||
NODE_TXS_SCHED_MAX_ENTRIES: 10 |
|||
NODE_TXS_SCHED_MAX_DELTA_HEIGHT: 18 |
|||
NODE_JWT_ACCESS_EXPIRES: 900 |
|||
NODE_JWT_REFRESH_EXPIRES: 7200 |
|||
NODE_PREFIX_STATUS: status |
|||
NODE_PREFIX_SUPPORT: support |
|||
NODE_PREFIX_STATUS_PUSHTX: status |
|||
NODE_TRACKER_MEMPOOL_PERIOD: 10000 |
|||
NODE_TRACKER_UNCONF_TXS_PERIOD: 300000 |
|||
NODE_ACTIVE_INDEXER: local_indexer |
|||
NODE_FEE_TYPE: ECONOMICAL |
|||
|
|||
# SECURITY |
|||
NODE_API_KEY: $SAMOURAI_SERVER_NODE_API_KEY |
|||
NODE_ADMIN_KEY: $SAMOURAI_SERVER_NODE_ADMIN_KEY |
|||
NODE_JWT_SECRET: $SAMOURAI_SERVER_NODE_JWT_SECRET |
|||
|
|||
# BITCOIN |
|||
BITCOIND_IP: $BITCOIN_IP |
|||
BITCOIND_RPC_PORT: $BITCOIN_RPC_PORT |
|||
BITCOIND_RPC_USER: $BITCOIN_RPC_USER |
|||
BITCOIND_RPC_PASSWORD: $BITCOIN_RPC_PASS |
|||
BITCOIND_ZMQ_RAWTXS: $BITCOIN_ZMQ_RAWTX_PORT |
|||
BITCOIND_ZMQ_BLK_HASH: $BITCOIN_ZMQ_HASHBLOCK_PORT |
|||
|
|||
# EXPLORER |
|||
EXPLORER_INSTALL: "off" |
|||
|
|||
# INDEXER |
|||
INDEXER_IP: $ELECTRUM_IP |
|||
INDEXER_RPC_PORT: $ELECTRUM_PORT |
|||
INDEXER_BATCH_SUPPORT: inactive # 'active' for ElectrumX, 'inactive' otherwise |
|||
depends_on: |
|||
- db |
|||
networks: |
|||
default: |
|||
ipv4_address: $APP_SAMOURAI_SERVER_NODE_IP |
|||
|
|||
whirlpool: |
|||
image: louneskmt/dojo-whirlpool:1.2.1@sha256:8674bca0d901e8d65d49e5cf38c597c37bf1d99168114a58b63b242dd1b38d05 |
|||
init: true |
|||
logging: *default-logging |
|||
restart: on-failure |
|||
command: /restart.sh |
|||
user: "1000:1000" |
|||
environment: |
|||
COMMON_BTC_NETWORK: $BITCOIN_NETWORK |
|||
WHIRLPOOL_RESYNC: "on" |
|||
WHIRLPOOL_DEBUG: "off" |
|||
WHIRLPOOL_DEBUG_CLIENT: "off" |
|||
NGINX_IP: $APP_SAMOURAI_SERVER_IP |
|||
volumes: |
|||
- ${APP_DATA_DIR}/whirlpool:/home/whirlpool/.whirlpool-cli |
|||
networks: |
|||
default: |
|||
ipv4_address: $APP_SAMOURAI_SERVER_WHIRLPOOL_IP |
|||
|
|||
nginx: |
|||
image: nginx:1.19-alpine@sha256:c2ce58e024275728b00a554ac25628af25c54782865b3487b11c21cafb7fabda |
|||
init: true |
|||
logging: *default-logging |
|||
restart: on-failure |
|||
command: /bin/sh -c "envsubst < /var/www/connect/js/conf.template.js > /var/www/connect/js/conf.js && /wait-for node:8080 --timeout=720 -- nginx" |
|||
volumes: |
|||
- ${APP_DATA_DIR}/nginx/wait-for:/wait-for |
|||
- ${APP_DATA_DIR}/nginx/nginx.conf:/etc/nginx/nginx.conf |
|||
- ${APP_DATA_DIR}/nginx/${BITCOIN_NETWORK}.conf:/etc/nginx/sites-enabled/dojo.conf |
|||
- ${APP_DATA_DIR}/nginx/connect:/var/www/connect |
|||
environment: |
|||
COMMON_BTC_NETWORK: $BITCOIN_NETWORK |
|||
DOJO_HIDDEN_SERVICE: $APP_HIDDEN_SERVICE |
|||
WHIRLPOOL_HIDDEN_SERVICE: $SAMOURAI_SERVER_WHIRLPOOL_HIDDEN_SERVICE |
|||
NODE_PREFIX_SUPPORT: support |
|||
NODE_ADMIN_KEY: $SAMOURAI_SERVER_NODE_ADMIN_KEY |
|||
ports: |
|||
- "$APP_SAMOURAI_SERVER_PORT:80" |
|||
depends_on: |
|||
- node |
|||
networks: |
|||
default: |
|||
ipv4_address: $APP_SAMOURAI_SERVER_IP |
@ -0,0 +1,203 @@ |
|||
# Database tables |
|||
|
|||
# Copyright © 2019 – Katana Cryptographic Ltd. All Rights Reserved. |
|||
|
|||
|
|||
# Naming conventions |
|||
# 1. Table names are lowercase plural |
|||
# 2. Join table names are snake_case plural |
|||
# 3. Column names have a table prefix |
|||
# 4. Foreign key names match primary key of foreign table |
|||
|
|||
|
|||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; |
|||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; |
|||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; |
|||
/*!40101 SET NAMES utf8 */; |
|||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; |
|||
/*!40103 SET TIME_ZONE='+00:00' */; |
|||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; |
|||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; |
|||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; |
|||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; |
|||
|
|||
-- |
|||
-- Table structure for table `addresses` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `addresses` ( |
|||
`addrID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`addrAddress` varchar(74) DEFAULT NULL, |
|||
PRIMARY KEY (`addrID`), |
|||
UNIQUE KEY `addrAddress` (`addrAddress`) |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `banned_addresses` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `banned_addresses` ( |
|||
`bannedAddressId` int(11) NOT NULL AUTO_INCREMENT, |
|||
`addrAddress` varchar(35) NOT NULL, |
|||
PRIMARY KEY (`bannedAddressId`), |
|||
UNIQUE KEY `banned_addresses_addresses` (`addrAddress`) |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `blocks` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `blocks` ( |
|||
`blockID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`blockHash` char(64) NOT NULL DEFAULT '', |
|||
`blockParent` int(10) unsigned DEFAULT NULL, |
|||
`blockHeight` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`blockTime` int(10) unsigned NOT NULL DEFAULT '0', |
|||
PRIMARY KEY (`blockID`), |
|||
UNIQUE KEY `blockHash` (`blockHash`), |
|||
KEY `blockParent` (`blockParent`), |
|||
KEY `blockHeight` (`blockHeight`), |
|||
CONSTRAINT `blocks_ibfk_1` FOREIGN KEY (`blockParent`) REFERENCES `blocks` (`blockID`) ON DELETE SET NULL ON UPDATE NO ACTION |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `hd` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `hd` ( |
|||
`hdID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`hdXpub` char(112) DEFAULT NULL, |
|||
`hdCreated` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`hdType` smallint(5) unsigned NOT NULL DEFAULT '0', |
|||
PRIMARY KEY (`hdID`), |
|||
UNIQUE KEY `hdXpub` (`hdXpub`), |
|||
KEY `hdCreated` (`hdCreated`) |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `hd_addresses` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `hd_addresses` ( |
|||
`hdAddrID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`hdID` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`addrID` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`hdAddrChain` smallint(5) unsigned NOT NULL DEFAULT '0', |
|||
`hdAddrIndex` int(10) unsigned NOT NULL DEFAULT '0', |
|||
PRIMARY KEY (`hdAddrID`), |
|||
UNIQUE KEY `hdID_2` (`hdID`,`addrID`), |
|||
KEY `hdID` (`hdID`), |
|||
KEY `addrID` (`addrID`), |
|||
CONSTRAINT `hd_addresses_ibfk_1` FOREIGN KEY (`hdID`) REFERENCES `hd` (`hdID`) ON DELETE CASCADE ON UPDATE CASCADE, |
|||
CONSTRAINT `hd_addresses_ibfk_2` FOREIGN KEY (`addrID`) REFERENCES `addresses` (`addrID`) ON DELETE CASCADE ON UPDATE CASCADE |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `inputs` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `inputs` ( |
|||
`inID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`outID` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`txnID` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`inIndex` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`inSequence` int(10) unsigned NOT NULL DEFAULT '0', |
|||
PRIMARY KEY (`inID`), |
|||
UNIQUE KEY `txnID_2` (`txnID`,`inIndex`), |
|||
KEY `outID` (`outID`), |
|||
KEY `txnID` (`txnID`), |
|||
CONSTRAINT `inputs_ibfk_1` FOREIGN KEY (`txnID`) REFERENCES `transactions` (`txnID`) ON DELETE CASCADE ON UPDATE CASCADE, |
|||
CONSTRAINT `inputs_ibfk_2` FOREIGN KEY (`outID`) REFERENCES `outputs` (`outID`) ON DELETE CASCADE ON UPDATE CASCADE |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `outputs` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `outputs` ( |
|||
`outID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`txnID` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`addrID` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`outIndex` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`outAmount` bigint(20) unsigned NOT NULL DEFAULT '0', |
|||
`outScript` varchar(20000) NOT NULL DEFAULT '', |
|||
PRIMARY KEY (`outID`), |
|||
UNIQUE KEY `txnID_2` (`txnID`,`addrID`,`outIndex`), |
|||
KEY `txnID` (`txnID`), |
|||
KEY `addrID` (`addrID`), |
|||
CONSTRAINT `outputs_ibfk_1` FOREIGN KEY (`txnID`) REFERENCES `transactions` (`txnID`) ON DELETE CASCADE ON UPDATE CASCADE, |
|||
CONSTRAINT `outputs_ibfk_2` FOREIGN KEY (`addrID`) REFERENCES `addresses` (`addrID`) ON DELETE CASCADE ON UPDATE CASCADE |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `transactions` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `transactions` ( |
|||
`txnID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`txnTxid` char(64) DEFAULT NULL, |
|||
`txnCreated` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`txnVersion` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`txnLocktime` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`blockID` int(10) unsigned DEFAULT NULL, |
|||
PRIMARY KEY (`txnID`), |
|||
UNIQUE KEY `txnTxid` (`txnTxid`), |
|||
KEY `txnCreated` (`txnCreated`), |
|||
KEY `blockID` (`blockID`), |
|||
CONSTRAINT `transactions_ibfk_1` FOREIGN KEY (`blockID`) REFERENCES `blocks` (`blockID`) ON DELETE SET NULL ON UPDATE NO ACTION |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
-- |
|||
-- Table structure for table `scheduled_transactions` |
|||
-- |
|||
|
|||
/*!40101 SET @saved_cs_client = @@character_set_client */; |
|||
/*!40101 SET character_set_client = utf8 */; |
|||
CREATE TABLE IF NOT EXISTS `scheduled_transactions` ( |
|||
`schID` int(10) unsigned NOT NULL AUTO_INCREMENT, |
|||
`schTxid` char(64) NOT NULL DEFAULT '', |
|||
`schCreated` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`schRaw` varchar(50000) NOT NULL DEFAULT '', |
|||
`schParentID` int(10) unsigned DEFAULT NULL, |
|||
`schParentTxid` char(64) DEFAULT '', |
|||
`schDelay` int(10) unsigned NOT NULL DEFAULT '0', |
|||
`schTrigger` int(10) unsigned NOT NULL DEFAULT '0', |
|||
PRIMARY KEY (`schID`), |
|||
UNIQUE KEY `schTxid` (`schTxid`), |
|||
KEY `schParentID` (`schParentID`), |
|||
CONSTRAINT `scheduled_transactions_ibfk_1` FOREIGN KEY (`schParentID`) REFERENCES `scheduled_transactions` (`schID`) ON DELETE SET NULL ON UPDATE NO ACTION |
|||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1; |
|||
/*!40101 SET character_set_client = @saved_cs_client */; |
|||
|
|||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; |
|||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; |
|||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; |
|||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; |
|||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; |
|||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; |
|||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; |
|||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; |
@ -0,0 +1,2 @@ |
|||
[mysqld] |
|||
sql_mode="NO_ENGINE_SUBSTITUTION" |
@ -0,0 +1,14 @@ |
|||
#!/bin/bash |
|||
|
|||
for i in {30..0}; do |
|||
if echo "SELECT 1" | mysql -h"db" -u"root" -p"$MYSQL_ROOT_PASSWORD" &> /dev/null; then |
|||
break |
|||
fi |
|||
echo "MySQL init process in progress..." |
|||
sleep 1 |
|||
done |
|||
|
|||
if [ -f /docker-entrypoint-initdb.d/2_update.sql ]; then |
|||
mysql -h"db" -u"root" -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < /docker-entrypoint-initdb.d/2_update.sql |
|||
echo "Updated database with 2_update.sql" |
|||
fi |
@ -0,0 +1,349 @@ |
|||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ |
|||
|
|||
/* Document |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* 1. Correct the line height in all browsers. |
|||
* 2. Prevent adjustments of font size after orientation changes in iOS. |
|||
*/ |
|||
|
|||
html { |
|||
line-height: 1.15; /* 1 */ |
|||
-webkit-text-size-adjust: 100%; /* 2 */ |
|||
} |
|||
|
|||
/* Sections |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Remove the margin in all browsers. |
|||
*/ |
|||
|
|||
body { |
|||
margin: 0; |
|||
} |
|||
|
|||
/** |
|||
* Render the `main` element consistently in IE. |
|||
*/ |
|||
|
|||
main { |
|||
display: block; |
|||
} |
|||
|
|||
/** |
|||
* Correct the font size and margin on `h1` elements within `section` and |
|||
* `article` contexts in Chrome, Firefox, and Safari. |
|||
*/ |
|||
|
|||
h1 { |
|||
font-size: 2em; |
|||
margin: 0.67em 0; |
|||
} |
|||
|
|||
/* Grouping content |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* 1. Add the correct box sizing in Firefox. |
|||
* 2. Show the overflow in Edge and IE. |
|||
*/ |
|||
|
|||
hr { |
|||
box-sizing: content-box; /* 1 */ |
|||
height: 0; /* 1 */ |
|||
overflow: visible; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the inheritance and scaling of font size in all browsers. |
|||
* 2. Correct the odd `em` font sizing in all browsers. |
|||
*/ |
|||
|
|||
pre { |
|||
font-family: monospace, monospace; /* 1 */ |
|||
font-size: 1em; /* 2 */ |
|||
} |
|||
|
|||
/* Text-level semantics |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Remove the gray background on active links in IE 10. |
|||
*/ |
|||
|
|||
a { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
/** |
|||
* 1. Remove the bottom border in Chrome 57- |
|||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. |
|||
*/ |
|||
|
|||
abbr[title] { |
|||
border-bottom: none; /* 1 */ |
|||
text-decoration: underline; /* 2 */ |
|||
text-decoration: underline dotted; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Add the correct font weight in Chrome, Edge, and Safari. |
|||
*/ |
|||
|
|||
b, |
|||
strong { |
|||
font-weight: bolder; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the inheritance and scaling of font size in all browsers. |
|||
* 2. Correct the odd `em` font sizing in all browsers. |
|||
*/ |
|||
|
|||
code, |
|||
kbd, |
|||
samp { |
|||
font-family: monospace, monospace; /* 1 */ |
|||
font-size: 1em; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Add the correct font size in all browsers. |
|||
*/ |
|||
|
|||
small { |
|||
font-size: 80%; |
|||
} |
|||
|
|||
/** |
|||
* Prevent `sub` and `sup` elements from affecting the line height in |
|||
* all browsers. |
|||
*/ |
|||
|
|||
sub, |
|||
sup { |
|||
font-size: 75%; |
|||
line-height: 0; |
|||
position: relative; |
|||
vertical-align: baseline; |
|||
} |
|||
|
|||
sub { |
|||
bottom: -0.25em; |
|||
} |
|||
|
|||
sup { |
|||
top: -0.5em; |
|||
} |
|||
|
|||
/* Embedded content |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Remove the border on images inside links in IE 10. |
|||
*/ |
|||
|
|||
img { |
|||
border-style: none; |
|||
} |
|||
|
|||
/* Forms |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* 1. Change the font styles in all browsers. |
|||
* 2. Remove the margin in Firefox and Safari. |
|||
*/ |
|||
|
|||
button, |
|||
input, |
|||
optgroup, |
|||
select, |
|||
textarea { |
|||
font-family: inherit; /* 1 */ |
|||
font-size: 100%; /* 1 */ |
|||
line-height: 1.15; /* 1 */ |
|||
margin: 0; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Show the overflow in IE. |
|||
* 1. Show the overflow in Edge. |
|||
*/ |
|||
|
|||
button, |
|||
input { /* 1 */ |
|||
overflow: visible; |
|||
} |
|||
|
|||
/** |
|||
* Remove the inheritance of text transform in Edge, Firefox, and IE. |
|||
* 1. Remove the inheritance of text transform in Firefox. |
|||
*/ |
|||
|
|||
button, |
|||
select { /* 1 */ |
|||
text-transform: none; |
|||
} |
|||
|
|||
/** |
|||
* Correct the inability to style clickable types in iOS and Safari. |
|||
*/ |
|||
|
|||
button, |
|||
[type="button"], |
|||
[type="reset"], |
|||
[type="submit"] { |
|||
-webkit-appearance: button; |
|||
} |
|||
|
|||
/** |
|||
* Remove the inner border and padding in Firefox. |
|||
*/ |
|||
|
|||
button::-moz-focus-inner, |
|||
[type="button"]::-moz-focus-inner, |
|||
[type="reset"]::-moz-focus-inner, |
|||
[type="submit"]::-moz-focus-inner { |
|||
border-style: none; |
|||
padding: 0; |
|||
} |
|||
|
|||
/** |
|||
* Restore the focus styles unset by the previous rule. |
|||
*/ |
|||
|
|||
button:-moz-focusring, |
|||
[type="button"]:-moz-focusring, |
|||
[type="reset"]:-moz-focusring, |
|||
[type="submit"]:-moz-focusring { |
|||
outline: 1px dotted ButtonText; |
|||
} |
|||
|
|||
/** |
|||
* Correct the padding in Firefox. |
|||
*/ |
|||
|
|||
fieldset { |
|||
padding: 0.35em 0.75em 0.625em; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the text wrapping in Edge and IE. |
|||
* 2. Correct the color inheritance from `fieldset` elements in IE. |
|||
* 3. Remove the padding so developers are not caught out when they zero out |
|||
* `fieldset` elements in all browsers. |
|||
*/ |
|||
|
|||
legend { |
|||
box-sizing: border-box; /* 1 */ |
|||
color: inherit; /* 2 */ |
|||
display: table; /* 1 */ |
|||
max-width: 100%; /* 1 */ |
|||
padding: 0; /* 3 */ |
|||
white-space: normal; /* 1 */ |
|||
} |
|||
|
|||
/** |
|||
* Add the correct vertical alignment in Chrome, Firefox, and Opera. |
|||
*/ |
|||
|
|||
progress { |
|||
vertical-align: baseline; |
|||
} |
|||
|
|||
/** |
|||
* Remove the default vertical scrollbar in IE 10+. |
|||
*/ |
|||
|
|||
textarea { |
|||
overflow: auto; |
|||
} |
|||
|
|||
/** |
|||
* 1. Add the correct box sizing in IE 10. |
|||
* 2. Remove the padding in IE 10. |
|||
*/ |
|||
|
|||
[type="checkbox"], |
|||
[type="radio"] { |
|||
box-sizing: border-box; /* 1 */ |
|||
padding: 0; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Correct the cursor style of increment and decrement buttons in Chrome. |
|||
*/ |
|||
|
|||
[type="number"]::-webkit-inner-spin-button, |
|||
[type="number"]::-webkit-outer-spin-button { |
|||
height: auto; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the odd appearance in Chrome and Safari. |
|||
* 2. Correct the outline style in Safari. |
|||
*/ |
|||
|
|||
[type="search"] { |
|||
-webkit-appearance: textfield; /* 1 */ |
|||
outline-offset: -2px; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Remove the inner padding in Chrome and Safari on macOS. |
|||
*/ |
|||
|
|||
[type="search"]::-webkit-search-decoration { |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the inability to style clickable types in iOS and Safari. |
|||
* 2. Change font properties to `inherit` in Safari. |
|||
*/ |
|||
|
|||
::-webkit-file-upload-button { |
|||
-webkit-appearance: button; /* 1 */ |
|||
font: inherit; /* 2 */ |
|||
} |
|||
|
|||
/* Interactive |
|||
========================================================================== */ |
|||
|
|||
/* |
|||
* Add the correct display in Edge, IE 10+, and Firefox. |
|||
*/ |
|||
|
|||
details { |
|||
display: block; |
|||
} |
|||
|
|||
/* |
|||
* Add the correct display in all browsers. |
|||
*/ |
|||
|
|||
summary { |
|||
display: list-item; |
|||
} |
|||
|
|||
/* Misc |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Add the correct display in IE 10+. |
|||
*/ |
|||
|
|||
template { |
|||
display: none; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct display in IE 10. |
|||
*/ |
|||
|
|||
[hidden] { |
|||
display: none; |
|||
} |
@ -0,0 +1,123 @@ |
|||
body { |
|||
background-color: #1D1B1B; |
|||
font-family: system-ui,-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,Segoe UI,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji; |
|||
color: #fff; |
|||
} |
|||
|
|||
*, h1, h2, h3, h4, h5, h6, p, span { |
|||
color: #fff; |
|||
font-size: 20px; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
.success { |
|||
color: #63FB72; |
|||
} |
|||
|
|||
.text-muted { |
|||
opacity: 0.8; |
|||
} |
|||
|
|||
hr { |
|||
width: 100%; |
|||
height: 2px; |
|||
background: #2F2C2C; |
|||
border: none; |
|||
} |
|||
|
|||
.container { |
|||
padding: 40px; |
|||
max-width: 1440px; |
|||
margin: auto; |
|||
} |
|||
|
|||
.app-icon { |
|||
border-radius: 20px; |
|||
} |
|||
|
|||
.app { |
|||
display: flex; |
|||
margin: 20px 0 40px 0; |
|||
} |
|||
|
|||
.app > .app-icon { |
|||
flex-shrink: 0; |
|||
height: 140px; |
|||
width: 140px; |
|||
box-shadow: 0 0 40px 0 rgba(0,0,0,0.95); |
|||
margin-right: 24px; |
|||
} |
|||
|
|||
.app > .app-details > .app-status { |
|||
display: block; |
|||
font-size: 20px; |
|||
margin: 10px 0 0 0; |
|||
} |
|||
|
|||
|
|||
|
|||
.app > .app-details > .app-name { |
|||
font-size: 52px; |
|||
line-height: 52px; |
|||
font-weight: bold; |
|||
margin: 10px 0 0 0; |
|||
} |
|||
|
|||
.heading { |
|||
display: flex; |
|||
} |
|||
|
|||
.heading > .number { |
|||
flex-shrink: 0; |
|||
background: #C12525; |
|||
height: 66px; |
|||
width: 66px; |
|||
border-radius: 100%; |
|||
line-height: 66px; |
|||
text-align: center; |
|||
font-size: 36px; |
|||
font-weight: bold; |
|||
box-shadow: 0 0 20px 0 rgba(0,0,0,0.8); |
|||
} |
|||
.heading > .text { |
|||
font-size: 52px; |
|||
line-height: 52px; |
|||
font-weight: bold; |
|||
display: inline-block; |
|||
margin: 5px 0 0 20px; |
|||
} |
|||
|
|||
.steps { |
|||
margin: 40px 0 0 9px; |
|||
} |
|||
|
|||
.steps > .step { |
|||
margin-bottom: 20px; |
|||
font-size: 20px; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
.qr { |
|||
position: relative; |
|||
width: 260px; |
|||
height: 260px; |
|||
margin: 20px 0; |
|||
} |
|||
|
|||
.qr > .icon { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate3d(-50%, -50%, 0); |
|||
height: 66px; |
|||
width: 66px; |
|||
background: #ffffff; |
|||
} |
|||
|
|||
.qr > .icon > img { |
|||
display: block; |
|||
width: 60px; |
|||
height: 60px; |
|||
margin: 3px 0 0 3px; |
|||
border-radius: 15%; |
|||
} |
After Width: | Height: | Size: 2.5 KiB |
@ -0,0 +1,92 @@ |
|||
<!doctype html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="utf-8"> |
|||
|
|||
<title>Samourai Server</title> |
|||
|
|||
<link rel="shortcut icon" type="image/jpg" href="img/icon.svg" /> |
|||
|
|||
<link rel="stylesheet" href="css/normalize.css"> |
|||
<link rel="stylesheet" href="css/style.css"> |
|||
</head> |
|||
|
|||
<body> |
|||
<section class="container"> |
|||
<div class="app"> |
|||
<img class="app-icon" src="img/icon.svg" /> |
|||
<div class="app-details"> |
|||
<span class="app-status success">● Running</span> |
|||
<h1 class="app-name">Samourai Server</h1> |
|||
</div> |
|||
</div> |
|||
<p class="text-muted">Follow the instructions below to pair Dojo and Whirlpool running on your Umbrel to your |
|||
Samourai Wallet. |
|||
</p> |
|||
</section> |
|||
<hr /> |
|||
<section class="container"> |
|||
<div class="heading"> |
|||
<span class="number">1</span> |
|||
<h2 class="text">How to connect Dojo</h2> |
|||
</div> |
|||
<ol class="steps"> |
|||
<li class="step">Open the Samourai Wallet app on your phone.</li> |
|||
<li class="step">If you already have an existing wallet on it, send all of your funds to a different wallet |
|||
that you |
|||
control and erase your existing wallet from Settings > Wallet > Secure Erase Wallet. If you don’t |
|||
have a wallet setup, skip this step.</li> |
|||
<li class="step">Select Mainnet.</li> |
|||
<li class="step">Tap the 3-dot menu and select “Connect to existing Dojo”.</li> |
|||
<li class="step">Tap “Connect to existing Dojo” and scan this QR Code: |
|||
<div class="qr"> |
|||
<div class="qr-contents"></div> |
|||
<div class="icon"> |
|||
<img src="img/icon.svg" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</li> |
|||
<li class="step">Tap "Start New Wallet" and finish the wallet creation process.</li> |
|||
<li class="step">Congratulations! Your Samourai Wallet is now backed by the Dojo server running on your |
|||
Umbrel. Open |
|||
Network Options by tapping the WiFi-like icon on the top to verify if “Dojo Full Node” is successfully |
|||
enabled (it should display a green dot).</li> |
|||
</ol> |
|||
</section> |
|||
<hr /> |
|||
<section class="container"> |
|||
<div class="heading"> |
|||
<span class="number">2</span> |
|||
<h2 class="text">How to connect Whirlpool</h2> |
|||
</div> |
|||
<ol class="steps"> |
|||
<li class="step">Install <a href="https://gist.github.com/lukechilds/0be1d56ecd28092822e4fa750b5945c0" target="_blank">Tor</a> on your computer.</li> |
|||
<li class="step">Download and install <a href="https://code.samourai.io/whirlpool/whirlpool-gui/-/releases" |
|||
target="_blank">Whirlpool GUI</a>.</li> |
|||
<li class="step">Select: Advanced: remote CLI.</li> |
|||
<li class="step">Enter "<b id="whirlpool-hidden-service"></b>" (without quotes) in “CLI |
|||
address”.</li> |
|||
<li class="step">Tor proxy should now auto enable and set itself to “socks5://127.0.0.1:9050”.</li> |
|||
<li class="step">Click connect.</li> |
|||
<li class="step">Click QR code icon to scan a QR code from Samourai Wallet on your phone.</li> |
|||
<li class="step">Open Samourai Wallet on your phone.</li> |
|||
<li class="step">Go Settings > Transactions > Experimental > Pair to Whirlpool GUI. Show the QR code on your |
|||
phone to your desktop's webcam to scan it.</li> |
|||
<li class="step">Click “Initialize GUI”.</li> |
|||
<li class="step">Enter your Samourai Wallet’s passphrase (BIP39 passphrase set in Samourai wallet).</li> |
|||
<li class="step">Choose a number of mixes for a UTXO.</li> |
|||
<li class="step">Click “Mix”.</li> |
|||
<li class="step">Congratulations! Whirlpool is now mixing your UTXOs on your Umbrel!</li> |
|||
</ol> |
|||
<p><strong>Note:</strong> You'll need to open Whirlpool GUI and re-enter your password to continue mixing after restarting or updating your Umbrel.</p> |
|||
</section> |
|||
<script src="js/qrcode.min.js"></script> |
|||
<script src="js/conf.js"></script> |
|||
<script src="js/script.js"></script> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,5 @@ |
|||
var dojoHiddenService = "$DOJO_HIDDEN_SERVICE"; |
|||
var whirlpoolHiddenService = "http://$WHIRLPOOL_HIDDEN_SERVICE"; |
|||
var bitcoinNetwork = "$COMMON_BTC_NETWORK"; |
|||
var apiKey = "$NODE_ADMIN_KEY"; |
|||
var supportPrefix = "$NODE_PREFIX_SUPPORT"; |
File diff suppressed because one or more lines are too long
@ -0,0 +1,37 @@ |
|||
var baseRoute = bitcoinNetwork == "testnet" ? "test/v2" : "v2"; |
|||
|
|||
fetch(`http://${window.location.host}/${baseRoute}/auth/login`, { |
|||
method: 'POST', |
|||
headers: new Headers({ |
|||
'Content-Type': 'application/x-www-form-urlencoded' |
|||
}), |
|||
body: `apikey=${apiKey}` |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
fetch(`http://${window.location.host}/${baseRoute}/${supportPrefix}/pairing`, { |
|||
method: 'GET', |
|||
headers: new Headers({ |
|||
'Authorization': 'Bearer ' + data.authorizations.access_token, |
|||
'Content-Type': 'application/json' |
|||
}) |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
var pairingInfo = data; |
|||
pairingInfo.pairing.url = `http://${dojoHiddenService}/${baseRoute}`; |
|||
|
|||
const qrcodeSvg = new QRCode({ |
|||
content: JSON.stringify(pairingInfo), |
|||
join: true, |
|||
container: "svg-viewbox", |
|||
padding: 3, |
|||
color: "#000000", |
|||
background: "#ffffff", |
|||
ecl: "M", |
|||
}).svg(); |
|||
document.querySelector('.qr-contents').innerHTML = qrcodeSvg; |
|||
|
|||
document.getElementById('whirlpool-hidden-service').innerText = `${whirlpoolHiddenService}`; |
|||
}); |
|||
}); |
@ -0,0 +1,74 @@ |
|||
# Proxy WebSockets |
|||
# https://www.nginx.com/blog/websocket-nginx/ |
|||
map $http_upgrade $connection_upgrade { |
|||
default upgrade; |
|||
'' close; |
|||
} |
|||
|
|||
# WebSocket server listening here |
|||
upstream websocket { |
|||
server node:8080; |
|||
} |
|||
|
|||
# Site Configuration |
|||
server { |
|||
listen 80; |
|||
server_name _; |
|||
|
|||
# Set proxy timeouts for the application |
|||
proxy_connect_timeout 600; |
|||
proxy_read_timeout 600; |
|||
proxy_send_timeout 600; |
|||
send_timeout 600; |
|||
|
|||
# Connection details page |
|||
location /connect { |
|||
alias /var/www/connect; |
|||
index index.html; |
|||
try_files $uri $uri/ =404; |
|||
} |
|||
|
|||
# Proxy WebSocket connections first |
|||
location /v2/inv { |
|||
proxy_pass http://websocket; |
|||
proxy_http_version 1.1; |
|||
proxy_set_header Upgrade $http_upgrade; |
|||
proxy_set_header Connection $connection_upgrade; |
|||
} |
|||
|
|||
# PushTX server is separate, so proxy first |
|||
location /v2/pushtx/ { |
|||
proxy_pass http://node:8081/; |
|||
} |
|||
|
|||
# Tracker server is separate, so proxy first |
|||
location /v2/tracker/ { |
|||
proxy_pass http://node:8082/; |
|||
} |
|||
|
|||
# Proxy requests to maintenance tool |
|||
location = /admin/conf/index.js { |
|||
proxy_pass http://node:8080/static/admin/conf/index-mainnet.js; |
|||
} |
|||
|
|||
location /admin/ { |
|||
proxy_pass http://node:8080/static/admin/; |
|||
} |
|||
|
|||
# Proxy all other v2 requests to the accounts server |
|||
location /v2/ { |
|||
proxy_pass http://node:8080/; |
|||
} |
|||
|
|||
# Redirect onion address to maintenance tool |
|||
location = / { |
|||
return 301 /admin; |
|||
} |
|||
|
|||
# Serve remaining requests |
|||
location / { |
|||
return 200 '{"status":"ok"}'; |
|||
add_header Content-Type application/json; |
|||
} |
|||
} |
|||
|
@ -0,0 +1,45 @@ |
|||
user nginx; |
|||
worker_processes auto; |
|||
daemon off; |
|||
|
|||
# Log critical errors and higher to stderr |
|||
# (see https://github.com/nginxinc/docker-nginx/blob/594ce7a8bc26c85af88495ac94d5cd0096b306f7/mainline/alpine/Dockerfile#L104) |
|||
error_log /var/log/nginx/error.log crit; |
|||
pid /var/run/nginx.pid; |
|||
|
|||
|
|||
events { |
|||
worker_connections 1024; |
|||
} |
|||
|
|||
|
|||
http { |
|||
include /etc/nginx/mime.types; |
|||
default_type application/octet-stream; |
|||
|
|||
# Disable activity logging for privacy. |
|||
access_log off; |
|||
|
|||
# Do not reveal the version of server |
|||
server_tokens off; |
|||
|
|||
sendfile on; |
|||
|
|||
keepalive_timeout 95; |
|||
|
|||
# Enable response compression |
|||
gzip on; |
|||
# Compression level: 1-9 |
|||
gzip_comp_level 1; |
|||
# Disable gzip compression for older IE |
|||
gzip_disable msie6; |
|||
# Minimum length of response before gzip kicks in |
|||
gzip_min_length 128; |
|||
# Compress these MIME types in addition to text/html |
|||
gzip_types application/json; |
|||
# Help with proxying by adding the Vary: Accept-Encoding response |
|||
gzip_vary on; |
|||
|
|||
include /etc/nginx/sites-enabled/*.conf; |
|||
} |
|||
|
@ -0,0 +1,79 @@ |
|||
# Proxy WebSockets |
|||
# https://www.nginx.com/blog/websocket-nginx/ |
|||
map $http_upgrade $connection_upgrade { |
|||
default upgrade; |
|||
'' close; |
|||
} |
|||
|
|||
# WebSocket server listening here |
|||
upstream websocket { |
|||
server node:8080; |
|||
} |
|||
|
|||
# Site Configuration |
|||
server { |
|||
listen 80; |
|||
server_name _; |
|||
|
|||
# Set proxy timeouts for the application |
|||
proxy_connect_timeout 600; |
|||
proxy_read_timeout 600; |
|||
proxy_send_timeout 600; |
|||
send_timeout 600; |
|||
|
|||
# Connection details page |
|||
location /connect { |
|||
alias /var/www/connect; |
|||
index index.html; |
|||
try_files $uri $uri/ =404; |
|||
} |
|||
|
|||
# Proxy WebSocket connections first |
|||
location /test/v2/inv { |
|||
proxy_pass http://websocket; |
|||
proxy_http_version 1.1; |
|||
proxy_set_header Upgrade $http_upgrade; |
|||
proxy_set_header Connection $connection_upgrade; |
|||
} |
|||
|
|||
# PushTX server is separate, so proxy first |
|||
location /test/v2/pushtx/ { |
|||
proxy_pass http://node:8081/; |
|||
} |
|||
|
|||
# Tracker server is separate, so proxy first |
|||
location /test/v2/tracker/ { |
|||
proxy_pass http://node:8082/; |
|||
} |
|||
|
|||
# Proxy requests to maintenance tool |
|||
location = /admin/conf/index.js { |
|||
proxy_pass http://node:8080/static/admin/conf/index-testnet.js; |
|||
} |
|||
|
|||
location /admin/ { |
|||
proxy_pass http://node:8080/static/admin/; |
|||
} |
|||
|
|||
# Proxy all other v2 requests to the accounts server |
|||
location /test/v2/ { |
|||
proxy_pass http://node:8080/; |
|||
} |
|||
|
|||
# Redirect onion address to maintenance tool |
|||
location = / { |
|||
return 301 /admin; |
|||
} |
|||
|
|||
# Serve remaining requests |
|||
location / { |
|||
return 200 '{"status":"ok"}'; |
|||
add_header Content-Type application/json; |
|||
} |
|||
|
|||
location /test/ { |
|||
return 200 '{"status":"ok"}'; |
|||
add_header Content-Type application/json; |
|||
} |
|||
} |
|||
|
@ -0,0 +1,79 @@ |
|||
#!/bin/sh |
|||
|
|||
TIMEOUT=15 |
|||
QUIET=0 |
|||
|
|||
echoerr() { |
|||
if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi |
|||
} |
|||
|
|||
usage() { |
|||
exitcode="$1" |
|||
cat << USAGE >&2 |
|||
Usage: |
|||
$cmdname host:port [-t timeout] [-- command args] |
|||
-q | --quiet Do not output any status messages |
|||
-t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout |
|||
-- COMMAND ARGS Execute command with args after the test finishes |
|||
USAGE |
|||
exit "$exitcode" |
|||
} |
|||
|
|||
wait_for() { |
|||
for i in `seq $TIMEOUT` ; do |
|||
nc -z "$HOST" "$PORT" > /dev/null 2>&1 |
|||
|
|||
result=$? |
|||
if [ $result -eq 0 ] ; then |
|||
if [ $# -gt 0 ] ; then |
|||
exec "$@" |
|||
fi |
|||
exit 0 |
|||
fi |
|||
sleep 1 |
|||
done |
|||
echo "Operation timed out" >&2 |
|||
exit 1 |
|||
} |
|||
|
|||
while [ $# -gt 0 ] |
|||
do |
|||
case "$1" in |
|||
*:* ) |
|||
HOST=$(printf "%s\n" "$1"| cut -d : -f 1) |
|||
PORT=$(printf "%s\n" "$1"| cut -d : -f 2) |
|||
shift 1 |
|||
;; |
|||
-q | --quiet) |
|||
QUIET=1 |
|||
shift 1 |
|||
;; |
|||
-t) |
|||
TIMEOUT="$2" |
|||
if [ "$TIMEOUT" = "" ]; then break; fi |
|||
shift 2 |
|||
;; |
|||
--timeout=*) |
|||
TIMEOUT="${1#*=}" |
|||
shift 1 |
|||
;; |
|||
--) |
|||
shift |
|||
break |
|||
;; |
|||
--help) |
|||
usage 0 |
|||
;; |
|||
*) |
|||
echoerr "Unknown argument: $1" |
|||
usage 1 |
|||
;; |
|||
esac |
|||
done |
|||
|
|||
if [ "$HOST" = "" -o "$PORT" = "" ]; then |
|||
echoerr "Error: you need to provide a host and port to test." |
|||
usage 2 |
|||
fi |
|||
|
|||
wait_for "$@" |
Loading…
Reference in new issue