Skip to content

Commit d3c819e

Browse files
authored
Merge pull request #384 from Evrard-Nil/improve-vmm-cly
feat: add VM resizing and port updating functionality
2 parents ce87147 + ed8c962 commit d3c819e

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

vmm/src/vmm-cli.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ def read_utf8(filepath: str) -> str:
123123
with open(filepath, 'rb') as f:
124124
return f.read().decode('utf-8')
125125

126-
127126
class UnixSocketHTTPConnection(http.client.HTTPConnection):
128127
"""HTTPConnection that connects to a Unix domain socket."""
129128

@@ -332,6 +331,33 @@ def remove_vm(self, vm_id: str) -> None:
332331
self.rpc_call('RemoveVm', {'id': vm_id})
333332
print(f"Removed VM {vm_id}")
334333

334+
def resize_vm(
335+
self,
336+
vm_id: str,
337+
vcpu: Optional[int] = None,
338+
memory: Optional[int] = None,
339+
disk_size: Optional[int] = None,
340+
image: Optional[str] = None,
341+
) -> None:
342+
"""Resize a VM"""
343+
params = {"id": vm_id}
344+
if vcpu is not None:
345+
params["vcpu"] = vcpu
346+
if memory is not None:
347+
params["memory"] = memory
348+
if disk_size is not None:
349+
params["disk_size"] = disk_size
350+
if image is not None:
351+
params["image"] = image
352+
353+
if len(params) == 1:
354+
raise Exception(
355+
"at least one parameter must be specified for resize: --vcpu, --memory, --disk, or --image"
356+
)
357+
358+
self.rpc_call("ResizeVm", params)
359+
print(f"Resized VM {vm_id}")
360+
335361
def show_logs(self, vm_id: str, lines: int = 20, follow: bool = False) -> None:
336362
"""Show VM logs"""
337363
path = f"/logs?id={vm_id}&follow={str(follow).lower()}&ansi=false&lines={lines}"
@@ -609,6 +635,15 @@ def update_vm_app_compose(self, vm_id: str, app_compose: str) -> None:
609635
self.rpc_call('UpgradeApp', {'id': vm_id,
610636
'compose_file': app_compose})
611637
print(f"App compose updated for VM {vm_id}")
638+
639+
def update_vm_ports(self, vm_id: str, ports: List[str]) -> None:
640+
"""Update port mapping for a VM"""
641+
port_mappings = [parse_port_mapping(port) for port in ports]
642+
self.rpc_call(
643+
"UpgradeApp", {"id": vm_id,
644+
"update_ports": True, "ports": port_mappings}
645+
)
646+
print(f"Port mapping updated for VM {vm_id}")
612647

613648
def list_gpus(self, json_output: bool = False) -> None:
614649
"""List all available GPUs"""
@@ -884,6 +919,18 @@ def main():
884919
remove_parser = subparsers.add_parser('remove', help='Remove a VM')
885920
remove_parser.add_argument('vm_id', help='VM ID to remove')
886921

922+
# Resize command
923+
resize_parser = subparsers.add_parser("resize", help="Resize a VM")
924+
resize_parser.add_argument("vm_id", help="VM ID to resize")
925+
resize_parser.add_argument("--vcpu", type=int, help="Number of vCPUs")
926+
resize_parser.add_argument(
927+
"--memory", type=parse_memory_size, help="Memory size (e.g. 1G, 100M)"
928+
)
929+
resize_parser.add_argument(
930+
"--disk", type=parse_disk_size, help="Disk size (e.g. 20G, 1T)"
931+
)
932+
resize_parser.add_argument("--image", type=str, help="Image name")
933+
887934
# Logs command
888935
logs_parser = subparsers.add_parser('logs', help='Show VM logs')
889936
logs_parser.add_argument('vm_id', help='VM ID to show logs for')
@@ -1016,6 +1063,19 @@ def main():
10161063
update_user_config_parser.add_argument(
10171064
'user_config', help='Path to user config file')
10181065

1066+
# Update port mapping
1067+
update_ports_parser = subparsers.add_parser(
1068+
"update-ports", help="Update port mapping for a VM"
1069+
)
1070+
update_ports_parser.add_argument("vm_id", help="VM ID to update")
1071+
update_ports_parser.add_argument(
1072+
"--port",
1073+
action="append",
1074+
type=str,
1075+
required=True,
1076+
help="Port mapping in format: protocol[:address]:from:to (can be used multiple times)",
1077+
)
1078+
10191079
args = parser.parse_args()
10201080

10211081
cli = VmmCLI(args.url, args.auth_user, args.auth_password)
@@ -1028,6 +1088,14 @@ def main():
10281088
cli.stop_vm(args.vm_id, args.force)
10291089
elif args.command == 'remove':
10301090
cli.remove_vm(args.vm_id)
1091+
elif args.command == 'resize':
1092+
cli.resize_vm(
1093+
args.vm_id,
1094+
vcpu=args.vcpu,
1095+
memory=args.memory,
1096+
disk_size=args.disk,
1097+
image=args.image,
1098+
)
10311099
elif args.command == 'logs':
10321100
cli.show_logs(args.vm_id, args.lines, args.follow)
10331101
elif args.command == 'compose':
@@ -1046,6 +1114,8 @@ def main():
10461114
args.vm_id, open(args.user_config, 'r').read())
10471115
elif args.command == 'update-app-compose':
10481116
cli.update_vm_app_compose(args.vm_id, open(args.compose, 'r').read())
1117+
elif args.command == "update-ports":
1118+
cli.update_vm_ports(args.vm_id, args.port)
10491119
elif args.command == 'kms':
10501120
if not args.kms_action:
10511121
kms_parser.print_help()

0 commit comments

Comments
 (0)