repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

pico / pubsub / html
Eric Bower · 23 Sep 24

marketing.page.tmpl

  1{{template "base" .}}
  2
  3{{define "title"}}pubsub using ssh{{end}}
  4
  5{{define "meta"}}
  6<meta name="description" content="pubsub using ssh" />
  7
  8<meta property="og:type" content="website">
  9<meta property="og:site_name" content="{{.Site.Domain}}">
 10<meta property="og:url" content="https://{{.Site.Domain}}">
 11<meta property="og:title" content="{{.Site.Domain}}">
 12<meta property="og:description" content="pubsub using ssh">
 13{{end}}
 14
 15{{define "attrs"}}class="container-sm"{{end}}
 16
 17{{define "body"}}
 18<header class="flex flex-col items-center gap">
 19  <img src="https://pico.sh/logo.svg" alt="pico logo" width="50" height="50" />
 20  <h1 class="text-2xl font-bold text-center">Authenticated <code>*nix</code> pipes over <code>ssh</code></h1>
 21</header>
 22
 23<hr />
 24
 25<article class="flex flex-col gap-2">
 26  <div>
 27    <p>
 28      The simplest authenticated pubsub system.  Send messages through
 29      user-defined channels.  By default, channels are private to the authenticated
 30      ssh user.  The default pubsub model is multicast with bidirectional
 31      blocking, meaning a publisher (<code>pub</code>) will send its message to all
 32      subscribers (<code>sub</code>) on a channel.  Further, both <code>pub</code> and
 33      <code>sub</code> will wait for at least one event to be sent or received on the channel.
 34    </p>
 35
 36    <blockquote>This service is undergoing active development, expect bugs, feature dev, and server restarts</blockquote>
 37  </div>
 38
 39  <div>
 40    <h2 class="text-xl">A basic API</h2>
 41    <pre>ssh {{.Site.Domain}} sub mykey</pre>
 42    <pre>echo "hello world!" | ssh {{.Site.Domain}} pub mykey</pre>
 43
 44    <details>
 45      <summary>Demo</summary>
 46      <script
 47        src="https://asciinema.org/a/52qRVi77CTjfAoZj9IaGMygDr.js"
 48        id="asciicast-52qRVi77CTjfAoZj9IaGMygDr"
 49        async="true"
 50        data-theme="dracula"
 51        data-loop="true"
 52        data-speed="1.5"
 53        data-idle-time-limit="2"
 54      ></script>
 55    </details>
 56  </div>
 57
 58  <div>
 59    <h2 class="text-xl">Simple desktop notifications</h2>
 60    <pre>ssh {{.Site.Domain}} sub notify; notify-send "job done!"</pre>
 61    <pre>./longjob.sh; ssh {{.Site.Domain}} pub notify -e</pre>
 62  </div>
 63
 64  <div>
 65    <h2 class="text-xl">File sharing</h2>
 66    <pre>cat doc.md | ssh {{.Site.Domain}} pub thedoc</pre>
 67    <pre>ssh {{.Site.Domain}} sub thedoc > ./important.md</pre>
 68
 69    <details>
 70      <summary>Demo</summary>
 71      <script
 72        src="https://asciinema.org/a/TW0chshVssDj35hvr9NKNC2CK.js"
 73        id="asciicast-TW0chshVssDj35hvr9NKNC2CK"
 74        async="true"
 75        data-theme="dracula"
 76        data-loop="true"
 77        data-speed="1.5"
 78        data-idle-time-limit="2"
 79      ></script>
 80    </details>
 81  </div>
 82
 83  <div>
 84    <h2 class="text-xl">Pipe command output</h2>
 85    <p>Send command output through our <code>pipe</code> command.</p>
 86
 87    <details>
 88      <summary>Demo</summary>
 89      <script
 90        src="https://asciinema.org/a/7e3SVyxKa31D0iZ4X5PJm8b6E.js"
 91        id="asciicast-7e3SVyxKa31D0iZ4X5PJm8b6E"
 92        async="true"
 93        data-theme="dracula"
 94        data-loop="true"
 95        data-speed="1.5"
 96        data-idle-time-limit="2"
 97      ></script>
 98    </details>
 99  </div>
