diff --git a/Dockerfile b/Dockerfile index fbd642c..0b6a33c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,91 +1,30 @@ -FROM ubuntu:16.04 +FROM von-indy:latest -ARG uid=1000 -ARG indy_stream=master - -ARG indy_plenum_ver=1.2.237 -ARG indy_anoncreds_ver=1.0.32 -ARG indy_node_ver=1.2.297 -ARG python3_indy_crypto_ver=0.2.0 -ARG indy_crypto_ver=0.2.0 - -ENV LC_ALL="C.UTF-8" -ENV LANG="C.UTF-8" -ENV SHELL="/bin/bash" - -ENV RUST_LOG=error - -# Install environment -RUN apt-get update -y && apt-get install -y \ - git \ - wget \ - python3.5 \ - python3-pip \ - python-setuptools \ - python3-nacl \ - apt-transport-https \ - ca-certificates \ - build-essential \ - pkg-config \ - cmake \ - libssl-dev \ - libsqlite3-dev \ - libsodium-dev \ - curl - -RUN pip3 install -U \ - pip \ - setuptools - -RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 68DB5E88 -RUN echo "deb https://repo.sovrin.org/deb xenial $indy_stream" >> /etc/apt/sources.list - -RUN useradd -ms /bin/bash -u $uid indy - -RUN apt-get update -y && apt-get install -y \ - indy-plenum=${indy_plenum_ver} \ - indy-anoncreds=${indy_anoncreds_ver} \ - indy-node=${indy_node_ver} \ - python3-indy-crypto=${python3_indy_crypto_ver} \ - libindy-crypto=${indy_crypto_ver} \ - libzmq3-dev \ - vim - -USER indy -WORKDIR /home/indy - -# Install rust toolchain -RUN curl -o rustup https://sh.rustup.rs -RUN chmod +x rustup -RUN ./rustup -y - -# Build libindy -RUN git clone https://github.com/bcgov/indy-sdk.git -WORKDIR /home/indy/indy-sdk/libindy -RUN git fetch -RUN /home/indy/.cargo/bin/cargo build - -# Move libindy to lib path USER root -RUN mv target/debug/libindy.so /usr/lib -RUN pip3 install --upgrade setuptools -RUN pip3 install pipenv +ADD --chown=indy:indy indy_config.py /etc/indy/ -USER indy -WORKDIR /home/indy - -ADD bin/* /usr/local/bin/ +RUN apt-get update -y && \ + apt-get install -y --no-install-recommends \ + build-essential \ + python3.5-dev && \ + pip --no-cache-dir install \ + sanic==0.7.0 \ + ujson==1.33 && \ + apt-get remove --purge -y \ + build-essential \ + python3.5-dev && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* -RUN awk '{if (index($1, "NETWORK_NAME") != 0) {print("NETWORK_NAME = \"sandbox\"")} else print($0)}' /etc/indy/indy_config.py> /tmp/indy_config.py -RUN mv /tmp/indy_config.py /etc/indy/indy_config.py +ADD . $HOME -ADD --chown=indy:indy . /home/indy +RUN mkdir -p $HOME/ledger/sandbox/data && \ + mkdir -p $HOME/.indy_client/wallet && \ + chown -R indy:indy $HOME && \ + chmod -R ug+rw $HOME -RUN mkdir -p /home/indy/.indy_client/wallet +# used by validator-info +#RUN apt-get install -y --no-install-recommends iproute2 sovrin -RUN chgrp -R indy /home/indy/.indy_client/wallet \ - && chmod -R g+rwx /home/indy/.indy_client/wallet - -RUN cd server && \ - pipenv install -r requirements.txt \ No newline at end of file +USER indy diff --git a/bin/read_ledger b/bin/read_ledger index 19d7e38..783a106 100755 --- a/bin/read_ledger +++ b/bin/read_ledger @@ -122,7 +122,7 @@ def print_txns(ledger, args): return # --seq_no - seq_no = args.seq_no + seq_no = int(args.seq_no) if args.seq_no is not None else None if seq_no: print_by_seq_no(ledger, seq_no, serializer) return @@ -147,8 +147,8 @@ def print_count(ledger): def print_all(ledger, serializer): - frm = args.frm - to = args.to + frm = int(args.frm) if args.frm is not None else None + to = int(args.to) if args.to is not None else None for txn in ledger.getAllTxn(frm=frm, to=to): txn = serializer.serialize(txn, toBytes=False) print(txn) diff --git a/bin/von_generate_transactions b/bin/von_generate_transactions index 9873ebf..a7cd813 100755 --- a/bin/von_generate_transactions +++ b/bin/von_generate_transactions @@ -26,8 +26,8 @@ nodeArg="" if [ ! -z "$nodeNum" ]; then nodeArg="--nodeNum $nodeNum" # Only run this for nodes: - echo init_indy_node "Node$nodeNum" 9418 80 - init_indy_node "Node$nodeNum" 9418 80 + #echo init_indy_node "Node$nodeNum" 9418 80 + #init_indy_node "Node$nodeNum" 9418 80 fi if [ ! -z $ipAddresses ]; then diff --git a/docker-compose.yml b/docker-compose.yml index d3fc835..1e7a618 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,23 +4,21 @@ services: # Client # client: - build: . - image: von-base + image: von-network-base command: 'bash -c ''./scripts/start_client.sh''' environment: - DOCKERHOST=${DOCKERHOST} networks: - von volumes: - - von-client-cli:/home/indy/.indy-cli - - von-client-libindy:/var/lib/indy + - client-cli:/home/indy/.indy-cli + - client-data:/var/lib/indy # # Webserver # webserver: - build: . - image: von-base + image: von-network-base command: 'bash -c ''./scripts/start_webserver.sh''' environment: - IP=${IP} @@ -37,7 +35,7 @@ services: - node4 volumes: - ./server:/home/indy/server - - von-webserver:/home/indy/.indy-cli + - webserver-cli:/home/indy/.indy-cli - node1-data:/home/indy/.mnt/node1 - node2-data:/home/indy/.mnt/node2 - node3-data:/home/indy/.mnt/node3 @@ -47,8 +45,7 @@ services: # Nodes # node1: - build: . - image: von-base + image: von-network-base command: 'bash -c ''./scripts/start_node.sh 1''' networks: - von @@ -60,11 +57,10 @@ services: - IPS=${IPS} - DOCKERHOST=${DOCKERHOST} volumes: - - node1-data:/var/lib/indy - + - node1-data:/home/indy/ledger + node2: - build: . - image: von-base + image: von-network-base command: 'bash -c ''./scripts/start_node.sh 2''' networks: - von @@ -76,11 +72,10 @@ services: - IPS=${IPS} - DOCKERHOST=${DOCKERHOST} volumes: - - node2-data:/var/lib/indy + - node2-data:/home/indy/ledger node3: - build: . - image: von-base + image: von-network-base command: 'bash -c ''./scripts/start_node.sh 3''' networks: - von @@ -92,11 +87,10 @@ services: - IPS=${IPS} - DOCKERHOST=${DOCKERHOST} volumes: - - node3-data:/var/lib/indy - + - node3-data:/home/indy/ledger + node4: - build: . - image: von-base + image: von-network-base command: 'bash -c ''./scripts/start_node.sh 4''' networks: - von @@ -108,16 +102,16 @@ services: - IPS=${IPS} - DOCKERHOST=${DOCKERHOST} volumes: - - node4-data:/var/lib/indy + - node4-data:/home/indy/ledger networks: von: volumes: + client-cli: + client-data: + webserver-cli: node1-data: node2-data: node3-data: node4-data: - von-client-cli: - von-client-libindy: - von-webserver: diff --git a/indy_config.py b/indy_config.py new file mode 100644 index 0000000..2ba64c1 --- /dev/null +++ b/indy_config.py @@ -0,0 +1,12 @@ +NETWORK_NAME = 'sandbox' + +LEDGER_DIR = '/home/indy/ledger' +LOG_DIR = '/home/indy/log' +KEYS_DIR = LEDGER_DIR +GENESIS_DIR = LEDGER_DIR +BACKUP_DIR = '/home/indy/backup' +PLUGINS_DIR = '/home/indy/plugins' +NODE_INFO_DIR = LEDGER_DIR + +CLI_BASE_DIR = '/home/indy/.indy-cli/' +CLI_NETWORK_DIR = '/home/indy/.indy-cli/networks' diff --git a/manage b/manage index d57d8ac..51810f9 100755 --- a/manage +++ b/manage @@ -4,7 +4,7 @@ export DOCKERHOST=${APPLICATION_URL-$(docker run --net=host codenvy/che-ip)} set -e SCRIPT_HOME="$( cd "$( dirname "$0" )" && pwd )" -export COMPOSE_PROJECT_NAME="von" +export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-von}" # ================================================================================================================= # Usage: @@ -21,7 +21,6 @@ usage () { start - Creates the application containers from the built images and starts the services based on the docker-compose.yml file. - Examples: $0 start $0 start ,,, & @@ -84,7 +83,15 @@ case "$1" in docker-compose stop ;; build) - docker-compose build + # Build von-indy image used as a base + if [ -n "$INDY_RELEASE" ]; then + INDY_BUILD_FLAGS="--build-arg indy_build_flags=--release" + fi + echo -e "\nBuilding von-indy image ..." + docker build -t 'von-indy' $INDY_BUILD_FLAGS \ + 'https://github.com/cywolf/von-indy.git' + + docker build -t von-network-base . ;; rebuild) docker-compose build --no-cache @@ -102,4 +109,4 @@ case "$1" in usage;; esac -popd >/dev/null \ No newline at end of file +popd >/dev/null diff --git a/scripts/start_webserver.sh b/scripts/start_webserver.sh index a24fedd..8d975fb 100755 --- a/scripts/start_webserver.sh +++ b/scripts/start_webserver.sh @@ -4,17 +4,22 @@ set -e if [ ! -d "/home/indy/.indy-cli/networks/sandbox" ]; then echo "Ledger does not exist - Creating..." -if [ ! -z "$IPS" ]; then - echo von_generate_transactions -s "$IPS" - von_generate_transactions -s "$IPS" -elif [ ! -z "$IP" ]; then - echo von_generate_transactions -i "$IP" - von_generate_transactions -i "$IP" -else - echo von_generate_transactions - von_generate_transactions + if [ ! -z "$IPS" ]; then + echo von_generate_transactions -s "$IPS" + von_generate_transactions -s "$IPS" + elif [ ! -z "$IP" ]; then + echo von_generate_transactions -i "$IP" + von_generate_transactions -i "$IP" + else + echo von_generate_transactions + von_generate_transactions + fi fi -fi +# link node ledgers where webserver can find them +for node in 1 2 3 4; do + ln -s /home/indy/.mnt/node${node}/sandbox/data/Node${node} \ + /home/indy/ledger/sandbox/data/node${node} +done -cd server && pipenv run python server.py \ No newline at end of file +cd server && python server.py diff --git a/server/server.py b/server/server.py index 53685d1..26e9102 100644 --- a/server/server.py +++ b/server/server.py @@ -1,4 +1,4 @@ -#! /usr/bin/python3 +#! /usr/bin/env python3 import asyncio from datetime import datetime @@ -20,7 +20,8 @@ app.static('/include', './static/include') app.static('/favicon.ico', './static/favicon.ico') -python_path = "/usr/bin/python3" +python_path = "/home/indy/bin/python3" +indy_exec_path = "/usr/local/bin/" indy_txn_types = { "0": "NODE", @@ -54,7 +55,7 @@ def json_reponse(data): def validator_info(node_name, as_json=True): - args = [python_path, "/usr/local/bin/validator-info"] + args = [python_path, indy_exec_path + "validator-info"] if as_json: args.append("--json") else: @@ -64,7 +65,8 @@ def validator_info(node_name, as_json=True): if as_json: # The result is polluted with logs in the latest version. # We pull out json - corrected_stdout = re.search(r'(?s)\n({.*})', proc.stdout).group(1) + m = re.search(r'(?s)\n({.*})', proc.stdout) + corrected_stdout = m.group(1) if m else proc.stdout return json.loads(corrected_stdout) return proc @@ -72,11 +74,12 @@ def validator_info(node_name, as_json=True): def read_ledger(ledger, seq_no=0, seq_to=1000, node_name='node1', format="data"): if ledger != "domain" and ledger != "pool" and ledger != "config": raise ValueError("Unsupported ledger type: {}".format(ledger)) - args = [python_path, "/usr/local/bin/read_ledger", "--type", ledger] + args = [python_path, indy_exec_path + "read_ledger", "--type", ledger] if seq_no > 0: args.extend(["--seq_no", str(seq_no)]) args.extend(["--to", str(seq_to)]) - args.extend(["--base_dir", "/home/indy/.mnt/" + node_name]) + #args.extend(["--base_dir", "/home/indy/.mnt/" + node_name]) + args.extend(["--node_name", node_name]) proc = subprocess.run(args, stdout=subprocess.PIPE, universal_newlines=True) if format == "pretty" or format == "data": @@ -239,51 +242,63 @@ async def genesis(request): # Easily write dids for new identity owners @app.route('/register', methods=['POST']) async def register(request): - try: - seed = request.json['seed'] - except KeyError as e: - return sanic_text( - 'Missing query parameter: seed', - status=400 - ) - - if not 0 <= len(seed) <= 32: + global pool + + if not request.json: return sanic_text( - 'Seed must be between 0 and 32 characters long.', + 'Expected json request body', status=400 - ) - - # Pad with zeroes - seed += '0' * (32 - len(seed)) + ) - wallet = Wallet( + seed = request.json.get('seed') + did = request.json.get('did') + verkey = request.json.get('verkey') + alias = request.json.get('alias') + + if seed: + if not 0 <= len(seed) <= 32: + return sanic_text( + 'Seed must be between 0 and 32 characters long.', + status=400 + ) + # Pad with zeroes + seed += '0' * (32 - len(seed)) + else: + if not did or not verkey: + return sanic_text( + 'Either seed the seed parameter or the did and verkey parameters must be provided.', + status=400 + ) + + if seed: + wallet = Wallet( pool, seed, seed + '-wallet' ) - await wallet.create() - - new_agent = _BaseAgent(wallet) - - await new_agent.open() - - # Register agent on the network - print('\n\nRegister agents\n\n') - for ag in (trust_anchor, new_agent): - print('\n\nGet Nym: ' + str(ag) + '\n\n') - if not json.loads(await trust_anchor.get_nym(ag.did)): - print('\n\nSend Nym: ' + str(ag) + '\n\n') - await trust_anchor.send_nym(ag.did, ag.verkey) + async with _BaseAgent(await wallet.create()) as new_agent: + did = new_agent.did + verkey = new_agent.verkey - await new_agent.close() + print('\n\nRegister agent\n\n') + await register_did(did, verkey, alias) return sanic_json({ - 'seed': seed, - 'did': new_agent.did, - 'verkey': new_agent.verkey + 'seed': seed, + 'did': did, + 'verkey': verkey }) +# Helper to register a DID and verkey on the ledger +async def register_did(did, verkey, alias=None): + global trust_anchor + print('\n\nGet Nym: ' + str(did) + '\n\n') + if not json.loads(await trust_anchor.get_nym(did)): + print('\n\nSend Nym: ' + str(did) + '/' + str(verkey) + '\n\n') + await trust_anchor.send_nym(did, verkey, alias) + + if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(boot())