Files
InstallerRobot/agent/app/core/installer.py
2026-05-26 15:43:56 +07:00

69 lines
2.1 KiB
Python

from __future__ import annotations
from pathlib import Path
from app.core.command_runner import CommandRunner
def _parse_deb_control_output(output: str) -> dict[str, str]:
metadata: dict[str, str] = {}
for line in output.splitlines():
key, separator, value = line.partition(":")
if not separator:
continue
normalized_key = key.strip().lower()
if normalized_key in {"package", "version", "architecture"}:
metadata[normalized_key] = value.strip()
return metadata
class DebInstaller:
def __init__(self, command_runner: CommandRunner) -> None:
self.command_runner = command_runner
def get_deb_metadata(self, file_path: Path) -> dict[str, str]:
result = self.command_runner.run([
"dpkg-deb",
"-f",
str(file_path),
"Package",
"Version",
"Architecture",
])
metadata = _parse_deb_control_output(result.stdout)
missing_fields = [
field
for field in ("package", "version", "architecture")
if not metadata.get(field)
]
if missing_fields:
raise ValueError(
"Downloaded .deb is missing metadata fields: "
f"{', '.join(missing_fields)}"
)
return metadata
def install_deb(self, file_path: Path) -> None:
self.command_runner.run(["apt", "install", "-y", str(file_path)])
def remove_package(self, package_name: str, purge: bool = False) -> None:
action = "purge" if purge else "remove"
self.command_runner.run(["apt", action, "-y", package_name])
def get_package_version(self, package_name: str) -> str | None:
result = self.command_runner.run(["dpkg-query", "-W", "-f=${Version}", package_name])
version = result.stdout.strip()
return version or None
def check_package_installed(self, package_name: str) -> bool:
try:
self.get_package_version(package_name)
return True
except Exception:
return False