From b637c140dfc5ef584f4e9e91ebac22f48b273882 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Sat, 21 Oct 2023 03:04:16 -0700 Subject: [PATCH] add bootstrap instructions --- README.md | 42 +++++++++++++++ v0.0.7/farmer | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++ v0.0.7/sprout | 69 ++++++++++++++++++++++++ 3 files changed, 256 insertions(+) create mode 100644 README.md create mode 100755 v0.0.7/farmer create mode 100755 v0.0.7/sprout diff --git a/README.md b/README.md new file mode 100644 index 0000000..e433478 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# Quickstart + +Want to get up and running as quickly as possible to see what all the fuss is about? +Use our bootstrap scripts! + +1. Download and initialize the command line utility from our releases to your dev machine. +```bash +# replace 'linux' with darwin if you're on macOS +curl -L releases.grlx.dev/linux/amd64/grlx > grlx && chmod +x grlx +./grlx init +``` +You'll be asked some questions, such as which interface the `farmer` is listening on, and which ports to use for communication. +Set the interface to the domain name or IP address of the `farmer`. +Once configured, the CLI prints out your administrator public key, which you'll need for the next step! + +2. On your control server, you'll need to install the `farmer`. +```bash +# or, just run as root instead of sudo +curl -L bootstrap.grlx.dev/latest/farmer | sudo bash +``` +You'll be asked several questions about the interface to listen on, which ports to use, etc. +For the quick start, it's recommended to use the default ports (make sure there's no firewall in the way!). +You'll be prompted for an admin public key, which you should have gotten from the prior step, and a certificate host name(s). +Make sure the certificate host name matches the external-facing interface (a domain or IP address) as it will be used for TLS validation! + +3. On all of your fleet nodes, you'll need to install the `sprout`. +```bash +# or, just run as root instead of sudo +# FARMER_BUS_PORT and FARMER_API_PORT variables are available in case you chose +# to use different ports. +curl -L bootstrap.grlx.dev/latest/sprout | FARMER_INTERFACE=localhost sudo -E bash +``` +Once the sprout is up and running, return to the CLI. + +4. If all is well, you're ready to `cook`! +```bash +grlx keys accept -A +sleep 15; +grlx -T \* test ping +grlx -T \* cmd run whoami +grlx -T \* cmd run --out json -- uname -a +``` diff --git a/v0.0.7/farmer b/v0.0.7/farmer new file mode 100755 index 0000000..431b1a2 --- /dev/null +++ b/v0.0.7/farmer @@ -0,0 +1,145 @@ +#!/usr/bin/env bash +set -e -o pipefail + +# determine machine architecture +arch=$(uname -m) +case $arch in + "x86_64") + machine_arch="amd64" + ;; + "i686"|"i386") + machine_arch="386" + ;; + "aarch64"|"arm64"|"armv8") + machine_arch="arm64" + ;; + "armv7l") + machine_arch="arm" + ;; + *) + echo "Unknown machine architecture: $arch" + exit 1 + ;; +esac + + +# install farmer + +if [ ! -f /usr/local/bin/grlx-farmer ]; then + curl -f -L -s "https://artifacts.grlx.dev/linux/${machine_arch}/v0.0.7/farmer" > /usr/local/bin/grlx-farmer + chmod +x /usr/local/bin/grlx-farmer +fi + +# install systemd service +cat << EOF > /etc/systemd/system/grlx-farmer.service +[Unit] +Description=grlx farmer +Documentation=https://docs.grlx.dev +After=network-online.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/grlx-farmer +Restart=always +RestartSec=30 +User=farmer +Group=farmer + +[Install] +WantedBy=multi-user.target +EOF + +# configure farmer if it's not already configured +if [ ! -f /etc/grlx/farmer ]; then + # install gum if it's not already installed for interactive config + if ! command -v gum >/dev/null 2>&1; then + tempdir="" + if command -v mktemp >/dev/null 2>&1; then + tempdir=$(mktemp -d) + else + tempdir="/tmp/grlx-farmer-gum" + mkdir -p "$tempdir" + fi + #trap 'rm -r "$tempdir"' EXIT + case $machine_arch in + "386") + curl -f -L -s "https://github.com/charmbracelet/gum/releases/download/v0.11.0/gum_0.11.0_Linux_i386.tar.gz" > "$tempdir/gum.tar.gz" + ;; + "amd64") + curl -f -L -s "https://github.com/charmbracelet/gum/releases/download/v0.11.0/gum_0.11.0_Linux_x86_64.tar.gz" > "$tempdir/gum.tar.gz" + ;; + "arm64") + curl -f -L -s "https://github.com/charmbracelet/gum/releases/download/v0.11.0/gum_0.11.0_Linux_arm64.tar.gz" > "$tempdir/gum.tar.gz" + ;; + "arm") + curl -f -L -s "https://github.com/charmbracelet/gum/releases/download/v0.11.0/gum_0.11.0_Linux_arm.tar.gz" > "$tempdir/gum.tar.gz" + ;; + esac + echo "Installing gum..." + echo "$tempdir" + ls -ashil "$tempdir" + tar -C "$tempdir" -xzf "$tempdir/gum.tar.gz" + mv "$tempdir/gum" /usr/local/bin/gum + chmod +x /usr/local/bin/gum + fi + + mkdir -p /etc/grlx + if [ -z "$FARMER_INTERFACE" ]; then + FARMER_INTERFACE=$(gum input --value="localhost" --prompt="Choose an interface for the farmer: > ") + fi + if [ -z "$FARMER_API_PORT" ]; then + FARMER_API_PORT=$(gum input --value=5405 --prompt="Choose a port for the farmer API: > ") + fi + if [ -z "$FARMER_BUS_PORT" ]; then + FARMER_BUS_PORT=$(gum input --value=5406 --prompt="Choose a port for the farmer bus: > ") + fi + if [ -z "$FARMER_ORGANIZATION" ]; then + FARMER_ORGANIZATION=$(gum input --value="Your Organization" --prompt="Choose an organization name for the farmer: > ") + fi + if [ -z "$ADMIN_PUBKEYS" ]; then + ADMIN_PUBKEYS=() + while true; do + ADMIN_PUBKEYS+=($(gum input --width=57 --placeholder="ABC25HBCYNHYMIFTN372NCKASUQPJCTBA66GLKXFYM3QGRP42IC5BYYF" --prompt="Enter an admin public key (generated by 'grlx auth pubkey'): > ")) + if ! gum confirm "Add another admin public key?"; then + break + fi + done + fi + if [ -z "$CERTHOSTS" ]; then + CERTHOSTS=() + while true; do + CERTHOSTS+=($(gum input --placeholder="mydomain.com" --prompt="Enter a domain or IP to generate a certificate for: > ")) + if ! gum confirm "Add another domain or IP?"; then + break + fi + done + fi + + + cat << EOF > /etc/grlx/farmer +certhosts: +$(for host in "${CERTHOSTS[@]}"; do echo " - $host"; done) +certificatevalidtime: 8760h0m0s +configroot: /etc/grlx/ +farmerapiport: "$FARMER_API_PORT" +farmerbusport: "$FARMER_BUS_PORT" +farmerinterface: $FARMER_INTERFACE +farmerpki: /etc/grlx/pki/farmer/ +farmerurl: https://$FARMER_INTERFACE:$FARMER_API_PORT +keyfile: /etc/grlx/pki/farmer/tls-key.pem +nkeyfarmerprivfile: /etc/grlx/pki/farmer/farmer.nkey +nkeyfarmerpubfile: /etc/grlx/pki/farmer/farmer.nkey.pub +organization: $FARMER_ORGANIZATION +rootca: /etc/grlx/pki/farmer/tls-rootca.pem +rootcapriv: /etc/grlx/pki/farmer/tls-rootca-key.pem +pubkeys: + admin: +$(for key in "${ADMIN_PUBKEYS[@]}"; do echo " - $key"; done) +EOF + +fi +useradd -r -s /usr/sbin/nologin farmer >/dev/null || true +chown -R farmer:farmer /etc/grlx +chmod 700 /etc/grlx +systemctl daemon-reload +systemctl enable --now grlx-farmer diff --git a/v0.0.7/sprout b/v0.0.7/sprout new file mode 100755 index 0000000..826105e --- /dev/null +++ b/v0.0.7/sprout @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +set -e -o pipefail + +arch=$(uname -m) + +case $arch in + "x86_64") + machine_arch="amd64" + ;; + "i686"|"i386") + machine_arch="386" + ;; + "aarch64"|"arm64"|"armv8") + machine_arch="arm64" + ;; + "armv7l") + machine_arch="arm" + ;; + *) + echo "Unknown machine architecture: $arch" + exit 1 + ;; +esac + +if [ ! -f /etc/grlx/sprout ]; then + mkdir -p /etc/grlx + if [ -z "$FARMER_INTERFACE" ]; then + echo "FARMER_INTERFACE is not set. Please set it to the domain or IP of your farmer." + exit 1 + fi + if [ -z "$FARMER_API_PORT" ]; then + FARMER_PORT=5405 + fi + if [ -z "$FARMER_BUS_PORT" ]; then + FARMER_PORT=5406 + fi + + cat << EOF > /etc/grlx/sprout +farmerinterface: $FARMER_INTERFACE +farmerbusport: $FARMER_BUS_PORT +farmerapiport: $FARMER_API_PORT +farmerurl: https://$FARMER_INTERFACE:$FARMER_PORT +EOF +fi +chmod 600 /etc/grlx/sprout + +curl -s "https://artifacts.grlx.dev/linux/${machine_arch}/v0.0.7/sprout" > /usr/local/bin/grlx-sprout +chmod +x /usr/local/bin/grlx-sprout + +cat << EOF > /etc/systemd/system/grlx-sprout.service +[Unit] +Description=grlx sprout +Documentation=https://docs.grlx.dev +After=network-online.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/grlx-sprout +Restart=always +RestartSec=30 +User=root +Group=root + +[Install] +WantedBy=multi-user.target +EOF + +systemctl daemon-reload +systemctl enable --now grlx-sprout