173 lines
5.0 KiB
Bash
Executable File
173 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# AUTHOR: Clemens Schwaighofer
|
|
# DATE: 2025/6/27
|
|
# DESC: create a new basic clone
|
|
|
|
# COMMAND: new_clone.sh <Repo.git> <branch> [<host>] [<Repo Target Name>] [<remote name>]
|
|
|
|
|
|
function error() {
|
|
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
|
|
}
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $(basename "${BASH_SOURCE[0]}") [-h | --help] -r | --repository <Repository URL> -b | --branch <Branch Name> [-H | --host <Host name>] [-f | --folder <Folder name>] [-n | --remote <Remote name>]
|
|
|
|
New clone a git repository via ssh into the clone folder.
|
|
|
|
Available options:
|
|
|
|
-h, --help Print this help and exit
|
|
-r, --repository <Repository URL> Repository path (e.g. user/repo.git)
|
|
-b, --branch <Branch Name> Branch to clone (e.g. main)
|
|
-H, --host <Host name> Override SSH host from ssh config (e.g. my-ssh-host)
|
|
-f, --folder <Folder name> Target folder name for the repository (e.g. repo-name)
|
|
-n, --remote <Remote name> Remote name (defaults to origin)
|
|
|
|
EOF
|
|
exit
|
|
}
|
|
|
|
# REPOSITORY="$1";
|
|
# BRANCH="$2";
|
|
# REMOTE_HOST="$3";
|
|
# REPOSITORY_FOLDER="$4"
|
|
# REMOTE_NAME="$5";
|
|
# if [ "${REPOSITORY}" == "--help" ]; then
|
|
# echo "$0 <Repo.git> <branch> [<override host>] [<target folder>] [<remote name, defaults to origin>]";
|
|
# exit;
|
|
# fi;
|
|
REPOSITORY="";
|
|
BRANCH="";
|
|
REMOTE_HOST="";
|
|
REPOSITORY_FOLDER="";
|
|
REMOTE_NAME="origin";
|
|
while [ -n "${1-}" ]; do
|
|
case "${1}" in
|
|
-r | --repository)
|
|
REPOSITORY="${2-}";
|
|
shift
|
|
;;
|
|
-b | --branch)
|
|
BRANCH="${2-}";
|
|
shift
|
|
;;
|
|
-H | --host)
|
|
REMOTE_HOST="${2-}";
|
|
shift
|
|
;;
|
|
-f | --folder)
|
|
REPOSITORY_FOLDER="${2-}";
|
|
shift
|
|
;;
|
|
-n | --remote)
|
|
REMOTE_NAME="${2-}";
|
|
shift
|
|
;;
|
|
-h | --help)
|
|
usage
|
|
;;
|
|
# invalid option
|
|
-?*)
|
|
error "[!] Unknown option: '$1'."
|
|
;;
|
|
esac
|
|
shift;
|
|
done;
|
|
|
|
# if no repository or banch name given, show error
|
|
error=0
|
|
if [ -z "${REPOSITORY}" ]; then
|
|
echo "[!] Must set a repository full url, ssh only";
|
|
error=1;
|
|
fi;
|
|
if [ -z "${BRANCH}" ]; then
|
|
echo "[!] Must set a branch name";
|
|
error=1;
|
|
fi;
|
|
# further checks that repository folder if set can only by alphanumeric, -, _ or .
|
|
if [ -n "${REPOSITORY_FOLDER}" ]; then
|
|
if ! [[ "${REPOSITORY_FOLDER}" =~ ^[a-zA-Z0-9._-]+$ ]]; then
|
|
echo "[!] Repository folder name can only contain alphanumeric characters, dots, dashes or underscores";
|
|
error=1;
|
|
fi;
|
|
fi;
|
|
|
|
if [ $error -eq 1 ]; then
|
|
exit;
|
|
fi;
|
|
|
|
if [ -z "${REMOTE_NAME}" ]; then
|
|
REMOTE_NAME="origin"
|
|
fi;
|
|
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
|
# shellcheck source=init.sh
|
|
. "${BASE_FOLDER}init.sh";
|
|
|
|
if [ -z "${REPOSITORY}" ]; then
|
|
echo "[!] Must set a repository path";
|
|
error=1;
|
|
fi;
|
|
# if we have an ":" in the repository, split by it and replace it with the remote host
|
|
if [[ "${REPOSITORY}" == *":"* ]]; then
|
|
REPOSITORY=$(echo "${REPOSITORY}" | cut -d ":" -f 2);
|
|
fi;
|
|
# strip .git from the repository path, this is folder and ssh key Host name
|
|
if [ -z "${REPOSITORY_FOLDER}" ]; then
|
|
GIT_REPOSITORY_NAME=$(basename "${REPOSITORY}" .git);
|
|
else
|
|
GIT_REPOSITORY_NAME="${REPOSITORY_FOLDER}";
|
|
fi;
|
|
# set remote host if not set to the ssh config name
|
|
if [ -z "${REMOTE_HOST}" ]; then
|
|
REMOTE_HOST="${GIT_REPOSITORY_NAME}";
|
|
fi;
|
|
if [ $error -eq 1 ]; then
|
|
exit;
|
|
fi;
|
|
|
|
error=0
|
|
echo "* Validate SSH PEM Key exist and SSH config";
|
|
if ! grep "Host ${REMOTE_HOST}" "${GIT_WEBHOOK_BASE_FOLDER}"/.ssh/config; then
|
|
echo "[!] ssh config entry for Host ${REMOTE_HOST} is missing";
|
|
error=1;
|
|
else
|
|
# make sure the identiy file is there
|
|
# grep "IdentityFile" in this
|
|
SSH_TEST=("${SUDO_COMMAND[@]}" "ssh" "${REMOTE_HOST}");
|
|
result=$("${SSH_TEST[@]}" 2>&1);
|
|
# this can be key or deploy key
|
|
validate_string="You've successfully authenticated"
|
|
if [[ "$result" != *"$validate_string"* ]]; then
|
|
echo "Could not connect to ${REMOTE_HOST}: ${result}";
|
|
error=1;
|
|
fi;
|
|
fi;
|
|
|
|
if [ $error -eq 1 ]; then
|
|
exit;
|
|
fi;
|
|
|
|
unique_id=$(uuidgen | tr -d '-' | head -c 8);
|
|
|
|
# log folder target
|
|
LOG_FILE="${GIT_WEBHOOK_BASE_FOLDER}${LOG_FOLDER}${GIT_REPOSITORY_NAME}.log";
|
|
# from the repository get the last path without the .git so we have the target folder
|
|
echo "[$(date +"%Y-%m-%d %H:%M:%S")] [${unique_id}] [START] New clone from ${REMOTE_HOST}:${REPOSITORY}::${BRANCH} into ${GIT_REPOSITORY_NAME}" | tee -a "$LOG_FILE";
|
|
# clone everything
|
|
GIT_COMMAND=("${GIT_COMMAND_BASE[@]}" "clone" "-b" "${BRANCH}" "--single-branch" "--depth" "1" "--origin" "${REMOTE_NAME}" "${REMOTE_HOST}:${REPOSITORY}" "${GIT_WEBHOOK_BASE_FOLDER}${CLONE_BASE}${GIT_REPOSITORY_NAME}")
|
|
"${GIT_COMMAND[@]}" 2>&1 | tee -a "$LOG_FILE";
|
|
# set the repository folder
|
|
GIT_REPOSITORY_FOLDER="${GIT_WEBHOOK_BASE_FOLDER}${CLONE_BASE}${GIT_REPOSITORY_NAME}";
|
|
# show origin info
|
|
GIT_COMMAND=("${GIT_COMMAND_BASE[@]}" "-C" "${GIT_REPOSITORY_FOLDER}" remote show "${REMOTE_NAME}" );
|
|
"${GIT_COMMAND[@]}" 2>&1 | tee -a "$LOG_FILE";
|
|
# get last log entry
|
|
GIT_COMMAND=("${GIT_COMMAND_BASE[@]}" "-C" "${GIT_REPOSITORY_FOLDER}" log -n 1 --pretty=short --no-color);
|
|
"${GIT_COMMAND[@]}" 2>&1 | tee -a "$LOG_FILE";
|
|
echo "[$(date +"%Y-%m-%d %H:%M:%S")] [${unique_id}] [FINISH] clone completed" | tee -a "$LOG_FILE";
|
|
|
|
# __END__
|