Skip to content

Commit 2d20b87

Browse files
committed
BUGFIX:
- A pending DCS update on bot startup did not stop the scheduler from starting the servers.
1 parent 269e2b3 commit 2d20b87

File tree

4 files changed

+107
-92
lines changed

4 files changed

+107
-92
lines changed

core/data/impl/nodeimpl.py

Lines changed: 97 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -745,18 +745,10 @@ async def register(self):
745745
if not self.locals['DCS'].get('cloud', False) or self.master:
746746
self.autoupdate.start()
747747
else:
748-
branch, old_version = await self.get_dcs_branch_and_version()
749-
try:
750-
new_version = await self.get_latest_version(branch)
751-
if new_version:
752-
if parse(old_version) < parse(new_version):
753-
self.log.warning(
754-
f"- Your DCS World version is outdated. Consider upgrading to version {new_version}.")
755-
elif parse(old_version) > parse(new_version):
756-
self.log.critical(
757-
f"- The DCS World version you are using has been rolled back to version {new_version}!")
758-
except Exception:
759-
self.log.warning("Version check failed, possible auth-server outage.")
748+
new_version = await self.is_dcs_update_available()
749+
if new_version:
750+
self.log.warning(
751+
f"- Your DCS World version is outdated. Consider upgrading to version {new_version}.")
760752

761753
async def unregister(self):
762754
async with self.cpool.connection() as conn:
@@ -854,7 +846,7 @@ async def check_nodes():
854846
self.suspect[node.name] = node
855847

856848
try:
857-
# do not do any checks, if we are supposed to shut down
849+
# do not do any checks if we are supposed to shut down
858850
if self.node.is_shutdown.is_set():
859851
return self.master
860852

@@ -1032,87 +1024,96 @@ async def rename_server(self, server: Server, new_name: str):
10321024
if server.is_remote:
10331025
server.name = new_name
10341026

1035-
@tasks.loop(minutes=5.0)
1036-
async def autoupdate(self):
1027+
async def is_dcs_update_available(self) -> Optional[str]:
1028+
branch, old_version = await self.get_dcs_branch_and_version()
1029+
try:
1030+
new_version = await self.get_latest_version(branch)
1031+
if not new_version:
1032+
self.log.debug("DCS update check failed, no version received from ED.")
1033+
elif parse(old_version) < parse(new_version):
1034+
return new_version
1035+
elif new_version < old_version:
1036+
self.log.warning(
1037+
f"Your current DCS version {old_version} has been reverted to version {new_version}."
1038+
f"You might want to manually downgrade the version.")
1039+
except aiohttp.ClientError:
1040+
self.log.warning("DCS update check failed, possible server outage at ED.")
1041+
return None
1042+
1043+
async def do_dcs_update(self, new_version: str):
10371044
from services.bot import BotService
10381045
from services.servicebus import ServiceBus
10391046

