confighelper: backup the entire configuraiton
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
ad00e08d11
commit
fc6714b30d
|
@ -8,8 +8,6 @@ from __future__ import annotations
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
import hashlib
|
import hashlib
|
||||||
import shutil
|
|
||||||
import filecmp
|
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
|
@ -34,6 +32,7 @@ if TYPE_CHECKING:
|
||||||
from moonraker import Server
|
from moonraker import Server
|
||||||
from components.gpio import GpioFactory, GpioOutputPin
|
from components.gpio import GpioFactory, GpioOutputPin
|
||||||
from components.template import TemplateFactory, JinjaTemplate
|
from components.template import TemplateFactory, JinjaTemplate
|
||||||
|
from io import TextIOWrapper
|
||||||
_T = TypeVar("_T")
|
_T = TypeVar("_T")
|
||||||
ConfigVal = Union[None, int, float, bool, str, dict, list]
|
ConfigVal = Union[None, int, float, bool, str, dict, list]
|
||||||
|
|
||||||
|
@ -453,6 +452,30 @@ class ConfigHelper:
|
||||||
"failed to load. In the future this will result "
|
"failed to load. In the future this will result "
|
||||||
"in a startup error.")
|
"in a startup error.")
|
||||||
|
|
||||||
|
def create_backup(self):
|
||||||
|
cfg_path = self.server.get_app_args()["config_file"]
|
||||||
|
cfg = pathlib.Path(cfg_path).expanduser().resolve()
|
||||||
|
backup = cfg.parent.joinpath(f".{cfg.name}.bkp")
|
||||||
|
backup_fp: Optional[TextIOWrapper] = None
|
||||||
|
try:
|
||||||
|
if backup.exists():
|
||||||
|
cfg_mtime: int = 0
|
||||||
|
for cfg_fname in set(self.file_section_map.keys()):
|
||||||
|
cfg = pathlib.Path(cfg_fname)
|
||||||
|
cfg_mtime = max(cfg_mtime, cfg.stat().st_mtime_ns)
|
||||||
|
backup_mtime = backup.stat().st_mtime_ns
|
||||||
|
if backup_mtime >= cfg_mtime:
|
||||||
|
# Backup already exists and is current
|
||||||
|
return
|
||||||
|
backup_fp = backup.open("w")
|
||||||
|
self.config.write(backup_fp)
|
||||||
|
logging.info(f"Backing up last working configuration to '{backup}'")
|
||||||
|
except Exception:
|
||||||
|
logging.exception("Failed to create a backup")
|
||||||
|
finally:
|
||||||
|
if backup_fp is not None:
|
||||||
|
backup_fp.close()
|
||||||
|
|
||||||
def get_configuration(
|
def get_configuration(
|
||||||
server: Server, app_args: Dict[str, Any]
|
server: Server, app_args: Dict[str, Any]
|
||||||
) -> ConfigHelper:
|
) -> ConfigHelper:
|
||||||
|
@ -515,18 +538,6 @@ def parse_config_file(
|
||||||
config_files.extend(paths)
|
config_files.extend(paths)
|
||||||
return file_sections
|
return file_sections
|
||||||
|
|
||||||
def backup_config(cfg_path: str) -> None:
|
|
||||||
cfg = pathlib.Path(cfg_path).expanduser().resolve()
|
|
||||||
backup = cfg.parent.joinpath(f".{cfg.name}.bkp")
|
|
||||||
try:
|
|
||||||
if backup.exists() and filecmp.cmp(cfg, backup):
|
|
||||||
# Backup already exists and is current
|
|
||||||
return
|
|
||||||
shutil.copy2(cfg, backup)
|
|
||||||
logging.info(f"Backing up last working configuration to '{backup}'")
|
|
||||||
except Exception:
|
|
||||||
logging.exception("Failed to create a backup")
|
|
||||||
|
|
||||||
def find_config_backup(cfg_path: str) -> Optional[str]:
|
def find_config_backup(cfg_path: str) -> Optional[str]:
|
||||||
cfg = pathlib.Path(cfg_path).expanduser().resolve()
|
cfg = pathlib.Path(cfg_path).expanduser().resolve()
|
||||||
backup = cfg.parent.joinpath(f".{cfg.name}.bkp")
|
backup = cfg.parent.joinpath(f".{cfg.name}.bkp")
|
||||||
|
|
|
@ -160,9 +160,7 @@ class Server:
|
||||||
await asyncio.gather(*optional_comps)
|
await asyncio.gather(*optional_comps)
|
||||||
|
|
||||||
if not self.warnings:
|
if not self.warnings:
|
||||||
cfg_file = self.app_args['config_file']
|
await self.event_loop.run_in_thread(self.config.create_backup)
|
||||||
await self.event_loop.run_in_thread(
|
|
||||||
confighelper.backup_config, cfg_file)
|
|
||||||
|
|
||||||
if start_server:
|
if start_server:
|
||||||
await self.start_server()
|
await self.start_server()
|
||||||
|
|
Loading…
Reference in New Issue