Skip to content

Commit

Permalink
Changing update process because os.execl() doesn't work anymore with …
Browse files Browse the repository at this point in the history
…gunicorn server and its workers
  • Loading branch information
Stefal committed Jun 18, 2024
1 parent 8bfe867 commit a1da082
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 190 deletions.
188 changes: 12 additions & 176 deletions rtkbase_update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ old_version=$4
standard_user=$5
checking=$6

#argument checking
[[ -d "${source_directory}" ]] || { echo 'ERROR! source_directory is not a directory'; exit 1; }
[[ -d "${destination_directory}" ]] || { echo 'ERROR! destination_directory is not a directory'; exit 1; }
[[ -d "${data_dir}" ]] || { echo 'ERROR! data_dir is not a directory'; exit 1; }
[[ "${old_version}" =~ ^[+-]?[0-9]+\.?[0-9]*$ ]] || { echo 'ERROR! wrong type for current_version variable'; exit 1; }
[[ $(id -u "${standard_user}") ]] &>/dev/null || { echo 'ERROR! user does not exist'; exit 1; }
# $checking variable doesn't need to be checked as it is used only if it is set to '--checking'

#store service status before upgrade
str2str_active=$(systemctl is-active str2str_tcp)
str2str_ntrip_A_active=$(systemctl is-active str2str_ntrip_A)
Expand Down Expand Up @@ -93,15 +101,15 @@ insert_rtcm_msg() {
local delay=${4}

new_rtcm=''
if [[ ! $(echo ${text_line} | grep ${msg_to_insert}) ]]
if [[ ! $(echo ${text_line} | grep -q ${msg_to_insert}) ]]
then
for (( i=${msg_to_insert}; i<=${highest_msg}; i++ ))
do
if [[ $(echo ${text_line} | grep $i) ]]
if [[ $(echo ${text_line} | grep -q $i) ]]
then
echo 'insert '${msg_to_insert}' before '$i
new_rtcm=$(echo ${text_line} | sed 's|'"${i}"'|'"${msg_to_insert}${delay}"',&|')
#echo ${new_rtcm}
echo ${new_rtcm}
break
fi
done
Expand All @@ -111,116 +119,6 @@ insert_rtcm_msg() {
fi
}

upd_2.0.2() {
if [[ $(grep -E "^receiver_format='ubx'" ${destination_directory}/settings.conf) ]]
then
# Add -TAJD=1 option to rtcm/ntrip output for ublox receivers
grep -q "^ntrip_receiver_options" ${destination_directory}/settings.conf || \
sed -i "/^rtcm_msg=.*/a ntrip_receiver_options='-TADJ=1'" ${destination_directory}/settings.conf
grep -q "^rtcm_receiver_options" ${destination_directory}/settings.conf || \
sed -i "/^rtcm_svr_msg=.*/a rtcm_receiver_options='-TADJ=1'" ${destination_directory}/settings.conf
fi
#upd_2.0.4
}

upd_2.1.0() {
upd_2.1.1 "$@"
}

upd_2.1.1() {
#stopping services to copy new rtklib app
#systemctl stop rtkbase_web <- don't do that, it will kill this script process.
systemctl stop str2str_tcp
#Get Rtklib 2.4.3 b34 release
wget -qO - https://github.com/tomojitakasu/RTKLIB/archive/v2.4.3-b34.tar.gz | tar -xvz
#Install Rtklib app
make --directory=RTKLIB-2.4.3-b34/app/consapp/str2str/gcc
make --directory=RTKLIB-2.4.3-b34/app/consapp/str2str/gcc install
make --directory=RTKLIB-2.4.3-b34/app/consapp/rtkrcv/gcc
make --directory=RTKLIB-2.4.3-b34/app/consapp/rtkrcv/gcc install
make --directory=RTKLIB-2.4.3-b34/app/consapp/convbin/gcc
make --directory=RTKLIB-2.4.3-b34/app/consapp/convbin/gcc install
#deleting RTKLIB
rm -rf RTKLIB-2.4.3-b34/

#restarting str2str_tcp service
systemctl start str2str_tcp

#update python module
python3 -m pip install -r ${destination_directory}'/web_app/requirements.txt'

#copying new service
file_path=${destination_directory}'/unit/str2str_rtcm_serial.service'
file_name=$(basename ${file_path})
echo copying ${file_name}
sed -e 's|{script_path}|'"$(readlink -f "$2")"'|' -e 's|{user}|'"${standard_user}"'|' ${file_path} > /etc/systemd/system/${file_name}
systemctl daemon-reload

#inserting new rtcm message 1008 and 1033 inside rtcm_msg and rtcm_svr_msg
insert_rtcm_msg $(grep "^rtcm_msg=" ${destination_directory}/settings.conf) 1008 1042 '(10)' && \
sed -i '/^rtcm_msg=/c\'"${new_rtcm}" ${destination_directory}/settings.conf
insert_rtcm_msg $(grep "^rtcm_msg=" ${destination_directory}/settings.conf) 1033 1230 '(10)' && \
sed -i '/^rtcm_msg=/c\'"${new_rtcm}" ${destination_directory}/settings.conf
insert_rtcm_msg $(grep "^rtcm_svr_msg=" ${destination_directory}/settings.conf) 1008 1042 '(10)' && \
sed -i '/^rtcm_svr_msg=/c\'"${new_rtcm}" ${destination_directory}/settings.conf
insert_rtcm_msg $(grep "^rtcm_svr_msg=" ${destination_directory}/settings.conf) 1033 1230 '(10)' && \
sed -i '/^rtcm_svr_msg=/c\'"${new_rtcm}" ${destination_directory}/settings.conf

#restarting runnning rtcm services to send the new messages.
# my bad ! these services are already stopped. the command bellow won't restart them
#systemctl is-active --quiet str2str_ntrip && systemctl restart str2str_ntrip
#systemctl is-active --quiet str2str_rtcm_svr && systemctl restart str2str_rtcm_svr
}

upd_2.2.0() {
#update python module
python3 -m pip install -r ${destination_directory}'/web_app/requirements.txt' --extra-index-url https://www.piwheels.org/simple

#copying new service
file_path=${destination_directory}'/unit/str2str_local_ntrip_caster.service'
file_name=$(basename ${file_path})
echo copying ${file_name}
sed -e 's|{script_path}|'"$(readlink -f "$2")"'|' -e 's|{user}|'"${standard_user}"'|' ${file_path} > /etc/systemd/system/${file_name}

#fix previous wrong path to run_cast.sh inside str2str_rtcm_serial.service during 2.1.1 to 2.2.0 update (/var/tmp/rtkbase/run_cast.sh)
sed -i 's|'/var/tmp/rtkbase'|'"$(readlink -f "$2")"'|' /etc/systemd/system/str2str_rtcm_serial.service

systemctl daemon-reload
}

upd_2.3.0() {
upd_2.3.2 "$@"
}

upd_2.3.1() {
upd_2.3.2 "$@"
}

upd_2.3.2() {
#Add restart condition in gpsd.service
if ! grep -q '^Restart=' /etc/systemd/system/gpsd.service ; then
sed -i '/^ExecStart=.*/a Restart=always' /etc/systemd/system/gpsd.service
sed -i '/^Restart=always.*/a RestartSec=30' /etc/systemd/system/gpsd.service
fi
systemctl daemon-reload
upd_2.3.3 "$@"
}

upd_2.3.3() {
#update gpsd unit file
cp /lib/systemd/system/gpsd.service /etc/systemd/system/gpsd.service
sed -i 's/^After=.*/After=str2str_tcp.service/' /etc/systemd/system/gpsd.service
sed -i '/^# Needed with chrony/d' /etc/systemd/system/gpsd.service
#Add restart condition
grep -qi '^Restart=' /etc/systemd/system/gpsd.service || sed -i '/^ExecStart=.*/a Restart=always' /etc/systemd/system/gpsd.service
grep -qi '^RestartSec=' /etc/systemd/system/gpsd.service || sed -i '/^Restart=always.*/a RestartSec=30' /etc/systemd/system/gpsd.service
#Add ExecStartPre condition to not start gpsd if str2str_tcp is not running. See https://github.com/systemd/systemd/issues/1312
grep -qi '^ExecStartPre=' /etc/systemd/system/gpsd.service || sed -i '/^ExecStart=.*/i ExecStartPre=systemctl is-active str2str_tcp.service' /etc/systemd/system/gpsd.service
systemctl daemon-reload
systemctl restart gpsd
upd_2.3.4 "$@"
}

upgrade_rtklib() {
systemctl stop str2str_tcp
systemctl stop rtkbase_raw2nmea
Expand All @@ -229,69 +127,6 @@ upgrade_rtklib() {
"${destination_directory}"'/tools/install.sh' --user "${standard_user}" --rtklib
}

upd_2.3.4() {
#store service status before stopping str2str
str2str_active=$(systemctl is-active str2str_tcp)
str2str_ntrip_active=$(systemctl is-active str2str_ntrip)
str2str_local_caster=$(systemctl is-active str2str_local_ntrip_caster)
str2str_rtcm=$(systemctl is-active str2str_rtcm_svr)
str2str_serial=$(systemctl is-active str2str_rtcm_serial)
str2str_file=$(systemctl is-active str2str_file)
systemctl stop str2str_tcp
#Add new requirements for v2.4
${destination_directory}'/tools/install.sh' --user "${standard_user}" --dependencies
# Copy new services
systemctl stop str2str_ntrip.service
systemctl disable str2str_ntrip.service
rm /etc/systemd/system/str2str_ntrip.service
systemctl reset-failed
file_path=${destination_directory}'/unit/str2str_ntrip_A.service'
file_name=$(basename ${file_path})
echo copying ${file_name}
sed -e 's|{script_path}|'"$(readlink -f "$2")"'|' -e 's|{user}|'"${standard_user}"'|' ${file_path} > /etc/systemd/system/${file_name}
file_path=${destination_directory}'/unit/str2str_ntrip_B.service'
file_name=$(basename ${file_path})
echo copying ${file_name}
sed -e 's|{script_path}|'"$(readlink -f "$2")"'|' -e 's|{user}|'"${standard_user}"'|' ${file_path} > /etc/systemd/system/${file_name}
systemctl daemon-reload
#update rtklib binary to the one from rtklibexplorer fork.
upgrade_rtklib
#update python module
"${destination_directory}"'/tools/install.sh' --user "${standard_user}" --rtkbase-requirements
# Get F9P firmware release
source <( grep '=' "${destination_directory}"/settings.conf )
if [[ $(python3 "${destination_directory}"/tools/ubxtool -f /dev/"${com_port}" -s ${com_port_settings%%:*} -p MON-VER) =~ 'ZED-F9P' ]]
then
echo 'Get F9P firmware release'
firmware=$(python3 "${destination_directory}"/tools/ubxtool -f /dev/"${com_port}" -s ${com_port_settings%%:*} -p MON-VER | grep 'FWVER' | awk '{print $NF}')
grep -q "^receiver_firmware" ${destination_directory}/settings.conf || \
sed -i "/^receiver_format=.*/a receiver_firmware=\'${firmware}\'" ${destination_directory}/settings.conf
fi
#restart str2str if it was active before upgrading rtklib
[ $str2str_active = 'active' ] && systemctl start str2str_tcp
#replace parameters from str2str_ntrip to str2str_ntrip_A service
sed -i 's/^\[ntrip\]/\[ntrip_A\]/' ${destination_directory}/settings.conf
sed -i 's/^svr_addr=/svr_addr_a=/' ${destination_directory}/settings.conf
sed -i 's/^svr_port=/svr_port_a=/' ${destination_directory}/settings.conf
sed -i 's/^svr_pwd=/svr_pwd_a=/' ${destination_directory}/settings.conf
sed -i 's/^mnt_name=/mnt_name_a=/' ${destination_directory}/settings.conf
sed -i 's/^rtcm_msg=/rtcm_msg_a=/' ${destination_directory}/settings.conf
sed -i 's/^ntrip_receiver_options=/ntrip_a_receiver_options=/' ${destination_directory}/settings.conf

#start str2str_ntrip_A if str2str_ntrip was active before upgrading rtklib.
[ $str2str_ntrip_active = 'active' ] && systemctl enable str2str_ntrip_A && systemctl start str2str_ntrip_A
# restart previously running services
[ $str2str_local_caster = 'active' ] && systemctl start str2str_local_ntrip_caster
[ $str2str_rtcm = 'active' ] && systemctl start str2str_rtcm_svr
[ $str2str_serial = 'active' ] && systemctl start str2str_rtcm_serial
[ $str2str_file = 'active' ] && systemctl start str2str_file
}

upd_2.4b() {
echo 'Calling upd2.3.4'
upd_2.3.4 "$@"
}

upd_2.4.0() {
echo '####################'
echo 'Update from 2.4.0'
Expand Down Expand Up @@ -370,6 +205,7 @@ upd_2.5.0 () {
return 0

}

#check if we can apply the update
#FOR THE OLDER ME -> Don't forget to modify the os detection if there is a 2.5.x release !!!
[[ $checking == '--checking' ]] && check_before_update && exit
Expand Down
12 changes: 12 additions & 0 deletions unit/disabled/rtkbase_update.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=RTKBase update service


[Service]
User=root
Type=oneshot
EnvironmentFile=/home/stephane/gnss_venv/rtkbase/tools/service_args.conf
ExecStart=/var/tmp/rtkbase_update.sh ${ARG1} ${ARG2} ${ARG3} ${ARG4} ${ARG5}

[Install]
WantedBy=multi-user.target
26 changes: 13 additions & 13 deletions web_app/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
#import reach_bluetooth.bluetoothctl
#import reach_bluetooth.tcp_bridge

from threading import Thread
from flask_bootstrap import Bootstrap4
from flask import Flask, render_template, session, request, flash, url_for
from flask import send_file, send_from_directory, redirect, abort
Expand Down Expand Up @@ -282,13 +281,12 @@ def check_update(source_url = None, current_release = None, prerelease=rtkbaseco
# socketio.emit("new release", json.dumps(new_release), namespace="/test")
#return new_release
## test

new_release = {}
source_url = source_url if source_url is not None else "https://api.github.com/repos/stefal/rtkbase/releases"
current_release = current_release if current_release is not None else rtkbaseconfig.get("general", "version").strip("v")
current_release = current_release.split("-beta", 1)[0].split("-alpha", 1)[0].split("-rc", 1)[0].split("b", 1)[0]

try:
try:
response = requests.get(source_url)
response = response.json()
for release in response:
Expand Down Expand Up @@ -357,18 +355,22 @@ def update_rtkbase(update_file=False):

source_path = os.path.join("/var/tmp/", primary_folder)
script_path = os.path.join(source_path, "rtkbase_update.sh")
data_dir = app.config["DOWNLOAD_FOLDER"].split("/")[-1]
current_release = rtkbaseconfig.get("general", "version").strip("v")
standard_user = rtkbaseconfig.get("general", "user")
#launch update verifications
answer = subprocess.run([script_path, source_path, rtkbase_path, app.config["DOWNLOAD_FOLDER"].split("/")[-1], current_release, standard_user, "--checking"], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE)
answer = subprocess.run([script_path, source_path, rtkbase_path, data_dir, current_release, standard_user, "--checking"], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE)
if answer.returncode != 0:
socketio.emit("updating_rtkbase_stopped", json.dumps({"error" : answer.stderr.splitlines()}), namespace="/test")
else : #if ok, launch update script
print("Launch update")
socketio.emit("updating_rtkbase", namespace="/test")
rtk.shutdownBase()
time.sleep(1)
os.execl(script_path, "unused arg0", source_path, rtkbase_path, app.config["DOWNLOAD_FOLDER"].split("/")[-1], current_release, standard_user)
#update_service=ServiceController('rtkbase_update.service')
#update_service.start()
subprocess.Popen([script_path, source_path, rtkbase_path, data_dir, current_release, standard_user])
#os.execl('/var/tmp/rtkbase_update.sh', "unused arg0", source_path, rtkbase_path, data_dir, current_release, standard_user)

def download_update(update_path):
update_archive = "/var/tmp/rtkbase_update.tar.gz"
Expand Down Expand Up @@ -521,14 +523,18 @@ def upload_file():
#### Handle connect/disconnect events ####

@socketio.on("connect", namespace="/test")
def testConnect():
def clientConnect():
global connected_clients
connected_clients += 1
print("Browser client connected")
if rtkbaseconfig.get("general", "updated", fallback="False").lower() == "true":
rtkbaseconfig.remove_option("general", "updated")
rtkbaseconfig.write_file()
socketio.emit("update_successful", json.dumps({"result": 'true'}), namespace="/test")
rtk.sendState()

@socketio.on("disconnect", namespace="/test")
def testDisconnect():
def clientDisconnect():
global connected_clients
connected_clients -=1
print("Browser client disconnected")
Expand Down Expand Up @@ -977,12 +983,6 @@ def arg_parse():
services_list = load_units(services_list)
#Update standard user in settings.conf
update_std_user(services_list)
#check if we run RTKBase for the first time after an update
#and restart some services to let them send the new release number.
if rtkbaseconfig.get("general", "updated", fallback="False").lower() == "true":
restartServices(["ntrip_A", "ntrip_B", "local_ntrip_caster", "rtcm_svr", "rtcm_client", "rtcm_udp_svr", "rtcm_udp_client", "rtcm_serial"])
rtkbaseconfig.remove_option("general", "updated")
rtkbaseconfig.write_file()
#Start a "manager" thread
manager_thread = Thread(target=manager, daemon=True)
manager_thread.start()
Expand Down
14 changes: 13 additions & 1 deletion web_app/static/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -572,9 +572,21 @@ $(document).ready(function () {

socket.on("updating_rtkbase", function() {
$("#updateModal .modal-body").text("Please wait...Updating...");
update_countdown(600, 0);
//update_countdown(1200, 0);
})

socket.on("update_successful", function() {
console.log("update successful");
$("#updateModal .modal-body").text("Update Successful!");
$("#start-update-button").html('Refresh');
$("#start-update-button").prop("disabled", false);
$("#start-update-button").off("click");
$("#start-update-button").on("click", function() {
location.reload();
});
$("#updateModal").modal();
});

function update_countdown(remaining, count) {
if(remaining === 0)
location.reload();
Expand Down

0 comments on commit a1da082

Please sign in to comment.