100
101  <div>
102    <h2 class="text-xl">Chat</h2>
103    <p>Use our <code>pipe</code> command to have a chat with someone.</p>
104    <pre>ssh {{.Site.Domain}} pipe mychan -p</pre>
105    <p>Now anyone with a <code>pico</code> account can subscribe to this channel using the same command.</p>
106
107    <details>
108      <summary>Demo</summary>
109      <script
110        src="https://asciinema.org/a/fLBHAcPQqqawkrdpRdgEVFNrm.js"
111        id="asciicast-fLBHAcPQqqawkrdpRdgEVFNrm"
112        async="true"
113        data-theme="dracula"
114        data-loop="true"
115        data-speed="1.5"
116        data-idle-time-limit="2"
117      ></script>
118    </details>
119  </div>
120
121  <div>
122    <h2 class="text-xl">Pipe reverse shell</h2>
123    <p>If you squint hard enough you can give users interactive access to your shell.</p>
124
125    <details>
126      <summary>Demo</summary>
127      <script
128        src="https://asciinema.org/a/S3LSLOi9mHQOPZHoK0xlkiKLM.js"
129        id="asciicast-S3LSLOi9mHQOPZHoK0xlkiKLM"
130        async="true"
131        data-theme="dracula"
132        data-loop="true"
133        data-speed="1.5"
134        data-idle-time-limit="2"
135      ></script>
136    </details>
137  </div>
138
139  <div>
140    <h2 class="text-xl">Simple CI/CD</h2>
141    <pre>ssh {{.Site.Domain}} sub myimg; docker pull myimg && docker up -d dev</pre>
142    <pre>docker buildx build --push -t myimg .; ssh {{.Site.Domain}} pub myimg -e</pre>
143  </div>
144
145  <div>
146    <h2 class="text-xl">Pubsub interactions</h2>
147
148    <h3 class="text-lg">Multiple subs</h3>
149    <details>
150      <summary>Demo</summary>
151      <script
152        src="https://asciinema.org/a/Ccee82V83EUyaZzFYbTn36BLF.js"
153        id="asciicast-Ccee82V83EUyaZzFYbTn36BLF"
154        async="true"
155        data-theme="dracula"
156        data-loop="true"
157        data-speed="1.5"
158        data-idle-time-limit="2"
159      ></script>
160    </details>
161
162    <h3 class="text-lg">Multiple pubs</h3>
163    <details>
164      <summary>Demo</summary>
165      <script
166        src="https://asciinema.org/a/ONe1OphgsKUt9MMPVRBiSbwd0.js"
167        id="asciicast-ONe1OphgsKUt9MMPVRBiSbwd0"
168        async="true"
169        data-theme="dracula"
170        data-loop="true"
171        data-speed="1.5"
172        data-idle-time-limit="2"
173      ></script>
174    </details>
175
176    <h3 class="text-lg">Multiple pubs and subs</h3>
177    <details>
178      <summary>Demo</summary>
179      <script
180        src="https://asciinema.org/a/HAlhNCLFLvuGjiqnEEUvWVi1h.js"
181        id="asciicast-HAlhNCLFLvuGjiqnEEUvWVi1h"
182        async="true"
183        data-theme="dracula"
184        data-loop="true"
185        data-speed="1.5"
186        data-idle-time-limit="2"
187      ></script>
188    </details>
189  </div>
190
191  <div>
192    <h2 class="text-xl">Send a public message</h2>
193    <pre>echo "hello world!" | ssh {{.Site.Domain}} pub mychan -p</pre>
194    <p>Now anyone with a <code>pico</code> account can subscribe to this channel:</p>
195    <pre>ssh {{.Site.Domain}} sub mychan -p</pre>
196  </div>
197
198  <div>
199    <h2 class="text-xl">Caveats</h2>
200    <p>
201      You must always pipe something into <code>pub</code> or else it will block
202      indefinitely until the process is killed.  However, you can provide a
203      flag to send an empty message: <code>pub xyz -e</code>.
204    </p>
205  </div>
206
207  <div>
208    <h2 class="text-xl">Inspiration</h2>
209    <p>
210      A special thanks to <a href="https://patchbay.pub">patchbay.pub</a> for our inspiration.
211    </p>
212  </div>
213
214  <div class="text-center mb-2">
215    <p>built on our <a href="https://github.com/picosh/pubsub">go pkg</a>.</p>
216    <a href="https://pico.sh/getting-started" class="btn-link inline-block">GET STARTED</a>
217  </div>
218</article>
219
220{{template "marketing-footer" .}}
221{{end}}