/// <summary>
        /// Create an SSH connection to a remote machine.
        /// </summary>
        /// <param name="remoteSSHConnectionString"></param>
        /// <returns></returns>
        /// <remarks>Should only get called by the _connection initalizer</remarks>
        private async Task <SSHRecoveringConnection> CreateSSHConnectionTo(string remoteSSHConnectionString = null, Action <string> dumpLine = null)
        {
            // Use the default
            remoteSSHConnectionString = remoteSSHConnectionString ?? _machine.RemoteSSHConnectionString;
            Interlocked.Increment(ref NumberOfRecoveringConnections);

            if (_connectionLock != null)
            {
                throw new InvalidOperationException("Connection lock has already been aquired. Interal error");
            }
            _connectionLock = await _gConnectionInterlockLimiter.LockAsync();

            TraceHelpers.TraceInfo(25, $"CreateSSHConnectionTo: Aquired RemoteSSH Lock (free: {_gConnectionInterlockLimiter.CurrentCount})", opt: TraceEventType.Start);

            // Create a recovering connection
            return(new SSHRecoveringConnection(async() =>
            {
                return await Policy
                .Handle <SSHConnectFailureException>()
                .WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) })
                .ExecuteAsync(async() =>
                {
                    var c = new SSHConnectionTunnel(remoteSSHConnectionString);
                    Interlocked.Increment(ref NumberOfSSHTunnels);

                    if (_machine.ConfigureLines != null)
                    {
                        var logForError = new StringBuilder();
                        try
                        {
                            // Don't dump setup unless the user really wants to see it!
                            var localdumper = Environment.Verbose | Environment.CompileDebug
                                    ? dumpLine
                                    : (Action <string>)null;

                            foreach (var line in _machine.ConfigureLines)
                            {
                                var rep = line.Replace("ROOTVersionNumber", ROOTVersionNumber);
                                await c.ExecuteLinuxCommandAsync(rep, processLine: s => RecordLine(logForError, s, localdumper));
                            }
                        }
                        catch (Exception e)
                        {
                            c.Dispose();
                            string errMsg = ReformatLog(logForError);
                            Trace.WriteLine($"Error making a SSH connection: {errMsg}");
                            throw new RemoteBashCommandFailureException($"Error making a SSH connection: {errMsg}", e);
                        }
                    }

                    return c;
                });
            }));
        }
Beispiel #2
0
        public async Task SSHTunnelAddTwo()
        {
            using (var t = new SSHConnectionTunnel(File.ReadLines("testMachineTwo.txt").First()))
            {
                var pid2 = await GetPID(t);

                Assert.IsTrue(pid2 != "");
                Assert.AreEqual(1, t.TunnelCount);
                Console.WriteLine(pid2);

                await t.ExecuteLinuxCommandAsync("export", l => Console.WriteLine(l));
            }
        }