Commit ec68385a authored by Mathieu Westphal's avatar Mathieu Westphal

SSH support

This adds SSH support in the pqServerConfiguration XML file.

Instead of relying to complex .pvsc file, it is now possible to use the following tags to configure connection through SSH:

* `<SSHCommand exec=...>` instead of `<Command exec=...> ` so the command will be executed through SSH
* `<SSHConfig user="user">`, child of `<SSHCommand>` with an optional argument to set the SSH user
* `<Terminal exec=/path/to/term/>`, child of `<SSHConfig>` with an optional terminal executable argument. When this tag is set, the SSH command will be executed through on a new terminal
* `<Askpass/>`, child of `<SSHConfig>`, so an askpass program is used. Make sure to set SSH_ASKPASS and DISPLAY before using this. Incompatible with `<Terminal>` tag, only on Linux.
* `<PortForwarding local="port">`, child of `<SSHConfig>` with an optional local port argument, this is the biggest change. This allow to set up port fowarding through SSH tunneling. If no local port is defined, the server port will be used.

When `PortForwarding` is used, it is completely invisible to the user, remote host and port are correct and not related to the SSH tunelling. In order to inform the user that the communication between client and server are secured, the server icon in the pipeline browser is slightly different.

Example of a simple configuration file:
```XML
<Servers>
  <Server name="SimpleSshServer" configuration="" resource="cs://127.0.0.1:11111">
    <CommandStartup>
      <SSHCommand exec="/home/login/pv/startpvserver.sh" timeout="0" delay="5">
        <SSHConfig user="login">
          <Terminal/>
        </SSHConfig>
        <Arguments>
          <Argument value="$PV_SERVER_PORT$"/>
        </Arguments>
      </SSHCommand>
    </CommandStartup>
  </Server>
</Servers>
```

Also, the new environment variable `PV_SSH_PF_SERVER_PORT` should be set when performing reverse connection with  port forwarding.

In order to be able to use it you need:
 * On Linux: any terminal emulator, ssh (default on most distributions) and ssh_askpass if needed
 * On Windows: Preferably an installed Putty (plink), alternatively, windows 10 spring update SSH client, and cmd.exe (default)
 * On MacOS: Terminal.app and ssh (both default)
