Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
first test to add reputer
Browse files Browse the repository at this point in the history
  • Loading branch information
okedeji committed Apr 22, 2024
1 parent d3152b2 commit 1090987
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 104 deletions.
84 changes: 11 additions & 73 deletions allocmd/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from jinja2 import Environment, FileSystemLoader
from importlib.resources import files
from termcolor import colored, cprint
from .utilities.utils import generate_all_files, print_allora_banner, run_key_generate_command, deployWorker, deployValidator, generateWorkerAccount, generateProdCompose, check_docker_running
from .utilities.typings import Command
from .utilities.utils import generate_all_files, print_allora_banner, run_key_generate_command, deployWorker, deployValidator, generateWorkerAccount, generateProdCompose, check_docker_running, blocklessNode
from .utilities.typings import Command, BlocklessNodeType
from .utilities.constants import cliVersion

template_path = files('allocmd').joinpath('templates')
Expand All @@ -26,82 +26,20 @@ def generate():
@click.option('--env', 'environment', required=True, type=click.Choice(['dev', 'prod']), help='Environment to generate for')
@click.option('--name', required=False, help='Name of the worker.')
@click.option('--topic', required=False, type=int, help='The topic ID the worker is registered with.')
def worker(environment, name=None, topic=None):
def worker(environment, type= BlocklessNodeType.worker, name=None, topic=None):
"""Initialize your Allora Worker Node with necessary boilerplates"""

if not check_docker_running():
cprint("Docker is not running on your machine, please start docker before running this command", 'red')
return
blocklessNode(environment, env, type, name, topic)

if environment == 'dev':
if topic is None:
cprint("You must provide topic id when running development init.", 'red')
return
elif name is None:
cprint("You must provide name when running development init.", 'red')
return
@generate.command()
@click.option('--env', 'environment', required=True, type=click.Choice(['dev', 'prod']), help='Environment to generate for')
@click.option('--name', required=False, help='Name of the reputer.')
@click.option('--topic', required=False, type=int, help='The topic ID the reputer is registered with.')
def reputer(environment, type= BlocklessNodeType.reputer, name=None, topic=None):
"""Initialize your Allora Reputer Node with necessary boilerplates"""

blocklessNode(environment, env, type, name, topic)

print_allora_banner()
cprint("Welcome to the Allora CLI!", 'green', attrs=['bold'])
print(colored("Allora CLI assists in the seamless creation and deployment of Allora worker nodes", 'yellow'))
print(colored("to provide model inference to the Allora Chain.", 'yellow'))
cprint(f"\nThis command will generate some files in the directory named '{name}'.", 'cyan')

if click.confirm(colored("\nWould you like to proceed?", 'white', attrs=['bold']), default=True):
cprint("\nProceeding with the creation of worker node directory...", 'green')

head_peer_id = run_key_generate_command(name)

file_configs = [
{
"template_name": "Dockerfile.j2",
"file_name": "Dockerfile",
"context": {}
},
{
"template_name": "main.py.j2",
"file_name": "main.py",
"context": {}
},
{
"template_name": "dev-docker-compose.yaml.j2",
"file_name": "dev-docker-compose.yaml",
"context": {"head_peer_id": head_peer_id, "topic_id": topic}
},
{
"template_name": "requirements.txt.j2",
"file_name": "requirements.txt",
"context": {}
},
{
"template_name": "gitignore.j2",
"file_name": ".gitignore",
"context": {}
},
{
"template_name": "env.j2",
"file_name": ".env",
"context": {}
},
{
"template_name": "config.yaml.j2",
"file_name": "config.yaml",
"context": {"name": name, "topic_id": topic}
}
]

generate_all_files(env, file_configs, Command.INIT, name)

generateWorkerAccount(name)
else:
cprint("\nOperation cancelled.", 'red')
elif environment == 'prod':
devComposePath = os.path.join(os.getcwd(), 'dev-docker-compose.yaml')
if not os.path.exists(devComposePath):
cprint("You must initialize the worker on dev please run allocmd init --env dev --name <worker name> --topic <topic id> and then run the prod init in the directory created", 'red')
else:
generateProdCompose(env)

@generate.command()
@click.option('--name',required=True, help='Name of the validator.')
Expand Down
10 changes: 2 additions & 8 deletions allocmd/templates/config.yaml.j2
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
# place all worker configuration variables here
# place all {{ b7s_type }} configuration variables here

