Seafile Upgrade Script for CE Raspberry Pi Version

Hello Seafile Community,

I have written some lines of bash to automate my upgrade process of my server version on my single-board computer. I use the Seafile CE on a armv7l architecture (My source is the rasperry pi version from Github).
I would be very happy about positive criticism and general feedback.

Here’s my repo: https://github.com/klangborste/seafile_rpi_bash_upgrader

Hope this helps.

4 Likes

Hi @klangborste can you summarize, point by point, what is doing the seafile_rpi_bash_upgrader, in order to explain to the community?

BTW, I find the script very good and your effort for the seafile community much better! :+1:

Hi @jobenvil
I’m happy other people can use my work, too. :blush: Thanks for your kind words.
There’s also a lot of commenting within the bash script, but I will tell you more now and there will also be an README.md later, in case somebody has a question or maybe want to know something to increase the quality of the script :smirk:

######## variable setup ########
set -o errexit
set -o nounset

grn=$'\e[1;32m'
red=$'\e[1;31m'
end=$'\e[0m'

### the script is written in such a manner that it's important to write a trailing slashs on the variable dir names
https=true #set to true for https usage on your seafile system

“https=true” means that the seafile server is reachable under https.

domain=""

Here you can type in your domain name (IP address should also do it, but it’s not tested)

sea_user=""

User runs the seafile / seahub process

sea_grp=""

Group runs the seafile / seahub process

tmp_dir=""

Temporary directory used for download and unzip the new package of the version

sea_dir=""

Seafile main directory, e.g. /opt/seafile

#log_path="/var/log/"
#log_file="seafile_updater_$(/bin/date -I)"
################################

Logging is not implemented yet. Maybe somebody has an idea. :slightly_smiling_face: I just put it in there so I won’t forget to implement it in the future.

### get the latest release installed on the server ###
serv_ver=$(/usr/bin/curl -s "${ssl_switch}://${domain}/api2/server-info/" | /usr/bin/awk '/version/{print substr($0, 14, length($0)-46)}')
if [ -z "${serv_ver}" ]; then
        echo "${red}error on validate server version!${end}"
        exit 1
fi

### get the latest release available on GitHub ###
git_ver=$(/usr/bin/curl -s "https://api.github.com/repos/haiwen/seafile-rpi/releases/latest" | /usr/bin/awk '/tag_name/{print substr($0, 17, length($0)-18)}')
if [ -z "${git_ver}" ]; then
        echo "${red}error on validate available git version!${end}"
        exit 1
fi

The momentary installed version and the available version from github are pulled by “curl”.

if [ "${serv_ver}" == "${git_ver}" ]; then
        echo "${grn}the newest seafile rpi server version is already installed!${end}"
        exit 1

The script exits itself and write out this green line if there is no new update available.

else
        ### do all the parsing of the versions
        old_ifs="${IFS}"
        IFS='.'

I’m working here with internal field separator for parsing.

        init_git_ver=($git_ver)
        init_serv_ver=($serv_ver)

        git_major=${init_git_ver[0]}
        git_minor=${init_git_ver[1]}
        git_maint=${init_git_ver[2]}

        serv_major=${init_serv_ver[0]}
        serv_minor=${init_serv_ver[1]}
        serv_maint=${init_serv_ver[2]}

Split the version string with arrays in own characters to discriminate major, minor and maint version numbers.

        ### set again back to the original internal field separator
        IFS="${old_ifs}"

        ### check if parsing was successfullfy
        only_num='^[0-9]$'
        for var in $serv_major $serv_minor $serv_maint $git_major $git_minor $git_maint ; do
                if ! [[ $var =~ $only_num ]] ; then
                        echo "${red}variable not a single number - aborted!${end}"
                        exit 1
                fi
        done

Here the script checks if parsing was working correctly. @jobenvil: Do you plan to make major, minor and maint versions bigger then one digit, e.g. “6.10.32”?

        ### if seafile tar-file not already exists
        if [ ! -f "${tmp_dir}seafile-server_${git_ver}_stable_pi.tar.gz" ]; then
                 ### get the latest version as tar.gz file from GitHub
                /usr/bin/wget "https://github.com/haiwen/seafile-rpi/releases/download/v${git_ver}/seafile-server_${git_ver}_stable_pi.tar.gz" -P "${tmp_dir}" || { /bin/echo "${red}download latest server software package failed${end}"; exit 1; }

Get the latest tar.gz package of the latest version with “wget”.

        else
                /bin/echo "${red}seafile latest tar.gz already exists in tmp-dir${end}"
                exit 1
        fi
        ### if seafile directory not already exists
        if [ ! -d "${sea_dir}seafile-server-${git_ver}/" ]; then
                ### untar the archive
                /bin/tar xzf "${tmp_dir}seafile-server_${git_ver}_stable_pi.tar.gz" -C "${tmp_dir}" || { /bin/echo "${red}untar server package failed${end}"; exit 1; }

Using “tar” for unpackaging the tar’ed file.

                ### move file to seafile working directory
                /bin/mv "${tmp_dir}seafile-server-${git_ver}/" "${sea_dir}" || { /bin/echo "${red}move new untar-ed server software package to sea_dir failed${end}"; exit 1; }

