#!/bin/bash set -euo pipefail IFS=$'\n\t' volume_prefix=cloner mirror_image="valicek1/repo-cloner-mirror" function die(){ echo $@ 1>&2 exit 1 } function checkProjectName(){ # check, if volume does not exist yet name=$1 # should not be empty [ -n "$read_project_name" ] || die "Empty project name is not allowed" set +e docker volume inspect $volume_prefix-$1 > /dev/null 2>&1 exists=$? set -e if [ $exists -eq 0 ] then die "Target volume for project '$name' exists - please try again!" fi } function createConfigFile(){ # creates config file, writes it to $1 location loc=$1 # vars local tmpl_name=$read_project_name local tmpl_url=$read_url local tmpl_interval=$read_interval local tmpl_submodules=$read_submodules if [ $read_submodule_limit = "N" ] then local tmpl_submodules_depth_enabled='# ' local tmpl_submodules_depth=50000 else local tmpl_submodules_depth_enabled='' local tmpl_submodules_depth=$read_submodule_limit fi cat > $loc <<-EOF # cloner.cfg # main config # created at $(date +"%Y-%m-%d %X") # main url - url of main repo - just to clone cloner_repo_url=$tmpl_url # project name (names of volumes are derrived from this cloner_project_name=$tmpl_name # cloner interval (in minutes, default=0 - run always) cloner_interval=$tmpl_interval # do you need submodules support? (1/0) cloner_submodules=$tmpl_submodules # max depth of submodule scan (default = unlimited, uncomment to use) ${tmpl_submodules_depth_enabled}cloner_submodule_depth=$tmpl_submodules_depth EOF } function generateSSHKey(){ # generates ssh key with $1 path and $2 description local keyfile=$1/id_rsa local description=$2 echo "Creating SSH deployment key.." ssh-keygen -f $keyfile -b 4096 -C "$description" -N "" echo echo "Public key is:" echo "-----------------------------------------------------" cat $keyfile.pub echo "-----------------------------------------------------" echo -n "Please make sure that key is set up at your git hosting and press enter.." read } function reuseSSHKey(){ # pastes ssh key to file $1 with vim local keyfile=$1 local scratch=$(mktemp) echo "# Please paste private ssh key here and save this file" > $scratch vim $scratch sed -e 's/#.*$//' $scratch > $keyfile rm $scratch echo "Checking key..." chmod 0600 $keyfile ssh-keygen -y -f $keyfile -P "" } function createVolume(){ # create volume $1 local volname=$1 echo "Creating docker volume $volname" docker volume create $volname > /dev/null echo "Populating volume with stuff..." local filler="cloner-creator-filler-$(hostname)" tar c /data | docker run -v $volname:/data -i --name $filler --rm busybox:latest tar -C / -x } # start reading vars echo -n "Enter project name: " read read_project_name checkProjectName "$read_project_name" # repository URL echo -n "Enter git repository URL: " read read_url [ -n "$read_url" ] || die "Empty url is not allowed!" # check interval echo -n "Enter check interval in minutes [5]: " read read_interval [ -n "$read_interval" ] || read_interval=5 [[ "$read_interval" =~ ^[0-9]+$ ]] || echo "Entered interval is not number. Try again.." # submodule use echo -n "Mirror including submodules? [Y/n]" read read_submodules [ -n "$read_submodules" ] || read_submodules=Y [[ "$read_submodules" =~ ^[Yy]$ ]] && read_submodules=1 || read_submodules=0 # submodule limit if [ $read_submodules -eq 1 ] then echo -n "Limit for submodule discovery [/N]: " read read_submodule_limit [ -n "$read_submodule_limit" ] || read_submodule_limit=N if ! [[ "$read_submodule_limit" =~ ^[Nn]$ ]] then [[ "$read_submodule_limit" =~ ^[0-9]+$ ]] || die "Submodule limit must be n,N or number!" fi else read_submodule_limit=N fi # start generating config mkdir -p /data/config createConfigFile /data/config/cloner.cfg # use ssh config? echo -n "Would you like to use SSH auth? ([C]reate new key/[U]se existing key/[N]o) [C/u/n]: " read read_ssh [ -n "$read_ssh" ] || read_ssh=C [[ "$read_ssh" =~ ^[CcUuNn]$ ]] || die "Invalid SSH key option, script is exiting now.." # ssh resolutions? # create dir if needed [[ "$read_ssh" =~ ^[nN]$ ]] || mkdir -p /data/config/auth/ssh # generate new key if [[ "$read_ssh" =~ ^[Cc]$ ]] then # create key generateSSHKey /data/config/auth/ssh "cloner-deploy-key-$read_project_name" fi # use existing key if [[ "$read_ssh" =~ ^[Uu]$ ]] then # load key reuseSSHKey /data/config/auth/ssh/id_rsa fi volume_name=$volume_prefix-$read_project_name createVolume $volume_name echo "First run - initialization of repos..." if ! docker run -it -v $volume_name:/data --name cloner-runner-$read_project_name --rm $mirror_image then echo -n "First run failed - remove image? [Y/n]" read read_cleanup [ -n "$read_cleanup" ] || read_cleanup=Y if [[ "$read_cleanup" =~ ^[Yy]$ ]] then docker volume rm $volume_name fi else echo "Setup has finished!" fi