271 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| package templates
 | |
| 
 | |
| import "git.wamblee.org/converge/pkg/models"
 | |
| 
 | |
| 
 | |
| templ AgentUsage(access models.ConvergeAccess, usageInputs UsageInputs) {
 | |
|     <div>
 | |
| 
 | |
|     for _, message := range usageInputs.ErrorMessages {
 | |
|     <div class="alert alert-danger" role="alert">
 | |
|       {message}
 | |
|     </div>
 | |
|     }
 | |
| 
 | |
|     <h2>downloading and running the agent</h2>
 | |
|     <p>
 | |
|     This is what you run on a remote server, typically in your continuous integration job.
 | |
|     </p>
 | |
| 
 | |
|     if usageInputs.RemoteShells[BASH] {
 | |
|         <code-sample id="run-agent-bash">@templ.Raw(addSshKeys(BASH, usageInputs.SshKeys)) <br/>
 | |
|         {DOWNLOAD_COMMAND[usageInputs.DownloadCommand]} agent {GetDownloadSecureOption(usageInputs)} http{access.Secure}://{access.BaseUrl}/downloads/agent<br/>
 | |
|         chmod 755 agent <br/>
 | |
|         ./agent {GetAgentSecureOption(usageInputs)} --id {usageInputs.Id} ws{access.Secure}://{access.BaseUrl}<br/>
 | |
|         rm -f agent <br/>
 | |
|         </code-sample>
 | |
|     }
 | |
|     if usageInputs.RemoteShells[CMD]  {
 | |
|         <code-sample id="run-agent-cmd">@templ.Raw(addSshKeys(CMD, usageInputs.SshKeys)) <br/>
 | |
|         {DOWNLOAD_COMMAND[usageInputs.DownloadCommand]} agent.exe {GetDownloadSecureOption(usageInputs)} http{access.Secure}://{access.BaseUrl}/downloads/agent.exe <br/>
 | |
|         .\agent {GetAgentSecureOption(usageInputs)} --id {usageInputs.Id} ws{access.Secure}://{access.BaseUrl} <br/>
 | |
|         del agent.exe <br/>
 | |
|         </code-sample>
 | |
|     }
 | |
|     if usageInputs.RemoteShells[POWERSHELL]  {
 | |
|         <code-sample id="run-agent-powershell">@templ.Raw(addSshKeys(POWERSHELL, usageInputs.SshKeys)) <br/>
 | |
|         {DOWNLOAD_COMMAND[usageInputs.DownloadCommand]} agent.exe {GetDownloadSecureOption(usageInputs)} http{access.Secure}://{access.BaseUrl}/downloads/agent.exe <br/>
 | |
|         .\agent {GetAgentSecureOption(usageInputs)} --id {usageInputs.Id} ws{access.Secure}://{access.BaseUrl} <br/>
 | |
|         del agent.exe <br/>
 | |
|         </code-sample>
 | |
|     }
 | |
| 
 | |
|     <p>
 | |
|         The agent has more command-line options than shown here.
 | |
|         Download the agent and run it without arguments to
 | |
|         see all options.
 | |
|     </p>
 | |
|     <p>
 | |
|         <b>Tip</b>: Run the above command locally in a similar shell (for instance in a
 | |
|         docker container) then try to connect to the shell using the commands below. If that
 | |
|         works, then you are all set.
 | |
|     </p>
 | |
| 
 | |
| 
 | |
|     <h2>connecting to the agent</h2>
 | |
| 
 | |
|     <p>
 | |
|        You need to install <code>wsproxy</code>, which is available in the <a href="downloads.html">downloads</a> section and
 | |
|        make it availebla in your path. This utility needs to be downloaded only once, if a newer version of
 | |
|        <code>wsproxy</code> is needed it will tell you about that.
 | |
|     </p>
 | |
| 
 | |
| 
 | |
|     <p>The embedded ssh server in the agent supports both ssh and sftp.
 | |
|     </p>
 | |
| 
 | |
|      <code-sample id="ssh-connect">
 | |
|           ssh -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.BaseUrl}/client/{usageInputs.Id}"  {"localhost"}
 | |
|       </code-sample>
 | |
|       <code-sample id="sftp-connect">
 | |
|           sftp -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.BaseUrl}/client/{usageInputs.Id}" {"localhost"}
 | |
|       </code-sample>
 | |
| 
 | |
|     <p>For other ssh clients that do not support the openssh ProxyCommand option, there is another
 | |
|     way to connect. In this method, a local port forwarder is started that forwards a local port
 | |
|     to the webserver. Then you can start an ssh client that connects to the local tcp port.
 | |
|     </p>
 | |