parent ad657b8e
......@@ -783,6 +783,59 @@ if (EXISTS "${smooth_flash}")
endforeach()
endif()
option(PARAVIEW_SSH_SERVERS_TESTING
"Add SSH Servers testing"
OFF)
mark_as_advanced(PARAVIEW_SSH_SERVERS_TESTING)
if(PARAVIEW_SSH_SERVERS_TESTING)
message(STATUS
"With PARAVIEW_SSH_SERVERS_TESTING, to have the SSH Server tests pass, make sure that this machine has its own ssh public key as an authorized_keys and that 127.0.0.1 is in the known_hosts file, /usr/bin/xterm is available. In case of failing tests, pvserver logs are available in ${CMAKE_CURRENT_BINARY_DIR}")
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/server.sh.in"
"${CMAKE_CURRENT_BINARY_DIR}/tmp/server.sh" @ONLY)
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/server_rc.sh.in"
"${CMAKE_CURRENT_BINARY_DIR}/tmp/server_rc.sh" @ONLY)
file(
COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/server.sh
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
file(
COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/server_rc.sh
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/sshServers.pvsc.in"
"${CMAKE_CURRENT_BINARY_DIR}/sshServers.pvsc" @ONLY)
set(ssh_server_tests
SimpleSSHServer
SimpleSSHServerAskPass
SimpleSSHServerTermExec
SimpleRCSSHServer
SSHServerPortForwarding
RCSSHServerPortForwarding
)
foreach(tname IN LISTS ssh_server_tests)
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/${tname}.xml.in"
"${CMAKE_CURRENT_BINARY_DIR}/${tname}.xml" @ONLY)
list(APPEND TESTS_WITHOUT_BASELINES
${CMAKE_CURRENT_BINARY_DIR}/${tname}.xml)
set(${tname}_DISABLE_CS TRUE)
set(${tname}_DISABLE_CRS TRUE)
endforeach()
endif(PARAVIEW_SSH_SERVERS_TESTING)
#------------------------------------------------------------------------------
# Probe picking does not work in render server mode
......
<?xml version="1.0" ?>
<pqevents>
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerConnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/load" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/LoadServerConfigurationDialog" command="filesSelected" arguments="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/sshServers.pvsc" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCurrent" arguments="0.0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCheckState" arguments="0.0,0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/connect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionOpenData" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/FileOpenDialog" command="filesSelected" arguments="$PARAVIEW_DATA_ROOT/can.ex2" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerDisconnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/1QMessageBox0/qt_msgbox_buttonbox/1QPushButton0" command="activate" arguments="" />
</pqevents>
<?xml version="1.0" ?>
<pqevents>
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerConnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/load" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/LoadServerConfigurationDialog" command="filesSelected" arguments="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/sshServers.pvsc" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCurrent" arguments="1.0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCheckState" arguments="1.0,0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/connect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionOpenData" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/FileOpenDialog" command="filesSelected" arguments="$PARAVIEW_DATA_ROOT/can.ex2" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerDisconnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/1QMessageBox0/qt_msgbox_buttonbox/1QPushButton0" command="activate" arguments="" />
</pqevents>
<?xml version="1.0" ?>
<pqevents>
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerConnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/load" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/LoadServerConfigurationDialog" command="filesSelected" arguments="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/sshServers.pvsc" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCurrent" arguments="2.0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCheckState" arguments="2.0,0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/connect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionOpenData" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/FileOpenDialog" command="filesSelected" arguments="$PARAVIEW_DATA_ROOT/can.ex2" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerDisconnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/1QMessageBox0/qt_msgbox_buttonbox/1QPushButton0" command="activate" arguments="" />
</pqevents>
<?xml version="1.0" ?>
<pqevents>
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerConnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/load" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/LoadServerConfigurationDialog" command="filesSelected" arguments="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/sshServers.pvsc" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCurrent" arguments="3.0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCheckState" arguments="3.0,0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/connect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionOpenData" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/FileOpenDialog" command="filesSelected" arguments="$PARAVIEW_DATA_ROOT/can.ex2" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerDisconnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/1QMessageBox0/qt_msgbox_buttonbox/1QPushButton0" command="activate" arguments="" />
</pqevents>
<?xml version="1.0" ?>
<pqevents>
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerConnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/load" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/LoadServerConfigurationDialog" command="filesSelected" arguments="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/sshServers.pvsc" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCurrent" arguments="4.0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCheckState" arguments="4.0,0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/connect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionOpenData" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/FileOpenDialog" command="filesSelected" arguments="$PARAVIEW_DATA_ROOT/can.ex2" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerDisconnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/1QMessageBox0/qt_msgbox_buttonbox/1QPushButton0" command="activate" arguments="" />
</pqevents>
<?xml version="1.0" ?>
<pqevents>
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerConnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/load" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/LoadServerConfigurationDialog" command="filesSelected" arguments="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/sshServers.pvsc" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCurrent" arguments="5.0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/servers" command="setCheckState" arguments="5.0,0" />
<pqevent object="pqClientMainWindow/pqServerConnectDialog/stackedWidget/page_choose/connect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionOpenData" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/FileOpenDialog" command="filesSelected" arguments="$PARAVIEW_DATA_ROOT/can.ex2" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/MainControlsToolbar/actionServerDisconnect" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/1QMessageBox0/qt_msgbox_buttonbox/1QPushButton0" command="activate" arguments="" />
</pqevents>
DISPLAY=:0 @ParaView_BINARY_DIR@/bin/pvserver -sp=$1 2>&1 | tee sshServer.log
DISPLAY=:0 @ParaView_BINARY_DIR@/bin/pvserver -rc -ch=$1 -sp=$2 | tee sshServer.log
<Servers>
<Server name="SimpleSshServer" configuration="" resource="cs://127.0.0.1:11111">
<CommandStartup>
<SSHCommand exec="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/server.sh" timeout="0" delay="5">
<SSHConfig>
<Terminal/>
</SSHConfig>
<Arguments>
<Argument value="$PV_SERVER_PORT$"/>
</Arguments>
</SSHCommand>
</CommandStartup>
</Server>
<Server name="SimpleSshServerAskpass" configuration="" resource="cs://127.0.0.1:11111">
<CommandStartup>
<SSHCommand exec="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/server.sh" timeout="0" delay="5">
<SSHConfig>
<Askpass/>
</SSHConfig>
<Arguments>
<Argument value="$PV_SERVER_PORT$"/>
</Arguments>
</SSHCommand>
</CommandStartup>
</Server>
<Server name="SimpleSshServerTermExec" configuration="" resource="cs://127.0.0.1:11111">
<CommandStartup>
<SSHCommand exec="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/server.sh" timeout="0" delay="5">
<SSHConfig>
<Terminal exec="/usr/bin/xterm"/>
</SSHConfig>
<Arguments>
<Argument value="$PV_SERVER_PORT$"/>
</Arguments>
</SSHCommand>
</CommandStartup>
</Server>
<Server name="SimpleRCSshServer" configuration="" resource="csrc://127.0.0.1:11111">
<CommandStartup>
<SSHCommand exec="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/server_rc.sh" timeout="0" delay="5">
<SSHConfig>
<Terminal/>
</SSHConfig>
<Arguments>
<Argument value="$PV_CLIENT_HOST$"/>
<Argument value="$PV_SERVER_PORT$"/>
</Arguments>
</SSHCommand>
</CommandStartup>
</Server>
<Server name="SSHPortForwardingServer" configuration="" resource="cs://127.0.0.1:11111">
<CommandStartup>
<SSHCommand exec="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/server.sh" timeout="0" delay="5">
<SSHConfig>
<Terminal/>
<PortForwarding local="8080"/>
</SSHConfig>
<Arguments>
<Argument value="$PV_SERVER_PORT$"/>
</Arguments>
</SSHCommand>
</CommandStartup>
</Server>
<Server name="SSHPortForwardingRCServer" configuration="" resource="csrc://127.0.0.1:11114">
<CommandStartup>
<SSHCommand exec="@ParaView_BINARY_DIR@/Applications/ParaView/Testing/XML/server_rc.sh" timeout="0" delay="5">
<SSHConfig>
<Terminal/>
<PortForwarding local="8080"/>
</SSHConfig>
<Arguments>
<Argument value="localhost"/>
<Argument value="$PV_SSH_PF_SERVER_PORT$"/>
</Arguments>
</SSHCommand>
</CommandStartup>
</Server>
</Servers>
This adds SSH support in the pqServerConfiguration XML file.
Instead of relying to complex .pvsc file, it is now possible to use the following tags to configure connection through SSH:
* `<SSHCommand exec=...>` instead of `<Command exec=...> ` so the command will be executed through SSH
* `<SSHConfig user="user">`, child of `<SSHCommand>` with an optional argument to set the SSH user
* `<Terminal exec=/path/to/term/>`, child of `<SSHConfig>` with an optional terminal executable argument. When this tag is set, the SSH command will be executed through on a new terminal
* `<Askpass/>`, child of `<SSHConfig>`, so an askpass program is used. Make sure to set SSH_ASKPASS and DISPLAY before using this. Incompatible with `<Terminal>` tag, only on Linux.
* `<PortForwarding local="port">`, child of `<SSHConfig>` with an optional local port argument, this is the biggest change. This allow to set up port fowarding through SSH tunneling. If no local port is defined, the server port will be used.
When `PortForwarding` is used, it is completely invisible to the user, remote host and port are correct and not related to the SSH tunelling. In order to inform the user that the communication between client and server are secured, the server icon in the pipeline browser is slightly different.
Example of a simple configuration file:
```XML
<Servers>
<Server name="SimpleSshServer" configuration="" resource="cs://127.0.0.1:11111">
<CommandStartup>
<SSHCommand exec="/home/login/pv/startpvserver.sh" timeout="0" delay="5">
<SSHConfig user="login">
<Terminal/>
</SSHConfig>
<Arguments>
<Argument value="$PV_SERVER_PORT$"/>
</Arguments>
</SSHCommand>
</CommandStartup>
</Server>
</Servers>
```
Also, the new environment variable `PV_SSH_PF_SERVER_PORT` should be set when performing reverse connection with port forwarding.
In order to be able to use it you need:
* On Linux: any terminal emulator, ssh (default on most distributions) and ssh_askpass if needed
* On Windows: Preferably an installed Putty (plink), alternatively, windows 10 spring update SSH client, and cmd.exe (default)
* On MacOS: Terminal.app and ssh (both default)
......@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqLoadStateReaction.h"
#include "pqRecentlyUsedResourcesList.h"
#include "pqServer.h"
#include "pqServerConfiguration.h"
#include "pqServerResource.h"
#include <QFileInfo>
......@@ -178,7 +179,13 @@ bool pqStandardRecentlyUsedResourceLoaderImplementation::addDataFilesToRecentRes
{
if (server)
{
// Needed to get the display resource in case of port forwarding
pqServerResource resource = server->getResource();
pqServerConfiguration config = resource.configuration();
if (!config.isNameDefault())
{
resource = config.resource();
}
resource.setPath(files[0]);
resource.addData("PARAVIEW_DATA", "1");
......@@ -203,11 +210,19 @@ bool pqStandardRecentlyUsedResourceLoaderImplementation::addStateFileToRecentRes
{
if (server)
{
// Needed to get the display resource in case of port forwarding
pqServerResource tmpResource = server->getResource();
pqServerConfiguration config = tmpResource.configuration();
if (!config.isNameDefault())
{
tmpResource = config.resource();
}
// Add this to the list of recent server resources ...
pqServerResource resource;
resource.setScheme("session");
resource.setPath(filename);
resource.setSessionServer(server->getResource());
resource.setSessionServer(tmpResource);
resource.addData("PARAVIEW_STATE", "1");
pqApplicationCore* core = pqApplicationCore::instance();
core->recentlyUsedResources().add(resource);
......@@ -224,8 +239,15 @@ bool pqStandardRecentlyUsedResourceLoaderImplementation::addCinemaDatabaseToRece
{
if (server)
{
// Add this to the list of recent server resources ...
// Needed to get the display resource in case of port forwarding
pqServerResource resource = server->getResource();
pqServerConfiguration config = resource.configuration();
if (!config.isNameDefault())
{
resource = config.resource();
}
// Add this to the list of recent server resources ...
resource.setPath(filename);
resource.addData("PARAVIEW_CINEMA_DATABASE", "1");
......
......@@ -193,6 +193,7 @@
<file>Icons/pqScalarBar16.png</file>
<file>Icons/pqScalarBar24.png</file>
<file>Icons/pqScalarBar32.png</file>
<file>Icons/pqSecureServer16.png</file>
<file>Icons/pqSelect16.png</file>
<file>Icons/pqSelect24.png</file>
<file>Icons/pqSelect32.png</file>
......
......@@ -91,6 +91,7 @@ public:
enum IconType
{
SERVER,
SECURE_SERVER,
LINK,
GEOMETRY,
BAGCHART,
......@@ -214,6 +215,11 @@ public:
case pqPipelineModel::Server:
{
pqServer* server = qobject_cast<pqServer*>(this->Object);
if (server->getResource().configuration().isPortForwarding())
{
return SECURE_SERVER;
}
vtkSMLiveInsituLinkProxy* proxy = pqLiveInsituManager::linkProxy(server);
return proxy ? ((vtkSMPropertyHelper(proxy, "SimulationPaused").GetAs<int>() == 1)
? INSITU_SERVER_PAUSED
......@@ -466,6 +472,8 @@ void pqPipelineModel::constructor()
this->PixmapList = new QPixmap[pqPipelineModelDataItem::LAST + 1];
this->PixmapList[pqPipelineModelDataItem::SERVER].load(":/pqWidgets/Icons/pqServer16.png");
this->PixmapList[pqPipelineModelDataItem::SECURE_SERVER].load(
":/pqWidgets/Icons/pqSecureServer16.png");
this->PixmapList[pqPipelineModelDataItem::LINK].load(":/pqWidgets/Icons/pqLinkBack16.png");
this->PixmapList[pqPipelineModelDataItem::GEOMETRY].load(":/pqWidgets/Icons/pq3DView16.png");
this->PixmapList[pqPipelineModelDataItem::BAGCHART].load(":/pqWidgets/Icons/pqBagChart16.png");
......@@ -799,7 +807,7 @@ QVariant pqPipelineModel::data(const QModelIndex& idx, int role) const
int time = server->getRemainingLifeTime();
QString timeLeft =
time > -1 ? QString(" (%1min left)").arg(QString::number(time)) : QString();
return QString("%1 (%2)%3").arg(name).arg(resource.toURI()).arg(timeLeft);
return QString("%1 (%2)%3").arg(name).arg(resource.configuration().URI()).arg(timeLeft);
}
else
{
......
......@@ -144,10 +144,18 @@ void pqRecentFilesMenu::buildMenu()
QString key;
if (this->SortByServers)
{
pqServerResource hostResource = (resource.scheme() == "session")
? resource.sessionServer().schemeHostsPorts()
: resource.schemeHostsPorts();
key = hostResource.toURI();
pqServerConfiguration config = resource.configuration();
if (config.isNameDefault())
{
pqServerResource hostResource = (resource.scheme() == "session")
? resource.sessionServer().schemeHostsPorts()
: resource.schemeHostsPorts();
key = hostResource.toURI();
}
else
{
key = resource.configuration().URI();
}
}
clusteredResources[key].push_back(resource);
}
......
......@@ -401,6 +401,9 @@ void pqServerConnectDialog::editConfiguration(const pqServerConfiguration& confi
{
type = CLIENT_SERVER_REVERSE_CONNECT;
this->Internals->port->setValue(configuration.resource().port(11111));
// set the host the the remote server name is correct, even if it not used for connecting.
this->Internals->host->setText(configuration.resource().host());
}
else if (scheme == "cdsrs")
{
......@@ -415,6 +418,10 @@ void pqServerConnectDialog::editConfiguration(const pqServerConfiguration& confi
type = CLIENT_DATA_SERVER_RENDER_SERVER_REVERSE_CONNECT;
this->Internals->dataServerPort->setValue(configuration.resource().dataServerPort(11111));
this->Internals->renderServerPort->setValue(configuration.resource().renderServerPort(22222));
// set the host the the remote server name is correct, even if it not used for connecting.
this->Internals->dataServerHost->setText(configuration.resource().dataServerHost());
this->Internals->renderServerHost->setText(configuration.resource().renderServerHost());
}
this->Internals->type->setCurrentIndex(type);
this->updateServerType();
......@@ -511,7 +518,7 @@ void pqServerConnectDialog::acceptConfigurationPage1()
case CLIENT_SERVER_REVERSE_CONNECT:
resource.setScheme("csrc");
resource.setHost("localhost");
resource.setHost(this->Internals->host->text());
resource.setPort(this->Internals->port->value());
break;
......@@ -525,9 +532,9 @@ void pqServerConnectDialog::acceptConfigurationPage1()
case CLIENT_DATA_SERVER_RENDER_SERVER_REVERSE_CONNECT:
resource.setScheme("cdsrsrc");
resource.setDataServerHost("localhost");
resource.setDataServerHost(this->Internals->dataServerHost->text());
resource.setDataServerPort(this->Internals->dataServerPort->value());
resource.setRenderServerHost("localhost");
resource.setRenderServerHost(this->Internals->renderServerHost->text());
resource.setRenderServerPort(this->Internals->renderServerPort->value());
break;
......@@ -556,7 +563,7 @@ void pqServerConnectDialog::editServerStartup()
{
double delay, timeout;
this->Internals->startup_type->setCurrentIndex(1);
this->Internals->commandLine->setText(config.command(timeout, delay));
this->Internals->commandLine->setText(config.execCommand(timeout, delay));
this->Internals->delay->setValue(delay);
}
break;
......
......@@ -208,6 +208,7 @@ QProcessEnvironment getDefaultEnvironment(const pqServerConfiguration& configura
options.insert("PV_VERSION_FULL", PARAVIEW_VERSION_FULL);
options.insert("PV_SERVER_HOST", resource.host());
options.insert("PV_SERVER_PORT", QString::number(resource.port(11111)));
options.insert("PV_SSH_PF_SERVER_PORT", configuration.portForwardingLocalPort());
options.insert("PV_DATA_SERVER_HOST", resource.dataServerHost());
options.insert("PV_DATA_SERVER_PORT", QString::number(resource.dataServerPort(11111)));
options.insert("PV_RENDER_SERVER_HOST", resource.renderServerHost());
......@@ -623,7 +624,7 @@ bool pqServerLauncher::connectToPrelaunchedServer()
dialog.activateWindow();
}
const pqServerResource& resource = this->Internals->Configuration.resource();
const pqServerResource& resource = this->Internals->Configuration.actualResource();
this->Internals->Server =
builder->createServer(resource, this->Internals->Configuration.connectionTimeout());
return this->Internals->Server != NULL;
......@@ -632,7 +633,7 @@ bool pqServerLauncher::connectToPrelaunchedServer()
//-----------------------------------------------------------------------------
bool pqServerLauncher::isReverseConnection() const
{
const pqServerResource& resource = this->Internals->Configuration.resource();
const pqServerResource& resource = this->Internals->Configuration.actualResource();
return (resource.scheme() == "csrc" || resource.scheme() == "cdsrsrc");
}
......@@ -737,7 +738,7 @@ bool pqServerLauncher::launchServer(bool show_status_dialog)
}
// replace all $FOO$ with values for QProcessEnvironment.
QRegExp regex("\\$([^$]*)\\$");
QRegExp regex("\\$([^$ ]*)\\$");
// Do string-substitution for the command line.
while (regex.indexIn(command) > -1)
......
......@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqApplicationCore.h"
#include "pqFileDialogModel.h"
#include "pqServer.h"
#include "pqServerConfiguration.h"
#include "pqServerResource.h"
#include "pqSettings.h"
......@@ -59,7 +60,7 @@ pqFileDialogRecentDirsModel::pqFileDialogRecentDirsModel(
// from the pqSettings. If server==NULL, we use the "builtin:" resource.
pqServerResource resource = server ? server->getResource() : pqServerResource("builtin:");
QString uri = resource.toURI();
QString uri = resource.configuration().URI();
pqApplicationCore* core = pqApplicationCore::instance();
pqSettings* settings = core->settings();
......
This diff is collapsed.
......@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define pqServerConfiguration_h
#include "pqCoreModule.h"
#include "pqServerResource.h"
#include "vtkSmartPointer.h"
#include <QObject>
......@@ -77,11 +78,27 @@ public:
bool isNameDefault() const;
/**
* Get/Set the URI that describes the server scheme, hostname(s) and port(s).
* Get/Set the resource that describes the server scheme, hostname(s) and port(s).
*/
pqServerResource resource() const;
void setResource(const pqServerResource&);
void setResource(const QString&);
void setResource(const pqServerResource&);
/**
* Get the actual resource that describes the server scheme, hostname(s) and port(s).
* Can be different from resource() when using SSH Port Forwarding as it will point to
* ip and port actually used for the tcp connection,
* which can be different than the server where the pvserver is running.
* eg. it will give you localhost:8080, instead of serverip:serverport when using port forwarding.
* Using this method is needed only when using low level tcp api.
* ressource() method should be used in any other cases.
*/
pqServerResource actualResource() const;
/**
* get the resource URI
*/
QString URI() const;
/**
* Get/Set the timeout in seconds that will be used when connecting
......@@ -108,11 +125,24 @@ public:
/**
* If startupType() == COMMAND, then this method can be used to obtain
* the command for the startup. Note that this does not include any
* information options etc. that may be specified in the startup.
* the command for the startup, from the client side.
* Note that this does not include any information options etc.
* that may be specified in the startup.
* This is the full command to be executed on the client,
* which includes xterm, ssh...
*/
QString command(double& timeout, double& delay) const;
/**
* If startupType() == COMMAND, then this method can be used to obtain
* the command for the startup, on the remote server,
* contained in the exec attributes.
* Note that this does not include any information options etc.
* that may be specified in the startup. This also
* recovers timeout and delay attributes.
*/
QString execCommand(double& timeout, double& delay) const;
/**
* changes the startup type to manual.
*/
......@@ -143,14 +173,39 @@ public:
*/
vtkPVXMLElement* hintsXML() const;
/**
* Get if this is a port forwarding configuration.
* PortForwardingConfiguration uses SSH tunneling
* and is configured directly in xml server file
*/
bool isPortForwarding() const { return this->PortForwarding; };
/**
* Get the port forwarding local port.
* Initialized by the server xml if port forwarding is used.
* Equal to the ressource port if port forwarding is not used.
*/
QString portForwardingLocalPort() const;
protected:
vtkPVXMLElement* startupXML() const;
void parseSshPortForwardingXML();
QString sshFullCommand(QString sshCommand, vtkPVXMLElement* sshConfigXML) const;
static QString termCommand();
static QString sshCommand();
static QString lookForCommand(QString command);
private:
void constructor(vtkPVXMLElement*, int connectionTimeout = 60);
bool Mutable;
int ConnectionTimeout;
vtkSmartPointer<vtkPVXMLElement> XML;
bool PortForwarding;
bool SSHCommand;
QString PortForwardingLocalPort;
QString ActualURI;
};
#endif
......@@ -117,6 +117,8 @@ public:
/**
* Returns a compact string representation of the resource in URI format
* Prefer using configuration->URI() if a configuration is available
* and not default.
*/
const QString toURI() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment