public async Task WriteAsync(ulong offset, byte[] data)
            {
                using (var semLock = await _writeLock.LockAsync().ConfigureAwait(false))
                {
                    if (IsDone)
                    {
                        return;
                    }

                    await Target.WriteAsync(offset, data);

                    WrittenBytes       += (ulong)data.Length;
                    Target.WrittenBytes = WrittenBytes;

                    if (WrittenBytes == ExpectedBytes)
                    {
                        await Target.CompleteAsync().ConfigureAwait(false);

                        IsDone = true;

                        if (_handler.FileDownloaded != null)
                        {
                            _handler.RunEventHandler(() => _handler.FileDownloaded.Invoke(_handler, ManifestFile));
                        }
                    }
                }
            }
        /// <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;
                });
            }));
        }
Esempio n. 3
0
            public async Task WriteAsync(ulong offset, byte[] data)
            {
                using (var semLock = await _writeLock.LockAsync())
                {
                    await Target.WriteAsync(offset, data);

                    WrittenBytes       += (ulong)data.Length;
                    Target.WrittenBytes = WrittenBytes;

                    if (WrittenBytes == ExpectedBytes)
                    {
                        await Target.CompleteAsync();
                    }
                }
            }
Esempio n. 4
0
        public async Task Update()
        {
            // TODO: Ensure only one Update is running across all instances of SMA (in case SMA is closed during the update process)
            // TODO: Offer manual updates
            // TODO: Add option to wait for user confirmation to update

            if (UpdateEnabled == false)
            {
                return;
            }

            try
            {
                if (Wininet.HasNetworking() == false)
                {
                    return;
                }

                CancellationTokenSource cts = new CancellationTokenSource(0);
                cts.Cancel();

                using (await _semaphore.LockAsync(cts.Token))
                    using (var updateMgr = CreateUpdateMgr())
                    {
                        State = SMAUpdateState.Fetching;

                        var updateInfo = await updateMgr.CheckForUpdate(false, progress => ProgressPct = progress);

                        if (updateInfo?.ReleasesToApply == null)
                        {
                            State = SMAUpdateState.Error;
                            return;
                        }

                        if (updateInfo.ReleasesToApply.None())
                        {
                            State = SMAUpdateState.UpToDate;
                            return;
                        }

                        State = SMAUpdateState.Downloading;

                        await updateMgr.DownloadReleases(updateInfo.ReleasesToApply, progress => ProgressPct = progress);

                        State = SMAUpdateState.Applying;

                        await updateMgr.ApplyReleases(updateInfo, progress => ProgressPct = progress);

                        State = SMAUpdateState.CreatingUninstaller;

                        await updateMgr.CreateUninstallerRegistryEntry();

                        State = SMAUpdateState.Updated;
                    }
            }
            catch (TaskCanceledException) {}
            catch (Exception ex) // TODO: Update Squirrel UpdateManager to send sub-classed Exceptions
            {
                LogTo.Warning(ex, $"An exception was caught while {State.Name().ToLower()} update");
                State = SMAUpdateState.Error;
            }
            finally
            {
                _semaphore.Release();
            }
        }