Exemple #1
0
        private static SshCommand ExecuteCommand(SshClient client, string commandText)
        {
            ConsoleManager.WriteLine("SSH TX:");
            ConsoleManager.WriteLine(commandText, ConsoleColor.Green);


            using (var command = client.CreateCommand(commandText))
            {
                var result = command.Execute();
                ConsoleManager.WriteLine("SSH RX:");

                if (command.ExitStatus != 0)
                {
                    ConsoleManager.ErrorWriteLine("Error " + command.ExitStatus);
                    ConsoleManager.ErrorWriteLine(command.Error);
                }

                if (string.IsNullOrWhiteSpace(result) == false)
                {
                    ConsoleManager.WriteLine(result, ConsoleColor.Yellow);
                }

                return(command);
            }
        }
Exemple #2
0
        /// <summary>
        /// Starts the monitor mode.
        /// </summary>
        /// <param name="fsMonitor">The fs monitor.</param>
        /// <param name="sshClient">The SSH client.</param>
        /// <param name="sftpClient">The SFTP client.</param>
        /// <param name="shellStream">The shell stream.</param>
        /// <param name="verbOptions">The verb options.</param>
        private static void StartMonitorMode(FileSystemMonitor fsMonitor, SshClient sshClient, SftpClient sftpClient, ShellStream shellStream, MonitorVerbOptions verbOptions)
        {
            fsMonitor.FileSystemEntryChanged += (s, e) =>
            {
                // Detect changes to the monitor file by ignoring deletions and checking file paths.
                if (e.ChangeType != FileSystemEntryChangeType.FileAdded && e.ChangeType != FileSystemEntryChangeType.FileModified)
                {
                    return;
                }

                // If the change was not in the monitor file, then ignore it
                if (e.Path.ToLowerInvariant().Equals(verbOptions.MonitorFile.ToLowerInvariant()) == false)
                {
                    return;
                }

                // Create a new deployment once
                CreateNewDeployment(sshClient, sftpClient, shellStream, verbOptions);
            };

            fsMonitor.Start();
            ConsoleManager.WriteLine("File System Monitor is now running.");
            ConsoleManager.WriteLine("Writing a new monitor file will trigger a new deployment.");
            ConsoleManager.WriteLine("Press H for help!");
            ConsoleManager.WriteLine("Ground Control to Major Tom: Have a nice trip in space!", ConsoleColor.DarkCyan);
        }
Exemple #3
0
 /// <summary>
 /// Prepares the given target path for deployment. If clean target is false, it does nothing.
 /// </summary>
 /// <param name="sftpClient">The SFTP client.</param>
 /// <param name="targetPath">The target path.</param>
 /// <param name="cleanTarget">if set to <c>true</c> [clean target].</param>
 private static void PrepareTargetPath(SftpClient sftpClient, MonitorVerbOptions verbOptions)
 {
     if (verbOptions.CleanTarget == 0)
     {
         return;
     }
     ConsoleManager.WriteLine("    Cleaning Target Path '" + verbOptions.TargetPath + "'", ConsoleColor.Green);
     DeleteLinuxDirectoryRecursive(sftpClient, verbOptions.TargetPath);
 }
Exemple #4
0
        /// <summary>
        /// Creates the given directory structure on the target machine.
        /// </summary>
        /// <param name="sftpClient">The SFTP client.</param>
        /// <param name="targetPath">The target path.</param>
        private static void CreateTargetPath(SftpClient sftpClient, MonitorVerbOptions verbOptions)
        {
            if (sftpClient.Exists(verbOptions.TargetPath) == true)
            {
                return;
            }

            ConsoleManager.WriteLine("    Target Path '" + verbOptions.TargetPath + "' does not exist. -- Will attempt to create.", ConsoleColor.Green);
            CreateLinuxDirectoryRecursive(sftpClient, verbOptions.TargetPath);
            ConsoleManager.WriteLine("    Target Path '" + verbOptions.TargetPath + "' created successfully.", ConsoleColor.Green);
        }
Exemple #5
0
        /// <summary>
        /// Checks that both, SFTP and SSH clients have a working connection. If they don't it attempts to reconnect.
        /// </summary>
        /// <param name="sshClient">The SSH client.</param>
        /// <param name="sftpClient">The SFTP client.</param>
        /// <param name="verbOptions">The verb options.</param>
        private static void EnsureMonitorConnection(SshClient sshClient, SftpClient sftpClient, MonitorVerbOptions verbOptions)
        {
            if (sshClient.IsConnected == false)
            {
                ConsoleManager.WriteLine("Connecting to host " + verbOptions.Host + ":" + verbOptions.Port + " via SSH.");
                sshClient.Connect();
            }

            if (sftpClient.IsConnected == false)
            {
                ConsoleManager.WriteLine("Connecting to host " + verbOptions.Host + ":" + verbOptions.Port + " via SFTP.");
                sftpClient.Connect();
            }
        }
