Merge branch 'cic-eth-server' of https://github.com/williamluke4/cic-internal-integration into cic-eth-server

This commit is contained in:
William Luke 2021-11-09 11:48:52 +03:00
commit c48177c78c
17 changed files with 411 additions and 87 deletions

1
.envrc
View File

@ -5,3 +5,4 @@ export TOKEN_NAME=Coffee
export TOKEN_SYMBOL=COFE
export TOKEN_DECIMALS=6
export FAUCET_AMOUNT=30000000000
export DATABASE_DEBUG=1

View File

@ -10,6 +10,7 @@ include:
#- local: 'apps/data-seeding/.gitlab-ci.yml'
stages:
- version
- build
- test
- deploy
@ -20,9 +21,39 @@ variables:
DOCKER_BUILDKIT: "1"
COMPOSE_DOCKER_CLI_BUILD: "1"
CI_DEBUG_TRACE: "true"
SEMVERBOT_VERSION: "0.2.0"
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
#before_script:
# - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
version:
#image: python:3.7-stretch
image: registry.gitlab.com/grassrootseconomics/cic-base-images/ci-version:b01318ae
stage: version
script:
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
- ssh-keyscan gitlab.com >> ~/.ssh/known_hosts && chmod 644 ~/.ssh/known_hosts
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- git remote set-url origin git@gitlab.com:grassrootseconomics/cic-internal-integration.git
- export TAG=$(sbot predict version -m auto)
- |
if [[ -z $TAG ]]
then
echo "tag could not be set $@"
exit 1
fi
- echo $TAG > version
- git tag -a v$TAG -m "ci tagged"
- git push origin v$TAG
artifacts:
paths:
- version
rules:
- if: $CI_COMMIT_REF_PROTECTED == "true"
when: always
- if: $CI_COMMIT_REF_NAME == "master"
when: always
# runs on protected branches and pushes to repo
build-push:
@ -30,12 +61,17 @@ build-push:
tags:
- integration
#script:
# - TAG=$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA sh ./scripts/build-push.sh
# - TAG=$CI_Cbefore_script:
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
script:
- TAG=latest sh ./scripts/build-push.sh
- TAG=latest ./scripts/build-push.sh
- TAG=$(cat ./version) ./scripts/build-push.sh
rules:
- if: $CI_COMMIT_REF_PROTECTED == "true"
when: always
- if: $CI_COMMIT_REF_NAME == "master"
when: always
deploy-dev:
stage: deploy

16
.semverbot.toml Normal file
View File

@ -0,0 +1,16 @@
[git]
[git.config]
email = "semverbot@grassroots.org"
name = "semvervot"
[git.tags]
prefix = "v"
[semver]
mode = "git-commit"
[semver.detection]
patch = ["fix", "[fix]", "patch", "[patch]"]
minor = ["minor", "[minor]", "feat", "[feat]", "release", "[release]", "bump", "[bump]"]
major = ["BREAKING CHANGE"]

View File

