added scripts

This commit is contained in:
David Allen 2025-06-06 08:34:18 -06:00
parent a11f8ac85e
commit 88befdcc43
Signed by: towk
GPG key ID: 0430CDBE22619155
2 changed files with 147 additions and 0 deletions

62
init-instance.sh Normal file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env bash
#
# setup-student.sh
#
# Usage:
# curl -sL URL_TO_THIS_SCRIPT | bash -s -- GITHUB_USERNAME
#
# This script must be run as the 'rocky' user (with passwordless sudo).
# It takes one argument: the GitHub username of the student.
# It will:
# 1. Retrieve the student's public SSH keys from GitHub and install them
# so they can SSH in as 'rocky'.
# 2. Install cowsay, screen, and tmux.
# 3. Update /etc/motd to welcome the student via cowsay and point them
# at the tutorial repo.
set -euo pipefail
if [ "$#" -ne 1 ]; then
echo "Error: Missing GitHub username."
echo "Usage: $0 GITHUB_USERNAME"
exit 1
fi
GH_USER="$1"
SSH_DIR="/home/rocky/.ssh"
AUTHORIZED_KEYS="$SSH_DIR/authorized_keys"
MOTD_FILE="/etc/motd"
TUTORIAL_URL="https://github.com/OpenCHAMI/tutorial-2025"
echo "→ Installing SSH keys for GitHub user '$GH_USER'..."
# Create .ssh directory if needed
sudo mkdir -p "$SSH_DIR"
sudo chmod 700 "$SSH_DIR"
# Fetch and install public keys
KEYS=$(curl -fsSL "https://github.com/${GH_USER}.keys")
if [ ! -z "${KEYS}" ]; then
echo "${KEYS}" | sudo tee "$AUTHORIZED_KEYS" >/dev/null
echo " ✓ Retrieved keys from https://github.com/${GH_USER}.keys"
else
echo " ✗ Could not find keys for user '$GH_USER'; please check the username and that authorization SSH keys are present."
exit 2
fi
sudo chmod 600 "$AUTHORIZED_KEYS"
sudo chown -R rocky:rocky "$SSH_DIR"
echo "→ Installing packages: cowsay, screen, tmux..."
sudo dnf install -y cowsay screen tmux
echo "→ Updating MOTD in $MOTD_FILE..."
# Generate motd with cowsay greeting and tutorial link
sudo tee "$MOTD_FILE" >/dev/null <<EOF
$(/usr/bin/cowsay "Welcome, ${GH_USER}!")
To get started, see the tutorial at:
${TUTORIAL_URL}
EOF
echo "✔ Setup complete. Student '$GH_USER' can now SSH in and will be greeted on login."

85
setup-ec2-instances.py Executable file
View file

@ -0,0 +1,85 @@
#!/usr/bin/env python3
## This script uses a CSV file with the following columns
## to automate provisioning student EC2 instances with AWS
## by running a script. This script is meant is not meant to
## be ran by the user (e.g. students). It also requires an SSH
## keyfile (which is assumed to be shared between instances)
## to log into the instances and run the SSH commands.
#
# CSV columns:
#
# 1. EC2 instance public IP address (public_ip_address)
# 2. GitHub username (github_username)
#
# Usage:
#
# ./setup-instances.py <path_to_csv> <path_to_keyfile> --script-url <script_url>
#
# Example:
#
# ./setup-instances.py ./users.csv ./openchami.pem https://gist.githubusercontent.com/alexlovelltroy/96bfc8bb6f59c0845617a0dc659871de/raw
from fabric import Connection
from argparse import ArgumentParser
from csv import DictReader
DEFAULT_SCRIPT_URL = "https://gist.githubusercontent.com/davidallendj/bb57c25adefb3e9921ccc3502e9ca13b/raw/2165263c07edc59c007b015c8d21f245f403c09d/setup-student.sh"
def read_user_data(csv_path: str, ignore_header: bool) -> list:
data = []
with open(csv_path, 'r') as file:
if ignore_header:
next(file)
reader = DictReader(file)
for row in reader:
data.append(row)
return data
def ssh_setup_instance(
remote_host: str,
username: str,
keyfile_path: str,
script_url: str = DEFAULT_SCRIPT_URL
) -> None:
# download the script on the remote host instance
conn = Connection(
host=f"rocky@{remote_host}",
connect_kwargs={"key_filename": keyfile_path}
)
result = conn.run(f"curl -fssL {script_url} -o ./setup-student.sh && chmod 755 ./setup-student.sh && ./setup-student.sh {username}", hide=True)
print("{0.stdout}\n".format(result))
def main() -> None:
# setup command-line arguments
parser = ArgumentParser(
prog='setup-instance',
description='Automates setting up an EC2 instance for the OpenCHAMI tutorial.',
epilog='./setup-instances.py <path_to_csv> <path_to_keyfile> <setup_script_url>'
)
parser.add_argument('csv-file', help="Path to CSV containing user information.", default="")
parser.add_argument('keyfile', help="Path to key file used to log into AWS EC2 instance. This is assumed to be shared between instances.")
parser.add_argument('--script-url', dest="script-url", help="URL pointing to setup script to initialize EC2 instance.", default=DEFAULT_SCRIPT_URL)
parser.add_argument('--ignore-header', dest="ignore-header", type=bool, help="Ignores the first line in CSV file.", default=False)
args = vars(parser.parse_args())
# read contents from CSV file and load into dict
data: list = read_user_data(args["csv-file"], args["ignore-header"])
if len(data) == 0:
print("no data found in CSV file")
exit()
# run SSH commands to setup instance
for row in data:
print(f"{row}")
ip_addr: str = row["public_ip_address"]
username: str = row["github_username"]
if not ip_addr or not username:
continue
ssh_setup_instance(ip_addr, username, args["keyfile"], args["script-url"])
if __name__ == "__main__":
main()