mirror of
https://github.com/sickcodes/Docker-OSX.git
synced 2025-06-21 00:52:51 +02:00
127 lines
5.3 KiB
Python
127 lines
5.3 KiB
Python
# utils.py
|
|
|
|
import time
|
|
import uuid
|
|
from constants import (
|
|
DOCKER_IMAGE_BASE,
|
|
DEFAULT_DOCKER_PARAMS,
|
|
VERSION_SPECIFIC_PARAMS,
|
|
MACOS_VERSIONS
|
|
)
|
|
|
|
# Path to the generated images inside the Docker container
|
|
CONTAINER_MACOS_IMG_PATH = "/home/arch/OSX-KVM/mac_hdd_ng.img"
|
|
# The OpenCore.qcow2 path can vary if BOOTDISK env var is used.
|
|
# The default generated one by the scripts (if not overridden by BOOTDISK) is:
|
|
CONTAINER_OPENCORE_QCOW2_PATH = "/home/arch/OSX-KVM/OpenCore/OpenCore.qcow2"
|
|
|
|
|
|
def get_unique_container_name() -> str:
|
|
"""Generates a unique Docker container name."""
|
|
return f"skyscope-osx-vm-{uuid.uuid4().hex[:8]}"
|
|
|
|
def build_docker_command(macos_version_name: str, container_name: str) -> list[str]:
|
|
"""
|
|
Builds the docker run command arguments as a list.
|
|
|
|
Args:
|
|
macos_version_name: The display name of the macOS version (e.g., "Sonoma").
|
|
container_name: The unique name for the Docker container.
|
|
|
|
Returns:
|
|
A list of strings representing the docker command and its arguments.
|
|
"""
|
|
if macos_version_name not in MACOS_VERSIONS:
|
|
raise ValueError(f"Unsupported macOS version: {macos_version_name}")
|
|
|
|
image_tag = MACOS_VERSIONS[macos_version_name]
|
|
full_image_name = f"{DOCKER_IMAGE_BASE}:{image_tag}"
|
|
|
|
# Removed --rm: we need the container to persist for file extraction
|
|
final_command_args = ["docker", "run", "-it", "--name", container_name]
|
|
|
|
# Base parameters for the docker command
|
|
run_params = DEFAULT_DOCKER_PARAMS.copy()
|
|
|
|
# Override/extend with version-specific parameters
|
|
if macos_version_name in VERSION_SPECIFIC_PARAMS:
|
|
version_specific = VERSION_SPECIFIC_PARAMS[macos_version_name]
|
|
|
|
# More robustly handle environment variables (-e)
|
|
# Collect all -e keys from defaults and version-specific
|
|
default_env_vars = {k.split(" ", 1)[1].split("=")[0]: v for k, v in DEFAULT_DOCKER_PARAMS.items() if k.startswith("-e ")}
|
|
version_env_vars = {k.split(" ", 1)[1].split("=")[0]: v for k, v in version_specific.items() if k.startswith("-e ")}
|
|
|
|
merged_env_vars = {**default_env_vars, **version_env_vars}
|
|
|
|
# Remove all old -e params from run_params before adding merged ones
|
|
keys_to_remove_from_run_params = [k_param for k_param in run_params if k_param.startswith("-e ")]
|
|
for k_rem in keys_to_remove_from_run_params:
|
|
del run_params[k_rem]
|
|
|
|
# Add merged env vars back with the "-e VAR_NAME" format for keys
|
|
for env_name, env_val_str in merged_env_vars.items():
|
|
run_params[f"-e {env_name}"] = env_val_str
|
|
|
|
# Add other non -e version-specific params
|
|
for k, v in version_specific.items():
|
|
if not k.startswith("-e "):
|
|
run_params[k] = v
|
|
|
|
# Construct the command list
|
|
for key, value in run_params.items():
|
|
if key.startswith("-e "):
|
|
# Key is like "-e VARNAME", value is the actual value string like "'data'" or "GENERATE_UNIQUE='true'"
|
|
env_var_name_from_key = key.split(" ", 1)[1] # e.g. GENERATE_UNIQUE or CPU
|
|
|
|
# If value string itself contains '=', it's likely the full 'VAR=val' form
|
|
if isinstance(value, str) and '=' in value and value.strip("'").upper().startswith(env_var_name_from_key.upper()):
|
|
# e.g. value is "GENERATE_UNIQUE='true'"
|
|
final_env_val = value.strip("'")
|
|
else:
|
|
# e.g. value is "'true'" for key "-e GENERATE_UNIQUE"
|
|
final_env_val = f"{env_var_name_from_key}={value.strip("'")}"
|
|
final_command_args.extend(["-e", final_env_val])
|
|
else: # for --device, -p, -v
|
|
final_command_args.extend([key, value.strip("'")]) # Strip quotes for safety
|
|
|
|
final_command_args.append(full_image_name)
|
|
|
|
return final_command_args
|
|
|
|
def build_docker_cp_command(container_name_or_id: str, container_path: str, host_path: str) -> list[str]:
|
|
"""Builds the 'docker cp' command."""
|
|
return ["docker", "cp", f"{container_name_or_id}:{container_path}", host_path]
|
|
|
|
def build_docker_stop_command(container_name_or_id: str) -> list[str]:
|
|
"""Builds the 'docker stop' command."""
|
|
return ["docker", "stop", container_name_or_id]
|
|
|
|
def build_docker_rm_command(container_name_or_id: str) -> list[str]:
|
|
"""Builds the 'docker rm' command."""
|
|
return ["docker", "rm", container_name_or_id]
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# Test the functions
|
|
container_name = get_unique_container_name()
|
|
print(f"Generated container name: {container_name}")
|
|
|
|
for version_name_key in MACOS_VERSIONS.keys():
|
|
print(f"Command for {version_name_key}:")
|
|
cmd_list = build_docker_command(version_name_key, container_name)
|
|
print(" ".join(cmd_list))
|
|
print("-" * 20)
|
|
|
|
test_container_id = container_name # or an actual ID
|
|
print(f"CP Main Image: {' '.join(build_docker_cp_command(test_container_id, CONTAINER_MACOS_IMG_PATH, './mac_hdd_ng.img'))}")
|
|
print(f"CP OpenCore Image: {' '.join(build_docker_cp_command(test_container_id, CONTAINER_OPENCORE_QCOW2_PATH, './OpenCore.qcow2'))}")
|
|
print(f"Stop Command: {' '.join(build_docker_stop_command(test_container_id))}")
|
|
print(f"Remove Command: {' '.join(build_docker_rm_command(test_container_id))}")
|
|
|
|
# Test with a non-existent version
|
|
try:
|
|
build_docker_command("NonExistentVersion", container_name)
|
|
except ValueError as e:
|
|
print(e)
|