request-vm-on-golem 0.1.24__py3-none-any.whl → 0.1.26__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.
@@ -0,0 +1,209 @@
1
+ """VM management service."""
2
+ from typing import Dict, List, Optional
3
+ from datetime import datetime
4
+
5
+ from ..provider.client import ProviderClient
6
+ from ..errors import RequestorError, VMError
7
+ from .database_service import DatabaseService
8
+ from .ssh_service import SSHService
9
+
10
+ class VMService:
11
+ """Service for VM operations."""
12
+
13
+ def __init__(
14
+ self,
15
+ db_service: DatabaseService,
16
+ ssh_service: SSHService,
17
+ provider_client: Optional[ProviderClient] = None
18
+ ):
19
+ self.db = db_service
20
+ self.ssh_service = ssh_service
21
+ self.provider_client = provider_client
22
+
23
+ async def create_vm(
24
+ self,
25
+ name: str,
26
+ cpu: int,
27
+ memory: int,
28
+ storage: int,
29
+ provider_ip: str,
30
+ ssh_key: str
31
+ ) -> Dict:
32
+ """Create a new VM with validation and error handling."""
33
+ try:
34
+ # Check if VM name already exists
35
+ existing_vm = await self.db.get_vm(name)
36
+ if existing_vm:
37
+ raise VMError(f"VM with name '{name}' already exists")
38
+
39
+ # Create VM on provider
40
+ vm = await self.provider_client.create_vm(
41
+ name=name,
42
+ cpu=cpu,
43
+ memory=memory,
44
+ storage=storage,
45
+ ssh_key=ssh_key
46
+ )
47
+
48
+ # Get VM access info
49
+ access_info = await self.provider_client.get_vm_access(vm['id'])
50
+
51
+ # Save VM details to database
52
+ config = {
53
+ 'cpu': cpu,
54
+ 'memory': memory,
55
+ 'storage': storage,
56
+ 'ssh_port': access_info['ssh_port']
57
+ }
58
+ await self.db.save_vm(
59
+ name=name,
60
+ provider_ip=provider_ip,
61
+ vm_id=access_info['vm_id'],
62
+ config=config
63
+ )
64
+
65
+ return {
66
+ 'name': name,
67
+ 'provider_ip': provider_ip,
68
+ 'vm_id': access_info['vm_id'],
69
+ 'config': config,
70
+ 'status': 'running'
71
+ }
72
+
73
+ except Exception as e:
74
+ raise VMError(f"Failed to create VM: {str(e)}")
75
+
76
+ async def destroy_vm(self, name: str) -> None:
77
+ """Destroy a VM and clean up resources."""
78
+ try:
79
+ # Get VM details
80
+ vm = await self.db.get_vm(name)
81
+ if not vm:
82
+ raise VMError(f"VM '{name}' not found")
83
+
84
+ try:
85
+ # Destroy VM on provider
86
+ await self.provider_client.destroy_vm(vm['vm_id'])
87
+ except Exception as e:
88
+ if "Not Found" not in str(e):
89
+ raise
90
+
91
+ # Remove from database
92
+ await self.db.delete_vm(name)
93
+
94
+ except Exception as e:
95
+ raise VMError(f"Failed to destroy VM: {str(e)}")
96
+
97
+ async def start_vm(self, name: str) -> None:
98
+ """Start a stopped VM."""
99
+ try:
100
+ # Get VM details
101
+ vm = await self.db.get_vm(name)
102
+ if not vm:
103
+ raise VMError(f"VM '{name}' not found")
104
+
105
+ # Start VM on provider
106
+ await self.provider_client.start_vm(vm['vm_id'])
107
+
108
+ # Update status in database
109
+ await self.db.update_vm_status(name, "running")
110
+
111
+ except Exception as e:
112
+ raise VMError(f"Failed to start VM: {str(e)}")
113
+
114
+ async def stop_vm(self, name: str) -> None:
115
+ """Stop a running VM."""
116
+ try:
117
+ # Get VM details
118
+ vm = await self.db.get_vm(name)
119
+ if not vm:
120
+ raise VMError(f"VM '{name}' not found")
121
+
122
+ # Stop VM on provider
123
+ await self.provider_client.stop_vm(vm['vm_id'])
124
+
125
+ # Update status in database
126
+ await self.db.update_vm_status(name, "stopped")
127
+
128
+ except Exception as e:
129
+ raise VMError(f"Failed to stop VM: {str(e)}")
130
+
131
+ async def list_vms(self) -> List[Dict]:
132
+ """List all VMs with their current status."""
133
+ try:
134
+ return await self.db.list_vms()
135
+ except Exception as e:
136
+ raise VMError(f"Failed to list VMs: {str(e)}")
137
+
138
+ async def get_vm(self, name: str) -> Optional[Dict]:
139
+ """Get VM details by name."""
140
+ try:
141
+ vm = await self.db.get_vm(name)
142
+ if not vm:
143
+ return None
144
+ return vm
145
+ except Exception as e:
146
+ raise VMError(f"Failed to get VM details: {str(e)}")
147
+
148
+ def format_vm_row(self, vm: Dict, colorize: bool = False) -> List:
149
+ """Format VM information for display."""
150
+ from click import style
151
+
152
+ row = [
153
+ vm['name'],
154
+ vm['status'],
155
+ vm['provider_ip'],
156
+ vm['config'].get('ssh_port', 'N/A'),
157
+ vm['config']['cpu'],
158
+ vm['config']['memory'],
159
+ vm['config']['storage'],
160
+ vm['created_at']
161
+ ]
162
+
163
+ if colorize:
164
+ # Format status with color and icon
165
+ status = row[1]
166
+ if status == "running":
167
+ row[1] = style("● " + status, fg="green", bold=True)
168
+ elif status == "stopped":
169
+ row[1] = style("● " + status, fg="yellow", bold=True)
170
+ else:
171
+ row[1] = style("● " + status, fg="red", bold=True)
172
+
173
+ # Format other columns
174
+ row[0] = style(row[0], fg="cyan") # Name
175
+ row[2] = style(row[2], fg="cyan") # IP
176
+ row[3] = style(str(row[3]), fg="cyan") # Port
177
+
178
+ return row
179
+
180
+ @property
181
+ def vm_headers(self) -> List[str]:
182
+ """Get headers for VM display."""
183
+ return [
184
+ "Name",
185
+ "Status",
186
+ "IP Address",
187
+ "SSH Port",
188
+ "CPU",
189
+ "Memory (GB)",
190
+ "Storage (GB)",
191
+ "Created"
192
+ ]
193
+
194
+ async def get_vm_stats(self, name: str) -> Dict:
195
+ """Get VM stats by name."""
196
+ try:
197
+ vm = await self.db.get_vm(name)
198
+ if not vm:
199
+ raise VMError(f"VM '{name}' not found")
200
+
201
+ key_pair = await self.ssh_service.get_key_pair()
202
+
203
+ return self.ssh_service.get_vm_stats(
204
+ host=vm['provider_ip'],
205
+ port=vm['config']['ssh_port'],
206
+ private_key_path=key_pair.private_key
207
+ )
208
+ except Exception as e:
209
+ raise VMError(f"Failed to get VM stats: {str(e)}")
@@ -1,18 +0,0 @@
1
- requestor/__init__.py,sha256=OqSUAh1uZBMx7GW0MoSMg967PVdmT8XdPJx3QYjwkak,116
2
- requestor/cli/__init__.py,sha256=e3E4oEGxmGj-STPtFkQwg_qIWhR0JAiAQdw3G1hXciU,37
3
- requestor/cli/commands.py,sha256=deW4HxJGJvWQCOEvkuPEzkIfSDOSYa2npO4i_4sesCo,24283
4
- requestor/config.py,sha256=3e0xAuteZ3JiE6uWHipQLQQklGN59hiqdqZUT2mUutM,2146
5
- requestor/db/__init__.py,sha256=Gm5DfWls6uvCZZ3HGGnyRHswbUQdeA5OGN8yPwH0hc8,88
6
- requestor/db/sqlite.py,sha256=kqutQMs3srcZHa5kI1cbHvOYr66cCfQCb2xuioNAbLc,4638
7
- requestor/errors.py,sha256=wVpHBuYgQx5pTe_SamugfK-k768noikY1RxvPOjQGko,665
8
- requestor/provider/__init__.py,sha256=fmW23aYUVciF8-gmBZkG-PLhn22upmcDzdPfAOLHG6g,103
9
- requestor/provider/client.py,sha256=OUP7CoOCCtKD6DB9eqFkOXK6A2BLFdM4DWSkoulJQxg,3213
10
- requestor/run.py,sha256=mFqoP93KuRpQZ8pmzP5pHvByaDjHJ9xRYRjYC77s6bg,1386
11
- requestor/ssh/__init__.py,sha256=hNgSqJ5s1_AwwxVRyFjUqh_LTBpI4Hmzq0F-f_wXN9g,119
12
- requestor/ssh/manager.py,sha256=h-93AXFJqzGo2lNTG2u-q4ivU9cCFeNDhYN55skPLBo,6566
13
- requestor/utils/logging.py,sha256=oFNpO8pJboYM8Wp7g3HOU4HFyBTKypVdY15lUiz1a4I,3721
14
- requestor/utils/spinner.py,sha256=PUHJdTD9jpUHur__01_qxXy87WFfNmjQbD_sLG-KlGo,2459
15
- request_vm_on_golem-0.1.24.dist-info/METADATA,sha256=969OAj0KxwHXeI6BWZkfiLbjyO-sYdBPxlDyEP9QyTE,9060
16
- request_vm_on_golem-0.1.24.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
17
- request_vm_on_golem-0.1.24.dist-info/entry_points.txt,sha256=Z-skRNpJ8aZcIl_En9mEm1ygkp9FKy0bzQoL3zO52-0,44
18
- request_vm_on_golem-0.1.24.dist-info/RECORD,,