freedombone-app-turtl 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. #!/bin/bash
  2. # _____ _ _
  3. # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
  4. # | __| _| -_| -_| . | . | | . | . | | -_|
  5. # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
  6. #
  7. # Freedom in the Cloud
  8. #
  9. # turtl app
  10. #
  11. # http://portallinux.es/instalacion-servidor-turtl-debian-8
  12. # http://framacloud.org/cultiver-son-jardin/installation-de-turtl/
  13. #
  14. # License
  15. # =======
  16. #
  17. # Copyright (C) 2016-2018 Bob Mottram <bob@freedombone.net>
  18. #
  19. # This program is free software: you can redistribute it and/or modify
  20. # it under the terms of the GNU Affero General Public License as published by
  21. # the Free Software Foundation, either version 3 of the License, or
  22. # (at your option) any later version.
  23. #
  24. # This program is distributed in the hope that it will be useful,
  25. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. # GNU Affero General Public License for more details.
  28. #
  29. # You should have received a copy of the GNU Affero General Public License
  30. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  31. VARIANTS="full full-vim writer"
  32. IN_DEFAULT_INSTALL=0
  33. SHOW_ON_ABOUT=1
  34. TURTL_DOMAIN_NAME=
  35. TURTL_CODE=
  36. TURTL_ONION_PORT=8107
  37. TURTL_PORT=8181
  38. TURTL_REPO="https://github.com/turtl/api.git"
  39. TURTL_COMMIT='53e00a5583f52de8f86ef380fe11c176b5738dcf'
  40. TURTL_ADMIN_PASSWORD=
  41. TURTL_STORAGE_LIMIT_MB=100
  42. TURTL_BASE_DIR=/etc/turtl
  43. # part of a hack to enable/disable signups
  44. TURTL_SIGNUP_STRING='Signup a new user'
  45. turtl_users_file=$TURTL_BASE_DIR/api/controllers/users.lisp
  46. TURTL_SHORT_DESCRIPTION=$'Turtl'
  47. TURTL_DESCRIPTION=$'Turtl notes'
  48. TURTL_MOBILE_APP_URL=
  49. turtl_variables=(ONION_ONLY
  50. DEFAULT_DOMAIN_NAME
  51. TURTL_DOMAIN_NAME
  52. TURTL_CODE
  53. TURTL_STORAGE_LIMIT_MB
  54. DDNS_PROVIDER
  55. MY_EMAIL_ADDRESS
  56. MY_USERNAME)
  57. function logging_on_turtl {
  58. echo -n ''
  59. }
  60. function logging_off_turtl {
  61. echo -n ''
  62. }
  63. function change_password_turtl {
  64. echo -n ''
  65. # change_username="$1"
  66. # new_user_password="$2"
  67. }
  68. function remove_user_turtl {
  69. echo -n ''
  70. # remove_username="$1"
  71. }
  72. function add_user_turtl {
  73. # new_username="$1"
  74. # new_user_password="$2"
  75. echo '0'
  76. }
  77. function install_interactive_turtl {
  78. if [ ! "$ONION_ONLY" ]; then
  79. ONION_ONLY='no'
  80. fi
  81. if [[ $ONION_ONLY != "no" ]]; then
  82. TURTL_DOMAIN_NAME='notes.local'
  83. write_config_param "TURTL_DOMAIN_NAME" "$TURTL_DOMAIN_NAME"
  84. else
  85. function_check interactive_site_details
  86. interactive_site_details "turtl" "TURTL_DOMAIN_NAME" "TURTL_CODE"
  87. fi
  88. APP_INSTALLED=1
  89. }
  90. function turtl_disable_registrations {
  91. if grep -q "$TURTL_SIGNUP_STRING" $turtl_users_file; then
  92. if [ -f $turtl_users_file ]; then
  93. cp $turtl_users_file $TURTL_BASE_DIR/.users.lisp
  94. sed -i '/(route (:post "\/users") (req res)/,/(send-json res user))))/{//!d}' $turtl_users_file
  95. sed -i 's|(send-json res user))))|())|g' $turtl_users_file
  96. chown -R turtl:turtl $TURTL_BASE_DIR
  97. systemctl restart turtl
  98. fi
  99. fi
  100. }
  101. function turtl_enable_registrations {
  102. if ! grep -q "$TURTL_SIGNUP_STRING" $turtl_users_file; then
  103. if [ -f $TURTL_BASE_DIR/.users.lisp ]; then
  104. cp $TURTL_BASE_DIR/.users.lisp $turtl_users_file
  105. rm $TURTL_BASE_DIR/.users.lisp
  106. chown -R turtl:turtl $TURTL_BASE_DIR
  107. systemctl restart turtl
  108. fi
  109. fi
  110. }
  111. function configure_interactive_turtl_signups {
  112. # This implements a hack which removes or adds the function needed
  113. # to sign up new users. It should eventually be removed once that
  114. # capability exists within the api
  115. dialog --title $"Allow new turtl signups" \
  116. --backtitle $"Freedombone Control Panel" \
  117. --defaultno \
  118. --yesno $"\\nAllow registration of new users?" 10 60
  119. sel=$?
  120. case $sel in
  121. 0)
  122. turtl_enable_registrations
  123. dialog --title $"Allow new turtl signups" \
  124. --msgbox $"New turtl user registrations are now allowed" 6 60
  125. return;;
  126. 1)
  127. turtl_disable_registrations
  128. dialog --title $"Disable new turtl signups" \
  129. --msgbox $"New turtl user registrations are now disabled" 6 60
  130. return;;
  131. 255) return;;
  132. esac
  133. }
  134. function configure_interactive_turtl_storage {
  135. data=$(mktemp 2>/dev/null)
  136. dialog --title $"Change storage limit" \
  137. --backtitle $"Freedombone Control Panel" \
  138. --inputbox $"Enter a storage limit in megabytes." 8 75 "$TURTL_STORAGE_LIMIT_MB" 2>"$data"
  139. sel=$?
  140. case $sel in
  141. 0)
  142. STORAGE=$(<"$data")
  143. if [ ${#STORAGE} -gt 0 ]; then
  144. TURTL_STORAGE_LIMIT_MB=$STORAGE
  145. sed -i "s|defparameter *default-storage-limit*.*|defparameter *default-storage-limit* ${TURTL_STORAGE_LIMIT_MB})|g" $TURTL_BASE_DIR/api/config/config.lisp
  146. systemctl restart turtl
  147. dialog --title $"Change storage limit" \
  148. --msgbox $"Storage limit changed to ${TURTL_STORAGE_LIMIT_MB}M" 6 50
  149. fi
  150. ;;
  151. esac
  152. rm -f "$data"
  153. }
  154. function configure_interactive_turtl {
  155. data=$(mktemp 2>/dev/null)
  156. dialog --backtitle $"Freedombone Control Panel" \
  157. --title $"turtl app settings" \
  158. --radiolist $"Choose an operation:" 12 70 3 \
  159. 1 $"Enable/disable new user registrations" off \
  160. 2 $"Change storage limit" off \
  161. 3 $"Exit" on 2> "$data"
  162. sel=$?
  163. case $sel in
  164. 1) rm -f "$data"
  165. exit 1;;
  166. 255) rm -f "$data"
  167. exit 1;;
  168. esac
  169. case $(cat "$data") in
  170. 1) configure_interactive_turtl_signups;;
  171. 2) configure_interactive_turtl_storage;;
  172. 3) rm -f "$data"
  173. return;;
  174. esac
  175. rm -f "$data"
  176. }
  177. function reconfigure_turtl {
  178. if [ -d $TURTL_BASE_DIR/data ]; then
  179. rm -rf $TURTL_BASE_DIR/data/*
  180. fi
  181. }
  182. function upgrade_turtl {
  183. CURR_TURTL_COMMIT=$(get_completion_param "turtl commit")
  184. if [[ "$CURR_TURTL_COMMIT" == "$TURTL_COMMIT" ]]; then
  185. return
  186. fi
  187. read_config_param "TURTL_DOMAIN_NAME"
  188. function_check set_repo_commit
  189. set_repo_commit $TURTL_BASE_DIR/api "turtl commit" "$TURTL_COMMIT" $TURTL_REPO
  190. # this is used as a crude way of disabling signups and so
  191. # should be superceded in future
  192. if [ -f $TURTL_BASE_DIR/.users.lisp ]; then
  193. turtl_disable_registrations
  194. fi
  195. systemctl restart turtl
  196. nginx_dissite $TURTL_DOMAIN_NAME
  197. chown -R turtl:turtl $TURTL_BASE_DIR
  198. nginx_ensite $TURTL_DOMAIN_NAME
  199. }
  200. function backup_local_turtl {
  201. read_config_param "TURTL_DOMAIN_NAME"
  202. source_directory=$TURTL_BASE_DIR
  203. if [ -d $source_directory ]; then
  204. dest_directory=turtl
  205. function_check suspend_site
  206. suspend_site ${TURTL_DOMAIN_NAME}
  207. function_check backup_directory_to_usb
  208. backup_directory_to_usb $source_directory $dest_directory
  209. function_check restart_site
  210. restart_site
  211. fi
  212. source_directory=/var/lib/rethinkdb
  213. if [ -d $source_directory ]; then
  214. dest_directory=rethinkdb
  215. function_check suspend_site
  216. suspend_site ${TURTL_DOMAIN_NAME}
  217. function_check backup_directory_to_usb
  218. backup_directory_to_usb $source_directory $dest_directory
  219. function_check restart_site
  220. restart_site
  221. fi
  222. }
  223. function restore_local_turtl {
  224. read_config_param "TURTL_DOMAIN_NAME"
  225. if [ $TURTL_DOMAIN_NAME ]; then
  226. temp_restore_dir=/root/tempturtl
  227. restore_directory_from_usb $temp_restore_dir turtl
  228. if [ -d ${temp_restore_dir}/etc/turtl ]; then
  229. cp -r ${temp_restore_dir}/etc/turtl/* /etc/turtl/
  230. else
  231. cp -r ${temp_restore_dir}/* /etc/turtl/
  232. fi
  233. # shellcheck disable=SC2181
  234. if [ ! "$?" = "0" ]; then
  235. set_user_permissions
  236. backup_unmount_drive
  237. exit 36723
  238. fi
  239. rm -rf ${temp_restore_dir}
  240. chown -R turtl:turtl $TURTL_BASE_DIR
  241. temp_restore_dir=/root/temprethinkdb
  242. restore_directory_from_usb $temp_restore_dir rethinkdb
  243. if [ -d ${temp_restore_dir}/var/lib/rethinkdb ]; then
  244. cp -r ${temp_restore_dir}/var/lib/rethinkdb/* /var/lib/rethinkdb/
  245. else
  246. cp -r ${temp_restore_dir}/* /var/lib/rethinkdb/
  247. fi
  248. # shellcheck disable=SC2181
  249. if [ ! "$?" = "0" ]; then
  250. set_user_permissions
  251. backup_unmount_drive
  252. exit 378324
  253. fi
  254. rm -rf ${temp_restore_dir}
  255. fi
  256. }
  257. function backup_remote_turtl {
  258. read_config_param "TURTL_DOMAIN_NAME"
  259. if [ $TURTL_DOMAIN_NAME ]; then
  260. temp_backup_dir=$TURTL_BASE_DIR
  261. if [ -d $temp_backup_dir ]; then
  262. echo $"Backing up turtl"
  263. backup_directory_to_friend $temp_backup_dir turtl
  264. echo $"Backup of turtl complete"
  265. else
  266. echo $"turtl domain specified but not found in $temp_backup_dir"
  267. exit 68725
  268. fi
  269. temp_backup_dir=/var/lib/rethinkdb
  270. if [ -d $temp_backup_dir ]; then
  271. echo $"Backing up rethinkdb"
  272. backup_directory_to_friend $temp_backup_dir rethinkdb
  273. echo $"Backup of rethinkdb complete"
  274. fi
  275. fi
  276. }
  277. function restore_remote_turtl {
  278. read_config_param "TURTL_DOMAIN_NAME"
  279. if [ $TURTL_DOMAIN_NAME ]; then
  280. temp_restore_dir=/root/tempturtl
  281. mkdir $temp_restore_dir
  282. function_check restore_directory_from_friend
  283. restore_directory_from_friend $temp_restore_dir turtl
  284. if [ -d ${temp_restore_dir}/etc/turtl ]; then
  285. cp -r ${temp_restore_dir}/etc/turtl/* /etc/turtl/
  286. else
  287. cp -r ${temp_restore_dir}/* /etc/turtl/
  288. fi
  289. # shellcheck disable=SC2181
  290. if [ ! "$?" = "0" ]; then
  291. if [ -d /etc/turtl_previous ]; then
  292. mv /etc/turtl_previous $TURTL_BASE_DIR
  293. fi
  294. set_user_permissions
  295. exit 37823
  296. fi
  297. rm -rf ${temp_restore_dir}
  298. temp_restore_dir=/root/temprethinkdb
  299. mkdir $temp_restore_dir
  300. function_check restore_directory_from_friend
  301. restore_directory_from_friend $temp_restore_dir rethinkdb
  302. if [ -d ${temp_restore_dir}/var/lib/rethinkdb ]; then
  303. cp -r ${temp_restore_dir}/var/lib/rethinkdb/* /var/lib/rethinkdb/
  304. else
  305. cp -r ${temp_restore_dir}/* /var/lib/rethinkdb/
  306. fi
  307. # shellcheck disable=SC2181
  308. if [ ! "$?" = "0" ]; then
  309. set_user_permissions
  310. exit 26783
  311. fi
  312. rm -rf ${temp_restore_dir}
  313. fi
  314. }
  315. function remove_turtl {
  316. if [ ! -d $TURTL_BASE_DIR ]; then
  317. return
  318. fi
  319. systemctl stop turtl
  320. systemctl disable turtl
  321. rm /etc/systemd/system/turtl.service
  322. systemctl daemon-reload
  323. remove_rethinkdb
  324. remove_app turtl
  325. remove_completion_param install_turtl
  326. sed -i '/turtl/d' "$COMPLETION_FILE"
  327. nginx_dissite $TURTL_DOMAIN_NAME
  328. if [ -f /etc/nginx/sites-available/$TURTL_DOMAIN_NAME ]; then
  329. rm /etc/nginx/sites-available/$TURTL_DOMAIN_NAME
  330. fi
  331. remove_certs $TURTL_DOMAIN_NAME
  332. function_check remove_onion_service
  333. remove_onion_service turtl ${TURTL_ONION_PORT}
  334. function_check remove_ddns_domain
  335. remove_ddns_domain $TURTL_DOMAIN_NAME
  336. rm -rf /etc/rethinkdb
  337. rm -rf /var/lib/rethinkdb
  338. rm -rf $TURTL_BASE_DIR
  339. groupdel -f turtl
  340. userdel -r turtl
  341. }
  342. function turtl_setup {
  343. PIDFILE=${PIDFILE:-nil}
  344. BINDADDR=${BINDADDR:-0.0.0.0}
  345. BINDPORT=${BINDPORT:-8181}
  346. PROD_ERR_HANDLING=${PROD_ERR_HANDLING:-t}
  347. if [[ $ONION_ONLY == 'no' ]]; then
  348. FQDN=${FQDN:-$TURTL_DOMAIN_NAME}
  349. SITE_URL=${SITE_URL:-https://$TURTL_DOMAIN_NAME}
  350. else
  351. FQDN=${FQDN:-$TURTL_ONION_HOSTNAME}
  352. SITE_URL=${SITE_URL:-http://$TURTL_ONION_HOSTNAME}
  353. fi
  354. ADMIN_EMAIL=${ADMIN_EMAIL:-$MY_EMAIL_ADDRESS}
  355. EMAIL_FROM=${EMAIL_FROM:-noreply@$DEFAULT_DOMAIN_NAME}
  356. SMTP_USER=${SMTP_USER:-}
  357. SMTP_PASS=${SMTP_PASS:-}
  358. DISPLAY_ERRORS=${DISPLAY_ERRORS:-t}
  359. DEFAULT_STORAGE_LIMIT=${DEFAULT_STORAGE_LIMIT:-100}
  360. STORAGE_INVITE_CREDIT=${STORAGE_INVITE_CREDIT:-25}
  361. if [[ $ONION_ONLY == 'no' ]]; then
  362. LOCAL_UPLOAD_URL=${LOCAL_UPLOAD_URL:-https://$TURTL_DOMAIN_NAME}
  363. else
  364. LOCAL_UPLOAD_URL=${LOCAL_UPLOAD_URL:-http://$TURTL_ONION_HOSTNAME}
  365. fi
  366. LOCAL_UPLOAD_PATH=${LOCAL_UPLOAD_PATH:-"$TURTL_BASE_DIR/data"}
  367. AWS_S3_TOKEN=${AWS_S3_TOKEN:-(:token ''
  368. :secret ''
  369. :bucket ''
  370. :endpoint 'https://s3.amazonaws.com')}
  371. # generates the config-file
  372. cat << __ENDCONFIG__ > $TURTL_BASE_DIR/api/config/config.lisp
  373. (in-package :turtl)
  374. (defparameter *root* (asdf:system-relative-pathname :turtl #P""))
  375. (defparameter *pid-file* "${PIDFILE}")
  376. (defvar *server-bind* "${BINDADDR}")
  377. (defvar *server-port* ${BINDPORT})
  378. (defvar *db-name* "turtl")
  379. (defvar *db-host* "127.0.0.1")
  380. (defvar *db-port* 28015)
  381. (defvar *production-error-handling* ${PROD_ERR_HANDLING})
  382. (defvar *enable-hsts-header* nil)
  383. (defvar *site-url* "${SITE_URL}")
  384. (defvar *api-path* "")
  385. (defvar *admin-email* "${ADMIN_EMAIL}")
  386. (defvar *email-from* "${EMAIL_FROM}")
  387. (defvar *email-user* "${SMTP_USER}")
  388. (defvar *email-pass* "${SMTP_PASS}")
  389. (defvar *display-errors* ${DISPLAY_ERRORS})
  390. (defparameter *default-storage-limit* ${DEFAULT_STORAGE_LIMIT})
  391. (defparameter *storage-invite-credit* ${STORAGE_INVITE_CREDIT})
  392. (vom:config :turtl :info)
  393. (defvar *local-upload* "${LOCAL_UPLOAD_PATH}")
  394. (defvar *local-upload-url* "${LOCAL_UPLOAD_URL}")
  395. (defvar *amazon-s3* "${AWS_S3_TOKEN}")
  396. __ENDCONFIG__
  397. cat $TURTL_BASE_DIR/api/config/config.footer >> $TURTL_BASE_DIR/api/config/config.lisp
  398. # start the turtl server
  399. systemctl restart rethinkdb
  400. if [ ! -f $TURTL_BASE_DIR/quicklisp/setup.lisp ]; then
  401. echo $"$TURTL_BASE_DIR/quicklisp/setup.lisp was not found"
  402. exit 6238234
  403. fi
  404. { echo '[Unit]';
  405. echo 'Description=Note taking service';
  406. echo 'Documentation=http://turtl.it';
  407. echo 'Requires=network.target';
  408. echo 'Requires=rethinkdb.service';
  409. echo 'After=network.target';
  410. echo 'After=rethinkdb.service';
  411. echo '';
  412. echo '[Service]';
  413. echo 'Type=simple';
  414. echo 'User=turtl';
  415. echo "WorkingDirectory=$TURTL_BASE_DIR/api/"; } > /etc/systemd/system/turtl.service
  416. if [[ "$check_architecture" == *"64"* && "$check_architecture" != *"arm"* ]]; then
  417. echo "ExecStart=$TURTL_BASE_DIR/ccl/lx86cl64 -l $TURTL_BASE_DIR/quicklisp/setup.lisp -l launch.lisp" >> /etc/systemd/system/turtl.service
  418. else
  419. if [[ "$check_architecture" != *"arm"* ]]; then
  420. echo "ExecStart=$TURTL_BASE_DIR/ccl/lx86cl -l $TURTL_BASE_DIR/quicklisp/setup.lisp -l launch.lisp" >> /etc/systemd/system/turtl.service
  421. else
  422. echo "ExecStart=$TURTL_BASE_DIR/ccl/armcl -l $TURTL_BASE_DIR/quicklisp/setup.lisp -l launch.lisp" >> /etc/systemd/system/turtl.service
  423. fi
  424. fi
  425. { echo '';
  426. echo '[Install]';
  427. echo 'WantedBy=multi-user.target'; } >> /etc/systemd/system/turtl.service
  428. chmod +x /etc/systemd/system/turtl.service
  429. chown -R turtl:turtl $TURTL_BASE_DIR
  430. systemctl enable turtl
  431. systemctl daemon-reload
  432. systemctl start turtl
  433. }
  434. function install_turtl_api {
  435. # https://github.com/ArthurGarnier/turtl-docker
  436. apt-get -yq install wget libterm-readline-perl-perl gcc libuv1-dev
  437. if [ ! -d $TURTL_BASE_DIR ]; then
  438. mkdir -p $TURTL_BASE_DIR
  439. fi
  440. cd "$TURTL_BASE_DIR" || exit 745726542
  441. mkdir cd $TURTL_BASE_DIR/data
  442. check_architecture=$(uname -a)
  443. # Install ccl
  444. if [[ "$check_architecture" != *"arm"* ]]; then
  445. wget -P $TURTL_BASE_DIR/ ftp://ftp.clozure.com/pub/release/1.11/ccl-1.11-linuxx86.tar.gz
  446. mkdir -p $TURTL_BASE_DIR/ccl
  447. tar xvzf $TURTL_BASE_DIR/ccl-1.11-linuxx86.tar.gz -C $TURTL_BASE_DIR/ccl --strip-components=1
  448. else
  449. wget -P $TURTL_BASE_DIR/ ftp://ftp.clozure.com/pub/release/1.11/ccl-1.11-linuxarm.tar.gz
  450. mkdir -p $TURTL_BASE_DIR/ccl
  451. tar xvzf $TURTL_BASE_DIR/ccl-1.11-linuxarm.tar.gz -C $TURTL_BASE_DIR/ccl --strip-components=1
  452. fi
  453. # install quicklisp
  454. cat << __ENDCONFIG__ > $TURTL_BASE_DIR/quicklisp_install
  455. (load (compile-file "asdf.lisp"))
  456. (load (compile-file "quicklisp.lisp"))
  457. (quicklisp-quickstart:install)
  458. (ql:system-apropos "vecto")
  459. (ql:quickload "alexandria")
  460. (ql:quickload "babel")
  461. (ql:quickload "blackbird")
  462. (ql:quickload "bordeaux-threads")
  463. (ql:quickload "cffi")
  464. (ql:quickload "chipz")
  465. (ql:quickload "chunga")
  466. (ql:quickload "cl-annot")
  467. (ql:quickload "cl-async")
  468. (ql:quickload "cl-async-future")
  469. (ql:quickload "cl-base64")
  470. (ql:quickload "cl-fad")
  471. (ql:quickload "cl-libuv")
  472. (ql:quickload "cl-mongo-id")
  473. (ql:quickload "cl-ppcre")
  474. (ql:quickload "cl-rethinkdb")
  475. (ql:quickload "cl-smtp")
  476. (ql:quickload "cl+ssl")
  477. (ql:quickload "cl-syntax")
  478. (ql:quickload "cl-utilities")
  479. (ql:quickload "cl-vectors")
  480. (ql:quickload "do-urlencode")
  481. (ql:quickload "drakma")
  482. (ql:quickload "drakma-async")
  483. (ql:quickload "event-glue")
  484. (ql:quickload "fast-http")
  485. (ql:quickload "fast-io")
  486. (ql:quickload "flexi-streams")
  487. (ql:quickload "ironclad")
  488. (ql:quickload "jonathan")
  489. (ql:quickload "local-time")
  490. (ql:quickload "md5")
  491. (ql:quickload "named-readtables")
  492. (ql:quickload "nibbles")
  493. (ql:quickload "proc-parse")
  494. (ql:quickload "puri")
  495. (ql:quickload "quri")
  496. (ql:quickload "salza2")
  497. (ql:quickload "secure-random")
  498. (ql:quickload "smart-buffer")
  499. (ql:quickload "split-sequence")
  500. (ql:quickload "static-vectors")
  501. (ql:quickload "trivial-backtrace")
  502. (ql:quickload "trivial-features")
  503. (ql:quickload "trivial-garbage")
  504. (ql:quickload "trivial-gray-streams")
  505. (ql:quickload "trivial-types")
  506. (ql:quickload "usocket")
  507. (ql:quickload "vecto")
  508. (ql:quickload "vom")
  509. (ql:quickload "wookie")
  510. (ql:quickload "xmls")
  511. (ql:quickload "xsubseq")
  512. (ql:quickload "yason")
  513. (ql:quickload "zpb-ttf")
  514. (ql:quickload "zpng")
  515. (ql:add-to-init-file)
  516. (ccl::quit)
  517. __ENDCONFIG__
  518. if [ ! -f asdf.lisp ]; then
  519. wget https://common-lisp.net/project/asdf/asdf.lisp
  520. fi
  521. if [ ! -f quicklisp.lisp ]; then
  522. wget https://beta.quicklisp.org/quicklisp.lisp
  523. fi
  524. if [ -d $TURTL_BASE_DIR ]; then
  525. chown -R turtl:turtl $TURTL_BASE_DIR
  526. fi
  527. adduser --disabled-login --home=$TURTL_BASE_DIR --gecos 'turtl' turtl
  528. if [ ! -d $TURTL_BASE_DIR ]; then
  529. echo $"$TURTL_BASE_DIR directory not created"
  530. exit 263493
  531. fi
  532. groupadd turtl
  533. chown -R turtl:turtl $TURTL_BASE_DIR
  534. if [[ "$check_architecture" != *"arm"* ]]; then
  535. if [[ "$check_architecture" == *"64"* ]]; then
  536. su -c "cat $TURTL_BASE_DIR/quicklisp_install | $TURTL_BASE_DIR/ccl/lx86cl64" - turtl
  537. else
  538. su -c "cat $TURTL_BASE_DIR/quicklisp_install | $TURTL_BASE_DIR/ccl/lx86cl" - turtl
  539. fi
  540. else
  541. su -c "cat $TURTL_BASE_DIR/quicklisp_install | $TURTL_BASE_DIR/ccl/larmcl" - turtl
  542. fi
  543. rm $TURTL_BASE_DIR/quicklisp_install
  544. install_rethinkdb
  545. echo "http-port=8091" > /etc/rethinkdb/instances.d/turtl.conf
  546. chown -R rethinkdb:rethinkdb /var/lib/rethinkdb
  547. # install turtl API
  548. cd "$TURTL_BASE_DIR/" || exit 6428462
  549. if [ -d /repos/turtl ]; then
  550. mkdir $TURTL_BASE_DIR/api
  551. cp -r -p /repos/turtl/. $TURTL_BASE_DIR/api
  552. cd "$TURTL_BASE_DIR/api" || exit 57141845
  553. git pull
  554. else
  555. git clone $TURTL_REPO $TURTL_BASE_DIR/api
  556. fi
  557. cd "$TURTL_BASE_DIR/api" || exit 35814614
  558. git checkout $TURTL_COMMIT -b $TURTL_COMMIT
  559. set_completion_param "turtl commit" "$TURTL_COMMIT"
  560. cd "$TURTL_BASE_DIR/quicklisp/local-projects" || exit 43618941415
  561. git clone git://github.com/orthecreedence/cl-hash-util
  562. if [[ "$check_architecture" != *"arm"* ]]; then
  563. if [[ "$check_architecture" == *"64"* ]]; then
  564. su -c "cat '(ccl:quit)' | $TURTL_BASE_DIR/ccl/lx86cl64 -l $TURTL_BASE_DIR/quicklisp/setup.lisp" - turtl
  565. else
  566. su -c "cat '(ccl:quit)' | $TURTL_BASE_DIR/ccl/lx86cl -l $TURTL_BASE_DIR/quicklisp/setup.lisp" - turtl
  567. fi
  568. else
  569. su -c "cat '(ccl:quit)' | $TURTL_BASE_DIR/ccl/larmcl -l $TURTL_BASE_DIR/quicklisp/setup.lisp" - turtl
  570. fi
  571. # config
  572. { echo '(defvar *enabled-cors-resources* "resource://turtl-at-lyonbros-dot-com"';
  573. echo ' "When set, will enable CORS for resource:// origins if they match the given';
  574. echo ' string. Entries should be comma separated (this string is passed verbatim in';
  575. echo ' the Access-Control-Allow-Origin header).")';
  576. echo '(defparameter *public-actions*';
  577. echo " \`((:post . ,(concatenate 'string *api-path* \"/users\"))";
  578. echo " (:post . ,(concatenate 'string *api-path* \"/log/error\"))";
  579. echo ' (:post . "/cla/sign")';
  580. echo ' (:get . "/ping")';
  581. echo ' (:get . "/admin")';
  582. echo " (:get . ,(cl-ppcre:create-scanner (concatenate 'string *api-path* \"/invites/codes/([0-9a-f-]+)\"))))";
  583. echo " \"A list of public resources/actions that do not require authentication.\")";
  584. echo "(defvar *analytics* '(:enabled t";
  585. echo ' :db "analytics"))'; } > "$TURTL_BASE_DIR/api/config/config.footer"
  586. cp $TURTL_BASE_DIR/asdf.lisp $TURTL_BASE_DIR/api
  587. echo '(load (compile-file "asdf.lisp"))' > $TURTL_BASE_DIR/api/launch.lisp
  588. echo "(pushnew \"./\" asdf:*central-registry* :test #'equal)" >> $TURTL_BASE_DIR/api/launch.lisp
  589. echo '(load "start")' >> $TURTL_BASE_DIR/api/launch.lisp
  590. TURTL_ONION_HOSTNAME=$(add_onion_service turtl 80 ${TURTL_ONION_PORT})
  591. turtl_setup
  592. }
  593. function install_turtl_nginx {
  594. turtl_nginx_site=/etc/nginx/sites-available/$TURTL_DOMAIN_NAME
  595. if [[ $ONION_ONLY == "no" ]]; then
  596. function_check nginx_http_redirect
  597. nginx_http_redirect $TURTL_DOMAIN_NAME
  598. { echo 'server {';
  599. echo ' listen 443 ssl;';
  600. echo ' #listen [::]:443 ssl;';
  601. echo " server_name ${TURTL_DOMAIN_NAME};";
  602. echo '';
  603. echo ' # Security'; } >> "$turtl_nginx_site"
  604. function_check nginx_ssl
  605. nginx_ssl $TURTL_DOMAIN_NAME
  606. function_check nginx_security_options
  607. nginx_security_options $TURTL_DOMAIN_NAME
  608. { echo ' add_header Strict-Transport-Security max-age=15768000;';
  609. echo '';
  610. echo ' # Logs';
  611. echo ' access_log /dev/null;';
  612. echo ' error_log /dev/null;';
  613. echo '';
  614. echo ' location / {'; } >> "$turtl_nginx_site"
  615. function_check nginx_limits
  616. nginx_limits $TURTL_DOMAIN_NAME '15m'
  617. { echo " proxy_pass http://localhost:${TURTL_PORT}/;";
  618. echo " proxy_set_header Host \$host;";
  619. echo ' proxy_buffering off;';
  620. echo ' }';
  621. echo '}'; } >> "$turtl_nginx_site"
  622. else
  623. echo -n '' > $turtl_nginx_site
  624. fi
  625. { echo 'server {';
  626. echo " listen 127.0.0.1:${TURTL_ONION_PORT};";
  627. echo " server_name ${TURTL_ONION_HOSTNAME};";
  628. echo ''; } >> $turtl_nginx_site
  629. function_check nginx_security_options
  630. nginx_security_options $TURTL_DOMAIN_NAME
  631. { echo '';
  632. echo ' # Logs';
  633. echo ' access_log /dev/null;';
  634. echo ' error_log /dev/null;';
  635. echo '';
  636. echo ' location / {'; } >> $turtl_nginx_site
  637. function_check nginx_limits
  638. nginx_limits $TURTL_DOMAIN_NAME '15m'
  639. { echo " proxy_pass http://localhost:${TURTL_PORT}/;";
  640. echo " proxy_set_header Host \$host;";
  641. echo ' proxy_buffering off;';
  642. echo ' }';
  643. echo '}'; } >> $turtl_nginx_site
  644. function_check add_ddns_domain
  645. add_ddns_domain $TURTL_DOMAIN_NAME
  646. set_completion_param "turtl domain" "$TURTL_DOMAIN_NAME"
  647. function_check create_site_certificate
  648. create_site_certificate $TURTL_DOMAIN_NAME 'yes'
  649. function_check nginx_ensite
  650. nginx_ensite $TURTL_DOMAIN_NAME
  651. systemctl restart nginx
  652. }
  653. function install_turtl {
  654. install_turtl_api
  655. install_turtl_nginx
  656. APP_INSTALLED=1
  657. }