feat: scripts for server initialization
This commit is contained in:
parent
583c3c46b4
commit
0d96105a95
135
init.sh
Executable file
135
init.sh
Executable file
@ -0,0 +1,135 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print messages
|
||||
info() {
|
||||
echo -e "${GREEN}[INFO] $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR] $1${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Detect OS
|
||||
OS=""
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
case $ID in
|
||||
ubuntu)
|
||||
OS="ubuntu"
|
||||
;;
|
||||
arch)
|
||||
OS="arch"
|
||||
;;
|
||||
*)
|
||||
error "Unsupported OS: $ID"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
error "Cannot detect OS. /etc/os-release not found."
|
||||
fi
|
||||
|
||||
info "Detected OS: $OS"
|
||||
|
||||
# Ensure we're in the dotfiles directory
|
||||
if [ ! -f "$(pwd)/.gitmodules" ]; then
|
||||
error "This script must be run from the dotfiles repository directory"
|
||||
fi
|
||||
|
||||
# Install prerequisites
|
||||
info "Installing prerequisites..."
|
||||
|
||||
if [ "$OS" = "ubuntu" ]; then
|
||||
# Update package lists
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install required packages
|
||||
sudo apt install -y git tmux stow fzf gcc
|
||||
|
||||
# Install optional packages (bat, fd-find, zoxide)
|
||||
sudo apt install -y bat fd-find
|
||||
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash
|
||||
|
||||
# Install eza (community-maintained ls alternative)
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg
|
||||
echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" | sudo tee /etc/apt/sources.list.d/gierens.list
|
||||
sudo chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list
|
||||
sudo apt update
|
||||
sudo apt install -y eza
|
||||
|
||||
# Install Neovim from GitHub releases (latest stable)
|
||||
info "Installing Neovim from GitHub releases..."
|
||||
NVIM_VERSION=$(curl -s https://api.github.com/repos/neovim/neovim/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
wget -O /tmp/nvim-linux64.tar.gz "https://github.com/neovim/neovim/releases/download/${NVIM_VERSION}/nvim-linux64.tar.gz"
|
||||
sudo tar -C /usr/local -xzf /tmp/nvim-linux64.tar.gz
|
||||
sudo ln -sf /usr/local/nvim-linux64/bin/nvim /usr/local/bin/nvim
|
||||
rm /tmp/nvim-linux64.tar.gz
|
||||
|
||||
# Install thefuck
|
||||
sudo apt install -y python3-pip
|
||||
pip3 install thefuck --user
|
||||
|
||||
elif [ "$OS" = "arch" ]; then
|
||||
# Ensure yay is installed for AUR packages
|
||||
if ! command -v yay &> /dev/null; then
|
||||
info "Installing yay..."
|
||||
sudo pacman -S --needed git base-devel
|
||||
git clone https://aur.archlinux.org/yay.git /tmp/yay
|
||||
cd /tmp/yay
|
||||
makepkg -si --noconfirm
|
||||
cd - && rm -rf /tmp/yay
|
||||
fi
|
||||
|
||||
# Install all packages
|
||||
yay -S --noconfirm git tmux neovim zoxide stow fzf bat eza fd gcc thefuck
|
||||
fi
|
||||
|
||||
# Initialize and update submodules
|
||||
info "Initializing git submodules..."
|
||||
git submodule update --init --recursive
|
||||
|
||||
# Backup existing config files
|
||||
info "Backing up existing configuration files..."
|
||||
BACKUP_DIR="$HOME/.dotfiles_backup_$(date +%F_%H-%M-%S)"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
for file in .gitconfig .zshrc .tmux.conf .bashrc; do
|
||||
[ -f "$HOME/$file" ] && mv "$HOME/$file" "$BACKUP_DIR/$file" && info "Backed up ~/$file to $BACKUP_DIR/$file"
|
||||
done
|
||||
|
||||
for dir in .config/nvim .config/mc kam .oh-my-zsh .tmux; do
|
||||
[ -d "$HOME/$dir" ] && mv "$HOME/$dir" "$BACKUP_DIR/$(basename $dir)" && info "Backed up ~/$dir to $BACKUP_DIR/$(basename $dir)"
|
||||
done
|
||||
|
||||
# Create symlinks with stow
|
||||
info "Creating symlinks with stow..."
|
||||
stow .
|
||||
|
||||
# Change shell to zsh
|
||||
if [ "$(basename "$SHELL")" != "zsh" ]; then
|
||||
info "Changing shell to zsh..."
|
||||
ZSH_PATH=$(which zsh)
|
||||
if [ -z "$ZSH_PATH" ]; then
|
||||
error "zsh not found. Please install zsh and run 'chsh -s $(which zsh)' manually."
|
||||
fi
|
||||
chsh -s "$ZSH_PATH"
|
||||
info "Shell changed to zsh. Please log out and log back in for the change to take effect."
|
||||
fi
|
||||
|
||||
# Final instructions
|
||||
info "Dotfiles setup complete!"
|
||||
echo "To source tmux configuration:"
|
||||
echo "1. Start tmux with 'tmux'"
|
||||
echo "2. Press <prefix>: (default is Ctrl+b)"
|
||||
echo "3. Type 'source ~/.tmux.conf' and press Enter"
|
||||
echo
|
||||
echo "Backup of previous configs is stored in: $BACKUP_DIR"
|
||||
echo "You may need to log out and log back in for zsh to take effect."
|
91
local_seed.sh
Executable file
91
local_seed.sh
Executable file
@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default values
|
||||
ANONYMOUS=false
|
||||
USERNAME="goodhumored"
|
||||
|
||||
# Function to print messages
|
||||
info() {
|
||||
echo -e "${GREEN}[INFO] $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[ERROR] $1${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Function to generate random username for anonymous mode
|
||||
generate_random_username() {
|
||||
echo "user$(head /dev/urandom | tr -dc a-z0-9 | head -c 8)"
|
||||
}
|
||||
|
||||
# Function to display usage
|
||||
usage() {
|
||||
echo "Usage: $0 [options]"
|
||||
echo "Options:"
|
||||
echo " -u, --username Username to create (default: goodhumored)"
|
||||
echo " -a, --anonymous Run in anonymous mode (random username, no dotfiles)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
-u|--username) USERNAME="$2"; shift ;;
|
||||
-a|--anonymous) ANONYMOUS=true ;;
|
||||
*) echo "Unknown parameter: $1"; usage ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Set username for anonymous mode
|
||||
if [ "$ANONYMOUS" = true ]; then
|
||||
USERNAME=$(generate_random_username)
|
||||
fi
|
||||
|
||||
# Check if running as root
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
error "This script must be run with sudo privileges"
|
||||
fi
|
||||
|
||||
# Create user and setup home directory
|
||||
info "Creating user $USERNAME..."
|
||||
useradd -m -s /bin/bash -G sudo "$USERNAME"
|
||||
chmod 700 "/home/$USERNAME"
|
||||
|
||||
# Setup SSH directory and authorized_keys
|
||||
info "Setting up SSH directory..."
|
||||
mkdir -p "/home/$USERNAME/.ssh"
|
||||
chmod 700 "/home/$USERNAME/.ssh"
|
||||
touch "/home/$USERNAME/.ssh/authorized_keys"
|
||||
chmod 600 "/home/$USERNAME/.ssh/authorized_keys"
|
||||
chown -R "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh"
|
||||
|
||||
# Install dependencies
|
||||
info "Installing dependencies..."
|
||||
apt-get update
|
||||
apt-get install -y git stow
|
||||
|
||||
# Clone and setup dotfiles (non-anonymous mode only)
|
||||
if [ "$ANONYMOUS" = false ]; then
|
||||
info "Cloning dotfiles repository..."
|
||||
su - "$USERNAME" -c "git clone https://github.com/goodhumored/dotfiles /home/$USERNAME/dotfiles"
|
||||
info "Running init.sh..."
|
||||
su - "$USERNAME" -c "cd /home/$USERNAME/dotfiles && ./init.sh"
|
||||
fi
|
||||
|
||||
info "Local server setup complete!"
|
||||
echo "Username: $USERNAME"
|
||||
if [ "$ANONYMOUS" = false ]; then
|
||||
echo "Dotfiles have been cloned and initialized."
|
||||
else
|
||||
echo "Anonymous mode: No dotfiles cloned."
|
||||
fi
|
||||
echo "You can now add an SSH public key to /home/$USERNAME/.ssh/authorized_keys"
|
150
seed.sh
Executable file
150
seed.sh
Executable file
@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Defaults
|
||||
ANONYMOUS=false
|
||||
PORT=22
|
||||
NEW_USER="goodhumored"
|
||||
PASS_DIR="$HOME/.password-store"
|
||||
|
||||
# Random username for anonymous mode
|
||||
generate_random_username() {
|
||||
echo "user$(head /dev/urandom | tr -dc a-z0-9 | head -c 8)"
|
||||
}
|
||||
|
||||
# Usage
|
||||
usage() {
|
||||
echo "Usage: $0 [options]"
|
||||
echo " -h, --host Server IP"
|
||||
echo " -p, --port SSH port (default: 22)"
|
||||
echo " -r, --root_user Sudo user for SSH"
|
||||
echo " -s, --server_name Server name for SSH config"
|
||||
echo " -u, --username User to create (default: goodhumored)"
|
||||
echo " -n, --pass_name Password store name"
|
||||
echo " -a, --anonymous Anonymous mode"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check sshpass
|
||||
if ! command -v sshpass &> /dev/null; then
|
||||
echo "Ошибка: нужен sshpass."
|
||||
echo "Установи: sudo apt-get install sshpass (Ubuntu) или sudo pacman -S sshpass (Arch)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse args
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--host) HOST="$2"; shift ;;
|
||||
-p|--port) PORT="$2"; shift ;;
|
||||
-r|--root_user) ROOT_USER="$2"; shift ;;
|
||||
-s|--server_name) SERVER_NAME="$2"; shift ;;
|
||||
-u|--username) NEW_USER="$2"; shift ;;
|
||||
-n|--pass_name) PASS_NAME="$2"; shift ;;
|
||||
-a|--anonymous) ANONYMOUS=true ;;
|
||||
*) echo "Неизвестный параметр: $1"; usage ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Validate args
|
||||
if [ -z "$HOST" ] || [ -z "$ROOT_USER" ] || [ -z "$SERVER_NAME" ]; then
|
||||
echo "Ошибка: нужны host, root_user и server_name"
|
||||
usage
|
||||
fi
|
||||
|
||||
# Prompt for password
|
||||
if [ "$ANONYMOUS" = false ]; then
|
||||
if [ -z "$PASS_NAME" ]; then
|
||||
read -p "Имя для хранения пароля: " PASS_NAME
|
||||
fi
|
||||
read -s -p "Пароль для SSH и sudo: " ROOT_PASS
|
||||
echo
|
||||
fi
|
||||
|
||||
# Set username for anonymous
|
||||
if [ "$ANONYMOUS" = true ]; then
|
||||
NEW_USER=$(generate_random_username)
|
||||
fi
|
||||
|
||||
# Generate SSH key
|
||||
KEY_PATH="$HOME/.ssh/keys/$SERVER_NAME"
|
||||
mkdir -p "$HOME/.ssh/keys"
|
||||
ssh-keygen -t ed25519 -f "$KEY_PATH" -N "" -C "$SERVER_NAME"
|
||||
|
||||
# Read public key
|
||||
PUBLIC_KEY=$(cat "$KEY_PATH.pub")
|
||||
|
||||
# Generate and store password
|
||||
NEW_PASS=""
|
||||
if [ "$ANONYMOUS" = false ]; then
|
||||
mkdir -p "$PASS_DIR"
|
||||
NEW_PASS="$(pass generate "$PASS_NAME" 16 | tail -n1)"
|
||||
echo "DEBUG: Generated password: '$NEW_PASS'"
|
||||
fi
|
||||
|
||||
# Update SSH config
|
||||
CONFIG_FILE="$HOME/.ssh/config"
|
||||
touch "$CONFIG_FILE"
|
||||
chmod 600 "$CONFIG_FILE"
|
||||
|
||||
# Remove old entry
|
||||
sed -i "/Host $SERVER_NAME/,/^\s*$/d" "$CONFIG_FILE"
|
||||
|
||||
# Add new entry
|
||||
cat << EOF >> "$CONFIG_FILE"
|
||||
|
||||
Host $SERVER_NAME
|
||||
HostName $HOST
|
||||
Port $PORT
|
||||
User $NEW_USER
|
||||
IdentityFile $KEY_PATH
|
||||
EOF
|
||||
|
||||
# SSH commands
|
||||
SSH_COMMANDS=$(cat << ENDSSH
|
||||
set -e
|
||||
echo '\$PUBLIC_KEY'
|
||||
|
||||
# Create user
|
||||
echo "\$SUDO_PASS" | sudo -S useradd -m -s /bin/bash -G sudo "\$NEW_USER"
|
||||
echo "\$SUDO_PASS" | sudo -S chmod 700 "/home/\$NEW_USER"
|
||||
|
||||
# Set password
|
||||
if [ -n "\$NEW_PASS" ]; then
|
||||
echo "DEBUG: Setting password for \$NEW_USER: \$NEW_PASS"
|
||||
echo "\$SUDO_PASS" | sudo -S bash -c "echo \"\$NEW_USER:\$NEW_PASS\" | chpasswd"
|
||||
fi
|
||||
|
||||
# Setup SSH dir
|
||||
echo "\$SUDO_PASS" | sudo -S mkdir -p "/home/\$NEW_USER/.ssh"
|
||||
echo "\$SUDO_PASS" | sudo -S chmod 700 "/home/\$NEW_USER/.ssh"
|
||||
echo "\$SUDO_PASS" | sudo -S touch "/home/\$NEW_USER/.ssh/authorized_keys"
|
||||
echo "\$SUDO_PASS" | sudo -S chmod 600 "/home/\$NEW_USER/.ssh/authorized_keys"
|
||||
echo "\$SUDO_PASS" | sudo -S chown -R "\$NEW_USER:\$NEW_USER" "/home/\$NEW_USER/.ssh"
|
||||
echo "\$SUDO_PASS" | sudo -S bash -c "echo \"\$PUBLIC_KEY\" >> /home/\$NEW_USER/.ssh/authorized_keys"
|
||||
|
||||
# Install deps
|
||||
echo "\$SUDO_PASS" | sudo -S apt-get update
|
||||
echo "\$SUDO_PASS" | sudo -S apt-get install -y git stow
|
||||
ENDSSH
|
||||
)
|
||||
|
||||
# Run SSH commands
|
||||
SSHPASS="$ROOT_PASS" sshpass -e ssh -p "$PORT" "$ROOT_USER@$HOST" "SUDO_PASS='$ROOT_PASS' ANONYMOUS=$ANONYMOUS NEW_USER='$NEW_USER' PUBLIC_KEY='$PUBLIC_KEY' NEW_PASS='$NEW_PASS' bash -c '$SSH_COMMANDS'"
|
||||
|
||||
ssh "$SERVER_NAME" bash -c "$(cat << ENDSSH
|
||||
set -e
|
||||
git clone https://github.com/goodhumored/dotfiles
|
||||
cd dotfiles
|
||||
./init.sh
|
||||
ENDSSH
|
||||
)"
|
||||
|
||||
echo "Настройка завершена!"
|
||||
echo "Пользователь: $NEW_USER"
|
||||
echo "SSH команда: ssh $SERVER_NAME"
|
||||
if [ "$ANONYMOUS" = false ]; then
|
||||
echo "Пароль сохранен в: $PASS_NAME"
|
||||
fi
|
114
seed_v2.sh
Normal file
114
seed_v2.sh
Normal file
@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- Константы ---
|
||||
DEFAULT_PORT=22
|
||||
DEFAULT_USER="goodhumored"
|
||||
PASS_DIR="$HOME/.password-store"
|
||||
KEYS_DIR="$HOME/.ssh/keys"
|
||||
|
||||
# --- Утилиты ---
|
||||
require() {
|
||||
if ! command -v "$1" &> /dev/null; then
|
||||
echo "Ошибка: нужна утилита '$1'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
require sshpass
|
||||
require ssh-keygen
|
||||
require pass
|
||||
|
||||
# --- Параметры ---
|
||||
ANONYMOUS=false
|
||||
PORT="$DEFAULT_PORT"
|
||||
NEW_USER="$DEFAULT_USER"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-h|--host) HOST="$2"; shift ;;
|
||||
-p|--port) PORT="$2"; shift ;;
|
||||
-r|--root_user) ROOT_USER="$2"; shift ;;
|
||||
-s|--server_name) SERVER_NAME="$2"; shift ;;
|
||||
-u|--username) NEW_USER="$2"; shift ;;
|
||||
-n|--pass_name) PASS_NAME="$2"; shift ;;
|
||||
-a|--anonymous) ANONYMOUS=true ;;
|
||||
*) echo "Неизвестный параметр: $1"; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[[ -z "${HOST:-}" || -z "${ROOT_USER:-}" || -z "${SERVER_NAME:-}" ]] && {
|
||||
echo "Ошибка: нужны --host, --root_user и --server_name"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Логика ---
|
||||
if $ANONYMOUS; then
|
||||
NEW_USER="user$(tr -dc a-z0-9 </dev/urandom | head -c 8)"
|
||||
fi
|
||||
|
||||
if [ -z "${PASS_NAME:-}" ] && ! $ANONYMOUS; then
|
||||
read -p "Имя для пароля: " PASS_NAME
|
||||
fi
|
||||
|
||||
if ! $ANONYMOUS; then
|
||||
read -s -p "Пароль root для подключения: " ROOT_PASS
|
||||
echo
|
||||
fi
|
||||
|
||||
# Генерация ключа
|
||||
mkdir -p "$KEYS_DIR"
|
||||
KEY_PATH="$KEYS_DIR/$SERVER_NAME"
|
||||
ssh-keygen -t ed25519 -N "" -f "$KEY_PATH" -C "$SERVER_NAME"
|
||||
|
||||
# Получение нового пароля
|
||||
if ! $ANONYMOUS; then
|
||||
mkdir -p "$PASS_DIR"
|
||||
NEW_PASS=$(pass generate -c "$PASS_NAME" 16 | tail -n1)
|
||||
echo "$NEW_PASS" | pass insert -m "$PASS_NAME"
|
||||
else
|
||||
NEW_PASS=""
|
||||
fi
|
||||
|
||||
# Обновление SSH-конфига
|
||||
CONFIG_FILE="$HOME/.ssh/config"
|
||||
touch "$CONFIG_FILE"
|
||||
chmod 600 "$CONFIG_FILE"
|
||||
sed -i "/Host $SERVER_NAME/,/^\s*$/d" "$CONFIG_FILE"
|
||||
cat <<EOF >> "$CONFIG_FILE"
|
||||
|
||||
Host $SERVER_NAME
|
||||
HostName $HOST
|
||||
Port $PORT
|
||||
User $NEW_USER
|
||||
IdentityFile $KEY_PATH
|
||||
EOF
|
||||
|
||||
# --- SSH Настройка сервера ---
|
||||
SSH_COMMANDS=$(cat <<'EOS'
|
||||
set -euo pipefail
|
||||
|
||||
sudo useradd -m -s /bin/bash -G sudo "$NEW_USER"
|
||||
echo "$NEW_USER:$NEW_PASS" | sudo chpasswd
|
||||
|
||||
sudo mkdir -p "/home/$NEW_USER/.ssh"
|
||||
sudo chmod 700 "/home/$NEW_USER/.ssh"
|
||||
echo "$PUBLIC_KEY" | sudo tee "/home/$NEW_USER/.ssh/authorized_keys" > /dev/null
|
||||
sudo chmod 600 "/home/$NEW_USER/.ssh/authorized_keys"
|
||||
sudo chown -R "$NEW_USER:$NEW_USER" "/home/$NEW_USER/.ssh"
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y git stow
|
||||
|
||||
if [ "$ANONYMOUS" = "false" ]; then
|
||||
sudo -u "$NEW_USER" git clone https://github.com/goodhumored/dotfiles /home/"$NEW_USER"/dotfiles
|
||||
sudo -u "$NEW_USER" bash -c "cd /home/$NEW_USER/dotfiles && ./init.sh"
|
||||
fi
|
||||
EOS
|
||||
)
|
||||
|
||||
SSHPASS="$ROOT_PASS" sshpass -e ssh -p "$PORT" "$ROOT_USER@$HOST" \
|
||||
env NEW_USER="$NEW_USER" NEW_PASS="$NEW_PASS" PUBLIC_KEY="$(cat "$KEY_PATH.pub")" ANONYMOUS="$ANONYMOUS" bash -c "$SSH_COMMANDS"
|
||||
|
||||
echo "Готово! Новый пользователь: $NEW_USER (SSH: ssh $SERVER_NAME)"
|
Loading…
x
Reference in New Issue
Block a user