· 8 years ago · Sep 29, 2017, 07:58 AM
1#!/bin/bash
2
3SCRIPT=$(readlink -f "$0")
4INSTALLPATH=$(dirname "${SCRIPT}")
5TOPDIR=$(dirname "${INSTALLPATH}")
6default_ccnet_conf_dir=${TOPDIR}/ccnet
7default_seafile_data_dir=${TOPDIR}/seafile-data
8default_seahub_db=${TOPDIR}/seahub.db
9default_conf_dir=${TOPDIR}/conf
10
11export SEAFILE_LD_LIBRARY_PATH=${INSTALLPATH}/seafile/lib/:${INSTALLPATH}/seafile/lib64:${LD_LIBRARY_PATH}
12
13use_existing_ccnet="false"
14use_existing_seafile="false"
15
16server_manual_http="https://github.com/haiwen/seafile/wiki"
17
18function welcome () {
19 echo "-----------------------------------------------------------------"
20 echo "This script will guide you to config and setup your seafile server."
21 echo -e "\nMake sure you have read seafile server manual at \n\n\t${server_manual_http}\n"
22 echo -e "Note: This script will guide your to setup seafile server using sqlite3,"
23 echo "which may have problems if your disk is on a NFS/CIFS/USB."
24 echo "In these cases, we sugguest you setup seafile server using MySQL."
25 echo
26 echo "Press [ENTER] to continue"
27 echo "-----------------------------------------------------------------"
28 read dummy
29 echo
30}
31
32function err_and_quit () {
33 printf "\n\n\033[33mError occured during setup. \nPlease fix possible issues and run the script again.\033[m\n\n"
34 exit 1;
35}
36
37function on_ctrl_c_pressed () {
38 printf "\n\n\033[33mYou have pressed Ctrl-C. Setup is interrupted.\033[m\n\n"
39 exit 1;
40}
41
42# clean newly created ccnet/seafile configs when exit on SIGINT
43trap on_ctrl_c_pressed 2
44
45function check_sanity () {
46 if ! [[ -d ${INSTALLPATH}/seahub && -d ${INSTALLPATH}/seafile \
47 && -d ${INSTALLPATH}/runtime ]]; then
48 echo
49 echo "The seafile-server diretory doesn't contain all needed files."
50 echo "Please make sure you have extracted all files and folders from tarball."
51 err_and_quit;
52 fi
53}
54
55function read_yes_no () {
56 printf "[yes|no] "
57 read yesno;
58 while [[ "${yesno}" != "yes" && "${yesno}" != "no" ]]
59 do
60 printf "please answer [yes|no] "
61 read yesno;
62 done
63
64 if [[ "${yesno}" == "no" ]]; then
65 return 1;
66 else
67 return 0;
68 fi
69}
70
71function check_existing_ccnet () {
72 if [[ -d ${default_ccnet_conf_dir} ]]; then
73 echo "It seems that you have created a ccnet configuration before. "
74 echo "Would you like to use the existing configuration?"
75
76 if ! read_yes_no; then
77 echo
78 echo "Please remove the existing configuration before continuing."
79 echo "You can do it by running \"rm -rf ${default_ccnet_conf_dir}\""
80 echo
81 exit 1;
82 else
83 echo
84 echo "Existing ccnet configuration is being used."
85 use_existing_ccnet=true
86 fi
87 fi
88 echo
89}
90
91function check_python_executable() {
92 if [[ "$PYTHON" != "" && -x $PYTHON ]]; then
93 return 0
94 fi
95
96 if which python2.7 2>/dev/null 1>&2; then
97 PYTHON=python2.7
98 elif which python27 2>/dev/null 1>&2; then
99 PYTHON=python27
100 else
101 echo
102 echo "Can't find a python executable of version 2.7 or above in PATH"
103 echo "Install python 2.7+ before continue."
104 echo "Or if you installed it in a non-standard PATH, set the PYTHON enviroment varirable to it"
105 echo
106 exit 1
107 fi
108
109 echo "Find python: $PYTHON"
110 echo
111}
112
113function check_python_module () {
114 module=$1
115 name=$2
116 hint=$3
117 printf " Checking python module: ${name} ... "
118 if ! $PYTHON -c "import ${module}" 2>/dev/null 1>&2; then
119 echo
120 printf "\033[33m ${name} \033[m is not installed, Please install it first.\n"
121 if [[ "${hint}" != "" ]]; then
122 printf "${hint}"
123 echo
124 fi
125 err_and_quit;
126 fi
127 echo -e "Done."
128}
129
130function check_python () {
131 echo "Checking python on this machine ..."
132 check_python_executable
133 if ! which $PYTHON 2>/dev/null 1>&2; then
134 echo "No $PYTHON found on this machine. Please install it first."
135 err_and_quit;
136 else
137 if ($Python --version 2>&1 | grep "3\\.[0-9].\\.[0-9]") 2>/dev/null 1>&2 ; then
138 printf "\033[33m Python version 3.x \033[m detected\n"
139 echo "Python 3.x is not supported. Please use python 2.x."
140 err_and_quit;
141 fi
142
143 if [[ $PYTHON == "python2.6" ]]; then
144 py26="2.6"
145 fi
146 hint="\nOn Debian/Ubntu: apt-get install python-setuptools\nOn CentOS/RHEL: yum install python${py26}-distribute"
147 check_python_module pkg_resources setuptools "${hint}"
148 hint="\nOn Debian/Ubntu: apt-get install python-imaging\nOn CentOS/RHEL: yum install python${py26}-imaging"
149 check_python_module PIL python-imaging "${hint}"
150 check_python_module sqlite3 python-sqlite3
151 fi
152 echo
153}
154
155function check_sqlite3 () {
156 echo -n "Checking for sqlite3 ..."
157 if ! which sqlite3 2>/dev/null 1>&2; then
158 echo -e "\nSqlite3 is not found. install it first.\n"
159 echo "On Debian/Ubuntu: apt-get install sqlite3"
160 echo "On CentOS/RHEL: yum install sqlite"
161 err_and_quit;
162 fi
163 printf "Done.\n\n"
164}
165
166function check_system_dependency () {
167 printf "Checking packages needed by seafile ...\n\n"
168 check_python;
169 check_sqlite3;
170 printf "Checking Done.\n\n"
171}
172
173function ask_question () {
174 question=$1
175 default=$2
176 key=$3
177 printf "${question}"
178 printf "\n"
179 if [[ "${default}" != "" && "${default}" != "nodefault" ]] ; then
180 printf "[default: ${default} ] "
181 elif [[ "${key}" != "" ]]; then
182 printf "[${key}]: "
183 fi
184}
185
186function get_server_name () {
187 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."
188 hint="You can use a-z, A-Z, 0-9, _ and -, and the length should be 3 ~ 15"
189 ask_question "${question}\n${hint}" "nodefault" "server name"
190 read server_name
191 if [[ "${server_name}" == "" ]]; then
192 echo
193 echo "server name cannot be empty"
194 get_server_name
195 elif [[ ! ${server_name} =~ ^[a-zA-Z0-9_-]{3,14}$ ]]; then
196 printf "\n\033[33m${server_name}\033[m is not a valid name.\n"
197 get_server_name;
198 fi
199 echo
200}
201
202function get_server_ip_or_domain () {
203 question="What is the ip or domain of this server?\nFor example, www.mycompany.com, or, 192.168.1.101"
204 ask_question "${question}\n" "nodefault" "This server's ip or domain"
205 read ip_or_domain
206 if [[ "${ip_or_domain}" == "" ]]; then
207 echo
208 echo "ip or domain cannot be empty"
209 get_server_ip_or_domain
210 fi
211 echo
212}
213
214function get_ccnet_server_port () {
215 question="What tcp port do you want to use for ccnet server?"
216 hint="10001 is the recommended port."
217 default="10001"
218 ask_question "${question}\n${hint}" "${default}"
219 read server_port
220 if [[ "${server_port}" == "" ]]; then
221 server_port="${default}"
222 fi
223 if [[ ! ${server_port} =~ ^[0-9]+$ ]]; then
224 echo "\"${server_port}\" is not a valid port number. "
225 get_ccnet_server_port
226 fi
227 echo
228}
229
230function get_seafile_server_port () {
231 question="What tcp port would you like to use for seafile server?"
232 hint="12001 is the recommended port."
233 default="12001"
234 ask_question "${question}\n${hint}" "${default}"
235 read seafile_server_port
236 if [[ "${seafile_server_port}" == "" ]]; then
237 seafile_server_port="${default}"
238 fi
239 if [[ ! ${seafile_server_port} =~ ^[0-9]+$ ]]; then
240 echo "\"${seafile_server_port}\" is not a valid port number. "
241 get_seafile_server_port
242 fi
243 echo
244}
245
246function get_fileserver_port () {
247 question="What tcp port do you want to use for seafile fileserver?"
248 hint="8082 is the recommended port."
249 default="8082"
250 ask_question "${question}\n${hint}" "${default}"
251 read fileserver_port
252 if [[ "${fileserver_port}" == "" ]]; then
253 fileserver_port="${default}"
254 fi
255 if [[ ! ${fileserver_port} =~ ^[0-9]+$ ]]; then
256 echo "\"${fileserver_port}\" is not a valid port number. "
257 get_fileserver_port
258 fi
259 echo
260}
261
262
263function get_seafile_data_dir () {
264 question="Where would you like to store your seafile data?"
265 note="Please use a volume with enough free space."
266 default=${default_seafile_data_dir}
267 ask_question "${question} \n\033[33mNote: \033[m${note}" "${default}"
268 read seafile_data_dir
269 if [[ "${seafile_data_dir}" == "" ]]; then
270 seafile_data_dir=${default}
271 fi
272
273 if [[ -d ${seafile_data_dir} && -f ${seafile_data_dir}/seafile.conf ]]; then
274 echo
275 echo "It seems that you have already existing seafile data in ${seafile_data_dir}."
276 echo "Would you like to use the existing seafile data?"
277 if ! read_yes_no; then
278 echo "You have chosen not to use existing seafile data in ${seafile_data_dir}"
279 echo "You need to specify a different seafile data directory or remove ${seafile_data_dir} before continuing."
280 get_seafile_data_dir
281 else
282 use_existing_seafile="true"
283 fi
284 elif [[ -d ${seafile_data_dir} && $(ls -A ${seafile_data_dir}) != "" ]]; then
285 echo
286 echo "${seafile_data_dir} is an existing non-empty directory. Please specify a different directory"
287 echo
288 get_seafile_data_dir
289 elif [[ ! ${seafile_data_dir} =~ ^/ ]]; then
290 echo
291 echo "\"${seafile_data_dir}\" is not an absolute path. Please specify an absolute path."
292 echo
293 get_seafile_data_dir
294 elif [[ ! -d $(dirname ${seafile_data_dir}) ]]; then
295 echo
296 echo "The path $(dirname ${seafile_data_dir}) does not exist."
297 echo
298 get_seafile_data_dir
299 fi
300 echo
301}
302
303function gen_seafdav_conf () {
304 mkdir -p ${default_conf_dir}
305 seafdav_conf=${default_conf_dir}/seafdav.conf
306 if ! $(cat > ${seafdav_conf} <<EOF
307[WEBDAV]
308enabled = false
309port = 8080
310fastcgi = false
311host = 0.0.0.0
312share_name = /
313EOF
314); then
315 echo "failed to generate seafdav.conf";
316 err_and_quit
317fi
318}
319
320function copy_user_manuals() {
321 src_docs_dir=${INSTALLPATH}/seafile/docs/
322 library_template_dir=${seafile_data_dir}/library-template
323 mkdir -p ${library_template_dir}
324 cp -f ${src_docs_dir}/*.doc ${library_template_dir}
325}
326
327function parse_params() {
328 while getopts n:i:p:d arg; do
329 case $arg in
330 n)
331 server_name=${OPTARG}
332 ;;
333 i)
334 ip_or_domain=${OPTARG}
335 ;;
336 p)
337 fileserver_port=${OPTARG}
338 ;;
339 d)
340 seafile_data_dir=${OPTARG}
341 ;;
342 esac
343 done
344}
345
346function validate_params() {
347 # server_name default hostname -s
348 if [[ "$server_name" == "" ]]; then
349 server_name=${SERVER_NAME:-`hostname -s`}
350 fi
351 if [[ ! ${server_name} =~ ^[a-zA-Z0-9_-]{3,14}$ ]]; then
352 echo "Invalid server name param"
353 err_and_quit;
354 fi
355
356 # ip_or_domain default hostname -i
357 if [[ "$ip_or_domain" == "" ]]; then
358 ip_or_domain=${SERVER_IP:-`hostname -i`}
359 fi
360 if [[ "$ip_or_domain" != "" && ! ${ip_or_domain} =~ ^[^.].+\..+[^.]$ ]]; then
361 echo "Invalid ip or domain param"
362 err_and_quit;
363 fi
364
365 # fileserver_port default 8082
366 if [[ "${fileserver_port}" == "" ]]; then
367 fileserver_port=${FILESERVER_PORT:-8082}
368 fi
369 if [[ ! ${fileserver_port} =~ ^[0-9]+$ ]]; then
370 echo "Invalid fileserver port param"
371 err_and_quit;
372 fi
373
374 if [[ "${seafile_data_dir}" == "" ]]; then
375 seafile_data_dir=${SEAFILE_DIR:-${default_seafile_data_dir}}
376 fi
377 if [[ -d ${seafile_data_dir} && $(ls -A ${seafile_data_dir}) != "" ]]; then
378 echo "${seafile_data_dir} is an existing non-empty directory. Please specify a different directory"
379 err_and_quit
380 elif [[ ! ${seafile_data_dir} =~ ^/ ]]; then
381 echo "\"${seafile_data_dir}\" is not an absolute path. Please specify an absolute path."
382 err_and_quit
383 elif [[ ! -d $(dirname ${seafile_data_dir}) ]]; then
384 echo "The path $(dirname ${seafile_data_dir}) does not exist."
385 err_and_quit
386 fi
387}
388
389function usage() {
390 echo "auto mode:"
391 echo -e "$0 auto\n" \
392 "-n server name\n" \
393 "-i ip or domain\n" \
394 "-p fileserver port\n" \
395 "-d seafile dir to store seafile data"
396 echo ""
397 echo "interactive mode:"
398 echo "$0"
399}
400
401# -------------------------------------------
402# Main workflow of this script
403# -------------------------------------------
404
405for param in $@; do
406 if [[ "$param" == "-h" || "$param" == "--help" ]]; then
407 usage;
408 exit 0
409 fi
410done
411
412need_pause=1
413if [[ $# -ge 1 && "$1" == "auto" ]]; then
414 # auto mode, no pause
415 shift
416 parse_params $@;
417 validate_params;
418 need_pause=0
419fi
420
421check_sanity;
422if [[ "${need_pause}" == "1" ]]; then
423 welcome;
424fi
425sleep .5
426check_system_dependency;
427sleep .5
428
429check_existing_ccnet;
430if [[ ${use_existing_ccnet} != "true" ]]; then
431 if [[ "${server_name}" == "" ]]; then
432 get_server_name;
433 fi
434 if [[ "${ip_or_domain}" == "" ]]; then
435 get_server_ip_or_domain;
436 fi
437 # get_ccnet_server_port;
438fi
439
440if [[ "$seafile_data_dir" == "" ]]; then
441 get_seafile_data_dir;
442fi
443if [[ ${use_existing_seafile} != "true" ]]; then
444 # get_seafile_server_port
445 if [[ "$fileserver_port" == "" ]]; then
446 get_fileserver_port
447 fi
448fi
449
450sleep .5
451
452printf "\nThis is your config information:\n\n"
453
454if [[ ${use_existing_ccnet} != "true" ]]; then
455 printf "server name: \033[33m${server_name}\033[m\n"
456 printf "server ip/domain: \033[33m${ip_or_domain}\033[m\n"
457else
458 printf "ccnet config: use existing config in \033[33m${default_ccnet_conf_dir}\033[m\n"
459fi
460
461if [[ ${use_existing_seafile} != "true" ]]; then
462 printf "seafile data dir: \033[33m${seafile_data_dir}\033[m\n"
463 printf "fileserver port: \033[33m${fileserver_port}\033[m\n"
464else
465 printf "seafile data dir: use existing data in \033[33m${seafile_data_dir}\033[m\n"
466fi
467
468if [[ "${need_pause}" == "1" ]]; then
469 echo
470 echo "If you are OK with the configuration, press [ENTER] to continue."
471 read dummy
472fi
473
474ccnet_init=${INSTALLPATH}/seafile/bin/ccnet-init
475seaf_server_init=${INSTALLPATH}/seafile/bin/seaf-server-init
476
477# -------------------------------------------
478# Create ccnet conf
479# -------------------------------------------
480if [[ "${use_existing_ccnet}" != "true" ]]; then
481 echo "Generating ccnet configuration in ${default_ccnet_conf_dir}..."
482 echo
483 if ! LD_LIBRARY_PATH=$SEAFILE_LD_LIBRARY_PATH "${ccnet_init}" \
484 -F "${default_conf_dir}" \
485 -c "${default_ccnet_conf_dir}" \
486 --name "${server_name}" \
487 --host "${ip_or_domain}"; then
488 err_and_quit;
489 fi
490
491 echo
492fi
493
494sleep 0.5
495
496# -------------------------------------------
497# Create seafile conf
498# -------------------------------------------
499if [[ "${use_existing_seafile}" != "true" ]]; then
500 echo "Generating seafile configuration in ${seafile_data_dir} ..."
501 echo
502 if ! LD_LIBRARY_PATH=$SEAFILE_LD_LIBRARY_PATH ${seaf_server_init} \
503 --central-config-dir "${default_conf_dir}" \
504 --seafile-dir "${seafile_data_dir}" \
505 --fileserver-port ${fileserver_port}; then
506
507 echo "Failed to generate seafile configuration"
508 err_and_quit;
509 fi
510
511 echo
512fi
513
514# -------------------------------------------
515# Write seafile.ini
516# -------------------------------------------
517
518echo "${seafile_data_dir}" > "${default_ccnet_conf_dir}/seafile.ini"
519
520# -------------------------------------------
521# Generate seafevents.conf
522# -------------------------------------------
523
524gen_seafdav_conf;
525
526# -------------------------------------------
527# generate seahub/settings.py
528# -------------------------------------------
529dest_settings_py=${TOPDIR}/conf/seahub_settings.py
530seahub_secret_keygen=${INSTALLPATH}/seahub/tools/secret_key_generator.py
531
532if [[ ! -f ${dest_settings_py} ]]; then
533 key=$($PYTHON "${seahub_secret_keygen}")
534 cat > ${dest_settings_py} <<EOF
535# -*- coding: utf-8 -*-
536SECRET_KEY = "$key"
537EOF
538fi
539
540# -------------------------------------------
541# Seahub related config
542# -------------------------------------------
543if [[ "${need_pause}" == "1" ]]; then
544 echo "-----------------------------------------------------------------"
545 echo "Seahub is the web interface for seafile server."
546 echo "Now let's setup seahub configuration. Press [ENTER] to continue"
547 echo "-----------------------------------------------------------------"
548 echo
549 read dummy
550fi
551
552# echo "Please specify the email address and password for the seahub administrator."
553# echo "You can use them to login as admin on your seahub website."
554# echo
555
556function get_seahub_admin_email () {
557 question="Please specify the email address for the seahub administrator:"
558 ask_question "${question}" "nodefault" "seahub admin email"
559 read seahub_admin_email
560 if [[ "${seahub_admin_email}" == "" ]]; then
561 echo "Seahub admin user name cannot be empty."
562 get_seahub_admin_email;
563 elif [[ ! ${seahub_admin_email} =~ ^.+@.*\..+$ ]]; then
564 echo "${seahub_admin_email} is not a valid email address"
565 get_seahub_admin_email;
566 fi
567}
568
569function get_seahub_admin_passwd () {
570 echo
571 question="Please specify the password you would like to use for seahub administrator:"
572 ask_question "${question}" "nodefault" "seahub admin password"
573 read -s seahub_admin_passwd
574 echo
575 question="Please enter the password again:"
576 ask_question "${question}" "nodefault" "seahub admin password again"
577 read -s seahub_admin_passwd_again
578 echo
579 if [[ "${seahub_admin_passwd}" != "${seahub_admin_passwd_again}" ]]; then
580 printf "\033[33mThe passwords didn't match.\033[m"
581 get_seahub_admin_passwd;
582 elif [[ "${seahub_admin_passwd}" == "" ]]; then
583 echo "Password cannot be empty."
584 get_seahub_admin_passwd;
585 fi
586}
587
588# get_seahub_admin_email;
589# sleep .5;
590# get_seahub_admin_passwd;
591# seahub_admin_passwd_enc=$(echo -n ${seahub_admin_passwd} | sha1sum | grep -o "[0-9a-f]*")
592# sleep .5;
593
594# printf "\n\n"
595# echo "This is your seahub admin username/password"
596# echo
597# printf "admin username: \033[33m${seahub_admin_email}\033[m\n"
598# printf "admin password: \033[33m**************\033[m\n\n"
599
600# echo
601# echo "If you are OK with the configuration, press [ENTER] to continue."
602# read dummy
603
604# usermgr_db_dir=${default_ccnet_conf_dir}/PeerMgr/
605# usermgr_db=${usermgr_db_dir}/usermgr.db
606
607# if [[ "${use_existing_ccnet}" != "true" ]]; then
608# # create admin user/passwd entry in ccnet db
609# if ! mkdir -p "${usermgr_db_dir}"; then
610# echo "Failed to create seahub admin."
611# err_and_quit;
612# fi
613
614# sql="CREATE TABLE IF NOT EXISTS EmailUser (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, email TEXT, passwd TEXT, is_staff bool NOT NULL, is_active bool NOT NULL, ctime INTEGER)";
615
616# if ! sqlite3 "${usermgr_db}" "${sql}" ; then
617# rm -f "${usermgr_db}"
618# echo "Failed to create seahub admin."
619# err_and_quit;
620# fi
621
622# sql="INSERT INTO EmailUser(email, passwd, is_staff, is_active, ctime) VALUES (\"${seahub_admin_email}\", \"${seahub_admin_passwd_enc}\", 1, 1, 0);"
623
624# if ! sqlite3 "${usermgr_db}" "${sql}" ; then
625# rm -f "${usermgr_db}"
626# echo "Failed to create seahub admin."
627# err_and_quit;
628# fi
629# fi
630
631echo "Creating seahub database now, it may take one minute, please wait... "
632echo
633
634seahub_db=${TOPDIR}/seahub.db
635seahub_sqls=${INSTALLPATH}/seahub/sql/sqlite3.sql
636
637if ! sqlite3 ${seahub_db} ".read ${seahub_sqls}" 2>/dev/null 1>&2; then
638 echo "Failed to sync seahub database."
639 err_and_quit;
640fi
641echo
642echo "Done."
643
644# prepare avatar folder
645
646media_dir=${INSTALLPATH}/seahub/media
647orig_avatar_dir=${INSTALLPATH}/seahub/media/avatars
648dest_avatar_dir=${TOPDIR}/seahub-data/avatars
649
650if [[ ! -d ${dest_avatar_dir} ]]; then
651 mkdir -p "${TOPDIR}/seahub-data"
652 mv "${orig_avatar_dir}" "${dest_avatar_dir}"
653 ln -s ../../../seahub-data/avatars ${media_dir}
654fi
655
656# Make a seafile-server symlink, like this:
657# /data/haiwen/
658# -- seafile-server-2.0.4
659# -- seafile-server-latest # symlink to 2.0.4
660seafile_server_symlink=${TOPDIR}/seafile-server-latest
661echo
662echo -n "creating seafile-server-latest symbolic link ... "
663if ! ln -s $(basename ${INSTALLPATH}) ${seafile_server_symlink}; then
664 echo
665 echo
666 echo "Failed to create symbolic link ${seafile_server_symlink}"
667 err_and_quit;
668fi
669echo "done"
670echo
671
672chmod 0600 "$dest_settings_py"
673chmod 0700 "$default_ccnet_conf_dir"
674chmod 0700 "$seafile_data_dir"
675chmod 0700 "$default_conf_dir"
676
677# -------------------------------------------
678# copy user manuals to library template
679# -------------------------------------------
680copy_user_manuals;
681
682# -------------------------------------------
683# final message
684# -------------------------------------------
685
686sleep 1
687
688echo
689echo "-----------------------------------------------------------------"
690echo "Your seafile server configuration has been completed successfully."
691echo "-----------------------------------------------------------------"
692echo
693echo "run seafile server: ./seafile.sh { start | stop | restart }"
694echo "run seahub server: ./seahub.sh { start <port> | stop | restart <port> }"
695echo
696echo "-----------------------------------------------------------------"
697echo "If the server is behind a firewall, remember to open these tcp ports:"
698echo "-----------------------------------------------------------------"
699echo
700echo "port of seafile fileserver: ${fileserver_port}"
701echo "port of seahub: 8000"
702echo
703echo -e "When problems occur, refer to\n"
704echo -e " ${server_manual_http}\n"
705echo "for more information."
706echo