name: {{ name }}
faucet_url: https://faucet.testnet.allora.network/
worker:
{{ b7s_type }}:
boot_nodes: /dns4/head-0.testnet.allora.network/tcp/9010/p2p/12D3KooWGAA1C2UNyj51QaGX5aXnVzRqeaqhyhUFFJixdqshwWC3
chain_rpc_address: https://allora-rpc.testnet.allora.network/
chain_topic_id: {{ topic_id }}
mnemonic: ""
hex_coded_pk: ""
address: ""
validator:
image_uri: alloranetwork/allora-chain
image_tag: latest
mnemonic: ""
hex_coded_pk: ""
address: ""
14 changes: 7 additions & 7 deletions allocmd/templates/dev-docker-compose.yaml.j2
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
version: "3.8"
services:
worker:
container_name: worker
{{ b7s_type }}:
container_name: {{ b7s_type }}
build: .
command:
- allora-node
- --role=worker
- --peer-db=/data/worker/peer-database
- --function-db=/data/worker/function-database
- --peer-db=/data/{{ b7s_type }}/peer-database
- --function-db=/data/{{ b7s_type }}/function-database
- --runtime-path=/app/runtime
- --runtime-cli=bls-runtime
- --workspace=/data/worker/workspace
- --private-key=/data/worker/key/priv.bin
- --workspace=/data/{{ b7s_type }}/workspace
- --private-key=/data/{{ b7s_type }}/key/priv.bin
- --log-level=debug
- --port=9011
- --topic={{ topic_id }}
Expand All @@ -27,7 +27,7 @@ services:
networks:
b7s-local:
aliases:
- worker
- {{ b7s_type }}
ipv4_address: 172.19.0.5

head:
Expand Down
2 changes: 1 addition & 1 deletion allocmd/utilities/constants.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cliVersion = "0.3.7"
cliVersion = "0.3.8"
5 changes: 5 additions & 0 deletions allocmd/utilities/typings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
class Command(Enum):
DEPLOY = auto()
INIT = auto()


class BlocklessNodeType(Enum):
worker = auto()
reputer = auto()
114 changes: 99 additions & 15 deletions allocmd/utilities/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
from termcolor import colored, cprint
import time
import shutil
from .typings import Command
from .typings import Command, BlocklessNodeType
import re
import yaml

def create_worker_account(worker_name, faucet_url, type='worker'):
def create_worker_account(worker_name, faucet_url, type:BlocklessNodeType):
current_file_dir = os.path.dirname(os.path.abspath(__file__))
cli_tool_dir = os.path.dirname(current_file_dir)
allora_chain_dir = os.path.join(cli_tool_dir, 'allora-chain')
Expand Down Expand Up @@ -78,7 +78,7 @@ def create_worker_account(worker_name, faucet_url, type='worker'):
f'{faucet_url}/send/testnet/{address}'
], stdout=subprocess.DEVNULL)

