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)
|
|
}
|
|
}
|