Browse Source

radicale app

Bob Mottram 8 years ago
parent
commit
a30ecdfdbe
2 changed files with 353 additions and 1 deletions
  1. 352
    0
      src/freedombone-app-radicale
  2. 1
    1
      src/freedombone-app-xmpp

+ 352
- 0
src/freedombone-app-radicale View File

@@ -0,0 +1,352 @@
1
+#!/bin/bash
2
+#
3
+# .---.                  .              .
4
+# |                      |              |
5
+# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
6
+# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
7
+# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
8
+#
9
+#                    Freedom in the Cloud
10
+#
11
+# Radicale calendar system
12
+#
13
+# Configuration based upon:
14
+#   https://gigacog.com/blog/2016/01/radicale-and-uwsgi-on-nginx-with-systemd
15
+#
16
+# License
17
+# =======
18
+#
19
+# Copyright (C) 2016 Bob Mottram <bob@freedombone.net>
20
+#
21
+# This program is free software: you can redistribute it and/or modify
22
+# it under the terms of the GNU Affero General Public License as published by
23
+# the Free Software Foundation, either version 3 of the License, or
24
+# (at your option) any later version.
25
+#
26
+# This program is distributed in the hope that it will be useful,
27
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
28
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
+# GNU Affero General Public License for more details.
30
+#
31
+# You should have received a copy of the GNU Affero General Public License
32
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
33
+
34
+VARIANTS='full full-vim'
35
+
36
+IN_DEFAULT_INSTALL=1
37
+SHOW_ON_ABOUT=1
38
+
39
+RADICALE_PASSWORD=
40
+RADICALE_ONION_PORT=8106
41
+RADICALE_PORT=5232
42
+RADICALE_DIRECTORY='/etc/radicale'
43
+
44
+radicale_variables=(ONION_ONLY
45
+                    MY_USERNAME
46
+                    RADICALE_PASSWORD
47
+                    DEFAULT_DOMAIN_NAME)
48
+
49
+function remove_user_radicale {
50
+    remove_username="$1"
51
+    if grep "$remove_username:" ${RADICALE_DIRECTORY}/users; then
52
+        sed -i "/$remove_username/d" ${RADICALE_DIRECTORY}/users
53
+        systemctl reload radicale
54
+    fi
55
+}
56
+
57
+function add_user_radicale {
58
+    new_username="$1"
59
+    new_user_password="$2"
60
+
61
+    if ! grep "$new_username:$new_user_password" ${RADICALE_DIRECTORY}/users; then
62
+        printf "$new_username:$new_user_password\n" >> ${RADICALE_DIRECTORY}/users
63
+        systemctl reload radicale
64
+    fi
65
+    echo '0'
66
+}
67
+
68
+function install_interactive_radicale {
69
+    echo -n ''
70
+    APP_INSTALLED=1
71
+}
72
+
73
+function change_password_radicale {
74
+    echo -n ''
75
+}
76
+
77
+function reconfigure_radicale {
78
+    echo -n ''
79
+}
80
+
81
+function upgrade_radicale {
82
+    if [ -f /etc/init.d/radicale ]; then
83
+        systemctl stop radicale
84
+        rm /etc/init.d/radicale
85
+        systemctl daemon-reload
86
+        systemctl start radicale
87
+    fi
88
+}
89
+
90
+function backup_local_radicale {
91
+    source_directory=${RADICALE_DIRECTORY}
92
+    if [ -d $source_directory ]; then
93
+        dest_directory=radicale
94
+        function_check backup_directory_to_usb
95
+        backup_directory_to_usb $source_directory $dest_directory
96
+    fi
97
+}
98
+
99
+function restore_local_radicale {
100
+    if [ -d ${RADICALE_DIRECTORY} ]; then
101
+        temp_restore_dir=/root/tempradicale
102
+        function_check restore_directory_from_usb
103
+        restore_directory_from_usb $temp_restore_dir radicale
104
+        cp -r $temp_restore_dir${RADICALE_DIRECTORY}/* ${RADICALE_DIRECTORY}
105
+        if [ ! "$?" = "0" ]; then
106
+            function_check backup_unmount_drive
107
+            backup_unmount_drive
108
+            exit 46872
109
+        fi
110
+        rm -rf $temp_restore_dir
111
+        systemctl restart radicale
112
+    fi
113
+}
114
+
115
+function backup_remote_radicale {
116
+    if [ -d ${RADICALE_DIRECTORY} ]; then
117
+        echo $"Backing up the radicale settings"
118
+        backup_directory_to_friend ${RADICALE_DIRECTORY} radicale
119
+        echo $"Backup of radicale settings complete"
120
+    fi
121
+}
122
+
123
+function restore_remote_radicale {
124
+    if [ -d ${RADICALE_DIRECTORY} ]; then
125
+        temp_restore_dir=/root/tempradicale
126
+        function_check restore_directory_from_friend
127
+        restore_directory_from_friend $temp_restore_dir radicale
128
+        cp -r $temp_restore_dir${RADICALE_DIRECTORY}/* ${RADICALE_DIRECTORY}
129
+        if [ ! "$?" = "0" ]; then
130
+            exit 463735
131
+        fi
132
+        rm -rf $temp_restore_dir
133
+        systemctl restart radicale
134
+    fi
135
+}
136
+
137
+function configure_firewall_for_radicale {
138
+    if [ ! -d ${RADICALE_DIRECTORY} ]; then
139
+        return
140
+    fi
141
+    if [[ $(is_completed $FUNCNAME) == "1" ]]; then
142
+        return
143
+    fi
144
+    if [[ $INSTALLED_WITHIN_DOCKER == "yes" ]]; then
145
+        # docker does its own firewalling
146
+        return
147
+    fi
148
+    if [[ $ONION_ONLY != "no" ]]; then
149
+        return
150
+    fi
151
+    firewall_add radicale ${RADICALE_PORT} tcp
152
+    mark_completed $FUNCNAME
153
+}
154
+
155
+function remove_radicale {
156
+    nginx_dissite radicale
157
+    systemctl stop radicale
158
+    systemctl stop uwsgi_rundir
159
+    systemctl disable radicale
160
+    systemctl disable uwsgi_rundir
161
+    if [ -f /etc/systemd/system/uwsgi_rundir.service ]; then
162
+        rm /etc/systemd/system/uwsgi_rundir.service
163
+    fi
164
+    if [ -f /etc/systemd/system/radicale.service ]; then
165
+        rm /etc/systemd/system/radicale.service
166
+    fi
167
+    if [ -f /etc/nginx/sites-available/radicale ]; then
168
+        rm /etc/nginx/sites-available/radicale
169
+    fi
170
+
171
+    firewall_remove ${RADICALE_PORT} tcp
172
+
173
+    function_check remove_onion_service
174
+    remove_onion_service radicale ${RADICALE_ONION_PORT}
175
+
176
+    apt-get -yq remove --purge radicale python-radicale
177
+    if [ -d ${RADICALE_DIRECTORY} ]; then
178
+        rm -rf ${RADICALE_DIRECTORY}
179
+    fi
180
+    if [ -d /var/www/radicale ]; then
181
+        rm -rf /var/www/radicale
182
+    fi
183
+
184
+    remove_completion_param install_radicale
185
+    sed -i '/radicale/d' $COMPLETION_FILE
186
+    sed -i '/Radicale/d' /home/$MY_USERNAME/README
187
+}
188
+
189
+function install_radicale {
190
+    if [[ $ONION_ONLY == 'no' ]]; then
191
+        # obtain a cert for the default domain
192
+        if [[ "$(cert_exists ${DEFAULT_DOMAIN_NAME} pem)" == "0" ]]; then
193
+            echo $'Obtaining certificate for the main domain'
194
+            create_site_certificate ${DEFAULT_DOMAIN_NAME} 'yes'
195
+        fi
196
+    fi
197
+
198
+    apt-get -yq install python-radicale uwsgi uwsgi-plugin-python radicale
199
+
200
+    if [ ! -d ${RADICALE_DIRECTORY} ]; then
201
+        echo $"ERROR: radicale does not appear to have installed"
202
+        exit 46372
203
+    fi
204
+    systemctl stop radicale
205
+    if [ -f /etc/init.d/radicale ]; then
206
+        rm /etc/init.d/radicale
207
+    fi
208
+
209
+    if [ ! -d ${RADICALE_DIRECTORY}/collections ]; then
210
+        mkdir -p ${RADICALE_DIRECTORY}/collections
211
+    fi
212
+    chown www-data:www-data ${RADICALE_DIRECTORY}/collections
213
+
214
+    echo '[auth]' >  ${RADICALE_DIRECTORY}/config
215
+    echo 'type = htpasswd' >> ${RADICALE_DIRECTORY}/config
216
+    echo 'htpasswd_filename = ${RADICALE_DIRECTORY}/users' >> ${RADICALE_DIRECTORY}/config
217
+    echo 'htpasswd_encryption = crypt' >> ${RADICALE_DIRECTORY}/config
218
+    echo '' >> ${RADICALE_DIRECTORY}/config
219
+    echo '[rights]' >> ${RADICALE_DIRECTORY}/config
220
+    echo 'type = owner_only' >> ${RADICALE_DIRECTORY}/config
221
+    echo '' >> ${RADICALE_DIRECTORY}/config
222
+    echo '[storage]' >> ${RADICALE_DIRECTORY}/config
223
+    echo 'type = filesystem' >> ${RADICALE_DIRECTORY}/config
224
+    echo 'filesystem_folder = ${RADICALE_DIRECTORY}/collections' >> ${RADICALE_DIRECTORY}/config
225
+
226
+    if [ ${#RADICALE_PASSWORD} -lt 8 ]; then
227
+        if [ -f $IMAGE_PASSWORD_FILE ]; then
228
+            RADICALE_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
229
+        else
230
+            RADICALE_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
231
+        fi
232
+    fi
233
+    add_user_radicale "$MY_USERNAME" "$RADICALE_PASSWORD"
234
+
235
+    if [ ! -f /var/www/radicale ]; then
236
+        mkdir /var/www/radicale
237
+    fi
238
+    echo 'import radicale' > /var/www/radicale/radicale.py
239
+    echo 'radicale.log.start()' >> /var/www/radicale/radicale.py
240
+    echo 'application = radicale.Application()' >> /var/www/radicale/radicale.py
241
+
242
+    echo '[uwsgi]' > /var/www/radicale/uwsgi.ini
243
+    echo 'plugins = python' >> /var/www/radicale/uwsgi.ini
244
+    echo 'socket = /var/run/uwsgi/radicale.sock' >> /var/www/radicale/uwsgi.ini
245
+    echo 'chmod-socket = 660' >> /var/www/radicale/uwsgi.ini
246
+    echo '' >> /var/www/radicale/uwsgi.ini
247
+    echo 'wsgi-file = /var/www/radicale/radicale.py' >> /var/www/radicale/uwsgi.ini
248
+    echo 'master' >> /var/www/radicale/uwsgi.ini
249
+    echo 'workers = 1' >> /var/www/radicale/uwsgi.ini
250
+    echo 'max-requests = 100' >> /var/www/radicale/uwsgi.ini
251
+    echo 'harakiri = 30' >> /var/www/radicale/uwsgi.ini
252
+    echo 'die-on-term' >> /var/www/radicale/uwsgi.ini
253
+
254
+    echo '#!/bin/sh' > /usr/local/bin/uwsgi_rundir.sh
255
+    echo 'mkdir -p /var/run/uwsgi' >> /usr/local/bin/uwsgi_rundir.sh
256
+    echo 'chown www-data:www-data /var/run/uwsgi' >> /usr/local/bin/uwsgi_rundir.sh
257
+    chmod +x /usr/local/bin/uwsgi_rundir.sh
258
+
259
+    echo '[Unit]' > /etc/systemd/system/uwsgi_rundir.service
260
+    echo 'Description=UWSGI socket directory' >> /etc/systemd/system/uwsgi_rundir.service
261
+    echo 'After=network.target' >> /etc/systemd/system/uwsgi_rundir.service
262
+    echo '' >> /etc/systemd/system/uwsgi_rundir.service
263
+    echo '[Service]' >> /etc/systemd/system/uwsgi_rundir.service
264
+    echo 'Type=simple' >> /etc/systemd/system/uwsgi_rundir.service
265
+    echo 'User=root' >> /etc/systemd/system/uwsgi_rundir.service
266
+    echo 'ExecStart=/usr/local/bin/uwsgi_rundir.sh' >> /etc/systemd/system/uwsgi_rundir.service
267
+    echo '' >> /etc/systemd/system/uwsgi_rundir.service
268
+    echo '[Install]' >> /etc/systemd/system/uwsgi_rundir.service
269
+    echo 'WantedBy=multi-user.target' >> /etc/systemd/system/uwsgi_rundir.service
270
+    systemctl enable uwsgi_rundir
271
+
272
+    echo '[Unit]' > /etc/systemd/system/radicale.service
273
+    echo 'Description=Start uwsgi for radicale' >> /etc/systemd/system/radicale.service
274
+    echo 'After=network.target' >> /etc/systemd/system/radicale.service
275
+    echo 'Requires=uwsgi_rundir.service' >> /etc/systemd/system/radicale.service
276
+    echo '' >> /etc/systemd/system/radicale.service
277
+    echo '[Service]' >> /etc/systemd/system/radicale.service
278
+    echo 'Type=simple' >> /etc/systemd/system/radicale.service
279
+    echo 'User=www-data' >> /etc/systemd/system/radicale.service
280
+    echo 'Group=www-data' >> /etc/systemd/system/radicale.service
281
+    echo 'ExecStart=/usr/bin/uwsgi --ini /var/www/radicale/uwsgi.ini' >> /etc/systemd/system/radicale.service
282
+    echo '' >> /etc/systemd/system/radicale.service
283
+    echo '[Install]' >> /etc/systemd/system/radicale.service
284
+    echo 'WantedBy=multi-user.target' >> /etc/systemd/system/radicale.service
285
+    systemctl enable radicale
286
+    systemctl start radicale
287
+
288
+    RADICALE_ONION_HOSTNAME=$(add_onion_service radicale 80 ${RADICALE_ONION_PORT})
289
+
290
+    if [[ $ONION_ONLY == 'no' ]]; then
291
+        echo 'server {' > /etc/nginx/sites-available/radicale
292
+        echo "    listen ${RADICALE_PORT} ssl;" >> /etc/nginx/sites-available/radicale
293
+        echo "    listen [::]:${RADICALE_PORT} ssl;" >> /etc/nginx/sites-available/radicale
294
+        echo '' >> /etc/nginx/sites-available/radicale
295
+        function_check nginx_ssl
296
+        nginx_ssl $DEFAULT_DOMAIN_NAME
297
+        function_check nginx_disable_sniffing
298
+        nginx_disable_sniffing $DEFAULT_DOMAIN_NAME
299
+        echo '' >> /etc/nginx/sites-available/radicale
300
+        echo "    server_name $DEFAULT_DOMAIN_NAME;" >> /etc/nginx/sites-available/radicale
301
+        echo '' >> /etc/nginx/sites-available/radicale
302
+        echo '    location / {' >> /etc/nginx/sites-available/radicale
303
+        echo '        uwsgi_pass unix:/var/run/uwsgi/radicale.sock;' >> /etc/nginx/sites-available/radicale
304
+        echo '        include uwsgi_params;' >> /etc/nginx/sites-available/radicale
305
+        echo '    }' >> /etc/nginx/sites-available/radicale
306
+        echo '}' >> /etc/nginx/sites-available/radicale
307
+        echo '' >> /etc/nginx/sites-available/radicale
308
+    else
309
+        echo -n '' > /etc/nginx/sites-available/radicale
310
+    fi
311
+    echo 'server {' >> /etc/nginx/sites-available/radicale
312
+    echo "    listen 127.0.0.1:${RADICALE_ONION_PORT} default_server;" >> /etc/nginx/sites-available/radicale
313
+    echo '' >> /etc/nginx/sites-available/radicale
314
+    echo "    server_name ${RADICALE_ONION_HOSTNAME};" >> /etc/nginx/sites-available/radicale
315
+    echo '' >> /etc/nginx/sites-available/radicale
316
+    echo '    location / {' >> /etc/nginx/sites-available/radicale
317
+    echo '        uwsgi_pass unix:/var/run/uwsgi/radicale.sock;' >> /etc/nginx/sites-available/radicale
318
+    echo '        include uwsgi_params;' >> /etc/nginx/sites-available/radicale
319
+    echo '    }' >> /etc/nginx/sites-available/radicale
320
+    echo '}' >> /etc/nginx/sites-available/radicale
321
+
322
+    # create a certificate
323
+    if [[ "$(cert_exists ${DEFAULT_DOMAIN_NAME} pem)" == "0" ]]; then
324
+        if [[ "$(cert_exists $DEFAULT_DOMAIN_NAME)" == "0" ]]; then
325
+            ${PROJECT_NAME}-addcert -h $DEFAULT_DOMAIN_NAME --dhkey ${DH_KEYLENGTH}
326
+            check_certificates $DEFAULT_DOMAIN_NAME
327
+        fi
328
+    fi
329
+
330
+    update_default_domain
331
+
332
+    nginx_ensite radicale
333
+    systemctl reload nginx
334
+
335
+    set_completion_param "radicale onion domain" "${RADICALE_ONION_HOSTNAME}"
336
+
337
+    if ! grep -q "Your RADICALE password is" /home/$MY_USERNAME/README; then
338
+        echo '' >> /home/$MY_USERNAME/README
339
+        echo $'# RADICALE' >> /home/$MY_USERNAME/README
340
+        echo $"RADICALE onion domain: ${RADICALE_ONION_HOSTNAME}" >> /home/$MY_USERNAME/README
341
+        echo $"Your RADICALE password is: ${RADICALE_PASSWORD}" >> /home/$MY_USERNAME/README
342
+        chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/README
343
+        chmod 600 /home/$MY_USERNAME/README
344
+    fi
345
+
346
+    function_check configure_firewall_for_radicale
347
+    configure_firewall_for_radicale
348
+
349
+    APP_INSTALLED=1
350
+}
351
+
352
+# NOTE: deliberately no exit 0

+ 1
- 1
src/freedombone-app-xmpp View File

@@ -180,7 +180,7 @@ function upgrade_xmpp {
180 180
 }
181 181
 
182 182
 function backup_local_xmpp {
183
-    source_directory=/var/lib/prosody xmpp
183
+    source_directory=/var/lib/prosody
184 184
     if [ -d $source_directory ]; then
185 185
         dest_directory=xmpp
186 186
         function_check backup_directory_to_usb