mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-09-30 20:46:32 +00:00
refactor: remove legacy bootnode code in favor of modern platform
Removed legacy components: - app.py - Old Quart/Flask application - main.py, manage.py - Legacy entry points - requirements.txt, Makefile - Old build config - bootnode/ - Legacy K8s/GCP orchestration - util/ - Old utility modules - casper/, casper-env/, casper-envoy/ - Obsolete Casper configs - geth/ - Legacy Ethereum node configs - config/ - Old K8s configs - *.log, *.json - Build artifacts The modern FastAPI platform in /api/ provides: - Multi-chain RPC proxy with 100+ chains - Token, NFT, and Transfer APIs - ERC-4337 Smart Wallets and Bundler - Webhooks with retry logic - Hanzo IAM integration - ClickHouse analytics
This commit is contained in:
@@ -1,119 +0,0 @@
|
||||
sha1 := $(shell git rev-parse --short=8 HEAD)
|
||||
geth := /bin/geth --datadir=/data
|
||||
net ?= testnet
|
||||
cfg := config/$(net)
|
||||
region := us-central1
|
||||
zone ?= us-central1-a
|
||||
number ?= 657758440341
|
||||
node ?= geth
|
||||
name ?= node
|
||||
project_id ?= hanzo-ai
|
||||
pod ?= $(node)-$(net)-$(number)
|
||||
|
||||
export KUBECONFIG=config/$(node)-$(net)-$(zone)/cluster.yaml
|
||||
|
||||
all: deploy
|
||||
|
||||
### GCLOUD SPECIFIC COMMANDS ###
|
||||
|
||||
# authenticate gcloud
|
||||
gcloud-auth:
|
||||
gcloud auth application-default login
|
||||
gcloud config set project $(project_id)
|
||||
|
||||
# Add secret for hanzo-ai gcr.io. This enables our cluster to pull images from
|
||||
# our shared image repo. This should only be run once after cluster creation.
|
||||
gcloud-add-gcr-key:
|
||||
kubectl create -f config/secret.yaml
|
||||
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "gcr-secret"}]}'
|
||||
|
||||
# Default to whatever zone you launched your cluster in to reduce key strokes
|
||||
gcloud-region-zone-defaults:
|
||||
gcloud compute project-info add-metadata --metadata=google-compute-default-region=$(region)
|
||||
gcloud compute project-info add-metadata --metadata=google-compute-default-zone=$(zone)
|
||||
|
||||
# Get credentials for kubectl for current cluster
|
||||
gcloud-get-credentials:
|
||||
gcloud container clusters get-credentials $(node)-$(net) --zone $(zone) --project $(project_id)
|
||||
# rm -rf config/$(node)-$(net)-$(zone)
|
||||
# mv -f config/$(node)-$(net) config/$(node)-$(net)-$(zone)
|
||||
@echo "KUBECONFIG=$(KUBECONFIG)" > kubeconfig
|
||||
echo "`source kubeconfig` to update KUBECONFIG environemental variable"
|
||||
|
||||
#build image
|
||||
build:
|
||||
gcloud builds submit \
|
||||
--machine-type n1-highcpu-8 \
|
||||
--timeout 30m \
|
||||
-t gcr.io/$(project_id)/$(name):$(sha1) \
|
||||
-t gcr.io/$(project_id)/$(name):latest \
|
||||
$(name)
|
||||
|
||||
# deploy: build
|
||||
# kubectl set image deployment/$(node)-$(net) $(node)-$(net)=gcr.io/$(project_id)/$(node):$(sha1)
|
||||
|
||||
### KUBERNETES SPECIFIC COMMANDS ###
|
||||
|
||||
create: build create-volume create-pod
|
||||
|
||||
# Setup a high-performance persistent disk. Use SSDs, and at least 500 GB of storage for adequate IO performance
|
||||
# Ensure proper flags for ext4:
|
||||
# mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb
|
||||
# create-disk:
|
||||
# gcloud compute disks create --size=500GB --type=pd-ssd --zone=us-central1-a geth-$(net)-data
|
||||
|
||||
create-volume:
|
||||
kubectl apply -f config/sc.yaml
|
||||
kubectl apply -f $(cfg)/pvc.yaml
|
||||
|
||||
create-snapshot:
|
||||
gcloud compute disks snapshot $(disk) --snapshot-names=$(snapshot) --zone=$(zone)
|
||||
|
||||
create-disk-from-snapshot:
|
||||
gcloud compute disks create $(disk) --source-snapshot=$(snapshot) --type=pd-ssd --zone=$(zone)
|
||||
|
||||
create-pod:
|
||||
kubectl apply -f $(cfg)/pod.yaml
|
||||
|
||||
delete-pod:
|
||||
kubectl delete -f $(cfg)/pod.yaml
|
||||
|
||||
delete:
|
||||
kubectl delete -f $(cfg)/pod.yaml || echo not running
|
||||
kubectl delete -f $(cfg)/pvc.yaml || echo not running
|
||||
kubectl delete -f $(cfg)/sc.yaml || echo not running
|
||||
gcloud compute disks delete --zone=$(zone) $(node)-$(net)-disk
|
||||
|
||||
status:
|
||||
kubectl get pods -o yaml
|
||||
|
||||
logs:
|
||||
kubectl logs $(pod) -f
|
||||
|
||||
ssh:
|
||||
kubectl exec -it $(pod) -- /bin/bash
|
||||
|
||||
attach:
|
||||
kubectl exec -it $(pod) -- $(geth) attach
|
||||
|
||||
nodeinfo:
|
||||
kubectl exec -it $(pod) -- $(geth) attach --exec 'admin.nodeInfo'
|
||||
|
||||
syncstatus:
|
||||
kubectl exec -it $(pod) -- $(geth) attach --exec 'eth.syncing'
|
||||
|
||||
blocknumber:
|
||||
kubectl exec -it $(pod) -- $(geth) attach --exec 'eth.blockNumber'
|
||||
|
||||
kubeconfig:
|
||||
source kubeconfig
|
||||
|
||||
deps:
|
||||
pip install - ./requirements.txt
|
||||
|
||||
# Run Server
|
||||
serve: kubeconfig
|
||||
python app.py
|
||||
|
||||
serve-prod: kubeconfig
|
||||
hypercorn app:app -b 0.0.0.0:80
|
||||
@@ -1,368 +0,0 @@
|
||||
"""
|
||||
LEGACY BOOTNODE APPLICATION
|
||||
===========================
|
||||
|
||||
⚠️ SECURITY NOTICE: This is the legacy Bootnode application.
|
||||
|
||||
✅ FIXED: Hardcoded credentials have been removed and replaced with environment variables.
|
||||
|
||||
🔄 MIGRATION RECOMMENDED: Consider migrating to the modern FastAPI version in /api/bootnode/
|
||||
- Better security with JWT authentication
|
||||
- Modern async/await patterns
|
||||
- Comprehensive API documentation
|
||||
- Support for 11+ blockchains
|
||||
- Rate limiting and monitoring
|
||||
|
||||
To run this legacy app safely:
|
||||
1. Copy .env.example to .env
|
||||
2. Set secure values for all environment variables
|
||||
3. Use strong passwords and random tokens
|
||||
|
||||
For new development, use the modern API in /api/ instead.
|
||||
"""
|
||||
|
||||
from threading import Thread
|
||||
from functools import wraps
|
||||
from quart import Quart, request
|
||||
from quart_cors import cors
|
||||
from bootnode import Bootnode
|
||||
from util import to_nodes, jsonify
|
||||
from pymongo import MongoClient
|
||||
import datetime
|
||||
import asyncio
|
||||
import httpx
|
||||
import datetime
|
||||
import os
|
||||
|
||||
# Load environment variables
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.get_child_watcher().attach_loop(loop)
|
||||
|
||||
app = Quart(__name__)
|
||||
cors(app)
|
||||
|
||||
SUPPORTED_PROVIDERS = ['private-cloud', 'google']
|
||||
SUPPORTED_ZONES = {
|
||||
'google': ['us-central1-a', 'europe-west6-a', 'asia-east2-a'],
|
||||
'private-cloud': ['london1', 'munich1', 'oslo1', 'tokyo1'],
|
||||
}
|
||||
|
||||
# connect to mongo and set up database vars
|
||||
mongo_client = MongoClient()
|
||||
bootnode_db = mongo_client.bootnode
|
||||
nodes_collection = bootnode_db.nodes
|
||||
updates_collection = bootnode_db.updates
|
||||
node_statuses = bootnode_db.node_statuses
|
||||
|
||||
# set up system update loop
|
||||
async def update_nodes_lambda(date, zone, provider):
|
||||
print('updating', date, zone, provider)
|
||||
print('-------- Getting ' + provider + ' nodes in zone: ' + zone + ' --------')
|
||||
bootnode = Bootnode('casper', 'testnet', provider, zone)
|
||||
|
||||
deployments = [d.to_dict() for d in await bootnode.list_deployments()]
|
||||
services = [s.to_dict() for s in await bootnode.list_services()]
|
||||
pods = [p.to_dict() for p in await bootnode.list_pods()]
|
||||
|
||||
nodes = to_nodes(deployments, services, pods, zone)
|
||||
|
||||
for node in nodes:
|
||||
node['lastUpdated'] = date
|
||||
|
||||
if node.get('blockchain', None) == 'casper' and node.get('ip', None) is not None:
|
||||
try:
|
||||
ip = node['ip']
|
||||
port = 9001
|
||||
if provider == 'private-cloud':
|
||||
for p in node['ports']:
|
||||
if p['port'] == 9001:
|
||||
port = p['nodePort']
|
||||
|
||||
node['provider'] = provider
|
||||
|
||||
print('Pod', zone + ' ' + node['id'] + ' ' + node['ip'])
|
||||
|
||||
start = datetime.datetime.now()
|
||||
|
||||
async with httpx.AsyncClient(verify=False) as client:
|
||||
reqs = [
|
||||
client.put(f'https://{ip}:{port}/show/blocks',
|
||||
json={'depth': 1}),
|
||||
client.put(f'https://{ip}:{port}/show/dag',
|
||||
json={'depth': 10,
|
||||
'showJustifications': True})
|
||||
]
|
||||
|
||||
ress = await asyncio.gather(*reqs)
|
||||
|
||||
blockdata = ress[0]
|
||||
dag = ress[1]
|
||||
|
||||
end = datetime.datetime.now()
|
||||
|
||||
node['metadata'] = {
|
||||
'block': blockdata.json()[0],
|
||||
'dag': dag.json(),
|
||||
}
|
||||
node['latencyMillis'] = (end - start).microseconds / 1000
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print('cannot get metadata for ' + node['id'] + ': ' +
|
||||
str(e))
|
||||
|
||||
nodes_collection.insert_one(node)
|
||||
# except Exception as e:
|
||||
# print('update nodes loop error: ' + str(e))
|
||||
# finally:
|
||||
|
||||
# function to spin off thread
|
||||
async def update_nodes_loop():
|
||||
while True:
|
||||
try:
|
||||
date = datetime.datetime.utcnow()
|
||||
|
||||
updates = []
|
||||
for provider in SUPPORTED_PROVIDERS:
|
||||
zones = SUPPORTED_ZONES[provider]
|
||||
|
||||
for zone in zones:
|
||||
updates.append(update_nodes_lambda(date, zone, provider))
|
||||
|
||||
await asyncio.gather(*updates)
|
||||
|
||||
updates_collection.update_one(
|
||||
{
|
||||
'name': 'nodes',
|
||||
},
|
||||
{
|
||||
'$set': {
|
||||
'date': date
|
||||
},
|
||||
},
|
||||
True
|
||||
)
|
||||
|
||||
await asyncio.sleep(1)
|
||||
except Exception as e:
|
||||
print('update_nodes_loop error' + str(e))
|
||||
|
||||
def update_nodes_thread():
|
||||
print('starting update thread')
|
||||
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(update_nodes_loop())
|
||||
|
||||
Thread(target=update_nodes_thread).start()
|
||||
|
||||
def auth_required(fn):
|
||||
@wraps(fn)
|
||||
async def wrapped_fn(*args, **kwargs):
|
||||
# SECURITY: Check for environment variable instead of hardcoded token
|
||||
import os
|
||||
expected_token = os.environ.get('LEGACY_API_TOKEN')
|
||||
if not expected_token:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'API token not configured',
|
||||
})
|
||||
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if not auth_header or auth_header != f'Bearer {expected_token}':
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'authorization required',
|
||||
})
|
||||
return await fn(*args, **kwargs)
|
||||
return wrapped_fn
|
||||
|
||||
@app.route('/login', methods=['POST'])
|
||||
async def login():
|
||||
try:
|
||||
json = await request.get_json()
|
||||
|
||||
# SECURITY: Use environment variables for credentials
|
||||
import os
|
||||
admin_email = os.environ.get('LEGACY_ADMIN_EMAIL')
|
||||
admin_password = os.environ.get('LEGACY_ADMIN_PASSWORD')
|
||||
api_token = os.environ.get('LEGACY_API_TOKEN')
|
||||
|
||||
if not all([admin_email, admin_password, api_token]):
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'Authentication not properly configured'
|
||||
})
|
||||
|
||||
print('login attempt for:', json.get('email', 'unknown'))
|
||||
|
||||
if json.get('email') == admin_email and json.get('password') == admin_password:
|
||||
return jsonify({'token': api_token})
|
||||
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'incorrect username or password'
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'could not get login: ' + str(e),
|
||||
})
|
||||
|
||||
@app.route('/nodes', methods=['GET'])
|
||||
@auth_required
|
||||
async def get_nodes():
|
||||
try:
|
||||
update = updates_collection.find_one({ 'name': 'nodes' })
|
||||
# print(update)
|
||||
# print('getting node data as of ' + str(update['date']))
|
||||
nodes = nodes_collection.find({'lastUpdated': update['date']})
|
||||
|
||||
ns = []
|
||||
for node in nodes:
|
||||
node.pop('_id')
|
||||
ns.append(node)
|
||||
|
||||
return jsonify(ns)
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'could not get nodes: ' + str(e),
|
||||
})
|
||||
|
||||
@app.route('/nodes', methods=['DELETE'])
|
||||
@auth_required
|
||||
async def delete_nodes():
|
||||
try:
|
||||
print('deleting everything!')
|
||||
|
||||
update = updates_collection.find_one({ 'name': 'nodes' })
|
||||
nodes = nodes_collection.find({'lastUpdated': update['date']})
|
||||
|
||||
dns = []
|
||||
for node in nodes:
|
||||
dns.append(delete_node(node['id'], node['provider'], node['zone']))
|
||||
|
||||
await asyncio.gather(*dns)
|
||||
|
||||
print('deleted ' + str(len(dns)) + ' nodes')
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'could not delete a nodes: ' + str(e)
|
||||
})
|
||||
|
||||
@app.route('/nodes', methods=['PUT'])
|
||||
@auth_required
|
||||
async def put_node():
|
||||
try:
|
||||
json = await request.get_json()
|
||||
|
||||
print('launching ' + str(json['number']) + ' nodes in ' + str(json['zone']))
|
||||
|
||||
provider = json['provider']
|
||||
if provider not in SUPPORTED_PROVIDERS:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': provider + ' is not a valid provider',
|
||||
})
|
||||
|
||||
zone = json['zone']
|
||||
if zone not in SUPPORTED_ZONES[provider]:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': zone + ' is not a valid zone',
|
||||
})
|
||||
|
||||
bootnode = Bootnode('casper', 'testnet', provider, zone)
|
||||
|
||||
number = 1
|
||||
if json['number'] is not None:
|
||||
number = int(json['number'])
|
||||
|
||||
nodes = []
|
||||
|
||||
ds = []
|
||||
for i in range(number):
|
||||
|
||||
async def create_deployment():
|
||||
data = await bootnode.create_deployment()
|
||||
# print('deployment created', data.deployment)
|
||||
|
||||
ds.append(create_deployment())
|
||||
|
||||
await asyncio.gather(*ds)
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'nodes-starting': number,
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'could not create a node: ' + str(e)
|
||||
})
|
||||
|
||||
@app.route('/nodes/<node_id>', methods=['GET'])
|
||||
@auth_required
|
||||
async def get_node(node_id, provider=None, zone=None):
|
||||
try:
|
||||
json = await request.get_json()
|
||||
|
||||
if provider is None:
|
||||
provider = json['provider']
|
||||
if zone is None:
|
||||
zone = json['zone']
|
||||
|
||||
bootnode = Bootnode('casper', 'testnet', provider, zone)
|
||||
|
||||
deployment = await bootnode.get_deployment(node_id)
|
||||
service = await bootnode.get_service(node_id)
|
||||
pods = [p.to_dict() for p in await bootnode.list_pods(label_selector='app=' + node_id)]
|
||||
|
||||
return jsonify(to_nodes([deployment.to_dict()],
|
||||
[service.to_dict()], pods, zone))
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'node not found: ' + str(e)
|
||||
})
|
||||
|
||||
@app.route('/nodes/<node_id>', methods=['DELETE'])
|
||||
@auth_required
|
||||
async def delete_node(node_id, provider=None, zone=None):
|
||||
is_called = provider is not None
|
||||
|
||||
try:
|
||||
print('deleting ' + str(node_id) + ' from provider ' + str(provider) + ' and zone ' + str(zone))
|
||||
|
||||
if provider is None:
|
||||
json = await request.get_json()
|
||||
|
||||
provider = json['provider']
|
||||
zone = json['zone']
|
||||
|
||||
bootnode = Bootnode('casper', 'testnet', provider, zone)
|
||||
await bootnode.delete_deployment(node_id)
|
||||
|
||||
return jsonify({
|
||||
'status': 'ok',
|
||||
})
|
||||
except Exception as e:
|
||||
print('delete_node error', e)
|
||||
|
||||
return jsonify({
|
||||
'status': 'failed',
|
||||
'error': 'could not delete: ' + str(e)
|
||||
})
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port='4000')
|
||||
@@ -1,6 +0,0 @@
|
||||
from . import gcloud
|
||||
from . import kubernetes
|
||||
from .kubernetes import Kubernetes
|
||||
from .gcloud import Gcloud
|
||||
from .bootnode import Bootnode
|
||||
from .complete import complete
|
||||
@@ -1,310 +0,0 @@
|
||||
from .gcloud import Gcloud
|
||||
from .kubernetes import Kubernetes
|
||||
from .template import Ethereum, Casper, Service, Ingress, Backend, ServicePort
|
||||
from .table import table
|
||||
import secrets
|
||||
import asyncio
|
||||
|
||||
blockchains = [Ethereum, Casper]
|
||||
gcloud = Gcloud()
|
||||
|
||||
class Bootnode(object):
|
||||
def __init__(self, chain, network, provider, zone):
|
||||
self.gcloud = gcloud
|
||||
|
||||
self.chain = self.find_blockchain(chain)
|
||||
self.network, id = self.chain.normalize_network(network)
|
||||
self.zone = zone
|
||||
self.provider = provider
|
||||
|
||||
if self.chain is None:
|
||||
raise Exception('Blockchain "" does not exist' % chain)
|
||||
|
||||
if provider == 'private-cloud':
|
||||
self.cluster = '{0}-{1}-encloudify-{2}'.format(self.chain.get_name(),
|
||||
network,
|
||||
zone)
|
||||
else:
|
||||
self.cluster = '{0}-{1}-{2}'.format(self.chain.get_name(),
|
||||
network,
|
||||
zone)
|
||||
|
||||
try:
|
||||
self.kube = Kubernetes('config/{0}/cluster.yaml'.format(self.cluster))
|
||||
except Exception as e:
|
||||
print('{0} is a new cluster: '.format(self.cluster) + str(e))
|
||||
|
||||
# Disks
|
||||
def list_disks(self, network=None):
|
||||
table(self.gcloud.list_disks(network=network), 'name', 'status', 'link')
|
||||
|
||||
def create_disk(self, snapshot, name):
|
||||
snap = self.gcloud.get_snapshot(snapshot)
|
||||
print(snap.create_disk(name))
|
||||
|
||||
def get_disk(self, name):
|
||||
table(self.gcloud.get_disk(name), ['name', 'status', 'link'])
|
||||
|
||||
def get_last_disk(self, network=None):
|
||||
table(self.gcloud.last_disk(network=network), 'name', 'status', 'link')
|
||||
|
||||
# Snapshots
|
||||
def list_snapshots(self, network=None):
|
||||
table(self.gcloud.list_snapshots(network=network), 'name', 'status', 'link')
|
||||
|
||||
def get_snapshot(self, name):
|
||||
table(self.gcloud.get_snapshot(name), 'name', 'status', 'link')
|
||||
|
||||
def get_last_snapshot(self, network=None):
|
||||
table(self.gcloud.get_last_snapshot(network=network), 'name', 'status', 'link')
|
||||
|
||||
async def snapshot_disk(self, name):
|
||||
disk = self.gcloud.get_disk(name)
|
||||
pod = await self.kube.get_pod(disk.pod)
|
||||
print(self.gcloud.snapshot_pod(pod))
|
||||
|
||||
async def snapshot_pod(self, name):
|
||||
pod = await self.kube.get_pod(name)
|
||||
print(self.gcloud.snapshot_pod(pod))
|
||||
|
||||
async def update_snapshot(self):
|
||||
if not network:
|
||||
raise Exception('Network must be specified')
|
||||
|
||||
# Re-use last snapshot so subsequent snapshots are just deltas,
|
||||
# otherwise find any sync'd pod and start there
|
||||
snap = self.gcloud.get_last_snapshot(network=self.network)
|
||||
if snap:
|
||||
pod = await self.kube.get_pod(snap.pod)
|
||||
else:
|
||||
pod = await self.kube.get_synced_pod(self.network)
|
||||
|
||||
if not pod or pod.syncing():
|
||||
raise Exception('Pod not synced: ""' % pod.name)
|
||||
|
||||
name = "{0}-{1}-{2}".format(pod.client, pod.network, pod.block_number())
|
||||
print(self.gcloud.snapshot_disk(pod.disk, name, pod_name=pod.name))
|
||||
|
||||
def find_blockchain(self, chain):
|
||||
"""
|
||||
Find constructor to use for given blockchain node, i.e. Ethereum()
|
||||
which generates a config for `geth`.
|
||||
"""
|
||||
for blockchain in blockchains:
|
||||
if blockchain.is_blockchain(chain):
|
||||
return blockchain
|
||||
|
||||
async def create_load_balancer(self, name=None):
|
||||
"""
|
||||
Create a new load balancer for a given set of pods.
|
||||
"""
|
||||
|
||||
service_name = self.cluster + '-svc'
|
||||
ingress_name = self.cluster + '-ing'
|
||||
|
||||
service = Service(
|
||||
metadata=Metadata(
|
||||
name=service_name,
|
||||
annotations={"cloud.google.com/neg": '{"ingress": true}'},
|
||||
),
|
||||
spec=Spec(
|
||||
selector={"run": self.cluster},
|
||||
ports=[ServicePort(port=80, protocol='TCP', targetServicePort=9376)]
|
||||
),
|
||||
)
|
||||
|
||||
ingress = Ingress(
|
||||
metadata=Metadata(
|
||||
name=ingress_name,
|
||||
),
|
||||
spec=Spec(
|
||||
backend=Backend(
|
||||
serviceName=service_name,
|
||||
serviceServicePort=80,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
creates = [
|
||||
self.kube.create_service(service),
|
||||
self.kube.create_ingress(ingress),
|
||||
]
|
||||
|
||||
await asyncio.gather(*creates)
|
||||
|
||||
|
||||
async def create_pod(self, name=None):
|
||||
"""
|
||||
Create a new pod for a specific chain on a specific network of that
|
||||
chain. Ex. geth-mainnet
|
||||
"""
|
||||
|
||||
if not name:
|
||||
name = '{0}-{1}-{2}'.format(self.chain.get_name(), self.network, secrets.randbelow(1000000000000))
|
||||
|
||||
print('Creating pod {0}'.format(name))
|
||||
config = self.chain(name, self.network, self.cluster).spec.template
|
||||
|
||||
disk_name = config.spec.volumes[0].gcePersistentDisk.pdName
|
||||
snap = self.gcloud.get_last_snapshot(self.network)
|
||||
if snap:
|
||||
snap.create_disk(disk_name)
|
||||
else:
|
||||
self.gcloud.create_disk(disk_name)
|
||||
|
||||
# pool = self.kube.get_pool(network)
|
||||
# if not pool:
|
||||
# self.kube.create_pool(network)
|
||||
print(await self.kube.create_pod(config))
|
||||
|
||||
async def delete_pod(self, name):
|
||||
await self.kube.delete_pod(name)
|
||||
|
||||
async def list_pods(self, label_selector=None, network=None):
|
||||
if network is None:
|
||||
network = self.network
|
||||
|
||||
pods = await self.kube.list_pods(label_selector=label_selector, network=self.network)
|
||||
#table(pods, 'name', 'status')
|
||||
|
||||
return pods
|
||||
|
||||
async def get_pod(self, name):
|
||||
table(await self.kube.get_pod(name), 'name', 'phase', 'ip')
|
||||
|
||||
async def get_last_pod(self):
|
||||
table(await self.kube.get_last_pod(network=self.network), 'name', 'phase', 'block_number', 'ip')
|
||||
|
||||
async def get_synced_pod(self):
|
||||
table(await self.kube.get_synced_pod(network=self.network), 'name', 'phase', 'block_number', 'ip')
|
||||
|
||||
async def create_deployment(self, name=None):
|
||||
"""
|
||||
Create a new deployment for a specific chain on a specific network of that
|
||||
chain. Ex. geth-mainnet
|
||||
"""
|
||||
|
||||
if not name:
|
||||
name = '{0}-{1}-{2}'.format(self.chain.get_name(), self.network, secrets.randbelow(1000000000000))
|
||||
|
||||
config = self.chain(name, self.network, self.cluster)
|
||||
|
||||
# disk_name = config.spec.template.spec.volumes[0].gcePersistentDisk.pdName
|
||||
# snap = self.gcloud.get_last_snapshot(self.network)
|
||||
# if snap:
|
||||
# snap.create_disk(disk_name)
|
||||
# else:
|
||||
# self.gcloud.create_disk(disk_name)
|
||||
|
||||
# pool = self.kube.get_pool(network)
|
||||
# if not pool:
|
||||
# self.kube.create_pool(network)
|
||||
print('Creating service for {0}'.format(name))
|
||||
|
||||
service = await self.kube.create_service(config.get_service())
|
||||
|
||||
if 'encloudify' not in self.cluster:
|
||||
service = await self.kube.get_service('service-'+name)
|
||||
while service.ip == '':
|
||||
print('NO IP!', service.ip)
|
||||
service = await self.kube.get_service('service-'+name)
|
||||
await asyncio.sleep(5)
|
||||
print('IP!', service.ip)
|
||||
|
||||
config.set_env('EXTERNAL_IP', service.ip)
|
||||
|
||||
volume = config.get_volume_claim()
|
||||
|
||||
if volume is not None:
|
||||
print('Creating volume for {0}'.format(name))
|
||||
pvc = await self.kube.create_volume(volume)
|
||||
|
||||
print('Creating deployment for {0}'.format(name))
|
||||
deployment = await self.kube.create_deployment(config)
|
||||
|
||||
return {
|
||||
'service': service,
|
||||
'volume': volume,
|
||||
'deployment': deployment,
|
||||
}
|
||||
|
||||
async def delete_deployment(self, name):
|
||||
try:
|
||||
await self.kube.delete_service('service-' + name)
|
||||
except Exception as e:
|
||||
print('warning: could not delete service ' + 'service-' + name + ': ' +
|
||||
str(e))
|
||||
try:
|
||||
await self.kube.delete_volume_claim(name+'-pd')
|
||||
except Exception as e:
|
||||
print('warning: could not delete volume claim ' + name + '-pd : ' +
|
||||
str(e))
|
||||
await self.kube.delete_deployment(name)
|
||||
|
||||
async def list_deployments(self, network=None):
|
||||
if network is None:
|
||||
network = self.network
|
||||
|
||||
deployments = await self.kube.list_deployments(network=network)
|
||||
#table(deployments, 'name')
|
||||
|
||||
return deployments
|
||||
|
||||
async def get_deployment(self, name):
|
||||
deployment = await self.kube.get_deployment(name)
|
||||
table([deployment], 'name')
|
||||
|
||||
return deployment
|
||||
|
||||
async def list_services(self, network=None):
|
||||
if network is None:
|
||||
network = self.network
|
||||
|
||||
services = await self.kube.list_services(network=network)
|
||||
#table(services, 'name', 'ip', 'ports')
|
||||
|
||||
return services
|
||||
|
||||
async def get_service(self, name):
|
||||
service = await self.kube.get_service('service-' + name)
|
||||
table([service], 'name', 'ip', 'ports')
|
||||
|
||||
return service
|
||||
|
||||
async def get_block_number(self, name):
|
||||
pod = await self.kube.get_pod(name)
|
||||
print(pod.block_number())
|
||||
|
||||
# Cluster
|
||||
def create_cluster(self):
|
||||
"""
|
||||
Create a new cluster for a specific chain on a specific network of that
|
||||
chain. Ex. geth-mainnet
|
||||
"""
|
||||
|
||||
print(self.gcloud.create_cluster(self.chain.get_name(), self.network,
|
||||
self.zone))
|
||||
|
||||
def delete_cluster(self):
|
||||
"""
|
||||
Delete a cluster for a specific chain on a specific network of that
|
||||
chain. Ex. geth-mainnet
|
||||
"""
|
||||
|
||||
chain_name = self.chain.get_name()
|
||||
|
||||
print(self.gcloud.delete_cluster(self.cluster))
|
||||
|
||||
def list_clusters(self):
|
||||
table(self.gcloud.list_clusters(), 'name', 'status', 'ip',
|
||||
'node_count', 'version')
|
||||
|
||||
def get_cluster(self):
|
||||
print(self.gcloud.get_cluster(self.cluster))
|
||||
|
||||
# Scaling
|
||||
def scale_up(args):
|
||||
pass
|
||||
|
||||
def scale_down(args):
|
||||
pass
|
||||
@@ -1,20 +0,0 @@
|
||||
import sys
|
||||
|
||||
|
||||
def complete(argv, parser):
|
||||
"""Return completions for commandline."""
|
||||
if not argv[1:]:
|
||||
return
|
||||
|
||||
if not argv[1] == 'complete':
|
||||
return
|
||||
|
||||
# Generate list of command:descriptions
|
||||
completions = []
|
||||
commands = parser.format_help().split('\n')[8:-5]
|
||||
for cmd in commands:
|
||||
k, v = cmd.strip().split(None, 1)
|
||||
completions.append("{0}:{1}".format(k, v))
|
||||
|
||||
print('\n'.join(completions))
|
||||
sys.exit(0)
|
||||
@@ -1,397 +0,0 @@
|
||||
from google.cloud import container_v1
|
||||
from oauth2client.client import GoogleCredentials
|
||||
from protobuf_to_dict import protobuf_to_dict as pbd
|
||||
from googleapiclient import discovery
|
||||
import re
|
||||
|
||||
PROJECT = 'hanzo-ai'
|
||||
REGION = 'us-central1'
|
||||
ZONE = 'us-central1-a'
|
||||
|
||||
def project_zone_from_disk(s):
|
||||
"""
|
||||
Helper to pull project id and zone off a disk URI.
|
||||
"""
|
||||
match = re.match(r'.*v1/projects/(.*)/zones/(.*)/disk', s)
|
||||
return match[1], match[2]
|
||||
|
||||
|
||||
def type_from_url(s):
|
||||
"""
|
||||
Get disk type from disk URI.
|
||||
"""
|
||||
match = re.match(r'.*diskTypes/(.*)', s)
|
||||
return match[1]
|
||||
|
||||
|
||||
def ssd_type(project, zone):
|
||||
"""
|
||||
Return URI for SSD Disk type formatted to match gcloud requirements.
|
||||
"""
|
||||
return "projects/{0}/zones/{1}/diskTypes/pd-ssd".format(project, zone)
|
||||
|
||||
|
||||
class NodePool(object):
|
||||
"""
|
||||
GKE NodePool, annotated with values we care about.
|
||||
"""
|
||||
|
||||
def __init__(self, obj, api=None):
|
||||
self.gke_api = api
|
||||
self.name = obj['name']
|
||||
self.id = obj['name'] # NodePools do not seem to have an ID
|
||||
self.link = obj['self_link']
|
||||
self.status = obj['status']
|
||||
self.config = obj['config']
|
||||
self.autoscaling = obj['autoscaling']
|
||||
self.initial_node_count = obj['initial_node_count']
|
||||
self.management = obj['management']
|
||||
self.version = obj['version']
|
||||
self.instance_group = obj['instance_group_urls']
|
||||
|
||||
|
||||
class Cluster(object):
|
||||
"""
|
||||
GKE Cluster, annotated with values we care about.
|
||||
"""
|
||||
|
||||
def __init__(self, obj, api=None):
|
||||
self.gke_api = api
|
||||
self.name = obj['name']
|
||||
self.id = obj['name'] # Clusters do not seem to have an ID
|
||||
self.created_at = obj['create_time']
|
||||
self.link = obj['self_link']
|
||||
self.status = obj['status']
|
||||
self.zone = obj['zone']
|
||||
self.endpoint = obj['endpoint']
|
||||
self.ip = obj['endpoint']
|
||||
self.version = obj['current_master_version']
|
||||
self.master_version = obj['current_master_version']
|
||||
self.node_version = obj['current_node_version']
|
||||
self.node_count = obj['current_node_count']
|
||||
self.node_config = obj['node_config']
|
||||
self.master_auth = obj['master_auth']
|
||||
|
||||
# Not in the dict
|
||||
# self.maintenance_policy = obj['maintenance_policy']
|
||||
self.locations = obj['locations']
|
||||
self.instance_groupl = obj['instance_group_urls']
|
||||
|
||||
self.node_pools = [NodePool(o, api) for o in obj['node_pools']]
|
||||
|
||||
|
||||
class Disk(object):
|
||||
"""
|
||||
GCE Disk, annotated with values we care about.
|
||||
"""
|
||||
|
||||
def __init__(self, obj, api=None):
|
||||
self.gce_api = api
|
||||
self.name = obj['name']
|
||||
self.id = obj['id']
|
||||
self.created_at = obj['creationTimestamp']
|
||||
self.link = obj['selfLink']
|
||||
self.status = obj['status']
|
||||
self.size = obj['sizeGb']
|
||||
self.type = type_from_url(obj['type'])
|
||||
|
||||
labels = obj.get('labels', None)
|
||||
if labels:
|
||||
self.pod = labels['pod-name']
|
||||
else:
|
||||
self.pod = None
|
||||
|
||||
self.project, self.zone = project_zone_from_disk(self.link)
|
||||
|
||||
self.source_image = None
|
||||
self.source_image_id = None
|
||||
|
||||
if 'sourceImage' in obj:
|
||||
self.source_image = obj['sourceImage']
|
||||
self.source_image_id = obj['sourceImageId']
|
||||
|
||||
|
||||
class Snapshot(object):
|
||||
"""
|
||||
GCE Snapshot, annotated with values we care about.
|
||||
"""
|
||||
|
||||
def __init__(self, obj, api=None):
|
||||
self.gce_api = api
|
||||
self.name = obj['name']
|
||||
|
||||
bits = self.name.split('-')
|
||||
self.client = bits[0]
|
||||
self.network = bits[1]
|
||||
self.block = int(bits[2])
|
||||
|
||||
labels = obj.get('labels', None)
|
||||
if labels:
|
||||
self.pod = labels['pod-name']
|
||||
else:
|
||||
self.pod = None
|
||||
|
||||
self.id = obj['id']
|
||||
self.created_at = obj['creationTimestamp']
|
||||
self.disk_size = obj['diskSizeGb'] + 'Gi'
|
||||
|
||||
self.link = obj['selfLink']
|
||||
self.source_disk = obj['sourceDisk']
|
||||
self.source_disk_id = obj['sourceDiskId']
|
||||
self.status = obj['status']
|
||||
self.storage_bytes = obj['storageBytes']
|
||||
self.storage_byts_status = obj['storageBytesStatus']
|
||||
|
||||
self.project, self.zone = project_zone_from_disk(self.source_disk)
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
def create_disk(self, name):
|
||||
return self.gce_api.create_disk(name, self, self.project, self.zone)
|
||||
|
||||
|
||||
class Gcloud(object):
|
||||
"""
|
||||
Client for both Google Compute Engine and Google Container Engine.
|
||||
"""
|
||||
|
||||
def __init__(self, project=PROJECT, region=REGION, zone=ZONE):
|
||||
self.project = project
|
||||
self.region = region
|
||||
self.zone = zone
|
||||
self.gce_api = discovery.build('compute', 'v1')
|
||||
self.gke_api = container_v1.ClusterManagerClient()
|
||||
|
||||
# Disks
|
||||
def create_disk(self, name, snapshot, project=None, zone=None):
|
||||
"""
|
||||
Create a new disk from a given snapshot.
|
||||
"""
|
||||
if not project:
|
||||
project = snapshot.project
|
||||
if not zone:
|
||||
zone = snapshot.zone
|
||||
|
||||
body = {
|
||||
'name': name,
|
||||
'description': 'from-pod: {0} from-snapshot: {1}'.format(snapshot.pod, snapshot.name),
|
||||
'labels': {
|
||||
'snapshot-name': snapshot.name,
|
||||
'pod-name': snapshot.pod,
|
||||
'project': project,
|
||||
'zone': zone,
|
||||
},
|
||||
'sourceSnapshot': snapshot.link,
|
||||
'zone': zone,
|
||||
'type': ssd_type(project, zone),
|
||||
}
|
||||
return self.gce_api.disks().insert(project=project, zone=zone,
|
||||
body=body).execute()
|
||||
|
||||
def get_disk(self, name):
|
||||
"""
|
||||
Get a specific disk by name.
|
||||
"""
|
||||
for disk in self.list_disks():
|
||||
if disk.name == name:
|
||||
return disk
|
||||
|
||||
def get_last_disk(self, network=None):
|
||||
"""
|
||||
Get last disk created.
|
||||
"""
|
||||
return max(self.list_disks(network), key=lambda x: x.created_at)
|
||||
|
||||
def list_disks(self, network=None):
|
||||
"""
|
||||
List disks for project / zone, optionally filter by network.
|
||||
"""
|
||||
disks = [Disk(s, self) for s in
|
||||
self.gce_api.disks().list(project=self.project, zone=self.zone).execute()['items']]
|
||||
|
||||
if not network:
|
||||
return disks
|
||||
|
||||
return [s for s in disks if s.network == network]
|
||||
|
||||
# Snapshots
|
||||
def get_snapshot(self, name):
|
||||
"""
|
||||
Get a snapshot by name.
|
||||
"""
|
||||
for snap in self.list_snapshots():
|
||||
if snap.name == name:
|
||||
return snap
|
||||
|
||||
def get_last_snapshot(self, network=None):
|
||||
"""
|
||||
Get snapshot with highest block number.
|
||||
"""
|
||||
return max(self.list_snapshots(network), key=lambda x: x.block)
|
||||
|
||||
def list_snapshots(self, network=None):
|
||||
"""
|
||||
List all snapshots for a given network.
|
||||
|
||||
:param network: The name of the network
|
||||
:return: Returns the list of snapshots, parsed into objects
|
||||
"""
|
||||
snaps = [Snapshot(s, self) for s in
|
||||
self.gce_api.snapshots().list(project=self.project).execute()['items']]
|
||||
|
||||
if not network:
|
||||
return snaps
|
||||
|
||||
return [s for s in snaps if s.network == network]
|
||||
|
||||
def snapshot_disk(self, disk, name, pod_name=None, project=None, zone=None):
|
||||
"""
|
||||
Create a snapshot of a given disk. Optionally label with Pod disk is
|
||||
associated.
|
||||
|
||||
:param network: The name of the network
|
||||
:return: Returns the list of snapshots, parsed into objects
|
||||
"""
|
||||
|
||||
if not project:
|
||||
project = self.project
|
||||
if not zone:
|
||||
zone = self.zone
|
||||
|
||||
body = {
|
||||
'name': name,
|
||||
'labels': {
|
||||
'pod-name': pod_name,
|
||||
'project': project,
|
||||
'zone': zone,
|
||||
},
|
||||
'description': 'from-pod: {0}'.format(pod_name)
|
||||
}
|
||||
|
||||
return self.gce_api.disks().createSnapshot(project=project, zone=zone,
|
||||
disk=disk,
|
||||
body=body).execute()
|
||||
|
||||
def snapshot_pod(self, pod, project=None, zone=None):
|
||||
"""
|
||||
Snapshot a running pod, as long as it is synced.
|
||||
"""
|
||||
if pod.syncing():
|
||||
raise Exception('Pod not synced: ""' % pod.name)
|
||||
|
||||
name = "{0}-{1}-{2}".format(pod.client, pod.network, pod.block_number())
|
||||
return self.snapshot_disk(pod.disk, name, pod_name=pod.name)
|
||||
|
||||
# Clusters
|
||||
def create_cluster(self, chain, network, zone=None, retry=None, timeout=None):
|
||||
"""
|
||||
Creates a new GKE cluster using NEG.
|
||||
"""
|
||||
# gcloud container clusters create neg-demo-cluster \
|
||||
# --enable-ip-alias \
|
||||
# --create-subnetwork="" \
|
||||
# --network=default \
|
||||
# --zone=us-central1-a
|
||||
if not zone:
|
||||
zone = self.zone
|
||||
|
||||
name = "{}-{}".format(chain, network)
|
||||
version = "1.12.6-gke.10"
|
||||
|
||||
body = {
|
||||
"cluster": {
|
||||
"name": name,
|
||||
"description": "Bootnode created and managed cluster for {} chain, {} network".format(chain, network),
|
||||
"nodePools": [{
|
||||
"name": "default-pool",
|
||||
"version": version,
|
||||
"initialNodeCount": 1,
|
||||
"autoscaling": {
|
||||
"enabled": True,
|
||||
"minNodeCount": 1,
|
||||
"maxNodeCount": 100,
|
||||
},
|
||||
"management": {
|
||||
"autoRepair": True,
|
||||
"autoUpgrade": True,
|
||||
},
|
||||
"config": {
|
||||
"machineType": "n1-standard-8",
|
||||
"diskSizeGb": 100,
|
||||
"diskType": "pd-ssd",
|
||||
"minCpuPlatform": "Intel Skylake",
|
||||
"oauthScopes": [
|
||||
"https://www.googleapis.com/auth/compute",
|
||||
"https://www.googleapis.com/auth/devstorage.read_only",
|
||||
],
|
||||
},
|
||||
}],
|
||||
"loggingService": "logging.googleapis.com",
|
||||
"monitoringService": "monitoring.googleapis.com",
|
||||
"ipAllocationPolicy": {
|
||||
"useIpAliases": True,
|
||||
"createSubnetwork": True,
|
||||
},
|
||||
"initialClusterVersion": version,
|
||||
# "addons_config": {
|
||||
# "horizontal_pod_autoscaling": {
|
||||
# "disabled": False,
|
||||
# },
|
||||
# "http_load_balancing": {
|
||||
# "disabled": False,
|
||||
# },
|
||||
# "kubernetes_dashboard": {
|
||||
# "disabled": False,
|
||||
# },
|
||||
# },
|
||||
},
|
||||
}
|
||||
|
||||
credentials = GoogleCredentials.get_application_default()
|
||||
service = discovery.build('container', 'v1', credentials=credentials)
|
||||
return service.projects().zones().clusters().create(projectId=self.project, zone=zone, body=body).execute()
|
||||
# self.gke_api.create_cluster(self.project, zone, cluster)
|
||||
|
||||
def delete_cluster(self, cluster_id, zone=None, retry=None, timeout=None):
|
||||
"""
|
||||
Deletes a specific cluster.
|
||||
"""
|
||||
if not zone:
|
||||
zone = self.zone
|
||||
|
||||
credentials = GoogleCredentials.get_application_default()
|
||||
service = discovery.build('container', 'v1', credentials=credentials)
|
||||
return service.projects().zones().clusters().delete(projectId=self.project,
|
||||
zone=zone,
|
||||
clusterId=cluster_id).execute()
|
||||
|
||||
def list_clusters(self, project=None, zone=None, retry=None, timeout=None):
|
||||
"""
|
||||
Lists all clusters owned by a project in either the specified zone or
|
||||
all zones.
|
||||
"""
|
||||
return [Cluster(c, self) for c in
|
||||
pbd(self.gke_api.list_clusters(self.project, self.zone, retry,
|
||||
timeout))['clusters']]
|
||||
|
||||
def get_cluster(self, cluster_id, zone=None, retry=None, timeout=None):
|
||||
"""
|
||||
Gets the details of a specific cluster.
|
||||
"""
|
||||
if not zone:
|
||||
zone = self.zone
|
||||
|
||||
credentials = GoogleCredentials.get_application_default()
|
||||
service = discovery.build('container', 'v1', credentials=credentials)
|
||||
return service.projects().zones().clusters().get(projectId=self.project,
|
||||
zone=zone,
|
||||
clusterId=cluster_id).execute()
|
||||
|
||||
# Misc operations
|
||||
def cancel_operation(self, operation_id, retry=None, timeout=None):
|
||||
"""
|
||||
Cancels the specified operation.
|
||||
"""
|
||||
return self.gke_api.cancel_operation(self.project, self.zone,
|
||||
operation_id, retry, timeout)
|
||||
@@ -1,287 +0,0 @@
|
||||
from kubernetes_asyncio import client, config
|
||||
from kubernetes.stream import stream
|
||||
import asyncio
|
||||
|
||||
NAMESPACE = 'default'
|
||||
|
||||
class Node(object):
|
||||
def __init__(self, node, api=None):
|
||||
self.api = api
|
||||
self.node = node
|
||||
|
||||
|
||||
class Pool(object):
|
||||
def __init__(self, pool, api=None):
|
||||
self.api = api
|
||||
self.pool = pool
|
||||
|
||||
|
||||
class Pod(object):
|
||||
def __init__(self, pod, api=None):
|
||||
self.api = api
|
||||
self.pod = pod
|
||||
|
||||
name = pod.metadata.name
|
||||
self.name = name
|
||||
|
||||
self.status = pod.status.phase
|
||||
self.ip = pod.status.host_ip
|
||||
|
||||
try:
|
||||
# Pod names should follow client-network-number scheme
|
||||
bits = name.split('-')
|
||||
self.client = bits[0]
|
||||
self.network = bits[1]
|
||||
|
||||
# Currently only support directly attached gce persistent disks
|
||||
try:
|
||||
self.disk = pod.spec.volumes[0].gce_persistent_disk.pd_name
|
||||
except Exception:
|
||||
self.disk = 'unknown'
|
||||
|
||||
# Pod may not follow correct naming scheme
|
||||
if len(bits) > 2:
|
||||
self.number = int(bits[2])
|
||||
else:
|
||||
self.number = -1
|
||||
except Exception as e:
|
||||
print('warning: probably not one of ours: ' + str(e))
|
||||
self.client = ''
|
||||
self.network = ''
|
||||
self.number = -1
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'name': self.name,
|
||||
'blockchain': self.client,
|
||||
'network': self.network,
|
||||
'number': self.number,
|
||||
'status': self.status,
|
||||
'ip': self.ip,
|
||||
}
|
||||
|
||||
class Service(object):
|
||||
def __init__(self, service, api=None):
|
||||
self.api = api
|
||||
self.service = service
|
||||
|
||||
selector = service.spec.selector
|
||||
name = 'unknown-unknown'
|
||||
if selector is not None:
|
||||
self.name = name = selector['app']
|
||||
|
||||
if service.status.load_balancer is not None and \
|
||||
service.status.load_balancer.ingress is not None:
|
||||
self.ip = service.status.load_balancer.ingress[0].ip
|
||||
else:
|
||||
self.ip = ''
|
||||
|
||||
self.ports = service.spec.ports
|
||||
|
||||
try:
|
||||
# Pod names should follow client-network-number scheme
|
||||
bits = name.split('-')
|
||||
self.client = bits[0]
|
||||
self.network = bits[1]
|
||||
|
||||
if len(bits) > 2:
|
||||
self.number = int(bits[2])
|
||||
else:
|
||||
self.number = -1
|
||||
except Exception as e:
|
||||
print('warning: probably not one of ours: ' + str(e))
|
||||
self.client = ''
|
||||
self.network = ''
|
||||
self.number = -1
|
||||
|
||||
def to_dict(self):
|
||||
ports = []
|
||||
for port in self.ports:
|
||||
p = {'port': port.port, 'name': port.name}
|
||||
if hasattr(port, 'node_port'):
|
||||
p['nodePort'] = port.node_port
|
||||
ports.append(p)
|
||||
return {
|
||||
'name': self.name,
|
||||
'blockchain': self.client,
|
||||
'network': self.network,
|
||||
'number': self.number,
|
||||
'ip': self.ip,
|
||||
'ports': ports,
|
||||
}
|
||||
|
||||
# def exec(self, js):
|
||||
# command = [
|
||||
# '/bin/geth',
|
||||
# '--datadir=/data',
|
||||
# 'attach',
|
||||
# '--exec',
|
||||
# js
|
||||
# ]
|
||||
# return self.api.exec(self.name, command).lower()
|
||||
|
||||
# def syncing(self):
|
||||
# if self.exec('eth.syncing').lower() == 'false':
|
||||
# return False
|
||||
# else:
|
||||
# return True
|
||||
|
||||
# def block_number(self):
|
||||
# try:
|
||||
# return int(self.exec('eth.blockNumber'))
|
||||
# except:
|
||||
# return -1
|
||||
|
||||
# def __repr__(self):
|
||||
# return self.name
|
||||
|
||||
class Deployment(object):
|
||||
def __init__(self, deployment, api=None):
|
||||
self.api = api
|
||||
self.deployment = deployment
|
||||
|
||||
name = deployment.metadata.name
|
||||
self.name = name
|
||||
|
||||
try:
|
||||
# Pod names should follow client-network-number scheme
|
||||
bits = name.split('-')
|
||||
self.client = bits[0]
|
||||
self.network = bits[1]
|
||||
|
||||
# Pod may not follow correct naming scheme
|
||||
if len(bits) > 2:
|
||||
self.number = int(bits[2])
|
||||
else:
|
||||
self.number = -1
|
||||
except Exception as e:
|
||||
print('warning: probably not one of ours: ' + str(e))
|
||||
self.client = ''
|
||||
self.network = ''
|
||||
self.number = -1
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'name': self.name,
|
||||
'blockchain': self.client,
|
||||
'network': self.network,
|
||||
'number': self.number,
|
||||
}
|
||||
|
||||
class Kubernetes(object):
|
||||
def __init__(self, config_path='config/ethereum-testnet/cluster.yaml'):
|
||||
self.config_path = config_path
|
||||
self.api = None
|
||||
|
||||
async def init_apis(self):
|
||||
if self.api is None:
|
||||
api_client = await config.new_client_from_config(self.config_path)
|
||||
|
||||
self.api = client.CoreV1Api(api_client)
|
||||
self.apps_api = client.AppsV1Api(api_client)
|
||||
|
||||
async def exec(self, pod_name, command, namespace=NAMESPACE, stdin=False,
|
||||
stderr=True, stdout=True, tty=False):
|
||||
await self.init_apis()
|
||||
return await stream(self.api.connect_get_namespaced_pod_exec, pod_name,
|
||||
namespace, command=command, stdin=stdin, stderr=stderr,
|
||||
stdout=stdout, tty=tty)
|
||||
|
||||
async def create_volume(self, config):
|
||||
await self.init_apis()
|
||||
return await self.api.create_namespaced_persistent_volume_claim(NAMESPACE, body=config)
|
||||
|
||||
async def delete_volume(self, name):
|
||||
await self.init_apis()
|
||||
return await self.api.delete_namespaced_persistent_volume_claim(name,
|
||||
NAMESPACE,
|
||||
body=client.V1DeleteOptions(),
|
||||
grace_period_seconds=60,
|
||||
propagation_policy='Background')
|
||||
|
||||
async def create_service(self, config):
|
||||
await self.init_apis()
|
||||
return Service(await self.api.create_namespaced_service(NAMESPACE, body=config), self)
|
||||
|
||||
async def delete_service(self, name):
|
||||
await self.init_apis()
|
||||
return await self.api.delete_namespaced_service(name, NAMESPACE, body=client.V1DeleteOptions())
|
||||
|
||||
async def list_services(self, network=None):
|
||||
await self.init_apis()
|
||||
services = [Service(p, self) for p in
|
||||
(await self.api.list_namespaced_service(NAMESPACE)).items]
|
||||
|
||||
if not network:
|
||||
return services
|
||||
|
||||
return [p for p in services if p.network == network]
|
||||
|
||||
async def get_service(self, name):
|
||||
await self.init_apis()
|
||||
return Service(await self.api.read_namespaced_service(name, NAMESPACE), self)
|
||||
|
||||
async def create_pod(self, config):
|
||||
await self.init_apis()
|
||||
return await self.api.create_namespaced_pod(NAMESPACE, body=config)
|
||||
|
||||
async def delete_pod(self, name):
|
||||
await self.init_apis()
|
||||
return await self.api.delete_namespaced_pod(name, NAMESPACE, body=client.V1DeleteOptions())
|
||||
|
||||
async def list_pods(self, label_selector=None, network=None):
|
||||
await self.init_apis()
|
||||
if label_selector is None:
|
||||
pods = [Pod(p, self) for p in
|
||||
(await self.api.list_namespaced_pod(NAMESPACE)).items]
|
||||
else:
|
||||
pods = [Pod(p, self) for p in
|
||||
(await self.api.list_namespaced_pod(NAMESPACE, label_selector=label_selector)).items]
|
||||
|
||||
if not network:
|
||||
return pods
|
||||
|
||||
return [p for p in pods if p.network == network]
|
||||
|
||||
async def get_pod(self, name):
|
||||
await self.init_apis()
|
||||
for pod in await self.list_pods():
|
||||
if pod.name == name:
|
||||
return pod
|
||||
raise Exception('Pod not found: "%s"' % name)
|
||||
|
||||
async def create_deployment(self, config):
|
||||
await self.init_apis()
|
||||
return await self.apps_api.create_namespaced_deployment(NAMESPACE, body=config)
|
||||
|
||||
async def delete_deployment(self, name):
|
||||
await self.init_apis()
|
||||
return await self.apps_api.delete_namespaced_deployment(name, NAMESPACE, body=client.V1DeleteOptions())
|
||||
|
||||
async def list_deployments(self, network=None):
|
||||
await self.init_apis()
|
||||
deployments = [Deployment(p, self) for p in (await self.apps_api.list_namespaced_deployment(NAMESPACE)).items]
|
||||
|
||||
if not network:
|
||||
return deployments
|
||||
|
||||
return [p for p in deployments if p.network == network]
|
||||
|
||||
async def get_deployment(self, name):
|
||||
await self.init_apis()
|
||||
return Deployment(await self.apps_api.read_namespaced_deployment(name, NAMESPACE), self)
|
||||
|
||||
async def get_last_pod(self, network=None):
|
||||
await self.init_apis()
|
||||
return max(await self.list_pods(network), key=lambda x: x.number)
|
||||
|
||||
async def get_synced_pod(self, network=None):
|
||||
await self.init_apis()
|
||||
pods = await self.list_pods(network)
|
||||
for pod in sorted(pods, key=lambda x: x.number):
|
||||
if not pod.syncing():
|
||||
return pod
|
||||
|
||||
async def create_ingress(self, config):
|
||||
await self.init_apis()
|
||||
await self.api.create_namespaced_ingress(NAMESPACE, config)
|
||||
@@ -1,32 +0,0 @@
|
||||
from tabulate import tabulate
|
||||
from collections import Iterable
|
||||
|
||||
|
||||
def attr(obj, a):
|
||||
"""
|
||||
Returns value of attribute on an object, calling attribute if necessary.
|
||||
"""
|
||||
v = getattr(obj, a, None)
|
||||
if callable(v):
|
||||
return v()
|
||||
return v
|
||||
|
||||
|
||||
def table(data, *attrs):
|
||||
"""
|
||||
Takes an object or list of objects and prints specified attributes in a
|
||||
nicely formatted table.
|
||||
"""
|
||||
|
||||
# Ensure data is iterable
|
||||
if not isinstance(data, Iterable):
|
||||
data = [data]
|
||||
|
||||
# Generate headers from attributes specified
|
||||
headers = [a.upper().replace('_', ' ') for a in attrs]
|
||||
|
||||
# Generate tabular data from list of objects
|
||||
table = [[attr(o, a) for a in attrs] for o in data]
|
||||
|
||||
# Pretty print table and headers
|
||||
print(tabulate(table, headers=headers))
|
||||
@@ -1,885 +0,0 @@
|
||||
import os.path
|
||||
import secrets
|
||||
|
||||
class Dict(dict):
|
||||
def __init__(self, **kwargs):
|
||||
dict.__init__(self, **kwargs)
|
||||
self.__dict__ = self
|
||||
|
||||
|
||||
class Selector(Dict):
|
||||
def __init__(self, matchLabels={}, match_expressions=[]):
|
||||
Dict.__init__(self, matchLabels=matchLabels,
|
||||
match_expressions=match_expressions)
|
||||
|
||||
self.matchLabels = matchLabels
|
||||
self.match_expressions=[]
|
||||
|
||||
class ExecAction(Dict):
|
||||
def __init__(self, command=[]):
|
||||
Dict.__init__(self, command=command)
|
||||
|
||||
self.command=command
|
||||
|
||||
class Probe(Dict):
|
||||
def __init__(self, exec=None, failureThreshold=3, initialDelaySeconds=10,
|
||||
periodSeconds=10, successThreshold=1, timeoutSeconds=1):
|
||||
Dict.__init__(self, exec=exec,
|
||||
failureThreshold=failureThreshold,
|
||||
initialDelaySeconds=initialDelaySeconds,
|
||||
periodSeconds=periodSeconds,
|
||||
successThreshold=successThreshold,
|
||||
timeoutSeconds=timeoutSeconds)
|
||||
|
||||
self.exec=exec
|
||||
self.failureThreshold=failureThreshold
|
||||
self.initialDelaySeconds=initialDelaySeconds
|
||||
self.periodSeconds=periodSeconds
|
||||
self.successThreshold=successThreshold
|
||||
self.timeoutSeconds=timeoutSeconds
|
||||
|
||||
class Metadata(Dict):
|
||||
def __init__(self, name='', cluster='', blockchain='', network='',
|
||||
labels=None, annotations=None):
|
||||
Dict.__init__(self, name=name, cluster=cluster, blockchain=blockchain,
|
||||
network=network, labels=labels)
|
||||
self.name = name
|
||||
self.cluster = cluster
|
||||
self.blockchain = blockchain
|
||||
self.network = network
|
||||
self.annotations = annotations
|
||||
self.labels = labels
|
||||
|
||||
class PodSpec(Dict):
|
||||
def __init__(self, containers=(), volumes=(), ports=(), selector=None,
|
||||
backend=None):
|
||||
Dict.__init__(self, selector=selector, containers=containers,
|
||||
volumes=volumes)
|
||||
self.containers = containers
|
||||
self.selector = selector
|
||||
self.volumes = volumes
|
||||
self.backend = backend
|
||||
|
||||
class Resources(Dict):
|
||||
def __init__(self, requests=None, limits=None):
|
||||
Dict.__init__(self, requests=requests, limits=limits)
|
||||
self.requests = requests
|
||||
self.limits = limits
|
||||
|
||||
class EnvVar(Dict):
|
||||
def __init__(self, name=None, value=None, valueFrom=None):
|
||||
Dict.__init__(self, name=name, value=value, valueFrom=valueFrom)
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.valueFrom = valueFrom
|
||||
|
||||
class EnvVarSource(Dict):
|
||||
def __init__(self, fieldRef=None):
|
||||
Dict.__init__(self, fieldRef=fieldRef)
|
||||
self.fieldRef = fieldRef
|
||||
|
||||
class ObjectFieldSelector(Dict):
|
||||
def __init__(self, fieldPath=None):
|
||||
Dict.__init__(self, fieldPath=fieldPath)
|
||||
self.fieldPath = fieldPath
|
||||
|
||||
class Container(Dict):
|
||||
def __init__(self, name, image, command, args, imagePullPolicy='Always', resources=None,
|
||||
volumeMounts=None, livenessProbe=None, readinessProbe=None,
|
||||
env=None):
|
||||
Dict.__init__(self, name=name, image=image,command=command, args=args,
|
||||
imagePullPolicy=imagePullPolicy, resources=resources, livenessProbe=livenessProbe,
|
||||
readinessProbe=readinessProbe, env=env)
|
||||
self.name = name
|
||||
self.image = image
|
||||
self.command = command
|
||||
self.args = args
|
||||
self.imagePullPolicy = imagePullPolicy
|
||||
self.env = env
|
||||
self.resources = resources
|
||||
self.volumeMounts = volumeMounts
|
||||
self.livenessProbe = livenessProbe
|
||||
self.readinessProbe = readinessProbe
|
||||
|
||||
class Requests(Dict):
|
||||
def __init__(self, cpu=None, memory=None):
|
||||
Dict.__init__(self, cpu=cpu, memory=memory)
|
||||
self.cpu = cpu
|
||||
self.memory = memory
|
||||
|
||||
|
||||
class Limits(Dict):
|
||||
def __init__(self, cpu=None, memory=None):
|
||||
Dict.__init__(self, cpu=cpu, memory=memory)
|
||||
self.cpu = cpu
|
||||
self.memory = memory
|
||||
|
||||
|
||||
class VolumeMount(Dict):
|
||||
def __init__(self, name, mountPath):
|
||||
Dict.__init__(self, name=name, mountPath=mountPath)
|
||||
self.name = name
|
||||
self.mountPath = mountPath
|
||||
|
||||
|
||||
class Volume(Dict):
|
||||
def __init__(self, name, gcePersistentDisk=None, persistentVolumeClaim=None, emptyDir = None):
|
||||
Dict.__init__(self,
|
||||
name=name,
|
||||
gcePersistentDisk=gcePersistentDisk,
|
||||
persistentVolumeClaim=persistentVolumeClaim,
|
||||
emptyDir=emptyDir)
|
||||
self.name = name
|
||||
self.gcePersistentDisk = gcePersistentDisk
|
||||
self.persistentVolumeClaim = persistentVolumeClaim
|
||||
self.emptyDir = emptyDir
|
||||
|
||||
class PersistentVolumeClaimVolume(Dict):
|
||||
def __init__(self, claimName):
|
||||
Dict.__init__(self, claimName=claimName)
|
||||
self.claimName = claimName
|
||||
|
||||
class GcePersistentDisk(Dict):
|
||||
def __init__(self, pdName, fsType):
|
||||
Dict.__init__(self, pdName=pdName, fsType=fsType)
|
||||
self.pdName = pdName
|
||||
self.fsType = fsType
|
||||
|
||||
class EmptyDir(Dict):
|
||||
def __init__(self, medium='', sizeLimit='10Gi'):
|
||||
Dict.__init__(self, medium=medium, sizeLimit=sizeLimit)
|
||||
self.medium = medium
|
||||
self.sizeLimit = sizeLimit
|
||||
|
||||
class Backend(Dict):
|
||||
def __init__(self, serviceName, servicePort):
|
||||
Dict.__init__(self, serviceName=serviceName, servicePort=servicePort)
|
||||
self.serviceName = serviceName
|
||||
self.servicePort = servicePort
|
||||
|
||||
|
||||
class ServicePort(Dict):
|
||||
def __init__(self, name=None, node_port=None, port=None, protocol='TCP',
|
||||
targetPort=None, nodePort=None):
|
||||
Dict.__init__(self, port=port, protocol=protocol,
|
||||
targetPort=targetPort, nodePort=nodePort)
|
||||
self.name = name
|
||||
self.nodePort = nodePort
|
||||
self.port = port
|
||||
self.protocol = protocol
|
||||
self.targetPort = targetPort
|
||||
|
||||
|
||||
class BaseTemplateSpec(Dict):
|
||||
def __init__(self, apiVersion='v1', kind=None, metadata=Metadata(),
|
||||
spec=PodSpec()):
|
||||
Dict.__init__(self, apiVersion=apiVersion, kind=kind,
|
||||
metadata=metadata, spec=spec)
|
||||
self.apiVersion = apiVersion
|
||||
self.kind = kind
|
||||
self.metadata = metadata
|
||||
self.spec = spec
|
||||
|
||||
class Ingress(BaseTemplateSpec):
|
||||
def __init__(self, metadata=None, spec=None):
|
||||
super(Ingress, self).__init__(apiVersion='extensions/extensions/v1beta1beta1',
|
||||
kind='Ingress', metadata=metadata, spec=spec)
|
||||
|
||||
|
||||
class PersistentVolumeClaim(BaseTemplateSpec):
|
||||
def __init__(self, metadata=None, spec=None):
|
||||
super(PersistentVolumeClaim, self).__init__(apiVersion='v1', kind='PersistentVolumeClaim', metadata=metadata, spec=spec)
|
||||
|
||||
class PersistentVolumeClaimSpec(Dict):
|
||||
def __init__(self, accessModes=['ReadWriteOnce'], resources=None,
|
||||
selector=None):
|
||||
Dict.__init__(self, accessModes=accessModes,
|
||||
resources=resources, selector=selector)
|
||||
|
||||
class ResourceRequirements(Dict):
|
||||
def __init__(self, requests={'storage': '10Gi'},
|
||||
limits=None):
|
||||
Dict.__init__(self, requests=requests,
|
||||
limits=limits)
|
||||
|
||||
class Service(BaseTemplateSpec):
|
||||
def __init__(self, metadata=None, spec=None):
|
||||
super(Service, self).__init__(apiVersion='v1', kind='Service',
|
||||
metadata=metadata, spec=spec)
|
||||
|
||||
class ServiceSpec(Dict):
|
||||
def __init__(self, clusterIp=None, externalIPs=None, externalName=None,
|
||||
externalTrafficPolicy=None, healthCheckNodePort=None,
|
||||
loadBalancerIp=None, loadBalancerSourceRanges=None, ports=None,
|
||||
publishNotReadyAddresses=False, selector=Selector(),
|
||||
sessionAffinity=None, sessionAffinityConfig=None, type='LoadBalancer'):
|
||||
Dict.__init__(self, clusterIp=clusterIp,
|
||||
externalIPs=externalIPs, externalName=externalName,
|
||||
externalTrafficPolicy=externalTrafficPolicy,
|
||||
healthCheckNodePort=healthCheckNodePort,
|
||||
loadBalancerIp=loadBalancerIp,
|
||||
loadBalancerSourceRanges=loadBalancerSourceRanges,
|
||||
ports=ports, publishNotReadyAddresses=publishNotReadyAddresses,
|
||||
selector=selector, sessionAffinity=sessionAffinity,
|
||||
sessionAffinityConfig=sessionAffinityConfig, type=type)
|
||||
|
||||
self.externalIPs=externalIPs
|
||||
self.externalName=externalName
|
||||
self.externalTrafficPolicy=externalTrafficPolicy
|
||||
self.healthCheckNodePort=healthCheckNodePort
|
||||
self.loadBalancerIp=loadBalancerIp
|
||||
self.loadBalancerSourceRanges=loadBalancerSourceRanges
|
||||
self.ports=ports
|
||||
self.publishNotReadyAddresses=publishNotReadyAddresses
|
||||
self.selector=selector
|
||||
self.sessionAffinity=sessionAffinity
|
||||
self.sessionAffinityConfig=sessionAffinityConfig
|
||||
self.type=type
|
||||
|
||||
class Pod(BaseTemplateSpec):
|
||||
def __init__(self, metadata=None, spec=None):
|
||||
super(Pod, self).__init__(apiVersion='v1', kind='Pod',
|
||||
metadata=metadata, spec=spec)
|
||||
|
||||
class DeploymentStrategy(Dict):
|
||||
def __init__(self, type='RollingUpdate'):
|
||||
Dict.__init__(self, type=type)
|
||||
|
||||
self.type = type
|
||||
|
||||
class DeploymentSpec(Dict):
|
||||
def __init__(self,
|
||||
minReadySeconds=0,
|
||||
paused=False,
|
||||
progressDeadlineSeconds=600,
|
||||
replicas=1,
|
||||
revisionHistoryLimit=10,
|
||||
selector={},
|
||||
strategy=DeploymentStrategy(),
|
||||
template=BaseTemplateSpec()):
|
||||
Dict.__init__(self,
|
||||
minReadySeconds=minReadySeconds,
|
||||
paused=paused,
|
||||
progressDeadlineSeconds=progressDeadlineSeconds,
|
||||
replicas=replicas,
|
||||
revisionHistoryLimit=revisionHistoryLimit,
|
||||
selector=selector,
|
||||
strategy=strategy,
|
||||
template=template)
|
||||
|
||||
self.minReadySeconds = minReadySeconds
|
||||
self.paused = paused
|
||||
self.progressDeadlineSeconds = progressDeadlineSeconds
|
||||
self.replicas = replicas
|
||||
self.revisionHistoryLimit = revisionHistoryLimit
|
||||
self.selector = selector
|
||||
self.strategy = strategy
|
||||
self.template = template
|
||||
|
||||
class Deployment(BaseTemplateSpec):
|
||||
def __init__(self, metadata=None, spec=None):
|
||||
super(Deployment, self).__init__(apiVersion='apps/v1', kind='Deployment',
|
||||
metadata=metadata, spec=spec)
|
||||
|
||||
class Blockchain(Deployment):
|
||||
def __init__(self, name, cluster, blockchain, network, image, command,
|
||||
args, env, path,
|
||||
requests=None, limits=None):
|
||||
|
||||
"""
|
||||
Takes blockchain parameters and generates a DeploymentSpec json
|
||||
"""
|
||||
|
||||
self.name = name
|
||||
self.cluster = cluster
|
||||
self.blockchain = blockchain
|
||||
self.network = network
|
||||
self.image = image
|
||||
self.command = command
|
||||
self.args = args
|
||||
self.path = path
|
||||
|
||||
self.deploymentMetadata = Metadata(
|
||||
name=name,
|
||||
cluster=cluster,
|
||||
blockchain=blockchain,
|
||||
network=network,
|
||||
labels={
|
||||
'cluster': cluster,
|
||||
'blockchain': blockchain,
|
||||
'network': network,
|
||||
})
|
||||
|
||||
self.podMetadata = Metadata(
|
||||
name='pod-' + name,
|
||||
cluster=cluster,
|
||||
blockchain=blockchain,
|
||||
network=network,
|
||||
labels={
|
||||
'app': name
|
||||
})
|
||||
|
||||
client = os.path.basename(command)
|
||||
|
||||
podSpec = self.podSpec = PodSpec(
|
||||
selector={},
|
||||
containers=[],
|
||||
volumes=[],
|
||||
)
|
||||
|
||||
self.deploymentSpec = DeploymentSpec(
|
||||
selector=Selector(
|
||||
matchLabels={
|
||||
'app': name
|
||||
}
|
||||
),
|
||||
template=BaseTemplateSpec(
|
||||
metadata=self.podMetadata,
|
||||
spec=self.podSpec,
|
||||
)
|
||||
)
|
||||
|
||||
container = Container(
|
||||
name=name,
|
||||
image=image,
|
||||
command=[command],
|
||||
args=args,
|
||||
volumeMounts=[VolumeMount(mountPath=path, name=name + '-pv')],
|
||||
resources=Resources(),
|
||||
readinessProbe=Probe(
|
||||
exec=ExecAction(
|
||||
command=['./scripts/alive.sh']
|
||||
)
|
||||
),
|
||||
livenessProbe=Probe(
|
||||
exec=ExecAction(
|
||||
command=['./scripts/alive.sh']
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
if requests:
|
||||
container.resources.request = requests
|
||||
if limits:
|
||||
container.resources.limits = limits
|
||||
|
||||
self.podSpec.containers.append(container)
|
||||
|
||||
# user empty dir for private cloud stuff
|
||||
if 'encloudify' in cluster:
|
||||
container.env=[EnvVar(
|
||||
name='EXTERNAL_IP',
|
||||
valueFrom=EnvVarSource(
|
||||
fieldRef=ObjectFieldSelector(
|
||||
fieldPath='status.hostIP',
|
||||
),
|
||||
),
|
||||
)]
|
||||
|
||||
volume = Volume(
|
||||
name=name + '-pv',
|
||||
emptyDir=EmptyDir()
|
||||
)
|
||||
|
||||
self.podSpec.volumes.append(volume)
|
||||
else:
|
||||
volume = Volume(
|
||||
name=name + '-pv',
|
||||
persistentVolumeClaim=PersistentVolumeClaimVolume(
|
||||
claimName=name + '-pd'
|
||||
)
|
||||
)
|
||||
|
||||
self.podSpec.volumes.append(volume)
|
||||
|
||||
# Create a PodSpec
|
||||
super(Blockchain, self).__init__(metadata=self.deploymentMetadata, spec=self.deploymentSpec)
|
||||
|
||||
self.name = name
|
||||
self.cluster = cluster
|
||||
self.blockchain = blockchain
|
||||
self.network = network
|
||||
self.podSpec = podSpec
|
||||
|
||||
def set_env(self, name, value, container_id=0):
|
||||
if self.podSpec.containers[container_id].env is None:
|
||||
self.podSpec.containers[container_id].env = [EnvVar(name=name,
|
||||
value=value)]
|
||||
else:
|
||||
self.podSpec.containers[container_id].env.append(EnvVar(name=name,
|
||||
value=value))
|
||||
|
||||
def get_service(self, ports):
|
||||
if 'encloudify' in self.cluster:
|
||||
return Service(
|
||||
metadata=Metadata(
|
||||
name='service-' + self.name,
|
||||
cluster=self.cluster,
|
||||
blockchain=self.blockchain,
|
||||
network=self.network
|
||||
),
|
||||
spec=ServiceSpec(
|
||||
selector={
|
||||
'app': self.name
|
||||
},
|
||||
type='NodePort',
|
||||
ports=ports,
|
||||
)
|
||||
)
|
||||
else:
|
||||
return Service(
|
||||
metadata=Metadata(
|
||||
name='service-' + self.name,
|
||||
cluster=self.cluster,
|
||||
blockchain=self.blockchain,
|
||||
network=self.network
|
||||
),
|
||||
spec=ServiceSpec(
|
||||
selector={
|
||||
'app': self.name
|
||||
},
|
||||
type='LoadBalancer',
|
||||
ports=ports,
|
||||
)
|
||||
)
|
||||
|
||||
def get_volume_claim(self, size='10Gi'):
|
||||
if 'encloudify' in self.cluster:
|
||||
return None
|
||||
else:
|
||||
return PersistentVolumeClaim(
|
||||
metadata=Metadata(
|
||||
name=self.name + '-pd',
|
||||
cluster=self.cluster,
|
||||
blockchain=self.blockchain,
|
||||
network=self.network
|
||||
),
|
||||
spec=PersistentVolumeClaimSpec(
|
||||
resources=ResourceRequirements(
|
||||
requests={
|
||||
'storage': size,
|
||||
},
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def to_network_id(cls, network):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def to_network(cls, network_id):
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def normalize_network(cls, network):
|
||||
return None, 0
|
||||
|
||||
@classmethod
|
||||
def is_blockchain(cls, chain):
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "none"
|
||||
|
||||
class Ethereum(Blockchain):
|
||||
def __init__(self, name, network='mainnet', cluster=None,
|
||||
image='gcr.io/hanzo-ai/geth:latest', command='/bin/geth',
|
||||
args=None, datadir='/data', path='./data/geth/chaindata',
|
||||
size=None, rpc=True, ws=True, rpcport=8545, wsport=8546,
|
||||
rpccorsdomain='*', wsorigins='*', requests=None, limits=None):
|
||||
|
||||
"""
|
||||
Takes Ethereum parameters and generates a DeploymentSpec json
|
||||
"""
|
||||
|
||||
# Normalize networks
|
||||
network, network_id = Ethereum.normalize_network(network)
|
||||
|
||||
if args is None:
|
||||
args = [
|
||||
'--networkid={0}'.format(network_id),
|
||||
'--datadir=/data',
|
||||
'--ethash.dagdir=/data/geth/chaindata/dag',
|
||||
'--syncmode=fast',
|
||||
]
|
||||
|
||||
if rpc:
|
||||
args.extend([
|
||||
'--rpc',
|
||||
'--rpcaddr=0.0.0.0',
|
||||
'--rpcapi="eth,net,web3"',
|
||||
'--rpcport={0}'.format(rpcport),
|
||||
'--rpccorsdomain="{0}"'.format(rpccorsdomain),
|
||||
])
|
||||
|
||||
if ws:
|
||||
args.extend([
|
||||
'--ws',
|
||||
'--wsaddr=0.0.0.0',
|
||||
'--wsapi="eth,net,web3"',
|
||||
'--wsport={0}'.format(wsport),
|
||||
'--wsorigins="{0}"'.format(wsorigins),
|
||||
])
|
||||
|
||||
if size is None and requests is None:
|
||||
if network is 'mainnet':
|
||||
size = 'large'
|
||||
elif network is 'testnet':
|
||||
size = 'medium'
|
||||
else:
|
||||
size = 'small'
|
||||
|
||||
if size == 'small':
|
||||
requests = Requests(cpu='2', memory='1Gi')
|
||||
limits = Limits(cpu='2', memory='1536Mi')
|
||||
args.extend([
|
||||
'--cache=512',
|
||||
'--maxpeers=15',
|
||||
])
|
||||
|
||||
elif size == 'medium':
|
||||
requests = Requests(cpu='2', memory='2Gi')
|
||||
limits = Limits(cpu='2', memory='3Gi')
|
||||
args.extend([
|
||||
'--cache=1024',
|
||||
'--maxpeers=25',
|
||||
])
|
||||
|
||||
elif size == 'large':
|
||||
requests = Requests(cpu='2', memory='4Gi')
|
||||
limits = Limits(cpu='2', memory='6Gi')
|
||||
args.extend([
|
||||
'--cache=2048',
|
||||
'--maxpeers=50',
|
||||
])
|
||||
|
||||
elif size == 'huge':
|
||||
requests = Requests(cpu='2', memory='8Gi')
|
||||
limits = Limits(cpu='2', memory='12Gi')
|
||||
args.extend([
|
||||
'--cache=4096',
|
||||
'--maxpeers=100',
|
||||
])
|
||||
|
||||
# Generate a PodSpec
|
||||
super(Ethereum, self).__init__(name, cluster, 'ethereum', network, image,
|
||||
command, args, None, path, requests, limits)
|
||||
|
||||
this.rpcport=rpcport
|
||||
this.wsport=wsport
|
||||
|
||||
|
||||
def get_service(self):
|
||||
ports = []
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='rpc',
|
||||
protocol='TCP',
|
||||
port=self.rpcport,
|
||||
targetPort=8545
|
||||
))
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='ws',
|
||||
protocol='TCP',
|
||||
port=self.wsport,
|
||||
targetPort=8546
|
||||
))
|
||||
|
||||
print(ports)
|
||||
service = super(Ethereum, self).get_service(ports)
|
||||
print(service)
|
||||
|
||||
return service
|
||||
|
||||
def get_volume_claim(self, size='100Gi'):
|
||||
return PersistentVolumeClaim(
|
||||
metadata=Metadata(
|
||||
name=self.name + '-pv',
|
||||
cluster=self.cluster,
|
||||
blockchain=self.blockchain,
|
||||
network=self.network
|
||||
),
|
||||
spec=PersistentVolumeClaimSpec(
|
||||
resources=ResourceRequirements(
|
||||
requests={
|
||||
'storage': size,
|
||||
},
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def to_network_id(cls, network):
|
||||
return {
|
||||
'mainnet': 1,
|
||||
'frontier': 1,
|
||||
'1': 1,
|
||||
|
||||
'morden': 2,
|
||||
'2': 2,
|
||||
|
||||
'testnet': 3,
|
||||
'ropsten': 3,
|
||||
'3': 3,
|
||||
|
||||
'rinkeby': 4,
|
||||
'4': 4
|
||||
}.get(str(network).lower())
|
||||
|
||||
@classmethod
|
||||
def to_network(cls, network_id):
|
||||
return {
|
||||
1: 'mainnet',
|
||||
2: 'morden',
|
||||
3: 'testnet',
|
||||
4: 'rinkeby'
|
||||
}.get(network_id)
|
||||
|
||||
@classmethod
|
||||
def normalize_network(cls, network):
|
||||
network_id = Ethereum.to_network_id(network)
|
||||
network = Ethereum.to_network(network_id)
|
||||
return network, network_id
|
||||
|
||||
@classmethod
|
||||
def is_blockchain(cls, chain):
|
||||
return chain in ['ethereum', 'eth', 'geth']
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return 'geth'
|
||||
|
||||
class Casper(Blockchain):
|
||||
def __init__(self, name, network='mainnet', cluster=None, path='/.casperlabs',
|
||||
image='gcr.io/hanzo-ai/casper:latest',
|
||||
command='/scripts/start.sh',
|
||||
grpcport=40401, serverport=40400, discoveryport=40404,
|
||||
bootstrapaddress=None, externalip=None,
|
||||
args=None, size=None, requests=None):
|
||||
|
||||
"""
|
||||
Takes Casper parameters and generates a DeploymentSpec json
|
||||
"""
|
||||
|
||||
# Normalize networks
|
||||
network, network_id = Casper.normalize_network(network)
|
||||
|
||||
if args is None:
|
||||
args = []
|
||||
# '--grpc-port {0}'.format(grpcport),
|
||||
# '--server-port {0}'.format(serverport),
|
||||
# '--server-no-upnp',
|
||||
# ]
|
||||
|
||||
if bootstrapaddress is None:
|
||||
args.extend(['--casper-standalone'])
|
||||
else:
|
||||
args.extend([
|
||||
'--server-bootstrap {0}'.format(bootstrapaddress),
|
||||
])
|
||||
|
||||
if size is None and requests is None:
|
||||
if network is 'mainnet':
|
||||
size = 'medium'
|
||||
elif network is 'testnet':
|
||||
size = 'small'
|
||||
else:
|
||||
size = 'small'
|
||||
|
||||
if size == 'small':
|
||||
requests = Requests(cpu='1', memory='2Gi')
|
||||
limits = Limits(cpu='1', memory='2Gi')
|
||||
|
||||
elif size == 'medium':
|
||||
requests = Requests(cpu='2', memory='2Gi')
|
||||
limits = Limits(cpu='2', memory='2Gi')
|
||||
|
||||
# Generate a PodSpec
|
||||
super(Casper, self).__init__(name, cluster, 'casper', network, image,
|
||||
command, args, None, path, requests, limits)
|
||||
|
||||
grpc_port = 40401
|
||||
# user empty dir for private cloud stuff
|
||||
if 'encloudify' in cluster:
|
||||
# self.grpc_port_external = secrets.randbelow(2767) + 30000
|
||||
# self.server_port = secrets.randbelow(2767) + 30000
|
||||
# self.discovery_port = secrets.randbelow(2767) + 30000
|
||||
|
||||
self.grpc_port_external = secrets.randbelow(2767) + 30000
|
||||
self.server_port = secrets.randbelow(2767) + 30000
|
||||
self.discovery_port = secrets.randbelow(2767) + 30000
|
||||
|
||||
grpc_port = self.grpc_port_external
|
||||
|
||||
self.podSpec.containers[0].env.append(EnvVar(
|
||||
name='PORTS',
|
||||
value='--grpc-port-external {0} --server-port {1} --server-kademlia-port {2}'.format(self.grpc_port_external,
|
||||
self.server_port,
|
||||
self.discovery_port)
|
||||
))
|
||||
|
||||
envoyContainer = Container(
|
||||
name=name+'-envoy',
|
||||
image='gcr.io/hanzo-ai/casper-envoy:latest',
|
||||
command=['/scripts/start.sh'],
|
||||
args=['--config-path envoyConfig.yaml'],
|
||||
env=[EnvVar(name='GRPC_PORT', value='{0}'.format(grpc_port))],
|
||||
resources=Resources(limits=Limits(cpu='0.1', memory='0.1Gi')),
|
||||
)
|
||||
|
||||
self.podSpec.containers.append(envoyContainer)
|
||||
|
||||
def get_service(self):
|
||||
ports = []
|
||||
if 'encloudify' in self.cluster:
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='grpc',
|
||||
protocol='TCP',
|
||||
port=self.grpc_port_external,
|
||||
nodePort=self.grpc_port_external,
|
||||
))
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='server',
|
||||
protocol='TCP',
|
||||
port=self.server_port,
|
||||
nodePort=self.server_port,
|
||||
))
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='discovery',
|
||||
protocol='TCP',
|
||||
port=self.discovery_port,
|
||||
nodePort=self.discovery_port,
|
||||
))
|
||||
else:
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='grpc',
|
||||
protocol='TCP',
|
||||
port=40401,
|
||||
targetPort=40401
|
||||
))
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='server',
|
||||
protocol='TCP',
|
||||
port=40400,
|
||||
targetPort=40400
|
||||
))
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='discovery',
|
||||
protocol='TCP',
|
||||
port=40404,
|
||||
targetPort=40404
|
||||
))
|
||||
ports.append(
|
||||
ServicePort(
|
||||
name='rpc',
|
||||
protocol='TCP',
|
||||
port=9001,
|
||||
targetPort=9001
|
||||
))
|
||||
# ports.append(
|
||||
# ServicePort(
|
||||
# name='secure-rpc',
|
||||
# protocol='TCP',
|
||||
# port=9002,
|
||||
# targetPort=9002
|
||||
# ))
|
||||
|
||||
service = super(Casper, self).get_service(ports)
|
||||
|
||||
return service
|
||||
|
||||
@classmethod
|
||||
def to_network_id(cls, network):
|
||||
return {
|
||||
'mainnet': 1,
|
||||
'frontier': 1,
|
||||
'1': 1,
|
||||
|
||||
'morden': 2,
|
||||
'2': 2,
|
||||
|
||||
'testnet': 3,
|
||||
'ropsten': 3,
|
||||
'3': 3,
|
||||
|
||||
'rinkeby': 4,
|
||||
'4': 4
|
||||
}.get(str(network).lower())
|
||||
|
||||
@classmethod
|
||||
def to_network(cls, network_id):
|
||||
return {
|
||||
1: 'mainnet',
|
||||
2: 'morden',
|
||||
3: 'testnet',
|
||||
4: 'rinkeby'
|
||||
}.get(network_id)
|
||||
|
||||
@classmethod
|
||||
def normalize_network(cls, network):
|
||||
network_id = Casper.to_network_id(network)
|
||||
network = Casper.to_network(network_id)
|
||||
return network, network_id
|
||||
|
||||
@classmethod
|
||||
def is_blockchain(cls, chain):
|
||||
return chain in ['casper', 'cbc']
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return 'casper'
|
||||
|
||||
class Bitcoin(Blockchain):
|
||||
def __init__(self, name, network, image, command, args, path,
|
||||
resources=None, limits=None):
|
||||
"""
|
||||
Takes Bitcoin parameters and generates a DeploymentSpec json
|
||||
"""
|
||||
|
||||
#Generate PodSpec
|
||||
super(Bitcoin, self).__init__(name, 'bitcoin', network, image, command,
|
||||
args, path, resources, limits)
|
||||
|
||||
@classmethod
|
||||
def to_network_id(cls, network):
|
||||
return {
|
||||
'mainnet': 1,
|
||||
'frontier': 1,
|
||||
'1': 1,
|
||||
|
||||
'morden': 2,
|
||||
'2': 2,
|
||||
|
||||
'testnet': 3,
|
||||
'ropsten': 3,
|
||||
'3': 3,
|
||||
|
||||
'rinkeby': 4,
|
||||
'4': 4
|
||||
}.get(str(network).lower())
|
||||
|
||||
@classmethod
|
||||
def to_network(cls, network_id):
|
||||
return {
|
||||
1: 'mainnet',
|
||||
2: 'testnet',
|
||||
}.get(network_id)
|
||||
|
||||
@classmethod
|
||||
def normalize_network(cls, network):
|
||||
network_id = Ethereum.to_network_id(network)
|
||||
network = Ethereum.to_network(network_id)
|
||||
return network, network_id
|
||||
|
||||
@classmethod
|
||||
def is_blockchain(cls, chain):
|
||||
return chain in ['bitcoin']
|
||||
@@ -1,44 +0,0 @@
|
||||
# FROM ubuntu:18.04
|
||||
|
||||
# RUN apt-get update
|
||||
# RUN apt-get install curl gnupg openjdk-11-jre-headless -y
|
||||
# RUN curl -sO http://repo.casperlabs.io/casperlabs/repo/master/casperlabs-node_0.2_all.deb
|
||||
# RUN curl -sO http://repo.casperlabs.io/casperlabs/repo/master/casperlabs-engine-grpc-server_0.2_amd64.deb
|
||||
# RUN curl -sO http://repo.casperlabs.io/casperlabs/repo/master/casperlabs-client_0.2_all.deb
|
||||
# RUN dpkg -i casperlabs-node_0.2_all.deb
|
||||
# RUN dpkg -i casperlabs-engine-grpc-server_0.2_amd64.deb
|
||||
# RUN dpkg -i casperlabs-client_0.2_all.deb
|
||||
|
||||
# FROM ubuntu:18.04
|
||||
|
||||
# RUN apt-get update
|
||||
# RUN apt-get install curl gnupg openjdk-11-jre-headless -y
|
||||
# RUN echo "deb https://dl.bintray.com/casperlabs/debian /" | tee -a /etc/apt/sources.list.d/sbt.list
|
||||
# RUN curl -o casperlabs-public.key.asc https://bintray.com/user/downloadSubjectPublicKey?username=casperlabs
|
||||
# RUN apt-key add casperlabs-public.key.asc
|
||||
# RUN apt-get update
|
||||
# RUN apt install casperlabs -y
|
||||
|
||||
FROM openjdk:11-slim
|
||||
RUN apt-get update
|
||||
RUN apt-get install psmisc unzip git gnupg apt-transport-https ca-certificates openssl dirmngr -y
|
||||
RUN echo "deb https://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list
|
||||
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
|
||||
RUN apt-get update
|
||||
RUN apt-get install sbt build-essential cmake curl -y
|
||||
RUN curl https://sh.rustup.rs -sSf > $HOME/rustup.sh
|
||||
RUN chmod 775 $HOME/rustup.sh
|
||||
RUN $HOME/rustup.sh -y
|
||||
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.25.0/install.sh | bash
|
||||
RUN bash -c "source $HOME/.cargo/env; rustup update"
|
||||
RUN bash -c "source $HOME/.cargo/env; rustup toolchain install nightly"
|
||||
RUN bash -c "source $HOME/.cargo/env; rustup target add wasm32-unknown-unknown --toolchain nightly"
|
||||
ENV PROTOC_VERSION=3.6.1
|
||||
ENV PROTOC_ZIP=protoc-$PROTOC_VERSION-linux-x86_64.zip
|
||||
RUN curl -OL https://github.com/google/protobuf/releases/download/v$PROTOC_VERSION/$PROTOC_ZIP
|
||||
RUN unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
|
||||
RUN rm -f $PROTOC_ZIP
|
||||
RUN git clone -b v0.3.1 https://github.com/CasperLabs/CasperLabs.git
|
||||
|
||||
COPY scripts/ scripts
|
||||
RUN ./scripts/build.sh
|
||||
@@ -1,2 +0,0 @@
|
||||
This dockerfile loads the scratch build of casper only. It is used by the
|
||||
casper dockerfile so we don't have to rebuild everything everytime.
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mkdir /.casperlabs
|
||||
cd CasperLabs
|
||||
sbt -mem 5000 client/universal:stage
|
||||
sbt -mem 5000 node/universal:stage
|
||||
cd execution-engine
|
||||
bash -c "source $HOME/.cargo/env; cargo build"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
FROM envoyproxy/envoy:latest
|
||||
COPY config /envoy
|
||||
COPY scripts /scripts
|
||||
RUN apt-get update
|
||||
RUN apt-get install gettext-base -y
|
||||
ADD casper-envoy.crt /etc/casper-envoy.crt
|
||||
ADD casper-envoy.key /etc/casper-envoy.key
|
||||
WORKDIR /envoy
|
||||
@@ -1,2 +0,0 @@
|
||||
This dockerfile is the image for the envoy proxy for converting http rpc to
|
||||
http2 grpc.
|
||||
@@ -1,21 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDhjCCAm4CCQDqVC6OouuZGzANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC
|
||||
VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAcMC0xvcyBBbmdlbGVzMQ4w
|
||||
DAYDVQQKDAVIYW56bzEOMAwGA1UECwwFSGFuem8xDjAMBgNVBAMMBUhhbnpvMRow
|
||||
GAYJKoZIhvcNAQkBFgtoaUBoYW56by5haTAeFw0xOTA1MTIwNDE3MjNaFw0yMDA1
|
||||
MTEwNDE3MjNaMIGEMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEU
|
||||
MBIGA1UEBwwLTG9zIEFuZ2VsZXMxDjAMBgNVBAoMBUhhbnpvMQ4wDAYDVQQLDAVI
|
||||
YW56bzEOMAwGA1UEAwwFSGFuem8xGjAYBgkqhkiG9w0BCQEWC2hpQGhhbnpvLmFp
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuWJNXvx6V65T2kvXoJyx
|
||||
/KmUFH2PIklQ0AxfuUOPxkdNGh2d8wk4XTy2sRDwPrK7h02qMHWCDlMgOCpKSaUn
|
||||
U5uWI13uRaGJB6xaZC98SHf1Mn2b8lbvzzCzy57KOJsOq3JxR0ia9POD1ZNWI5xB
|
||||
Nj3RXQ/N9oxzgpp90+JWmlXneJprGhMLRRHQVwFuBhsTIOK8EaryNk1CwGraYa7H
|
||||
qSxDoAN4k1OvKAp8Sk021/kMrZzxKyaChHeiMW7ee7wtJ7Z1JcqWbNhuOvBsgtrK
|
||||
2CxwVa0bzYGNP23GA7fKNUXC/5zG+ODn7v03PRdzptWe1rrHVp3JLK9FMTEacWCT
|
||||
4wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCbRvWdNoga5gH2IsgnyXNcMxX+igEX
|
||||
x/MoFyU4rxef8YVNWkEqKaiS26sNL+oHfim0EJ9kGaHoB1OxaVtc3QMzXJrESfxO
|
||||
0AtbvJnxVt6Tn2hgDfVtCKrjquwxxkd8iEdN6cKwwY1VmebrF839aXQW7BEAXLAq
|
||||
YL3CRMGwVmIl9ML1d5KPLw+9b/GmVo7fHhfP8Uc92MnSc4XM371xpsJPm70nb8jz
|
||||
rD21aoa7QXZWM/f2wB2L5YLg4wThp6MO7J6gpVXwtG5ofR/PKYbKsRPgGWkuVC95
|
||||
G2//H6Bc1AGa1TI2MZ1hUr55ds5UjvXUhfnD2jLgnfMeyBA/1V8rwDWQ
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAuWJNXvx6V65T2kvXoJyx/KmUFH2PIklQ0AxfuUOPxkdNGh2d
|
||||
8wk4XTy2sRDwPrK7h02qMHWCDlMgOCpKSaUnU5uWI13uRaGJB6xaZC98SHf1Mn2b
|
||||
8lbvzzCzy57KOJsOq3JxR0ia9POD1ZNWI5xBNj3RXQ/N9oxzgpp90+JWmlXneJpr
|
||||
GhMLRRHQVwFuBhsTIOK8EaryNk1CwGraYa7HqSxDoAN4k1OvKAp8Sk021/kMrZzx
|
||||
KyaChHeiMW7ee7wtJ7Z1JcqWbNhuOvBsgtrK2CxwVa0bzYGNP23GA7fKNUXC/5zG
|
||||
+ODn7v03PRdzptWe1rrHVp3JLK9FMTEacWCT4wIDAQABAoIBAQCXHgHyDx/vv6SN
|
||||
C0v/mhwg2V9jgKKgEWG15pBVZjSaLd81DbWGuxpeLrLCDgu5IFtrxSyZigB1it91
|
||||
yUt7UwyGxAqUU+p6il44ig+5IVhPfrG68degqaucmpfFwXAYypUfvw+GSzI9wQ/T
|
||||
luId7y7dd3DmSo7bjsxOR3+QrC1qan8GEN3qztIo+kpqR422LtgbSIcijDdXv8PQ
|
||||
u4c2jEH5zfyarccRSw72mlHenu37e6vRXXxbmlKUtv2Gq8mflYcG3kdT+2ONbQ9M
|
||||
75fBVZnla1sIk2vzC7ToL2JSVfZatWjIGc5tHrUChayUHYfCNyqK3pBTQy8yLqhJ
|
||||
UQ5qH5VRAoGBAOEB9wOrzw//duAVKgma8wqO2lW1lLp9cCW7+IyX+G6AN+TBKntk
|
||||
jfl9IimB1oe23HW6wlXHCmQugKDj4nR8Wi3/Ngo8DsrVWg/vP289Jmtvafb8y3vF
|
||||
3pnamZLHc5aUwBEUT8GkutzvxwHHbSFBMmRA2d4vFOQcAPUfwTUexeq5AoGBANLr
|
||||
KONz2+fMZA8tR3/0UEKtS8IYqFzl76y0ydL9Phs4EYv5T8rFaAzEgTVD1Uneag4E
|
||||
yK+7gIXxNiW6ZV9n1jybstBFXdFi2K26GSc+ycDUTxALaGabES4YfyQFt+ZbyG9R
|
||||
egYzgVfeQRh713P3PvfaSa+IOptKm0vMciKJ9LV7AoGBANEGlERyzS7dcb+FqcG2
|
||||
kmWSg73vq7T7Zr2HO8TQQNfWgRYfZKmwpjvJRX0twu/crj0oO/SXrU2X7aKJUQxJ
|
||||
oTTty3QCivNe9AWtik56jkBsBhKOkTHwhXSEIPq8EuMmWK8FIXqQ347zqPo8G2Mz
|
||||
P+7mV/8R2eR3J2SQFVqVteLxAoGAe1NlJRmpi2/HUdh35ilEhLgvg95HE4qfCazs
|
||||
FaJdniy6lc3BCh9DJ7P+mNaA8CBMgsXpUlegXrEbqBPFEnP0oJupgn4MzVGuwGYA
|
||||
LyJXdZiuYgNJmDUzZnCMZtOxI9Cm8fACGX4kMuyRw28mG3iGKQZJ74kIO6T0CO4S
|
||||
Dn/7xeECgYBzhEIwaBNEXhKS62o4tPAmgj073Rui8ufBVt1SiGpT7tPPYqB4/N+a
|
||||
ukcCGbJQz9Ovidon0DNZijcd5v5qkEf95bz8BY9Dpj7rT5EdWsELyWaTInkJ2jWG
|
||||
I/cfRVPOYrRPG3ylXhNaZM8mKzBGczbGePFDwsZgXeWqbF+lgj1Xfw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
Binary file not shown.
@@ -1,123 +0,0 @@
|
||||
# datatype specs can be found at https://www.envoyproxy.io/docs/envoy/v1.7.1/api-v2/api#envoy-api-reference
|
||||
# datatypes are listed in parentheses in comments; if surrounded by square brackets = array of said datatype; if ":R" appended = required
|
||||
# the top-level object is (config.bootstrap.v2.Bootstrap)
|
||||
|
||||
# datatype specs can be found at https://www.envoyproxy.io/docs/envoy/v1.7.1/api-v2/api#envoy-api-reference
|
||||
# datatypes are listed in parentheses in comments; if surrounded by square brackets = array of said datatype; if ":R" appended = required
|
||||
# the top-level object is (config.bootstrap.v2.Bootstrap)
|
||||
|
||||
admin: #(config.bootstrap.v2.Admin:R)
|
||||
access_log_path: envoyLog.txt #(string:R)
|
||||
address:
|
||||
socket_address: { address: 0.0.0.0, port_value: 9000 } #(core.Address:R) envoy admin port; can connect a browser here if desired
|
||||
|
||||
static_resources: #(config.bootstrap.v2.Bootstrap.StaticResources)
|
||||
listeners: #([Listener])
|
||||
- name: casperNodeWebListener #(string)
|
||||
address: #(core.Address:R)
|
||||
socket_address: { address: 0.0.0.0, port_value: 9001 } #(core.Address) where a browser should connect to talk to a node
|
||||
filter_chains: #([listener.FilterChain]:R)
|
||||
- filters: #([listener.Filter])
|
||||
- name: envoy.http_connection_manager #(string:R) make downstream http, i.e. facing out from node cluster
|
||||
config: #(config.filter.network.http_connection_manager.v2.HttpConnectionManager) specific type depends on value of name field
|
||||
stat_prefix: casperNodeWebFilter #(string:R) prepended to stats for this filter
|
||||
codec_type: AUTO #(config.filter.network.http_connection_manager.v2.HttpConnectionManager.CodecType) options: AUTO (default), HTTP1, HTTP2
|
||||
route_config: #(RouteConfiguration) required for static connection configurations
|
||||
name: local_route #(string)
|
||||
virtual_hosts: #([route.VirtualHost]) array of virtual hosts composing the route table; may need to add "cors" (route.CorsPolicy) to route.VirtualHost
|
||||
- name: casperNodeWebVHost #(string:R)
|
||||
domains: [ "*" ] #([string]:R) if this matches the host component of incoming url, route to this virtual host
|
||||
cors:
|
||||
allow_credentials: true
|
||||
allow_methods: GET, PUT, DELETE, POST, PATCH, OPTIONS
|
||||
allow_headers: content-type,origin,authorization
|
||||
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web
|
||||
expose_headers: grpc-status,grpc-message,x-envoy-upstream-service-time
|
||||
routes: #([route.Route])
|
||||
- match: { prefix: "/", headers: [ { name: ":method", exact_match: "OPTIONS" } ] }
|
||||
direct_response:
|
||||
status: 204
|
||||
response_headers_to_add:
|
||||
- header: { key: "Access-Control-Allow-Origin", value: "*" }
|
||||
append: false
|
||||
- header: { key: "Access-Control-Allow-Methods", value: "DELETE, HEAD, OPTIONS, GET, PATCH, POST, PUT" }
|
||||
append: false
|
||||
- header: { key: "Allow", value: "DELETE, HEAD, OPTIONS, GET, PATCH, POST, PUT" }
|
||||
append: false
|
||||
- header: { key: "Access-Control-Allow-Headers", value: "Authorization, Content-Type" }
|
||||
append: false
|
||||
- header: { key: "Content-Type", value: "text/html; charset=utf-8" }
|
||||
append: false
|
||||
|
||||
- match: { prefix: "/" } #(route.RouteMatch:R) inside "match" element, one of "prefix", "path", "regex" is required # inside "match" element, can also match headers with "headers" (route.HeaderMatcher) and query params with "query_parameters" (route.QueryParameterMatcher)
|
||||
route: { cluster: casperNodes } #(route.routeAction) inside "route" element, one of "cluster", "cluster_header", "weighted_clusters" is required
|
||||
http_filters: #([config.filter.network.http_connection_manager.v2.HttpFilter]) filter order does not appear to be significant
|
||||
- name: envoy.grpc_json_transcoder #(string:R)
|
||||
config: #(config.filter.http.transcoder.v2.GrpcJsonTranscoder) specific type depends on value of name field
|
||||
proto_descriptor: casperMessageDescSet.pb #(string:R) name of file emitted by protoc using the --descriptor_set_out option
|
||||
match_incoming_request_route: true #(bool) if false, match a fixed URL pattern determined by service and endpoint names in .proto file
|
||||
# need additional steps when compiling the .proto file; see https://www.envoyproxy.io/docs/envoy/v1.7.1/configuration/http_filters/grpc_json_transcoder_filter
|
||||
services: #([string]:R) one element per service in .proto file (which is also in the descriptor set file) that is to be exposed
|
||||
- io.casperlabs.casper.protocol.DeployService
|
||||
- name: envoy.router #(string:R)
|
||||
# other options for elements of the "http_filters" array: envoy.grpc_web, envoy.grpc_http1_bridge, envoy.cors
|
||||
# - name: casperNodeWebListener #(string)
|
||||
# address: #(core.Address:R)
|
||||
# socket_address: { address: 0.0.0.0, port_value: 9002 } #(core.Address) where a browser should connect to talk to a node
|
||||
# filter_chains: #([listener.FilterChain]:R)
|
||||
# - filters: #([listener.Filter])
|
||||
# - name: envoy.http_connection_manager #(string:R) make downstream http, i.e. facing out from node cluster
|
||||
# config: #(config.filter.network.http_connection_manager.v2.HttpConnectionManager) specific type depends on value of name field
|
||||
# stat_prefix: casperNodeWebFilter #(string:R) prepended to stats for this filter
|
||||
# codec_type: AUTO #(config.filter.network.http_connection_manager.v2.HttpConnectionManager.CodecType) options: AUTO (default), HTTP1, HTTP2
|
||||
# route_config: #(RouteConfiguration) required for static connection configurations
|
||||
# name: local_route #(string)
|
||||
# virtual_hosts: #([route.VirtualHost]) array of virtual hosts composing the route table; may need to add "cors" (route.CorsPolicy) to route.VirtualHost
|
||||
# - name: casperNodeWebVHost #(string:R)
|
||||
# domains: [ "*" ] #([string]:R) if this matches the host component of incoming url, route to this virtual host
|
||||
# cors:
|
||||
# allow_credentials: true
|
||||
# allow_methods: GET, PUT, DELETE, POST, PATCH, OPTIONS
|
||||
# allow_headers: content-type,origin,authorization
|
||||
# allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web
|
||||
# expose_headers: grpc-status,grpc-message,x-envoy-upstream-service-time
|
||||
# routes: #([route.Route])
|
||||
# - match: { prefix: "/", headers: [ { name: ":method", exact_match: "OPTIONS" } ] }
|
||||
# direct_response:
|
||||
# status: 204
|
||||
# response_headers_to_add:
|
||||
# - header: { key: "Access-Control-Allow-Origin", value: "*" }
|
||||
# append: false
|
||||
# - header: { key: "Access-Control-Allow-Methods", value: "DELETE, HEAD, OPTIONS, GET, PATCH, POST, PUT" }
|
||||
# append: false
|
||||
# - header: { key: "Allow", value: "DELETE, HEAD, OPTIONS, GET, PATCH, POST, PUT" }
|
||||
# append: false
|
||||
# - header: { key: "Access-Control-Allow-Headers", value: "Authorization, Content-Type" }
|
||||
# append: false
|
||||
# - header: { key: "Content-Type", value: "text/html; charset=utf-8" }
|
||||
# append: false
|
||||
|
||||
# - match: { prefix: "/" } #(route.RouteMatch:R) inside "match" element, one of "prefix", "path", "regex" is required # inside "match" element, can also match headers with "headers" (route.HeaderMatcher) and query params with "query_parameters" (route.QueryParameterMatcher)
|
||||
# route: { cluster: casperNodes } #(route.routeAction) inside "route" element, one of "cluster", "cluster_header", "weighted_clusters" is required
|
||||
# http_filters: #([config.filter.network.http_connection_manager.v2.HttpFilter]) filter order does not appear to be significant
|
||||
# - name: envoy.grpc_json_transcoder #(string:R)
|
||||
# config: #(config.filter.http.transcoder.v2.GrpcJsonTranscoder) specific type depends on value of name field
|
||||
# proto_descriptor: casperMessageDescSet.pb #(string:R) name of file emitted by protoc using the --descriptor_set_out option
|
||||
# match_incoming_request_route: true #(bool) if false, match a fixed URL pattern determined by service and endpoint names in .proto file
|
||||
# # need additional steps when compiling the .proto file; see https://www.envoyproxy.io/docs/envoy/v1.7.1/configuration/http_filters/grpc_json_transcoder_filter
|
||||
# services: #([string]:R) one element per service in .proto file (which is also in the descriptor set file) that is to be exposed
|
||||
# - io.casperlabs.casper.protocol.DeployService
|
||||
# - name: envoy.router #(string:R)
|
||||
# # other options for elements of the "http_filters" array: envoy.grpc_web, envoy.grpc_http1_bridge, envoy.cors
|
||||
tls_context:
|
||||
common_tls_context:
|
||||
tls_certificates:
|
||||
- certificate_chain: { filename: "/etc/casper-envoy.crt" }
|
||||
private_key: { filename: "/etc/casper-envoy.key" }
|
||||
|
||||
clusters: #([Cluster])
|
||||
- name: casperNodes #(string:R)
|
||||
http2_protocol_options: { } #(core.Http2ProtocolOptions) this is required to make the upstream connection be http2 (required because it's grpc)
|
||||
connect_timeout: { seconds: 2 } #(Duration:R) this is a protobuf datatype
|
||||
hosts: #([core.Address]) this is deprecated in favor of ClusterLoadAssignment
|
||||
- socket_address: { address: 0.0.0.0, port_value: $GRPC_PORT } #([core.Address]:R if static) casper node port
|
||||
@@ -1,197 +0,0 @@
|
||||
---------- Creating Socket File ----------
|
||||
touch /.casperlabs/.casper-node.sock
|
||||
---------- Starting Execution Engine ----------
|
||||
/root/.cargo/bin/cargo run --bin casperlabs-engine-grpc-server /.casperlabs/.casper-node.sock &
|
||||
Compiling wasm-prep v0.1.0 (/CasperLabs/execution-engine/wasm-prep)
|
||||
Compiling shared v0.2.0 (/CasperLabs/execution-engine/shared)
|
||||
Compiling storage v0.1.0 (/CasperLabs/execution-engine/storage)
|
||||
Compiling execution-engine v0.1.0 (/CasperLabs/execution-engine/engine)
|
||||
Compiling casperlabs-engine-grpc-server v0.3.0 (/CasperLabs/execution-engine/comm)
|
||||
---------- Starting Node ----------
|
||||
./node/target/universal/stage/bin/casperlabs-node run --server-use-gossiping --server-data-dir /.casperlabs --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem -b "casperlabs://[email protected]?protocol=40400&discovery=40404" --server-host 35.192.61.54
|
||||
21:14:27.070 [main] INFO io.casperlabs.node.Main$ - CasperLabs node 0.3 (665e0c190bd7b6dcfbd912218a56c75daa45c67d)
|
||||
21:14:27.149 [main] INFO io.casperlabs.node.NodeEnvironment$ - Using data dir: /.casperlabs
|
||||
21:14:27.160 [main] INFO i.c.c.t.GenerateCertificateIfAbsent - No certificate found at path /.casperlabs/node.certificate.pem
|
||||
21:14:27.161 [main] INFO i.c.c.t.GenerateCertificateIfAbsent - Generating a X.509 certificate for the node
|
||||
21:14:27.165 [main] INFO i.c.c.t.GenerateCertificateIfAbsent - Generating a PEM secret key for the node
|
||||
21:14:28.150 [main] INFO io.casperlabs.comm.UPnP$ - trying to open ports using UPnP....
|
||||
Finished dev [unoptimized + debuginfo] target(s) in 26.01s
|
||||
Running `target/debug/casperlabs-engine-grpc-server /.casperlabs/.casper-node.sock`
|
||||
Server is listening on socket: /.casperlabs/.casper-node.sock
|
||||
21:14:37.247 [main] INFO io.casperlabs.comm.UPnP$ - INFO - No gateway devices found
|
||||
21:14:37.253 [main] INFO io.casperlabs.comm.UPnP$ - No need to open any port
|
||||
21:14:38.581 [main] WARN i.c.b.BlockDagFileStorage$ - CRC file /.casperlabs/dagstorage/latest-messages-crc did not contain a valid CRC value
|
||||
21:14:38.603 [main] WARN i.c.b.BlockDagFileStorage$ - CRC file /.casperlabs/dagstorage/block-metadata-crc did not contain a valid CRC value
|
||||
21:14:39.266 [main] INFO io.casperlabs.node.api.Servers$ - gRPC diagnostics service started on port 40402.
|
||||
21:14:39.570 [main] INFO io.casperlabs.node.api.Servers$ - gRPC deployment service started on port 40401.
|
||||
21:14:39.751 [main] INFO io.casperlabs.node.MetricsRuntime - No Influx configuration found
|
||||
21:14:39.763 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to InfluxDB disabled.
|
||||
21:14:39.764 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to Prometheus disabled.
|
||||
21:14:39.767 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to Zipkin disabled.
|
||||
21:14:39.769 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to JMX.
|
||||
21:14:39.790 [main] INFO kamon.metrics.SystemMetrics - Starting the Kamon(SystemMetrics) module
|
||||
21:14:40.047 [main] INFO io.casperlabs.node.api.Servers$ - HTTP server started on port 40403.
|
||||
21:14:42.558 [main] WARN i.casperlabs.casper.genesis.Genesis$ - Specified bonds file None does not exist. Falling back on generating random validators.
|
||||
21:14:42.661 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator 6d6cb8d21839956806a454a4a1dd5623ffc63df47d6e45156e8a81dcb0bd3763 with bond 2
|
||||
21:14:42.663 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator 8e8558f3c16379b9500a1f2472fcc62d337520211e0b0183400d8eae23223acc with bond 3
|
||||
21:14:42.664 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator 270af344e64ebc85f9f544d4e82b5fe138d2ea37c7faeb5a1c89153378b8d8a7 with bond 4
|
||||
21:14:42.665 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator 4d34b334b5b880129b9957ad3fb47e122f2077920dea4b2c7631f5e2fbbadcf6 with bond 1
|
||||
21:14:42.666 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator a02f382c265f74aa1e29bca63585979057d4d49e024ea5fc842a3d4425f674eb with bond 5
|
||||
21:14:42.674 [main] WARN i.c.casper.ValidatorIdentity$ - No private key detected, cannot create validator identification.
|
||||
21:14:42.679 [main] INFO i.c.node.casper.gossiping.package$ - Starting in default mode
|
||||
21:14:43.050 [main] INFO io.casperlabs.node.NodeRuntime - Starting node that will bootstrap from Node(<ByteString@5fc7255c size=20>,3.16.244.129,40400,40404)
|
||||
21:14:43.057 [main] INFO io.casperlabs.node.NodeRuntime - Listening for traffic on casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:14:44.668 [node-runner-28] INFO i.c.c.gossiping.GossipServiceServer - Received notification about 1 new blocks from casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:14:44.955 [node-runner-27] INFO i.c.node.casper.gossiping.package$ - Validating genesis-like block 3cc14fb755......
|
||||
21:14:45.071 [node-runner-27] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Attempting to add Block 3cc14fb755... to DAG.
|
||||
Effects applied. New state hash is: Blake2bHash([86, 34, 94, 200, 7, 200, 168, 251, 27, 186, 60, 15, 247, 221, 85, 229, 213, 163, 251, 227, 103, 100, 22, 220, 98, 40, 57, 16, 139, 74, 114, 76])
|
||||
21:14:45.663 [grpc-default-executor-1] WARN i.c.b.BlockDagFileStorage$ - Block 3cc14fb755e2c6f1641a436f0d91b11022132fccc19d7f92c75b6a23bfd2077b sender is empty
|
||||
21:14:45.758 [grpc-default-executor-1] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Added 3cc14fb755...
|
||||
21:14:45.780 [node-runner-28] INFO i.c.c.gossiping.GenesisApproverImpl - Downloaded Genesis candidate 3cc14fb755e2c6f1641a436f0d91b11022132fccc19d7f92c75b6a23bfd2077b from bootstrap.
|
||||
21:14:45.863 [node-runner-28] INFO i.c.c.gossiping.GenesisApproverImpl - Transitioned to approved genesis state.
|
||||
21:14:45.871 [node-runner-27] WARN i.c.casper.ValidatorIdentity$ - No private key detected, cannot create validator identification.
|
||||
21:14:45.953 [node-runner-27] WARN i.c.blockstorage.BlockDagFileStorage - Block 3cc14fb755e2c6f1641a436f0d91b11022132fccc19d7f92c75b6a23bfd2077b is already stored
|
||||
Effects applied. New state hash is: Blake2bHash([86, 34, 94, 200, 7, 200, 168, 251, 27, 186, 60, 15, 247, 221, 85, 229, 213, 163, 251, 227, 103, 100, 22, 220, 98, 40, 57, 16, 139, 74, 114, 76])
|
||||
21:14:45.971 [grpc-default-executor-1] INFO i.c.node.casper.gossiping.package$ - Making the transition to block processing.
|
||||
21:14:47.083 [node-runner-27] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Attempting to add Block 8c7b3bc30e... to DAG.
|
||||
Effects applied. New state hash is: Blake2bHash([31, 185, 249, 230, 239, 12, 212, 130, 82, 232, 85, 211, 102, 10, 52, 40, 81, 37, 234, 46, 108, 88, 124, 41, 85, 91, 79, 232, 105, 118, 121, 115])
|
||||
21:14:48.180 [grpc-default-executor-1] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Added 8c7b3bc30e...
|
||||
21:14:48.193 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New fork-choice tip is block 8c7b3bc30e....
|
||||
21:14:48.266 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Fault tolerance for block 8c7b3bc30e... is 1.0; threshold is 0.0
|
||||
21:14:48.276 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Removed 0 deploys from deploy history as we finalized block 8c7b3bc30e....
|
||||
21:14:48.278 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New last finalized block hash is 8c7b3bc30e....
|
||||
21:14:48.850 [node-runner-27] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Attempting to add Block 76de718919... to DAG.
|
||||
Effects applied. New state hash is: Blake2bHash([240, 60, 209, 207, 47, 122, 188, 166, 176, 167, 107, 94, 155, 72, 86, 79, 206, 144, 85, 101, 43, 236, 201, 93, 171, 165, 168, 134, 179, 218, 44, 191])
|
||||
21:14:49.419 [grpc-default-executor-1] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Added 76de718919...
|
||||
21:14:49.423 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New fork-choice tip is block 76de718919....
|
||||
21:14:49.425 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Fault tolerance for block 76de718919... is 1.0; threshold is 0.0
|
||||
21:14:49.447 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Removed 0 deploys from deploy history as we finalized block 76de718919....
|
||||
21:14:49.448 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New last finalized block hash is 76de718919....
|
||||
21:14:49.452 [node-runner-28] INFO i.c.c.gossiping.GossipServiceServer - Synced 3 blocks with casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:15:43.155 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Peers: 14
|
||||
21:15:43.159 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:15:43.160 [grpc-io-42] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:16:02.261 [node-runner-28] INFO i.c.c.gossiping.GossipServiceServer - Received notification about 1 new blocks from casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:16:03.058 [node-runner-27] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Attempting to add Block bf919a3f59... to DAG.
|
||||
Effects applied. New state hash is: Blake2bHash([221, 163, 169, 14, 202, 22, 191, 224, 165, 146, 40, 183, 166, 160, 240, 244, 21, 195, 24, 181, 137, 131, 90, 166, 93, 240, 145, 245, 2, 6, 156, 18])
|
||||
21:16:03.846 [grpc-default-executor-1] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Added bf919a3f59...
|
||||
21:16:03.850 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New fork-choice tip is block bf919a3f59....
|
||||
21:16:03.851 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Fault tolerance for block bf919a3f59... is 1.0; threshold is 0.0
|
||||
21:16:03.854 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Removed 0 deploys from deploy history as we finalized block bf919a3f59....
|
||||
21:16:03.855 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New last finalized block hash is bf919a3f59....
|
||||
21:16:04.589 [node-runner-28] INFO i.c.c.gossiping.GossipServiceServer - Synced 2 blocks with casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:16:43.488 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Peers: 19
|
||||
21:16:43.489 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:16:43.489 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:16:43.489 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:16:43.489 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:16:43.489 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:17:00.186 [node-runner-27] INFO i.c.c.gossiping.GossipServiceServer - Received notification about 1 new blocks from casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:17:05.898 [node-runner-27] INFO i.c.c.gossiping.GossipServiceServer - Received notification about 1 new blocks from casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:17:05.959 [node-runner-28] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Attempting to add Block 66c9ff93a4... to DAG.
|
||||
21:17:09.957 [node-runner-28] INFO i.c.c.gossiping.GossipServiceServer - Received notification about 1 new blocks from casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
Effects applied. New state hash is: Blake2bHash([124, 236, 165, 57, 229, 120, 35, 87, 21, 17, 235, 11, 114, 49, 157, 128, 111, 141, 75, 29, 167, 225, 219, 152, 255, 59, 163, 200, 42, 157, 5, 67])
|
||||
21:17:14.304 [grpc-default-executor-1] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Added 66c9ff93a4...
|
||||
21:17:14.306 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New fork-choice tip is block 66c9ff93a4....
|
||||
21:17:14.307 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Fault tolerance for block 66c9ff93a4... is 1.0; threshold is 0.0
|
||||
21:17:14.387 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - Removed 0 deploys from deploy history as we finalized block 66c9ff93a4....
|
||||
21:17:14.388 [grpc-default-executor-1] INFO i.c.casper.MultiParentCasperImpl - New last finalized block hash is 66c9ff93a4....
|
||||
21:17:17.070 [node-runner-27] INFO i.c.c.gossiping.GossipServiceServer - Synced 2 blocks with casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:17:17.071 [node-runner-28] INFO i.c.c.gossiping.GossipServiceServer - Synced 2 blocks with casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:17:17.071 [node-runner-27] INFO i.c.c.gossiping.GossipServiceServer - Synced 2 blocks with casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:17:35.002 [node-runner-27] INFO i.c.c.gossiping.GossipServiceServer - Received notification about 1 new blocks from casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:17:40.073 [node-runner-27] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Attempting to add Block ac7bb68813... to DAG.
|
||||
21:17:43.980 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Peers: 22
|
||||
21:17:43.981 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:17:43.981 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:17:43.983 [grpc-io-47] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
Effects applied. New state hash is: Blake2bHash([151, 65, 52, 109, 39, 68, 101, 89, 249, 95, 159, 254, 26, 102, 115, 200, 255, 121, 57, 94, 122, 136, 103, 46, 113, 193, 226, 154, 237, 76, 52, 20])
|
||||
21:17:54.270 [grpc-default-executor-4] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Added ac7bb68813...
|
||||
21:17:54.272 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - New fork-choice tip is block ac7bb68813....
|
||||
21:17:54.273 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - Fault tolerance for block ac7bb68813... is 1.0; threshold is 0.0
|
||||
21:17:54.365 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - Removed 0 deploys from deploy history as we finalized block ac7bb68813....
|
||||
21:17:54.366 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - New last finalized block hash is ac7bb68813....
|
||||
21:17:55.502 [node-runner-27] INFO i.c.c.gossiping.GossipServiceServer - Synced 2 blocks with casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:18:44.504 [grpc-io-48] INFO i.c.node.casper.gossiping.package$ - Peers: 26
|
||||
21:18:44.505 [grpc-io-48] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:18:44.505 [grpc-io-48] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:18:44.505 [grpc-io-48] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:18:44.505 [grpc-io-48] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:18:50.221 [node-runner-27] INFO i.c.c.gossiping.GossipServiceServer - Received notification about 1 new blocks from casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
21:19:19.080 [node-runner-27] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Attempting to add Block 1b63e98e17... to DAG.
|
||||
Effects applied. New state hash is: Blake2bHash([52, 107, 237, 204, 30, 210, 56, 97, 220, 248, 228, 13, 150, 114, 0, 235, 125, 144, 171, 6, 222, 77, 213, 24, 94, 8, 138, 74, 94, 181, 231, 101])
|
||||
21:19:38.413 [grpc-default-executor-4] INFO i.c.c.MultiParentCasperImpl$StatelessExecutor - Added 1b63e98e17...
|
||||
21:19:38.415 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - New fork-choice tip is block 1b63e98e17....
|
||||
21:19:38.415 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - Fault tolerance for block 1b63e98e17... is 1.0; threshold is 0.0
|
||||
21:19:38.669 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - Removed 0 deploys from deploy history as we finalized block 1b63e98e17....
|
||||
21:19:38.670 [grpc-default-executor-4] INFO i.c.casper.MultiParentCasperImpl - New last finalized block hash is 1b63e98e17....
|
||||
21:19:45.099 [grpc-io-41] INFO i.c.node.casper.gossiping.package$ - Peers: 28
|
||||
21:19:45.100 [grpc-io-41] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:19:45.100 [grpc-io-41] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:19:55.307 [node-runner-28] ERROR i.c.shared.UncaughtExceptionLogger$ - Uncaught Exception : Java heap space
|
||||
java.lang.OutOfMemoryError: Java heap space
|
||||
at java.base/java.util.Arrays.copyOfRange(Arrays.java:4030)
|
||||
at com.google.protobuf.ByteString$ArraysByteArrayCopier.copyFrom(ByteString.java:121)
|
||||
at com.google.protobuf.ByteString.copyFrom(ByteString.java:298)
|
||||
at com.google.protobuf.CodedInputStream$ArrayDecoder.readBytes(CodedInputStream.java:927)
|
||||
at io.casperlabs.casper.consensus.Deploy$Code.mergeFrom(Deploy.scala:537)
|
||||
at io.casperlabs.casper.consensus.Deploy$Code.mergeFrom(Deploy.scala:494)
|
||||
at scalapb.LiteParser$.readMessage(LiteParser.scala:15)
|
||||
at io.casperlabs.casper.consensus.Deploy$Body.mergeFrom(Deploy.scala:407)
|
||||
at io.casperlabs.casper.consensus.Deploy$Body.mergeFrom(Deploy.scala:366)
|
||||
at scalapb.LiteParser$.readMessage(LiteParser.scala:15)
|
||||
at io.casperlabs.casper.consensus.Deploy.mergeFrom(Deploy.scala:78)
|
||||
at io.casperlabs.casper.consensus.Deploy.mergeFrom(Deploy.scala:16)
|
||||
at scalapb.LiteParser$.readMessage(LiteParser.scala:15)
|
||||
at io.casperlabs.casper.consensus.Block$ProcessedDeploy.mergeFrom(Block.scala:760)
|
||||
at io.casperlabs.casper.consensus.Block$ProcessedDeploy.mergeFrom(Block.scala:700)
|
||||
at scalapb.LiteParser$.readMessage(LiteParser.scala:15)
|
||||
at io.casperlabs.casper.consensus.Block$Body.mergeFrom(Block.scala:522)
|
||||
at io.casperlabs.casper.consensus.Block$Body.mergeFrom(Block.scala:489)
|
||||
at scalapb.LiteParser$.readMessage(LiteParser.scala:15)
|
||||
at io.casperlabs.casper.consensus.Block.mergeFrom(Block.scala:78)
|
||||
at io.casperlabs.casper.consensus.Block.mergeFrom(Block.scala:16)
|
||||
at scalapb.LiteParser$.parseFrom(LiteParser.scala:9)
|
||||
at scalapb.GeneratedMessageCompanion.parseFrom(GeneratedMessageCompanion.scala:188)
|
||||
at scalapb.GeneratedMessageCompanion.parseFrom$(GeneratedMessageCompanion.scala:188)
|
||||
at io.casperlabs.casper.consensus.Block$.parseFrom(Block.scala:125)
|
||||
at scalapb.GeneratedMessageCompanion.parseFrom(GeneratedMessageCompanion.scala:204)
|
||||
at scalapb.GeneratedMessageCompanion.parseFrom$(GeneratedMessageCompanion.scala:204)
|
||||
at io.casperlabs.casper.consensus.Block$.parseFrom(Block.scala:125)
|
||||
at io.casperlabs.comm.gossiping.DownloadManagerImpl.$anonfun$fetchAndRestore$10(DownloadManager.scala:490)
|
||||
at io.casperlabs.comm.gossiping.DownloadManagerImpl$$Lambda$2212/0x0000000840b21440.apply(Unknown Source)
|
||||
at cats.effect.Sync.$anonfun$delay$1(Sync.scala:54)
|
||||
at cats.effect.Sync$$Lambda$1167/0x0000000840583840.apply(Unknown Source)
|
||||
21:20:45.484 [grpc-io-51] INFO i.c.node.casper.gossiping.package$ - Peers: 29
|
||||
21:20:45.484 [grpc-io-51] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:22:47.951 [node-runner-28] INFO i.c.node.casper.gossiping.package$ - Peers: 30
|
||||
21:22:47.951 [node-runner-28] INFO i.c.node.casper.gossiping.package$ - Disconnected from casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:22:47.951 [node-runner-28] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:22:47.952 [node-runner-28] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:23:48.132 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Peers: 32
|
||||
21:23:48.133 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:23:48.133 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:24:48.706 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Peers: 37
|
||||
21:24:48.707 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:24:48.707 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:24:48.707 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:24:48.707 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:24:48.707 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:25:48.899 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Peers: 40
|
||||
21:25:48.900 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:25:48.900 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:25:48.900 [grpc-io-56] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:26:49.093 [grpc-io-55] INFO i.c.node.casper.gossiping.package$ - Disconnected from casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
21:26:49.093 [grpc-io-55] INFO i.c.node.casper.gossiping.package$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
cat /envoy/envoyConfigTemplate.yaml | envsubst \$GRPC_PORT > /envoy/envoyConfig.yaml
|
||||
envoy $@
|
||||
@@ -1,136 +0,0 @@
|
||||
---------- Creating Socket File ----------
|
||||
touch /.casperlabs/.casper-node.sock
|
||||
---------- Starting Execution Engine ----------
|
||||
/root/.cargo/bin/cargo run --bin casperlabs-engine-grpc-server /.casperlabs/.casper-node.sock &
|
||||
Compiling wasm-prep v0.1.0 (/CasperLabs/execution-engine/wasm-prep)
|
||||
Compiling shared v0.2.0 (/CasperLabs/execution-engine/shared)
|
||||
Compiling storage v0.1.0 (/CasperLabs/execution-engine/storage)
|
||||
Compiling execution-engine v0.1.0 (/CasperLabs/execution-engine/engine)
|
||||
Compiling casperlabs-engine-grpc-server v0.2.0 (/CasperLabs/execution-engine/comm)
|
||||
---------- Starting Node ----------
|
||||
./node/target/universal/stage/bin/casperlabs-node run --server-data-dir /.casperlabs --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem -b "casperlabs://[email protected]?protocol=40400&discovery=40404" --server-host 104.197.47.175
|
||||
18:38:21.876 [main] INFO io.casperlabs.node.Main$ - CasperLabs node 0.2 (cb4e6b941646630d7ad6c40d44790177a0e07ce0)
|
||||
18:38:21.954 [main] INFO io.casperlabs.node.NodeEnvironment$ - Using data dir: /.casperlabs
|
||||
18:38:21.964 [main] INFO i.c.c.t.GenerateCertificateIfAbsent - No certificate found at path /.casperlabs/node.certificate.pem
|
||||
18:38:21.965 [main] INFO i.c.c.t.GenerateCertificateIfAbsent - Generating a X.509 certificate for the node
|
||||
18:38:21.969 [main] INFO i.c.c.t.GenerateCertificateIfAbsent - Generating a PEM secret key for the node
|
||||
18:38:22.764 [main] INFO io.casperlabs.comm.UPnP$ - trying to open ports using UPnP....
|
||||
Finished dev [unoptimized + debuginfo] target(s) in 26.47s
|
||||
Running `target/debug/casperlabs-engine-grpc-server /.casperlabs/.casper-node.sock`
|
||||
Server is listening on socket: /.casperlabs/.casper-node.sock
|
||||
18:38:31.847 [main] INFO io.casperlabs.comm.UPnP$ - INFO - No gateway devices found
|
||||
18:38:31.854 [main] INFO io.casperlabs.comm.UPnP$ - No need to open any port
|
||||
18:38:33.300 [main] WARN i.c.b.BlockDagFileStorage$ - CRC file /.casperlabs/dagstorage/latest-messages-crc did not contain a valid CRC value
|
||||
18:38:33.317 [main] WARN i.c.b.BlockDagFileStorage$ - CRC file /.casperlabs/dagstorage/block-metadata-crc did not contain a valid CRC value
|
||||
18:38:33.949 [main] INFO io.casperlabs.node.api.Servers$ - gRPC diagnostics service started on port 40402.
|
||||
18:38:34.196 [main] INFO io.casperlabs.node.api.Servers$ - gRPC deployment service started on port 40401.
|
||||
18:38:34.305 [main] INFO io.casperlabs.node.MetricsRuntime - No Influx configuration found
|
||||
18:38:34.315 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to InfluxDB disabled.
|
||||
18:38:34.316 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to Prometheus disabled.
|
||||
18:38:34.319 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to Zipkin disabled.
|
||||
18:38:34.346 [main] INFO io.casperlabs.node.MetricsRuntime - Reporting metrics to JMX.
|
||||
18:38:34.368 [main] INFO kamon.metrics.SystemMetrics - Starting the Kamon(SystemMetrics) module
|
||||
18:38:34.583 [main] INFO io.casperlabs.node.api.Servers$ - HTTP server started on port 40403.
|
||||
18:38:34.847 [main] INFO i.c.c.util.comm.CasperPacketHandler$ - Starting in default mode
|
||||
18:38:36.055 [main] WARN i.casperlabs.casper.genesis.Genesis$ - Specified bonds file None does not exist. Falling back on generating random validators.
|
||||
18:38:36.160 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator 31d18ab029bd224e03449812a827bb5245be70d5753633a50bb2adfe62c062fa with bond 2
|
||||
18:38:36.163 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator b2633edf0f22a398919636e13470c0b683d0ecccf4f3b3a256dca1b58ad1b7ee with bond 5
|
||||
18:38:36.165 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator e1539a1330f2aa4873f75008d47710e8001a621e5a7489616aaba724ba22d71b with bond 4
|
||||
18:38:36.167 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator c9c2e73d33efcc660b7818539117f2ee35b6758656d88f1d588e90fe71725122 with bond 1
|
||||
18:38:36.169 [main] INFO i.casperlabs.casper.genesis.Genesis$ - Created validator bfab3c7f6915bd1d53dff14a03a14c8fe7dcb73675ea20e17b4bb5a9d746226e with bond 3
|
||||
18:38:36.179 [main] WARN i.c.casper.ValidatorIdentity$ - No private key detected, cannot create validator identification.
|
||||
18:38:38.945 [node-runner-27] INFO i.c.node.casper.transport.package$ - Started transport layer on port 40400.
|
||||
18:38:38.968 [node-runner-27] INFO io.casperlabs.node.NodeRuntime - Starting node that will bootstrap from Node(<ByteString@15e12420 size=20>,13.59.27.228,40400,40404)
|
||||
18:38:39.050 [node-runner-27] INFO io.casperlabs.node.NodeRuntime - Listening for traffic on casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:43:40.552 [tl-dispatcher-49] INFO io.casperlabs.comm.rp.Connect$ - Peers: 1.
|
||||
18:43:40.554 [tl-dispatcher-49] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@7160cad size=20>,104.197.68.103,40400,40404)
|
||||
18:43:51.251 [tl-dispatcher-49] INFO io.casperlabs.comm.rp.Connect$ - Peers: 2.
|
||||
18:43:51.252 [tl-dispatcher-49] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@4691a044 size=20>,34.92.13.52,40400,40404)
|
||||
18:43:51.510 [tl-dispatcher-49] INFO io.casperlabs.comm.rp.Connect$ - Peers: 3.
|
||||
18:43:51.510 [tl-dispatcher-49] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@28d61774 size=20>,34.92.187.128,40400,40404)
|
||||
18:43:54.363 [tl-dispatcher-49] INFO io.casperlabs.comm.rp.Connect$ - Peers: 4.
|
||||
18:43:54.364 [tl-dispatcher-49] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@45e28b92 size=20>,35.238.5.230,40400,40404)
|
||||
18:43:56.217 [tl-dispatcher-50] INFO io.casperlabs.comm.rp.Connect$ - Peers: 5.
|
||||
18:43:56.218 [tl-dispatcher-50] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@31be876a size=20>,35.220.156.128,40400,40404)
|
||||
18:43:57.256 [tl-dispatcher-49] INFO io.casperlabs.comm.rp.Connect$ - Peers: 6.
|
||||
18:43:57.256 [tl-dispatcher-49] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@5d9759ed size=20>,34.65.187.48,40400,40404)
|
||||
18:44:00.977 [tl-dispatcher-50] INFO io.casperlabs.comm.rp.Connect$ - Peers: 7.
|
||||
18:44:00.978 [tl-dispatcher-50] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@499edb0f size=20>,35.224.146.19,40400,40404)
|
||||
18:44:01.407 [tl-dispatcher-50] INFO io.casperlabs.comm.rp.Connect$ - Peers: 8.
|
||||
18:44:01.408 [tl-dispatcher-50] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@60dacc47 size=20>,104.154.233.240,40400,40404)
|
||||
18:44:01.595 [tl-dispatcher-50] INFO io.casperlabs.comm.rp.Connect$ - Peers: 9.
|
||||
18:44:01.596 [tl-dispatcher-50] INFO i.casperlabs.comm.rp.HandleMessages$ - Responded to protocol handshake request from Node(<ByteString@251a92e1 size=20>,34.65.138.196,40400,40404)
|
||||
18:44:03.648 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 10.
|
||||
18:44:03.649 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:04.586 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 11.
|
||||
18:44:04.587 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:04.610 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 12.
|
||||
18:44:04.610 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:04.634 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 13.
|
||||
18:44:04.635 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:04.659 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 14.
|
||||
18:44:04.659 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:05.246 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 15.
|
||||
18:44:05.246 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:06.284 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 16.
|
||||
18:44:06.285 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:06.312 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 17.
|
||||
18:44:06.312 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:06.413 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 18.
|
||||
18:44:06.414 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:06.996 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 19.
|
||||
18:44:06.997 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:07.158 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 20.
|
||||
18:44:07.159 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:07.205 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 21.
|
||||
18:44:07.205 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:07.789 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 22.
|
||||
18:44:07.789 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:08.656 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 23.
|
||||
18:44:08.656 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:09.521 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 24.
|
||||
18:44:09.522 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:10.467 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 25.
|
||||
18:44:10.467 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:11.885 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 26.
|
||||
18:44:11.886 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:12.525 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Peers: 27.
|
||||
18:44:12.526 [node-runner-26] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:12.699 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Peers: 28.
|
||||
18:44:12.699 [node-runner-27] INFO io.casperlabs.comm.rp.Connect$ - Connected to casperlabs://[email protected]?protocol=40400&discovery=40404.
|
||||
18:44:41.409 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:45:53.574 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:47:05.349 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:48:15.581 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:49:25.075 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:50:35.248 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:51:44.983 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:52:55.376 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:54:06.962 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:55:16.591 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:56:27.085 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:57:36.475 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:58:46.973 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
18:59:57.855 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:01:07.544 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:02:17.281 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:13:29.901 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:13:29.965 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
19:14:09.650 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:14:09.746 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
19:14:16.786 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:14:16.786 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
19:15:04.276 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
19:15:04.276 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:15:14.278 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:15:16.275 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:15:40.252 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:15:44.996 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:15:51.418 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
19:15:51.418 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:15:56.115 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:15:56.186 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
19:16:39.641 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:16:39.642 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
19:17:25.774 [node-runner-27] WARN i.c.casper.MultiParentCasperRef$ - Could not show blocks.. Casper instance was not available yet.
|
||||
19:17:25.774 [node-runner-26] WARN i.c.casper.MultiParentCasperRef$ - Could not visualize graph.. Casper instance was not available yet.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
FROM gcr.io/hanzo-ai/casper-env:latest
|
||||
RUN apt-get install dnsutils telnet wget iputils-ping -y
|
||||
COPY scripts/ scripts
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# echo "---------- Starting Execution Engine ----------"
|
||||
# cd /CasperLabs/execution-engine
|
||||
# $HOME/.cargo/bin/cargo run --bin casperlabs-engine-grpc-server /.casperlabs/.casper-node.sock &
|
||||
|
||||
# echo "---------- Start Bootstrapping Node ----------"
|
||||
# cd /CasperLabs
|
||||
# ./node/target/universal/stage/bin/casperlabs-node run -s --server-data-dir /.casperlabs &
|
||||
# while ! [ -s /.casperlabs/genesis/bonds.txt ]; do
|
||||
# sleep 5
|
||||
# done
|
||||
# sleep 5
|
||||
# echo "---------- Finish Bootstrapping Node ----------"
|
||||
# killall -9 java
|
||||
# sleep 5
|
||||
echo "---------- Creating Socket File ----------"
|
||||
|
||||
echo "touch /.casperlabs/.casper-node.sock"
|
||||
touch /.casperlabs/.casper-node.sock
|
||||
|
||||
echo "---------- Starting Execution Engine ----------"
|
||||
cd /CasperLabs/execution-engine
|
||||
|
||||
echo "$HOME/.cargo/bin/cargo run --bin casperlabs-engine-grpc-server /.casperlabs/.casper-node.sock &"
|
||||
$HOME/.cargo/bin/cargo run --bin casperlabs-engine-grpc-server /.casperlabs/.casper-node.sock &
|
||||
|
||||
sleep 30
|
||||
|
||||
echo "---------- Starting Node ----------"
|
||||
cd /CasperLabs
|
||||
|
||||
# KEY_FILE=$(find /.casperlabs -type f -name *.sk | sort | tail -n 1 | head -n 1)
|
||||
# CL_VALIDATOR_PUBLIC_KEY=$(echo "$KEY_FILE" | awk -F '[/.]' '{print $(NF-1)}')
|
||||
# CL_VALIDATOR_PRIVATE_KEY=$(cat "$KEY_FILE")
|
||||
|
||||
# echo "./node/target/universal/stage/bin/casperlabs-node run --server-data-dir /.casperlabs --casper-validator-public-key $CL_VALIDATOR_PUBLIC_KEY --casper-validator-private-key $CL_VALIDATOR_PRIVATE_KEY --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem --server-host 0.0.0.0 $@"
|
||||
# ./node/target/universal/stage/bin/casperlabs-node run --server-data-dir /.casperlabs --casper-validator-public-key $CL_VALIDATOR_PUBLIC_KEY --casper-validator-private-key $CL_VALIDATOR_PRIVATE_KEY --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem --server-host 0.0.0.0 $@
|
||||
|
||||
# echo "./node/target/universal/stage/bin/casperlabs-node run --server-data-dir /.casperlabs --casper-validator-public-key 4387a0089d7cbf53493d39923bc182a17edfd70279fdfbd992e97073ffd62bfb --casper-validator-private-key e08d66a68ea53857a61abfd998fb9f741e62f1390788bc3a1dbb0190665bbc3d --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem -b \"casperlabs://[email protected]?protocol=40400&discovery=40404\" --server-host $EXTERNAL_IP"
|
||||
# ./node/target/universal/stage/bin/casperlabs-node run --server-data-dir /.casperlabs --casper-validator-public-key 4387a0089d7cbf53493d39923bc182a17edfd70279fdfbd992e97073ffd62bfb --casper-validator-private-key e08d66a68ea53857a61abfd998fb9f741e62f1390788bc3a1dbb0190665bbc3d --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem -b "casperlabs://[email protected]?protocol=40400&discovery=40404" --server-host $EXTERNAL_IP
|
||||
|
||||
echo "./node/target/universal/stage/bin/casperlabs-node run --server-use-gossiping --server-data-dir /.casperlabs --casper-validator-public-key 27525108e2fb7df7fb9a9d64883081e5e51a2946aac79b000e77a60429058576 --casper-validator-private-key 976a47bfe27a3e15eec5e76763f076d51215bf5e9f3f76dff9dd5fdcf6064252 --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem -b \"casperlabs://[email protected]?protocol=40400&discovery=40404\" --server-host $EXTERNAL_IP $PORTS"
|
||||
./node/target/universal/stage/bin/casperlabs-node run --server-use-gossiping --server-data-dir /.casperlabs --casper-validator-public-key 27525108e2fb7df7fb9a9d64883081e5e51a2946aac79b000e77a60429058576 --casper-validator-private-key 976a47bfe27a3e15eec5e76763f076d51215bf5e9f3f76dff9dd5fdcf6064252 --tls-certificate /.casperlabs/node.certificate.pem --tls-key /.casperlabs/node.key.pem -b "casperlabs://[email protected]?protocol=40400&discovery=40404" --server-host $EXTERNAL_IP $PORTS
|
||||
@@ -1,45 +0,0 @@
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURDekNDQWZPZ0F3SUJBZ0lRRDBxMjZqb0F5WEdMbzQzNXJsK3UyREFOQmdrcWhraUc5dzBCQVFzRkFEQXYKTVMwd0t3WURWUVFERXlSa1pHUmtNek0xTUMxbFl6VTNMVFJrT1RJdE9EQXdaUzA1TnpZMVkySmtaalUwWVRVdwpIaGNOTVRrd05ESXlNVFV6T1RJM1doY05NalF3TkRJd01UWXpPVEkzV2pBdk1TMHdLd1lEVlFRREV5UmtaR1JrCk16TTFNQzFsWXpVM0xUUmtPVEl0T0RBd1pTMDVOelkxWTJKa1pqVTBZVFV3Z2dFaU1BMEdDU3FHU0liM0RRRUIKQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURPTkM0QzRYbGxIVWpjdjhnMkt4V0owYUg2cDcxb2x6bGI5SlQyeFFZRApkV0szZEgvOGJGdEptam5kbExuamdpaGh2allQMzR3NFk0OFZjODhya3Y0UDBoRERLK0RFeTVGeklaMWc3OUVqCnlwcWVQT3VsWFpBNW9vSXArYUU0OTJiSnRseVBIamttR296aVpjWmsyWXdIMFA0WDFVaDQzMFJuS1h0eTVFbEsKNzhWcWMxWlVHaThSWUZYV3JKczZaNmd2Wk15Wm0rUXNBRVFXVkFhMHNUbExEZ1Jrd3NpNnRWN1NlVFQycWw1NwoyMGZiREdqaFJUQ1Zuei9SUGRCYUJQV05obk1yazNyYUZlNGpvUitQTjVCejE1cDVObFlZN29qdldqWG00TTRNCmhkbkw5dHlZa0UraHNBdVZTM0JSUSttdmtRVU1zOEE3S3RkYml6dXdHNUlQQWdNQkFBR2pJekFoTUE0R0ExVWQKRHdFQi93UUVBd0lDQkRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFBbgpqdndmbWFyMEREWUtkd3BjWDE1WHNUUnJBU1JWdnFqOEZLZ0pkQVU2SVA5azFDaDlSREcvT0Npc2UycXVoVk9SCmhtVXBzMTVXRHZzK05sZmZJZE1GR1czT0daMHlhd1FucXRxeWtLNFhsaSszQUg1RHFEdUFJQlF1OHNTQnVUbjgKNUFOUDlLaHdUdjVHYjBlSjRNSEtlOTYrRTVwOXBIL3crY0VXRlM3VlRnM285eGlwR0Eya2lKV3VPQ2dMb0VvWgpVYlFGY2d2SHJnTkVhOEtlTHY2a0tNa3h2Y3BHUnpSam8yWi9hREZVZG9aWDJsOWJ2dGV6OENUdzlSeXV1SW1nCmd5Z0xEU2F4dy9QWnZGMXNyZVZUY0Q0T21sa1FLdFROS09QaG9oWEFGSXNKN3UvQjlnbUtmN1BMamQzcURVUEoKUmY1L0hvWVVDRkt0c0szUGJtdDkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
server: https://35.184.239.41
|
||||
name: gke_hanzo-ai_us-central1-a_casper-testnet
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURERENDQWZTZ0F3SUJBZ0lSQUt1TkNnZEQwYVFSSlpIOUlMS3VrY1F3RFFZSktvWklodmNOQVFFTEJRQXcKTHpFdE1Dc0dBMVVFQXhNa1lXRTFaVGswWXpFdE9EZGtNeTAwWkdVMExUaGxaV010TnpsaE1tSTFaRE0wTmpWaApNQjRYRFRFNE1EUXdNakl4TkRRME5sb1hEVEl6TURRd01USXlORFEwTmxvd0x6RXRNQ3NHQTFVRUF4TWtZV0UxClpUazBZekV0T0Rka015MDBaR1UwTFRobFpXTXROemxoTW1JMVpETTBOalZoTUlJQklqQU5CZ2txaGtpRzl3MEIKQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBd0RWU01JTDBjVGt6bThWd1pnSDhTc3NRNFdWdWUyQXRHcGRicTV6VQpBRlBMWHFpUXFKUHVPUzBlYkt6WVhIYzlWMXdHdkg0M2phWnF2UXFNb1NMMlZRZzZTRGpaTDdVdmVYbUhxRUthCm9oV0VySGl2Nmp6TnBiYm1pRVQ5WEYzNDByTVVsUm5Pa25oY1VzWU9SWEhDdDRIZHNUUkR5NjhPUXRmdmx2RmsKei96UlpteHdFNFZYK1NIOVlRZ1ZVUUZBTExKVlNCSjBuZkpYczdlZUgrblNKMVp4TlVKTVZnbTZyQ3BsUzZtdQpyNUw2U2VpRWZpeGFmbGUyTTNlZXRWa3Q1cHZQL2lPckQ5VXV3ZW01ZWVXTGZPQ0RHcnk5RndqaFMvbUZIUXFtCjBBUnpySW1VSDdDemRReWhDTXdNLzNrZFBkMWZwbVVCRnUzOVExK0kyZVFpUFFJREFRQUJveU13SVRBT0JnTlYKSFE4QkFmOEVCQU1DQWdRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQQpHWW5IbGRjZ281VEpNVnNCeGw5bWlKZnJiaHAxUDExV1NFVkhraVdTY0lGc3U5Z3puNnRHOVZnQXZkK1pkT21zCmVJOHBHYXlkMmtqNGVCd1psaHRsMXYydytPR2dWSTA3U3Z0V2pTV0N0RGNaUTRYSGNTTTk4TGxKeCsySDkvRW4KMktUa0VBWG01Q1MyL3IrQ3QrZ1h5cld1bmJKYTRpa3FMNkNDTGlOdk1jbngzd0Fjc3BmK0hxd09kTjVNcWI0NAppRG1RTDVHejFVcGRCY010a20rOVdZdGRLZTNZQ2NqaWNPRXhTbUNjY2pzOGhMNXB0YWkxbXNMYngwZ1BGMElECmFRZTF2VE00SmNVeGd1cHhOcUxDaVo3TG1aejhob0s3K0d6RkptbSs0MHBCay9mSEo3OW05c0lFN1FrTXREeHAKYzlNRGdlSWRsTWxSRndWRzdBSTdQZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
|
||||
server: https://35.188.203.215
|
||||
name: gke_hanzo-ai_us-central1-a_ethereum
|
||||
contexts:
|
||||
- context:
|
||||
cluster: gke_hanzo-ai_us-central1-a_casper-testnet
|
||||
user: gke_hanzo-ai_us-central1-a_casper-testnet
|
||||
name: gke_hanzo-ai_us-central1-a_casper-testnet
|
||||
- context:
|
||||
cluster: gke_hanzo-ai_us-central1-a_ethereum
|
||||
user: gke_hanzo-ai_us-central1-a_ethereum
|
||||
name: gke_hanzo-ai_us-central1-a_ethereum
|
||||
current-context: gke_hanzo-ai_us-central1-a_casper-testnet
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: gke_hanzo-ai_us-central1-a_casper-testnet
|
||||
user:
|
||||
auth-provider:
|
||||
config:
|
||||
access-token: ya29.Gl0ZB_FfCtyxOWCcfYgQ5IWIX3T2lsRa7jjtrBnU6Eq7fMDr_-PesAFtQnbrUTwkM8YirDdtvaYhLWsZPANNXYKi8-57gaXSXw9ENAj8-es1ynL4KlJUA_gZ6HnpMIg
|
||||
cmd-args: config config-helper --format=json
|
||||
cmd-path: /usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin/gcloud
|
||||
expiry: 2019-05-29T22:35:06Z
|
||||
expiry-key: '{.credential.token_expiry}'
|
||||
token-key: '{.credential.access_token}'
|
||||
name: gcp
|
||||
- name: gke_hanzo-ai_us-central1-a_ethereum
|
||||
user:
|
||||
auth-provider:
|
||||
config:
|
||||
access-token: ya29.GlzzBi8pofXKitZvlwuzKKT5e9XcNmM4RAOQ8v9C67Kic54hhJBCUpluIdsD-NV6lDOqupt2fPC0IeYDUbjRgmDaR_oNnTuleGNwGYXsov9w9vx82cge-OOHqxWO9A
|
||||
cmd-args: config config-helper --format=json
|
||||
cmd-path: /usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin/gcloud
|
||||
expiry: 2019-04-22 16:53:11
|
||||
expiry-key: '{.credential.token_expiry}'
|
||||
token-key: '{.credential.access_token}'
|
||||
name: gcp
|
||||
@@ -1,13 +0,0 @@
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: gce-ssd-sc
|
||||
allowVolumeExpansion: true
|
||||
reclaimPolicy: Retain
|
||||
mountOptions:
|
||||
- discard
|
||||
provisioner: kubernetes.io/gce-pd
|
||||
parameters:
|
||||
type: pd-ssd
|
||||
zones: us-central1-a
|
||||
fsType: ext4
|
||||
@@ -1,7 +0,0 @@
|
||||
apiVersion: v1
|
||||
type: kubernetes.io/dockercfg
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: gcr-secret
|
||||
data:
|
||||
.dockercfg: eyJodHRwczovL2djci5pbyI6eyJhdXRoIjoiWDJwemIyNWZhMlY1T25zS0lDQWlkSGx3WlNJNklDSnpaWEoyYVdObFgyRmpZMjkxYm5RaUxBb2dJQ0p3Y205cVpXTjBYMmxrSWpvZ0ltaGhibnB2TFdGcElpd0tJQ0FpY0hKcGRtRjBaVjlyWlhsZmFXUWlPaUFpWm1RME9UQTNOVGhpTWpKak1ESTFObVZsWWpBM056VTROemRqTTJWaE1UazBOamRqT1dRME55SXNDaUFnSW5CeWFYWmhkR1ZmYTJWNUlqb2dJaTB0TFMwdFFrVkhTVTRnVUZKSlZrRlVSU0JMUlZrdExTMHRMVnh1VFVsSlJYWlJTVUpCUkVGT1FtZHJjV2hyYVVjNWR6QkNRVkZGUmtGQlUwTkNTMk4zWjJkVGFrRm5SVUZCYjBsQ1FWRkROVGhSZVN0ME9ITnRibTR4TTF4dVlYVm9TalpZVG1WbmFsVlhhblY2Um1nclQwZEdkUzlwTlRjNFVGcEViV0UxT1VWQ2MwSklTRWRVTTA5aFkxRlVRalUwYkdwUU4wczRWRU5wTUVoVmVGeHVORWxuWVZGNGFucEROVzVHYUZGNE9TOVRlak5FVVdkRWFrcHFVM041Y0ZKMGJYa3diVEJWV0VoT2ExWkdWek55U25ScVVXczVTMmx1ZFZaUVFucFJSMXh1Y0c4MlRHUmxUakpHU1VsQ1FtSm1TRlp0UldWSlZEVTFORzUyVGs4eVVsZE5TVmxoYjA0dlMwbHNNVGxUYVdONmFXbHdMemxCT1ZBeUx5dE1ZbmR5VEZ4dWMwTm9hMmg1V0dsWVUwWXhSWFIyTkhCcU5ITk9VelZpZGs1VE9HVkxVQzlHVEdRMk1EQkVibGxCVVhScGRHRm5PVzByVDJzMmVqTnhXRWhOYkZCNE0xeHVhWGswYTA0dksyTlhWVmhCZVhoS1VVUjRaVVZoVTFwSlNGSlBOWE56ZEVVMlkyOUpaR1JTVW1Ndk1FaEVaRGhCY1c5bmJ6TmlkbEJUVEZSNk5FOHZZbHh1TDJzNE5VNTFlRTVCWjAxQ1FVRkZRMmRuUlVGRVdqWnVhV2hYTjJkd1puQk1MMVJYVlVoU1UwNVlVMUZ3VW1OalNuQlBTMVI1WVhOSU1uVnFRMHRLTDF4dWNXZFpiV0ZXUWxOQ2JDOVJhSFZrTkRSUU1tZGpRMGRKWjNCUmJUbGFiMU13YVM5bVQzWkRVR0ZrTVhGUUwyWTNjV0UyUVdob1ZWWk5WVmxJUlV0ak4xeHVNR3A1VnpoR1F6WlFNbXM0WXpjMmJURXdRVTU0Y2pSUFoydGxOa2N4Ym1nclNuTlRZMFl2VjNvMFRrMDBRMk5uTUZKeGNUVnJabFp0V0VoR1VHVkVOMXh1TnpkSGJFRnpUMWhXYUcxRFkycE9OVEV2Y0M5c0x5dDZObGR6WkdsNk1tZG1TVk5DYWsxdFVtTmplbTFsWlVGNk0ySlFaM0JKT1VwdlVVOWxha0kwUjF4dU4wOHZkRE5uZUU0NGRISkxaazVWTVRoeFUzUlJNRnB3ZUhsbFZuRnNXRUZDWmxncmJGZE9WM294YVVoc2RtbHZPRWRMUTBsb1FrUlNOMjUxTld0VGIxeHViMkZPY0ZkQ1owMVRaRXhPV2pkS0wya3JVRmxQYkRkTmRXbGllV05oY1dkTFZIcFZaakF3VlVWUlMwSm5VVVJqVTJwTVVtc3JXaXRhU2pJelZrdHlNbHh1Ym5BclUwWjZkVFJUVUdSWFJVc3lRMVl3Vm5wNkswTlhkVGRPWnk5VGVXSlVabkZxUzJ0MlVVWjZOMkZUZDJoRGNrMVNkWGszYzBWcE0wTlRhMWN6UVZ4dVoyMTFOMnhSZUZCb1ZFSTJSRmRDVnpoUVNUWmxXaTlUZDB4WmExUlNTQ3M1TUROSFJIbG5TVXBRTDNGTmVVOVRNR3R2YXpGT1MxZFZVWGRtTldSbllWeHVZbWR4UzBjellrcEtXVGhKV2pWek5qUk5OMEV3YWtaQkwxRkxRbWRSUkZsR1Z6bFBablF5VTJOalEwTkZhRVpzVEhoMGFra3lXWFlyV21NemNWWnFibHh1VVVsNk1EUXlhM0puUVVZclkxRjJTbTVaY2psaGJWVnRORTlTVnpWM2FXZGxNemRrUm5jNFNFbG5OVEJPYWpKcVRYZFRVV0Z1Y0RnemFFMTNlbVJQWjF4dVp6bFFkbVZTWkRoeFRFTjRXUzgzVm14TE5rRlNMemxJVWl0VldDOU5NMHRGUlRsVVFpdEVZVWhYYkd0NVRqUklaR3BvVFVoVVduVmlXbk5OYjBoeWNseHViMDVFTlZsMGNXaHJVVXRDWjBVMldUZHhOMWRJVm5kc1dFSjRiMU5wVGpaRWVXTmFkMUZaVFdseGMySm5hbnBMUmtrMmQzTmpiekpMUm1SSWJsb3lMMXh1TkdSb1RIQkJZMWc1UTFsQmRGYzNUVzgzTWtGV1ZHSlhOVnBDTVRoUWJrcDZkRkkzTlc5MVRUQjJTVXBUWTBaaVkwdEhjV1ZZY2tKd1dITnZVVWMxTDF4dVNVUkhNV2RMZGk5UU5IWTFUMUV3VDIxTlQzaGFNekpaV2pCSlQxTk9LMDVQV21SNlIzaDJSRzFrWmlzeE1sUllhSGN4U0UxaGJXeEJiMGRCU2tGbWRWeHVPVE5tVVVkdmN6bFFiazFyTURKd00yUnhRMEZsV2prd2VEWk9SbGc0YjNwMGRVZ3dkRE4zZDNjMVV6SkZibWhwY0V3NFNTOTFTMmhOU25neGJ6aDZlbHh1Tm05dVpIZzJTekpLYTNGc1NFbEdNVlZXT1hZM1ZVcGhhMDVxUWxsU1MyRldSMUZ6ZEcxNWNXbGxibE53UjNGWFltMHlVemcxTDFwWk5XRlVLMmN5WlZ4dVRFbHZlbmhEYzBSV0wzSnRhWFptTjJsNlYxUjZabGxaTVVwSmREZFFlSG96UTBoUWMzZEZRMmRaUlVGckswdFJiV2d4TldOSVFrNUhWbWN5VTBsMmMxeHVkRkpLT1RVMFprVnpTVlJ6YW5SSWNqQklNVk53WTJKUE5HWmxVRWw1TlZCeFUwb3ZjMUJwY0RBM1pubEdWRm8xZFVaelNVTXpOSEZKWVcxcU5UUm9jbHh1VjBoUmEyVkRWSFpvUzBGV1VISkVNWGc0VUc5SE9XUnJiRlIzYnpWNVMzbG5lWGRhV1ZKcFJGcEJjVzFYUkRKallrVXJUMkZOUmpCcGNDczJVVXhLVjF4dVdqaEpiRmRDZW5KT1ZraHFLMkl6Y21SR2MycFFkM2M5WEc0dExTMHRMVVZPUkNCUVVrbFdRVlJGSUV0RldTMHRMUzB0WEc0aUxBb2dJQ0pqYkdsbGJuUmZaVzFoYVd3aU9pQWlhR0Z1ZW04dFoyTnlRR2hoYm5wdkxXRnBMbWxoYlM1bmMyVnlkbWxqWldGalkyOTFiblF1WTI5dElpd0tJQ0FpWTJ4cFpXNTBYMmxrSWpvZ0lqRXdNamM1T0RNNE5UUTROamsyT1RBM056WTBNU0lzQ2lBZ0ltRjFkR2hmZFhKcElqb2dJbWgwZEhCek9pOHZZV05qYjNWdWRITXVaMjl2WjJ4bExtTnZiUzl2TDI5aGRYUm9NaTloZFhSb0lpd0tJQ0FpZEc5clpXNWZkWEpwSWpvZ0ltaDBkSEJ6T2k4dllXTmpiM1Z1ZEhNdVoyOXZaMnhsTG1OdmJTOXZMMjloZFhSb01pOTBiMnRsYmlJc0NpQWdJbUYxZEdoZmNISnZkbWxrWlhKZmVEVXdPVjlqWlhKMFgzVnliQ0k2SUNKb2RIUndjem92TDNkM2R5NW5iMjluYkdWaGNHbHpMbU52YlM5dllYVjBhREl2ZGpFdlkyVnlkSE1pTEFvZ0lDSmpiR2xsYm5SZmVEVXdPVjlqWlhKMFgzVnliQ0k2SUNKb2RIUndjem92TDNkM2R5NW5iMjluYkdWaGNHbHpMbU52YlM5eWIySnZkQzkyTVM5dFpYUmhaR0YwWVM5NE5UQTVMMmhoYm5wdkxXZGpjaVUwTUdoaGJucHZMV0ZwTG1saGJTNW5jMlZ5ZG1salpXRmpZMjkxYm5RdVkyOXRJZ3A5IiwiZW1haWwiOiJub3RAdmFsLmlkIn19Cg==
|
||||
@@ -1,34 +0,0 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y install autoconf \
|
||||
automake \
|
||||
bsdmainutils \
|
||||
build-essential \
|
||||
curl \
|
||||
g++-multilib \
|
||||
git \
|
||||
iputils-ping \
|
||||
libc6-dev \
|
||||
libtool \
|
||||
m4 \
|
||||
ncurses-dev \
|
||||
pkg-config \
|
||||
python \
|
||||
python-software-properties \
|
||||
screen \
|
||||
software-properties-common \
|
||||
sysstat \
|
||||
unzip \
|
||||
vim \
|
||||
wget \
|
||||
zlib1g-dev
|
||||
|
||||
RUN add-apt-repository ppa:longsleep/golang-backports
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y install golang-go
|
||||
|
||||
# Build geth
|
||||
COPY scripts/ scripts
|
||||
RUN ./scripts/build.sh
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
curl -H "Content-Type: application/json" --data "{\"jsonrpc\":\"2.0\",\"method\":\"net_version\",\"params\":[],\"id\":67}" localhost:8545
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Clone geth repo
|
||||
git clone https://github.com/ethereum/go-ethereum
|
||||
cd go-ethereum
|
||||
git checkout v1.8.18
|
||||
|
||||
make geth
|
||||
|
||||
# Make sure geth is on $PATH
|
||||
ln -s /go-ethereum/build/bin/geth /bin/geth
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"type": "service_account",
|
||||
"project_id": "hanzo-ai",
|
||||
"private_key_id": "377249f3876e0a98fc53567a2b7fcaef2410871c",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDVJbSXW5nYYr8M\njD2rERV6U7kgXmmy+6pjl2W6UGgMdhncZmnHDrvG7Ww/g7xI3H+Dy1HbmAQAbnKl\nTji+4bONAMeFZowbjPLoqMkz+svjVOteJ8HdPswUkj2lGP4VZj7ViP1qoFCHp5T8\nk4q4zHisvJfsvJCv2YmfffgSSN8U3eIhFm7oFa0d0ATN1ey1B7rQ60T/8/2fczRl\nxjU76uDpmOVGWp5yk05uqlmuwjeD9HstgbP4/EcSJt8QnftIYoznLhw5ZDIF38VS\nBnt1LrNOKb8wgD9jF+tILVyFCW/2UG9Jii+F3ETkmej/rSiyV2ZKHJKKBvsTTjL5\n1e0D6Tf1AgMBAAECggEAAtictn/M2hrXcyE4tusr7Oo81wskli3qjzVwjPk8HDkn\nflwlEBy6soBtjLgDYkk9r/1IX23XxvKWKcNcvbpvlnPANkrqekAlWOGIGO2XD9Ni\nBMEs7fmZIrKExKcoVkqXq0+c+ccSPf16318zpwFlvOUwrpgicSFZnKgKZqJTW8/y\npXfd10X3MEQ3YWa2I9XzbIPOGl3tv6LYL8Qv5IVHCOGggLQlMjxtMtS7nJ4FKGub\n01WqYh6FwtDheYpezz3SMZa1L49cLo+lXtbq33HLnjnsG0X8eavimWj21+Vg8QRM\nWjR4Y3CZIGa3Uhy/MPEnDQBU3EBft2Z7/2hUGmXWgQKBgQD4Wqbb4U+MMAlSw240\n6xX59gk2GvqQEdUhukIe3q0PgH1Gs4WZwGpep8hxvWV67n7Bzv3G2dJHA1kK6ZN7\nRCnn7H4cbQo6gxlOz0QJY4Mf7pPbTmpgpr0fE5iPZ7HXQ12WksnNtvNyb5mNW6y4\n/W+wcXiktPIgXVGBLq9ZzmcLfQKBgQDbtZQuQZjxeGqeMffHbPT11HpR/zpm2s2U\nklBPn7oc1oRlmFz6ghmADQu014gpmk5jN9rLQC7YiB2SslUoC3KZ+Hk7M68SgxXs\nGPkSNPgJ8OHJZnqTTAvMm0p9CJrUU0jn+TVqzjsWCFrMxYae7Z8Ir5sxh58R50Tm\nKAQiVp1X2QKBgQDHpL/bo+y5aegkwvt1yME61gCjoN5pMByf50W94Q1Hl+edDTVJ\n2rbnboMgg7rvLodxLv8see+irFtI/WlUPwBc8uyR10nQrZCLnOw5i+hdpADx28CB\n/6eqMquCJD5/KCU0pL1bBEYBaRsL2nUnpHvDYAQ2i0rUn4+khC3ryJNnVQKBgF6/\nMUW5WCFZ0nCiD75aiFCy7oUJ0b+lP96AMk4EDZh+Ed5WFFKbZC/KcG/uOnPmbUNw\nRNQ9u3X5TPeEHCEGvscTVgRnx2nuSbflFRP677QpwtS9csKumrADj93Xph1GRTx0\nRcrnYKehtrZzwBgtVNXEFOMJH1nzJ80xGIdOXtARAoGAZ7PmX5y3FwXETHCNUoPa\nb0dn2S4FTWGiKgpUtG3fNxj1siLsUtIEKMcO/M70OU3r52tWkfcV8bZy5ocn33DA\npBgqrR+xBH9jX6QLqNRCMMJkjpHg3rUoLbgwVXrHRrDjmMiKzYKcqgo6ekpmsTsN\nM/JKc+H8t9hfyQ3VFbLoc7A=\n-----END PRIVATE KEY-----\n",
|
||||
"client_email": "[email protected]",
|
||||
"client_id": "117525766487983735449",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/pull-images-from-registry%40hanzo-ai.iam.gserviceaccount.com"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
from waitress import serve
|
||||
from app import app
|
||||
|
||||
serve(app, host='0.0.0.0', port=80)
|
||||
@@ -1,157 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import argparse
|
||||
from bootnode import Bootnode, complete
|
||||
|
||||
|
||||
def run_command(cmd, args):
|
||||
# Get argument names
|
||||
keys = [k for k in dir(args) if not k.startswith('_') and not k == 'command']
|
||||
|
||||
# Create kwargs from args specified
|
||||
kwargs = dict(map(lambda k: (k, getattr(args, k)), keys))
|
||||
|
||||
# Clear out any default args that are unspecified
|
||||
kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
||||
|
||||
bootnode = Bootnode(args.chain, args.network, args.zone)
|
||||
|
||||
del kwargs['chain']
|
||||
del kwargs['network']
|
||||
del kwargs['zone']
|
||||
|
||||
# Call relevant method on Bootnode
|
||||
getattr(bootnode, cmd)(**kwargs)
|
||||
|
||||
|
||||
def parser():
|
||||
parser = argparse.ArgumentParser(description='Cluster management commands')
|
||||
parser.add_argument('--chain', help='Blockchain')
|
||||
parser.add_argument('--network', help='Blockchain network')
|
||||
parser.add_argument('--zone', help='Cluster zone')
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# Disks
|
||||
create_disk = subparsers.add_parser('create-disk', help='Create disk')
|
||||
create_disk.add_argument('snapshot', help='Name of snapshot to use as source')
|
||||
create_disk.add_argument('name', help='Name of disk')
|
||||
create_disk.set_defaults(command='create_disk')
|
||||
|
||||
get_disk = subparsers.add_parser('disk', help='Get disk')
|
||||
get_disk.add_argument('name', help='Name of disk')
|
||||
get_disk.set_defaults(command='get_disk')
|
||||
|
||||
list_disks = subparsers.add_parser('disks', help='List disks')
|
||||
list_disks.set_defaults(command='list_disks')
|
||||
|
||||
get_last_disk = subparsers.add_parser('last-disk', help='Get last disk')
|
||||
get_last_disk.set_defaults(command='get_last_disk')
|
||||
|
||||
# Snapshots
|
||||
get_snapshot = subparsers.add_parser('snapshot', help='Get snapshot')
|
||||
get_snapshot.add_argument('name', help='Name of snapshot')
|
||||
get_snapshot.set_defaults(command='get_snapshot')
|
||||
|
||||
list_snapshots = subparsers.add_parser('snapshots', help='List snapshots')
|
||||
list_snapshots.set_defaults(command='list_snapshots')
|
||||
|
||||
get_last_snapshot = subparsers.add_parser('last-snapshot', help='Get last snapshot')
|
||||
get_last_snapshot.set_defaults(command='get_last_snapshot')
|
||||
|
||||
snapshot_pod = subparsers.add_parser('snapshot-pod', help='Snapshot pod')
|
||||
snapshot_pod.add_argument('name', help='Pod to snapshot')
|
||||
snapshot_pod.set_defaults(command='snapshot_pod')
|
||||
|
||||
snapshot_disk = subparsers.add_parser('snapshot-disk', help='Snapshot disk')
|
||||
snapshot_disk.add_argument('name', help='Disk to snapshot')
|
||||
snapshot_disk.set_defaults(command='snapshot_disk')
|
||||
|
||||
update_snapshot = subparsers.add_parser('update-snapshot', help='Update snapshot for a given network')
|
||||
update_snapshot.add_argument('network', help='Network to snapshot')
|
||||
update_snapshot.set_defaults(command='update_snapshot')
|
||||
|
||||
# Pods
|
||||
create_pod = subparsers.add_parser('create-pod', help='Create pod')
|
||||
create_pod.set_defaults(command='create_pod')
|
||||
|
||||
delete_pod = subparsers.add_parser('delete-pod', help='Delete pod')
|
||||
delete_pod.add_argument('name', help='Name of pod')
|
||||
delete_pod.set_defaults(command='delete_pod')
|
||||
|
||||
list_pods = subparsers.add_parser('pods', help='List pods')
|
||||
list_pods.set_defaults(command='list_pods')
|
||||
|
||||
get_pod = subparsers.add_parser('pod', help='Get pod')
|
||||
get_pod.add_argument('name', help='Name of pod')
|
||||
get_pod.set_defaults(command='get_pod')
|
||||
|
||||
get_last_pod = subparsers.add_parser('last-pod', help='Last pod')
|
||||
get_last_pod.set_defaults(command='get_last_pod')
|
||||
|
||||
last_parser = subparsers.add_parser('synced-pod', help='Get any synced pod')
|
||||
last_parser.set_defaults(command='get_synced_pod')
|
||||
|
||||
get_block_number = subparsers.add_parser('block-number', help='Get block number for pod')
|
||||
get_block_number.add_argument('name', help='Name of pod')
|
||||
get_block_number.set_defaults(command='get_block_number')
|
||||
|
||||
# Deployments
|
||||
create_deployment = subparsers.add_parser('create-deployment', help='Create deployment')
|
||||
create_deployment.set_defaults(command='create_deployment')
|
||||
|
||||
delete_deployment = subparsers.add_parser('delete-deployment', help='Delete deployment')
|
||||
delete_deployment.add_argument('name', help='Name of deployment')
|
||||
delete_deployment.set_defaults(command='delete_deployment')
|
||||
|
||||
list_deployments = subparsers.add_parser('deployments', help='List deployments')
|
||||
list_deployments.set_defaults(command='list_deployments')
|
||||
|
||||
get_deployment = subparsers.add_parser('deployment', help='Get deployment')
|
||||
get_deployment.add_argument('name', help='Name of deployment')
|
||||
get_deployment.set_defaults(command='get_deployment')
|
||||
|
||||
get_last_deployment = subparsers.add_parser('last-deployment', help='Last deployment')
|
||||
get_last_deployment.set_defaults(command='get_last_deployment')
|
||||
|
||||
# Clusters
|
||||
create_cluster = subparsers.add_parser('create-cluster', help='Create a new cluster')
|
||||
create_cluster.set_defaults(command='create_cluster')
|
||||
|
||||
delete_cluster = subparsers.add_parser('delete-cluster', help='Delete a cluster')
|
||||
delete_cluster.set_defaults(command='delete_cluster')
|
||||
|
||||
list_clusters = subparsers.add_parser('clusters', help='List clusters')
|
||||
list_clusters.set_defaults(command='list_clusters')
|
||||
|
||||
get_cluster = subparsers.add_parser('cluster', help='Get cluster')
|
||||
get_cluster.set_defaults(command='get_cluster')
|
||||
|
||||
# Load balancers
|
||||
create_load_balancer = subparsers.add_parser('create-load-balancer', help='Create a new load_balancer')
|
||||
create_load_balancer.set_defaults(command='create_load_balancer')
|
||||
|
||||
# Scale up
|
||||
scale_up = subparsers.add_parser('scale-up', help='Scale up blockchain nodes')
|
||||
scale_up.add_argument('network', help='Network to scale')
|
||||
scale_up.set_defaults(command='scale_up')
|
||||
|
||||
# Scale down
|
||||
scale_down = subparsers.add_parser('scale-down', help='Scale down blockchain nodes')
|
||||
scale_down.add_argument('network', help='Network to scale')
|
||||
scale_down.set_defaults(command='scale_down')
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = parser()
|
||||
complete(sys.argv, parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
cmd = args.command
|
||||
except AttributeError:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
run_command(cmd, args)
|
||||
@@ -1,32 +0,0 @@
|
||||
# Legacy Bootnode Dependencies
|
||||
# NOTE: Consider migrating to the modern FastAPI version in /api/ instead
|
||||
|
||||
# Core web framework
|
||||
quart>=0.19.0
|
||||
quart-cors>=0.7.0
|
||||
hypercorn>=0.16.0
|
||||
|
||||
# Environment variables
|
||||
python-dotenv>=1.0.0
|
||||
|
||||
# Database
|
||||
pymongo>=4.6.0
|
||||
|
||||
# HTTP client
|
||||
httpx>=0.26.0 # Modern replacement for requests_async
|
||||
|
||||
# Kubernetes
|
||||
kubernetes>=29.0.0
|
||||
kubernetes_asyncio>=29.0.0
|
||||
|
||||
# Google Cloud
|
||||
google-api-python-client>=2.0.0
|
||||
google-auth-httplib2>=0.2.0
|
||||
google-cloud-container>=2.30.0
|
||||
|
||||
# Utilities
|
||||
tabulate>=0.9.0
|
||||
protobuf>=4.25.0
|
||||
|
||||
# Security notice: This is the legacy app
|
||||
# Consider migrating to the modern FastAPI version in /api/
|
||||
@@ -1,2 +0,0 @@
|
||||
from .json import jsonify
|
||||
from .convert import to_nodes
|
||||
@@ -1,48 +0,0 @@
|
||||
def to_nodes(deployments, services, pods, zone):
|
||||
nodes_by_id = {}
|
||||
nodes = []
|
||||
for d in deployments:
|
||||
try:
|
||||
nodes_by_id[d['name']] = len(nodes)
|
||||
|
||||
nodes.append({
|
||||
'blockchain': d['blockchain'],
|
||||
'network': d['network'],
|
||||
'id': d['name'],
|
||||
'instances': [],
|
||||
'zone': zone,
|
||||
})
|
||||
except Exception as e:
|
||||
print('warning: skipping invalid deployment ' + str(d) + ': ' + str(e))
|
||||
|
||||
for s in services:
|
||||
try:
|
||||
i = nodes_by_id.get(s['name'])
|
||||
|
||||
if i is not None:
|
||||
nodes[i]['ip'] = s['ip']
|
||||
nodes[i]['ports'] = s['ports']
|
||||
else:
|
||||
print('{0} does not exist'.format(s['name']))
|
||||
except Exception as e:
|
||||
print('warning: skipping invalid service ' + str(s) + ': ' + str(e))
|
||||
|
||||
for p in pods:
|
||||
try:
|
||||
i = nodes_by_id.get('{0}-{1}-{2}'.format(p['blockchain'], p['network'], p['number']))
|
||||
|
||||
if i is not None:
|
||||
nodes[i]['instances'].append({
|
||||
'name': p['name'],
|
||||
'status': p['status'],
|
||||
})
|
||||
|
||||
if nodes[i]['ip'] == '':
|
||||
nodes[i]['ip'] = p['ip']
|
||||
else:
|
||||
print('{0} does not exist'.format(p['name']))
|
||||
except Exception as e:
|
||||
print('warning: skipping invalid pod ' + str(p) + ': ' + str(e))
|
||||
|
||||
return nodes
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import json
|
||||
import datetime
|
||||
from quart import Response
|
||||
|
||||
def default(o):
|
||||
if isinstance(o, (datetime.date, datetime.datetime)):
|
||||
return o.isoformat()
|
||||
|
||||
def jsonify(obj):
|
||||
return Response(json.dumps(obj, indent = 2, separators = (', ', ': '), default=default),
|
||||
content_type='application/json')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user