-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnextcloud-production-update.sh
234 lines (210 loc) · 6.21 KB
/
nextcloud-production-update.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/usr/bin/env bash
APP_NAME=Nextcloud
APP_LOCATION=/var/www/virtual/$USER/html
TMP_LOCATION=~/tmp
VERBOSE_OUTPUT=true
NO_BACKUP=false
NO_INTERACTION=false
ORG=nextcloud # Organisation or GitHub user
REPO=server
GITHUB_API_URL=https://api.github.com/repos/$ORG/$REPO/releases
function ncc
{
php "$APP_LOCATION"/occ "$@"
}
function is_verbose
{
if [[ $VERBOSE_OUTPUT == "true" ]]
then return 0
else return 1
fi
}
function verbose_echo
{
if is_verbose
then echo "$@"
fi
}
function get_current_version
{
ncc --version |
awk '{print $NF}'
}
function get_major_version
{
local complete_version=$1
echo "$complete_version" | awk --field-separator "." '{print $1}'
}
function get_latest_version
{
tag_name=$(curl --silent $GITHUB_API_URL > "$TMP_LOCATION"/github_api_response.json
jq . "$TMP_LOCATION"/github_api_response.json |
jq 'map(select(.tag_name | test("(v'"$MAJOR_VERSION"'.\\d+.\\d+$)")))' |
jq --raw-output '.[0].tag_name')
rm "$TMP_LOCATION"/github_api_response.json
## remove the first character 'v', for example 'v24.0.1' -> '24.0.1' using substring syntax
local version="${tag_name:1}"
echo "$version"
}
function do_update_procedure
{
cd $TMP_LOCATION || exit 1
folder_should_not_exist "$TMP_LOCATION/nextcloud"
verbose_echo "Download latest-$MAJOR_VERSION.zip"
local release_archive="latest-$MAJOR_VERSION.zip"
local signature_file=${release_archive}.asc
curl --progress-bar --remote-name https://download.nextcloud.com/server/releases/"$release_archive"
curl --silent --remote-name https://download.nextcloud.com/server/releases/"$signature_file"
curl --silent --remote-name https://nextcloud.com/nextcloud.asc
gpg --import nextcloud.asc
if ! gpg --verify "$TMP_LOCATION/$signature_file" "$TMP_LOCATION/$release_archive"
then echo "gpg verification results in a BAD signature"; exit 1
fi
verbose_echo "unzip latest-$MAJOR_VERSION.zip"
unzip -q latest-"$MAJOR_VERSION".zip
verbose_echo "Copy config to new version"
cp "$APP_LOCATION"/config/config.php $TMP_LOCATION/nextcloud/config/
if [[ $NO_BACKUP == "true" ]]
then
verbose_echo "Delete $APP_LOCATION"
rm -r "$APP_LOCATION"
else
verbose_echo "Create application backup by moving the directory"
verbose_echo "Destination: ~/nextcloud_application_backup_$CURRENT_VERSION"
folder_should_not_exist ~/nextcloud_application_backup_"$CURRENT_VERSION"
mv "$APP_LOCATION" ~/nextcloud_application_backup_"$CURRENT_VERSION"
fi
verbose_echo "Moving new files to destination"
mv $TMP_LOCATION/nextcloud "$APP_LOCATION"
verbose_echo "Removing setup files"
rm latest-"$MAJOR_VERSION".zip
rm latest-"$MAJOR_VERSION".zip.asc
rm nextcloud.asc
## official docs: (!) this MUST be executed from within your nextcloud installation directory
cd "$APP_LOCATION" || exit 1
ncc upgrade
ncc db:add-missing-primary-keys --no-interaction
ncc db:add-missing-columns --no-interaction
ncc db:add-missing-indices --no-interaction
ncc db:convert-filecache-bigint --no-interaction
ncc app:update --all
## App updates may require additional steps to be done by the `upgrade` command
ncc upgrade
/usr/sbin/restorecon -R "$APP_LOCATION"
if test -f ~/etc/services.d/notify_push.ini
then supervisorctl restart notify_push
fi
}
function folder_should_not_exist
{
local folder_path=$1
if test -d "$folder_path"
then
echo "The folder should not exist at this point in time. Delete or move: $folder_path"
echo "abort update procedure"
exit 1
fi
}
function process_parameters
{
while test $# -gt 0
do
local next_parameter=$1
case $next_parameter in
--no-backup )
NO_BACKUP=true
shift
;;
--no-interaction )
NO_INTERACTION=true
shift
;;
--no-verbose | --quiet )
VERBOSE_OUTPUT=false
shift
;;
* )
echo "$next_parameter can not be processed, exiting script"
exit 1
;;
esac
done
}
## version_lower_than A B
# returns whether A < B
function version_lower_than
{
test "$(echo "$@" |
tr " " "\n" |
sort --version-sort --reverse |
head --lines=1)" != "$1"
}
function is_data_used_in_nextcloud_directory
{
test -d "$APP_LOCATION"/data || return 1
# shellcheck disable=SC2012
directory_elements_counter=$(ls "$APP_LOCATION"/data | wc -l)
## Some older releases provide a data folder with a index.html file
if [[ directory_elements_counter -gt 1 ]]
then return 0
else return 1
fi
}
function yes_no_question
{
local question=$1
while true
do
read -r -p "$question (y/n) " ANSWER
case $ANSWER in
[Yy]* | [Jj]* )
return 0
;;
[Nn]* )
return 1
;;
* ) echo "Please answer yes or no. ";;
esac
done
}
function no_interaction_mode
{
if [[ $NO_INTERACTION == "true" ]]; then return 0; else return 1; fi
}
function set_critical_section { set -o pipefail -o errexit; }
function unset_critical_section { set +o pipefail +o errexit; }
function main
{
set_critical_section
process_parameters "$@"
CURRENT_VERSION=$(get_current_version)
MAJOR_VERSION=$(get_major_version "$CURRENT_VERSION")
LATEST_VERSION=$(get_latest_version)
if is_data_used_in_nextcloud_directory
then
echo "It looks like your data directory is located at the default location inside Nextcloud root"
echo "This is not supported by this update script. Please use an external location."
exit 1
fi
if [ "$CURRENT_VERSION" = "$LATEST_VERSION" ]
then
verbose_echo "Your $APP_NAME $MAJOR_VERSION already has the latest point release."
verbose_echo "You are running $APP_NAME $CURRENT_VERSION"
if is_verbose; then ncc update:check; fi
verbose_echo "If you want to do a major update don't skip major releases."
verbose_echo "Example: 18.0.5 -> 18.0.11 -> 19.0.5 -> 20.0.2"
verbose_echo "Therefore it is recommended to use the built-in updater"
else
if version_lower_than "$CURRENT_VERSION" "$LATEST_VERSION"
then
echo "There is a new point release version available."
echo "Doing update from $CURRENT_VERSION to $LATEST_VERSION"
if no_interaction_mode || yes_no_question "Do you want to start the update procedure?"
then do_update_procedure
fi
fi
fi
unset_critical_section
}
main "$@"
exit $?