provisioning/taskservs/polkadot/solochain/default/install-polkadot-solochain.sh

245 lines
8.6 KiB
Bash
Raw Permalink Normal View History

#!/bin/bash
# Info: Script to install Polkadot Solochain
# Author: Provisioning System
# Release: 1.0
# Date: 2025-07-24
USAGE="install-polkadot-solochain.sh"
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
[ -r "env-polkadot-solochain" ] && . ./env-polkadot-solochain
POLKADOT_VERSION=${POLKADOT_VERSION:-stable2024}
POLKADOT_TEMPLATE_REPO="https://github.com/paritytech/polkadot-sdk-solochain-template.git"
POLKADOT_RUN_USER=${POLKADOT_RUN_USER:-polkadot}
POLKADOT_RUN_GROUP=${POLKADOT_RUN_GROUP:-polkadot}
POLKADOT_RUN_USER_HOME=${POLKADOT_RUN_USER_HOME:-/home/polkadot}
POLKADOT_WORK_PATH=${POLKADOT_WORK_PATH:-/var/lib/polkadot}
POLKADOT_CONFIG_PATH=${POLKADOT_CONFIG_PATH:-/etc/polkadot}
POLKADOT_BIN_PATH=${POLKADOT_BIN_PATH:-/usr/local/bin}
POLKADOT_NODE_BINARY=${POLKADOT_NODE_BINARY:-solochain-template-node}
POLKADOT_BUILD_PATH="/opt/polkadot-solochain-build"
POLKADOT_BASE_PATH=${POLKADOT_BASE_PATH:-/var/lib/polkadot/data}
POLKADOT_KEYSTORE_PATH=${POLKADOT_KEYSTORE_PATH:-/var/lib/polkadot/keystore}
POLKADOT_SYSTEMCTL_MODE=${POLKADOT_SYSTEMCTL_MODE:-enabled}
echo "Installing Polkadot Solochain ${POLKADOT_VERSION}..."
# Install system dependencies
echo "Installing system dependencies..."
if command -v apt-get >/dev/null 2>&1; then
apt-get update
apt-get install -y curl git build-essential pkg-config libssl-dev protobuf-compiler clang cmake
elif command -v yum >/dev/null 2>&1; then
yum groupinstall -y "Development Tools"
yum install -y curl git openssl-devel protobuf-compiler clang cmake pkg-config
elif command -v dnf >/dev/null 2>&1; then
dnf groupinstall -y "Development Tools"
dnf install -y curl git openssl-devel protobuf-compiler clang cmake pkg-config
else
echo "Package manager not found. Please install dependencies manually."
exit 1
fi
# Install Rust if not present
if ! command -v rustc >/dev/null 2>&1; then
echo "Installing Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
rustup default stable
rustup target add wasm32-unknown-unknown
fi
# Create user and group
if ! id "$POLKADOT_RUN_USER" &>/dev/null; then
groupadd -r "$POLKADOT_RUN_GROUP"
useradd -r -g "$POLKADOT_RUN_GROUP" -d "$POLKADOT_RUN_USER_HOME" -s /bin/bash -c "Polkadot service user" "$POLKADOT_RUN_USER"
fi
# Create directories
mkdir -p "$POLKADOT_CONFIG_PATH"
mkdir -p "$POLKADOT_WORK_PATH"
mkdir -p "$POLKADOT_BASE_PATH"
mkdir -p "$POLKADOT_KEYSTORE_PATH"
mkdir -p "$POLKADOT_RUN_USER_HOME"
mkdir -p "$POLKADOT_BUILD_PATH"
# Clone and build Polkadot solochain template
echo "Cloning Polkadot solochain template..."
cd "$POLKADOT_BUILD_PATH"
if [ ! -d "polkadot-sdk-solochain-template" ]; then
git clone "$POLKADOT_TEMPLATE_REPO" polkadot-sdk-solochain-template
fi
cd polkadot-sdk-solochain-template
# Checkout specific version if needed
if [ "$POLKADOT_VERSION" != "stable2024" ] && [ "$POLKADOT_VERSION" != "latest" ]; then
git checkout "$POLKADOT_VERSION" || echo "Version $POLKADOT_VERSION not found, using default branch"
fi
echo "Building Polkadot solochain node (this may take 20-30 minutes)..."
export RUST_LOG=info
# Build the node
cargo build --release
if [ ! -f "target/release/$POLKADOT_NODE_BINARY" ]; then
echo "Failed to build Polkadot solochain node"
exit 1
fi
# Install binary
echo "Installing binary..."
cp "target/release/$POLKADOT_NODE_BINARY" "$POLKADOT_BIN_PATH/"
chmod +x "$POLKADOT_BIN_PATH/$POLKADOT_NODE_BINARY"
# Create chain specification if not exists
echo "Generating chain specification..."
if [ ! -f "$POLKADOT_CONFIG_PATH/local-testnet.json" ]; then
cd "$POLKADOT_BUILD_PATH/polkadot-sdk-solochain-template"
# Generate raw chain spec
"$POLKADOT_BIN_PATH/$POLKADOT_NODE_BINARY" build-spec --disable-default-bootnode --chain local > "$POLKADOT_CONFIG_PATH/local-testnet-plain.json"
"$POLKADOT_BIN_PATH/$POLKADOT_NODE_BINARY" build-spec --chain "$POLKADOT_CONFIG_PATH/local-testnet-plain.json" --raw --disable-default-bootnode > "$POLKADOT_CONFIG_PATH/local-testnet.json"
fi
# Create node key if not exists
if [ ! -f "$POLKADOT_CONFIG_PATH/node-key" ] && [ -z "$POLKADOT_NODE_KEY" ]; then
echo "Generating node key..."
openssl rand -hex 32 > "$POLKADOT_CONFIG_PATH/node-key"
fi
# Create runtime configuration
cat > "$POLKADOT_CONFIG_PATH/runtime-config.json" << EOF
{
"name": "${POLKADOT_RUNTIME_NAME:-solochain-template}",
"version": "${POLKADOT_RUNTIME_VERSION:-1.0.0}",
"pvm_enabled": ${POLKADOT_PVM_ENABLED:-true},
"wasm_execution": "${POLKADOT_WASM_EXECUTION:-compiled}",
"heap_pages": ${POLKADOT_HEAP_PAGES:-64}
}
EOF
# Set ownership
chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_WORK_PATH"
chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_BASE_PATH"
chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_KEYSTORE_PATH"
chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_RUN_USER_HOME"
chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_CONFIG_PATH"
# Create systemd service file
cat > /etc/systemd/system/polkadot-solochain.service << EOF
[Unit]
Description=Polkadot Solochain Node
Documentation=https://docs.polkadot.com/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=$POLKADOT_RUN_USER
Group=$POLKADOT_RUN_GROUP
EnvironmentFile=$POLKADOT_CONFIG_PATH/node.env
WorkingDirectory=$POLKADOT_WORK_PATH
ExecStart=$POLKADOT_BIN_PATH/$POLKADOT_NODE_BINARY \\
--base-path $POLKADOT_BASE_PATH \\
--chain $POLKADOT_CONFIG_PATH/local-testnet.json \\
--port 30333 \\
--rpc-port ${POLKADOT_RPC_PORT:-9944} \\
--rpc-bind-addr ${POLKADOT_RPC_BIND_ADDR:-127.0.0.1} \\
--validator \\
--name \${POLKADOT_NODE_NAME:-SolochainNode} \\
--execution ${POLKADOT_EXECUTION_STRATEGY:-wasm} \\
--state-cache-size ${POLKADOT_STATE_CACHE_SIZE:-67108864} \\
--log ${POLKADOT_LOG_LEVEL:-info}
Restart=always
RestartSec=10
# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$POLKADOT_WORK_PATH $POLKADOT_BASE_PATH $POLKADOT_KEYSTORE_PATH $POLKADOT_CONFIG_PATH
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# Resource limits
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
# Create environment file for systemd service
cat > "$POLKADOT_CONFIG_PATH/node.env" << EOF
POLKADOT_NODE_NAME=${POLKADOT_NETWORK_NAME:-SolochainNode}
RUST_LOG=${POLKADOT_LOG_LEVEL:-info}
EOF
# Load additional environment variables from template if available
if [ -f "env-polkadot-solochain" ]; then
cat env-polkadot-solochain >> "$POLKADOT_CONFIG_PATH/node.env"
fi
# Initialize keys for development if in dev mode
if [ "${POLKADOT_DEV_MODE:-false}" = "true" ] || [ "${POLKADOT_ALICE_VALIDATOR:-false}" = "true" ]; then
echo "Setting up development keys..."
sudo -u "$POLKADOT_RUN_USER" "$POLKADOT_BIN_PATH/$POLKADOT_NODE_BINARY" key insert \
--base-path "$POLKADOT_BASE_PATH" \
--chain "$POLKADOT_CONFIG_PATH/local-testnet.json" \
--scheme Sr25519 \
--suri "//Alice" \
--key-type aura \
--password-interactive < /dev/null || true
sudo -u "$POLKADOT_RUN_USER" "$POLKADOT_BIN_PATH/$POLKADOT_NODE_BINARY" key insert \
--base-path "$POLKADOT_BASE_PATH" \
--chain "$POLKADOT_CONFIG_PATH/local-testnet.json" \
--scheme Ed25519 \
--suri "//Alice" \
--key-type gran \
--password-interactive < /dev/null || true
fi
# Enable and start service
systemctl daemon-reload
systemctl "$POLKADOT_SYSTEMCTL_MODE" polkadot-solochain.service
if [ "$POLKADOT_SYSTEMCTL_MODE" = "enabled" ]; then
systemctl start polkadot-solochain.service
# Wait a moment for service to start
sleep 5
fi
echo "Polkadot Solochain installation completed!"
echo "Service: polkadot-solochain.service"
echo "RPC endpoint: ws://${POLKADOT_RPC_BIND_ADDR:-127.0.0.1}:${POLKADOT_RPC_PORT:-9944}"
echo "HTTP RPC endpoint: http://${POLKADOT_RPC_BIND_ADDR:-127.0.0.1}:${POLKADOT_HTTP_PORT:-9933}"
echo "Configuration: $POLKADOT_CONFIG_PATH/"
echo "Data directory: $POLKADOT_BASE_PATH"
echo "Keystore: $POLKADOT_KEYSTORE_PATH"
echo ""
echo "Connect with Polkadot-JS Apps:"
echo "https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F${POLKADOT_RPC_BIND_ADDR:-127.0.0.1}%3A${POLKADOT_RPC_PORT:-9944}"
# Display service status
if systemctl is-active --quiet polkadot-solochain.service; then
echo "✅ Polkadot solochain service is running"
else
echo "⚠️ Polkadot solochain service status:"
systemctl status polkadot-solochain.service --no-pager -l
fi
# Cleanup build directory if requested
if [ "${POLKADOT_CLEANUP_BUILD:-false}" = "true" ]; then
echo "Cleaning up build directory..."
rm -rf "$POLKADOT_BUILD_PATH"
fi