mirror of
https://github.com/EvernodeXRPL/sashimono.git
synced 2026-07-23 23:20:42 +00:00
IPV6 related Message board changes. (#284)
This commit is contained in:
committed by
GitHub
parent
20cfbbfad0
commit
8bcb2db9b0
8
dependencies/user-install.sh
vendored
8
dependencies/user-install.sh
vendored
@@ -170,13 +170,13 @@ echo "[Service]
|
||||
Environment=DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns" >$docker_service_override_conf
|
||||
|
||||
# We need to enable ipv6 configurations if outbound ipv6 address is specified.
|
||||
if [ "$outbound_ipv6" != "-"] && [ "$outbound_net_interface" != "-"]; then
|
||||
if [ "$outbound_ipv6" != "-" ] && [ "$outbound_net_interface" != "-" ]; then
|
||||
|
||||
# Pass the relevant ipv6 parameters to rootlesskit flags. rootlesskit will in turn pass these to slirp4nets.
|
||||
# Also apply ipv6 route configuration patch in the dockerd process namespace (credits: https://github.com/containers/podman/issues/15850#issuecomment-1320028298)
|
||||
echo "
|
||||
Environment=\"DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=--ipv6 --outbound-addr6=$outbound_ipv6\"
|
||||
ExecStartPost=/bin/bash -c 'nsenter -U --preserve-credentials -n -t $(pgrep -u $user dockerd) /bin/bash -c \"ip addr add fd00::100/64 dev tap0 && ip route add default via fd00::2 dev tap0\"'
|
||||
ExecStartPost=/bin/bash -c 'nsenter -U --preserve-credentials -n -t $""(pgrep -u $user dockerd) /bin/bash -c \"ip addr add fd00::100/64 dev tap0 && ip route add default via fd00::2 dev tap0\"'
|
||||
" >>$docker_service_override_conf
|
||||
|
||||
# Set the predefined ipv6 parameters to docker daemon config.
|
||||
@@ -190,10 +190,10 @@ if [ "$outbound_ipv6" != "-"] && [ "$outbound_net_interface" != "-"]; then
|
||||
}" >$user_dir/.config/docker/daemon.json
|
||||
|
||||
# Add the outbound ipv6 address to the specified network interface.
|
||||
ip addr add $outbound_ipv6 $outbound_net_interface
|
||||
ip addr add $outbound_ipv6 dev $outbound_net_interface
|
||||
|
||||
# Add instructions to the cleanup script so the outbound ip assignment will be removed upon user install.
|
||||
echo "ip addr del $outbound_ipv6 $outbound_net_interface" >>$cleanup_script
|
||||
echo "ip addr del $outbound_ipv6 dev $outbound_net_interface" >>$cleanup_script
|
||||
fi
|
||||
|
||||
# Overwrite docker-rootless cli args on the docker service unit file (ExecStart is not supported by override.conf).
|
||||
|
||||
@@ -23,7 +23,7 @@ rm -r $tmp
|
||||
|
||||
# Override rootlesskit with our own version based on original rootlesskit v1.1.1
|
||||
# We need this custom version to have outbound ipv6 address support (https://github.com/EvernodeXRPL/rootlesskit/tree/outbound-addr-support)
|
||||
curl -s https://github.com/EvernodeXRPL/rootlesskit/releases/download/v1.1.1-evernode-patch1/rootlesskit --output $docker_bin/rootlesskit
|
||||
curl -fsSL https://github.com/EvernodeXRPL/rootlesskit/releases/download/v1.1.1-evernode-patch1/rootlesskit --output $docker_bin/rootlesskit
|
||||
chmod +x $docker_bin/rootlesskit
|
||||
|
||||
chown -R $(id -u):$(id -g) $docker_bin/*
|
||||
|
||||
50
installer/jshelper/package-lock.json
generated
50
installer/jshelper/package-lock.json
generated
@@ -6,7 +6,7 @@
|
||||
"": {
|
||||
"name": "evernode-setup-helper",
|
||||
"dependencies": {
|
||||
"evernode-js-client": "0.6.18",
|
||||
"evernode-js-client": "0.6.19",
|
||||
"ip6addr": "0.2.5"
|
||||
}
|
||||
},
|
||||
@@ -111,9 +111,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bignumber.js": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz",
|
||||
"integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==",
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
|
||||
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
@@ -363,9 +363,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/evernode-js-client": {
|
||||
"version": "0.6.18",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.18.tgz",
|
||||
"integrity": "sha512-0q6rp6qM/54zcOVi5GDftZ/ZvP5BeBZvwhH9dN+B5REvtNdaXeN2d0Jkj50LPaTiU6a/LCRMziRFUdV3eXtakA==",
|
||||
"version": "0.6.19",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.19.tgz",
|
||||
"integrity": "sha512-E8oEVsEOuX72V8ECmqt08U+Q/U4Kygl/X+my8TtnaSrDuIYu4EMMaFp0441XyNpTZH25rvE9rTwy5ZhvhN3T9g==",
|
||||
"dependencies": {
|
||||
"elliptic": "6.5.4",
|
||||
"libsodium-wrappers": "0.7.10",
|
||||
@@ -1026,9 +1026,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.13.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
|
||||
"integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.0.tgz",
|
||||
"integrity": "sha512-WR0RJE9Ehsio6U4TuM+LmunEsjQ5ncHlw4sn9ihD6RoJKZrVyH9FWV3dmnwu8B2aNib1OvG2X6adUCyFpQyWcg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
@@ -1172,9 +1172,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-client": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xrpl-client/-/xrpl-client-2.1.1.tgz",
|
||||
"integrity": "sha512-JKq6bMd50kdjyfrputVq8S7GI8Ttl1AxO7ALA6oRleAhoRfeicGbRjS5IFcL9pgsLIVzVC/7eKAtdhK+lf0ywA==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/xrpl-client/-/xrpl-client-2.1.2.tgz",
|
||||
"integrity": "sha512-Lg9aq8CSeL/9nx7THJThoYpSZVQ9Eq7M4YrXbLv8nN91izoUYMM6qcx2b1qeIQFb3oxQdVYkkqqxfjoiwp05/w==",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"websocket": "^1.0.34"
|
||||
@@ -1390,9 +1390,9 @@
|
||||
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg=="
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz",
|
||||
"integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig=="
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
|
||||
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug=="
|
||||
},
|
||||
"bindings": {
|
||||
"version": "1.5.0",
|
||||
@@ -1597,9 +1597,9 @@
|
||||
}
|
||||
},
|
||||
"evernode-js-client": {
|
||||
"version": "0.6.18",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.18.tgz",
|
||||
"integrity": "sha512-0q6rp6qM/54zcOVi5GDftZ/ZvP5BeBZvwhH9dN+B5REvtNdaXeN2d0Jkj50LPaTiU6a/LCRMziRFUdV3eXtakA==",
|
||||
"version": "0.6.19",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.19.tgz",
|
||||
"integrity": "sha512-E8oEVsEOuX72V8ECmqt08U+Q/U4Kygl/X+my8TtnaSrDuIYu4EMMaFp0441XyNpTZH25rvE9rTwy5ZhvhN3T9g==",
|
||||
"requires": {
|
||||
"elliptic": "6.5.4",
|
||||
"libsodium-wrappers": "0.7.10",
|
||||
@@ -2113,9 +2113,9 @@
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.13.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
|
||||
"integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.0.tgz",
|
||||
"integrity": "sha512-WR0RJE9Ehsio6U4TuM+LmunEsjQ5ncHlw4sn9ihD6RoJKZrVyH9FWV3dmnwu8B2aNib1OvG2X6adUCyFpQyWcg==",
|
||||
"requires": {}
|
||||
},
|
||||
"xrpl": {
|
||||
@@ -2258,9 +2258,9 @@
|
||||
}
|
||||
},
|
||||
"xrpl-client": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xrpl-client/-/xrpl-client-2.1.1.tgz",
|
||||
"integrity": "sha512-JKq6bMd50kdjyfrputVq8S7GI8Ttl1AxO7ALA6oRleAhoRfeicGbRjS5IFcL9pgsLIVzVC/7eKAtdhK+lf0ywA==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/xrpl-client/-/xrpl-client-2.1.2.tgz",
|
||||
"integrity": "sha512-Lg9aq8CSeL/9nx7THJThoYpSZVQ9Eq7M4YrXbLv8nN91izoUYMM6qcx2b1qeIQFb3oxQdVYkkqqxfjoiwp05/w==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"websocket": "^1.0.34"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"build": "ncc build index.js --minify -o dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"evernode-js-client": "0.6.18",
|
||||
"evernode-js-client": "0.6.19",
|
||||
"ip6addr": "0.2.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ if [ "$NO_MB" == "" ]; then
|
||||
# ! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN betagen $EVERNODE_GOVERNOR_ADDRESS $inetaddr $lease_amount $rippled_server $xrpl_account_secret && echo "XRPLACC_FAILURE" && rollback
|
||||
# doreg=1
|
||||
|
||||
! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN new $xrpl_account_address $xrpl_account_secret $EVERNODE_GOVERNOR_ADDRESS $inetaddr $lease_amount $rippled_server && echo "XRPLACC_FAILURE" && rollback
|
||||
! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN new $xrpl_account_address $xrpl_account_secret $EVERNODE_GOVERNOR_ADDRESS $inetaddr $lease_amount $rippled_server $ipv6_subnet $ipv6_net_interface && echo "XRPLACC_FAILURE" && rollback
|
||||
doreg=1
|
||||
fi
|
||||
|
||||
|
||||
@@ -483,14 +483,14 @@ function set_ipv6_subnet() {
|
||||
[ -z "$primary_subnet" ] && echo "Invalid ipv6 subnet specified. It must be a valid ipv6 subnet in the CIDR format of \"xxxx:xxxx:xxxx:xxxx::/NN\"." && continue
|
||||
|
||||
# For further validation, we check whether the subnet prefix is actually assigned to any network interfaces of the host.
|
||||
local subnet_prefix="$(cut -d'/' -f1 <<<$primary_subnet)"
|
||||
local subnet_prefix="$(cut -d'/' -f1 <<<$primary_subnet | sed 's/::*$//g')"
|
||||
local prefix_len="$(cut -d'/' -f2 <<<$primary_subnet)"
|
||||
local net_interfaces=$(ip -6 -br addr | grep $subnet_prefix)
|
||||
local interface_count=$(echo "$net_interfaces" | wc -l)
|
||||
|
||||
[ "$prefix_len" -gt $max_ipv6_prefix_len ] && echo "Maximum allowed prefix length for $evernode is $max_ipv6_prefix_len." && continue
|
||||
[ -z "$net_interfaces" ] && echo "Could not find a network interface with the specified ipv6 subnet." && continue
|
||||
[ "$interface_count" -gt 1 ] && echo "Found more than 1 network interface with the specified upv6 subnet." && echo "$net_interfaces" && continue
|
||||
[ "$interface_count" -gt 1 ] && echo "Found more than 1 network interface with the specified ipv6 subnet." && echo "$net_interfaces" && continue
|
||||
|
||||
ipv6_subnet=$primary_subnet
|
||||
ipv6_net_interface=$(echo "$net_interfaces" | awk '{ print $1 }')
|
||||
@@ -1008,6 +1008,8 @@ function config() {
|
||||
local update_mb=0
|
||||
|
||||
local sub_mode=${1}
|
||||
local occupied_instance_count=$(sashi list | jq length)
|
||||
|
||||
if [ "$sub_mode" == "resources" ] ; then
|
||||
|
||||
local ramMB=${2} # memory to allocate for contract instances.
|
||||
@@ -1022,6 +1024,10 @@ function config() {
|
||||
\n Disk space: $(GB $max_storage_kbytes)
|
||||
\n Instance count: $max_instance_count\n" && exit 0
|
||||
|
||||
if ( [[ $occupied_instance_count -gt 0 ]] ); then
|
||||
echomult "Could not proceed the re-configuration as there are occupied instances." && exit 1
|
||||
fi
|
||||
|
||||
local help_text="Usage: evernode config resources | evernode config resources <memory MB> <swap MB> <disk MB> <max instance count>\n"
|
||||
[ ! -z $ramMB ] && [[ $ramMB != 0 ]] && ! validate_positive_decimal $ramMB &&
|
||||
echomult "Invalid memory size.\n $help_text" && exit 1
|
||||
@@ -1057,7 +1063,11 @@ function config() {
|
||||
|
||||
local amount=${2} # Contract instance lease amount in EVRs.
|
||||
[ -z $amount ] && echomult "Your current lease amount is: $cfg_lease_amount EVRs.\n" && exit 0
|
||||
|
||||
|
||||
if ( [[ $occupied_instance_count -gt 0 ]] ); then
|
||||
echomult "Could not proceed the re-configuration as there are occupied instances." && exit 1
|
||||
fi
|
||||
|
||||
! validate_positive_decimal $amount &&
|
||||
echomult "Invalid lease amount.\n Usage: evernode config leaseamt | evernode config leaseamt <lease amount>\n" &&
|
||||
exit 1
|
||||
|
||||
@@ -13,16 +13,18 @@ async function main() {
|
||||
|
||||
try {
|
||||
if (process.argv.length >= 3) {
|
||||
if (process.argv.length == 9 && process.argv[2] === 'new') {
|
||||
if (process.argv.length >= 9 && process.argv[2] === 'new') {
|
||||
const accountAddress = process.argv[3];
|
||||
const accountSecret = process.argv[4];
|
||||
const governorAddress = process.argv[5];
|
||||
const domain = process.argv[6];
|
||||
const leaseAmount = process.argv[7];
|
||||
const rippledServer = process.argv[8];
|
||||
const ipv6Subnet = (process.argv[9] === '-') ? null : process.argv[9];
|
||||
const ipv6NetInterface = (process.argv[10] === '-') ? null : process.argv[10];
|
||||
const setup = new Setup();
|
||||
const acc = await setup.setupHostAccount(accountAddress, accountSecret, rippledServer, governorAddress, domain);
|
||||
setup.newConfig(acc.address, acc.secret, governorAddress, parseFloat(leaseAmount), rippledServer);
|
||||
setup.newConfig(acc.address, acc.secret, governorAddress, parseFloat(leaseAmount), rippledServer, ipv6Subnet, ipv6NetInterface);
|
||||
}
|
||||
else if (process.argv.length === 7 && process.argv[2] === 'betagen') {
|
||||
const governorAddress = process.argv[3];
|
||||
@@ -71,7 +73,7 @@ async function main() {
|
||||
console.log(`Usage:
|
||||
node index.js - Run message board.
|
||||
node index.js version - Print version.
|
||||
node index.js new [address] [secret] [governorAddress] [leaseAmount] - Create new config files.
|
||||
node index.js new [address] [secret] [governorAddress] [leaseAmount] [rippledServer] [ipv6Subnet] [ipv6Interface] - Create new config files.
|
||||
node index.js betagen [governorAddress] [domain or ip] [leaseAmount] [rippledServer] - Generate beta host account and populate the configs.
|
||||
node index.js register [countryCode] [cpuMicroSec] [ramKb] [swapKb] [diskKb] [totalInstanceCount] [description] - Register the host on Evernode.
|
||||
node index.js transfer [transfereeAddress] - Initiate a transfer.
|
||||
|
||||
@@ -23,12 +23,13 @@ appenv = {
|
||||
SASHI_CONFIG_PATH: (appenv.IS_DEV_MODE ? "../build/" : path.join(appenv.DATA_DIR, '../')) + "sa.cfg",
|
||||
SASHI_TABLE_NAME: 'instances',
|
||||
LAST_WATCHED_LEDGER: 'last_watched_ledger',
|
||||
LAST_ASSIGNED_IPV6_ADDRESS: 'last_assigned_ipv6_address',
|
||||
ACQUIRE_LEASE_TIMEOUT_THRESHOLD: 0.8,
|
||||
ACQUIRE_LEASE_WAIT_TIMEOUT_THRESHOLD: 0.4,
|
||||
ORPHAN_PRUNE_SCHEDULER_INTERVAL_HOURS: 4,
|
||||
SASHIMONO_SCHEDULER_INTERVAL_SECONDS: 2,
|
||||
SASHI_CLI_PATH: appenv.IS_DEV_MODE ? "../build/sashi" : "/usr/bin/sashi",
|
||||
MB_VERSION: '0.6.7',
|
||||
MB_VERSION: '0.6.8',
|
||||
TOS_HASH: '757A0237B44D8B2BBB04AE2BAD5813858E0AECD2F0B217075E27E0630BA74314' // This is the sha256 hash of TOS text.
|
||||
}
|
||||
Object.freeze(appenv);
|
||||
|
||||
@@ -348,7 +348,7 @@ class MessageBoard {
|
||||
console.log(`Cannot find an URIToken for ${lease.containerName}`);
|
||||
else {
|
||||
const uriInfo = evernode.UtilHelpers.decodeLeaseTokenUri(uriToken.URI);
|
||||
await this.destroyInstance(lease.containerName, lease.tenant, uriInfo.leaseIndex);
|
||||
await this.destroyInstance(lease.containerName, lease.tenant, uriInfo.leaseIndex, uriInfo?.outboundIP?.address);
|
||||
}
|
||||
|
||||
this.activeInstanceCount--;
|
||||
@@ -528,7 +528,7 @@ class MessageBoard {
|
||||
// After destroying, If the URIToken is owned by the tenant, burn the URIToken and recreate and refund the tenant.
|
||||
if (uriToken) {
|
||||
const uriInfo = evernode.UtilHelpers.decodeLeaseTokenUri(uriToken.URI);
|
||||
await this.recreateLeaseOffer(instance.name, lease.tenant_xrp_address, uriInfo.leaseIndex);
|
||||
await this.recreateLeaseOffer(instance.name, lease.tenant_xrp_address, uriInfo.leaseIndex, uriInfo.outboundIP?.address);
|
||||
|
||||
await this.#queueAction(async () => {
|
||||
console.log(`Refunding tenant ${lease.tenant_xrp_address}...`);
|
||||
@@ -575,7 +575,7 @@ class MessageBoard {
|
||||
const uriToken = (await (new evernode.XrplAccount(lease.tenant_xrp_address)).getURITokens())?.find(n => n.index == lease.container_name);
|
||||
if (uriToken) {
|
||||
const uriInfo = evernode.UtilHelpers.decodeLeaseTokenUri(uriToken.URI);
|
||||
await this.recreateLeaseOffer(lease.container_name, lease.tenant_xrp_address, uriInfo.leaseIndex);
|
||||
await this.recreateLeaseOffer(lease.container_name, lease.tenant_xrp_address, uriInfo.leaseIndex, uriInfo.outboundIP?.address);
|
||||
|
||||
await this.#queueAction(async () => {
|
||||
// If lease is in ACQUIRING status acquire response is not received by the tenant and lease is not in expiry list.
|
||||
@@ -669,7 +669,7 @@ class MessageBoard {
|
||||
if (uriToken) {
|
||||
const uriInfo = evernode.UtilHelpers.decodeLeaseTokenUri(uriToken.URI);
|
||||
// Have to recreate the URIToken Offer for the lease as previous one was not utilized.
|
||||
await this.recreateLeaseOffer(eventInfo.data.uriTokenId, eventInfo.data.tenant, uriInfo.leaseIndex);
|
||||
await this.recreateLeaseOffer(eventInfo.data.uriTokenId, eventInfo.data.tenant, uriInfo.leaseIndex, uriInfo.outboundIP?.address);
|
||||
|
||||
await this.#queueAction(async () => {
|
||||
console.log(`Refunding tenant ${eventInfo.data.tenant} for acquire...`);
|
||||
@@ -723,14 +723,14 @@ class MessageBoard {
|
||||
return null;
|
||||
}
|
||||
|
||||
async recreateLeaseOffer(uriTokenId, tenantAddress, leaseIndex) {
|
||||
async recreateLeaseOffer(uriTokenId, tenantAddress, leaseIndex, outboundIP) {
|
||||
await this.#queueAction(async () => {
|
||||
// Burn the URIToken and recreate the offer.
|
||||
await this.hostClient.expireLease(uriTokenId, tenantAddress).catch(console.error);
|
||||
// We refresh the config here, So if the purchaserTargetPrice is updated by the purchaser service, the new value will be taken.
|
||||
await this.hostClient.refreshConfig();
|
||||
const leaseAmount = this.cfg.xrpl.leaseAmount ? this.cfg.xrpl.leaseAmount : parseFloat(this.hostClient.config.purchaserTargetPrice);
|
||||
await this.hostClient.offerLease(leaseIndex, leaseAmount, appenv.TOS_HASH).catch(console.error);
|
||||
await this.hostClient.offerLease(leaseIndex, leaseAmount, appenv.TOS_HASH, outboundIP).catch(console.error);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -743,6 +743,8 @@ class MessageBoard {
|
||||
let requestValidated = false;
|
||||
let createRes;
|
||||
let leaseIndex = -1; // Lease index cannot be negative, So we keep initial non populated value as -1.
|
||||
let instanceOutboundIPAddress = null;
|
||||
|
||||
|
||||
this.db.open();
|
||||
|
||||
@@ -762,6 +764,7 @@ class MessageBoard {
|
||||
throw 'Could not find the uriToken for lease acquire request.';
|
||||
|
||||
const uriInfo = evernode.UtilHelpers.decodeLeaseTokenUri(uriToken.URI);
|
||||
instanceOutboundIPAddress = uriInfo?.outboundIP?.address;
|
||||
|
||||
if (leaseAmount != uriInfo.leaseAmount)
|
||||
throw 'URIToken embedded lease amount and acquire lease amount does not match.';
|
||||
@@ -790,10 +793,10 @@ class MessageBoard {
|
||||
console.error(`Sashimono busy timeout. Took: ${diff} seconds. Threshold: ${threshold} seconds`);
|
||||
// Update the lease status of the request to 'SashiTimeout'.
|
||||
await this.updateAcquireStatus(acquireRefId, LeaseStatus.SASHI_TIMEOUT);
|
||||
await this.recreateLeaseOffer(uriTokenId, tenantAddress, leaseIndex);
|
||||
await this.recreateLeaseOffer(uriTokenId, tenantAddress, leaseIndex, uriInfo?.outboundIP?.address);
|
||||
}
|
||||
else {
|
||||
const instanceRequirements = r.payload;
|
||||
const instanceRequirements = { ...r.payload, outbound_ipv6: (uriInfo.outboundIP?.family == 6) ? uriInfo.outboundIP?.address : "-", outbound_net_interface: (uriInfo.outboundIP?.family == 6) ? this.cfg.networking.ipv6.interface : "-" };
|
||||
createRes = await this.sashiCli.createInstance(containerName, instanceRequirements);
|
||||
|
||||
// Number of validated ledgers passed while the instance is created.
|
||||
@@ -804,7 +807,7 @@ class MessageBoard {
|
||||
console.error(`Instance creation timeout. Took: ${diff} seconds. Threshold: ${threshold} seconds`);
|
||||
// Update the lease status of the request to 'SashiTimeout'.
|
||||
await this.updateLeaseStatus(acquireRefId, LeaseStatus.SASHI_TIMEOUT);
|
||||
await this.destroyInstance(createRes.content.name, tenantAddress, leaseIndex);
|
||||
await this.destroyInstance(createRes.content.name, tenantAddress, leaseIndex, instanceOutboundIPAddress);
|
||||
} else {
|
||||
console.log(`Instance created for ${tenantAddress}`);
|
||||
|
||||
@@ -826,6 +829,10 @@ class MessageBoard {
|
||||
await this.hostClient.updateRegInfo(this.activeInstanceCount);
|
||||
|
||||
// Send the acquire response with created instance info.
|
||||
// Modify Response.
|
||||
createRes.content.domain = createRes.content.ip;
|
||||
createRes.content.outbound_ip = uriInfo.outboundIP?.address;
|
||||
delete createRes.content.ip;
|
||||
const options = instanceRequirements?.messageKey ? { messageKey: instanceRequirements.messageKey } : {};
|
||||
await this.hostClient.acquireSuccess(acquireRefId, tenantAddress, createRes, options);
|
||||
});
|
||||
@@ -845,7 +852,7 @@ class MessageBoard {
|
||||
|
||||
// Re-create the lease offer (Only if the uriToken belongs to this request has a lease index).
|
||||
if (leaseIndex >= 0)
|
||||
await this.recreateLeaseOffer(uriTokenId, tenantAddress, leaseIndex).catch(console.error);
|
||||
await this.recreateLeaseOffer(uriTokenId, tenantAddress, leaseIndex, instanceOutboundIPAddress).catch(console.error);
|
||||
|
||||
await this.#queueAction(async () => {
|
||||
// Send error transaction with received leaseAmount.
|
||||
@@ -858,10 +865,10 @@ class MessageBoard {
|
||||
}
|
||||
}
|
||||
|
||||
async destroyInstance(containerName, tenantAddress, leaseIndex) {
|
||||
async destroyInstance(containerName, tenantAddress, leaseIndex, outboundIP = null) {
|
||||
// Destroy the instance.
|
||||
await this.sashiCli.destroyInstance(containerName);
|
||||
await this.recreateLeaseOffer(containerName, tenantAddress, leaseIndex).catch(console.error);
|
||||
await this.recreateLeaseOffer(containerName, tenantAddress, leaseIndex, outboundIP).catch(console.error);
|
||||
}
|
||||
|
||||
async handleExtendLease(r) {
|
||||
@@ -974,6 +981,9 @@ class MessageBoard {
|
||||
{ name: 'value', type: DataTypes.INTEGER, notNull: true }
|
||||
]);
|
||||
await this.createLastWatchedLedgerEntryIfNotExists();
|
||||
if (this.cfg?.networking?.ipv6?.subnet && this.cfg?.networking?.ipv6?.interface) {
|
||||
await this.createLastAssignedIPEntryIfNotExists();
|
||||
}
|
||||
}
|
||||
|
||||
async createLastWatchedLedgerEntryIfNotExists() {
|
||||
@@ -983,6 +993,16 @@ class MessageBoard {
|
||||
}
|
||||
}
|
||||
|
||||
async createLastAssignedIPEntryIfNotExists() {
|
||||
let ret = await this.db.getValues(this.utilTable, { name: appenv.LAST_ASSIGNED_IPV6_ADDRESS });
|
||||
if (ret.length === 0) {
|
||||
const lastMintedLeaseToken = (await this.hostClient.xrplAcc.getURITokens()).filter(n => evernode.EvernodeHelpers.isValidURI(n.URI, evernode.EvernodeConstants.LEASE_TOKEN_PREFIX_HEX)).sort((a, b) => b.PreviousTxnLgrSeq - a.PreviousTxnLgrSeq)[0];
|
||||
const lastMintedLeaseTokenData = evernode.UtilHelpers.decodeLeaseTokenUri(lastMintedLeaseToken.URI);
|
||||
|
||||
await this.db.insertValue(this.utilTable, { name: appenv.LAST_ASSIGNED_IPV6_ADDRESS, value: lastMintedLeaseTokenData.outboundIP?.address });
|
||||
}
|
||||
}
|
||||
|
||||
async getAcquiredRecords() {
|
||||
return (await this.db.getValues(this.leaseTable, { status: LeaseStatus.ACQUIRED }));
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ const fs = require('fs');
|
||||
const { SqliteDatabase } = require('./sqlite-handler');
|
||||
const { ConfigHelper } = require('./config-helper');
|
||||
const { SashiCLI } = require('./sashi-cli');
|
||||
const { UtilHelper } = require('./util-helper');
|
||||
|
||||
function setEvernodeDefaults(governorAddress, rippledServer, xrplApi = null) {
|
||||
evernode.Defaults.set({
|
||||
@@ -56,8 +57,8 @@ class Setup {
|
||||
ConfigHelper.writeConfig(cfg, appenv.CONFIG_PATH, appenv.SECRET_CONFIG_PATH);
|
||||
}
|
||||
|
||||
newConfig(address = "", secret = "", governorAddress = "", leaseAmount = 0, rippledServer = null) {
|
||||
this.#saveConfig({
|
||||
newConfig(address = "", secret = "", governorAddress = "", leaseAmount = 0, rippledServer = null, ipv6Subnet = null, ipv6NetInterface = null) {
|
||||
const baseConfig = {
|
||||
version: appenv.MB_VERSION,
|
||||
xrpl: {
|
||||
address: address,
|
||||
@@ -66,7 +67,9 @@ class Setup {
|
||||
rippledServer: rippledServer || appenv.DEFAULT_RIPPLED_SERVER,
|
||||
leaseAmount: leaseAmount
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.#saveConfig(ipv6NetInterface ? { ...baseConfig, networking: { ipv6: { subnet: ipv6Subnet, interface: ipv6NetInterface } } } : baseConfig);
|
||||
}
|
||||
|
||||
async setupHostAccount(address, secret, rippledServer, governorAddress, domain) {
|
||||
@@ -176,7 +179,8 @@ class Setup {
|
||||
async register(countryCode, cpuMicroSec, ramKb, swapKb, diskKb, totalInstanceCount, cpuModel, cpuCount, cpuSpeed, emailAddress, description) {
|
||||
console.log("Registering host...");
|
||||
let cpuModelFormatted = cpuModel.replaceAll('_', ' ');
|
||||
const acc = this.#getConfig().xrpl;
|
||||
const config = this.#getConfig();
|
||||
const acc = config.xrpl;
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
|
||||
const hostClient = new evernode.HostClient(acc.address, acc.secret);
|
||||
@@ -200,10 +204,15 @@ class Setup {
|
||||
await hostClient.register(countryCode, cpuMicroSec,
|
||||
Math.floor((ramKb + swapKb) / 1000), Math.floor(diskKb / 1000), totalInstanceCount, cpuModelFormatted.substring(0, 40), cpuCount, cpuSpeed, description.replaceAll('_', ' '), emailAddress);
|
||||
|
||||
// Generate IPV6 Address (If the host has done relevant configuration)
|
||||
let ipV6AddressList = [];
|
||||
if (config?.networking?.ipv6?.subnet)
|
||||
ipV6AddressList = UtilHelper.generateIPV6Addresses(config.networking.ipv6.subnet, totalInstanceCount);
|
||||
|
||||
// Create lease offers.
|
||||
console.log("Creating lease offers for instance slots...");
|
||||
for (let i = 0; i < totalInstanceCount; i++) {
|
||||
await hostClient.offerLease(i, acc.leaseAmount, appenv.TOS_HASH);
|
||||
await hostClient.offerLease(i, acc.leaseAmount, appenv.TOS_HASH, ipV6AddressList.length > 0 ? ipV6AddressList[i] : null);
|
||||
console.log(`Created lease offer ${i + 1} of ${totalInstanceCount}.`);
|
||||
}
|
||||
|
||||
@@ -316,7 +325,7 @@ class Setup {
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, hostClient.xrplApi);
|
||||
|
||||
const hostInfo = await hostClient.getHostInfo();
|
||||
|
||||
|
||||
await hostClient.disconnect();
|
||||
|
||||
console.log(JSON.stringify(hostInfo, null, 2));
|
||||
@@ -429,11 +438,22 @@ class Setup {
|
||||
// Get sold URITokens.
|
||||
const db = new SqliteDatabase(appenv.DB_PATH);
|
||||
const leaseTable = appenv.DB_TABLE_NAME;
|
||||
const utilTable = appenv.DB_UTIL_TABLE_NAME;
|
||||
const config = this.#getConfig();
|
||||
|
||||
db.open();
|
||||
const leaseRecords = (await db.getValues(leaseTable).finally(() => { db.close() })).filter(i => (i.status === "Acquired" || i.status === "Extended"));
|
||||
const soldCount = leaseRecords.length;
|
||||
|
||||
// NOTE : This was added after IPV6 address assignment to URI tokens. If we allow to change the instance count
|
||||
// there may be an issue of loosing the IP address assignment order, because the acquisitions never follows any order.
|
||||
// Due to that nature there may a chance of having sold instances with intermediate IP addresses. Hence in such kind of a scenario
|
||||
// we cannot handle the LAST_ASSIGNED_IPV6_ADDRESS property as we expect.
|
||||
// TODO : Should cater to reconfigure with occupied leases (sold instances).
|
||||
if (soldCount)
|
||||
throw `There are ${soldCount} active instances. Hence it is not possible to reconfigure.`;
|
||||
|
||||
|
||||
if (totalInstanceCount && soldCount > totalInstanceCount)
|
||||
throw `There are ${soldCount} active instances, So max instance count cannot be less than that.`;
|
||||
|
||||
@@ -526,8 +546,12 @@ class Setup {
|
||||
}
|
||||
}
|
||||
|
||||
db.open();
|
||||
let lastAssignedIPV6 = (config?.networking?.ipv6?.subnet) ? (await db.getValues(utilTable).finally(() => { db.close() })).find(i => (i.name === appenv.LAST_ASSIGNED_IPV6_ADDRESS)).value : null;
|
||||
for (const uriToken of uriTokensToBurn) {
|
||||
try {
|
||||
if (lastAssignedIPV6)
|
||||
lastAssignedIPV6 = UtilHelper.generateValidIPV6Address(config.networking.ipv6.subnet, lastAssignedIPV6, true);
|
||||
await hostClient.expireLease(uriToken.uriTokenId);
|
||||
}
|
||||
catch (e) {
|
||||
@@ -540,17 +564,26 @@ class Setup {
|
||||
await initClients(rippledServer);
|
||||
}
|
||||
|
||||
for (const idx of uriTokenIndexesToCreate) {
|
||||
for (const idx of uriTokenIndexesToCreate.sort((a, b) => { return a - b; })) {
|
||||
try {
|
||||
if (lastAssignedIPV6)
|
||||
lastAssignedIPV6 = UtilHelper.generateValidIPV6Address(config.networking.ipv6.subnet, lastAssignedIPV6);
|
||||
|
||||
await hostClient.offerLease(idx,
|
||||
leaseAmount ? leaseAmount : acc.leaseAmount,
|
||||
appenv.TOS_HASH);
|
||||
appenv.TOS_HASH,
|
||||
lastAssignedIPV6);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastAssignedIPV6) {
|
||||
db.open();
|
||||
(await db.updateValue(utilTable, { value: lastAssignedIPV6 }, { name: appenv.LAST_ASSIGNED_IPV6_ADDRESS }).finally(() => { db.close() }));
|
||||
}
|
||||
|
||||
await deinitClients();
|
||||
}
|
||||
|
||||
@@ -601,7 +634,7 @@ class Setup {
|
||||
// Burn the URITokens and recreate the offer.
|
||||
await hostClient.expireLease(containerName, lease.tenant_xrp_address).catch(console.error);
|
||||
|
||||
await hostClient.offerLease(uriInfo.leaseIndex, acc.leaseAmount, appenv.TOS_HASH).catch(console.error);
|
||||
await hostClient.offerLease(uriInfo.leaseIndex, acc.leaseAmount, appenv.TOS_HASH, uriInfo?.outboundIP?.address).catch(console.error);
|
||||
|
||||
// Refund EVRs to the tenant.
|
||||
const currentTime = evernode.UtilHelpers.getCurrentUnixTime();
|
||||
|
||||
74
mb-xrpl/lib/util-helper.js
Normal file
74
mb-xrpl/lib/util-helper.js
Normal file
@@ -0,0 +1,74 @@
|
||||
const ip6addr = require('ip6addr');
|
||||
|
||||
class UtilHelper {
|
||||
|
||||
static generateIPV6Addresses(subnetStr, addressCount) {
|
||||
|
||||
// Incrementally assign IPv6 addresses
|
||||
const generatedIPs = [];
|
||||
|
||||
for (let i = 0; generatedIPs.length < addressCount; i++) {
|
||||
const generatedIP = this.generateValidIPV6Address(subnetStr, (i > 0) ? generatedIPs[i - 1] : null);
|
||||
if (generatedIP) {
|
||||
generatedIPs.push(generatedIP);
|
||||
}
|
||||
}
|
||||
|
||||
return generatedIPs;
|
||||
}
|
||||
|
||||
static generateValidIPV6Address(subnetStr, offsetIP = null, isBelowOffset = false) {
|
||||
// Define your IPv6 subnet
|
||||
const subnet = ip6addr.createCIDR(subnetStr);
|
||||
|
||||
if (offsetIP && !subnet.contains(offsetIP))
|
||||
throw "Invalid offset IP Address."
|
||||
|
||||
if (offsetIP) {
|
||||
const newAddressBuf = Buffer.from(offsetIP.split(':').map(v => {
|
||||
const bytes = [];
|
||||
for (let i = 0; i < v.length; i += 2) {
|
||||
bytes.push(parseInt(v.substr(i, 2), 16));
|
||||
}
|
||||
return bytes;
|
||||
}).flat());
|
||||
|
||||
let j = newAddressBuf.length - 1;
|
||||
while (j >= 0) {
|
||||
if (isBelowOffset) {
|
||||
if (newAddressBuf[j] - 1 < 0) {
|
||||
newAddressBuf[j] = parseInt("0xFF", 16);
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
newAddressBuf[j]--;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (newAddressBuf[j] + 1 > parseInt("0xFF", 16)) {
|
||||
newAddressBuf[j] = 0;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
newAddressBuf[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ipString = newAddressBuf.toString('hex').toUpperCase().replace(/(.{4})(?!$)/g, "$1:");
|
||||
if (subnet.contains(ipString)) {
|
||||
return ipString;
|
||||
}
|
||||
} else
|
||||
return subnet.first().toBuffer().toString('hex').toUpperCase().replace(/(.{4})(?!$)/g, "$1:");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
UtilHelper
|
||||
}
|
||||
1725
mb-xrpl/package-lock.json
generated
1725
mb-xrpl/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
"build": "npm run lint && ncc build app.js --minify -o dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"evernode-js-client": "0.6.18",
|
||||
"evernode-js-client": "0.6.19",
|
||||
"sqlite3": "5.0.2",
|
||||
"ip6addr": "0.2.5"
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace cli
|
||||
constexpr const int BUFFER_SIZE = 4096; // Max read buffer size.
|
||||
constexpr const char *MSG_LIST = "{\"type\": \"list\"}";
|
||||
constexpr const char *MSG_BASIC = "{\"type\":\"%s\",\"container_name\":\"%s\"}";
|
||||
constexpr const char *MSG_CREATE = "{\"type\":\"create\",\"container_name\":\"%s\",\"owner_pubkey\":\"%s\",\"contract_id\":\"%s\",\"image\":\"%s\",\"config\":{}}";
|
||||
constexpr const char *MSG_CREATE = "{\"type\":\"create\",\"container_name\":\"%s\",\"owner_pubkey\":\"%s\",\"contract_id\":\"%s\",\"image\":\"%s\",\"outbound_ipv6\":\"%s\",\"outbound_net_interface\":\"%s\",\"config\":{}}";
|
||||
|
||||
constexpr const char *DOCKER_ATTACH = "DOCKER_HOST=unix:///run/user/$(id -u %s)/docker.sock %s/dockerbin/docker attach --detach-keys=\"ctrl-c\" %s";
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace cli
|
||||
}
|
||||
|
||||
// Read the length of the message to a buffer
|
||||
uint8_t length_buffer[8];
|
||||
uint8_t length_buffer[8];
|
||||
int res = read(ctx.socket_fd, length_buffer, 8);
|
||||
if (res == -1)
|
||||
{
|
||||
@@ -171,7 +171,7 @@ namespace cli
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint32_t message_length = uint32_from_bytes(length_buffer);
|
||||
const uint32_t message_length = uint32_from_bytes(length_buffer);
|
||||
|
||||
// Resize the message buffer to fit to the message length
|
||||
message.resize(message_length);
|
||||
@@ -214,11 +214,11 @@ namespace cli
|
||||
return ret;
|
||||
}
|
||||
|
||||
int create(std::string_view container_name, std::string_view owner, std::string_view contract_id, std::string_view image)
|
||||
int create(std::string_view container_name, std::string_view owner, std::string_view contract_id, std::string_view image, std::string_view outbound_ipv6, std::string_view outbound_net_interface)
|
||||
{
|
||||
std::string msg, output;
|
||||
msg.resize(95 + container_name.size() + owner.size() + contract_id.size() + image.size());
|
||||
sprintf(msg.data(), MSG_CREATE, container_name.data(), owner.data(), contract_id.data(), image.data());
|
||||
msg.resize(142 + container_name.size() + owner.size() + contract_id.size() + image.size() + outbound_ipv6.size() + outbound_net_interface.size());
|
||||
sprintf(msg.data(), MSG_CREATE, container_name.data(), owner.data(), contract_id.data(), image.data(), outbound_ipv6.data(), outbound_net_interface.data());
|
||||
|
||||
const int ret = get_json_output(msg, output);
|
||||
if (ret == 0)
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace cli
|
||||
|
||||
int execute_basic(std::string_view type, std::string_view container_name);
|
||||
|
||||
int create(std::string_view container_name, std::string_view owner, std::string_view contract_id, std::string_view image);
|
||||
int create(std::string_view container_name, std::string_view owner, std::string_view contract_id, std::string_view image, std::string_view outbound_ipv6, std::string_view outbound_net_interface);
|
||||
|
||||
int list();
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace cli
|
||||
const std::string value_to_string(const jsoncons::json &val);
|
||||
|
||||
void deinit();
|
||||
|
||||
|
||||
uint32_t uint32_from_bytes(const uint8_t *data);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,10 +90,12 @@ int parse_cmd(int argc, char **argv)
|
||||
std::string json_message;
|
||||
json->add_option("-m,--message", json_message, "JSON message");
|
||||
|
||||
std::string owner, contract_id, image;
|
||||
std::string owner, contract_id, image, outbound_ipv6, outbound_net_interface;
|
||||
create->add_option("-o,--owner", owner, "Hex (ed-prefixed) public key of the instance owner");
|
||||
create->add_option("-c,--contract-id", contract_id, "Contract Id (GUID) of the instance");
|
||||
create->add_option("-i,--image", image, "Container image to use");
|
||||
create->add_option("-a,--outbound-ipv6", outbound_ipv6, "Outbound IPV6 Address");
|
||||
create->add_option("-f,--outbound-net-interface", outbound_net_interface, "Outbound IPV6 Network Interface (Façade)");
|
||||
|
||||
std::string container_name;
|
||||
create->add_option("-n,--name", container_name, "Instance name");
|
||||
@@ -134,8 +136,7 @@ int parse_cmd(int argc, char **argv)
|
||||
return execute_cli([]()
|
||||
{
|
||||
std::cout << cli::ctx.socket_path << std::endl;
|
||||
return 0;
|
||||
});
|
||||
return 0; });
|
||||
}
|
||||
else if (list->parsed())
|
||||
{
|
||||
@@ -146,8 +147,7 @@ int parse_cmd(int argc, char **argv)
|
||||
std::cerr << "Failed to list instances." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
return 0; });
|
||||
}
|
||||
else if (json->parsed() && !json_message.empty())
|
||||
{
|
||||
@@ -158,13 +158,12 @@ int parse_cmd(int argc, char **argv)
|
||||
return -1;
|
||||
|
||||
std::cout << output << std::endl;
|
||||
return 0;
|
||||
});
|
||||
return 0; });
|
||||
}
|
||||
else if (create->parsed() && !container_name.empty() && !owner.empty() && !contract_id.empty() && !image.empty())
|
||||
{
|
||||
return execute_cli([&]()
|
||||
{ return cli::create(container_name, owner, contract_id, image); });
|
||||
{ return cli::create(container_name, owner, contract_id, image, outbound_ipv6, outbound_net_interface); });
|
||||
}
|
||||
else if (start->parsed() && !container_name.empty())
|
||||
{
|
||||
|
||||
@@ -211,7 +211,7 @@ namespace comm
|
||||
|
||||
hp::instance_info info;
|
||||
std::string error_msg;
|
||||
if (hp::create_new_instance(error_msg, info, msg.container_name, msg.pubkey, msg.contract_id, msg.image) == -1)
|
||||
if (hp::create_new_instance(error_msg, info, msg.container_name, msg.pubkey, msg.contract_id, msg.image, msg.outbound_ipv6, msg.outbound_net_interface) == -1)
|
||||
__HANDLE_RESPONSE(msg::MSGTYPE_CREATE_ERROR, error_msg, -1);
|
||||
|
||||
if (hp::initiate_instance(error_msg, info.container_name, init_msg) == -1)
|
||||
@@ -283,7 +283,7 @@ namespace comm
|
||||
}
|
||||
else
|
||||
__HANDLE_RESPONSE("error", TYPE_ERROR, -1);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -302,7 +302,8 @@ namespace comm
|
||||
uint32_to_bytes(length_buffer, message.length());
|
||||
|
||||
int res = write(ctx.data_socket, length_buffer, 8);
|
||||
if (res == -1) {
|
||||
if (res == -1)
|
||||
{
|
||||
disconnect();
|
||||
return -1;
|
||||
}
|
||||
@@ -310,16 +311,15 @@ namespace comm
|
||||
res = write(ctx.data_socket, message.data(), message.length());
|
||||
// Close connection after sending the response to the client.
|
||||
disconnect();
|
||||
|
||||
return res == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
return res == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given uint32_t number to bytes in big endian format.
|
||||
* @param dest Byte array pointer.
|
||||
* @param x Number to be converted.
|
||||
*/
|
||||
*/
|
||||
void uint32_to_bytes(uint8_t *dest, const uint32_t x)
|
||||
{
|
||||
dest[0] = (uint8_t)((x >> 24) & 0xff);
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace hp
|
||||
* @param image Docker image name to use (image prefix name must exists).
|
||||
* @return 0 on success and -1 on error.
|
||||
*/
|
||||
int create_new_instance(std::string &error_msg, instance_info &info, std::string_view container_name, std::string_view owner_pubkey, const std::string &contract_id, const std::string &image)
|
||||
int create_new_instance(std::string &error_msg, instance_info &info, std::string_view container_name, std::string_view owner_pubkey, const std::string &contract_id, const std::string &image, std::string_view outbound_ipv6, std::string_view outbound_net_interface)
|
||||
{
|
||||
// Creating an instance with same name is not allowed.
|
||||
hp::instance_info existing_instance;
|
||||
@@ -186,8 +186,8 @@ namespace hp
|
||||
int user_id;
|
||||
std::string username;
|
||||
if (install_user(
|
||||
user_id, username, instance_resources.cpu_us, instance_resources.mem_kbytes, instance_resources.swap_kbytes,
|
||||
instance_resources.storage_kbytes, container_name, instance_ports, image_name, "-", "-") == -1)
|
||||
user_id, username, instance_resources.cpu_us, instance_resources.mem_kbytes, instance_resources.swap_kbytes,
|
||||
instance_resources.storage_kbytes, container_name, instance_ports, image_name, outbound_ipv6, outbound_net_interface) == -1)
|
||||
{
|
||||
error_msg = USER_INSTALL_ERROR;
|
||||
return -1;
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace hp
|
||||
|
||||
void deinit();
|
||||
|
||||
int create_new_instance(std::string &error_msg, instance_info &info, std::string_view container_name, std::string_view owner_pubkey, const std::string &contract_id, const std::string &image_key);
|
||||
int create_new_instance(std::string &error_msg, instance_info &info, std::string_view container_name, std::string_view owner_pubkey, const std::string &contract_id, const std::string &image_key, std::string_view outbound_ipv6, std::string_view outbound_net_interface);
|
||||
|
||||
int initiate_instance(std::string &error_msg, std::string_view container_name, const msg::initiate_msg &config_msg);
|
||||
|
||||
|
||||
@@ -135,6 +135,8 @@ namespace msg::json
|
||||
msg.pubkey = d[msg::FLD_PUBKEY].as<std::string>();
|
||||
msg.contract_id = d[msg::FLD_CONTRACT_ID].as<std::string>();
|
||||
msg.image = d[msg::FLD_IMAGE].as<std::string>();
|
||||
msg.outbound_ipv6 = d[msg::FLD_OUTBOUND_IPV6].is<std::string>() ? d[msg::FLD_OUTBOUND_IPV6].as<std::string>() : "-";
|
||||
msg.outbound_net_interface = d[msg::FLD_OUTBOUND_NET_INTERFACE].is<std::string>() ? d[msg::FLD_OUTBOUND_NET_INTERFACE].as<std::string>() : "-";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace msg
|
||||
std::string pubkey;
|
||||
std::string contract_id;
|
||||
std::string image;
|
||||
std::string outbound_ipv6;
|
||||
std::string outbound_net_interface;
|
||||
};
|
||||
|
||||
struct history_configuration
|
||||
@@ -172,6 +174,8 @@ namespace msg
|
||||
constexpr const char *FLD_CONTAINER_NAME = "container_name";
|
||||
constexpr const char *FLD_CONTRACT_ID = "contract_id";
|
||||
constexpr const char *FLD_IMAGE = "image";
|
||||
constexpr const char *FLD_OUTBOUND_IPV6 = "outbound_ipv6";
|
||||
constexpr const char *FLD_OUTBOUND_NET_INTERFACE = "outbound_net_interface";
|
||||
constexpr const char *FLD_KNOWN_PEERS = "known_peers";
|
||||
constexpr const char *FLD_MESH = "mesh";
|
||||
constexpr const char *FLD_USER = "user";
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace version
|
||||
{
|
||||
// Sashimono agent version. Written to new configs.
|
||||
constexpr const char *AGENT_VERSION = "0.6.7";
|
||||
constexpr const char *AGENT_VERSION = "0.6.8";
|
||||
|
||||
// Minimum compatible config version (this will be used to validate configs).
|
||||
constexpr const char *MIN_CONFIG_VERSION = "0.5.0";
|
||||
|
||||
Reference in New Issue
Block a user