Exemple #6
0
        /// <summary>
        /// Runs pre and post deployment commands over the SSH client
        /// </summary>
        /// <param name="sshClient">The SSH client.</param>
        /// <param name="commandText">The command text.</param>
        private static void RunShellStreamCommand(ShellStream shellStream, MonitorVerbOptions verbOptions)
        {
            var commandText = verbOptions.PostCommand;

            if (string.IsNullOrWhiteSpace(commandText) == true)
            {
                return;
            }

            ConsoleManager.WriteLine("    Executing shell command.", ConsoleColor.Green);
            shellStream.WriteLine(commandText);
            shellStream.Flush();
            ConsoleManager.WriteLine("    TX: " + commandText, ConsoleColor.DarkYellow);
        }
Exemple #7
0
 /// <summary>
 /// Prints the currently supplied monitor mode options.
 /// </summary>
 /// <param name="verbOptions">The verb options.</param>
 /// <param name="monitorFile">The monitor file.</param>
 /// <param name="sourcePath">The source path.</param>
 /// <param name="targetPath">The target path.</param>
 private static void PrintMonitorOptions(MonitorVerbOptions verbOptions)
 {
     ConsoleManager.WriteLine(string.Empty);
     ConsoleManager.WriteLine("Monitor mode starting");
     ConsoleManager.WriteLine("Monitor parameters follow: ");
     ConsoleManager.WriteLine("    Monitor File    " + verbOptions.MonitorFile, ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Source Path     " + verbOptions.SourcePath, ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Excluded Files  " + verbOptions.ExcludeFileSuffixes, ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Target Address  " + verbOptions.Host + ":" + verbOptions.Port.ToString(), ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Username        " + verbOptions.Username, ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Target Path     " + verbOptions.TargetPath, ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Clean Target    " + (verbOptions.CleanTarget == 0 ? "NO" : "YES"), ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Pre Deployment  " + verbOptions.PreCommand, ConsoleColor.DarkYellow);
     ConsoleManager.WriteLine("    Post Deployment " + verbOptions.PostCommand, ConsoleColor.DarkYellow);
 }
Exemple #8
0
        /// <summary>
        /// Runs the deployment command.
        /// </summary>
        /// <param name="sshClient">The SSH client.</param>
        /// <param name="commandText">The command text.</param>
        private static void RunSshClientCommand(SshClient sshClient, MonitorVerbOptions verbOptions)
        {
            var commandText = verbOptions.PreCommand;

            if (string.IsNullOrWhiteSpace(commandText) == true)
            {
                return;
            }

            ConsoleManager.WriteLine("    Executing SSH client command.", ConsoleColor.Green);
            var result = sshClient.RunCommand(commandText);

            ConsoleManager.WriteLine(string.Format("    SSH TX: {0}", commandText), ConsoleColor.DarkYellow);
            ConsoleManager.WriteLine(string.Format("    SSH RX: [{0}] ", result.ExitStatus, result.Result), ConsoleColor.DarkYellow);
        }
Exemple #9
0
        /// <summary>
        /// Creates a new deployment cycle.
        /// </summary>
        /// <param name="sshClient">The SSH client.</param>
        /// <param name="sftpClient">The SFTP client.</param>
        /// <param name="shellStream">The shell stream.</param>
        /// <param name="verbOptions">The verb options.</param>
        private static void CreateNewDeployment(SshClient sshClient, SftpClient sftpClient, ShellStream shellStream, MonitorVerbOptions verbOptions)
        {
            // At this point the change has been detected; Make sure we are not deploying
            ConsoleManager.WriteLine(string.Empty);

            if (IsDeploying)
            {
                ConsoleManager.WriteLine("WARNING: Deployment already in progress. Deployment will not occur.", ConsoleColor.DarkYellow);
                return;
            }

            // Lock Deployment
            IsDeploying = true;
            var stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();

            try
            {
                ForwardShellStreamOutput = false;
                PrintDeploymentNumber(DeploymentNumber);
                RunSshClientCommand(sshClient, verbOptions);
                CreateTargetPath(sftpClient, verbOptions);
                PrepareTargetPath(sftpClient, verbOptions);
                UploadFilesToTarget(sftpClient, verbOptions);
            }
            catch (Exception ex)
            {
                PrintException(ex);
            }
            finally
            {
                // Unlock deployment
                IsDeploying = false;
                DeploymentNumber++;
                stopwatch.Stop();
                ConsoleManager.WriteLine("    Finished deployment in "
                                         + Math.Round(stopwatch.Elapsed.TotalSeconds, 2).ToString()
                                         + " seconds.", ConsoleColor.Green);

                ForwardShellStreamOutput = true;
                RunShellStreamCommand(shellStream, verbOptions);
            }
        }
Exemple #10
0
        /// <summary>
        /// Uploads the files in the source Windows path to the target Linux path.
        /// </summary>
        /// <param name="sftpClient">The SFTP client.</param>
        /// <param name="targetPath">The target path.</param>
        /// <param name="sourcePath">The source path.</param>
        /// <param name="ignoreFileSuffixes">The ignore file suffixes.</param>
        private static void UploadFilesToTarget(SftpClient sftpClient, MonitorVerbOptions verbOptions)
        {
            var filesInSource = System.IO.Directory.GetFiles(verbOptions.SourcePath, FileSystemMonitor.AllFilesPattern, System.IO.SearchOption.AllDirectories);
            var filesToDeploy = new List <string>();

            foreach (var file in filesInSource)
            {
                var ignore = false;

                foreach (var ignoreSuffix in verbOptions.ExcludeFileSuffixList)
                {
                    if (file.EndsWith(ignoreSuffix))
                    {
                        ignore = true;
                        break;
                    }
                }

                if (ignore)
                {
                    continue;
                }
                filesToDeploy.Add(file);
            }

            ConsoleManager.WriteLine("    Deploying " + filesToDeploy.Count + " files.", ConsoleColor.Green);
            foreach (var file in filesToDeploy)
            {
                var relativePath    = MakeRelativePath(file, verbOptions.SourcePath + Path.DirectorySeparatorChar);
                var fileTargetPath  = Path.Combine(verbOptions.TargetPath, relativePath).Replace(WindowsDirectorySeparatorChar, LinuxDirectorySeparatorChar);
                var targetDirectory = Path.GetDirectoryName(fileTargetPath).Replace(WindowsDirectorySeparatorChar, LinuxDirectorySeparatorChar);

                CreateLinuxDirectoryRecursive(sftpClient, targetDirectory);

                using (var fileStream = System.IO.File.OpenRead(file))
                {
                    sftpClient.UploadFile(fileStream, fileTargetPath);
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// Stops the monitor mode by closing SFTP and SSH connections, and stopping the File System Monitor.
        /// </summary>
        /// <param name="sftpClient">The SFTP client.</param>
        /// <param name="sshClient">The SSH client.</param>
        /// <param name="fsMonitor">The fs monitor.</param>
        private static void StopMonitorMode(SftpClient sftpClient, SshClient sshClient, FileSystemMonitor fsMonitor)
        {
            ConsoleManager.WriteLine(string.Empty);

            fsMonitor.Stop();
            ConsoleManager.WriteLine("File System monitor was stopped.");

            if (sftpClient.IsConnected == true)
            {
                sftpClient.Disconnect();
            }

            ConsoleManager.WriteLine("SFTP client disconnected.");

            if (sshClient.IsConnected == true)
            {
                sshClient.Disconnect();
            }

            ConsoleManager.WriteLine("SSH client disconnected.");
            ConsoleManager.WriteLine("Application will exit now.");
        }
Exemple #12
0
        /// <summary>
        /// Starts the user interaction.
        /// </summary>
        /// <param name="fsMonitor">The fs monitor.</param>
        /// <param name="sshClient">The SSH client.</param>
        /// <param name="sftpClient">The SFTP client.</param>
        /// <param name="shellStream">The shell stream.</param>
        /// <param name="verbOptions">The verb options.</param>
        private static void StartUserInteraction(FileSystemMonitor fsMonitor, SshClient sshClient, SftpClient sftpClient, ShellStream shellStream, MonitorVerbOptions verbOptions)
        {
            ForwardShellStreamInput = false;

            while (true)
            {
                var readKey = Console.ReadKey(true);

                if (readKey.Key == ConsoleKey.F1)
                {
                    ForwardShellStreamInput = !ForwardShellStreamInput;
                    if (ForwardShellStreamInput)
                    {
                        ConsoleManager.WriteLine("    >> Entered console input forwarding.", ConsoleColor.Green);
                        ForwardShellStreamOutput = true;
                    }
                    else
                    {
                        ConsoleManager.WriteLine("    >> Left console input forwarding.", ConsoleColor.Red);
                    }


                    continue;
                }

                if (ForwardShellStreamInput)
                {
                    if (readKey.Key == ConsoleKey.Enter)
                    {
                        shellStream.WriteLine(string.Empty);
                    }
                    else
                    {
                        shellStream.WriteByte((byte)readKey.KeyChar);
                    }

                    shellStream.Flush();
                    continue;
                }

                if (readKey.Key == ConsoleKey.Q)
                {
                    break;
                }

                if (readKey.Key == ConsoleKey.C)
                {
                    ConsoleManager.Clear();
                    continue;
                }

                if (readKey.Key == ConsoleKey.N)
                {
                    CreateNewDeployment(sshClient, sftpClient, shellStream, verbOptions);
                    continue;
                }

                if (readKey.Key == ConsoleKey.E)
                {
                    RunSshClientCommand(sshClient, verbOptions);
                    continue;
                }

                if (readKey.Key == ConsoleKey.S)
                {
                    RunShellStreamCommand(shellStream, verbOptions);
                    continue;
                }

                if (readKey.Key != ConsoleKey.H)
                {
                    ConsoleManager.WriteLine("Unrecognized command '" + readKey.KeyChar + "' -- Press 'H' to get a list of available commands.", ConsoleColor.Red);
                }

                if (readKey.Key == ConsoleKey.H)
                {
                    var helpColor = ConsoleColor.Cyan;
                    ConsoleManager.WriteLine("Console help", helpColor);
                    ConsoleManager.WriteLine("    H    Prints this screen", helpColor);
                    ConsoleManager.WriteLine("    Q    Quits this application", helpColor);
                    ConsoleManager.WriteLine("    C    Clears the screen", helpColor);
                    ConsoleManager.WriteLine("    N    Force a deployment cycle", helpColor);
                    ConsoleManager.WriteLine("    E    Run the Pre-deployment command", helpColor);
                    ConsoleManager.WriteLine("    S    Run the Post-deployment command", helpColor);
                    ConsoleManager.WriteLine("    F1   Toggle shell-interactive mode", helpColor);

                    ConsoleManager.WriteLine(string.Empty);
                    continue;
                }
            }
        }
Exemple #13
0
 /// <summary>
 /// Prints the deployment number the Monitor is currently in.
 /// </summary>
 /// <param name="deploymentNumber">The deployment number.</param>
 private static void PrintDeploymentNumber(int deploymentNumber)
 {
     ConsoleManager.WriteLine("    Starting deployment ID " + deploymentNumber + " - "
                              + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString(), ConsoleColor.Green);
 }
Exemple #14
0
        static void Main(string[] args)
        {
            #region Handle Single Instance Application

            bool isNewMutex;
            AppMutex = new Mutex(true, MutexName, out isNewMutex);
            if (isNewMutex == false)
            {
                AppMutex             = null;
                Environment.ExitCode = CommandLine.Parser.DefaultExitCodeFail;
                return;
            }

            #endregion

            Console.WriteLine("SSH Deployment Tool [Version " + typeof(Unosquare.Labs.SshDeploy.Program).Assembly.GetName().Version.ToString() + "]");
            Console.WriteLine("(c) 2015 Unosquare SA de CV. All Rights Reserved.");

            var invokedVerbName = string.Empty;
            CliVerbOptionsBase invokedVerbOptions = null;
            var options = new CliOptions();

            var parseResult = CommandLine.Parser.Default.ParseArguments(args, options, (verb, verbOptions) =>
            {
                invokedVerbName    = verb;
                invokedVerbOptions = verbOptions as CliVerbOptionsBase;

                if (invokedVerbOptions != null)
                {
                    ConsoleManager.Verbose = invokedVerbOptions.Verbose != 0;
                }
            });

            if (parseResult == false)
            {
                Environment.ExitCode = CommandLine.Parser.DefaultExitCodeFail;
                return;
            }

            try
            {
                switch (invokedVerbName)
                {
                case CliOptions.RunVerb:
                {
                    var verbOptions = invokedVerbOptions as RunVerbOptions;
                    DeploymentManager.ExecuteRunVerb(verbOptions);
                    break;
                }

                case CliOptions.ShellVerb:
                {
                    var verbOptions = invokedVerbOptions as ShellVerbOptions;
                    DeploymentManager.ExecuteShellVerb(verbOptions);
                    break;
                }

                case CliOptions.MonitorVerb:
                {
                    var verbOptions = invokedVerbOptions as MonitorVerbOptions;
                    DeploymentManager.ExecuteMonitorVerb(verbOptions);
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                ConsoleManager.ErrorWriteLine("Error - " + ex.GetType().Name);
                ConsoleManager.ErrorWriteLine(ex.Message);
                ConsoleManager.ErrorWriteLine(ex.StackTrace);
                Environment.ExitCode = CommandLine.Parser.DefaultExitCodeFail;
            }

            if (Environment.ExitCode != 0)
            {
                ConsoleManager.ErrorWriteLine("Completed with errors. Exit Code " + Environment.ExitCode.ToString());
            }
            else
            {
                ConsoleManager.WriteLine("Completed.");
            }
        }