|     <code-sample id="tcptows-ssh">ssh -oServerAliveInterval=10 -p 10000  {"localhost"}</code-sample>
 | |
|     <code-sample id="tcptows-sftp">sftp -oServerAliveInterval=10 -p 10000 {"localhost"}</code-sample>
 | |
| 
 | |
|     <p>This requires the <code>tcptows</code> utility which is available in the
 | |
|        <a href="downloads.html">downloads</a> section. The utility must be started beforehand
 | |
|        using:
 | |
|     </p>
 | |
|     <code-sample id="tcptows-ssh">tcptows 10000 ws{access.Secure}://{access.BaseUrl}/client/{usageInputs.Id}</code-sample>
 | |
| 
 | |
|     <h2>working with the agent</h2>
 | |
| 
 | |
|      if usageInputs.RemoteShells[BASH] {
 | |
|         <div>
 | |
|         <code-sample id="session-bash">
 | |
|         # cd back to the agent directory <br/>
 | |
|         cd $agentdir <br/>
 | |
|         </code-sample>
 | |
|         <code-sample id="session-bash2">
 | |
|         # prevent logout when last user exits <br/>
 | |
|         touch $agentdir/.hold<br/>
 | |
|        </code-sample>
 | |
|        </div>
 | |
| 
 | |
|     }
 | |
|     if usageInputs.RemoteShells[CMD] {
 | |
|         <div>
 | |
|         <code-sample id="session-cmd">
 | |
|         # cd back to the agent directory <br/>
 | |
|         cd %agentdir%  <br/>
 | |
|         </code-sample>
 | |
|         <code-sample id="session-cmd2">
 | |
|         # prevent logout when last user exits <br/>
 | |
|         echo > %agentdir%\.hold <br/>
 | |
|         </code-sample>
 | |
|         </div>
 | |
|     }
 | |
|     if usageInputs.RemoteShells[POWERSHELL] {
 | |
|         <div>
 | |
|         <code-sample id="session-powershell">
 | |
|         # cd back to the agent directory <br/>
 | |
|         cd $env:agentdir  <br/>
 | |
|         </code-sample>
 | |
|         <code-sample id="session-powershell2">
 | |
|         # prevent logout when last user exits  <br/>
 | |
|         $null > $env:agentdir\.hold  <br/>
 | |
|         </code-sample>
 | |
|         </div>
 | |
|     }
 | |
|     if usageInputs.RemoteShells[CMD] || usageInputs.RemoteShells[POWERSHELL]  {
 | |
|             <p>
 | |
|               NOTE: When running the agent on windows, an exit of the remote session using
 | |
|               exit in powershell or command prompt does not terminate the shell completely.
 | |
|               To terminate the client ssh session must be killed by closing the terminal.
 | |
|               Cleanup of remote processes on the agent appears to work properly despite this
 | |
|               problem. It is just that exit of the windows shell (powershell or command prompt)
 | |
|               is not detected properly.
 | |
|           </p>
 | |
|         }
 | |
|     </div>
 | |
| }
 | |
| 
 | |
| 
 | |
| templ ShellUsage(access models.ConvergeAccess, usageInputs UsageInputs) {
 | |
|   <div>
 | |
|   @AgentUsage(access, usageInputs)
 | |
|   </div>
 | |
| }
 | |
| 
 | |
| 
 | |
