#!/bin/sh # Echo help information usage() { cat < Tool for VCS repository administration. VCS support: $possible_vcs Options: -h, --help Print help message. Commands: add [repository2] ... Create new repository. del [repository2] ... Delete existing repository. fixmod [repository2] ... Fix access rights for repository. useradd [user2] ... Set access rights for user(s) to repository. userdel [user2] ... Remove access rights for user(s) to repository. EOF } group_add() { groupadd -K GID_MIN=${group_gid_min} "${group_r_prefix}$1" || return 1 groupadd -K GID_MIN=${group_gid_min} "${group_w_prefix}$1" || return 1 } group_del() { groupdel "${group_r_prefix}$1" || return 1 groupdel "${group_w_prefix}$1" || return 1 } create_repo_svn() { svnadmin --fs-type=fsfs create "$1" || return 1 } create_repo_git() { mkdir -p "$1" || return 1 git -C "$1" init --bare --shared >/dev/null || return 1 } data_add() { local r_name="$1" local r_root="$2" local r_link="$3" local repo_r="${r_root}/${r_name}" local repo_w="${r_root}/${r_name}/${r_name}" mkdir -p "${repo_r}" local saved_umask=`umask` umask 002 local create_vcs_func="create_repo_$opts_vcs" $create_vcs_func "$repo_w" || return 1 umask ${saved_umask} } data_fixmod() { local r_name="$1" local r_root="$2" local r_link="$3" local repo_r="${r_root}/${r_name}" local repo_w="${r_root}/${r_name}/${r_name}" chmod 750 "${repo_r}" || return 1 chgrp "${group_r_prefix}${r_name}" "${repo_r}" || return 1 chgrp -R "${group_w_prefix}${r_name}" "${repo_w}" || return 1 local dirs="" dirs=`find "$repo_w" -type d` local dir="" for dir in $dirs; do chmod g+s "$dir" || return 1 done chmod -R g+w "${repo_w}" || return 1 } data_del() { local r_name="$1" local r_root="$2" rm -Rf "$r_root/$r_name" } link_add() { local r_name="$1" local r_root="$2" local r_link="$3" ln -sf "$r_root/$r_name/$r_name" "$r_link/$r_name" } link_del() { local r_name="$1" local r_link="$2" rm -f "$r_link/$r_name" } repository_add() { local rep_name="" for rep_name in "$@"; do find_repo "$rep_name" test "x$repo_root" = "x" || { echo "Error: The repository \"$rep_name\" already exists." 1>&2; exit 1; } eval repo_root="\$repository_${opts_vcs}_root" eval repo_link="\$repository_${opts_vcs}_link" test "x$repo_root" = "x" && { echo "Error: Illegal repository root \"\"" 1>&2; exit 1; } test "x$repo_link" = "x" && { echo "Error: Illegal repository link \"\"" 1>&2; exit 1; } test -d "$repo_root" || { echo "Error: Illegal repository root \"$repo_root\"" 1>&2; exit 1; } test -d "$repo_link" || { echo "Error: Illegal repository link \"$repo_link\"" 1>&2; exit 1; } group_add "$rep_name" || { echo "Error: Can't add group for repository \"$rep_name\"" 1>&2; exit 1; } data_add "$rep_name" "$repo_root" "$repo_link" || { echo "Error: Can't add repository \"$rep_name\"" 1>&2; exit 1; } data_fixmod "$rep_name" "$repo_root" "$repo_link" || { echo "Error: Can't fix mode for repository \"$rep_name\"" 1>&2; exit 1; } link_add "$rep_name" "$repo_root" "$repo_link" || { echo "Error: Can't add link for repository \"$rep_name\"" 1>&2; exit 1; } echo "The repository \"$rep_name\" was succesfully created." done } repository_del() { local rep_name="" local sure="" for rep_name in "$@"; do find_repo "$rep_name" test "x$repo_root" = "x" -o "x$repo_link" = "x" && { echo "Error: Can't find repository \"$rep_name\"" 1>&2; exit 1; } if test "x$opts_force" = "x"; then read -r -p "Deleting repository \"$rep_name\". Are you sure (y/n)? " sure test "x$sure" = "xy" -o "x$sure" = "xY" || { echo "The repository \"$rep_name\" will be not deleted."; continue; } fi link_del "$rep_name" "$repo_link" || { echo "Error: Can't remove link for repository \"$rep_name\"" 1>&2; exit 1; } data_del "$rep_name" "$repo_root" || { echo "Error: Can't remove repository \"$rep_name\"" 1>&2; exit 1; } group_del "$rep_name" || { echo "Error: Can't remove group for repository \"$rep_name\"" 1>&2; exit 1; } echo "The repository \"$rep_name\" was succesfully deleted." done } repository_fixmod() { local rep_name="" for rep_name in "$@"; do find_repo "$rep_name" test "x$repo_root" = "x" -o "x$repo_link" = "x" && { echo "Error: Can't find repository \"$rep_name\"" 1>&2; exit 1; } data_fixmod "$rep_name" "$repo_root" "$repo_link" || { echo "Error: Can't fix repository's \"$rep_name\" mode" 1>&2; exit 1; } link_add "$rep_name" "$repo_root" "$repo_link" || { echo "Error: Can't create link for repository \"$rep_name\"" 1>&2; exit 1; } echo "The repository \"$rep_name\" was succesfully fixed." done } user_add() { local w=0 local r=0 local repository_name="$1" local user_name="" shift case "$1" in r) r=1 ;; w) w=1 ;; rw|wr) r=1 w=1 ;; *) echo "Error: Illegal parameter \"$1\"" 1>&2 exit 1 ;; esac shift for user_name in "$@"; do test $r -ne 0 && adduser "${user_name}" "${group_r_prefix}${repository_name}" test $w -ne 0 && adduser "${user_name}" "${group_w_prefix}${repository_name}" done } user_del() { local w=0 local r=0 local repository_name=$1 local user_name="" shift case "$1" in r) r=1 ;; w) w=1 ;; rw|wr) r=1 w=1 ;; *) echo "Error: Illegal parameter \"$1\"" 1>&2 exit 1 ;; esac shift for user_name in "$@"; do test $r -ne 0 && deluser "${user_name}" "${group_r_prefix}${repository_name}" test $w -ne 0 && deluser "${user_name}" "${group_w_prefix}${repository_name}" done } find_repo() { local r="" local r_root="" repo_root="" repo_link="" for r in $possible_vcs; do eval r_root="\$repository_${r}_root" test "x$r_root" = "x" && continue test -d "$r_root/$1" || continue repo_root="$r_root" eval repo_link="\$repository_${r}_link" break done return 0 } #------------------ MAIN ----------------------------------------- possible_vcs="svn git" # Defaults for rfa.conf group_gid_min="3000" group_w_prefix="vcs-w-" group_r_prefix="vcs-r-" repository_root= repository_link= # Parse command line options action="help" opts_force="" opts_conf="/etc/repoforge/rfa.conf" opts_vcs="svn" while test "x$1" != "x"; do option="$1" case "$option" in -h|--help) usage exit 0 ;; -f|--force) opts_force=1 ;; # Config file -c) shift opts_conf="$1" ;; --config=*) opts_conf=`echo "$option" | sed 's/--config=//'` ;; # Choose VCS -s) shift opts_vcs="$1" ;; --vcs=*) opts_vcs=`echo "$option" | sed 's/--vcs=//'` ;; --git) opts_vcs="git" ;; --svn) opts_vcs="svn" ;; # Default *) action="$option" shift break ;; esac shift done # Early help message test "x$action" = "xhelp" && { usage; exit 0; } # Check options bad_vcs=1 for v in $possible_vcs; do test "x$opts_vcs" = "x$v" && { bad_vcs=""; break; } done test "x$bad_vcs" = "x" || { echo "Error: Illegal VCS \"$opts_vcs\"" 1>&2; exit 1; } # Include config file test -r "$opts_conf" && . $opts_conf # Compatibility (suppose SVN) test "x$repository_svn_root" = "x" && repository_svn_root="$repository_root" test "x$repository_svn_link" = "x" && repository_svn_link="$repository_link" # Action case "$action" in "add") test $# -lt 1 && { echo "Error: Repository name is expected" 1>&2; exit 1; } repository_add "$@" ;; "fixmod") test $# -lt 1 && { echo "Error: Repository name is expected" 1>&2; exit 1; } repository_fixmod "$@" ;; "del") test $# -lt 1 && { echo "Error: Repository name is expected" 1>&2; exit 1; } repository_del "$@" ;; "adduser"|"useradd") test $# -lt 3 && { echo "Error: Not enough parameters" 1>&2; exit 1; } user_add "$@" ;; "deluser"|"userdel") test $# -lt 3 && { echo "Error: Not enough parameters" 1>&2; exit 1; } user_del "$@" ;; *) echo "Error: Unknown command" 1>&2 exit 1 ;; esac exit $?