Files
pezkuwi-validator-v1.0.0/setup.sh
T
pezkuwichain 046efcc17d fix: Run SDK and frontend builds as actual user
**Problem**: cargo and npm commands were running as root when script
was executed with sudo, causing permission and PATH issues.

**Solution**:
- Detect actual user with $SUDO_USER in setup_sdk()
- Detect actual user with $SUDO_USER in setup_frontend()
- Run cargo build as actual user with proper PATH
- Run npm install/build as actual user

**Changes**:
- setup_sdk: Added ACTUAL_USER detection and su command for cargo
- setup_frontend: Added ACTUAL_USER detection and su for npm commands
- Both functions now source cargo env and run in user context

This ensures all builds happen with correct permissions and PATH
for the user who invoked sudo.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 06:35:00 +03:00

543 lines
15 KiB
Bash
Executable File

#!/bin/bash
# ========================================
# Pezkuwi Validator Setup Script v2.0.0
# ========================================
# This script automates the entire validator setup process
# Usage: ./setup.sh [validator_number]
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SHARED_DIR="$SCRIPT_DIR/shared"
VALIDATORS_DIR="$SCRIPT_DIR/validators"
# Function to print section headers
print_header() {
echo -e "\n${BLUE}========================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}========================================${NC}\n"
}
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to check dependency and display status
check_dependency() {
local cmd=$1
local name=$2
local version_cmd=$3
if command_exists "$cmd"; then
local version=$($version_cmd 2>&1 | head -n 1 || echo "unknown")
echo -e "${GREEN}${NC} $name: ${GREEN}Installed${NC} ($version)"
return 0
else
echo -e "${RED}${NC} $name: ${RED}Not installed${NC}"
return 1
fi
}
# Get validator number from argument or prompt
get_validator_number() {
if [ -n "$1" ]; then
VALIDATOR_NUM=$1
else
read -p "Enter validator number (1-10): " VALIDATOR_NUM
fi
# Validate validator number
if ! [[ "$VALIDATOR_NUM" =~ ^[1-9]$|^10$ ]]; then
echo -e "${RED}Error: Validator number must be between 1 and 10${NC}"
exit 1
fi
VALIDATOR_DIR="$VALIDATORS_DIR/validator$VALIDATOR_NUM"
echo -e "${GREEN}Setting up Validator $VALIDATOR_NUM${NC}"
}
# Global variables for dependencies
missing_deps=()
RUST_MISSING=0
NODE_MISSING=0
# Check system dependencies
check_dependencies() {
print_header "Checking System Dependencies"
missing_deps=()
# Essential build tools
if ! check_dependency "git" "Git" "git --version"; then
missing_deps+=("git")
fi
if ! check_dependency "curl" "Curl" "curl --version"; then
missing_deps+=("curl")
fi
if ! check_dependency "wget" "Wget" "wget --version"; then
missing_deps+=("wget")
fi
# Build essentials
if ! check_dependency "gcc" "GCC" "gcc --version"; then
missing_deps+=("build-essential")
fi
if ! check_dependency "make" "Make" "make --version"; then
missing_deps+=("build-essential")
fi
# Check pkg-config
if ! check_dependency "pkg-config" "pkg-config" "pkg-config --version"; then
missing_deps+=("pkg-config")
fi
# Check libssl-dev
if ! dpkg -l | grep -q libssl-dev; then
echo -e "${RED}${NC} libssl-dev: ${RED}Not installed${NC}"
missing_deps+=("libssl-dev")
else
echo -e "${GREEN}${NC} libssl-dev: ${GREEN}Installed${NC}"
fi
# Check clang
if ! check_dependency "clang" "Clang" "clang --version"; then
missing_deps+=("clang")
fi
# Check Rust
if ! check_dependency "rustc" "Rust" "rustc --version"; then
RUST_MISSING=1
else
RUST_MISSING=0
fi
# Check Cargo
if ! check_dependency "cargo" "Cargo" "cargo --version"; then
RUST_MISSING=1
fi
# Check Node.js
if ! check_dependency "node" "Node.js" "node --version"; then
NODE_MISSING=1
else
NODE_MISSING=0
fi
# Check npm
if ! check_dependency "npm" "npm" "npm --version"; then
NODE_MISSING=1
fi
# Check systemd (should be available on Ubuntu)
if ! check_dependency "systemctl" "systemd" "systemctl --version"; then
echo -e "${YELLOW}Warning: systemd not found. Service management may not work.${NC}"
fi
# Check nginx
if ! check_dependency "nginx" "Nginx" "nginx -v"; then
missing_deps+=("nginx")
fi
}
# Install missing dependencies
install_dependencies() {
print_header "Installing Missing Dependencies"
echo "Updating package list..."
sudo apt-get update
# Install system packages
if [ ${#missing_deps[@]} -gt 0 ]; then
echo -e "\n${YELLOW}Installing system packages:${NC} ${missing_deps[*]}"
sudo apt-get install -y "${missing_deps[@]}"
echo -e "${GREEN}✓ System packages installed${NC}"
fi
# Install Rust if missing
if [ $RUST_MISSING -eq 1 ]; then
echo -e "\n${YELLOW}Installing Rust...${NC}"
echo "This may take a few minutes. Please wait..."
# Detect actual user (not root when using sudo)
ACTUAL_USER=${SUDO_USER:-$USER}
ACTUAL_HOME=$(eval echo ~$ACTUAL_USER)
echo "Installing Rust for user: $ACTUAL_USER"
# Install Rust as the actual user
su - $ACTUAL_USER -c 'curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --verbose'
# Configure Rust toolchain as the actual user
echo -e "\n${YELLOW}Configuring Rust toolchain...${NC}"
su - $ACTUAL_USER -c 'source $HOME/.cargo/env && rustup default stable'
su - $ACTUAL_USER -c 'source $HOME/.cargo/env && rustup update'
echo -e "\n${YELLOW}Adding WebAssembly target...${NC}"
su - $ACTUAL_USER -c 'source $HOME/.cargo/env && rustup target add wasm32-unknown-unknown'
echo -e "${GREEN}✓ Rust installed successfully for $ACTUAL_USER${NC}"
else
# Ensure wasm target is installed
echo -e "\n${YELLOW}Ensuring wasm32-unknown-unknown target...${NC}"
ACTUAL_USER=${SUDO_USER:-$USER}
su - $ACTUAL_USER -c 'source $HOME/.cargo/env && rustup target add wasm32-unknown-unknown 2>/dev/null' || true
fi
# Install Node.js if missing
if [ $NODE_MISSING -eq 1 ]; then
echo -e "\n${YELLOW}Installing Node.js...${NC}"
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
echo -e "${GREEN}✓ Node.js installed${NC}"
fi
echo -e "\n${GREEN}✓ All dependencies installed!${NC}"
}
# Clone and build pezkuwi-sdk
setup_sdk() {
print_header "Setting up pezkuwi-sdk"
mkdir -p "$SHARED_DIR"
cd "$SHARED_DIR"
if [ -d "pezkuwi-sdk" ]; then
echo -e "${YELLOW}pezkuwi-sdk already exists. Updating...${NC}"
cd pezkuwi-sdk
git fetch origin
git pull origin main || git pull origin master
else
echo "Cloning pezkuwi-sdk from GitHub..."
git clone --depth 1 https://github.com/pezkuwichain/pezkuwi-sdk.git
cd pezkuwi-sdk
fi
echo -e "\n${YELLOW}Building pezkuwi-sdk (Release mode)...${NC}"
echo "This may take 15-30 minutes..."
# Detect actual user for cargo build
ACTUAL_USER=${SUDO_USER:-$USER}
SDK_PATH="$SHARED_DIR/pezkuwi-sdk"
# Build the node in release mode as the actual user
echo "Building as user: $ACTUAL_USER"
su - $ACTUAL_USER -c "cd $SDK_PATH && source \$HOME/.cargo/env && cargo build --release"
echo -e "${GREEN}✓ pezkuwi-sdk built successfully${NC}"
}
# Clone and build DKSweb frontend
setup_frontend() {
print_header "Setting up DKSweb Frontend"
cd "$SHARED_DIR"
if [ -d "DKSweb" ]; then
echo -e "${YELLOW}DKSweb already exists. Updating...${NC}"
cd DKSweb
git fetch origin
git pull origin main || git pull origin master
else
echo "Cloning DKSweb from GitHub..."
# TODO: Replace with actual repository URL
git clone --depth 1 https://github.com/pezkuwichain/DKSweb.git
cd DKSweb
fi
# Detect actual user
ACTUAL_USER=${SUDO_USER:-$USER}
FRONTEND_PATH="$SHARED_DIR/DKSweb"
echo -e "\n${YELLOW}Installing frontend dependencies...${NC}"
su - $ACTUAL_USER -c "cd $FRONTEND_PATH && npm install"
echo -e "\n${YELLOW}Building frontend...${NC}"
su - $ACTUAL_USER -c "cd $FRONTEND_PATH && npm run build"
echo -e "${GREEN}✓ DKSweb frontend built successfully${NC}"
}
# Configure validator-specific settings
configure_validator() {
print_header "Configuring Validator $VALIDATOR_NUM"
# Calculate ports (each validator gets 10 ports starting from base)
BASE_PORT=$((30333 + ($VALIDATOR_NUM - 1) * 10))
P2P_PORT=$BASE_PORT
RPC_PORT=$((9944 + ($VALIDATOR_NUM - 1)))
WS_PORT=$((9945 + ($VALIDATOR_NUM - 1)))
PROMETHEUS_PORT=$((9615 + ($VALIDATOR_NUM - 1)))
echo "Validator $VALIDATOR_NUM ports:"
echo " P2P Port: $P2P_PORT"
echo " RPC Port: $RPC_PORT"
echo " WebSocket Port: $WS_PORT"
echo " Prometheus Port: $PROMETHEUS_PORT"
# Create validator config file
CONFIG_FILE="$VALIDATOR_DIR/config/validator.conf"
mkdir -p "$(dirname "$CONFIG_FILE")"
cat > "$CONFIG_FILE" << EOF
# Validator $VALIDATOR_NUM Configuration
VALIDATOR_NUM=$VALIDATOR_NUM
VALIDATOR_NAME="validator-$VALIDATOR_NUM"
P2P_PORT=$P2P_PORT
RPC_PORT=$RPC_PORT
WS_PORT=$WS_PORT
PROMETHEUS_PORT=$PROMETHEUS_PORT
DATA_DIR=$VALIDATOR_DIR/data
KEYS_DIR=$VALIDATOR_DIR/keys
LOGS_DIR=$VALIDATOR_DIR/logs
SDK_PATH=$SHARED_DIR/pezkuwi-sdk
FRONTEND_PATH=$SHARED_DIR/DKSweb
EOF
echo -e "${GREEN}✓ Configuration file created${NC}"
# Source the validator keys script if it exists
KEYS_SCRIPT="$VALIDATOR_DIR/config/keys.sh"
if [ -f "$KEYS_SCRIPT" ]; then
echo -e "\n${YELLOW}Loading validator keys...${NC}"
source "$KEYS_SCRIPT"
echo -e "${GREEN}✓ Validator keys loaded${NC}"
else
echo -e "\n${YELLOW}Warning: No keys.sh found for validator $VALIDATOR_NUM${NC}"
echo "Please create $KEYS_SCRIPT with validator keys"
fi
}
# Setup systemd service
setup_service() {
print_header "Setting up Systemd Service"
SERVICE_FILE="/etc/systemd/system/pezkuwi-validator-$VALIDATOR_NUM.service"
sudo tee "$SERVICE_FILE" > /dev/null << EOF
[Unit]
Description=Pezkuwi Validator $VALIDATOR_NUM
After=network.target
[Service]
Type=simple
User=$USER
WorkingDirectory=$VALIDATOR_DIR
EnvironmentFile=$VALIDATOR_DIR/config/validator.conf
ExecStart=$SHARED_DIR/pezkuwi-sdk/target/release/pezkuwi-node \\
--base-path $VALIDATOR_DIR/data \\
--chain local \\
--validator \\
--name validator-$VALIDATOR_NUM \\
--port $P2P_PORT \\
--rpc-port $RPC_PORT \\
--ws-port $WS_PORT \\
--prometheus-port $PROMETHEUS_PORT \\
--rpc-cors all \\
--ws-external \\
--rpc-external
Restart=always
RestartSec=10
StandardOutput=append:$VALIDATOR_DIR/logs/validator.log
StandardError=append:$VALIDATOR_DIR/logs/validator-error.log
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd
sudo systemctl daemon-reload
echo -e "${GREEN}✓ Systemd service created${NC}"
echo "Service name: pezkuwi-validator-$VALIDATOR_NUM"
}
# Setup nginx for frontend
setup_nginx() {
print_header "Setting up Nginx"
NGINX_CONF="/etc/nginx/sites-available/pezkuwi-frontend"
if [ ! -f "$NGINX_CONF" ]; then
sudo tee "$NGINX_CONF" > /dev/null << 'EOF'
server {
listen 80;
listen [::]:80;
server_name _;
root /home/$USER/pezkuwi-validator-v2.0.0/shared/DKSweb/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:9944;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
EOF
# Replace $USER with actual user
sudo sed -i "s/\$USER/$USER/g" "$NGINX_CONF"
# Enable site
sudo ln -sf "$NGINX_CONF" /etc/nginx/sites-enabled/
# Remove default site if exists
sudo rm -f /etc/nginx/sites-enabled/default
# Test nginx configuration
sudo nginx -t
# Restart nginx
sudo systemctl restart nginx
sudo systemctl enable nginx
echo -e "${GREEN}✓ Nginx configured and restarted${NC}"
else
echo -e "${YELLOW}Nginx already configured${NC}"
fi
}
# Setup automatic updates
setup_auto_update() {
print_header "Setting up Automatic Updates"
# Create update script
UPDATE_SCRIPT="$SCRIPT_DIR/scripts/update.sh"
mkdir -p "$SCRIPT_DIR/scripts"
cat > "$UPDATE_SCRIPT" << 'EOF'
#!/bin/bash
# Automatic update script for Pezkuwi validator
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SHARED_DIR="$SCRIPT_DIR/../shared"
echo "Checking for updates..."
# Update SDK
cd "$SHARED_DIR/pezkuwi-sdk"
git fetch origin
if [ $(git rev-parse HEAD) != $(git rev-parse @{u}) ]; then
echo "SDK updates found. Rebuilding..."
git pull
cargo build --release
echo "Restarting validators..."
sudo systemctl restart pezkuwi-validator-*.service
fi
# Update Frontend
cd "$SHARED_DIR/DKSweb"
git fetch origin
if [ $(git rev-parse HEAD) != $(git rev-parse @{u}) ]; then
echo "Frontend updates found. Rebuilding..."
git pull
npm install
npm run build
echo "Frontend updated"
fi
echo "Update check complete"
EOF
chmod +x "$UPDATE_SCRIPT"
# Setup cron job for automatic updates (daily at 2 AM)
CRON_JOB="0 2 * * * $UPDATE_SCRIPT >> $SCRIPT_DIR/logs/auto-update.log 2>&1"
# Add to crontab if not already there
(crontab -l 2>/dev/null | grep -v "$UPDATE_SCRIPT"; echo "$CRON_JOB") | crontab -
echo -e "${GREEN}✓ Automatic updates configured${NC}"
echo "Updates will run daily at 2:00 AM"
}
# Main setup function
main() {
print_header "Pezkuwi Validator Setup v2.0.0"
# Get validator number
get_validator_number "$1"
# Check dependencies
check_dependencies || true
local dep_count=${#missing_deps[@]}
# Install missing dependencies if any
if [ $dep_count -gt 0 ] || [ $RUST_MISSING -eq 1 ] || [ $NODE_MISSING -eq 1 ]; then
echo -e "\n${YELLOW}Some dependencies are missing. Installing...${NC}"
install_dependencies
else
echo -e "\n${GREEN}✓ All dependencies already installed${NC}"
fi
# Setup shared components (only if not already done)
if [ ! -d "$SHARED_DIR/pezkuwi-sdk/target/release" ]; then
setup_sdk
else
echo -e "\n${GREEN}✓ SDK already built${NC}"
fi
if [ ! -d "$SHARED_DIR/DKSweb/dist" ]; then
setup_frontend
else
echo -e "\n${GREEN}✓ Frontend already built${NC}"
fi
# Configure validator
configure_validator
# Setup service
setup_service
# Setup nginx (only once for all validators)
setup_nginx
# Setup automatic updates
setup_auto_update
# Final instructions
print_header "Setup Complete!"
echo -e "${GREEN}Validator $VALIDATOR_NUM is ready!${NC}\n"
echo "Next steps:"
echo "1. Start the validator:"
echo -e " ${BLUE}sudo systemctl start pezkuwi-validator-$VALIDATOR_NUM${NC}"
echo ""
echo "2. Check validator status:"
echo -e " ${BLUE}sudo systemctl status pezkuwi-validator-$VALIDATOR_NUM${NC}"
echo ""
echo "3. View logs:"
echo -e " ${BLUE}tail -f $VALIDATOR_DIR/logs/validator.log${NC}"
echo ""
echo "4. Access frontend:"
echo -e " ${BLUE}http://YOUR_SERVER_IP${NC}"
echo ""
echo "5. Enable auto-start on boot:"
echo -e " ${BLUE}sudo systemctl enable pezkuwi-validator-$VALIDATOR_NUM${NC}"
echo ""
echo -e "${YELLOW}Note: Make sure to add validator keys to:${NC}"
echo -e "${YELLOW}$VALIDATOR_DIR/config/keys.sh${NC}"
}
# Run main function
main "$@"