confighelper: backup the entire configuraiton

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2022-04-05 15:26:11 -04:00
parent ad00e08d11
commit fc6714b30d
No known key found for this signature in database
GPG Key ID: 7027245FBBDDF59A
2 changed files with 26 additions and 17 deletions

View File

@ -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")

View File

@ -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()