diff --git a/packages/cosmic-swingset/Makefile b/packages/cosmic-swingset/Makefile
index 20e633cbae8..90c8889ffbd 100644
--- a/packages/cosmic-swingset/Makefile
+++ b/packages/cosmic-swingset/Makefile
@@ -135,7 +135,7 @@ scenario3-run:
cd t3 && ../bin/ag-solo start
docker-pull:
- for f in '' -pserver -setup -setup-solo -solo; do \
+ for f in '' -setup -solo; do \
docker pull $(REPOSITORY)$$f:latest || exit $$?; \
done
@@ -191,21 +191,6 @@ set-local-gci-ingress:
../../bin/ag-solo set-gci-ingress --chainID=$(CHAIN_ID) $$gci $$rpcport); \
done
-install-pserver:
- python3 -mvenv ve3
- ve3/bin/pip install -U setuptools wheel
- ve3/bin/pip install --editable ./provisioning-server
-
-run-pserver:
- ve3/bin/ag-pserver --listen tcp:8001 --controller tcp:localhost:8002
-
-install-setup-client:
- python3 -mvenv ve3-client
- ve3-client/bin/pip install -U setuptools wheel
- ve3-client/bin/pip install --editable ./setup-solo
-run-setup-client:
- ve3-client/bin/ag-setup-solo
-
###############################################################################
### Protobuf ###
###############################################################################
diff --git a/packages/cosmic-swingset/docker/ag-pserver b/packages/cosmic-swingset/docker/ag-pserver
deleted file mode 100755
index 024022e32ab..00000000000
--- a/packages/cosmic-swingset/docker/ag-pserver
+++ /dev/null
@@ -1,16 +0,0 @@
-#! /bin/sh
-PORT=8001
-TTY=-i
-test -t 0 && test -t 1 && TTY=-it
-
-case "$1" in
---pull)
- shift
- docker pull agoric/cosmic-swingset-pserver
- ;;
-esac
-
-exec docker run -p127.0.0.1:$PORT:$PORT \
- --volume=ag-pserver-state:/root/.ag-pserver \
- --rm $TTY \
- agoric/cosmic-swingset-pserver ${1+"$@"}
diff --git a/packages/cosmic-swingset/provisioning-server/.dockerignore b/packages/cosmic-swingset/provisioning-server/.dockerignore
deleted file mode 100644
index 2e0b6ac5bf0..00000000000
--- a/packages/cosmic-swingset/provisioning-server/.dockerignore
+++ /dev/null
@@ -1,3 +0,0 @@
-src/ag_pserver/__pycache__
-src/ag_pserver/ag_pserver.egg-info
-Dockerfile
diff --git a/packages/cosmic-swingset/provisioning-server/Dockerfile b/packages/cosmic-swingset/provisioning-server/Dockerfile
deleted file mode 100644
index f2090da0e38..00000000000
--- a/packages/cosmic-swingset/provisioning-server/Dockerfile
+++ /dev/null
@@ -1,18 +0,0 @@
-FROM debian:buster AS build
-
-RUN apt-get update -y && apt-get install gcc python3 python3-venv python3-dev -y && apt-get clean -y
-
-WORKDIR /usr/src/app
-RUN python3 -mvenv ve3
-RUN ve3/bin/pip install --upgrade pip
-RUN ve3/bin/pip install wheel
-COPY . provisioning-server/
-RUN ve3/bin/pip install provisioning-server/
-
-FROM debian:buster AS install
-
-WORKDIR /usr/src/app
-RUN apt-get update -y && apt-get install python3 -y && apt-get clean -y
-COPY --from=build /usr/src/app/ve3/ /usr/src/app/ve3/
-
-ENTRYPOINT ["ve3/bin/ag-pserver"]
diff --git a/packages/cosmic-swingset/provisioning-server/bin/ag-pserver.py b/packages/cosmic-swingset/provisioning-server/bin/ag-pserver.py
deleted file mode 100644
index 6b954a02345..00000000000
--- a/packages/cosmic-swingset/provisioning-server/bin/ag-pserver.py
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env python
-
-# see ../setup.py for installation instructions
diff --git a/packages/cosmic-swingset/provisioning-server/setup.py b/packages/cosmic-swingset/provisioning-server/setup.py
deleted file mode 100644
index 33854ea904c..00000000000
--- a/packages/cosmic-swingset/provisioning-server/setup.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-
-# run:
-# python3 -mvenv ../ve3
-# ../ve3/bin/pip install wheel
-# ../ve3/bin/pip install --editable .
-# ../ve3/bin/ag-pserver --listen tcp:8001 --controller tcp:localhost:8002
-
-# the provisioning webpage is in html/index.html , edit it in place
-
-from setuptools import setup
-import os
-setup(
- name="ag-pserver",
- description="provisioning server for Agoric testnet",
- license="MIT",
- package_dir={"": "src"},
- packages=["ag_pserver"],
- package_data={"ag_pserver": ['html/*']},
- install_requires=[
- "twisted[tls]",
- "magic-wormhole",
- "treq",
- ],
- entry_points={
- "console_scripts": [ "ag-pserver = ag_pserver.main:main" ],
- },
- include_package_data=True,
- version="0.2.0",
- )
-
diff --git a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/__init__.py b/packages/cosmic-swingset/provisioning-server/src/ag_pserver/__init__.py
deleted file mode 100644
index 8b137891791..00000000000
--- a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/index.html b/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/index.html
deleted file mode 100644
index d74710965d8..00000000000
--- a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/index.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-Agoric Testnet Provisioning Page
-
-
-
-Welcome to the Agoric Testnet
-
-On this page you can obtain a code to provision your client node.
-
-Type your nickname into this box and press the button to obtain a provisioning code. Then run ag-setup-solo [BASEDIR] and type the code into the prompt.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/response-template.html b/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/response-template.html
deleted file mode 100644
index 0c67e403a9c..00000000000
--- a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/response-template.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-Agoric Testnet Provisioning Page
-
-
-
-Provision Your Client Node
-
-The provisioning code for $$$NICKNAME$$$
- is: $$$CODE$$$
-
-
-
-Now run the following command and enter the provisioning code when asked:
-
-
-$ ag-setup-solo [BASEDIR]
-
-
-Then just follow the instructions. Thank you for provisioning an Agoric
-Testnet Client Node!
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/styles.css b/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/styles.css
deleted file mode 100644
index fcf5d40ea9e..00000000000
--- a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/html/styles.css
+++ /dev/null
@@ -1,3 +0,0 @@
-span.provisioning-code {
- color: #f00;
-}
diff --git a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/main.py b/packages/cosmic-swingset/provisioning-server/src/ag_pserver/main.py
deleted file mode 100644
index 8e1483c5c75..00000000000
--- a/packages/cosmic-swingset/provisioning-server/src/ag_pserver/main.py
+++ /dev/null
@@ -1,502 +0,0 @@
-from twisted.internet.task import react, deferLater
-from twisted.web import static, resource, server
-from twisted.web.template import Element, XMLFile, renderer, flattenString
-from twisted.internet import endpoints, defer, protocol
-from twisted.python import usage
-import wormhole
-import os.path
-import os
-import json
-import random
-import re
-from tempfile import NamedTemporaryFile
-
-from twisted.python import log
-import sys
-log.startLogging(sys.stdout)
-
-MAILBOX_URL = u"ws://relay.magic-wormhole.io:4000/v1"
-#MAILBOX_URL = u"ws://10.0.2.24:4000/v1"
-APPID = u"agoric.com/ag-testnet1/provisioning-tool"
-
-htmldir = os.path.join(os.path.dirname(__file__), "html")
-
-class SetConfigOptions(usage.Options):
- pass
-
-class AddPubkeysOptions(usage.Options):
- optParameters = [
- ["controller", "c", "NONE", "DEPRECATED"],
- ]
-
-class StartOptions(usage.Options):
- optParameters = [
- ["mountpoint", "m", "/", "controller's top level web page"],
- ["listen", "l", "tcp:8001", "client-visible HTTP listening port"],
- ["controller", "c", "NONE", "DEPRECATED"],
- ]
-
-class Options(usage.Options):
- subCommands = [
- ['set-cosmos-config', None, SetConfigOptions, "Pipe output of 'ag-setup-cosmos show-config' to this command"],
- ['set-cosmos-genesis', None, SetConfigOptions, "Pipe output of 'ag-setup-cosmos show-genesis' to this commmand"],
- ['add-pubkeys', None, AddPubkeysOptions, 'Add public keys from saved database'],
- ['start', None, StartOptions, 'Start the HTTP server'],
- ]
- optParameters = [
- ["home", None, os.path.join(os.environ["HOME"], '.ag-pserver'), "provisioning-server's state directory"],
- ['initial-token', 'T', 'NONE', "DEPRECATED"],
- ]
-
-class SendInputAndWaitProtocol(protocol.ProcessProtocol):
- def __init__(self, d, input):
- self.deferred = d
- self.input = input
- self.output = b''
- self.error = b''
-
- def connectionMade(self):
- self.transport.write(self.input)
- self.transport.closeStdin()
-
- def outReceived(self, data):
- self.output += data
- print(data.decode('latin-1'))
-
- def errReceived(self, data):
- self.error += data
- print(data.decode('latin-1'), file=sys.stderr)
-
- def processEnded(self, reason):
- self.deferred.callback((reason.value.exitCode, self.output, self.error))
-
-class StackedResource(resource.Resource):
- def __init__(self, stack):
- super().__init__()
- self.stack = [super(), *stack]
-
- def getChildWithDefault(self, *args):
- for s in self.stack:
- res = s.getChildWithDefault(*args)
- if not isinstance(res, resource.NoResource):
- return res
- return res
-
-def wwwroot(home):
- return os.path.join(home, 'wwwroot')
-
-def cosmosConfigFile(home):
- return os.path.join(wwwroot(home), 'current', 'chain.json')
-
-def cosmosGenesisFile(home):
- return os.path.join(wwwroot(home), 'current', 'genesis.json')
-
-def pubkeyDatabase(home):
- return os.path.join(home, 'pubkeys.jsona')
-
-class ConfigElement(Element):
- loader = XMLFile(os.path.join(htmldir, "index.html"))
-
- @staticmethod
- def gatherArgs(opts):
- meta = {}
- with open(cosmosConfigFile(opts['home'])) as f:
- config = f.read()
- gr = '/usr/src/app/lib/git-revision.txt'
- if os.path.exists(gr):
- with open(gr) as f:
- meta['package_git'] = f.read().strip()
- else:
- with os.popen('git rev-parse --short HEAD') as f:
- sha = f.read().strip()
- with os.popen('git diff --quiet || echo -dirty') as f:
- meta['package_git'] = sha + f.read().strip()
-
- pj = '/usr/src/app/package.json'
- pjson = {}
- if os.path.exists(pj):
- with open(pj) as f:
- pjson = json.load(f)
- else:
- pjpath = None
- # Walk upwards from the current directory.
- pj = os.path.abspath('package.json')
- while pj != pjpath:
- pjpath = pj
- if os.path.exists(pjpath):
- with open(pjpath) as f:
- pjson = json.load(f)
- break
- pj = os.path.join(os.path.dirname(pjpath), '../package.json')
- pj = os.path.abspath(pj)
-
- meta['package_version'] = pjson.get('version', 'unknown')
- meta['package_name'] = pjson.get('name', 'cosmic-swingset')
- repo = pjson.get('repository', 'https://github.com/Agoric/cosmic-swingset')
- cleanRev = meta['package_git'].replace('-dirty', '')
- link = repo + '/commit/' + cleanRev
- meta['package_repo'] = link
-
- return [config, meta]
-
- def __init__(self, config, meta):
- self._config = config
- self._meta = meta
-
- @renderer
- def config(self, request, tag):
- tag.fillSlots(cosmos_config=self._config)
- return tag
-
- @renderer
- def meta(self, request, tag):
- tag.fillSlots(**self._meta)
- return tag
-
-class ResponseElement(ConfigElement):
- loader = XMLFile(os.path.join(htmldir, "response-template.html"))
-
- def __init__(self, code, nickname, *args):
- super().__init__(*args)
- self._code = code
- self._nickname = nickname
-
- @renderer
- def code(self, request, tag):
- return self._code
-
- @renderer
- def nickname(self, request, tag):
- return self._nickname
-
-class Provisioner(resource.Resource):
- def __init__(self, reactor, o):
- self.reactor = reactor
- self.opts = o
-
- @defer.inlineCallbacks
- def build_page(self):
- with open(cosmosConfigFile(self.opts['home'])) as f:
- config = f.read()
-
- args = ConfigElement.gatherArgs(self.opts)
- html = yield flattenString(None, ConfigElement(*args))
- return html
-
- def render_GET(self, req):
- d = self.build_page()
- def built(response):
- req.write(response)
- req.finish()
- d.addCallback(built)
- d.addErrback(log.err)
- return server.NOT_DONE_YET
-
-
-@defer.inlineCallbacks
-def enablePubkey(reactor, opts, config, nickname, pubkey):
- mobj = {
- "type": "pleaseProvision",
- "nickname": nickname,
- "pubkey": pubkey,
- }
- # print("mobj:", mobj)
- def ret(server_message):
- return [mobj, server_message, config]
-
- args = [
- 'tx', 'swingset', 'provision-one', '--keyring-backend=test', nickname, pubkey,
- '--from=ag-solo', '--yes', '--broadcast-mode=block', # Don't return until committed.
- '--gas=auto', '--gas-adjustment=1.4',
- ]
- code, output = yield agCosmosHelper(reactor, opts, config, args, 10)
- if code != 0:
- return ret({"ok": False, "error": 'transfer returned ' + str(code)})
-
- ingressIndex = 1
- # this message is sent back to setup-solo/src/ag_setup_solo/main.py
- server_message = {
- "ok": True,
- "gci": config['gci'],
- "rpcAddrs": config['rpcAddrs'],
- "chainName": config['chainName'],
- "ingressIndex": ingressIndex,
- }
- print("send server_message", server_message)
- return ret(server_message)
-
-
-class RequestCode(resource.Resource):
- def __init__(self, reactor, o):
- self.reactor = reactor
- self.opts = o
-
- @defer.inlineCallbacks
- def got_message(self, client_message, nickname):
- cm = json.loads(client_message.decode("utf-8"))
- with open(cosmosConfigFile(self.opts['home'])) as f:
- config = json.loads(f.read())
-
- msgs = yield enablePubkey(self.reactor, self.opts, config, nickname, cm['pubkey'])
- return msgs
-
- def send_provisioning_response(self, msgs, w):
- [mobj, server_message, config] = msgs
- sm = json.dumps(server_message).encode("utf-8")
- print("send provisioning response", server_message)
- w.send_message(sm)
- d = w.close()
- def complete(_):
- print("provisioning complete")
- pkobj = {
- 'chainName': config['chainName'],
- 'pubkey': mobj['pubkey'],
- 'nickname': mobj['nickname'][:32],
- }
- print("save public key to database", pkobj)
- pkobj_str = json.dumps(pkobj)
- with open(pubkeyDatabase(self.opts['home']), 'a') as db:
- db.write(pkobj_str + ',\n')
- d.addCallbacks(complete,
- lambda f: print("provisioning error", f))
-
- @defer.inlineCallbacks
- def process_wormhole(self, nickname):
- w = wormhole.create(APPID, MAILBOX_URL, self.reactor)
- w.allocate_code()
- code = yield w.get_code()
-
- d = w.get_message()
- d.addCallback(self.got_message, nickname.decode('utf-8'))
- d.addCallback(self.send_provisioning_response, w)
- return code
-
- @defer.inlineCallbacks
- def build_provisioning_response(self, nickname):
- code = yield self.process_wormhole(nickname)
- args = ConfigElement.gatherArgs(self.opts)
- html = yield flattenString(None, ResponseElement(code, nickname, *args))
- return html
-
- def render_POST(self, req):
- nickname = req.args[b"nickname"][0]
- print(nickname)
- d = self.build_provisioning_response(nickname)
- def built(response):
- req.write(response)
- req.finish()
- d.addCallback(built)
- d.addErrback(log.err)
- return server.NOT_DONE_YET
-
- def render_GET(self, req):
- nickname = req.args[b"nickname"][0]
- d = self.process_wormhole(nickname)
- def built(code):
- req.setHeader('Content-Type', 'text/plain; charset=UTF-8')
- req.write((code + '\n').encode('utf-8'))
- req.finish()
- d.addCallback(built)
- d.addErrback(log.err)
- return server.NOT_DONE_YET
-
-class GenesisJSON(resource.Resource):
- def __init__(self, o):
- self.opts = o
-
- def render_GET(self, req):
- with open(cosmosGenesisFile(self.opts['home'])) as f:
- config = f.read()
- req.setHeader('Content-Type', 'application/json')
- return config.encode('utf-8')
-
-class ConfigJSON(resource.Resource):
- def __init__(self, o):
- self.opts = o
-
- def render_GET(self, req):
- with open(cosmosConfigFile(self.opts['home'])) as f:
- config = f.read()
- req.setHeader('Content-Type', 'application/json')
- return config.encode('utf-8')
-
-def run_server(reactor, o):
- print("dir is", __file__)
- provroot = static.File(htmldir)
- provisioner = Provisioner(reactor, o)
- provroot.putChild(b"", provisioner)
- provroot.putChild(b"index.html", provisioner)
- provroot.putChild(b"request-code", RequestCode(reactor, o))
-
- # Prefix the mountpoints.
- revpaths = o['mountpoint'].split('/')
- revpaths.reverse()
- for dir in revpaths:
- # print('mount root under ' + dir)
- if dir != '':
- r = resource.Resource()
- r.putChild(dir.encode('utf-8'), provroot)
- provroot = r
-
- # Override the paths.
- root = StackedResource([static.File(wwwroot(o['home'])), provroot])
- if o['mountpoint'] == '/':
- root.putChild(b"", provisioner)
-
- # Display the JSON config.
- root.putChild(b"network-config", ConfigJSON(o))
- root.putChild(b"genesis.json", GenesisJSON(o))
-
- site = server.Site(root)
- s = endpoints.serverFromString(reactor, o["listen"])
- s.listen(site)
- print("server running")
- return defer.Deferred()
-
-@defer.inlineCallbacks
-def agCosmosHelper(reactor, opts, config, args, retries = 1):
- code = None
- while code != 0 and retries > 0:
- if code is not None:
- # Wait 3 seconds between sends.
- yield deferLater(reactor, 3, lambda: None)
- retries -= 1
- rpcAddr = random.choice(config['rpcAddrs'])
- print('running', rpcAddr, args)
- d = defer.Deferred()
- processProtocol = SendInputAndWaitProtocol(d, b'')
- program = 'ag-cosmos-helper'
- reactor.spawnProcess(processProtocol, '/usr/local/bin/' + program, args=[
- program, *args,
- '--chain-id', config['chainName'], '-ojson',
- '--node', 'tcp://' + rpcAddr,
- '--home', os.path.join(opts['home'], 'ag-cosmos-helper-statedir'),
- ])
- code, output, stderr = yield d
- if code == 0:
- oj = json.loads(output.decode('utf-8'))
- code = oj.get('code', code)
- output = oj
- elif stderr[0:8] == b'ERROR: {':
- try:
- oj = json.loads(stderr[7:].decode('utf-8'))
- code = oj.get('code', code)
- output = oj
- except:
- pass
- elif stderr[0:14] == b'gas estimate: ':
- lines = stderr.split(b'\n')
- oj = json.loads(lines[1].decode('utf-8'))
- if oj.get('type') is None:
- # Reformat the message into what --generate-only produces.
- output = {
- 'type': 'cosmos-sdk/StdTx',
- 'value': {
- 'msg': oj['msgs'],
- 'fee': oj['fee'],
- 'signatures': None,
- 'memo': '',
- }}
- else:
- output = oj
- code = 0
-
- return code, output
-
-@defer.inlineCallbacks
-def doEnablePubkeys(reactor, opts, config, pkobjs):
- txes = []
- needIngress = []
-
- for pkobj in pkobjs:
- pubkey = pkobj['pubkey']
- nickname = pkobj['nickname']
- print('generating transaction for', pubkey)
- # Estimate the gas, with a little bit of padding.
- args = ['tx', 'swingset', 'provision-one', '--keyring-backend=test', nickname, pubkey,
- '--from=ag-solo', '--gas=auto', '--gas-adjustment=1.4']
- code, output = yield agCosmosHelper(reactor, opts, config, args, 1)
- if code == 0:
- txes.append(output)
-
- if len(txes) > 0:
- tx0 = txes[0]
- msgs = tx0['value']['msg']
- # Add up all the gases.
- gas = int(tx0['value']['fee']['gas'])
- for tx in txes[1:]:
- val = tx['value']
- gas += int(val['fee']['gas'])
- for msg in val['msg']:
- msgs.append(msg)
- tx0['value']['fee']['gas'] = str(gas)
- # Create a temporary file that is automatically deleted.
- with NamedTemporaryFile() as temp:
- # Save the amalgamated transaction.
- temp.write(json.dumps(tx0).encode('utf-8'))
- temp.flush()
-
- # Now the temp.name contents are available
- args = [
- 'tx', 'sign', temp.name, '--keyring-backend=test', '--from', config['bootstrapAddress'],
- '--yes', '--append=false',
- ]
-
- # Use the temp file in the sign request.
- code, output = yield agCosmosHelper(reactor, opts, config, args, 10)
- if code != 0:
- raise Exception('Cannot sign transaction')
- with NamedTemporaryFile() as temp:
- # Save the signed transaction.
- temp.write(json.dumps(output).encode('utf-8'))
- temp.flush()
-
- # Now the temp.name contents are available
- args = [
- 'tx', 'broadcast', temp.name,
- '--broadcast-mode=block',
- ]
-
- code, output = yield agCosmosHelper(reactor, opts, config, args, 10)
- if code != 0:
- raise Exception('Cannot broadcast transaction')
-
-def main():
- o = Options()
- o.parseOptions()
- if o.subCommand is not None and o.subCommand.startswith('set-cosmos-'):
- try:
- os.mkdir(o['home'])
- except FileExistsError:
- pass
- if o.subCommand == 'set-cosmos-config':
- fname = cosmosConfigFile(o['home'])
- elif o.subCommand == 'set-cosmos-genesis':
- fname = cosmosGenesisFile(o['home'])
- print('Reading %s from stdin; hit Ctrl-D to finish' % fname)
- cfgJson = sys.stdin.read()
- # Check that the JSON input is properly-formatted.
- json.loads(cfgJson)
- # Write out the JSON.
- with open(fname, 'w') as f:
- f.write(cfgJson)
- elif o.subCommand == 'add-pubkeys':
- # Now that we have our files, add all the accounts.
- with open(cosmosConfigFile(o['home']), 'r') as f:
- config = json.loads(f.read())
- try:
- # This file is comma-terminated lines of JSON objects.
- with open(pubkeyDatabase(o['home'])) as f:
- # Strip the trailing newlines and comma.
- pkobjs_str = f.read().rstrip().rstrip(',')
- # Interpret as an array.
- pkobjs = json.loads('[' + pkobjs_str + ']')
- except FileNotFoundError:
- return
- pkobjs.reverse()
- react(doEnablePubkeys, ({**o, **o.subOptions}, config, pkobjs))
- elif o.subCommand == 'start':
- react(run_server, ({**o, **o.subOptions},))
- else:
- print("Need either 'set-cosmos-config' or 'start'")
- sys.exit(1)
diff --git a/packages/deployment/Dockerfile b/packages/deployment/Dockerfile
index 62310673b85..0ebb7f48002 100644
--- a/packages/deployment/Dockerfile
+++ b/packages/deployment/Dockerfile
@@ -28,8 +28,7 @@ RUN ln -sf $PWD/setup/ag-setup-cosmos /usr/local/bin/
COPY package*.json setup/
RUN cd setup && npm install --production
-# Add the provisioning server, so we can deploy it via Ansible.
-COPY --from=agoric/cosmic-swingset-pserver /usr/src/app/ve3/ /usr/src/app/ve3/
+# Add the ag-solo, so we can deploy it via Ansible.
COPY --from=agoric/cosmic-swingset-solo /usr/src/app/lib/ag-solo/ /usr/src/app/lib/ag-solo/
COPY . setup/
diff --git a/packages/deployment/Makefile b/packages/deployment/Makefile
index 03c65c99b98..316b4ad873c 100644
--- a/packages/deployment/Makefile
+++ b/packages/deployment/Makefile
@@ -11,7 +11,7 @@ docker-show-fat:
docker build --file=Dockerfile.show-fat ../..
docker-build: docker-build-base docker-build-sdk docker-build-solo \
- docker-build-pserver docker-build-setup docker-build-vagrant
+ docker-build-setup docker-build-vagrant
docker-build-sdk:
docker build -t $(REPOSITORY_SDK):latest --file=Dockerfile.sdk ../..
@@ -25,9 +25,6 @@ docker-build-base:
echo "$$hash$$dirty" > $(SS)lib/git-revision.txt
docker build -t $(REPOSITORY):latest $(SS)
-docker-build-pserver:
- docker build -t $(REPOSITORY)-pserver:latest $(SS)provisioning-server
-
docker-build-solo:
docker build -t $(REPOSITORY)-solo:latest $(SS)lib/ag-solo
@@ -35,7 +32,7 @@ docker-build-vagrant:
docker build -t agoric/vagrant-debian:latest --file=../../vagrant/Dockerfile ../../vagrant
docker-push: docker-push-base docker-push-solo docker-push-setup \
- docker-push-pserver docker-push-ibc-alpha docker-push-vagrant
+ docker-push-ibc-alpha docker-push-vagrant
# ./docker is an emptyish directory.
docker-build-ibc-alpha:
@@ -54,11 +51,6 @@ docker-push-base:
$(DONT_PUSH_LATEST) docker push $(REPOSITORY_SDK):latest
docker push $(REPOSITORY_SDK):$(TAG)
-docker-push-pserver:
- docker tag $(REPOSITORY)-pserver:latest $(REPOSITORY)-pserver:$(TAG)
- $(DONT_PUSH_LATEST) docker push $(REPOSITORY)-pserver:latest
- docker push $(REPOSITORY)-pserver:$(TAG)
-
docker-push-solo:
docker tag $(REPOSITORY)-solo:latest $(REPOSITORY)-solo:$(TAG)
$(DONT_PUSH_LATEST) docker push $(REPOSITORY)-solo:latest
diff --git a/packages/deployment/ansible/dweb-copy.yml b/packages/deployment/ansible/dweb-copy.yml
new file mode 100644
index 00000000000..80d0f18ea5c
--- /dev/null
+++ b/packages/deployment/ansible/dweb-copy.yml
@@ -0,0 +1,11 @@
+---
+
+- hosts: "{{ service }}"
+ user: root
+ strategy: free
+ vars:
+ - service: dweb
+ - NETWORK_NAME: "{{ lookup('file', SETUP_HOME + '/network.txt') }}"
+ roles:
+ - init
+ - dweb-copy
diff --git a/packages/deployment/ansible/fetch-controller.yml b/packages/deployment/ansible/fetch-controller.yml
deleted file mode 100644
index 3a4dec00235..00000000000
--- a/packages/deployment/ansible/fetch-controller.yml
+++ /dev/null
@@ -1,12 +0,0 @@
----
-
-- hosts: ag-pserver
- user: root
- #any_errors_fatal: true
- gather_facts: yes
- strategy: free
- vars:
- - service: ag-pserver
- - data: "{{ SETUP_HOME }}/{{ service }}/data"
- roles:
- - fetch-controller
diff --git a/packages/deployment/ansible/install-controller.yml b/packages/deployment/ansible/install-controller.yml
deleted file mode 100644
index 024857d92d8..00000000000
--- a/packages/deployment/ansible/install-controller.yml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-
-- hosts: "{{ service }}"
- user: root
- #any_errors_fatal: true
- gather_facts: yes
- strategy: free
- vars:
- - service: ag-pserver
- - data: "{{ SETUP_HOME }}/{{ service }}/data"
- - GCI: "{{ lookup('file', SETUP_HOME + '/' + service + '/gci.txt') }}"
- - RPC_ADDRS: "{{ lookup('file', SETUP_HOME + '/' + service + '/rpcaddrs.txt') }}"
- - CHAIN_NAME: "{{ lookup('file', SETUP_HOME + '/ag-chain-cosmos/chain-name.txt') }}"
- - NETWORK_NAME: "{{ lookup('file', SETUP_HOME + '/network.txt') }}"
- roles:
- - stat-tls-keys
- - install-controller
diff --git a/packages/deployment/ansible/prepare-controller.yml b/packages/deployment/ansible/prepare-controller.yml
deleted file mode 100644
index af970b864bf..00000000000
--- a/packages/deployment/ansible/prepare-controller.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-
-- hosts: ag-pserver
- user: root
- #any_errors_fatal: true
- gather_facts: yes
- strategy: free
- vars:
- - service: ag-pserver
- - data: "{{ SETUP_HOME }}/{{ service }}/data"
- - APPDIR: "{{lookup('pipe', 'pwd')}}/../.."
- - HELPER_BINARY: "{{lookup('env', 'GOPATH') or '/usr/local'}}/bin/ag-cosmos-helper"
- - CHAIN_NAME: "{{ lookup('file', SETUP_HOME + '/ag-chain-cosmos/chain-name.txt') }}"
- roles:
- - copy
- - init
- - init-controller
- - fetch-controller
diff --git a/packages/deployment/ansible/roles/dweb-copy/tasks/main.yml b/packages/deployment/ansible/roles/dweb-copy/tasks/main.yml
new file mode 100644
index 00000000000..7ed515be7d6
--- /dev/null
+++ b/packages/deployment/ansible/roles/dweb-copy/tasks/main.yml
@@ -0,0 +1,55 @@
+---
+
+- name: Ensure public exists
+ become_user: "{{ service }}"
+ become: yes
+ file:
+ path: "/home/{{ service }}/public"
+ state: directory
+ mode: '0755'
+
+- name: Copy network-config
+ become_user: "{{ service }}"
+ become: yes
+ copy:
+ src: "{{ SETUP_HOME }}/{{ service }}/data/cosmos-chain.json"
+ dest: "/home/{{ service }}/public/network-config"
+ mode: '0644'
+
+- name: Copy genesis.json
+ become_user: "{{ service }}"
+ become: yes
+ copy:
+ src: "{{ SETUP_HOME }}/ag-chain-cosmos/data/genesis.json"
+ dest: "/home/{{ service }}/public/genesis.json"
+ mode: '0644'
+
+- name: "Stat CRT"
+ delegate_to: localhost
+ stat:
+ path="{{ SETUP_HOME }}/{{ NETWORK_NAME }}.crt"
+ register: stat_crt
+
+- name: "Stat KEY"
+ delegate_to: localhost
+ stat:
+ path="{{ SETUP_HOME }}/{{ NETWORK_NAME }}.key"
+ register: stat_key
+
+- name: "Copy {{ NETWORK_NAME }}.crt"
+ become_user: "{{ service }}"
+ become: yes
+ copy:
+ src: "{{ SETUP_HOME }}/{{ NETWORK_NAME }}.crt"
+ dest: "/home/{{ service }}/{{ NETWORK_NAME }}.crt"
+ mode: '0644'
+ when: stat_crt.stat.exists
+
+- name: "Copy {{ NETWORK_NAME }}.key"
+ become_user: "{{ service }}"
+ become: yes
+ copy:
+ src: "{{ SETUP_HOME }}/{{ NETWORK_NAME }}.key"
+ dest: "/home/{{ service }}/{{ NETWORK_NAME }}.key"
+ mode: "0600"
+ when: stat_key.stat.exists
diff --git a/packages/deployment/ansible/roles/fetch-controller/tasks/main.yml b/packages/deployment/ansible/roles/fetch-controller/tasks/main.yml
deleted file mode 100644
index 8c0d0eb3d1e..00000000000
--- a/packages/deployment/ansible/roles/fetch-controller/tasks/main.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-- name: "Fetch {{ data | default(service + '/data') }}/*/boot-address.txt"
- fetch:
- dest: "{{ data | default(service + '/data') }}/{{ inventory_hostname }}/boot-address.txt"
- flat: yes
- src: "/home/{{ service }}/.{{ service }}/ag-cosmos-helper-address"
diff --git a/packages/deployment/ansible/roles/init-controller/tasks/main.yml b/packages/deployment/ansible/roles/init-controller/tasks/main.yml
deleted file mode 100644
index 7a1aed218e2..00000000000
--- a/packages/deployment/ansible/roles/init-controller/tasks/main.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-- name: "Ensure /home/{{ service }}/.ag-pserver/wwwroot/{{ CHAIN_NAME }} exists"
- become: yes
- become_user: "{{ service }}"
- file:
- path: "/home/{{ service }}/.ag-pserver/wwwroot/{{ CHAIN_NAME }}"
- state: directory
-
-- name: "Create provisioning mnemonic"
- delegate_to: localhost
- shell:
- cmd: "ag-cosmos-helper keys mnemonic 2>&1 | tee provisioning-mnemonic.txt"
- chdir: "{{ SETUP_HOME }}"
- register: mnemonic
-
-- name: "Delete {{ service }} ag-solo key"
- become: yes
- become_user: "{{ service }}"
- shell:
- cmd: "ag-cosmos-helper --home=/home/{{ service }}/.ag-pserver/ag-cosmos-helper-statedir --keyring-backend=test keys delete ag-solo --yes"
- removes: "/home/{{ service }}/.ag-pserver/ag-cosmos-helper-statedir"
- ignore_errors: yes
-
-- name: "Create {{ service }} ag-solo key"
- become: yes
- become_user: "{{ service }}"
- shell:
- cmd: "ag-cosmos-helper --home=/home/{{ service }}/.ag-pserver/ag-cosmos-helper-statedir --keyring-backend=test keys add --recover ag-solo"
- stdin: "{{ mnemonic.stdout }}"
-
-- name: "Create ag-cosmos-helper-address"
- become: yes
- become_user: "{{ service }}"
- shell:
- cmd: "ag-cosmos-helper --home=/home/{{ service }}/.ag-pserver/ag-cosmos-helper-statedir \
- --keyring-backend=test keys show -a ag-solo > /home/{{ service }}/.ag-pserver/ag-cosmos-helper-address"
diff --git a/packages/deployment/ansible/roles/install-controller/tasks/main.yml b/packages/deployment/ansible/roles/install-controller/tasks/main.yml
deleted file mode 100644
index b655506e5c3..00000000000
--- a/packages/deployment/ansible/roles/install-controller/tasks/main.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-- name: "Ensure /home/{{ service }}/.{{ service }} exists"
- become_user: "{{ service }}"
- become: true
- file:
- path: "/home/{{ service }}/.{{ service }}"
- state: directory
- mode: 0755
-
-- name: "Install {{ data | default(service + '/data') }}/../../ag-chain-cosmos/data/genesis.json"
- become_user: "{{ service }}"
- become: true
- copy:
- src: "{{ data | default(service + '/data') }}/../../ag-chain-cosmos/data/genesis.json"
- dest: "/home/{{ service }}/.{{ service }}/wwwroot/{{ CHAIN_NAME }}/genesis.json"
- owner: "{{ service }}"
- group: "{{ service }}"
- mode: 0644
-
-- name: "Install {{ data | default(service + '/data') }}/cosmos-chain.json"
- become_user: "{{ service }}"
- become: true
- copy:
- src: "{{ data | default(service + '/data') }}/cosmos-chain.json"
- dest: "/home/{{ service }}/.{{ service }}/wwwroot/{{ CHAIN_NAME }}/chain.json"
- owner: "{{ service }}"
- group: "{{ service }}"
- mode: 0644
-
-- name: "Set wwwroot/current to {{ CHAIN_NAME }}"
- become_user: "{{ service }}"
- become: true
- file:
- state: link
- path: "/home/{{ service }}/.{{ service }}/wwwroot/current"
- src: "{{ CHAIN_NAME }}"
-
-- name: "Add {{ NETWORK_NAME }} keys"
- synchronize:
- src: "{{ SETUP_HOME }}/{{ NETWORK_NAME }}.{{ item }}"
- dest: "/home/{{ service }}/.{{ service }}/{{NETWORK_NAME}}.{{item}}"
- mode: push
- with_items:
- - crt
- - key
- when:
- - tlscrt.stat.exists
- - tlskey.stat.exists
diff --git a/packages/deployment/main.js b/packages/deployment/main.js
index 52c9b501bd6..0487e5dc4df 100644
--- a/packages/deployment/main.js
+++ b/packages/deployment/main.js
@@ -36,7 +36,7 @@ import {
const PROVISION_DIR = 'provision';
const PROVISIONER_NODE = 'node0'; // FIXME: Allow configuration.
const COSMOS_DIR = 'ag-chain-cosmos';
-const CONTROLLER_DIR = 'ag-pserver';
+const DWEB_DIR = 'dweb';
const SECONDS_BETWEEN_BLOCKS = 5;
// This is needed for hyphenated group names not to trigger Ansible.
@@ -49,9 +49,7 @@ const guardFile = async (file, maker) => {
return 0;
}
const parent = dirname(file);
- if (!(await exists(parent))) {
- await mkdir(parent);
- }
+ await mkdir(parent, { recursive: true });
let made = false;
const ret = await maker(async contents => {
await createFile(file, contents);
@@ -363,37 +361,22 @@ show-config display the client connection parameters
const networkName = await trimReadFile('network.txt');
const chainVersion = await trimReadFile('chain-version.txt');
const chainName = `${networkName}-${chainVersion}`;
- const pserverPassword = (await exists('pserver-password.txt'))
- ? await trimReadFile('pserver-password.txt')
- : '';
const currentChainName = await trimReadFile(
`${COSMOS_DIR}/chain-name.txt`,
).catch(_ => undefined);
if (subOpts.bump || currentChainName !== chainName) {
// We don't have matching parameters, so restart the chain.
- // Stop all the services.
- await reMain(['play', 'stop', '-eservice=ag-pserver']);
- await reMain([
- 'play',
- 'stop',
- '-eservice=ag-controller',
- '-euser=ag-pserver',
- ]);
+ // Stop the chain services.
await reMain(['play', 'stop', '-eservice=ag-chain-cosmos']);
- // Blow away controller/cosmos state.
- await needDoRun(['rm', '-rf', CONTROLLER_DIR, COSMOS_DIR]);
+ // Blow away cosmos state.
+ await needDoRun(['rm', '-rf', COSMOS_DIR]);
}
await guardFile(`${COSMOS_DIR}/chain-name.txt`, async makeFile => {
await makeFile(chainName);
});
- // Initialize the controller.
- await guardFile(`${CONTROLLER_DIR}/prepare.stamp`, () =>
- needReMain(['play', 'prepare-controller']),
- );
-
// Bootstrap the chain nodes.
await guardFile(`${COSMOS_DIR}/prepare.stamp`, () =>
needReMain(['play', 'prepare-cosmos']),
@@ -473,91 +456,61 @@ show-config display the client connection parameters
'Your Agoric Cosmos chain is now running!',
),
);
+ await needReMain(['dweb']);
+ break;
+ }
+
+ case 'dweb': {
+ await inited();
+ const networkName = await trimReadFile('network.txt');
const cfg = await needBacktick(`${shellEscape(progname)} show-config`);
process.stdout.write(`${chalk.yellow(cfg)}\n`);
- await guardFile(
- `${CONTROLLER_DIR}/data/cosmos-chain.json`,
- async makeFile => {
- await makeFile(cfg);
- },
- );
-
- await guardFile(`${CONTROLLER_DIR}/gci.txt`, async makeFile => {
- const gci = await needBacktick(`${shellEscape(progname)} show-gci`);
- await makeFile(gci);
- });
- await guardFile(`${CONTROLLER_DIR}/rpcaddrs.txt`, async makeFile => {
- const rpcAddrs = await needBacktick(
- `${shellEscape(progname)} show-rpcaddrs`,
- );
- await makeFile(rpcAddrs.replace(/,/g, ' '));
+ await guardFile(`${DWEB_DIR}/data/cosmos-chain.json`, async makeFile => {
+ await makeFile(cfg);
});
- await guardFile(`${CONTROLLER_DIR}/install.stamp`, () =>
- needReMain(['play', 'install-controller']),
- );
- // Install any pubkeys from a former instantiation.
- await guardFile(`${CONTROLLER_DIR}/pubkeys.stamp`, () =>
- needReMain([
- 'ssh',
- 'ag-pserver',
- 'sudo',
- '-u',
- 'ag-pserver',
- '/usr/src/app/ve3/bin/ag-pserver',
- 'add-pubkeys',
- '-c',
- 'http://localhost:8000/private/repl',
- ]),
+ const rpcAddrs = await needBacktick(
+ `${shellEscape(progname)} show-rpcaddrs`,
);
+ const match = rpcAddrs.match(/^([^,]+):\d+(,|$)/);
- let pserverFlags = '';
- const installFlags = [];
- const pub = `${networkName}.crt`;
+ let execline = `npx http-server ./public`;
+ let pWebHost;
+ const cert = `${networkName}.crt`;
const key = `${networkName}.key`;
- if ((await exists(pub)) && (await exists(key))) {
- pserverFlags = ` ${shellEscape(
- `--listen=ssl:443:privateKey=.ag-pserver/${key}:certKey=.ag-pserver/${pub}`,
- )}`;
- installFlags.push(
- `-eserviceLines=AmbientCapabilities=CAP_NET_BIND_SERVICE`,
- );
+ if ((await exists(cert)) && (await exists(key))) {
+ execline += ` --port=443 --ssl`;
+ execline += ` --cert=${shellEscape(cert)}`;
+ execline += ` --key=${shellEscape(key)}`;
+ pWebHost = `https://${match[1]}`;
+ } else {
+ execline += ` --port=80`;
+ pWebHost = `http://${match[1]}`;
}
- const mountpoint =
- pserverPassword === ''
- ? ''
- : ` -m ${shellEscape(`/provision-${pserverPassword}`)}`;
- const execline = `/usr/src/app/ve3/bin/ag-pserver start${pserverFlags}${mountpoint} -c http://localhost:8000/private/repl`;
- await guardFile(`${CONTROLLER_DIR}/service.stamp`, () =>
+ // Copy the needed files to the web server.
+ await needReMain(['play', 'dweb-copy']);
+
+ await guardFile(`${DWEB_DIR}/service.stamp`, () =>
needReMain([
'play',
'install',
- '-eservice=ag-pserver',
+ '-eservice=dweb',
`-eexecline=${shellEscape(execline)}`,
- ...installFlags,
+ `-eserviceLines=AmbientCapabilities=CAP_NET_BIND_SERVICE`,
]),
);
- await guardFile(`${CONTROLLER_DIR}/start.stamp`, () =>
- needReMain(['play', 'start', '-eservice=ag-pserver']),
+ await guardFile(`${DWEB_DIR}/start.stamp`, () =>
+ needReMain(['play', 'start', '-eservice=dweb']),
);
- const rpcAddrs = await needBacktick(
- `${shellEscape(progname)} show-rpcaddrs`,
- );
- const match = rpcAddrs.match(/^([^,]+):\d+(,|$)/);
- const pserverHost = pserverFlags
- ? `https://${match[1]}`
- : `http://${match[1]}:8001`;
initHint();
console.error(
`Use the following to provision:
-${chalk.yellow.bold(
- `ag-setup-solo --netconfig='${pserverHost}/network-config'`,
-)}
+${chalk.yellow.bold(`ag-setup-solo --netconfig='${pWebHost}/network-config'`)}
`,
);
if (await exists('/vagrant')) {
@@ -829,7 +782,7 @@ ${chalk.yellow.bold(
}
// We no longer are provisioned or have Cosmos.
- await needDoRun(['rm', '-rf', PROVISION_DIR, CONTROLLER_DIR, COSMOS_DIR]);
+ await needDoRun(['rm', '-rf', COSMOS_DIR, PROVISION_DIR, DWEB_DIR]);
break;
}
@@ -885,18 +838,18 @@ ${name}:
for (let instance = 0; instance < ips.length; instance += 1) {
const ip = ips[instance];
const node = `node${offset + instance}`;
- const moniker = `Agoric${offset + instance}`;
const units =
node === PROVISIONER_NODE
? `\
units:
- - ag-pserver.service
- ag-chain-cosmos.service
`
: '';
const host = `\
${node}:
- moniker: ${moniker}
+ moniker: Agoric${offset + instance}
+ website: https://testnet.agoric.com
+ identity: https://keybase.io/team/agoric.testnet.validators
ansible_host: ${ip}
ansible_ssh_user: root
ansible_ssh_private_key_file: '${SSH_PRIVATE_KEY_FILE}'
@@ -906,11 +859,10 @@ ${units}`;
addAll(host);
- // TODO: Don't make these hardcoded assumptions.
- // For now, we add all the nodes to ag-chain-cosmos, and the first node to ag-pserver.
+ // We add all the nodes to ag-chain-cosmos.
addChainCosmos(host);
if (node === PROVISIONER_NODE) {
- makeGroup('ag-pserver', 4)(host);
+ makeGroup('dweb', 4)(host);
}
}
}