diff --git a/.github/workflows/end2end_tests.yaml b/.github/workflows/end2end_tests.yaml index a08442921..d3cbdc43b 100644 --- a/.github/workflows/end2end_tests.yaml +++ b/.github/workflows/end2end_tests.yaml @@ -26,6 +26,7 @@ env: v3.1.2 v3.2.0 v3.3.0 + v3.4.0 BRANCHES: | trunk @@ -35,7 +36,6 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false - max-parallel: 8 matrix: np: [local, trunk, installer] npd: [local, trunk] @@ -54,28 +54,41 @@ jobs: npd: latest rvd: local rvd_atsign: "@8485wealthy51" - ### INSTALLER TESTS ### + ### SSHNPD INSTALLER TESTS ### - np: local npd: installer - wait: 30 + wait: 120 + - np: trunk npd: installer - wait: 30 + wait: 120 + - np: installer npd: installer - wait: 30 + wait: 120 + ### BACKWARD TESTS WITHOUT SYNC ### - np: local npd: latest - - np: latest npd: local - np: local - npd: v3.3.0 + npd: v3.4.0 + - np: v3.4.0 + npd: local + - np: local + npd: v3.3.0 - np: v3.3.0 npd: local + + ### BACKWARD TESTS WITH SYNC ### + - np: local + npd: v3.2.0 + wait: 200 + - np: v3.2.0 + npd: local steps: - name: Show Matrix Values run: | @@ -118,199 +131,6 @@ jobs: cat sshnpd/entrypoint.sh cat sshrvd/entrypoint.sh - - name: Store lists in env - run: | - - - name: Add runtime-release image to docker-compose.yaml - working-directory: tests/end2end_tests/tests - if: ${{ contains(env.RELEASES, matrix.np) || contains(env.RELEASES, matrix.npd) || (matrix.rvd && contains(env.RELEASES, matrix.rvd)) }} - run: | - cat service-image-runtime-release.yaml >> docker-compose.yaml - if [ "${{contains(env.RELEASES, matrix.np)}}" = true ]; then - echo ' - release=${{ matrix.np }}' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.np }}' >> docker-compose.yaml - elif [ "${{contains(env.RELEASES, matrix.npd)}}" = true ]; then - echo ' - release=${{ matrix.npd }}' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.npd }}' >> docker-compose.yaml - elif [ "${{contains(env.RELEASES, matrix.rvd)}}" = true ]; then - echo ' - release=${{ matrix.rvd }}' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.rvd }}' >> docker-compose.yaml - fi - - - name: Add runtime-branch image to docker-compose.yaml - working-directory: tests/end2end_tests/tests - if: ${{ contains(env.BRANCHES, matrix.np) || contains(env.BRANCHES, matrix.npd) || (matrix.rvd && contains(env.BRANCHES, matrix.rvd)) }} - run: | - cat service-image-runtime-branch.yaml >> docker-compose.yaml - if [ "${{contains(env.BRANCHES, matrix.np)}}" = true ]; then - echo ' - branch=${{ matrix.np }}' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.np }}' >> docker-compose.yaml - elif [ "${{contains(env.BRANCHES, matrix.npd)}}" = true ]; then - echo ' - branch=${{ matrix.npd }}' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.npd }}' >> docker-compose.yaml - elif [ "${{contains(env.BRANCHES, matrix.rvd)}}" = true ]; then - echo ' - branch=${{ matrix.rvd }}' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.rvd }}' >> docker-compose.yaml - fi - - - name: Add runtime-sshnp-installer image to docker-compose.yaml - working-directory: tests/end2end_tests/tests - if: ${{ matrix.np == 'installer' }} - run: | - cat service-image-runtime-sshnp-installer.yaml >> docker-compose.yaml - echo ' - client_atsign="${{ env.SSHNP_ATSIGN }}"' >> docker-compose.yaml - echo ' - device_atsign="${{ env.SSHNPD_ATSIGN }}"' >> docker-compose.yaml - echo ' - host_atsign="${{ matrix.rvd_atsign || env.DEFAULT_RVD_ATSIGN }}"' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:sshnp-installer' >> docker-compose.yaml - - - name: Add runtime-sshnpd-installer image to docker-compose.yaml - working-directory: tests/end2end_tests/tests - if: ${{ matrix.npd == 'installer' }} - run: | - cat service-image-runtime-sshnpd-installer.yaml >> docker-compose.yaml - echo ' - client_atsign="${{ env.SSHNP_ATSIGN }}"' >> docker-compose.yaml - echo ' - device_atsign="${{ env.SSHNPD_ATSIGN }}"' >> docker-compose.yaml - echo ' - device_name=${{ github.run_id }}${{ github.run_attempt }}${{ strategy.job-index }}' >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:sshnpd-installer' >> docker-compose.yaml - - - name: Add container-sshnp to docker-compose.yaml - working-directory: tests/end2end_tests/tests - run: | - cat service-container-sshnp.yaml >> docker-compose.yaml - if [ "${{ matrix.np }}" = 'installer' ]; then - echo ' image: atsigncompany/sshnp-e2e-runtime:sshnp-installer' >> docker-compose.yaml - else - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.np }}' >> docker-compose.yaml - fi - echo ' depends_on:' >> docker-compose.yaml - echo ' - container-sshnpd' >> docker-compose.yaml - if [ "${{contains(env.RELEASES, matrix.np)}}" = true ]; then - echo ' - image-runtime-release' >> docker-compose.yaml - elif [ "${{contains(env.BRANCHES, matrix.np)}}" = true ]; then - echo ' - image-runtime-branch' >> docker-compose.yaml - elif [ "${{ matrix.np }}" = 'installer' ]; then - echo ' - image-runtime-sshnp-installer' >> docker-compose.yaml - else - echo ' - image-runtime-local' >> docker-compose.yaml - fi - - - name: Add container-sshnpd to docker-compose.yaml - working-directory: tests/end2end_tests/tests - run: | - cat service-container-sshnpd.yaml >> docker-compose.yaml - if [ "${{ matrix.npd }}" = 'installer' ]; then - echo ' image: atsigncompany/sshnp-e2e-runtime:sshnpd-installer' >> docker-compose.yaml - else - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.npd }}' >> docker-compose.yaml - fi - echo ' depends_on:' >> docker-compose.yaml - if [ "${{ matrix.rvd }}" = true ]; then - echo ' - container-sshrvd' >> docker-compose.yaml - fi - if [ "${{contains(env.RELEASES, matrix.npd)}}" = true ]; then - echo ' - image-runtime-release' >> docker-compose.yaml - elif [ "${{contains(env.BRANCHES, matrix.npd)}}" = true ]; then - echo ' - image-runtime-branch' >> docker-compose.yaml - elif [ "${{ matrix.npd }}" = 'installer' ]; then - echo ' - image-runtime-sshnpd-installer' >> docker-compose.yaml - else - echo ' - image-runtime-local' >> docker-compose.yaml - fi - - - name: Add container-sshrvd to docker-compose.yaml - working-directory: tests/end2end_tests/tests - if: matrix.rvd - run: | - cat service-container-sshrvd.yaml >> docker-compose.yaml - echo ' image: atsigncompany/sshnp-e2e-runtime:${{ matrix.rvd }}' >> docker-compose.yaml - echo ' depends_on:' >> docker-compose.yaml - if [ "${{contains(env.RELEASES, matrix.rvd)}}" = true ]; then - echo ' - image-runtime-release' >> docker-compose.yaml - elif [ "${{contains(env.BRANCHES, matrix.rvd)}}" = true ]; then - echo ' - image-runtime-branch' >> docker-compose.yaml - else - echo ' - image-runtime-local' >> docker-compose.yaml - fi - - - name: docker-compose.yaml - if: always() - working-directory: tests/end2end_tests/tests - run: | - cat docker-compose.yaml - - - name: Build - working-directory: tests/end2end_tests/tests - run: | - docker compose build - - - name: Test - working-directory: tests/end2end_tests/tests - run: | - ${{ env.DOCKER_COMPOSE_UP_CMD }} - - - name: Logs - if: always() - working-directory: tests/end2end_tests/tests - run: | - docker compose ps -a - docker compose logs --timestamps - - - name: Tear down - if: always() - working-directory: tests/end2end_tests/tests - run: | - docker compose down - e2e_test_sync: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - # Leave these empty to avoid unwanted intellisense warnings - rvd: [""] - rvd_atsign: [""] - include: - - np: local - npd: v3.2.0 - wait: 300 - - - np: v3.2.0 - npd: local - steps: - - name: Show Matrix Values - run: | - echo "job index: ${{ strategy.job-index }}" - echo "np: ${{ matrix.np }}" - echo "npd: ${{ matrix.npd }}" - - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - - name: Copy NP/NPD keys - working-directory: tests/end2end_tests/contexts - run: | - echo "${{ secrets.ATKEYS_8INCANTEATER }}" > sshnp/keys/${{ env.SSHNP_ATSIGN }}_key.atKeys - echo "${{ secrets.ATKEYS_8052SIMPLE }}" > sshnpd/keys/${{ env.SSHNPD_ATSIGN }}_key.atKeys - - - name: Set up entrypoints - uses: ./.github/composite/setup_entrypoints - with: - sshnp: ${{ matrix.np }} - sshnp_atsign: ${{ env.SSHNP_ATSIGN }} - sshnpd: ${{ matrix.npd }} - sshnpd_atsign: ${{ env.SSHNPD_ATSIGN }} - sshrvd_atsign: ${{ matrix.rvd_atsign || env.DEFAULT_RVD_ATSIGN }} - devicename: ${{ github.run_id }}${{ github.run_attempt }}${{ strategy.job-index }} - wait_time: ${{ matrix.wait }} - - - name: Ensure entrypoints exist - working-directory: tests/end2end_tests/contexts - run: | - cat sshnp/entrypoint.sh - cat sshnpd/entrypoint.sh - cat sshrvd/entrypoint.sh - - - name: Store lists in env - run: | - - name: Add runtime-release image to docker-compose.yaml working-directory: tests/end2end_tests/tests if: ${{ contains(env.RELEASES, matrix.np) || contains(env.RELEASES, matrix.npd) || (matrix.rvd && contains(env.RELEASES, matrix.rvd)) }} diff --git a/packages/sshnoports/scripts/install_sshnp b/packages/sshnoports/scripts/install_sshnp deleted file mode 100755 index 38e13f33a..000000000 --- a/packages/sshnoports/scripts/install_sshnp +++ /dev/null @@ -1,382 +0,0 @@ -#!/bin/bash - -BINARY_NAME="sshnp"; - -# Prepend an @ to the front of the atsign if missing -norm_atsign() { - # shellcheck disable=SC2001 - atsign="@$(echo "$1" | sed -e 's/"//g' -e 's/^@//g')" - echo "$atsign" -} - -norm_version() { - version="tags/v$(echo "$1" | sed -e 's/"//g' -e 's/^tags\///g' -e 's/^v//g')" - echo "$version" -} - -# Print the usage information -usage() { - echo "Usage: $0 [options]" - echo "General options:" - echo " -u, --update Update the main binaries instead of installing" - echo " -l, --local Install using local zip/tgz" - echo " -r, --repo Install using local repo" - echo " -h, --help Display this help message" - echo "" - echo "Installation options:" - echo " -c, --client
Client address (e.g. @alice_client)" - echo " -d, --device
Device address (e.g. @alice_device)" - echo " -h, --host Default host rendezvous region code (am, eu, ap)" - echo " Specify an atSign to override with a custom host" - echo " -v, --version Version to install (default: latest)" -} - -# Parse the command-line args -parse_args() { - SSHNP_OP="install" - while [ $# -gt 0 ]; do - case "$1" in - -u|--update) - SSHNP_OP="update" - shift 1 - ;; - --cache-temp) - SSHNP_CACHE_TEMP=1 - shift 1 - ;; - --help) - usage - exit 0 - ;; - -l|--local) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_LOCAL="$2" - shift 2 - ;; - -r|--repo) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_DEV_MODE="$2" - shift 2 - ;; - -c|--client) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - CLIENT_ATSIGN="$2" - shift 2 - ;; - -d|--device) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - DEVICE_MANAGER_ATSIGN="$2" - shift 2 - ;; - -h|--host) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - HOST_RENDEZVOUS_ATSIGN="$2" - shift 2 - ;; - -v|--version) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_VERSION="$2" - shift 2 - ;; - *) - echo "Unknown argument: $1" - exit 1 - ;; - esac - done -} -validate_args () { - if [ "$SSHNP_OP" = "install" ]; then - while [ -z "$CLIENT_ATSIGN" ]; do - read -rp "Client address (e.g. @alice_client): " CLIENT_ATSIGN; - done - - while [ -z "$DEVICE_MANAGER_ATSIGN" ]; do - read -rp "Device address (e.g. @alice_device): " DEVICE_MANAGER_ATSIGN; - done - - if [ -z "$HOST_RENDEZVOUS_ATSIGN" ]; then - echo Pick your default region: - echo " am : Americas" - echo " ap : Asia Pacific" - echo " eu : Europe" - echo " @___ : Specify a custom region atSign" - read -rp "> " HOST_RENDEZVOUS_ATSIGN; - fi - - while ! echo "$HOST_RENDEZVOUS_ATSIGN" | grep -Eq "@.*"; do - case "$HOST_RENDEZVOUS_ATSIGN" in - [Aa][Mm]*) - HOST_RENDEZVOUS_ATSIGN="@rv_am" - ;; - [Ee][Uu]*) - HOST_RENDEZVOUS_ATSIGN="@rv_eu" - ;; - [Aa][Pp]*) - HOST_RENDEZVOUS_ATSIGN="@rv_ap" - ;; - @*) - # Do nothing for custom region - ;; - *) - echo "Invalid region: $HOST_RENDEZVOUS_ATSIGN" - read -rp "region: " HOST_RENDEZVOUS_ATSIGN; - ;; - esac - done - - CLIENT_ATSIGN="$(norm_atsign "$CLIENT_ATSIGN")" - DEVICE_MANAGER_ATSIGN="$(norm_atsign "$DEVICE_MANAGER_ATSIGN")" - echo; - fi -} - -# Load requirements statuses into variables -parse_requirements() { - REQ_SSH=$(command -v ssh) - REQ_SSHD=$(command -v sshd) - #REQ_SSH0=$(ssh -o "StrictHostKeyChecking no" -o "PasswordAuthentication no" 0 exit 2>/dev/null; echo $?) - REQ_CURL=$(command -v curl) -} - -# Check the script's requirements -check_requirements() { - if [ -z "$REQ_SSH" ]; then - echo " [X] Missing required dependency: ssh" - elif [ -z "$REQ_SSHD" ]; then - echo " [X] Missing required dependency: sshd" - # elif [ "$REQ_SSH0" != 0 ]; then - # echo " [X] sshd is not running" - fi - if [ -z "$REQ_CURL" ] && [ -z "$SSHNP_DEV_MODE" ] && [ -z "$SSHNP_LOCAL" ]; then - echo " [X] Missing required dependency: curl" - fi -} - -# Parse the system environment -parse_env() { - if [ -z "$SSHNP_USER" ]; then - SSHNP_USER="$USER"; - fi - HOME_PATH=$(eval echo "~$SSHNP_USER"); - - if [ -z "$SSHNP_VERSION" ]; then - SSHNP_VERSION="latest"; - else - SSHNP_VERSION="$(norm_version "$SSHNP_VERSION")" - fi - URL="https://api.github.com/repos/atsign-foundation/sshnoports/releases/$SSHNP_VERSION"; - - case "$(uname)" in - Darwin) - PLATFORM="macos" - EXT="zip" - ;; - Linux) - PLATFORM="linux" - EXT="tgz" - ;; - *) - PLATFORM="Unknown" - ;; - esac - - if [ "$PLATFORM" = "Unknown" ]; then - echo "Unsupported platform: $(uname)"; - exit 1; - fi - - # ARCH includes the dot at the end to avoid conflict between arm and arm64 - case "$(uname -m)" in - aarch64|arm64) ARCH="arm64\.";; - x86_64|amd64) ARCH="x64\.";; - armv7l|arm) ARCH="arm\.";; - riscv64) ARCH="riscv64\.";; - *) ARCH="Unknown";; - esac - - if [ "$ARCH" = "Unknown" ]; then - echo "Unsupported architecture: $(uname -m)"; - exit 1; - fi - - DOWNLOADS=$(curl -s "$URL" | grep browser_download_url | cut -d\" -f4); - DOWNLOAD=$(echo "$DOWNLOADS" | grep "$PLATFORM" | grep "$ARCH" | cut -d\" -f4) -} - -# Remove the temporary folder generated for processing the download/install -cleanup() { - if [ -z "$SSHNP_CACHE_TEMP" ]; then - rm -rf "$HOME_PATH/.atsign/temp/$TEMP_PATH"; - fi -} - -# Make the necessary directories for sshnpd -make_dirs() { - rm -rf "$HOME_PATH/.atsign/temp"; - mkdir -p "$HOME_PATH/.ssh" \ - "$HOME_PATH/.sshnp" \ - "$HOME_PATH/.atsign/keys" \ - "$HOME_PATH/.atsign/temp" \ - "$HOME_PATH/.local/bin"; -} - -# Build the dart binaries from the provided repo -build_dart_binaries() { - echo "DEV MODE: Installing from local repo: $SSHNP_DEV_MODE"; - cp -R "$SSHNP_DEV_MODE/packages/sshnoports/templates/" "$HOME_PATH/.atsign/temp/$BINARY_NAME/templates/"; -} - -# Make a copy of the locally provided archive -copy_local_archive() { - echo "DEV MODE: Installing using local $EXT file: $SSHNP_LOCAL"; - cp "$SSHNP_LOCAL" "$HOME_PATH/.atsign/temp/$BINARY_NAME.$EXT"; -} - -# Download the release archive -download_archive() { - echo "Downloading $BINARY_NAME from $DOWNLOAD"; - curl -sL "$DOWNLOAD" -o "$HOME_PATH/.atsign/temp/$BINARY_NAME.$EXT"; - if [ ! -f "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME.$EXT" ]; then - echo "Failed to download $BINARY_NAME"; - echo; - echo "Please try again, or download manually from $DOWNLOAD"; - echo "After downloading manually, run the following command to install:"; - if [ "$0" == 'bash' ]; then - echo "bash -c \"\$(curl https://get$BINARY_NAME.noports.com)\" -- -l "; - else - echo " $0 -l "; - fi - cleanup - exit 1; - fi -} - -# Unpack the downloaded / locally provided archive -unpack_archive() { - case "$EXT" in - zip) - unzip -qo "$HOME_PATH/.atsign/temp/$BINARY_NAME.$EXT" -d "$HOME_PATH/.atsign/temp"; - ;; - tgz|tar.gz) - tar -zxf "$HOME_PATH/.atsign/temp/$BINARY_NAME.$EXT" -C "$HOME_PATH/.atsign/temp/"; - ;; - esac - mv "$HOME_PATH/.atsign/temp/$TEMP_PATH/sshnp" "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME"; # Rename the extracted folder -} - -# Get the main binaries (branches based on the source: download/local/repo) -get_main_binaries() { - if [ -n "$SSHNP_DEV_MODE" ]; then - build_dart_binaries - else - if [ -n "$SSHNP_LOCAL" ]; then - copy_local_archive - else - download_archive - fi - unpack_archive - fi -} - -# Place the actual sshnp binary -setup_main_binaries() { - MAIN_BINARIES="$BINARY_NAME at_activate sshrv"; - for binary in $MAIN_BINARIES; do - mv "$HOME_PATH/.atsign/temp/$BINARY_NAME/$binary" "$HOME_PATH/.local/bin/$binary"; - chmod +x "$HOME_PATH/.local/bin/$binary"; - done - echo "Installed binaries: $MAIN_BINARIES"; -} - -# Place custom user based scripts -setup_custom_binary() { - SSHNP_KEY_FILE="$BINARY_NAME$DEVICE_MANAGER_ATSIGN" - ssh-keygen -o -a 100 -t ed25519 -f "$HOME_PATH/.ssh/$SSHNP_KEY_FILE" \ - -C "$BINARY_NAME$CLIENT_ATSIGN$DEVICE_MANAGER_ATSIGN" -N "" -q; - - echo "Installing $BINARY_NAME$DEVICE_MANAGER_ATSIGN to $HOME_PATH/.local/bin/$BINARY_NAME$DEVICE_MANAGER_ATSIGN"; - # = is used as the delimiter to avoid escaping / in the path - sed -e "s=\$BINARY_PATH=$HOME_PATH/.local/bin/$BINARY_NAME=g" \ - -e "s/\$SSHNP_PUBLIC_KEY/$SSHNP_KEY_FILE.pub/g" \ - -e "s/\$CLIENT_ATSIGN/$CLIENT_ATSIGN/g" \ - -e "s/\$DEVICE_MANAGER_ATSIGN/$DEVICE_MANAGER_ATSIGN/g" \ - -e "s/\$DEFAULT_HOST_ATSIGN/$HOST_RENDEZVOUS_ATSIGN/g" \ - <"$HOME_PATH/.atsign/temp/$BINARY_NAME/templates/client/sshnp-full.sh" \ - >"$HOME_PATH/.local/bin/$BINARY_NAME$DEVICE_MANAGER_ATSIGN" - chmod +x "$HOME_PATH/.local/bin/$BINARY_NAME$DEVICE_MANAGER_ATSIGN"; -} - - - -do_install() { - make_dirs - get_main_binaries - setup_main_binaries - - setup_custom_binary - - if ! echo "$PATH" | grep -q "$HOME_PATH/.local/bin"; then - PATH="\$PATH:$HOME_PATH/.local/bin"; - echo; - echo "Added $HOME_PATH/.local/bin to your PATH." - echo "Include the following line in your shell profile to persist across logins:" - echo " export PATH=\"\$PATH:$HOME_PATH/.local/bin\"" - fi - - echo; echo "Installation complete!"; -} - -do_update() { - make_dirs - get_main_binaries - setup_main_binaries - - echo; echo "Update complete!"; -} - -# Wrapping install steps prevents issues caused by interrupting the download -main () { - parse_requirements - REQ_ERRORS=$(check_requirements) - if [ -n "$REQ_ERRORS" ] ; then - echo "[ERROR] System failed to meet the following requirements:" - echo "$REQ_ERRORS" - exit 1 - fi - validate_args - parse_env - case "$SSHNP_OP" in - install) - do_install - ;; - update) - do_update - ;; - *) - echo "Invalid operation: $SSHNP_OP"; - exit 1; - ;; - esac -} - -parse_args "$@"; -main diff --git a/packages/sshnoports/scripts/install_sshnpd b/packages/sshnoports/scripts/install_sshnpd deleted file mode 100755 index 78881a18c..000000000 --- a/packages/sshnoports/scripts/install_sshnpd +++ /dev/null @@ -1,608 +0,0 @@ -#!/bin/bash - -BINARY_NAME="sshnpd"; - -# Prepend an @ to the front of the atsign if missing -norm_atsign() { - # shellcheck disable=SC2001 - atsign="@$(echo "$1" | sed -e 's/"//g' -e 's/^@//g')" - echo "$atsign" -} - -norm_version() { - version="tags/v$(echo "$1" | sed -e 's/"//g' -e 's/^tags\///g' -e 's/^v//g')" - echo "$version" -} - -# Print the usage information -usage() { - echo "Usage: $0 [options]" - echo "General options:" - echo " -u, --update Update all services instead of installing" - echo " --rename Rename device for client/device pair with the new name" - echo " -l, --local Install using local zip/tgz" - echo " -r, --repo Install using local repo" - echo " -h, --help Display this help message" - # Intentionally hidden argument used for debugging - # echo " --cache-temp Keep the temporary cache created by this script" - echo "" - echo "Installation options:" - echo " -c, --client
Client address (e.g. @alice_client)" - echo " -d, --device
Device address (e.g. @alice_device)" - echo " -n, --name Name of the device" - echo " -v, --version Version to install (default: latest)" - echo " --args Additional arguments to sshnpd (\"-v\" by default)" - echo " Possible args:" - echo " -s, --[no-]sshpublickey Update authorized_keys to include public key from sshnp" - echo " -u, --[no-]un-hide When set, makes various information visible to the manager atSign - e.g. username, version, etc" - echo " -v, --[no-]verbose More logging" - echo "" - echo "Rename options:" - echo " -c, --client
Client address (e.g. @alice_client)" - echo " -n, --name New name of the device" -} - -# Parse the command-line args -parse_args() { - SSHNP_OP="install" - while [ $# -gt 0 ]; do - case "$1" in - -u|--update) - SSHNP_OP="update" - shift 1 - ;; - --rename) - SSHNP_OP="rename" - shift 1 - ;; - --cache-temp) - SSHNP_CACHE_TEMP=1 - shift 1 - ;; - -h|--help) - usage - exit 0 - ;; - -l|--local) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_LOCAL="$2" - shift 2 - ;; - -r|--repo) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_DEV_MODE="$2" - shift 2 - ;; - -c|--client) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - CLIENT_ATSIGN="$2" - shift 2 - ;; - -d|--device) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - DEVICE_MANAGER_ATSIGN="$2" - shift 2 - ;; - -n|--name) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_DEVICE_NAME="$2" - shift 2 - ;; - -v|--version) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_VERSION="$2" - shift 2 - ;; - --args) - if [ $# -lt 0 ]; then - echo "Missing argument for $1"; - exit 1; - fi - SSHNP_SERVICE_ARGS="$2" - SSHNP_SERVICE_ARGS_PARSED=1 - shift 2 - ;; - *) - echo "Unknown argument: $1" - exit 1 - ;; - esac - done -} - -# Prompt for any missing but required arguments -validate_args() { - case "$SSHNP_OP" in - install|rename) - if [ -z "$CLIENT_ATSIGN" ]; then - read -rp "Client address (e.g. @alice_client): " CLIENT_ATSIGN; - fi - - if [ "$SSHNP_OP" != 'rename' ] && [ -z "$DEVICE_MANAGER_ATSIGN" ]; then - read -rp "Device address (e.g. @alice_device): " DEVICE_MANAGER_ATSIGN; - fi - - if [ -z "$SSHNP_DEVICE_NAME" ]; then - read -rp "Device name: " SSHNP_DEVICE_NAME; - fi - - while [ -z "$SSHNP_DEVICE_NAME" ] || - [ "${#SSHNP_DEVICE_NAME}" -gt 15 ] || - echo "$SSHNP_DEVICE_NAME" | grep -Eq "[^a-zA-Z0-9_]"; do - echo "Device name must be between 1 and 15 characters and only contain alphanumeric characters or \"_\""; - read -rp "Device name: " SSHNP_DEVICE_NAME; - done; - - CLIENT_ATSIGN="$(norm_atsign "$CLIENT_ATSIGN")" - DEVICE_MANAGER_ATSIGN="$(norm_atsign "$DEVICE_MANAGER_ATSIGN")" - echo; - esac -} - -# Load requirements statuses into variables -parse_requirements() { - REQ_SSH=$(command -v ssh) - REQ_SSHD=$(command -v sshd) - REQ_CRON=$(command -v crontab) - # REQ_SSH0=$(ssh -o "StrictHostKeyChecking no" -o "PasswordAuthentication no" 0 exit 2>/dev/null; echo $?) - if [ -n "$(command -v pgrep)" ]; then - REQ_SSHD_SERVICE=$(pgrep sshd) - REQ_CRON_SERVICE=$(pgrep cron) - else - # shellcheck disable=SC2009 - REQ_SSHD_SERVICE=$(ps -ef | grep -v grep | grep sshd | awk '{print $2}') - # shellcheck disable=SC2009 - REQ_CRON_SERVICE=$(ps -ef | grep -v grep | grep cron | awk '{print $2}') - fi - REQ_CURL=$(command -v curl) - REQ_TMUX=$(command -v tmux) - REQ_LOGR=$(command -v logrotate) -} - -# Check the script's requirements -check_requirements() { - if [ -z "$REQ_SSH" ]; then - echo " [X] Missing required dependency: ssh" - elif [ -z "$REQ_SSHD" ]; then - echo " [X] Missing required dependency: sshd" - elif [ -z "$REQ_SSHD_SERVICE" ]; then - echo " [X] sshd is not running" - fi - if [ -z "$REQ_CURL" ] && [ -z "$SSHNP_DEV_MODE" ] && [ -z "$SSHNP_LOCAL" ]; then - echo " [X] Missing required dependency: curl" - fi - if [ -z "$REQ_CURL" ] && [ -z "$SSHNP_DEV_MODE" ] && [ -z "$SSHNP_LOCAL" ]; then - echo " [X] Missing required dependency: curl" - fi - if [ -z "$REQ_CRON" ]; then - echo " [X] Missing required dependency: cron" - elif [ -z "$REQ_CRON_SERVICE" ]; then - echo " [X] cron is not running" - fi - if [ -z "$REQ_TMUX" ] && [ -z "$REQ_LOGR" ]; then - echo " [X] Missing required dependency" - echo " One of the following dependencies must be installed:" - echo " - tmux" - echo " - logrotate" - fi -} - -# Parse the system environment -parse_env() { - if [ -z "$SSHNP_USER" ]; then - SSHNP_USER="$USER"; - fi - HOME_PATH=$(eval echo "~$SSHNP_USER"); - - if [ -z "$SSHNP_VERSION" ]; then - SSHNP_VERSION="latest"; - else - SSHNP_VERSION="$(norm_version "$SSHNP_VERSION")" - fi - URL="https://api.github.com/repos/atsign-foundation/sshnoports/releases/$SSHNP_VERSION"; - - case "$(uname)" in - Darwin) - PLATFORM="macos" - EXT="zip" - ;; - Linux) - PLATFORM="linux" - EXT="tgz" - ;; - *) - PLATFORM="Unknown" - ;; - esac - - if [ "$PLATFORM" = "Unknown" ]; then - echo "Unsupported platform: $(uname)"; - exit 1; - fi - - # ARCH includes the dot at the end to avoid conflict between arm and arm64 - case "$(uname -m)" in - aarch64|arm64) ARCH="arm64\.";; - x86_64|amd64) ARCH="x64\.";; - armv7l|arm) ARCH="arm\.";; - riscv64) ARCH="riscv64\.";; - *) ARCH="Unknown";; - esac - - if [ "$ARCH" = "Unknown" ]; then - echo "Unsupported architecture: $(uname -m)"; - exit 1; - fi - - if [ -z "$SSHNP_LOCAL" ] && [ -z "$SSHNP_DEV_MODE" ]; then - DOWNLOADS=$(curl -s "$URL" | grep browser_download_url | cut -d\" -f4); - DOWNLOAD=$(echo "$DOWNLOADS" | grep "$PLATFORM" | grep "$ARCH" | cut -d\" -f4) - fi - - if [ -n "$SSHNP_DEV_MODE" ]; then - TEMP_PATH=$(date +%s); - elif [ -n "$SSHNP_LOCAL" ]; then - TEMP_PATH=$(date +%s); - else - TEMP_PATH="$SSHNP_VERSION" - fi - - if [ -z "$SSHNP_SERVICE_ARGS_PARSED" ]; then - SSHNP_SERVICE_ARGS="-v"; - else - SSHNP_SERVICE_ARGS="${SSHNP_SERVICE_ARGS//\"/\\\"}"; - fi -} - -# Remove the temporary folder generated for processing the download/install -cleanup() { - if [ -z "$SSHNP_CACHE_TEMP" ]; then - rm -rf "$HOME_PATH/.atsign/temp/$TEMP_PATH"; - fi -} - -# Make the necessary directories for sshnpd -make_dirs() { - rm -rf "$HOME_PATH/.atsign/temp/$TEMP_PATH"; - mkdir -p "$HOME_PATH/.ssh/" \ - "$HOME_PATH/.$BINARY_NAME/logs" \ - "$HOME_PATH/.atsign/keys" \ - "$HOME_PATH/.atsign/temp/$TEMP_PATH" \ - "$HOME_PATH/.local/bin"; - - if [ ! -f "$HOME_PATH/.ssh/authorized_keys" ]; then - touch "$HOME_PATH/.ssh/authorized_keys"; - chmod 600 "$HOME_PATH/.ssh/authorized_keys"; - fi -} - -# Build the dart binaries from the provided repo -build_dart_binaries() { - echo "DEV MODE: Installing from local repo: $SSHNP_DEV_MODE"; - mkdir -p "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/templates/" - - cp -R "$SSHNP_DEV_MODE"/packages/sshnoports/templates/* "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/templates/"; - - dart pub get -C "$SSHNP_DEV_MODE/packages/sshnoports" - - dart compile exe "$SSHNP_DEV_MODE/packages/sshnoports/bin/sshnp.dart" -o "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/sshnp"; - dart compile exe "$SSHNP_DEV_MODE/packages/sshnoports/bin/sshnpd.dart" -o "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/sshnpd"; - dart compile exe "$SSHNP_DEV_MODE/packages/sshnoports/bin/sshrv.dart" -o "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/sshrv"; - dart compile exe "$SSHNP_DEV_MODE/packages/sshnoports/bin/sshrvd.dart" -o "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/sshrvd"; - dart compile exe "$SSHNP_DEV_MODE/packages/sshnoports/bin/activate_cli.dart" -o "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/at_activate"; -} - -# Make a copy of the locally provided archive -copy_local_archive() { - echo "DEV MODE: Installing using local $EXT file: $SSHNP_LOCAL"; - cp "$SSHNP_LOCAL" "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME.$EXT"; -} - -# Download the release archive -download_archive() { - echo "Downloading $BINARY_NAME from $DOWNLOAD"; - curl -sL "$DOWNLOAD" -o "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME.$EXT"; - if [ ! -f "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME.$EXT" ]; then - echo "Failed to download $BINARY_NAME"; - echo; - echo "Please try again, or download manually from $DOWNLOAD"; - echo "After downloading manually, run the following command to install:"; - if [ "$0" == 'bash' ]; then - echo "bash -c \"\$(curl https://get$BINARY_NAME.noports.com)\" -- -l "; - else - echo " $0 -l "; - fi - cleanup - exit 1; - fi -} - -# Unpack the downloaded / locally provided archive -unpack_archive() { - if [ ! -f "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME.$EXT" ]; then - echo "Failed to download $BINARY_NAME"; - echo; - echo "Please try again, or download manually from $DOWNLOAD"; - echo "After downloading manually, run the following command to install:"; - if [ "$0" = 'bash' ]; then - echo "bash -c \"\$(curl https://getsshnpd.noports.com)\" -- -l "; - else - echo " $0 -l "; - fi - cleanup - exit 1; - fi - - case "$EXT" in - zip) - unzip -qo "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME.$EXT" -d "$HOME_PATH/.atsign/temp/$TEMP_PATH/"; - ;; - tgz|tar.gz) - tar -zxf "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME.$EXT" -C "$HOME_PATH/.atsign/temp/$TEMP_PATH/"; - ;; - esac - mv "$HOME_PATH/.atsign/temp/$TEMP_PATH/sshnp" "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME"; # Rename the extracted folder -} - -# Get the main binaries (branches based on the source: download/local/repo) -get_main_binaries() { - if [ -n "$SSHNP_DEV_MODE" ]; then - build_dart_binaries - else - if [ -n "$SSHNP_LOCAL" ]; then - copy_local_archive - else - download_archive - fi - unpack_archive - fi -} - -# Place the actual sshnp binary -setup_main_binaries() { - MAIN_BINARIES="$BINARY_NAME at_activate sshrv"; - for binary in $MAIN_BINARIES; do - mv "$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/$binary" "$HOME_PATH/.local/bin/$binary"; - chmod +x "$HOME_PATH/.local/bin/$binary"; - done - echo "Installed binaries: $MAIN_BINARIES"; -} - -# Kills the service outright -kill_service() { - killall -q -u "$SSHNP_USER" -r "$BINARY_NAME$CLIENT_ATSIGN$" -} - -# Kills the underlying instance, service will automatically restart -restart_service() { - killall -q -u "$SSHNP_USER" -r "$BINARY_NAME$" -} - -# Rename device given the version of the service file -rename_device() { - case "$SERVICE_RUN_VERSION" in - 1.*) - echo 1 - # Old format, no NAME= line - SERVICE_RUN_LINE=$(grep 'sshnpd ' < "$SSHNPD_SERVICE_BINARY_PATH") - OLD_DEVICE_NAME=$(echo "${SERVICE_RUN_LINE// -d /;/}" | cut -d';' -f2 | cut -d '"' -f2) - - # This replace should be fine since it wraps the device name in quotes - # all other quotations in v1.0.0 start with a special character (either $ or @) - # these characters are not supported by device name format - # so this string will never match anything else in the file - if [[ "$PLATFORM" = "macos" ]]; - then - sed -i '' "s/\"$OLD_DEVICE_NAME\"/\"$SSHNP_DEVICE_NAME\"/g" "$SSHNPD_SERVICE_BINARY_PATH" - else - sed -i "s/\"$OLD_DEVICE_NAME\"/\"$SSHNP_DEVICE_NAME\"/g" "$SSHNPD_SERVICE_BINARY_PATH" - fi - ;; - 2.*) - echo 2 - # New format, NAME= line - SERVICE_RUN_LINE=$(grep 'NAME=' < "$SSHNPD_SERVICE_BINARY_PATH") - OLD_DEVICE_NAME=$(echo "$SERVICE_RUN_LINE" | cut -d'=' -f2 | cut -d'"' -f2) - - # Since NAME= is on its own line, we can just replace the whole line - if [[ "$PLATFORM" = "macos" ]]; - then - sed -i '' "s/NAME=\"$OLD_DEVICE_NAME\"/NAME=\"$SSHNP_DEVICE_NAME\"/g" "$SSHNPD_SERVICE_BINARY_PATH" - else - sed -i "s/NAME=\"$OLD_DEVICE_NAME\"/NAME=\"$SSHNP_DEVICE_NAME\"/g" "$SSHNPD_SERVICE_BINARY_PATH" - fi - ;; - esac - - echo "Renamed $OLD_DEVICE_NAME to $SSHNP_DEVICE_NAME" -} - -# Place custom user based scripts -setup_service_script() { - SSHNPD_SERVICE_BINARY_PATH="$HOME_PATH/.local/bin/$BINARY_NAME$CLIENT_ATSIGN"; - SERVICE_RUN_VERSION="$(sed '2!d' "$SSHNPD_SERVICE_BINARY_PATH" | cut -d'v' -f2)" - - if [ "$SSHNP_OP" = 'rename' ] && [ ! -f "$SSHNPD_SERVICE_BINARY_PATH" ]; then - echo "Error: trying to rename service, but service binary not found"; - exit 1; - fi - if [ "$SSHNP_OP" = 'install' ]; then - # Set [SSHNP_SERVICE_ARGS] to include additional arguments to sshnpd - sed -e "s=\$HOME=$HOME_PATH=g" \ - -e "s/\$1/$DEVICE_MANAGER_ATSIGN/g" \ - -e "s/\$2/$CLIENT_ATSIGN/g" \ - -e "s/\$3/$SSHNP_DEVICE_NAME/g" \ - -e "s/\$\*/$SSHNP_SERVICE_ARGS/g" \ - <"$HOME_PATH/.atsign/temp/$TEMP_PATH/$BINARY_NAME/templates/headless/sshnpd.sh" \ - >"$SSHNPD_SERVICE_BINARY_PATH"; - chmod +x "$SSHNPD_SERVICE_BINARY_PATH"; - elif [ "$SSHNP_OP" = 'rename' ]; then - rename device - fi -} - -# Setup the cron job part of the service setup -setup_service_job() { - SSHNP_CRON_SCHEDULE="@reboot"; - if command -v tmux >/dev/null; then - SSHNPD_SERVICE_MECHANISM="tmux"; - SSHNP_COMMAND="tmux new-session -d -s $BINARY_NAME$CLIENT_ATSIGN && tmux send-keys -t $BINARY_NAME$CLIENT_ATSIGN $SSHNPD_SERVICE_BINARY_PATH C-m" - # Untested for the time being, feel free to use at your own risk: - # elif command -v screen; then - # SSHNP_COMMAND="screen -dmS $BINARY_NAME$CLIENT_ATSIGtN $SSHNPD_SERVICE_BINARY_PATH" - else - SSHNPD_SERVICE_MECHANISM="cron"; - SSHNP_COMMAND="nohup $SSHNPD_SERVICE_BINARY_PATH > $HOME_PATH/.$BINARY_NAME/logs/$CLIENT_ATSIGN.log 2> $HOME_PATH/.$BINARY_NAME/logs/$CLIENT_ATSIGN.err" - LOGROTATE="40 6 * * * logrotate -f $HOME_PATH/.$BINARY_NAME/logs/$CLIENT_ATSIGN.log" - fi - - CRONTAB_CONTENTS=$(crontab -l 2>/dev/null); - PREVIOUS_CRON_ENTRY=$(echo "$CRONTAB_CONTENTS" | grep -Fxq "$SSHNP_CRON_SCHEDULE $SSHNP_COMMAND") - if [ -n "$PREVIOUS_CRON_ENTRY" ]; then - NO_RUN=1; - echo "Cron job already installed: '$SSHNP_CRON_SCHEDULE $SSHNP_COMMAND'"; - else - (echo "$CRONTAB_CONTENTS"; echo "$SSHNP_CRON_SCHEDULE $SSHNP_COMMAND") | crontab - - echo "Installed cron job: '$SSHNP_CRON_SCHEDULE $SSHNP_COMMAND'"; - fi - - - if [ "$SSHNPD_SERVICE_MECHANISM" = "cron" ]; then - CRONTAB_CONTENTS=$(crontab -l 2>/dev/null); - PREVIOUS_LOGROTATE_ENTRY=$(echo "$CRONTAB_CONTENTS" | grep -Fxq "$LOGROTATE") - if [ -n "$PREVIOUS_LOGROTATE_ENTRY" ]; then - echo "Cron job already installed: '$LOGROTATE'"; - else - (echo "$CRONTAB_CONTENTS"; echo "$LOGROTATE") | crontab - - echo "Installed cron job: '$LOGROTATE'"; - fi - fi -} - -# Setup the service list entry part of the service setup -setup_service_entry() { - if [ ! -f "$SERVICE_LIST_FILE" ]; then - touch "$SERVICE_LIST_FILE"; - fi - - PREVIOUS_SERVICE_ENTRY=$(grep "$BINARY_NAME$CLIENT_ATSIGN " < "$SERVICE_LIST_FILE"); - OTHER_SERVICE_ENTRIES=$(grep -v "$BINARY_NAME$CLIENT_ATSIGN " < "$SERVICE_LIST_FILE"); - - if [ -n "$PREVIOUS_SERVICE_ENTRY" ]; then - echo "Removing previous service entry: $PREVIOUS_SERVICE_ENTRY"; - echo "$OTHER_SERVICE_ENTRIES" > "$SERVICE_LIST_FILE"; - fi - - if [ -n "$PREVIOUS_SERVICE_ENTRY" ] || [ "$SSHNP_OP" = 'install' ] ; then - echo "$BINARY_NAME$CLIENT_ATSIGN $SSHNPD_SERVICE_MECHANISM" >> "$SERVICE_LIST_FILE"; - fi - - if [ -n "$PREVIOUS_SERVICE_ENTRY" ]; then - echo "Service entry updated: $BINARY_NAME$CLIENT_ATSIGN $SSHNPD_SERVICE_MECHANISM"; - echo "Restarting service..."; - NO_RUN=''; - PREVIOUS_SERVICE_MECHANISM=$(echo "$PREVIOUS_SERVICE_ENTRY" | cut -d' ' -f2); - case "$PREVIOUS_SERVICE_MECHANISM" in - cron) - kill_service; - ;; - tmux) - tmux kill-session -t "$BINARY_NAME$CLIENT_ATSIGN"; - ;; - esac - else - echo "Service entry added: $BINARY_NAME$CLIENT_ATSIGN $SSHNPD_SERVICE_MECHANISM"; - fi -} - -# Place custom user based scripts -setup_service() { - # Files used by the setup functions below - SSHNPD_SERVICE_BINARY_PATH="$HOME_PATH/.local/bin/$BINARY_NAME$CLIENT_ATSIGN"; - SERVICE_LIST_FILE="$HOME_PATH/.$BINARY_NAME/.service_list"; - - setup_service_script - setup_service_job - setup_service_entry - - # Will start the service if needed (determine by the previous setup functions) - if [ -z "$NO_RUN" ]; then - echo "Starting $BINARY_NAME$CLIENT_ATSIGN service..."; - eval "$SSHNP_COMMAND &" - fi -} - -# Install a new sshnpd instance -do_install() { - make_dirs - get_main_binaries - setup_main_binaries - setup_service - cleanup - echo; echo "Installation complete!"; -} - -# Perform an update of all the sshnpd on the local user -do_update() { - make_dirs - get_main_binaries - setup_main_binaries - cleanup - echo; echo "Update complete!"; - restart_service -} - -# Perform a rename of an sshnpd instance -do_rename() { - setup_service - echo; echo "Rename complete!"; -} - -# Wrapping install steps prevents issues caused by interrupting the download -main () { - parse_requirements - REQ_ERRORS=$(check_requirements) - if [ -n "$REQ_ERRORS" ] ; then - echo "[ERROR] System failed to meet the following requirements:" - echo "$REQ_ERRORS" - exit 1 - fi - validate_args - parse_env - case "$SSHNP_OP" in - install) - do_install - ;; - update) - do_update - ;; - rename) - do_rename - ;; - *) - echo "Invalid operation: $SSHNP_OP"; - exit 1; - ;; - esac -} - -parse_args "$@"; -main diff --git a/scripts/install_sshnpd b/scripts/install_sshnpd index 78881a18c..1d014cccc 100755 --- a/scripts/install_sshnpd +++ b/scripts/install_sshnpd @@ -267,8 +267,6 @@ parse_env() { if [ -z "$SSHNP_SERVICE_ARGS_PARSED" ]; then SSHNP_SERVICE_ARGS="-v"; - else - SSHNP_SERVICE_ARGS="${SSHNP_SERVICE_ARGS//\"/\\\"}"; fi } diff --git a/tests/end2end_tests/image/Dockerfile b/tests/end2end_tests/image/Dockerfile index 556e66cee..fa29c4c7a 100644 --- a/tests/end2end_tests/image/Dockerfile +++ b/tests/end2end_tests/image/Dockerfile @@ -1,3 +1,30 @@ +# BASE +FROM debian:stable-20230814-slim@sha256:6fe30b9cb71d604a872557be086c74f95451fecd939d72afe3cffca3d9e60607 AS base + +ENV USER=atsign +ENV HOMEDIR=/${USER} +ENV USER_ID=1024 +ENV GROUP_ID=1024 + +CMD sudo service ssh start + +RUN set -eux ; \ + apt-get update ; \ + apt-get install -y openssh-server sudo vim nano iproute2 nmap tmux curl cron ; \ + groupadd --gid ${GROUP_ID} ${USER} ; \ + useradd --system --shell /bin/bash --home ${HOMEDIR} --uid ${USER_ID} --gid ${GROUP_ID} ${USER} ; \ + usermod -aG sudo ${USER} ; \ + mkdir -p ${HOMEDIR}/.ssh ${HOMEDIR}/.atsign/keys ${HOMEDIR}/.local/bin ; \ + touch ${HOMEDIR}/.ssh/authorized_keys ; \ + ssh-keygen -t ed25519 -a 100 -f ${HOMEDIR}/.ssh/id_ed25519 -q -N '' ; \ + chown -R ${USER}:${USER} ${HOMEDIR} ; \ + ex +"%s/^%sudo.*$/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/g" -scwq! /etc/sudoers ; \ + sed -E -i 's|^#?(PasswordAuthentication)\s.*|\1 no|' /etc/ssh/sshd_config ; \ + sed -i 's/#ListenAddress 0.0.0.0/ListenAddress 127.0.0.1/g' /etc/ssh/sshd_config ; +# END BASE + +# BRANCH +# BUILD BRANCH FROM dart:3.0.7@sha256:4dc0299dd863edbf81e0e43490fa9c610f6655b62a2e1bc0e0dc02dfea2105eb AS build-branch ENV URL=https://github.com/atsign-foundation/sshnoports.git @@ -20,6 +47,20 @@ RUN set -eux ; \ dart compile exe ${REPO_DIR}/packages/sshnoports/bin/sshrvd.dart -o ${OUTPUT_DIR}/sshrvd ; \ dart compile exe ${REPO_DIR}/packages/sshnoports/bin/activate_cli.dart -o ${OUTPUT_DIR}/at_activate ; +# RUNTIME BRANCH +FROM base AS runtime-branch + +COPY --chown=${USER}:${USER} --from=build-branch /app/output ${HOMEDIR}/.local/bin + +WORKDIR ${HOMEDIR} + +USER ${USER} + +ENTRYPOINT sudo service ssh start && sh ${HOMEDIR}/entrypoint.sh +# END BRANCH + +# LOCAL +# BUILD LOCAL FROM dart:3.0.7@sha256:4dc0299dd863edbf81e0e43490fa9c610f6655b62a2e1bc0e0dc02dfea2105eb AS build-local ENV REPO_DIR=/app/repo @@ -39,6 +80,20 @@ RUN set -eux ; \ dart compile exe ${REPO_DIR}/packages/sshnoports/bin/sshrvd.dart -o ${OUTPUT_DIR}/sshrvd ; \ dart compile exe ${REPO_DIR}/packages/sshnoports/bin/activate_cli.dart -o ${OUTPUT_DIR}/at_activate ; +# RUNTIME LOCAL +FROM base AS runtime-local + +COPY --chown=${USER}:${USER} --from=build-local /app/output ${HOMEDIR}/.local/bin + +WORKDIR ${HOMEDIR} + +USER ${USER} + +ENTRYPOINT sudo service ssh start && sh ${HOMEDIR}/entrypoint.sh +# END LOCAL + +# RELEASE +# BUILD RELEASE FROM debian:stable-20230814-slim@sha256:6fe30b9cb71d604a872557be086c74f95451fecd939d72afe3cffca3d9e60607 AS build-release ARG release @@ -74,39 +129,7 @@ RUN apt-get update ; \ cd sshnp ; \ mv sshnp sshnpd sshrv sshrvd at_activate ${OUTPUT_DIR} ; -FROM debian:stable-20230814-slim@sha256:6fe30b9cb71d604a872557be086c74f95451fecd939d72afe3cffca3d9e60607 AS base - -ENV USER=atsign -ENV HOMEDIR=/${USER} -ENV USER_ID=1024 -ENV GROUP_ID=1024 - -CMD sudo service ssh start - -RUN set -eux ; \ - apt-get update ; \ - apt-get install -y openssh-server sudo vim nano iproute2 nmap tmux curl cron ; \ - groupadd --gid ${GROUP_ID} ${USER} ; \ - useradd --system --shell /bin/bash --home ${HOMEDIR} --uid ${USER_ID} --gid ${GROUP_ID} ${USER} ; \ - usermod -aG sudo ${USER} ; \ - mkdir -p ${HOMEDIR}/.ssh ${HOMEDIR}/.atsign/keys ${HOMEDIR}/.local/bin ; \ - touch ${HOMEDIR}/.ssh/authorized_keys ; \ - ssh-keygen -t ed25519 -a 100 -f ${HOMEDIR}/.ssh/id_ed25519 -q -N '' ; \ - chown -R ${USER}:${USER} ${HOMEDIR} ; \ - ex +"%s/^%sudo.*$/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/g" -scwq! /etc/sudoers ; \ - sed -E -i 's|^#?(PasswordAuthentication)\s.*|\1 no|' /etc/ssh/sshd_config ; \ - sed -i 's/#ListenAddress 0.0.0.0/ListenAddress 127.0.0.1/g' /etc/ssh/sshd_config ; - -FROM base AS runtime-branch - -COPY --chown=${USER}:${USER} --from=build-branch /app/output ${HOMEDIR}/.local/bin - -WORKDIR ${HOMEDIR} - -USER ${USER} - -ENTRYPOINT sudo service ssh start && sh ${HOMEDIR}/entrypoint.sh - +# RUNTIME RELEASE FROM base AS runtime-release COPY --chown=${USER}:${USER} --from=build-release /app/output ${HOMEDIR}/.local/bin @@ -116,17 +139,10 @@ WORKDIR ${HOMEDIR} USER ${USER} ENTRYPOINT sudo service ssh start && sh ${HOMEDIR}/entrypoint.sh +# END RELEASE -FROM base AS runtime-local - -COPY --chown=${USER}:${USER} --from=build-local /app/output ${HOMEDIR}/.local/bin - -WORKDIR ${HOMEDIR} - -USER ${USER} - -ENTRYPOINT sudo service ssh start && sh ${HOMEDIR}/entrypoint.sh - +# SSHNP INSTALLER +# BUILD SSHNP INSTALLER FROM base AS build-sshnp-installer USER ${USER} @@ -142,27 +158,28 @@ ARG device_atsign ARG host_atsign RUN set -eux; \ - sh ${REPO_DIR}/packages/sshnoports/scripts/install_sshnp \ + sh ${REPO_DIR}/scripts/install_sshnp \ -c ${client_atsign} \ -d ${device_atsign} \ -h ${host_atsign}; +# RUNTIME SSHNP INSTALLER FROM build-sshnp-installer AS runtime-sshnp-installer USER ${USER} WORKDIR ${HOMEDIR} -ENV USE_INSTALLER=1 - ENTRYPOINT sudo service ssh start && sh ${HOMEDIR}/entrypoint.sh +# END SSHNP INSTALLER +# SSHNPD INSTALLER +# BUILD SSHNPD INSTALLER FROM base AS build-sshnpd-installer USER ${USER} WORKDIR ${HOMEDIR} ENV REPO_DIR=/app/repo -ENV USE_INSTALLER=1 # context must be the root of the repo COPY . ${REPO_DIR} @@ -174,20 +191,22 @@ ARG device_name RUN set -eux ; \ sudo service cron start; \ sudo service ssh start; \ - sh ${REPO_DIR}/packages/sshnoports/scripts/install_sshnpd \ + sh ${REPO_DIR}/scripts/install_sshnpd \ -c ${client_atsign} \ -d ${device_atsign} \ - -n ${device_name}; + -n ${device_name} \ + --args "-s -u -v" ; +# RUNTIME SSHNPD INSTALLER FROM build-sshnpd-installer AS runtime-sshnpd-installer USER ${USER} WORKDIR ${HOMEDIR} -ENV USE_INSTALLER=1 - ENTRYPOINT sudo service ssh start && sh ${HOMEDIR}/entrypoint.sh +# END SSHNPD INSTALLER +# MANUAL FROM runtime-branch AS manual-branch ENTRYPOINT sudo service ssh start && bash @@ -207,3 +226,4 @@ WORKDIR ${HOMEDIR} USER ${USER} ENTRYPOINT sudo service ssh start && bash +# END MANUAL \ No newline at end of file diff --git a/tests/end2end_tests/templates/sshnpd_installer_entrypoint.sh b/tests/end2end_tests/templates/sshnpd_installer_entrypoint.sh index d7466ad84..f442e49b1 100644 --- a/tests/end2end_tests/templates/sshnpd_installer_entrypoint.sh +++ b/tests/end2end_tests/templates/sshnpd_installer_entrypoint.sh @@ -1,4 +1,4 @@ #!/bin/bash -SSHNPD_COMMAND="$HOME/.local/bin/sshnpd@sshnpatsign -s -u" +SSHNPD_COMMAND="$HOME/.local/bin/sshnpd@sshnpatsign" echo "Running: $SSHNPD_COMMAND" eval "$SSHNPD_COMMAND"