1040-
# don't run, if an update is currently running
1047+
self.log.info('A new version of DCS World is available. Auto-updating ...')
1048+
rc = await self.update(warn_times=[300, 120, 60], version=new_version)
1049+
if rc == 0:
1050+
bus = ServiceRegistry.get(ServiceBus)
1051+
await bus.send_to_node({
1052+
"command": "rpc",
1053+
"service": BotService.__name__,
1054+
"method": "audit",
1055+
"params": {
1056+
"message": f"DCS World updated to version {new_version} on node {self.node.name}."
1057+
}
1058+
})
1059+
if isinstance(self.locals['DCS'].get('autoupdate'), dict):
1060+
config = self.locals['DCS'].get('autoupdate')
1061+
embed = discord.Embed(
1062+
colour=discord.Colour.blue(),
1063+
title=config.get(
1064+
'title', 'DCS has been updated to version {}!').format(new_version),
1065+
url=f"https://www.digitalcombatsimulator.com/en/news/changelog/stable/{new_version}/")
1066+
embed.description = config.get('description', 'The following servers have been updated:')
1067+
embed.set_thumbnail(url="https://forum.dcs.world/uploads/monthly_2023_10/"
1068+
"icons_4.png.f3290f2c17710d5ab3d0ec5f1bf99064.png")
1069+
embed.add_field(name=_('Server'),
1070+
value='\n'.join([
1071+
f'- {x.display_name}' for x in bus.servers.values() if not x.is_remote
1072+
]), inline=False)
1073+
embed.set_footer(
1074+
text=config.get('footer', 'Please make sure you update your DCS client to join!'))
1075+
params = {
1076+
"channel": config['channel'],
1077+
"embed": embed.to_dict()
1078+
}
1079+
if 'mention' in config:
1080+
params['mention'] = config['mention']
1081+
await bus.send_to_node({
1082+
"command": "rpc",
1083+
"service": BotService.__name__,
1084+
"method": "send_message",
1085+
"params": params
1086+
})
1087+
else:
1088+
if rc == 2:
1089+
message = f"DCS World update on node {self.name} was aborted (check disk space)!"
1090+
elif rc in [3, 350]:
1091+
message = (f"DCS World has been updated to version {new_version} on node {self.name}.\n"
1092+
f"The updater has requested a **reboot** of the system!")
1093+
else:
1094+
message = (f"DCS World could not be updated on node {self.name} due to an error ({rc}): "
1095+
f"{utils.get_win32_error_message(rc)}!")
1096+
self.log.error(message)
1097+
await ServiceRegistry.get(ServiceBus).send_to_node({
1098+
"command": "rpc",
1099+
"service": BotService.__name__,
1100+
"method": "alert",
1101+
"params": {
1102+
"title": "DCS Update Issue",
1103+
"message": message
1104+
}
1105+
})
1106+
1107+
@tasks.loop(minutes=5.0)
1108+
async def autoupdate(self):
1109+
# don't run if an update is currently running
10411110
if self.update_pending:
10421111
return
10431112
try:
1044-
try:
1045-
branch, old_version = await self.get_dcs_branch_and_version()
1046-
new_version = await self.get_latest_version(branch)
1047-
if not new_version:
1048-
self.log.debug("DCS update check failed, no version reveived from ED.")
1049-
return
1050-
except aiohttp.ClientError:
1051-
self.log.warning("DCS update check failed, possible server outage at ED.")
1052-
return
1053-
if parse(old_version) < parse(new_version):
1054-
self.log.info('A new version of DCS World is available. Auto-updating ...')
1055-
rc = await self.update([300, 120, 60])
1056-
if rc == 0:
1057-
bus = ServiceRegistry.get(ServiceBus)
1058-
await bus.send_to_node({
1059-
"command": "rpc",
1060-
"service": BotService.__name__,
1061-
"method": "audit",
1062-
"params": {
1063-
"message": f"DCS World updated to version {new_version} on node {self.node.name}."
1064-
}
1065-
})
1066-
if isinstance(self.locals['DCS'].get('autoupdate'), dict):
1067-
config = self.locals['DCS'].get('autoupdate')
1068-
embed = discord.Embed(
1069-
colour=discord.Colour.blue(),
1070-
title=config.get(
1071-
'title', 'DCS has been updated to version {}!').format(new_version),
1072-
url=f"https://www.digitalcombatsimulator.com/en/news/changelog/stable/{new_version}/")
1073-
embed.description = config.get('description', 'The following servers have been updated:')
1074-
embed.set_thumbnail(url="https://forum.dcs.world/uploads/monthly_2023_10/"
1075-
"icons_4.png.f3290f2c17710d5ab3d0ec5f1bf99064.png")
1076-
embed.add_field(name=_('Server'),
1077-
value='\n'.join([
1078-
f'- {x.display_name}' for x in bus.servers.values() if not x.is_remote
1079-
]), inline=False)
1080-
embed.set_footer(
1081-
text=config.get('footer', 'Please make sure you update your DCS client to join!'))
1082-
params = {
1083-
"channel": config['channel'],
1084-
"embed": embed.to_dict()
1085-
}
1086-
if 'mention' in config:
1087-
params['mention'] = config['mention']
1088-
await bus.send_to_node({
1089-
"command": "rpc",
1090-
"service": BotService.__name__,
1091-
"method": "send_message",
1092-
"params": params
1093-
})
1094-
else:
1095-
if rc == 2:
1096-
message = f"DCS World update on node {self.name} was aborted (check disk space)!"
1097-
elif rc in [3, 350]:
1098-
message = (f"DCS World has been updated to version {new_version} on node {self.name}.\n"
1099-
f"The updater has requested a **reboot** of the system!")
1100-
else:
1101-
message = (f"DCS World could not be updated on node {self.name} due to an error ({rc}): "
1102-
f"{utils.get_win32_error_message(rc)}!")
1103-
self.log.error(message)
1104-
await ServiceRegistry.get(ServiceBus).send_to_node({
1105-
"command": "rpc",
1106-
"service": BotService.__name__,
1107-
"method": "alert",
1108-
"params": {
1109-
"title": "DCS Update Issue",
1110-
"message": message
1111-
}
1112-
})
1113-
elif new_version < old_version:
1114-
self.log.warning(f"Your current DCS version {old_version} has been reverted to version {new_version}."
1115-
f"You might want to manually downgrade the version.")
1113+
version = await self.is_dcs_update_available()
1114+
if version:
1115+
await self.do_dcs_update(version)
1116+
11161117
except aiohttp.ClientError as ex:
11171118
self.log.warning(ex)
11181119
except Exception as ex:
@@ -1122,13 +1123,21 @@ async def autoupdate(self):
11221123
async def before_autoupdate(self):
11231124
from services.servicebus import ServiceBus
11241125

