104 lines
3.8 KiB
Python
104 lines
3.8 KiB
Python
import logging
|
|
import os
|
|
import platform
|
|
import subprocess
|
|
import time
|
|
|
|
from desktop_env.providers.base import Provider
|
|
|
|
logger = logging.getLogger("desktopenv.providers.vmware.VMwareProvider")
|
|
logger.setLevel(logging.INFO)
|
|
|
|
WAIT_TIME = 3
|
|
|
|
|
|
def get_vmrun_type(return_list=False):
|
|
if platform.system() == 'Windows' or platform.system() == 'Linux':
|
|
if return_list:
|
|
return ['-T', 'ws']
|
|
else:
|
|
return '-T ws'
|
|
elif platform.system() == 'Darwin': # Darwin is the system name for macOS
|
|
if return_list:
|
|
return ['-T', 'fusion']
|
|
else:
|
|
return '-T fusion'
|
|
else:
|
|
raise Exception("Unsupported operating system")
|
|
|
|
|
|
class VMwareProvider(Provider):
|
|
@staticmethod
|
|
def _execute_command(command: list, return_output=False):
|
|
process = subprocess.Popen(
|
|
command,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
text=True,
|
|
encoding="utf-8"
|
|
)
|
|
|
|
if return_output:
|
|
output = process.communicate()[0].strip()
|
|
return output
|
|
else:
|
|
return None
|
|
|
|
def start_emulator(self, path_to_vm: str, headless: bool, os_type: str):
|
|
print("Starting VMware VM...")
|
|
logger.info("Starting VMware VM...")
|
|
|
|
while True:
|
|
try:
|
|
output = subprocess.check_output(f"vmrun {get_vmrun_type()} list", shell=True, stderr=subprocess.STDOUT)
|
|
output = output.decode()
|
|
output = output.splitlines()
|
|
normalized_path_to_vm = os.path.abspath(os.path.normpath(path_to_vm))
|
|
|
|
if any(os.path.abspath(os.path.normpath(line)) == normalized_path_to_vm for line in output):
|
|
logger.info("VM is running.")
|
|
break
|
|
else:
|
|
logger.info("Starting VM...")
|
|
_command = ["vmrun"] + get_vmrun_type(return_list=True) + ["start", path_to_vm]
|
|
if headless:
|
|
_command.append("nogui")
|
|
VMwareProvider._execute_command(_command)
|
|
time.sleep(WAIT_TIME)
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
logger.error(f"Error executing command: {e.output.decode().strip()}")
|
|
|
|
def get_ip_address(self, path_to_vm: str) -> str:
|
|
logger.info("Getting VMware VM IP address...")
|
|
while True:
|
|
try:
|
|
output = VMwareProvider._execute_command(
|
|
["vmrun"] + get_vmrun_type(return_list=True) + ["getGuestIPAddress", path_to_vm, "-wait"],
|
|
return_output=True
|
|
)
|
|
logger.info(f"VMware VM IP address: {output}")
|
|
return output
|
|
except Exception as e:
|
|
logger.error(e)
|
|
time.sleep(WAIT_TIME)
|
|
logger.info("Retrying to get VMware VM IP address...")
|
|
|
|
def save_state(self, path_to_vm: str, snapshot_name: str):
|
|
logger.info("Saving VMware VM state...")
|
|
VMwareProvider._execute_command(
|
|
["vmrun"] + get_vmrun_type(return_list=True) + ["snapshot", path_to_vm, snapshot_name])
|
|
time.sleep(WAIT_TIME) # Wait for the VM to save
|
|
|
|
def revert_to_snapshot(self, path_to_vm: str, snapshot_name: str):
|
|
logger.info(f"Reverting VMware VM to snapshot: {snapshot_name}...")
|
|
VMwareProvider._execute_command(
|
|
["vmrun"] + get_vmrun_type(return_list=True) + ["revertToSnapshot", path_to_vm, snapshot_name])
|
|
time.sleep(WAIT_TIME) # Wait for the VM to revert
|
|
return path_to_vm
|
|
|
|
def stop_emulator(self, path_to_vm: str):
|
|
logger.info("Stopping VMware VM...")
|
|
VMwareProvider._execute_command(["vmrun"] + get_vmrun_type(return_list=True) + ["stop", path_to_vm])
|
|
time.sleep(WAIT_TIME) # Wait for the VM to stop
|