update_manager: refactor AppDeloy class
Don't require the `app_params` argument, instead dynamically generate the configuration from a dict. This simiplifies AppDeploy initialization as the internally generated configurations can be read in the same way as those supplied in moonraker.conf. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
54081612ca
commit
e9e86c3042
|
@ -8,7 +8,6 @@ from __future__ import annotations
|
|||
import pathlib
|
||||
import shutil
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
from .base_deploy import BaseDeploy
|
||||
|
||||
|
@ -28,7 +27,7 @@ if TYPE_CHECKING:
|
|||
|
||||
CHANNEL_TO_TYPE = {
|
||||
"stable": "zip",
|
||||
"beta": "zip_beta",
|
||||
"beta": "git_repo",
|
||||
"dev": "git_repo"
|
||||
}
|
||||
TYPE_TO_CHANNEL = {
|
||||
|
@ -38,29 +37,17 @@ TYPE_TO_CHANNEL = {
|
|||
}
|
||||
|
||||
class AppDeploy(BaseDeploy):
|
||||
def __init__(self,
|
||||
config: ConfigHelper,
|
||||
cmd_helper: CommandHelper,
|
||||
app_params: Optional[Dict[str, Any]]
|
||||
) -> None:
|
||||
def __init__(self, config: ConfigHelper, cmd_helper: CommandHelper) -> None:
|
||||
super().__init__(config, cmd_helper, prefix="Application")
|
||||
self.config = config
|
||||
self.app_params = app_params
|
||||
cfg_hash = self._calc_config_hash()
|
||||
super().__init__(config, cmd_helper, prefix="Application",
|
||||
cfg_hash=cfg_hash)
|
||||
self.debug = self.cmd_helper.is_debug_enabled()
|
||||
if app_params is not None:
|
||||
self.channel: str = app_params['channel']
|
||||
self.path: pathlib.Path = pathlib.Path(
|
||||
app_params['path']).expanduser().resolve()
|
||||
executable: Optional[str] = app_params['executable']
|
||||
self.type = CHANNEL_TO_TYPE[self.channel]
|
||||
else:
|
||||
self.type = config.get('type')
|
||||
self.channel = TYPE_TO_CHANNEL[self.type]
|
||||
self.path = pathlib.Path(
|
||||
config.get('path')).expanduser().resolve()
|
||||
executable = config.get('env', None)
|
||||
self.type = config.get('type')
|
||||
self.channel = config.get(
|
||||
"channel", TYPE_TO_CHANNEL[self.type]
|
||||
)
|
||||
self.path = pathlib.Path(
|
||||
config.get('path')).expanduser().resolve()
|
||||
executable = config.get('env', None)
|
||||
if self.channel not in CHANNEL_TO_TYPE.keys():
|
||||
raise config.error(
|
||||
f"Invalid Channel '{self.channel}' for config "
|
||||
|
@ -136,15 +123,6 @@ class AppDeploy(BaseDeploy):
|
|||
self._is_valid = storage.get('is_valid', False)
|
||||
return storage
|
||||
|
||||
def _calc_config_hash(self) -> str:
|
||||
cfg_hash = self.config.get_hash()
|
||||
if self.app_params is None:
|
||||
return cfg_hash.hexdigest()
|
||||
else:
|
||||
app_bytes = json.dumps(self.app_params).encode()
|
||||
cfg_hash.update(app_bytes)
|
||||
return cfg_hash.hexdigest()
|
||||
|
||||
def _verify_path(self,
|
||||
config: ConfigHelper,
|
||||
option: str,
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# Moonraker/Klipper update configuration
|
||||
#
|
||||
# Copyright (C) 2022 Eric Callahan <arksine.code@gmail.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import copy
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Dict
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from confighelper import ConfigHelper
|
||||
from components.database import MoonrakerDatabase
|
||||
|
||||
MOONRAKER_PATH = os.path.normpath(os.path.join(
|
||||
os.path.dirname(__file__), "../../.."))
|
||||
KLIPPER_DEFAULT_PATH = os.path.expanduser("~/klipper")
|
||||
KLIPPER_DEFAULT_EXEC = os.path.expanduser("~/klippy-env/bin/python")
|
||||
|
||||
BASE_CONFIG: Dict[str, Dict[str, str]] = {
|
||||
"moonraker": {
|
||||
"origin": "https://github.com/arksine/moonraker.git",
|
||||
"requirements": "scripts/moonraker-requirements.txt",
|
||||
"venv_args": "-p python3",
|
||||
"install_script": "scripts/install-moonraker.sh",
|
||||
"host_repo": "arksine/moonraker",
|
||||
"env": sys.executable,
|
||||
"path": MOONRAKER_PATH,
|
||||
"managed_services": "moonraker"
|
||||
},
|
||||
"klipper": {
|
||||
"moved_origin": "https://github.com/kevinoconnor/klipper.git",
|
||||
"origin": "https://github.com/Klipper3d/klipper.git",
|
||||
"requirements": "scripts/klippy-requirements.txt",
|
||||
"venv_args": "-p python2",
|
||||
"install_script": "scripts/install-octopi.sh",
|
||||
"host_repo": "arksine/moonraker",
|
||||
"managed_services": "klipper"
|
||||
}
|
||||
}
|
||||
|
||||
def get_base_configuration(config: ConfigHelper, channel: str) -> ConfigHelper:
|
||||
server = config.get_server()
|
||||
base_cfg = copy.deepcopy(BASE_CONFIG)
|
||||
app_type = "zip" if channel == "stable" else "git_repo"
|
||||
base_cfg["moonraker"]["channel"] = channel
|
||||
base_cfg["moonraker"]["type"] = app_type
|
||||
base_cfg["klipper"]["channel"] = channel
|
||||
base_cfg["klipper"]["type"] = app_type
|
||||
db: MoonrakerDatabase = server.lookup_component('database')
|
||||
base_cfg["klipper"]["path"] = db.get_item(
|
||||
"moonraker", "update_manager.klipper_path", KLIPPER_DEFAULT_PATH
|
||||
).result()
|
||||
base_cfg["klipper"]["env"] = db.get_item(
|
||||
"moonraker", "update_manager.klipper_exec", KLIPPER_DEFAULT_EXEC
|
||||
).result()
|
||||
return config.read_supplemental_dict(base_cfg)
|
|
@ -28,12 +28,8 @@ if TYPE_CHECKING:
|
|||
from .update_manager import CommandHelper
|
||||
|
||||
class GitDeploy(AppDeploy):
|
||||
def __init__(self,
|
||||
config: ConfigHelper,
|
||||
cmd_helper: CommandHelper,
|
||||
app_params: Optional[Dict[str, Any]] = None
|
||||
) -> None:
|
||||
super().__init__(config, cmd_helper, app_params)
|
||||
def __init__(self, config: ConfigHelper, cmd_helper: CommandHelper) -> None:
|
||||
super().__init__(config, cmd_helper)
|
||||
self.repo = GitRepo(cmd_helper, self.path, self.name,
|
||||
self.origin, self.moved_origin)
|
||||
if self.type != 'git_repo':
|
||||
|
@ -41,7 +37,7 @@ class GitDeploy(AppDeploy):
|
|||
|
||||
@staticmethod
|
||||
async def from_application(app: AppDeploy) -> GitDeploy:
|
||||
new_app = GitDeploy(app.config, app.cmd_helper, app.app_params)
|
||||
new_app = GitDeploy(app.config, app.cmd_helper)
|
||||
await new_app.reinstall()
|
||||
return new_app
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# Supplemental configuration for Moonraker's Update Manager
|
||||
# component. This file should not be modified.
|
||||
|
||||
[update_manager moonraker]
|
||||
origin: https://github.com/arksine/moonraker.git
|
||||
requirements: scripts/moonraker-requirements.txt
|
||||
venv_args: -p python3
|
||||
install_script: scripts/install-moonraker.sh
|
||||
host_repo: arksine/moonraker
|
||||
|
||||
[update_manager klipper]
|
||||
moved_origin: https://github.com/kevinoconnor/klipper.git
|
||||
origin: https://github.com/Klipper3d/klipper.git
|
||||
requirements: scripts/klippy-requirements.txt
|
||||
venv_args: -p python2
|
||||
install_script: scripts/install-octopi.sh
|
||||
host_repo: arksine/moonraker
|
|
@ -9,13 +9,13 @@ import asyncio
|
|||
import os
|
||||
import pathlib
|
||||
import logging
|
||||
import sys
|
||||
import shutil
|
||||
import zipfile
|
||||
import time
|
||||
import tempfile
|
||||
import re
|
||||
from thirdparty.packagekit import enums as PkEnum
|
||||
from . import base_config
|
||||
from .base_deploy import BaseDeploy
|
||||
from .app_deploy import AppDeploy
|
||||
from .git_deploy import GitDeploy
|
||||
|
@ -51,13 +51,6 @@ if TYPE_CHECKING:
|
|||
from dbus_next.aio import ProxyInterface
|
||||
JsonType = Union[List[Any], Dict[str, Any]]
|
||||
|
||||
MOONRAKER_PATH = os.path.normpath(os.path.join(
|
||||
os.path.dirname(__file__), "../../.."))
|
||||
SUPPLEMENTAL_CFG_PATH = os.path.join(
|
||||
os.path.dirname(__file__), "update_manager.conf")
|
||||
KLIPPER_DEFAULT_PATH = os.path.expanduser("~/klipper")
|
||||
KLIPPER_DEFAULT_EXEC = os.path.expanduser("~/klippy-env/bin/python")
|
||||
|
||||
# Check To see if Updates are necessary each hour
|
||||
UPDATE_REFRESH_INTERVAL = 3600.
|
||||
# Perform auto refresh no later than 4am
|
||||
|
@ -73,46 +66,30 @@ class UpdateManager:
|
|||
def __init__(self, config: ConfigHelper) -> None:
|
||||
self.server = config.get_server()
|
||||
self.event_loop = self.server.get_event_loop()
|
||||
self.app_config = config.read_supplemental_config(
|
||||
SUPPLEMENTAL_CFG_PATH)
|
||||
auto_refresh_enabled = config.getboolean('enable_auto_refresh', False)
|
||||
self.channel = config.get('channel', "dev")
|
||||
if self.channel not in ["dev", "beta"]:
|
||||
raise config.error(
|
||||
f"Unsupported channel '{self.channel}' in section"
|
||||
" [update_manager]")
|
||||
self.app_config = base_config.get_base_configuration(
|
||||
config, self.channel
|
||||
)
|
||||
auto_refresh_enabled = config.getboolean('enable_auto_refresh', False)
|
||||
self.cmd_helper = CommandHelper(config)
|
||||
self.updaters: Dict[str, BaseDeploy] = {}
|
||||
if config.getboolean('enable_system_updates', True):
|
||||
self.updaters['system'] = PackageDeploy(config, self.cmd_helper)
|
||||
db: DBComp = self.server.lookup_component('database')
|
||||
kpath = db.get_item("moonraker", "update_manager.klipper_path",
|
||||
KLIPPER_DEFAULT_PATH).result()
|
||||
kenv_path = db.get_item("moonraker", "update_manager.klipper_exec",
|
||||
KLIPPER_DEFAULT_EXEC).result()
|
||||
self.updaters['moonraker'] = get_deploy_class(MOONRAKER_PATH)(
|
||||
self.app_config[f"update_manager moonraker"], self.cmd_helper,
|
||||
{
|
||||
'channel': self.channel,
|
||||
'path': MOONRAKER_PATH,
|
||||
'executable': sys.executable
|
||||
}
|
||||
)
|
||||
mcfg = self.app_config["moonraker"]
|
||||
kcfg = self.app_config["klipper"]
|
||||
mclass = get_deploy_class(mcfg.get("path"))
|
||||
self.updaters['moonraker'] = mclass(mcfg, self.cmd_helper)
|
||||
kclass = BaseDeploy
|
||||
if (
|
||||
os.path.exists(kpath) and
|
||||
os.path.exists(kenv_path)
|
||||
os.path.exists(kcfg.get("path")) and
|
||||
os.path.exists(kcfg.get("env"))
|
||||
):
|
||||
self.updaters['klipper'] = get_deploy_class(kpath)(
|
||||
self.app_config[f"update_manager klipper"], self.cmd_helper,
|
||||
{
|
||||
'channel': self.channel,
|
||||
'path': kpath,
|
||||
'executable': kenv_path
|
||||
}
|
||||
)
|
||||
else:
|
||||
self.updaters['klipper'] = BaseDeploy(
|
||||
self.app_config[f"update_manager klipper"], self.cmd_helper)
|
||||
kclass = get_deploy_class(kcfg.get("path"))
|
||||
self.updaters['klipper'] = kclass(kcfg, self.cmd_helper)
|
||||
|
||||
# TODO: The below check may be removed when invalid config options
|
||||
# raise a config error.
|
||||
|
@ -135,8 +112,8 @@ class UpdateManager:
|
|||
self.updaters[name] = WebClientDeploy(cfg, self.cmd_helper)
|
||||
elif client_type in ["git_repo", "zip", "zip_beta"]:
|
||||
path = os.path.expanduser(cfg.get('path'))
|
||||
self.updaters[name] = get_deploy_class(path)(
|
||||
cfg, self.cmd_helper)
|
||||
dclass = get_deploy_class(path)
|
||||
self.updaters[name] = dclass(cfg, self.cmd_helper)
|
||||
else:
|
||||
raise config.error(
|
||||
f"Invalid type '{client_type}' for section [{section}]")
|
||||
|
@ -215,14 +192,12 @@ class UpdateManager:
|
|||
db: DBComp = self.server.lookup_component('database')
|
||||
db.insert_item("moonraker", "update_manager.klipper_path", kpath)
|
||||
db.insert_item("moonraker", "update_manager.klipper_exec", executable)
|
||||
kcfg = self.app_config["klipper"]
|
||||
kcfg.set_option("path", kpath)
|
||||
kcfg.set_option("env", executable)
|
||||
need_notification = not isinstance(kupdater, AppDeploy)
|
||||
self.updaters['klipper'] = get_deploy_class(kpath)(
|
||||
self.app_config[f"update_manager klipper"], self.cmd_helper,
|
||||
{
|
||||
'channel': self.channel,
|
||||
'path': kpath,
|
||||
'executable': executable
|
||||
})
|
||||
kclass = get_deploy_class(kpath)
|
||||
self.updaters['klipper'] = kclass(kcfg, self.cmd_helper)
|
||||
async with self.cmd_request_lock:
|
||||
umdb = self.cmd_helper.get_umdb()
|
||||
await umdb.pop('klipper', None)
|
||||
|
|
|
@ -35,12 +35,8 @@ RINFO_KEYS = [
|
|||
]
|
||||
|
||||
class ZipDeploy(AppDeploy):
|
||||
def __init__(self,
|
||||
config: ConfigHelper,
|
||||
cmd_helper: CommandHelper,
|
||||
app_params: Optional[Dict[str, Any]] = None
|
||||
) -> None:
|
||||
super().__init__(config, cmd_helper, app_params)
|
||||
def __init__(self, config: ConfigHelper, cmd_helper: CommandHelper) -> None:
|
||||
super().__init__(config, cmd_helper)
|
||||
self.official_repo: str = "?"
|
||||
self.owner: str = "?"
|
||||
# Extract repo from origin for validation
|
||||
|
@ -60,7 +56,7 @@ class ZipDeploy(AppDeploy):
|
|||
|
||||
@staticmethod
|
||||
async def from_application(app: AppDeploy) -> ZipDeploy:
|
||||
new_app = ZipDeploy(app.config, app.cmd_helper, app.app_params)
|
||||
new_app = ZipDeploy(app.config, app.cmd_helper)
|
||||
await new_app.reinstall()
|
||||
return new_app
|
||||
|
||||
|
|
Loading…
Reference in New Issue