feat(tools): Enhance guest tools installation and management
- Added new API endpoints for tool catalog and installation management. - Updated usage documentation to include new tool installation features. - Implemented asynchronous tool installation with job tracking. - Introduced integration tests for tool installation in disposable VMs. - Enhanced dashboard UI to reflect tool installation status and usage instructions. - Improved error handling and logging for tool installation processes. - Added support for multiple Python versions and Conda environments. - Refactored tool management logic to ensure better state handling and job persistence.
This commit is contained in:
+9
-3
@@ -281,7 +281,7 @@ class Installer:
|
||||
raise ToolError(f"installation directory is already in use: {prefix}")
|
||||
regular_file(marker)
|
||||
previous = json.loads(marker.read_bytes())
|
||||
if any(previous.get(key) != value for key, value in identity.items()):
|
||||
if not isinstance(previous, dict) or any(previous.get(key) != value for key, value in identity.items()):
|
||||
raise ToolError(f"installation directory belongs to a different release: {prefix}")
|
||||
if tool["kind"] != "conda" or previous.get("complete"):
|
||||
return prefix
|
||||
@@ -348,6 +348,10 @@ class Installer:
|
||||
if manifest.exists():
|
||||
regular_file(manifest)
|
||||
self.managed = json.loads(manifest.read_bytes())
|
||||
if (not isinstance(self.managed, dict) or any(
|
||||
not isinstance(values, list) or len(values) > 2 or any(not isinstance(value, str) for value in values)
|
||||
for values in self.managed.values())):
|
||||
raise ToolError("invalid managed tool file manifest")
|
||||
with tempfile.TemporaryDirectory(prefix=".install-", dir=ROOT) as name:
|
||||
temporary = Path(name)
|
||||
if tool["kind"] == "php":
|
||||
@@ -369,11 +373,13 @@ class Installer:
|
||||
|
||||
def main(payload):
|
||||
installer = Installer(payload["username"])
|
||||
info = {}
|
||||
try:
|
||||
if os.geteuid() != 0:
|
||||
raise ToolError("tool installation and inspection require guest root")
|
||||
info = platform_info()
|
||||
if not info["supported"] or info["architecture"] != payload["architecture"]:
|
||||
info["supported"] = info["supported"] and info["architecture"] == payload["architecture"]
|
||||
if not info["supported"]:
|
||||
raise ToolError("one-click tools require an Ubuntu 22.04 guest on the selected x86_64/ARM64 architecture")
|
||||
if payload.get("boot_id") and payload["boot_id"] != info["boot_id"]:
|
||||
raise ToolError("the guest rebooted during installation; retry on the current boot")
|
||||
@@ -385,7 +391,7 @@ def main(payload):
|
||||
raise ToolError("unsupported tool operation")
|
||||
result["ok"] = True
|
||||
except (ToolError, OSError, ValueError, KeyError, tarfile.TarError, subprocess.SubprocessError) as error:
|
||||
result = {"ok": False, "error": str(error)[:2048]}
|
||||
result = {"ok": False, "error": str(error)[:2048], "supported": info.get("supported")}
|
||||
result.update(output=installer.log.decode("utf-8", errors="replace"), truncated=installer.truncated)
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user