#!/bin/bash SCRIPT=$(readlink -f "$0") INSTALLPATH=$(dirname "${SCRIPT}") TOPDIR=$(dirname "${INSTALLPATH}") default_ccnet_conf_dir=${TOPDIR}/ccnet default_seafile_data_dir=${TOPDIR}/seafile-data default_seahub_db=${TOPDIR}/seahub.db default_conf_dir=${TOPDIR}/conf default_pids_dir=${TOPDIR}/pids default_logs_dir=${TOPDIR}/logs export SEAFILE_LD_LIBRARY_PATH=${INSTALLPATH}/seafile/lib/:${INSTALLPATH}/seafile/lib64:${LD_LIBRARY_PATH} server_manual_http='https://download.seafile.com/published/seafile-manual/home.md' function welcome () { echo "-----------------------------------------------------------------" echo "This script will guide you to config and setup your seafile server." echo -e "\nMake sure you have read seafile server manual at \n\n\t${server_manual_http}\n" echo -e "Note: This script will guide your to setup seafile server using sqlite3," echo "which may have problems if your disk is on a NFS/CIFS/USB." echo "In these cases, we suggest you setup seafile server using MySQL." echo echo "Press [ENTER] to continue" echo "-----------------------------------------------------------------" read dummy echo } function err_and_quit () { printf "\n\n\033[33mError occured during setup. \nPlease fix possible issues and run the script again.\033[m\n\n" exit 1; } function on_ctrl_c_pressed () { printf "\n\n\033[33mYou have pressed Ctrl-C. Setup is interrupted.\033[m\n\n" exit 1; } # clean newly created ccnet/seafile configs when exit on SIGINT trap on_ctrl_c_pressed 2 function check_sanity () { if ! [[ -d ${INSTALLPATH}/seahub && -d ${INSTALLPATH}/seafile \ && -d ${INSTALLPATH}/runtime ]]; then echo echo "The seafile-server diretory doesn't contain all needed files." echo "Please make sure you have extracted all files and folders from tarball." err_and_quit; fi } function read_yes_no () { printf "[yes|no] " read yesno; while [[ "${yesno}" != "yes" && "${yesno}" != "no" ]] do printf "please answer [yes|no] " read yesno; done if [[ "${yesno}" == "no" ]]; then return 1; else return 0; fi } function check_existing_ccnet () { if [[ -d ${default_ccnet_conf_dir} ]]; then echo "\033[31m Error: \033[0m Ccnet config dir \"${default_ccnet_conf_dir}\" already exists." echo exit 1; fi echo } function check_existing_seafile () { if [[ -d ${default_seafile_data_dir} ]]; then echo "\033[31m Error: \033[0m Seafile server data dir \"${default_seafile_data_dir}\" already exists." echo exit 1; fi echo } function check_python_executable() { if [[ "$PYTHON" != "" && -x $PYTHON ]]; then return 0 fi if which python3 2>/dev/null 1>&2; then PYTHON=python3 elif !(python --version 2>&1 | grep "3\.[0-9]\.[0-9]") 2>/dev/null 1>&2; then echo echo "The current version of python is not 3.x.x, please use Python 3.x.x ." echo err_and_quit else PYTHON="python"$(python --version | cut -b 8-10) if !which $PYTHON 2>/dev/null 1>&2; then echo echo "Can't find a python executable of $PYTHON in PATH" echo "Install $PYTHON before continue." echo "Or if you installed it in a non-standard PATH, set the PYTHON enviroment varirable to it" echo err_and_quit fi fi echo "Find python: $PYTHON" echo } function check_python_module () { module=$1 name=$2 hint=$3 printf " Checking python module: ${name} ... " if ! $PYTHON -c "import ${module}" 2>/dev/null 1>&2; then echo printf "\033[33m ${name} \033[m is not installed, Please install it first.\n" if [[ "${hint}" != "" ]]; then printf "${hint}" echo fi err_and_quit; fi echo -e "Done." } function check_python () { echo "Checking python on this machine ..." check_python_executable check_python_module sqlite3 python-sqlite3 echo } function check_sqlite3 () { echo -n "Checking for sqlite3 ..." if ! which sqlite3 2>/dev/null 1>&2; then echo -e "\nSqlite3 is not found. install it first.\n" echo "On Debian/Ubuntu: apt-get install sqlite3" echo "On CentOS/RHEL: yum install sqlite" err_and_quit; fi printf "Done.\n\n" } function check_system_dependency () { printf "Checking packages needed by seafile ...\n\n" check_python; check_sqlite3; printf "Checking Done.\n\n" } function ask_question () { question=$1 default=$2 key=$3 printf "${question}" printf "\n" if [[ "${default}" != "" && "${default}" != "nodefault" ]] ; then printf "[default: ${default} ] " elif [[ "${key}" != "" ]]; then printf "[${key}]: " fi } function get_server_name () { question="What would you like to use as the name of this seafile server?\nYour seafile users will be able to see the name in their seafile client." hint="You can use a-z, A-Z, 0-9, _ and -, and the length should be 3 ~ 15" ask_question "${question}\n${hint}" "nodefault" "server name" read server_name if [[ "${server_name}" == "" ]]; then echo echo "server name cannot be empty" get_server_name elif [[ ! ${server_name} =~ ^[a-zA-Z0-9_-]{3,14}$ ]]; then printf "\n\033[33m${server_name}\033[m is not a valid name.\n" get_server_name; fi echo } function get_server_ip_or_domain () { question="What is the ip or domain of this server?\nFor example, www.mycompany.com, or, 192.168.1.101" ask_question "${question}\n" "nodefault" "This server's ip or domain" read ip_or_domain if [[ "${ip_or_domain}" == "" ]]; then echo echo "ip or domain cannot be empty" get_server_ip_or_domain fi echo } # function get_ccnet_server_port () { # question="What tcp port do you want to use for ccnet server?" # hint="10001 is the recommended port." # default="10001" # ask_question "${question}\n${hint}" "${default}" # read server_port # if [[ "${server_port}" == "" ]]; then # server_port="${default}" # fi # if [[ ! ${server_port} =~ ^[0-9]+$ ]]; then # echo "\"${server_port}\" is not a valid port number. " # get_ccnet_server_port # fi # echo # } # function get_seafile_server_port () { # question="What tcp port would you like to use for seafile server?" # hint="12001 is the recommended port." # default="12001" # ask_question "${question}\n${hint}" "${default}" # read seafile_server_port # if [[ "${seafile_server_port}" == "" ]]; then # seafile_server_port="${default}" # fi # if [[ ! ${seafile_server_port} =~ ^[0-9]+$ ]]; then # echo "\"${seafile_server_port}\" is not a valid port number. " # get_seafile_server_port # fi # echo # } function get_fileserver_port () { question="What tcp port do you want to use for seafile fileserver?" hint="8082 is the recommended port." default="8082" ask_question "${question}\n${hint}" "${default}" read fileserver_port if [[ "${fileserver_port}" == "" ]]; then fileserver_port="${default}" fi if [[ ! ${fileserver_port} =~ ^[0-9]+$ ]]; then echo "\"${fileserver_port}\" is not a valid port number. " get_fileserver_port fi echo } # function get_seafile_data_dir () { # question="Where would you like to store your seafile data?" # note="Please use a volume with enough free space." # default=${default_seafile_data_dir} # ask_question "${question} \n\033[33mNote: \033[m${note}" "${default}" # read seafile_data_dir # if [[ "${seafile_data_dir}" == "" ]]; then # seafile_data_dir=${default} # fi # # if [[ -d ${seafile_data_dir} && -f ${seafile_data_dir}/seafile.conf ]]; then # echo # echo "It seems that you have already existing seafile data in ${seafile_data_dir}." # echo "Would you like to use the existing seafile data?" # if ! read_yes_no; then # echo "You have chosen not to use existing seafile data in ${seafile_data_dir}" # echo "You need to specify a different seafile data directory or remove ${seafile_data_dir} before continuing." # get_seafile_data_dir # else # use_existing_seafile="true" # fi # elif [[ -d ${seafile_data_dir} && $(ls -A ${seafile_data_dir}) != "" ]]; then # echo # echo "${seafile_data_dir} is an existing non-empty directory. Please specify a different directory" # echo # get_seafile_data_dir # elif [[ ! ${seafile_data_dir} =~ ^/ ]]; then # echo # echo "\"${seafile_data_dir}\" is not an absolute path. Please specify an absolute path." # echo # get_seafile_data_dir # elif [[ ! -d $(dirname ${seafile_data_dir}) ]]; then # echo # echo "The path $(dirname ${seafile_data_dir}) does not exist." # echo # get_seafile_data_dir # fi # echo # } function gen_gunicorn_conf () { mkdir -p ${default_conf_dir} gunicorn_conf=${default_conf_dir}/gunicorn.conf.py if ! $(cat > ${gunicorn_conf} < ${seafdav_conf} < "${default_ccnet_conf_dir}/seafile.ini" # ------------------------------------------- # Generate gunicorn.conf.py # ------------------------------------------- gen_gunicorn_conf; # ------------------------------------------- # Generate seafevents.conf # ------------------------------------------- gen_seafdav_conf; # ------------------------------------------- # generate seahub/settings.py # ------------------------------------------- dest_settings_py=${TOPDIR}/conf/seahub_settings.py seahub_secret_keygen=${INSTALLPATH}/seahub/tools/secret_key_generator.py if [[ ! -f ${dest_settings_py} ]]; then key=$($PYTHON "${seahub_secret_keygen}") cat > ${dest_settings_py} </dev/null 1>&2; then echo "Failed to sync ccnet groupmgr database." err_and_quit; fi ccnet_config_db=${TOPDIR}/ccnet/misc/config.db ccnet_config_sql=${INSTALLPATH}/sql/sqlite/config.sql if ! sqlite3 ${ccnet_config_db} ".read ${ccnet_config_sql}" 2>/dev/null 1>&2; then echo "Failed to sync ccnet config database." err_and_quit; fi ccnet_org_db=${TOPDIR}/ccnet/OrgMgr/orgmgr.db ccnet_org_sql=${INSTALLPATH}/sql/sqlite/org.sql if ! sqlite3 ${ccnet_org_db} ".read ${ccnet_org_sql}" 2>/dev/null 1>&2; then echo "Failed to sync ccnet org database." err_and_quit; fi ccnet_user_db=${TOPDIR}/ccnet/PeerMgr/usermgr.db ccnet_user_sql=${INSTALLPATH}/sql/sqlite/user.sql if ! sqlite3 ${ccnet_user_db} ".read ${ccnet_user_sql}" 2>/dev/null 1>&2; then echo "Failed to sync ccnet user database." err_and_quit; fi seafile_db=${TOPDIR}/seafile-data/seafile.db seafile_sql=${INSTALLPATH}/sql/sqlite/seafile.sql if ! sqlite3 ${seafile_db} ".read ${seafile_sql}" 2>/dev/null 1>&2; then echo "Failed to sync seafile database." err_and_quit; fi seahub_db=${TOPDIR}/seahub.db seahub_sqls=${INSTALLPATH}/seahub/sql/sqlite3.sql if ! sqlite3 ${seahub_db} ".read ${seahub_sqls}" 2>/dev/null 1>&2; then echo "Failed to sync seahub database." err_and_quit; fi echo echo "Done." # prepare avatar folder media_dir=${INSTALLPATH}/seahub/media orig_avatar_dir=${INSTALLPATH}/seahub/media/avatars dest_avatar_dir=${TOPDIR}/seahub-data/avatars if [[ ! -d ${dest_avatar_dir} ]]; then mkdir -p "${TOPDIR}/seahub-data" mv "${orig_avatar_dir}" "${dest_avatar_dir}" ln -s ../../../seahub-data/avatars ${media_dir} fi # Make a seafile-server symlink, like this: # /data/haiwen/ # -- seafile-server-2.0.4 # -- seafile-server-latest # symlink to 2.0.4 seafile_server_symlink=${TOPDIR}/seafile-server-latest echo echo -n "creating seafile-server-latest symbolic link ... " if ! ln -s $(basename ${INSTALLPATH}) ${seafile_server_symlink}; then echo echo echo "Failed to create symbolic link ${seafile_server_symlink}" err_and_quit; fi echo "done" echo chmod 0600 "$dest_settings_py" chmod 0700 "$default_ccnet_conf_dir" chmod 0700 "$default_seafile_data_dir" chmod 0700 "$default_conf_dir" # ------------------------------------------- # copy user manuals to library template # ------------------------------------------- copy_user_manuals; # ------------------------------------------- # final message # ------------------------------------------- sleep 1 echo echo "-----------------------------------------------------------------" echo "Your seafile server configuration has been completed successfully." echo "-----------------------------------------------------------------" echo echo "run seafile server: ./seafile.sh { start | stop | restart }" echo "run seahub server: ./seahub.sh { start | stop | restart }" echo echo "-----------------------------------------------------------------" echo "If the server is behind a firewall, remember to open these tcp ports:" echo "-----------------------------------------------------------------" echo echo "port of seafile fileserver: ${fileserver_port}" echo "port of seahub: 8000" echo echo -e "When problems occur, refer to\n" echo -e " ${server_manual_http}\n" echo "for more information." echo