update_manager: add "persistent_files" option to web clients

This allows clients to define files that will persist through an update, useful if the client has some sort of static configuration.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Arksine 2021-01-30 20:42:47 -05:00
parent 943b78195b
commit 39334d1098
1 changed files with 33 additions and 7 deletions

View File

@ -13,6 +13,7 @@ import zipfile
import io import io
import asyncio import asyncio
import time import time
import tempfile
import tornado.gen import tornado.gen
from tornado.ioloop import IOLoop, PeriodicCallback from tornado.ioloop import IOLoop, PeriodicCallback
from tornado.httpclient import AsyncHTTPClient from tornado.httpclient import AsyncHTTPClient
@ -839,6 +840,16 @@ class WebUpdater:
self.name = config.get_name().split()[-1] self.name = config.get_name().split()[-1]
self.path = os.path.realpath(os.path.expanduser( self.path = os.path.realpath(os.path.expanduser(
config.get("path"))) config.get("path")))
self.persistent_files = []
pfiles = config.get('persistent_files', None)
if pfiles is not None:
self.persistent_files = [pf.strip().strip("/") for pf in
pfiles.split("\n") if pf.strip()]
if ".version" in self.persistent_files:
raise config.error(
"Invalid value for option 'persistent_files': "
"'.version' can not be persistent")
self.version = self.remote_version = self.dl_url = "?" self.version = self.remote_version = self.dl_url = "?"
self.etag = None self.etag = None
self.init_evt = Event() self.init_evt = Event()
@ -914,13 +925,28 @@ class WebUpdater:
if self.version == self.remote_version: if self.version == self.remote_version:
# Already up to date # Already up to date
return return
if os.path.isdir(self.path): with tempfile.TemporaryDirectory(
shutil.rmtree(self.path) suffix=self.name, prefix="client") as tempdir:
os.mkdir(self.path) if os.path.isdir(self.path):
self.notify_update_response(f"Downloading Client: {self.name}") # find and move persistent files
archive = await self.umgr.http_download_request(self.dl_url) for fname in os.listdir(self.path):
with zipfile.ZipFile(io.BytesIO(archive)) as zf: src_path = os.path.join(self.path, fname)
zf.extractall(self.path) if fname in self.persistent_files:
dest_dir = os.path.dirname(os.path.join(tempdir, fname))
os.makedirs(dest_dir, exist_ok=True)
shutil.move(src_path, dest_dir)
shutil.rmtree(self.path)
os.mkdir(self.path)
self.notify_update_response(f"Downloading Client: {self.name}")
archive = await self.umgr.http_download_request(self.dl_url)
with zipfile.ZipFile(io.BytesIO(archive)) as zf:
zf.extractall(self.path)
# Move temporary files back into
for fname in os.listdir(tempdir):
src_path = os.path.join(tempdir, fname)
dest_dir = os.path.dirname(os.path.join(self.path, fname))
os.makedirs(dest_dir, exist_ok=True)
shutil.move(src_path, dest_dir)
self.version = self.remote_version self.version = self.remote_version
version_path = os.path.join(self.path, ".version") version_path = os.path.join(self.path, ".version")
if not os.path.exists(version_path): if not os.path.exists(version_path):