Files
hp-devkit/linux/hpdevkit.sh
2022-11-16 11:40:09 +05:30

320 lines
11 KiB
Bash
Executable File

#!/bin/bash
globalPrefix="hpdevkit"
version="0.1.0"
cluster="default"
clusterSize=$([ -z $HP_CLUSTER_SIZE ] && echo 3 || echo "$HP_CLUSTER_SIZE")
defaultNode=$([ -z $HP_DEFAULT_NODE ] && echo 1 || echo "$HP_DEFAULT_NODE")
devkitImage=$([ -z $HP_DEVKIT_IMAGE ] && echo "evernodedev/hpdevkit" || echo "$HP_DEVKIT_IMAGE")
instanceImage=$([ -z $HP_INSTANCE_IMAGE ] && echo "evernodedev/hotpocket:0.6.0-ubt.20.04-njs.16" || echo "$HP_INSTANCE_IMAGE")
hpUserPortBegin=$([ -z $HP_USER_PORT_BEGIN ] && echo 8081 || echo "$HP_USER_PORT_BEGIN")
hpPeerPortBegin=$([ -z $HP_PEER_PORT_BEGIN ] && echo 22861 || echo "$HP_PEER_PORT_BEGIN")
volumeMount=/$globalPrefix\_vol
volume=$globalPrefix\_$cluster\_vol
network=$globalPrefix\_$cluster\_net
containerPrefix=$globalPrefix\_$cluster\_node
bundleMount=$volumeMount/contract_bundle
deploymentContainerName=$globalPrefix\_$cluster\_deploymgr
codegenContainerName=$globalPrefix\_codegen
configOverridesFile="hp.cfg.override"
codegenOutputDir="/codegen-output"
cloudStorage="https://stevernode.blob.core.windows.net/evernode-dev-bb7ec110-f72e-430e-b297-9210468a4cbb"
bashScriptUrl="$cloudStorage/$globalPrefix-linux/$globalPrefix.sh"
hpdevkitDataDir="/etc/$globalPrefix"
versionTimestampFile="$hpdevkitDataDir/linuxlauncherscript.timestamp"
scriptBinPath="/usr/bin/$globalPrefix"
function devKitContainer() {
command="docker $1 -it"
if [ ! -z "$NAME" ]; then
command+=" --name $NAME"
fi
if [ ! -z "$DETACHED" ]; then
command+=" -d"
fi
if [ ! -z "$AUTOREMOVE" ]; then
command+=" --rm"
fi
if [ ! -z "$MOUNTSOCK" ]; then
command+=" --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock"
fi
if [ ! -z "$MOUNTVOLUME" ]; then
command+=" --mount type=volume,src=$volume,dst=$volumeMount"
fi
if [ ! -z "$ENTRYPOINT" ]; then
command+=" --entrypoint $ENTRYPOINT"
else
command+=" --entrypoint /bin/bash"
fi
if [ ! -z "$RESTARTPOLICY" ]; then
command+=" --restart $RESTARTPOLICY"
fi
command+=" -e CLUSTER=$cluster -e CLUSTER_SIZE=$clusterSize -e DEFAULT_NODE=$defaultNode -e VOLUME=$volume -e NETWORK=$network"
command+=" -e CONTAINER_PREFIX=$containerPrefix -e VOLUME_MOUNT=$volumeMount -e BUNDLE_MOUNT=$bundleMount -e HOTPOCKET_IMAGE=$instanceImage"
command+=" -e CONFIG_OVERRIDES_FILE=$configOverridesFile -e CODEGEN_OUTPUT=$codegenOutputDir"
command+=" -e HP_USER_PORT_BEGIN=$hpUserPortBegin -e HP_PEER_PORT_BEGIN=$hpPeerPortBegin"
command+=" $devkitImage"
if [ ! -z "$CMD" ]; then
if [ ! -z "$ENTRYPOINT" ]; then
command+=" $CMD"
else
command+=" -c '$CMD'"
fi
fi
eval $command
lastExitedCode=$?
if [ ! -z "STATUS" ]; then
if [ $lastExitedCode -eq 0 ]; then
return 0
else
return 1
fi
fi
}
function executeInContainer() {
if [ ! -z "$CONTAINERNAME" ]; then
cmd="docker exec -it $CONTAINERNAME /bin/bash -c '$1'"
! eval $cmd && echo "Docker execution failed."
fi
}
function initializeDeploymentCluster() {
docker inspect $deploymentContainerName &>/dev/null
if [[ $? -gt 0 ]]; then
echo "Initializing deployment cluster"
# Stop cluster if running. Create cluster if not exists.
AUTOREMOVE="true" MOUNTSOCK="true" CMD="cluster stop ; cluster create" devKitContainer run
# Spin up management container.
NAME="$deploymentContainerName" DETACHED="true" MOUNTSOCK="true" MOUNTVOLUME="true" RESTARTPOLICY="unless-stopped" devKitContainer run
# Bind the instance mesh network config together.
CONTAINERNAME="$deploymentContainerName" executeInContainer "cluster bindmesh"
fi
}
function teardownDeploymentCluster() {
docker stop $deploymentContainerName 2>/dev/null
docker rm $deploymentContainerName 2>/dev/null
AUTOREMOVE="true" MOUNTSOCK="true" CMD="cluster stop ; cluster destroy" devKitContainer run
}
function deploy() {
if [ ! -z "$1" ]; then
path="$1"
initializeDeploymentCluster
# If copying a directory, delete target bundle directory. If not create empty target bundle directory to copy a file.
prepareBundleDir=" "
if [[ -d "$path" ]]; then
prepareBundleDir="rm -rf $bundleMount"
else
prepareBundleDir="mkdir -p $bundleMount && rm -rf $bundleMount/* $bundleMount/.??*"
fi
CONTAINERNAME="$deploymentContainerName" executeInContainer "$prepareBundleDir"
docker cp "$path" "$deploymentContainerName:$bundleMount"
# Sync contract bundle to all instance directories in the cluster.
CONTAINERNAME="$deploymentContainerName" executeInContainer "cluster stop ; cluster sync ; cluster start"
if [ $defaultNode -gt 0 ]; then
echo "Streaming logs of node $defaultNode:"
CONTAINERNAME="$deploymentContainerName" executeInContainer "cluster logs $defaultNode"
fi
else
echo "Please specify directory or file path to deploy."
fi
}
function codeGenerator() {
platform=$1
apptype=$2
projName=$3
if [[ -d $projName ]]; then
echo "Directory '$projName' already exists."
exit 1
fi
NAME="$codegenContainerName" ENTRYPOINT="codegen" STATUS="true" CMD="$platform $apptype $projName" devKitContainer run
lastExitedCode=$?
if [ $lastExitedCode == 0 ]; then
! docker cp $codegenContainerName:$codegenOutputDir ./$projName && echo "Project '$projName' generation failed." && exit 1
echo "Project '$projName' created."
fi
docker rm $codegenContainerName &>/dev/null
}
function removeLauncher() {
rm $scriptBinPath
}
function createLauncher() {
# Copying the current script file to the bin directory
! curl -fsSL $bashScriptUrl --output $scriptBinPath &>/dev/null && echo "Error in creating launcher." && return 1
! chmod +x $scriptBinPath &>/dev/null && echo "Error in changing permission for the launcher." && return 1
return 0
}
function updateDevKit() {
local latestVersionTimestamp=$(online_version_timestamp $bashScriptUrl)
[ -z "$latestVersionTimestamp" ] && echo "Online launcher not found." && exit 1
# If Timestamp file is not found, re-run the install function.
if [ ! -f $versionTimestampFile ]; then
install
else
local currentVersionTimestamp=$(cat $versionTimestampFile)
if [ "$currentVersionTimestamp" == "$latestVersionTimestamp" ]; then
echo "HotPocket devkit is already upto date."
else
echo "Found a new version of HotPocket devkit."
! removeLauncher && echo "Removing the launcher failed."
! createLauncher && echo "Launcher creation failed."
echo $latestVersionTimestamp >$versionTimestampFile
echo "HotPocket devkit update completed !!"
fi
fi
echo "Updating docker images..."
docker pull $devkitImage &>/dev/null
docker pull $instanceImage &>/dev/null
# Clear if there's already deployed cluster since they are outdated now.
if docker inspect $deploymentContainerName &>/dev/null; then
echo "Cleaning the deployed contracts..."
teardownDeploymentCluster
fi
echo "Update Completed !!"
echo "NOTE: You need to re-deploy your contracts to make the new changes effective."
}
function checkExistance() {
command -v hpdevkit &>/dev/null && [ -f $scriptBinPath ] && [ -d $hpdevkitDataDir ] &&
echo -e "hpdevkit is already installed on your host. \nUse the 'hpdevkit' start your local HotPocket testing." &&
exit 1
}
function online_version_timestamp() {
# Send HTTP HEAD request and get last modified timestamp of the installer package or setup.sh.
curl --silent --head $1 | grep 'Last-Modified:' | sed 's/[^ ]* //'
}
function install() {
checkExistance
if [[ ! -d $hpdevkitDataDir ]]; then
! mkdir $hpdevkitDataDir && echo "Data path creation error." && exit 1
fi
! createLauncher && echo "Launcher creation failed."
# Creating timestamp file
local latestVersionTimestamp=$(online_version_timestamp $bashScriptUrl)
echo $latestVersionTimestamp >$versionTimestampFile
}
function uninstall() {
# Remove deployment cluster if exist.
if docker inspect $deploymentContainerName &>/dev/null; then
echo "Cleaning the deployed contracts..."
teardownDeploymentCluster
fi
# Remove docker images if exist.
if docker image inspect $devkitImage &>/dev/null; then
echo "Removing devkit docker image..."
docker image rm $devkitImage &>/dev/null
fi
if docker image inspect $instanceImage &>/dev/null; then
echo "Removing instance docker image..."
docker image rm $instanceImage &>/dev/null
fi
echo "Removing binaries..."
if [[ -d $hpdevkitDataDir ]]; then
rm -r $hpdevkitDataDir
fi
echo "Removing the launcher..."
removeLauncher
}
function is_user_root() {
[ "$(id -u)" -ne 0 ] && echo "Please run with root privileges (sudo)." && exit 1
}
echo "HotPocket devkit launcher ($version)"
funcCommand=$1
helpMessage="\nAvailable commands: hpdevkit <COMMAND> <ARGUMENTS if any>
\n COMMANDS:
\n\tdeploy <Contract path>
\n\tclean
\n\tstart <Node number>
\n\tstop <Node number>
\n\tlogs <Node number>
\n\tgen <Platform> <App type> <Project name>
\n\tupdate
\n\tuninstall
\n\thelp"
funcCommandError="Invalid command. Try 'hpdevkit help' for available commands."
if [ ! -z "$funcCommand" ]; then
if [ "$funcCommand" == "gen" ]; then
echo "Code generator"
codeGenerator $2 $3 $4
elif [ "$funcCommand" == "update" ]; then
is_user_root
echo "Checking for updates..."
updateDevKit
elif [ "$funcCommand" == "install" ]; then
is_user_root
echo "Installing..."
install
echo "Installation completed."
echo -e $helpMessage
elif [ "$funcCommand" == "uninstall" ]; then
is_user_root
echo "Unstalling hpdevkit..."
uninstall
echo -e "Unstallation Completed.\nThank you for using HotPocket devkit !"
elif [ "$funcCommand" == "help" ]; then
echo -e $helpMessage
else
echo "command: $funcCommand (cluster: $cluster)"
if [ "$funcCommand" == "deploy" ]; then
deploy "$2"
elif [ "$funcCommand" == "clean" ]; then
teardownDeploymentCluster
elif [[ "$funcCommand" == "logs" || "$funcCommand" == "start" || "$funcCommand" == "stop" ]]; then
AUTOREMOVE="true" MOUNTSOCK="true" ENTRYPOINT="cluster" CMD="$1 $2" devKitContainer run
else
echo "$funcCommandError"
fi
fi
else
echo -e $helpMessage
fi
exit 0