@ -4,6 +4,7 @@
This repo uses docker-compose and docker buildkit. Set the following environment variables to get started:
```
export COMPOSE_DOCKER_CLI_BUILD=1
export DOCKER_BUILDKIT=1

View File

@ -9,13 +9,13 @@ import logging
# external imports
import celery
from chainlib.chain import ChainSpec
from hexathon import strip_0x
# local imports
from cic_eth.api.base import ApiBase
from cic_eth.enum import LockEnum
from hexathon import strip_0x
app = celery.current_app
print(app.backend)
#logg = logging.getLogger(__name__)
logg = logging.getLogger()
@ -430,13 +430,13 @@ class Api(ApiBase):
return t
def balance(self, address, token_symbols, include_pending=True):
def balance(self, address, token_symbol, include_pending=True):
"""Calls the provided callback with the current token balance of the given address.
:param address: Ethereum address of holder
:type address: str, 0x-hex
:param token_symbols: ERC20 token symbols of tokens to send
:type token_symbols: list[str]
:param token_symbol: ERC20 token symbol of tokens to send
:type token_symbol: str
:param include_pending: If set, will include transactions that have not yet been fully processed
:type include_pending: bool
:returns: uuid of root task
@ -448,7 +448,7 @@ class Api(ApiBase):
s_tokens = celery.signature(
'cic_eth.eth.erc20.resolve_tokens_by_symbol',
[
token_symbols,
[token_symbol],
self.chain_spec.asdict(),
],
queue=self.queue,
@ -489,9 +489,9 @@ class Api(ApiBase):
s_balance_incoming.link(s_balance_outgoing)
last_in_chain = s_balance_outgoing
one = celery.chain(s_tokens, s_balance)
two = celery.chain(s_tokens, s_balance_incoming)
three = celery.chain(s_tokens, s_balance_outgoing)
one = s_tokens | s_balance
two = s_tokens | s_balance_incoming
three = s_tokens | s_balance_outgoing
t = None
if self.callback_param != None:
@ -501,7 +501,7 @@ class Api(ApiBase):
t = celery.chord([one, two, three])(s_result)
else:
# TODO: Chord is inefficient with only one chain, but assemble_balances must be able to handle different structures in order to avoid chord
one = celery.chain(s_tokens, s_balance)
one = s_tokens | s_balance
if self.callback_param != None:
s_result.link(self.callback_success).on_error(self.callback_error)
t = celery.chord([one])(s_result)

View File

@ -382,6 +382,8 @@ def cache_transfer_data(
sender_address = tx_normalize.wallet_address(tx['from'])
recipient_address = tx_normalize.wallet_address(tx_data[0])
token_value = tx_data[1]
source_token_address = tx_normalize.executable_address(tx['to'])
destination_token_address = source_token_address
session = SessionBase.create_session()
@ -389,8 +391,8 @@ def cache_transfer_data(
'hash': tx_hash_hex,
'from': sender_address,
'to': recipient_address,
'source_token': tx['to'],
'destination_token': tx['to'],
'source_token': source_token_address,
'destination_token': destination_token_address,
'from_value': token_value,
'to_value': token_value,
}
@ -422,14 +424,16 @@ def cache_transfer_from_data(
spender_address = tx_data[0]
recipient_address = tx_data[1]
token_value = tx_data[2]
source_token_address = tx_normalize.executable_address(tx['to'])
destination_token_address = source_token_address
session = SessionBase.create_session()
tx_dict = {
'hash': tx_hash_hex,
'from': tx['from'],
'to': recipient_address,
'source_token': tx['to'],
'destination_token': tx['to'],
'source_token': source_token_address,
'destination_token': destination_token_address,
'from_value': token_value,
'to_value': token_value,
}
@ -461,14 +465,16 @@ def cache_approve_data(
sender_address = tx_normalize.wallet_address(tx['from'])
recipient_address = tx_normalize.wallet_address(tx_data[0])
token_value = tx_data[1]
source_token_address = tx_normalize.executable_address(tx['to'])
destination_token_address = source_token_address
session = SessionBase.create_session()
tx_dict = {
'hash': tx_hash_hex,
'from': sender_address,
'to': recipient_address,
'source_token': tx['to'],
'destination_token': tx['to'],
'source_token': source_token_address,
'destination_token': destination_token_address,
'from_value': token_value,
'to_value': token_value,
}

View File

@ -0,0 +1,31 @@
import os
import cic_eth.cli
from cic_eth.graphql.config import config
from flask import Flask
from flask_graphql import GraphQLView
from cic_eth.graphql.schema import schema
app = cic_eth.cli.CeleryApp.from_config(config)
app.set_default()
print(app)
def create_app():
flask_app = Flask(__name__)
flask_app.add_url_rule(
'/graphql',
view_func=GraphQLView.as_view(
'graphql',
schema=schema,
graphiql=True
)
)
@flask_app.route("/")
def test():
return "Test ok!"
return flask_app
if __name__ == "__main__":
flask_app = create_app()
flask_app.run(host='0.0.0.0', port=5000, debug=True)

View File

@ -0,0 +1,10 @@
import cic_eth.cli
arg_flags = cic_eth.cli.argflag_std_base
local_arg_flags = cic_eth.cli.argflag_local_taskcallback
argparser = cic_eth.cli.ArgumentParser(arg_flags)
argparser.process_local_flags(local_arg_flags)
args = argparser.parse_args()
config = cic_eth.cli.Config.from_args(args, arg_flags, local_arg_flags)

View File

@ -0,0 +1,88 @@
from cic_eth.graphql.schema import schema
query_with_argument = """
{
defaultToken{
symbol
}
}
"""
# result = schema.execute(query_with_argument)
# print(result)
mutation_with_argument = """
mutation {
createAccount(password:"test"){
address
}
}
"""
m_result = schema.execute(mutation_with_argument)
print(m_result)
mutation_with_argument = """
mutation {
createAccount(password:"test"){
address
}
}
"""
m_result = schema.execute(mutation_with_argument)
print(m_result)
balance_query = """
query {
balance(address:"0x643c99d5ab51b5e06d55a68e6b24fd36e9d6b1c9", tokenSymbols:["GFT", "COFE"]){
balanceNetwork
balanceIncoming
balanceOutgoing
balanceAvailable
}
}
"""
balance_query_result = schema.execute(balance_query)
print(balance_query_result)
transfer_mutation = """
mutation {
transfer(fromAddress :"0xcf41bd087b71c72d748fe2b8b4c88b2367c37df3",
toAddress: "0x63474da1a315f9abe0999b6adb61ae8a9ea19a76"
value: 20
tokenSymbol: "COFE" ){
test
}
}
"""
# transfer_mutation_result = schema.execute(transfer_mutation)
# print(transfer_mutation_result)
balance_query = """
query {
balance(address:"0x63474da1a315f9abe0999b6adb61ae8a9ea19a76", tokenSymbols:["GFT"]){
balanceNetwork
balanceIncoming
balanceOutgoing
balanceAvailable
}
}
"""
# balance_query_result = schema.execute(balance_query)
# print(balance_query_result)
transactions_query = """
query {
transactions(address:"0xcf41bd087b71c72d748fe2b8b4c88b2367c37df3")
}
"""
# transactions_query_result = schema.execute(transactions_query)
# print(transactions_query_result)

View File

@ -1,40 +1,26 @@
# standard imports
import json
import logging
import sys
import uuid
import cic_eth.cli
import redis
from cic_eth.api.api_task import Api
from cic_eth.graphql.config import config
from graphene import (Boolean, Field, Float, Int, List, Mutation, ObjectType,
Schema, String)
arg_flags = cic_eth.cli.argflag_std_base
local_arg_flags = cic_eth.cli.argflag_local_taskcallback
argparser = cic_eth.cli.ArgumentParser(arg_flags)
argparser.process_local_flags(local_arg_flags)
args = argparser.parse_args()
config = cic_eth.cli.Config.from_args(args, arg_flags, local_arg_flags)
celery_app = cic_eth.cli.CeleryApp.from_config(config)
chain_spec = config.get('CHAIN_SPEC')
redis_host = config.get('REDIS_HOST')
redis_port = config.get('REDIS_PORT')
redis_db = config.get('REDIS_DB')
celery_queue = config.get('CELERY_QUEUE')
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__)
def init_api(redis_channel: str):
api = Api(
chain_spec,
queue=celery_queue,
callback_param='{}:{}:{}:{}'.format(
redis_host, redis_port, redis_db, redis_channel),
callback_task='cic_eth.callbacks.redis.redis',
callback_queue=celery_queue,
)
return api
def call(method, *args):
@ -43,10 +29,16 @@ def call(method, *args):
ps = r.pubsub()
ps.subscribe(redis_channel)
ps.get_message() # Subscription Object
api = init_api(redis_channel)
print(f"Channel init {redis_channel}")
print(args)
api = Api(
chain_spec,
queue=celery_queue,
callback_param='{}:{}:{}:{}'.format(
redis_host, redis_port, redis_db, redis_channel),
callback_task='cic_eth.callbacks.redis.redis',
callback_queue=celery_queue,
)
getattr(api, method)(*args)
ps.get_message() # returns None !?
@ -57,6 +49,7 @@ def call(method, *args):
'got no new address from cic-eth before timeout: {}\n'.format(e))
sys.exit(1)
ps.unsubscribe()
print(o)
m = json.loads(o['data'])
return m["result"]
@ -81,21 +74,34 @@ class TokenBalance(ObjectType):
return str(int(parent.balance_network) + int(parent.balance_incoming) - int(parent.balance_outgoing))
class Query(ObjectType):
default_token = Field(Token)
def resolve_default_token(parent, info):
# always pass an object for `me` field
data = call('default_token')
api = Api(
chain_spec,
queue=celery_queue,
)
task = api.default_token()
data = task.get()
print(data)
return Token(**data)
balance = Field(List(TokenBalance), address=String(),
token_symbols=List(String), include_pending=Boolean())
token_symbol=String(), include_pending=Boolean())
def resolve_balance(root, info, address, token_symbols, include_pending=True):
data = call('balance', address, token_symbols, include_pending)
print(data)
def resolve_balance(root, info, address, token_symbol, include_pending=True):
api = Api(
chain_spec,
queue=celery_queue,
)
task = api.balance(address=address, token_symbol=token_symbol, include_pending=include_pending)
data = task.get() #api call('balance', address, token_symbol, include_pending)
log.debug(data)
print(data, file=sys.stdout)
#[{'address': '3ff776b6f888980def9d4220858803f9dc5e341e', 'converters': [], 'balance_network': 0}]
return map(lambda token: TokenBalance(
address=token.get("address"),
@ -110,7 +116,13 @@ class Query(ObjectType):
required=True), limit=Int(default_value=10))
def resolve_transactions(root, info, address, limit):
data = call('list', address, limit)
api = Api(
chain_spec,
queue=celery_queue,
)
task = api.list(address=address, limit=limit)
data = task.get()
print(data)
#[{'address': '3ff776b6f888980def9d4220858803f9dc5e341e', 'converters': [], 'balance_network': 0}]
return "test"
@ -125,8 +137,12 @@ class CreateAccount(Mutation):
def mutate(root, info, password, register=True):
print(password, register)
api = Api(
chain_spec,
queue=celery_queue,
)
address = call('create_account', password, register)
address = call('create_account',password, register)
return CreateAccount(address=f"0x{address}")
@ -144,10 +160,10 @@ class Transfer(Mutation):
value,
token_symbol):
print(from_address, to_address, value, token_symbol)
redis_channel = str(uuid.uuid4())
api = init_api(redis_channel)
api = Api(
chain_spec,
queue=celery_queue,
)
t = api.transfer(from_address, to_address,
int(value * (10**6)), token_symbol)
print(f"t {t}")
@ -171,12 +187,15 @@ class TransferFrom(Mutation):
to_address,
value,
token_symbol, spender_address):
data = call('transfer_from', from_address,
to_address,
value,
token_symbol, spender_address)
return data
api = Api(
chain_spec,
queue=celery_queue,
)
task = api.transfer_from(from_address=from_address,
to_address=to_address,
value=value,
token_symbol=token_symbol, spender_address=spender_address)
return task.get()
class MyMutations(ObjectType):

View File

@ -72,7 +72,7 @@ def __balance_incoming_compatible(token_address, receiver_address):
status_compare = dead()
q = q.filter(Otx.status.op('&')(status_compare)==0)
# TODO: this can change the result for the recipient if tx is later obsoleted and resubmission is delayed.
q = q.filter(Otx.status.op('&')(StatusBits.IN_NETWORK)==StatusBits.IN_NETWORK)
#q = q.filter(Otx.status.op('&')(StatusBits.IN_NETWORK)==StatusBits.IN_NETWORK)
q = q.filter(TxCache.destination_token_address==token_address)
delta = 0
for r in q.all():

View File

@ -8,7 +8,6 @@ from urllib.parse import parse_qsl, urlparse
import cic_eth.cli
import redis
from cic_eth.api.api_task import Api
logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger()
@ -22,6 +21,7 @@ args = argparser.parse_args()
config = cic_eth.cli.Config.from_args(args, arg_flags, local_arg_flags)
celery_app = cic_eth.cli.CeleryApp.from_config(config)
from cic_eth.api.api_task import Api
# uwsgi application

View File

@ -4,3 +4,5 @@ semver==2.13.0
crypto-dev-signer>=0.4.15rc2,<0.5.0
uwsgi==2.0.19.1
graphene>=2.0
flask>=2.0.2
Flask-GraphQL>=2.0.1

View File

@ -193,6 +193,7 @@ async function processRequest(req, res) {
res.end();
return;
}
content = '';
break;
case 'get:automerge:client':
@ -251,7 +252,7 @@ async function processRequest(req, res) {
}
if (content === undefined) {
console.error('empty content', data);
console.error('empty content', mod, digest, data);
res.writeHead(404, {"Content-Type": "text/plain"});
res.end();
return;

View File

@ -6,6 +6,7 @@ volumes:
bloxberg-data: {}
contract-config: {}
services:
evm:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/bloxberg-node:${TAG:-latest}
@ -27,7 +28,7 @@ services:
# PGDATA: /tmp/cic/postgres
ports:
- ${DEV_POSTGRES_PORT:-63432}:5432
command: ["-c", "max_connections=200"]
command: [ "-c", "max_connections=200" ]
volumes:
- ./scripts/initdb/create_db.sql:/docker-entrypoint-initdb.d/1-create_all_db.sql
- postgres-db:/var/lib/postgresql/data
@ -38,6 +39,7 @@ services:
- ${DEV_REDIS_PORT:-63379}:6379
command: "--loglevel verbose"
bootstrap:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/contract-migration:${TAG:-latest}
build:
@ -85,6 +87,8 @@ services:
volumes:
- contract-config:/tmp/cic/config
cic-signer:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics/cic-internal-integration}/funga-eth:${TAG:-latest}
build:
@ -147,8 +151,6 @@ services:
SIGNER_SECRET: ${SIGNER_SECRET:-deadbeef}
TASKS_TRACE_QUEUE_STATUS: ${TASKS_TRACE_QUEUE_STATUS:-1}
restart: unless-stopped
ports:
- 8080:8000
depends_on:
- evm
- postgres
@ -166,6 +168,54 @@ services:
set +a
./start_tasker.sh --aux-all -q cic-eth -vv
cic-eth-server:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/cic-eth:${TAG:-latest}
ports:
- 5000:5000
build:
context: apps/cic-eth
dockerfile: docker/Dockerfile
args:
DOCKER_REGISTRY: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}
PIP_INDEX_URL: ${PIP_INDEX_URL:-https://pypi.org/simple}
EXTRA_PIP_INDEX_URL: ${EXTRA_PIP_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
EXTRA_PIP_ARGS: $EXTRA_PIP_ARGS
environment:
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS
RPC_PROVIDER: ${RPC_PROVIDER:-http://evm:8545}
CHAIN_SPEC: ${CHAIN_SPEC:-evm:byzantium:8996:bloxberg}
DATABASE_HOST: ${DATABASE_HOST:-postgres}
DATABASE_PORT: ${DATABASE_PORT:-5432}
DATABASE_NAME: ${DATABASE_NAME:-cic_eth}
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
DATABASE_USER: ${DATABASE_USER:-grassroots}
DATABASE_ENGINE: ${DATABASE_ENGINE:-postgres}
DATABASE_DRIVER: ${DATABASE_DRIVER:-psycopg2}
DATABASE_DEBUG: ${DATABASE_DEBUG:-0}
DATABASE_POOL_SIZE: 0
REDIS_PORT: 6379
REDIS_HOST: redis
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis}
CELERY_DEBUG: ${CELERY_DEBUG:-1}
SIGNER_PROVIDER: ${SIGNER_PROVIDER:-http://cic-signer:8000}
SIGNER_SECRET: ${SIGNER_SECRET:-deadbeef}
TASKS_TRACE_QUEUE_STATUS: ${TASKS_TRACE_QUEUE_STATUS:-1}
restart: unless-stopped
depends_on:
- cic-eth-tasker
volumes:
- signer-data:/run/crypto-dev-signer
- contract-config:/tmp/cic/config/:ro
command:
- /bin/bash
- -c
- |
set -a
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
set +a
python /root/cic_eth/graphql/app.py -vv
cic-eth-tracker:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics/cic-internal-integration}/cic-eth:${TAG:-latest}
build:
@ -213,6 +263,7 @@ services:
set +a
./start_tracker.sh -vv
cic-eth-dispatcher:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics/cic-internal-integration}/cic-eth:${TAG:-latest}
build:
@ -256,6 +307,7 @@ services:
set +a
./start_dispatcher.sh -vv
cic-eth-retrier:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics/cic-internal-integration}/cic-eth:${TAG:-latest}
build:
@ -301,6 +353,8 @@ services:
set +a
./start_retry.sh -vv
cic-cache-tracker:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics/cic-internal-integration}/cic-cache:${TAG:-latest}
build:
@ -348,6 +402,7 @@ services:
set +a
./start_tracker.sh -vv
cic-cache-tasker:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics/cic-internal-integration}/cic-cache:${TAG:-latest}
build:
@ -390,10 +445,11 @@ services:
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
set +a
/usr/local/bin/cic-cache-taskerd -vv
# "/usr/local/bin/uwsgi" \
# --wsgi-file /root/cic_cache/runnable/daemons/server.py \
# --http :8000 \
# --pyargv "-vv"
# "/usr/local/bin/uwsgi" \
# --wsgi-file /root/cic_cache/runnable/daemons/server.py \
# --http :8000 \
# --pyargv "-vv"
cic-cache-server:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics/cic-internal-integration}/cic-cache:${TAG:-latest}
@ -437,6 +493,7 @@ services:
volumes:
- contract-config:/tmp/cic/config/:ro
# metadata replacement server for swarm
cic-meta-server:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/cic-meta:${TAG:-latest}
@ -475,6 +532,7 @@ services:
volumes:
- ./apps/contract-migration/testdata/pgp/:/tmp/cic/pgp
cic-user-tasker:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/cic-user:${TAG:-latest}
build:
@ -510,6 +568,7 @@ services:
- ./apps/contract-migration/testdata/pgp/:/usr/src/secrets/
command: "/root/start_cic_user_tasker.sh -q cic-ussd -vv"
cic-user-server:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/cic-user:${TAG:-latest}
build:
@ -538,6 +597,7 @@ services:
- redis
command: "/root/start_cic_user_server.sh -vv"
cic-user-ussd-server:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/cic-user:${TAG:-latest}
build:
@ -575,6 +635,7 @@ services:
- ./apps/contract-migration/testdata/pgp/:/usr/src/secrets/
command: "/root/start_cic_user_ussd_server.sh -vv"
cic-notify-tasker:
image: ${DEV_DOCKER_REGISTRY:-registry.gitlab.com/grassrootseconomics}/cic-notify:${TAG:-latest}
build:

View File

@ -6,4 +6,7 @@ set -e
TAG=${TAG?Variable not set} \
docker-compose \
-f docker-compose.yml \
build
build \
--no-cache \
--parallel \
--progress plain

49
test.sh Normal file
View File

@ -0,0 +1,49 @@
# 0000
# 0001
# 0010
# 0011
# 0100
# 0101
# 0111
# 1000
# 1001
# 1010
# 1011
# 1100
# 1101
# 1111
RUN_MASK=31
LAST_BIT_POS=5
RUN_MASK_HIGHEST=0
for ((i=$LAST_BIT_POS; i>0; i--)); do
b=$((2**$((i-1))))
if [ $((b & $RUN_MASK)) -gt 0 ]; then
RUN_MASK_HIGHEST=$i
break
fi
done
echo $RUN_MASK_HIGHEST
bit=1
for ((i=0; i<$LAST_BIT_POS; i++)); do
runlevel="RUNLEVEL $bit"
if [[ $((RUN_MASK & $bit)) -eq ${bit} ]]; then
s="$runlevel - ${description[$i]}"
>&2 echo -e "\033[;96mRUNNING $s\033[;39m"
# source $((i+1))_${files[$i]}.sh
if [ $? -ne "0" ]; then
>&2 echo -e "\033[;31mFAILED $s\033[;39m"
exit 1;
fi
>&2 echo -e "\033[;32mSUCCEEDED $s\033[;39m"
>&2 echo -e "\033[;96mConfiguration state after $runlevel execution\033[;39m"
# confini-dump --schema-dir ./config
fi
bit=$((bit*2))
done