Unpacked directory in defined temp directory will be copied to the seafile productive directory.

        else
                /bin/echo "${red}seafile directory already exists${end}"
                exit 1
        fi
        ### setting right folder and file permissions on new folder structure
        /bin/chown -R "${sea_user}":"${sea_grp}" "${sea_dir}seafile-server-${git_ver}"/ || { /bin/echo "${red}chown the new server sea_dir failed${end}"; exit 1; }

Set permissions of user and group recursive for new copied seafile directory structure.

        ### stop all services from seafile before update started
        /bin/systemctl stop seafile.service seahub.service || { /bin/echo "${red}stop the seafile and/or seahub service failed${end}"; exit 1; }

Stop the service threw SystemD, like my system is build up. Here i planned one day to implement SysVInit support and other alternative options, too. Maybe somebody can help out there too?

        ### compare versions if there is a major or minor version upgrade needed
        if [ "${git_major}" -gt "${serv_major}" ] || [ "${git_minor}" -gt "${serv_minor}" ] ; then
                ### execute all needed incremental update scripts
                for path in $(/bin/ls "${sea_dir}seafile-server-${git_ver}"/upgrade/upgrade_*.sh); do
                        script=$(basename "$path")
                        old_ifs="${IFS}"
                        IFS='._'
                        init_script=($script)
                        script_major=${init_script[1]}
                        script_minor=${init_script[2]}
                        IFS="${old_ifs}"
                        ### search for necessary update scripts

Here the routine search for all necessary upgrade scripts needed to be installed. I hope I designed it so that major, minor and maint version upgrades will work independed with the version you start with.

                        if [ "${script_major}" -gt "${serv_major}" ] || [ "${script_major}" -eq "${serv_major}" ] && [ "${script_minor}" -ge "${serv_minor}" ]; then
                                /bin/su - "${sea_user}" -s /bin/bash -c "cd ${sea_dir}seafile-server-${git_ver}/ && upgrade/${script}" || { /bin/echo "${red}update script failed!${end}"; exit 1; }

Install the necessary scripts for major and minor upgrades one by one if needed.

                        fi
                done
        ### compare versions if there is a maint version upgrade needed
        elif [ "${git_maint}" -gt "${serv_maint}" ] ; then
                ### exexute the upgrade script itself
                /bin/su - "${sea_user}" -s /bin/bash -c "cd ${sea_dir}seafile-server-${git_ver} && upgrade/minor-upgrade.sh" || { /bin/echo "${red}update script failed!${end}"; exit 1; }

Execute minor-upgrade script only if last number of version (maint) is higher.

        fi
        ### seafile services start again
        /bin/systemctl start seafile.service seahub.service || { /bin/echo "${red}start the seafile and/or seahub service failed${end}"; exit 1; }

Start seafile and seahub service again over SystemD

        ### verfiy if correct version of seafile server software is installed
        try=0
        until [ $try -ge 5 ]; do
                verify_ver=$(/usr/bin/curl -s --connect-timeout 30 "${ssl_switch}://${domain}/api2/server-info/" | /usr/bin/awk '/version/{print substr($0, 14, length($0)-46)}')
                [ -n "${verify_ver}" ] && break
                try=$((try+1))
                sleep 10
        done
        ver_num='^[0-9].[0-9].[0-9]$'
        if ! [[ $verify_ver =~ $ver_num ]] ; then
                echo "${red}error on validate server version!${end}"
                exit 1
        fi
        if [ "${git_ver}" == "${verify_ver}" ]; then

Test if the API call with “curl” for the version was correct and compare so that the new installed version is fine.

                ### move old seafile version to installed dir as an archive for a possible rollback scenario
                /bin/mv "${sea_dir}seafile-server-${serv_ver}" "${sea_dir}installed/" || { /bin/echo "${red}move to archive dir failed${end}"; exit 1; }
                ### delete old temporary files and archives
                /bin/rm -rf "${tmp_dir}"* || { /bin/echo "${red}remove temporary files and directories failed${end}"; exit 1; }

Do some cleanup jobs. (Move old seafile directory to /installed and remove temporary files)

        else
                echo "${red}a bigger problem is occured, no new version was installed!${end}"

If there’s an error with the validation of server version over the API call this error will occur.

        fi
fi
2 Likes

Looks useful. Thanks for sharing :+1:

@Bernie_O @klangborste I released 6.3.2 for Raspberry Pi / ARM right now. You can test the Seafile Upgrade Script :blush:

Many thanks for the detailed description @klangborste ! I hope someone post his experiences with the upgrade script. From 6.3.1 to 6.3.2 is a good opportunity to check the script since there is no database upgrade.

2 Likes

Thanks for the new raspi-release @jobenvil

The upgrade script upgraded my server without any issues @klangborste

That’s a great new! thanks for testing @Bernie_O!

Nice to know that it helped somebody :slight_smile:
Thanks for your new version @jobenvil
I did also a upgrade to 3.2 today and it worked great.
I tried of course also last minor upgrade with seafile_updater.sh from 6.2.5 to 6.3.1 with success.