mirror of
https://github.com/gryf/boxpy.git
synced 2025-12-19 05:30:18 +01:00
Rework port for the ssh forwarding.
Till now, user has to provide port number (by commandline or through config file), otherwise 2222 will be set. That's unfortunate in case you need to have multiple machines and forgot about setting the correct port. In this patch random port will be used if no port is provided.
This commit is contained in:
54
box.py
54
box.py
@@ -3,6 +3,7 @@
|
||||
import argparse
|
||||
import collections.abc
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
@@ -42,7 +43,6 @@ boxpy_data:
|
||||
disk_size: 10240
|
||||
key: ~/.ssh/id_rsa
|
||||
memory: 2048
|
||||
port: 2222
|
||||
'''
|
||||
COMPLETIONS = {'bash': '''\
|
||||
_boxpy() {
|
||||
@@ -494,7 +494,7 @@ class VBoxManage:
|
||||
'--delete']) != 0:
|
||||
raise BoxVBoxFailure(f'Removing VM {self.name_or_uuid} failed')
|
||||
|
||||
def create(self, cpus, memory, port):
|
||||
def create(self, cpus, memory, port=None):
|
||||
self.uuid = None
|
||||
memory = convert_to_mega(memory)
|
||||
|
||||
@@ -513,6 +513,9 @@ class VBoxManage:
|
||||
if not self.uuid:
|
||||
raise BoxVBoxFailure(f'Cannot create VM "{self.name_or_uuid}".')
|
||||
|
||||
if not port:
|
||||
port = self._find_unused_port()
|
||||
|
||||
if subprocess.call(['vboxmanage', 'modifyvm', self.name_or_uuid,
|
||||
'--memory', str(memory),
|
||||
'--cpus', str(cpus),
|
||||
@@ -575,6 +578,48 @@ class VBoxManage:
|
||||
f'--{nic}', kind]) != 0:
|
||||
raise BoxVBoxFailure(f'Cannot modify VM "{self.name_or_uuid}".')
|
||||
|
||||
def _find_unused_port(self):
|
||||
self.get_vm_info()
|
||||
try:
|
||||
out = subprocess.check_output(['vboxmanage', 'list', 'vms'],
|
||||
encoding=sys.getdefaultencoding(),
|
||||
stderr=subprocess.DEVNULL)
|
||||
except subprocess.CalledProcessError:
|
||||
return 0
|
||||
|
||||
used_ports = []
|
||||
for line in out.split('\n'):
|
||||
if not line:
|
||||
continue
|
||||
vm_uuid = line.split('{')[1][:-1]
|
||||
if self.vm_info['uuid'] == vm_uuid:
|
||||
continue
|
||||
|
||||
try:
|
||||
info = (subprocess
|
||||
.check_output(['vboxmanage', 'showvminfo', vm_uuid],
|
||||
encoding=sys.getdefaultencoding(),
|
||||
stderr=subprocess.DEVNULL))
|
||||
except subprocess.CalledProcessError:
|
||||
continue
|
||||
|
||||
for line in info.split('\n'):
|
||||
if line.startswith('Config file:'):
|
||||
config = line.split('Config ' 'file:')[1].strip()
|
||||
|
||||
dom = xml.dom.minidom.parse(config)
|
||||
gebtn = dom.getElementsByTagName
|
||||
|
||||
if len(gebtn('Forwarding')):
|
||||
used_ports.append(gebtn('Forwarding')[0]
|
||||
.getAttribute('hostport'))
|
||||
|
||||
while True:
|
||||
port = random.randint(2000, 2999)
|
||||
if port not in used_ports:
|
||||
self.vm_info['port'] = port
|
||||
return port
|
||||
|
||||
def _get_vm_config(self):
|
||||
if self.vm_info.get('config_file'):
|
||||
return self.vm_info['config_file']
|
||||
@@ -858,6 +903,9 @@ def vmcreate(args, conf=None):
|
||||
# dettach ISO image
|
||||
_cleanup(vbox, iso, image, path_to_iso)
|
||||
vbox.poweron()
|
||||
|
||||
# reread config to update fields
|
||||
conf = Config(args, vbox)
|
||||
print('You can access your VM by issuing:')
|
||||
print(f'ssh -p {conf.port} -i {conf.ssh_key_path[:-4]} '
|
||||
f'{DISTROS[conf.distro]["username"]}@localhost')
|
||||
@@ -937,7 +985,7 @@ def main():
|
||||
create.add_argument('-n', '--hostname',
|
||||
help="VM hostname. Default same as vm name")
|
||||
create.add_argument('-p', '--port', help="set ssh port for VM, default "
|
||||
"2222")
|
||||
"random port from range 2000-2999")
|
||||
create.add_argument('-s', '--disk-size', help="disk size to be expanded "
|
||||
"to. By default to 10GB")
|
||||
create.add_argument('-u', '--cpus', type=int, help="amount of CPUs to be "
|
||||
|
||||
Reference in New Issue
Block a user