cua-computer 0.1.29__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- computer/__init__.py +5 -1
- computer/computer.py +268 -140
- computer/interface/factory.py +4 -1
- computer/interface/linux.py +595 -23
- computer/interface/macos.py +9 -1
- computer/models.py +17 -5
- computer/providers/__init__.py +4 -0
- computer/providers/base.py +105 -0
- computer/providers/cloud/__init__.py +5 -0
- computer/providers/cloud/provider.py +100 -0
- computer/providers/factory.py +118 -0
- computer/providers/lume/__init__.py +9 -0
- computer/providers/lume/provider.py +541 -0
- computer/providers/lume_api.py +559 -0
- computer/providers/lumier/__init__.py +8 -0
- computer/providers/lumier/provider.py +943 -0
- {cua_computer-0.1.29.dist-info → cua_computer-0.2.0.dist-info}/METADATA +6 -2
- cua_computer-0.2.0.dist-info/RECORD +29 -0
- cua_computer-0.1.29.dist-info/RECORD +0 -19
- {cua_computer-0.1.29.dist-info → cua_computer-0.2.0.dist-info}/WHEEL +0 -0
- {cua_computer-0.1.29.dist-info → cua_computer-0.2.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
"""Base provider interface for VM backends."""
|
2
|
+
|
3
|
+
import abc
|
4
|
+
from enum import Enum
|
5
|
+
from typing import Dict, List, Optional, Any, AsyncContextManager
|
6
|
+
|
7
|
+
|
8
|
+
class VMProviderType(str, Enum):
|
9
|
+
"""Enum of supported VM provider types."""
|
10
|
+
LUME = "lume"
|
11
|
+
LUMIER = "lumier"
|
12
|
+
CLOUD = "cloud"
|
13
|
+
UNKNOWN = "unknown"
|
14
|
+
|
15
|
+
|
16
|
+
class BaseVMProvider(AsyncContextManager):
|
17
|
+
"""Base interface for VM providers.
|
18
|
+
|
19
|
+
All VM provider implementations must implement this interface.
|
20
|
+
"""
|
21
|
+
|
22
|
+
@property
|
23
|
+
@abc.abstractmethod
|
24
|
+
def provider_type(self) -> VMProviderType:
|
25
|
+
"""Get the provider type."""
|
26
|
+
pass
|
27
|
+
|
28
|
+
@abc.abstractmethod
|
29
|
+
async def get_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
|
30
|
+
"""Get VM information by name.
|
31
|
+
|
32
|
+
Args:
|
33
|
+
name: Name of the VM to get information for
|
34
|
+
storage: Optional storage path override. If provided, this will be used
|
35
|
+
instead of the provider's default storage path.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
Dictionary with VM information including status, IP address, etc.
|
39
|
+
"""
|
40
|
+
pass
|
41
|
+
|
42
|
+
@abc.abstractmethod
|
43
|
+
async def list_vms(self) -> List[Dict[str, Any]]:
|
44
|
+
"""List all available VMs."""
|
45
|
+
pass
|
46
|
+
|
47
|
+
@abc.abstractmethod
|
48
|
+
async def run_vm(self, image: str, name: str, run_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
|
49
|
+
"""Run a VM by name with the given options.
|
50
|
+
|
51
|
+
Args:
|
52
|
+
image: Name/tag of the image to use
|
53
|
+
name: Name of the VM to run
|
54
|
+
run_opts: Dictionary of run options (memory, cpu, etc.)
|
55
|
+
storage: Optional storage path override. If provided, this will be used
|
56
|
+
instead of the provider's default storage path.
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
Dictionary with VM run status and information
|
60
|
+
"""
|
61
|
+
pass
|
62
|
+
|
63
|
+
@abc.abstractmethod
|
64
|
+
async def stop_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
|
65
|
+
"""Stop a VM by name.
|
66
|
+
|
67
|
+
Args:
|
68
|
+
name: Name of the VM to stop
|
69
|
+
storage: Optional storage path override. If provided, this will be used
|
70
|
+
instead of the provider's default storage path.
|
71
|
+
|
72
|
+
Returns:
|
73
|
+
Dictionary with VM stop status and information
|
74
|
+
"""
|
75
|
+
pass
|
76
|
+
|
77
|
+
@abc.abstractmethod
|
78
|
+
async def update_vm(self, name: str, update_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
|
79
|
+
"""Update VM configuration.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
name: Name of the VM to update
|
83
|
+
update_opts: Dictionary of update options (memory, cpu, etc.)
|
84
|
+
storage: Optional storage path override. If provided, this will be used
|
85
|
+
instead of the provider's default storage path.
|
86
|
+
|
87
|
+
Returns:
|
88
|
+
Dictionary with VM update status and information
|
89
|
+
"""
|
90
|
+
pass
|
91
|
+
|
92
|
+
@abc.abstractmethod
|
93
|
+
async def get_ip(self, name: str, storage: Optional[str] = None, retry_delay: int = 2) -> str:
|
94
|
+
"""Get the IP address of a VM, waiting indefinitely until it's available.
|
95
|
+
|
96
|
+
Args:
|
97
|
+
name: Name of the VM to get the IP for
|
98
|
+
storage: Optional storage path override. If provided, this will be used
|
99
|
+
instead of the provider's default storage path.
|
100
|
+
retry_delay: Delay between retries in seconds (default: 2)
|
101
|
+
|
102
|
+
Returns:
|
103
|
+
IP address of the VM when it becomes available
|
104
|
+
"""
|
105
|
+
pass
|
@@ -0,0 +1,100 @@
|
|
1
|
+
"""Cloud VM provider implementation.
|
2
|
+
|
3
|
+
This module contains a stub implementation for a future cloud VM provider.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import logging
|
7
|
+
from typing import Dict, List, Optional, Any
|
8
|
+
|
9
|
+
from ..base import BaseVMProvider, VMProviderType
|
10
|
+
|
11
|
+
# Setup logging
|
12
|
+
logger = logging.getLogger(__name__)
|
13
|
+
|
14
|
+
class CloudProvider(BaseVMProvider):
|
15
|
+
"""Cloud VM Provider stub implementation.
|
16
|
+
|
17
|
+
This is a placeholder for a future cloud VM provider implementation.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
host: str = "localhost",
|
23
|
+
port: int = 7777,
|
24
|
+
storage: Optional[str] = None,
|
25
|
+
verbose: bool = False,
|
26
|
+
):
|
27
|
+
"""Initialize the Cloud provider.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
host: Host to use for API connections (default: localhost)
|
31
|
+
port: Port for the API server (default: 7777)
|
32
|
+
storage: Path to store VM data
|
33
|
+
verbose: Enable verbose logging
|
34
|
+
"""
|
35
|
+
self.host = host
|
36
|
+
self.port = port
|
37
|
+
self.storage = storage
|
38
|
+
self.verbose = verbose
|
39
|
+
|
40
|
+
logger.warning("CloudProvider is not yet implemented")
|
41
|
+
|
42
|
+
@property
|
43
|
+
def provider_type(self) -> VMProviderType:
|
44
|
+
"""Get the provider type."""
|
45
|
+
return VMProviderType.CLOUD
|
46
|
+
|
47
|
+
async def __aenter__(self):
|
48
|
+
"""Enter async context manager."""
|
49
|
+
logger.debug("Entering CloudProvider context")
|
50
|
+
return self
|
51
|
+
|
52
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
53
|
+
"""Exit async context manager."""
|
54
|
+
logger.debug("Exiting CloudProvider context")
|
55
|
+
|
56
|
+
async def get_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
|
57
|
+
"""Get VM information by name."""
|
58
|
+
logger.warning("CloudProvider.get_vm is not implemented")
|
59
|
+
return {
|
60
|
+
"name": name,
|
61
|
+
"status": "unavailable",
|
62
|
+
"message": "CloudProvider is not implemented"
|
63
|
+
}
|
64
|
+
|
65
|
+
async def list_vms(self) -> List[Dict[str, Any]]:
|
66
|
+
"""List all available VMs."""
|
67
|
+
logger.warning("CloudProvider.list_vms is not implemented")
|
68
|
+
return []
|
69
|
+
|
70
|
+
async def run_vm(self, image: str, name: str, run_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
|
71
|
+
"""Run a VM with the given options."""
|
72
|
+
logger.warning("CloudProvider.run_vm is not implemented")
|
73
|
+
return {
|
74
|
+
"name": name,
|
75
|
+
"status": "unavailable",
|
76
|
+
"message": "CloudProvider is not implemented"
|
77
|
+
}
|
78
|
+
|
79
|
+
async def stop_vm(self, name: str, storage: Optional[str] = None) -> Dict[str, Any]:
|
80
|
+
"""Stop a running VM."""
|
81
|
+
logger.warning("CloudProvider.stop_vm is not implemented")
|
82
|
+
return {
|
83
|
+
"name": name,
|
84
|
+
"status": "stopped",
|
85
|
+
"message": "CloudProvider is not implemented"
|
86
|
+
}
|
87
|
+
|
88
|
+
async def update_vm(self, name: str, update_opts: Dict[str, Any], storage: Optional[str] = None) -> Dict[str, Any]:
|
89
|
+
"""Update VM configuration."""
|
90
|
+
logger.warning("CloudProvider.update_vm is not implemented")
|
91
|
+
return {
|
92
|
+
"name": name,
|
93
|
+
"status": "unchanged",
|
94
|
+
"message": "CloudProvider is not implemented"
|
95
|
+
}
|
96
|
+
|
97
|
+
async def get_ip(self, name: str, storage: Optional[str] = None, retry_delay: int = 2) -> str:
|
98
|
+
"""Get the IP address of a VM."""
|
99
|
+
logger.warning("CloudProvider.get_ip is not implemented")
|
100
|
+
raise NotImplementedError("CloudProvider.get_ip is not implemented")
|
@@ -0,0 +1,118 @@
|
|
1
|
+
"""Factory for creating VM providers."""
|
2
|
+
|
3
|
+
import logging
|
4
|
+
from typing import Dict, Optional, Any, Type, Union
|
5
|
+
|
6
|
+
from .base import BaseVMProvider, VMProviderType
|
7
|
+
|
8
|
+
logger = logging.getLogger(__name__)
|
9
|
+
|
10
|
+
|
11
|
+
class VMProviderFactory:
|
12
|
+
"""Factory for creating VM providers based on provider type."""
|
13
|
+
|
14
|
+
@staticmethod
|
15
|
+
def create_provider(
|
16
|
+
provider_type: Union[str, VMProviderType],
|
17
|
+
port: int = 7777,
|
18
|
+
host: str = "localhost",
|
19
|
+
bin_path: Optional[str] = None,
|
20
|
+
storage: Optional[str] = None,
|
21
|
+
shared_path: Optional[str] = None,
|
22
|
+
image: Optional[str] = None,
|
23
|
+
verbose: bool = False,
|
24
|
+
ephemeral: bool = False,
|
25
|
+
noVNC_port: Optional[int] = None
|
26
|
+
) -> BaseVMProvider:
|
27
|
+
"""Create a VM provider of the specified type.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
provider_type: Type of VM provider to create
|
31
|
+
port: Port for the API server
|
32
|
+
host: Hostname for the API server
|
33
|
+
bin_path: Path to provider binary if needed
|
34
|
+
storage: Path for persistent VM storage
|
35
|
+
shared_path: Path for shared folder between host and VM
|
36
|
+
image: VM image to use (for Lumier provider)
|
37
|
+
verbose: Enable verbose logging
|
38
|
+
ephemeral: Use ephemeral (temporary) storage
|
39
|
+
noVNC_port: Specific port for noVNC interface (for Lumier provider)
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
An instance of the requested VM provider
|
43
|
+
|
44
|
+
Raises:
|
45
|
+
ImportError: If the required dependencies for the provider are not installed
|
46
|
+
ValueError: If the provider type is not supported
|
47
|
+
"""
|
48
|
+
# Convert string to enum if needed
|
49
|
+
if isinstance(provider_type, str):
|
50
|
+
try:
|
51
|
+
provider_type = VMProviderType(provider_type.lower())
|
52
|
+
except ValueError:
|
53
|
+
provider_type = VMProviderType.UNKNOWN
|
54
|
+
|
55
|
+
if provider_type == VMProviderType.LUME:
|
56
|
+
try:
|
57
|
+
from .lume import LumeProvider, HAS_LUME
|
58
|
+
if not HAS_LUME:
|
59
|
+
raise ImportError(
|
60
|
+
"The pylume package is required for LumeProvider. "
|
61
|
+
"Please install it with 'pip install cua-computer[lume]'"
|
62
|
+
)
|
63
|
+
return LumeProvider(
|
64
|
+
port=port,
|
65
|
+
host=host,
|
66
|
+
storage=storage,
|
67
|
+
verbose=verbose,
|
68
|
+
ephemeral=ephemeral
|
69
|
+
)
|
70
|
+
except ImportError as e:
|
71
|
+
logger.error(f"Failed to import LumeProvider: {e}")
|
72
|
+
raise ImportError(
|
73
|
+
"The pylume package is required for LumeProvider. "
|
74
|
+
"Please install it with 'pip install cua-computer[lume]'"
|
75
|
+
) from e
|
76
|
+
elif provider_type == VMProviderType.LUMIER:
|
77
|
+
try:
|
78
|
+
from .lumier import LumierProvider, HAS_LUMIER
|
79
|
+
if not HAS_LUMIER:
|
80
|
+
raise ImportError(
|
81
|
+
"Docker is required for LumierProvider. "
|
82
|
+
"Please install Docker for Apple Silicon and Lume CLI before using this provider."
|
83
|
+
)
|
84
|
+
return LumierProvider(
|
85
|
+
port=port,
|
86
|
+
host=host,
|
87
|
+
storage=storage,
|
88
|
+
shared_path=shared_path,
|
89
|
+
image=image or "macos-sequoia-cua:latest",
|
90
|
+
verbose=verbose,
|
91
|
+
ephemeral=ephemeral,
|
92
|
+
noVNC_port=noVNC_port
|
93
|
+
)
|
94
|
+
except ImportError as e:
|
95
|
+
logger.error(f"Failed to import LumierProvider: {e}")
|
96
|
+
raise ImportError(
|
97
|
+
"Docker and Lume CLI are required for LumierProvider. "
|
98
|
+
"Please install Docker for Apple Silicon and run the Lume installer script."
|
99
|
+
) from e
|
100
|
+
|
101
|
+
elif provider_type == VMProviderType.CLOUD:
|
102
|
+
try:
|
103
|
+
from .cloud import CloudProvider
|
104
|
+
# Return the stub implementation of CloudProvider
|
105
|
+
return CloudProvider(
|
106
|
+
host=host,
|
107
|
+
port=port,
|
108
|
+
storage=storage,
|
109
|
+
verbose=verbose
|
110
|
+
)
|
111
|
+
except ImportError as e:
|
112
|
+
logger.error(f"Failed to import CloudProvider: {e}")
|
113
|
+
raise ImportError(
|
114
|
+
"The CloudProvider is not fully implemented yet. "
|
115
|
+
"Please use LUME or LUMIER provider instead."
|
116
|
+
) from e
|
117
|
+
else:
|
118
|
+
raise ValueError(f"Unsupported provider type: {provider_type}")
|