Accessing server web resources locally via SSH

While debugging a web app locally, one might need access to i.e. the database on a server. This can easily be achieved on macOS via

ssh -L 5432: -N

I tried to make this work as a XojoScript before starting the debug process.

var result as string
result = DoShellCommand("ssh -L 5432: -N")

But this obviously doesn’t work, as this script ends in an endless loop. Does anyone have an idea how this can be achieved? Running the bash command asynchronously doesn’t seem to help either.

fwiw… there is a mbs plug-in that allows connection via ssh

1 Like

unfortunately ending up in an endless loop as well. I bet I’m getting something completely wrong …

The problem with doing this in a post-build script is that the shell goes out of scope and terminates the connection. Instead, I suggest doing this in the Open event of your app, wrapped in #if DebugBuild pragmas. I just did this for a user about two weeks ago. Make a properties on the App class called:

SSHShell as Shell
tunnelDidOpen as Boolean

…add the following code to the Open event…

#if DebugBuild
  sshshell = New shell
  AddHandler sshshell.DataAvailable, AddressOf Shell_DataAvailable
  sshshell.ExecuteMode = shell.ExecuteModes.Asynchronous
  Dim cmd As String = "ssh -o ConnectTimeout=15 -L 5432: -N -v &"

  // to let the ssh tunnel get established
  Dim timeout As Integer = Ticks + 60*10
  While Ticks < timeout And Not tunnelDidOpen

  If Ticks >= timeout Then
    // Couldn't establish the SSH Tunnel
    Dim response As String = sshshell.Result
  End If
#EndIf DebugBuild

…and the following method:

Private Sub Shell_DataAvailable(obj As Shell)
  Static data As String
  data = data + obj.ReadAll
  If InStr(data,"Entering interactive session.") > 0 Then
    tunnelDidOpen = True
  End If
End Sub

When you run your app, the tunnel will be started and when it closes, the shell will close and take the tunnel with it.

Edit: I should note that I did this in a Web project where DoEvents is okay in the Opening event. If this were a desktop project, I would suggest instead using a Timer and call a second method to finish launching your app.

1 Like

One word: Brilliant!!

Thank you so much! Works perfectly fine.

For deploying my app from macOS to my linux web server on the internet, I’m using the following Build Script, set to run only for “release”. I called the script “deployToServer” and it has to be positioned after Build in the Linux Build Settings in the Xojo IDE:

var result as string
result = DoShellCommand("/Users/jmu/xojo/myapp/")

The file looks like the following:

echo "STOP myapp Services"
ssh  'sudo systemctl stop myapp.service'
rsync -avz --delete /Users/jmu/xojo/myapp/Builds\ -\ myappLinux\ 64\ bit/myapp/
echo "START myapp Services"
ssh 'sudo systemctl start myapp.service'
exit 0

This bash script stops the running app service on the server, then it deletes the existing content and rsynchs all the data from the build folder to the webserver and then restarts the app service on the server.

Disclaimer: perhaps one needs to adjust the owner and the rights after the rsync, but in my case it is working out-of-the-box.

Prerequisites: you need to run your app via a service. @Tim_Parnell has a script helping you on the necessary steps.