Skip to content

Commit 6147dcd

Browse files
Allow connection to a remote controller
Ref GNS3#1280
1 parent d900842 commit 6147dcd

10 files changed

+272
-97
lines changed

gns3/controller.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from .qt import QtCore, QtGui, qpartial
2323
from .symbol import Symbol
2424

25-
2625
import logging
2726
log = logging.getLogger(__name__)
2827

@@ -37,6 +36,7 @@ def __init__(self):
3736
super().__init__()
3837
self._connected = False
3938
self._cache_directory = tempfile.TemporaryDirectory()
39+
self._http_client = None
4040

4141
def connected(self):
4242
"""
@@ -55,8 +55,10 @@ def setHttpClient(self, http_client):
5555
:param http_client: Instance of HTTP client to communicate with the server
5656
"""
5757
self._http_client = http_client
58-
self._http_client.connection_connected_signal.connect(self._httpClientConnectedSlot)
59-
self.get('/version', None)
58+
if self._http_client:
59+
self._http_client.connection_connected_signal.connect(self._httpClientConnectedSlot)
60+
self._connected = False
61+
self.get('/version', None)
6062

6163
def _httpClientConnectedSlot(self):
6264
if not self._connected:

gns3/dialogs/setup_wizard.py

-9
Original file line numberDiff line numberDiff line change
@@ -254,15 +254,6 @@ def validateCurrentPage(self):
254254
return False
255255

256256
LocalServer.instance().updateLocalServerSettings(local_server_settings)
257-
LocalServer.instance().stopLocalServer(wait=True)
258-
if LocalServer.instance().startLocalServer():
259-
worker = WaitForConnectionWorker(local_server_settings["host"], local_server_settings["port"])
260-
dialog = ProgressDialog(worker, "Local server", "Connecting...", "Cancel", busy=True, parent=self)
261-
dialog.show()
262-
dialog.exec_()
263-
Controller.instance().setHttpClient(LocalServer.instance().httpClient())
264-
else:
265-
QtWidgets.QMessageBox.critical(self, "Local server", "Could not start the local server process: {}".format(local_server_settings["path"]))
266257

267258
elif self.currentPage() == self.uiSummaryWizardPage:
268259
use_local_server = self.uiLocalRadioButton.isChecked()

gns3/local_server.py

+23-7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from gns3.utils.http import getSynchronous
4141
from gns3.utils.sudo import sudo
4242
from gns3.http_client import HTTPClient
43+
from gns3.controller import Controller
4344

4445

4546
import logging
@@ -75,7 +76,7 @@ def cancel(self):
7576
return
7677

7778

78-
class LocalServer():
79+
class LocalServer(QtCore.QObject):
7980
"""
8081
Manage the local server process
8182
"""
@@ -84,13 +85,14 @@ def __init__(self, parent=None):
8485

8586
super().__init__()
8687
self._parent = parent
87-
self._http_client = None
8888
self._local_server_path = ""
8989
self._local_server_process = None
9090
self._config_directory = LocalConfig.instance().configDirectory()
9191
self._pid_path = os.path.join(self._config_directory, "gns3_server.pid")
9292
self.localServerSettings()
9393
self._port = self._settings["port"]
94+
self._http_client = HTTPClient(self._settings)
95+
Controller.instance().setHttpClient(self._http_client)
9496

9597
def parent(self):
9698
"""
@@ -206,13 +208,32 @@ def updateLocalServerSettings(self, new_settings):
206208
"""
207209
Update the local server settings. Keep the key not in new_settings
208210
"""
211+
old_settings = copy.copy(self._settings)
209212
if not self._settings:
210213
self._settings = new_settings
211214
else:
212215
self._settings.update(new_settings)
213216
self._port = self._settings["port"]
214217
LocalServerConfig.instance().saveSettings("Server", self._settings)
215218

219+
# Settings have changed we need to restart the server
220+
if old_settings != self._settings:
221+
if self._settings["auto_start"]:
222+
self.stopLocalServer(wait=True)
223+
if self.startLocalServer():
224+
worker = WaitForConnectionWorker(new_local_server_settings["host"], new_local_server_settings["port"])
225+
dialog = ProgressDialog(worker, "Local server", "Connecting...", "Cancel", busy=True, parent=self.parent())
226+
dialog.show()
227+
dialog.exec_()
228+
else:
229+
QtWidgets.QMessageBox.critical(self.parent(), "Local server", "Could not start the local server process: {}".format(new_local_server_settings["path"]))
230+
# If the controller is remote:
231+
else:
232+
self.stopLocalServer(wait=True)
233+
234+
self._http_client = HTTPClient(self._settings)
235+
Controller.instance().setHttpClient(self._http_client)
236+
216237
def shouldLocalServerAutoStart(self):
217238
"""
218239
Returns either the local server
@@ -357,11 +378,6 @@ def _findUnusedLocalPort(self, host):
357378
s.bind((host, 0))
358379
return s.getsockname()[1]
359380

360-
def httpClient(self):
361-
if self._http_client is None:
362-
self._http_client = HTTPClient(self._settings)
363-
return self._http_client
364-
365381
def startLocalServer(self):
366382
"""
367383
Starts the local server process.

gns3/main_window.py

-2
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,6 @@ def startupLoading(self):
969969

970970
# start and connect to the local server if needed
971971
LocalServer.instance().localServerAutoStart()
972-
Controller.instance().setHttpClient(LocalServer.instance().httpClient())
973972

974973
# start the GNS3 VM
975974
# FIXME: run in a thead to wait for the VM to be started
@@ -986,7 +985,6 @@ def startupLoading(self):
986985
# if progress_dialog.exec_():
987986
# pass
988987
# #gns3_vm.adjustLocalServerIP()
989-
# Controller.instance().setHttpClient(gns3_vm.httpClient())
990988

991989
# show the setup wizard
992990
if not self._settings["hide_setup_wizard"]:# and not gns3_vm.isRunning():

gns3/pages/server_preferences_page.py

+24-22
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from ..topology import Topology
3333
from ..utils.message_box import MessageBox
3434
from ..utils.progress_dialog import ProgressDialog
35-
from ..utils.wait_for_connection_worker import WaitForConnectionWorker
3635
from ..settings import LOCAL_SERVER_SETTINGS, SERVERS_SETTINGS
3736
from ..gns3_vm import GNS3VM
3837
from ..dialogs.edit_compute_dialog import EditComputeDialog
@@ -75,9 +74,6 @@ def __init__(self, parent=None):
7574
# load all available addresses
7675
for address in QtNetwork.QNetworkInterface.allAddresses():
7776
address_string = address.toString()
78-
# if address.protocol() == QtNetwork.QAbstractSocket.IPv6Protocol:
79-
# we do not want the scope id when using an IPv6 address...
80-
# address.setScopeId("")
8177
self.uiLocalServerHostComboBox.addItem(address_string, address.toString())
8278

8379
# default is 127.0.0.1
@@ -185,17 +181,19 @@ def _useLocalServerAutoStartSlot(self, state):
185181
"""
186182

187183
if state:
188-
self.uiGeneralSettingsGroupBox.setEnabled(True)
189-
self.uiConsolePortRangeGroupBox.setEnabled(True)
190-
self.uiUDPPortRangeGroupBox.setEnabled(True)
184+
self.uiGeneralSettingsGroupBox.setVisible(True)
185+
self.uiConsolePortRangeGroupBox.setVisible(True)
186+
self.uiUDPPortRangeGroupBox.setVisible(True)
187+
self.uiRemoteMainServerGroupBox.setVisible(False)
191188
else:
192189
if self.uiEnableVMCheckBox.isChecked() and not self.uiRemoteRadioButton.isChecked():
193190
QtWidgets.QMessageBox.critical(self, "Local GNS3 VM", "The local server need to be enable in order to use a local GNS3 VM. Please deactivate the local GNS3 VM before turning off the local server.")
194191
self.uiLocalServerAutoStartCheckBox.setChecked(True)
195192
return
196-
self.uiGeneralSettingsGroupBox.setEnabled(False)
197-
self.uiConsolePortRangeGroupBox.setEnabled(False)
198-
self.uiUDPPortRangeGroupBox.setEnabled(False)
193+
self.uiRemoteMainServerGroupBox.setVisible(True)
194+
self.uiGeneralSettingsGroupBox.setVisible(False)
195+
self.uiConsolePortRangeGroupBox.setVisible(False)
196+
self.uiUDPPortRangeGroupBox.setVisible(False)
199197

200198
def _restoreDefaultsSlot(self):
201199
"""
@@ -293,7 +291,16 @@ def _populateWidgets(self, servers_settings, vm_settings):
293291
if index != -1:
294292
self.uiLocalServerHostComboBox.setCurrentIndex(index)
295293
self.uiLocalServerPortSpinBox.setValue(servers_settings["port"])
294+
295+
self.uiRemoteMainServerHostLineEdit.setText(servers_settings["host"])
296+
self.uiRemoteMainServerPortSpinBox.setValue(servers_settings["port"])
297+
self.uiRemoteMainServerUserLineEdit.setText(servers_settings["user"])
298+
self.uiRemoteMainServerPasswordLineEdit.setText(servers_settings["password"])
299+
self.uiRemoteMainServerProtocolComboBox.setCurrentText(servers_settings["protocol"])
300+
296301
self.uiLocalServerAutoStartCheckBox.setChecked(servers_settings["auto_start"])
302+
self._useLocalServerAutoStartSlot(servers_settings["auto_start"])
303+
297304
self.uiLocalServerAuthCheckBox.setChecked(servers_settings["auth"])
298305
self.uiConsoleConnectionsToAnyIPCheckBox.setChecked(servers_settings["allow_console_from_anywhere"])
299306
self.uiConsoleStartPortSpinBox.setValue(servers_settings["console_start_port_range"])
@@ -410,10 +417,13 @@ def savePreferences(self):
410417
MessageBox(self, "Local server", "Please close your project or delete all the nodes running on the local server before changing the local server settings")
411418
return
412419
LocalServer.instance().updateLocalServerSettings(new_local_server_settings)
413-
restart_local_server = True
414420
else:
421+
new_local_server_settings["host"] = self.uiRemoteMainServerHostLineEdit.text()
422+
new_local_server_settings["port"] = self.uiRemoteMainServerPortSpinBox.value()
423+
new_local_server_settings["protocol"] = self.uiRemoteMainServerProtocolComboBox.currentText()
424+
new_local_server_settings["user"] = self.uiRemoteMainServerUserLineEdit.text()
425+
new_local_server_settings["password"] = self.uiRemoteMainServerPasswordLineEdit.text()
415426
LocalServer.instance().updateLocalServerSettings(new_local_server_settings)
416-
LocalServer.instance().stopLocalServer(wait=True)
417427

418428
# save the GNS3 VM preferences
419429
# new_gns3vm_settings = servers_settings["vm"].copy()
@@ -471,15 +481,7 @@ def savePreferences(self):
471481
# restart_local_server = True
472482
# self.uiLocalServerHostComboBox.setCurrentIndex(index)
473483
#
474-
# start or restart the local server if required
475-
if restart_local_server:
476-
LocalServer.instance().stopLocalServer(wait=True)
477-
if LocalServer.instance().startLocalServer():
478-
worker = WaitForConnectionWorker(new_local_server_settings["host"], new_local_server_settings["port"])
479-
dialog = ProgressDialog(worker, "Local server", "Connecting...", "Cancel", busy=True, parent=self)
480-
dialog.show()
481-
dialog.exec_()
482-
else:
483-
QtWidgets.QMessageBox.critical(self, "Local server", "Could not start the local server process: {}".format(new_local_server_settings["path"]))
484+
485+
484486

485487
self.loadPreferences()

gns3/settings.py

+1
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
"auth": True,
298298
"user": "",
299299
"password": "",
300+
"protocol": "http",
300301
"console_start_port_range": 5000,
301302
"console_end_port_range": 10000,
302303
"udp_start_port_range": 10000,

gns3/topology.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
from .modules.module_error import ModuleError
4141
from .items.node_item import NodeItem
4242
from .compute_manager import ComputeManager
43-
43+
from .controller import Controller
4444

4545
import logging
4646
log = logging.getLogger(__name__)
@@ -65,6 +65,14 @@ def __init__(self):
6565
self._images = []
6666
self._project = None
6767
self._main_window = None
68+
Controller.instance().connected_signal.connect(self._controllerConnectedSlot)
69+
70+
def _controllerConnectedSlot(self):
71+
"""
72+
We reset current project because the remote controller could have
73+
change location
74+
"""
75+
self.setProject(None)
6876

6977
def setMainWindow(self, main_window):
7078
self._main_window = main_window

0 commit comments

Comments
 (0)