1126+
# make sure the Scheduler does not interact
1127+
self.update_pending = True
11251128
# wait for all servers to be in a proper state
11261129
while True:
11271130
bus = ServiceRegistry.get(ServiceBus)
11281131
if bus and bus.servers and all(server.status != Status.UNREGISTERED for server in bus.servers.values()):
11291132
break
11301133
await asyncio.sleep(1)
11311134

1135+
# check for updates
1136+
new_version = await self.is_dcs_update_available()
1137+
if new_version:
1138+
await self.do_dcs_update(new_version)
1139+
self.update_pending = False
1140+
11321141
async def add_instance(self, name: str, *, template: str = "") -> "Instance":
11331142
from services.servicebus import ServiceBus
11341143

core/plugin.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import aiofiles
34
import asyncio
45
import discord.errors
56
import inspect
@@ -337,10 +338,10 @@ async def _init_db(self) -> bool:
337338
if cursor.rowcount == 0:
338339
tables_file = f'./plugins/{self.plugin_name}/db/tables.sql'
339340
if os.path.exists(tables_file):
340-
with open(tables_file, mode='r') as tables_sql:
341+
async with aiofiles.open(tables_file, mode='r') as tables_sql:
341342
for query in [
342343
stmt.strip()
343-
for stmt in sqlparse.split(tables_sql.read(), encoding='utf-8')
344+
for stmt in sqlparse.split(await tables_sql.read(), encoding='utf-8')
344345
if stmt.strip()
345346
]:
346347
self.log.debug(query.rstrip())
@@ -359,10 +360,10 @@ async def _init_db(self) -> bool:
359360
while parse(installed) < parse(self.plugin_version):
360361
updates_file = f'./plugins/{self.plugin_name}/db/update_v{installed}.sql'
361362
if os.path.exists(updates_file):
362-
with open(updates_file, mode='r') as updates_sql:
363+
async with aiofiles.open(updates_file, mode='r') as updates_sql:
363364
for query in [
364365
stmt.strip()
365-
for stmt in sqlparse.split(updates_sql.read(), encoding='utf-8')
366+
for stmt in sqlparse.split(await updates_sql.read(), encoding='utf-8')
366367
if stmt.strip()
367368
]:
368369
self.log.debug(query.rstrip())

plugins/scheduler/commands.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@ def check_action(rconf: dict):
453453

454454
@tasks.loop(minutes=1.0)
455455
async def check_state(self):
456+
# do not change the state if an update is pending
457+
if self.node.update_pending:
458+
return
459+
456460
next_startup = 0
457461
startup_delay = self.get_config().get('startup_delay', 10)
458462
for server_name, server in self.bot.servers.items():

services/servicebus/service.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ async def register_local_servers(self):
225225
await self.send_init(server)
226226
if server.maintenance:
227227
self.log.warning(f' => Maintenance mode enabled for Server {server.name}')
228+
228229
if utils.is_open(server.instance.dcs_host, server.instance.webgui_port):
229230
calls[server.name] = asyncio.create_task(
230231
server.send_to_dcs_sync({"command": "registerDCSServer"}, timeout)

0 commit comments

Comments
 (0)