print(colored(f"keys created and testnet-funded for this worker. please check config.yaml for your address and mnemonic", "green"))
print(colored(f"keys created and testnet-funded for this {type}. please check config.yaml for your address and mnemonic", "green"))
return mnemonic, hex_coded_pk, address
else:
print(colored("'make' is not available in the system's PATH. Please install it or check your PATH settings.", "red"))
Expand Down Expand Up @@ -120,23 +120,23 @@ def generate_all_files(env: Environment, file_configs, command: Command, name =
if command == Command.INIT:
cprint("\nAll files bootstrapped successfully. ALLORA!!!", 'green', attrs=['bold'])

def run_key_generate_command(worker_name):
def run_key_generate_command(worker_name, type:BlocklessNodeType):
command = (
f'docker run -it --entrypoint=bash -v "$(pwd)/{worker_name}/data":/data '
'alloranetwork/allora-inference-base:latest '
'-c "mkdir -p /data/head/key /data/worker/key && (cd /data/head/key && allora-keys) && (cd /data/worker/key && allora-keys)"'
f'-c "mkdir -p /data/head/key /data/{type}/key && (cd /data/head/key && allora-keys) && (cd /data/{type}/key && allora-keys)"'
)
try:
subprocess.run(command, shell=True, check=True)
peer_id_path = os.path.join(os.getcwd(), f'{worker_name}/data/head/key', 'identity')
with open(peer_id_path, 'r') as file:
cprint(f"local workers identity generated successfully.", 'cyan')
cprint(f"local {type} identity generated successfully.", 'cyan')
head_peer_id = file.read().strip()
return head_peer_id
except subprocess.CalledProcessError as e:
click.echo(f"error generating local workers identity: {e}", err=True)
click.echo(f"error generating local {type} identity: {e}", err=True)

def generateWorkerAccount(worker_name):
def generateWorkerAccount(worker_name, type:BlocklessNodeType):
config_path = os.path.join(os.getcwd(), worker_name, 'config.yaml')
try:
with open(config_path, 'r') as file:
Expand All @@ -148,7 +148,7 @@ def generateWorkerAccount(worker_name):
worker_name = config['name']
faucet_url = config['faucet_url']
account_details = None
if not config['worker']['mnemonic'] or not config['worker']['hex_coded_pk'] or not config['worker']['address']:
if not config[type]['mnemonic'] or not config[type]['hex_coded_pk'] or not config[type]['address']:
account_details = create_worker_account(worker_name, faucet_url, 'worker')

mnemonic = account_details[0] if account_details else config['worker']['mnemonic']
Expand All @@ -162,11 +162,10 @@ def generateWorkerAccount(worker_name):
with open(config_path, 'w') as file:
yaml.safe_dump(config, file)

def generateProdCompose(env: Environment):
def generateProdCompose(env: Environment, type:BlocklessNodeType):
"""Deploy resource production kubernetes cluster"""

subprocess.run("mkdir -p ./data/scripts", shell=True, check=True)
# subprocess.run("chmod -R +rx ./data/scripts", shell=True, check=True)

try:
result = subprocess.run("chmod -R +rx ./data/scripts", shell=True, check=True, capture_output=True, text=True)
Expand All @@ -185,10 +184,10 @@ def generateProdCompose(env: Environment):
return

worker_name = config['name']
hex_coded_pk = config['worker']['hex_coded_pk']
boot_nodes = config['worker']['boot_nodes']
chain_rpc_address = config['worker']['chain_rpc_address']
chain_topic_id = config['worker']['chain_topic_id']
hex_coded_pk = config[type]['hex_coded_pk']
boot_nodes = config[type]['boot_nodes']
chain_rpc_address = config[type]['chain_rpc_address']
chain_topic_id = config[type]['chain_topic_id']

file_configs = [
{
Expand All @@ -215,6 +214,91 @@ def generateProdCompose(env: Environment):
cprint(f"production docker compose file generated to be deployed", 'green')
cprint(f"please run chmod -R +rx ./data/scripts to grant script access to the image", 'yellow')


def blocklessNode(environment, env, type:BlocklessNodeType, name=None, topic=None):
"""Initialize your Allora Worker Node with necessary boilerplates"""

if not check_docker_running():
cprint("Docker is not running on your machine, please start docker before running this command", 'red')
return

if environment == 'dev':
if topic is None:
cprint(f"You must provide topic id when generating {type} in development", 'red')
return
elif name is None:
cprint(f"You must provide name when generating {type} in development", 'red')
return

print_allora_banner()
cprint("Welcome to the Allora CLI!", 'green', attrs=['bold'])
print(colored(f"Allora CLI assists in the seamless creation and deployment of Allora {type} nodes", 'yellow'))
cprint(f"\nThis command will generate some files in the directory named '{name}'.", 'cyan')

if click.confirm(colored("\nWould you like to proceed?", 'white', attrs=['bold']), default=True):
cprint(f"\nProceeding with the creation of {type} node directory...", 'green')

head_peer_id = run_key_generate_command(name, type)

file_configs = [
{
"template_name": "Dockerfile.j2",
"file_name": "Dockerfile",
"context": {}
},
{
"template_name": "main.py.j2",
"file_name": "main.py",
"context": {}
},
{
"template_name": "dev-docker-compose.yaml.j2",
"file_name": "dev-docker-compose.yaml",
"context": {"head_peer_id": head_peer_id, "topic_id": topic, "b7s_type": type}
},
{
"template_name": "requirements.txt.j2",
"file_name": "requirements.txt",
"context": {}
},
{
"template_name": "gitignore.j2",
"file_name": ".gitignore",
"context": {}
},
{
"template_name": "env.j2",
"file_name": ".env",
"context": {}
},
{
"template_name": "config.yaml.j2",
"file_name": "config.yaml",
"context": {"name": name, "topic_id": topic, "b7s_type": type}
}
]

generate_all_files(env, file_configs, Command.INIT, name)

generateWorkerAccount(name, type)
else:
cprint("\nOperation cancelled.", 'red')
elif environment == 'prod':
devComposePath = os.path.join(os.getcwd(), 'dev-docker-compose.yaml')
if not os.path.exists(devComposePath):
cprint(f"You must initialize the {type} on dev please run allocmd generate {type} --env dev --name <{type} name> --topic <topic id> and then run the prod generate in the directory created", 'red')
else:
generateProdCompose(env)










def deployWorker(env: Environment):
"""Deploy resource production kubernetes cluster"""

Expand Down

0 comments on commit 1090987

Please sign in to comment.