From f91fd623c5d7ccf27c8895d9388f67e04d0cb0de Mon Sep 17 00:00:00 2001 From: ravinsp <33562092+ravinsp@users.noreply.github.com> Date: Sun, 12 Jun 2022 23:35:20 +0530 Subject: [PATCH] Cluster mesh config. --- README.md | 15 +++++--- docker/scripts/cluster.sh | 78 ++++++++++++++++++++++++++++++++++++++- windows/hpdevkit.ps1 | 8 +++- 3 files changed, 91 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6868461..2cbc76e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ # Hot Pocket developer toolkit Developer toolkit for Hot Pocket smart contract development. This toolkit makes use of Docker to provide a cross-platform development tools for developers. -We use Docker containers to run Hot Pocket and smart contracts in a Linux environment. We also use Docker containers distributing developer tools so developers can use the tools on any platform as long as they install Docker. +We use Docker containers to run Hot Pocket and smart contracts in a Linux environment. We also use Docker containers to distribute developer tools so developers can use the tools on any platform as long as they install Docker. -## Docker +## Prerequisites +- [Docker](https://docs.docker.com/engine/install/) + +## Docker build Contains the docker image source files for cross-platform dev tools. ### Local build @@ -17,15 +20,15 @@ docker build -t hpdevkit . docker run -it --rm --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock hpdevkit cluster create 2 ``` -## Windows -Contains windows launcher scripts. Written using powershell and combiled to exe using [ps2exe](https://github.com/MScholtes/PS2EXE). +## Windows build +Contains windows launcher scripts. Written using powershell and compiled to exe using [ps2exe](https://github.com/MScholtes/PS2EXE). -## Prerequisites +### Prerequisites ```powershell Install-Module ps2exe ``` -### Generate exe +### Generate executable ```powershell cd windows Invoke-ps2exe .\hpdevkit.ps1 hpdevkit.exe diff --git a/docker/scripts/cluster.sh b/docker/scripts/cluster.sh index 4068d18..b946fbd 100644 --- a/docker/scripts/cluster.sh +++ b/docker/scripts/cluster.sh @@ -11,7 +11,8 @@ bundle_mount=$BUNDLE_MOUNT hotpocket_image=$HOTPOCKET_IMAGE config_overrides_file=$CONFIG_OVERRIDES_FILE -if [ "$command" = "create" ] || [ "$command" = "destroy" ] || [ "$command" = "start" ] || [ "$command" = "stop" ] || +if [ "$command" = "create" ] || [ "$command" = "bindmesh" ] || [ "$command" = "destroy" ] || \ + [ "$command" = "start" ] || [ "$command" = "stop" ] || \ [ "$command" = "logs" ] || [ "$command" = "sync" ] ; then echo "sub-command: $command" else @@ -71,9 +72,14 @@ function create_instance { # Create contract instance directory. docker run --rm --mount type=volume,src=$volume,dst=$volume_mount --rm $hotpocket_image new $volume_mount/node$node + let peer_port=22860+$node + let user_port=8080+$node + # Create container for hot pocket instance. local container_name="${container_prefix}_$node" - docker container create --name $container_name --privileged --mount type=volume,src=$volume,dst=$volume_mount $hotpocket_image run $(contract_dir_mount_path $node) + docker container create --name $container_name --privileged \ + -p $peer_port:$peer_port -p $user_port:$user_port --network $network --network-alias node$node \ + --mount type=volume,src=$volume,dst=$volume_mount $hotpocket_image run $(contract_dir_mount_path $node) } function change_instance_status { @@ -83,6 +89,72 @@ function change_instance_status { docker $action $container_name } + +# Function to generate JSON array string while skiping a given index. +function joinarr { + local arrname=$1[@] + local arr=("${!arrname}") + local ncount=$2 + local skip=$3 + + let prevlast=$ncount-2 + # Resetting prevlast if nothing is given to skip. + [ $skip -lt 0 ] && let prevlast=prevlast+1 + + local j=0 + local str="[" + for (( i=0; i<$ncount; i++ )) + do + if [ "$i" != "$skip" ] + then + str="$str\"${arr[i]}\"" + [ $j -lt $prevlast ] && str="$str," + let j=j+1 + fi + done + str="$str]" + echo $str +} + +# Update all instances hot pocket configs so they connect to each other as a cluster. +function bind_mesh { + local instance_count=$(get_container_count) + + # Collect pubkeys and peers of all nodes. + local all_pubkeys + local all_peers + local contract_id + for ((i=1; i<=$instance_count; i++)); + do + local contract_dir=$(contract_dir_mount_path $i) + local cfg_file=$contract_dir/cfg/hp.cfg + + # Use first instance contract id for all instances. + [ $i -eq 1 ] && contract_id=$(jq ".contract.id" $cfg_file) + + # Assign user and peer ports in incrementing order. + let peer_port=22860+$i + let user_port=8080+$i + + jq ".contract.id=$contract_id | .mesh.port=$peer_port | .user.port=$user_port" $cfg_file > $cfg_file.tmp \ + && mv $cfg_file.tmp $cfg_file + + all_pubkeys[i]=$(jq --raw-output ".node.public_key" $cfg_file) + all_peers[i]="node$i:${peer_port}" + done + + # Update unl and peer list for all instances. + local unl=$(joinarr all_pubkeys $instance_count -1) + for ((i=0; i<$instance_count; i++)); + do + let node=$i+1 + local contract_dir=$(contract_dir_mount_path $node) + local cfg_file=$contract_dir/cfg/hp.cfg + local peers=$(joinarr all_peers $instance_count $i) + jq ".contract.unl=$unl | .mesh.known_peers=$peers" $cfg_file > $cfg_file.tmp && mv $cfg_file.tmp $cfg_file + done +} + function create_cluster { ensure_cluser_not_exists @@ -168,6 +240,8 @@ function sync_contract_bundle { if [ $command = "create" ]; then ! validate_node_num_arg $cluster_size && echo "Invalid cluster size." && exit 1 create_cluster $cluster_size +elif [ $command = "bindmesh" ]; then + bind_mesh elif [ $command = "destroy" ]; then destroy_cluster elif [ $command = "start" ]; then diff --git a/windows/hpdevkit.ps1 b/windows/hpdevkit.ps1 index 9e76865..4ebcf16 100644 --- a/windows/hpdevkit.ps1 +++ b/windows/hpdevkit.ps1 @@ -59,6 +59,9 @@ function InitializeDeploymentCluster() { # Spin up management container. DevKitContainer -Mode "run" -Name $DeploymentContainerName -Detached -MountSock -MountVolume + + # Bind the instance mesh network config together. + ExecuteInDeploymentContainer -Cmd "cluster bindmesh" } } @@ -95,6 +98,7 @@ Function Deploy([string]$Path) { Write-Host "Hot Pocket devkit launcher" $Command = $args[0] +$CommandError = "Invalid command. Expected: deploy | clean | start | stop | logs" if ($Command) { Write-Host "command: $($Command) (cluster: $($Cluster))" @@ -115,9 +119,9 @@ if ($Command) { DevKitContainer -Mode "run" -AutoRemove -MountSock -Cmd "cluster $($args)" } else { - Write-Host "Invalid command. Expected: deploy | clean | logs" + Write-Host $CommandError } } else { - Write-Host "Please specify command." + Write-Host $CommandError } \ No newline at end of file