| templ Usage(access models.ConvergeAccess) {
 | |
|   <div>
 | |
|       <h1>usage</h1>
 | |
| 
 | |
|       <p>
 | |
|       <ol>
 | |
|       <li>Configure agent settings below</li>
 | |
|       <li>Copy paste the required commands for your agent</li>
 | |
|       <li>Copy paste the required commands for connecting to the remote shell on the agent through
 | |
|          Converge. </li>
 | |
|       </ol>
 | |
|       </p>
 | |
|       <!-- TODO Investigate how to do this properly with bootstrap -->
 | |
|       <style>
 | |
|       .minimal-width {
 | |
|         width: 1%;
 | |
|         white-space: nowrap;
 | |
|       }
 | |
|       </style>
 | |
| 
 | |
|       <form id="inputs" novalidate
 | |
|             class="persistent-form"
 | |
|             hx-post="../usage"
 | |
|             method="post"
 | |
|             hx-trigger="load,input delay:500ms,change,formdataloaded"
 | |
|             hx-target="#example-cli"
 | |
|             hx-on::after-request="saveFormToCookieEvent(event)">
 | |
|           <table class="table table-responsive">
 | |
|                <tr>
 | |
|                  <td class="minimal-width">
 | |
|                    <label
 | |
|                      for="rendez-vous-id"
 | |
|                      data-toggle="tooltip"
 | |
|                      title="this allows the remote agent and client to find each other">
 | |
|                      rendez-vous id<sup><i class="bi bi-info-circle small"></i></sup>
 | |
|                    </label>
 | |
|                  </td>
 | |
|                  <td>
 | |
|                    <input id="rendez-vous-id" class="form-control" name="rendez-vous-id" type="text" maxlength="40"></input>
 | |
|                  </td>
 | |
|                </tr>
 | |
|                <tr>
 | |
|                  <td class="minimal-width">
 | |
|                    <label
 | |
|                      for="ssh-keys"
 | |
|                      data-toggle="tooltip"
 | |
|                      title="public SSH public keys define which users are allowed to connect">
 | |
|                      public ssh keys<sup><i class="bi bi-info-circle small"></i></sup>
 | |
|                    </label>
 | |
|                  </td>
 | |
|                  <td>
 | |
|                    <textarea id="ssh-keys" class="form-control autogrow" name="ssh-keys" rows="5"></textarea>
 | |
|                  </td>
 | |
|               </tr>
 | |
|               <tr>
 | |
|                   <td class="minimal-width"><label
 | |
|                       for="remote-shell"
 | |
|                       data-toggle="tooltip"
 | |
|                       title="is the agent running on linux (sh-like shell) or windows?">
 | |
|                       agent environment<sup><i class="bi bi-info-circle small"></i></sup></label>
 | |
|                   </td>
 | |
|                   <td>
 | |
|                       <input checked id="remote-shell-0" name="remote-shell" type="radio" value={string(BASH)}> <label for="remote-shell-0">bash, sh, zsh, ...</label>
 | |
|                       <input id="remote-shell-1" name="remote-shell" type="radio" value={string(CMD)}> <label for="remote-shell-1">command prompt</label>
 | |
|                       <input id="remote-shell-2" name="remote-shell" type="radio" value={string(POWERSHELL)}> <label for="remote-shell-2">power shell</label>
 | |
|                   </td>
 | |
|               </tr>
 | |
|               <tr>
 | |
|                   <td class="minimal-width">
 | |
|                     <label
 | |
|                       for="download-command"
 | |
|                       data-toggle="tooltip"
 | |
|                       title="how is the agent downloaded to the remote environment?">
 | |
|                       download method<sup><i class="bi bi-info-circle small"></i></sup>
 | |
|                     </label>
 | |
|                   </td>
 | |
|                   <td>
 | |
|                       <input checked id="download-command-0" name="download-command" type="radio" value={string(CURL)}> <label for="download-command-0">curl</label>
 | |
|                       <input id="download-command-1" name="download-command" type="radio" value={string(WGET)}> <label for="download-command-1">wget</label>
 | |
|                   </td>
 | |
|               </tr>
 | |
|               <tr>
 | |
|                   <td class="minimal-width">
 | |
|                     <label
 | |
|                       for="certificate-validation"
 | |
|                       data-toggle="tooltip"
 | |
|                       title="turn off certificate validation if the converge certificate is untrusted by the remote system">
 | |
|                       certificate validation<sup><i class="bi bi-info-circle small"></i></sup>
 | |
|                     </label>
 | |
|                   </td>
 | |
|                   <td>
 | |
|                       <input checked id="certificate-validation-0" name="certificate-validation" type="checkbox" checked> <label for="certificate-validation-0"></label>
 | |
|                   </td>
 | |
|               </tr>
 | |
|               <!--tr>
 | |
|                   <td class="minimal-width"><label for="local-shell">local environment</label></td>
 | |
|                   <td>
 | |
|                       <input id="checked local-shell-0" name="local-shell" type="radio" value={BASH}> <label for="local-shell-0">*sh</label>
 | |
|                       <input id="local-shell-1" name="local-shell" type="radio" value={CMD}> <label for="local-shell-1">command prompt</label>
 | |
|                       <input id="local-shell-2" name="local-shell" type="radio" value={POWERSHELL}> <label for="local-shell-2">powershell</label>
 | |
|                   </td>
 | |
|               </tr -->
 | |
|           </table>
 | |
|       </form>
 | |
| 
 | |
|       <div id="example-cli">
 | |
|       </div>
 | |
|   </div>
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| templ UsageTab(access models.ConvergeAccess) {
 | |
|     @BasePage(2) {
 | |
|                     @Usage(access)
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| templ ShellUsageTab(access models.ConvergeAccess, usageInputs UsageInputs) {
 | |
|     @BasePage(2) {
 | |
|                     @ShellUsage(access, usageInputs)
 | |
|     }
 | |
| }
 |