Skip to content

Commit

Permalink
expand v0.10.0 notes
Browse files Browse the repository at this point in the history
  • Loading branch information
vito committed Aug 29, 2022
1 parent 83a9026 commit 958712d
Showing 1 changed file with 73 additions and 18 deletions.
91 changes: 73 additions & 18 deletions notes/v0.10.0.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,92 @@
This is a big release that overhauls the networking stack and adds a new kind
of value: a *thunk addr*.

Thunks can now provide ports:

```clojure
(-> ($ python -m http.server 80)
(with-image (linux/python))
(with-port :http 80))
```

Ports can be referenced using a [thunk addr]. A thunk addr is a lot like a
[thunk path] except it represents to a TCP address instead of a filesystem
path.
## thunk ports & addrs

Thunks can now provide TCP ports using [`with-port`] which can be referenced
with [`addr`] to construct a [thunk addr]:

```clojure
(def srv
(-> ($ python -m http.server 80)
(-> ($ python -m http.server "80")
(with-image (linux/python))
(with-port :http 80)))

(-> ($ wget (addr srv :http "http://$host:$port"))
(with-image (linux/ubuntu))
(with-image (linux/alpine))
run)
```

The server thunk runs lazily. The client thunk doesn't run until the server's
ports are listening.
A thunk addr is a lot like a [thunk path] except it represents to a TCP address
instead of a filesystem path.

When using a thunk addr you don't need to worry about managing the lifecycle of
the service that the thunk represents. The service will be run lazily,
de-duplicated across multiple Bass runs, and stopped when all clients go away.

The advantage of this approach over traditional service lifecycle management
parallels the advantages of using thunk paths instead of managing state in a
local filesystem. It allows thunks that depend on services provided by other
thunks to remain reproducible, just like thunks that depend on files created by
other thunks.

Thunks no longer run in the host network. Instead they run in a [bridge
network] to prevent port collisions.
[`with-port`]: https://bass-lang.org/stdlib.html#binding-with-port
[`addr`]: https://bass-lang.org/stdlib.html#binding-addr
[thunk path]: https://bass-lang.org/bassics.html#term-thunk%20path
[thunk addr]: https://bass-lang.org/bassics.html#term-thunk%20addr

Thunks use DNS to address each other in order to maximize caching. (Using IPs
would introduce a source of randomness!)

## bridge networking & DNS

To prevent port collisions, thunks no longer run in the host network. Instead
they run in a [bridge network] where each thunk has its own IP and reaches
other thunks using DNS.

Using DNS is important because IPs are not reproducible. If thunks reached each
other using direct container IPs then caches would be busted every time a
service runs.

Now that thunks run in their own network, you can't use Bass to run and expose
services to the host machine. This may be added in a future release via port
forwarding. Alternatively you could take the `path-name` (a bit of a misnomer)
of the thunk and reverse-proxy to its container port using the same DNS server
that thunks use.

[bridge network]: https://www.cni.dev/plugins/current/main/bridge/
[`path-name`]: https://bass-lang.org/stdlib.html#binding-path-name


## automatic TLS

Thunks may also use TLS. A unique "bass" certificate authority is generated by
the runtime and automaticaly trusted by all thunks that it runs.

To generate a certificate for a thunk, use [`with-tls`]:

```clojure
(def registry-mirror
(let [config {:version "0.1"
:http {:addr "0.0.0.0:5000"
:tls {:certificate "/registry.crt"
:key "/registry.key"}}
:storage {:filesystem {:rootdirectory "/var/lib/registry"}}
:proxy {:remoteurl "https://registry-1.docker.io"}}]
(-> ($ registry serve (mkfile ./config.yml (json config)))
(with-image (linux/registry))
(with-tls /registry.crt /registry.key)
(with-port :http 5000))))

(defn main []
(-> (from (linux/alpine)
($ apk add curl)
($ curl (addr registry-mirror :http "https://$host:$port/v2/")))
run))
```

Generating TLS certs is a necessary part of the puzzle because thunks use their
own hash as their hostname and DNS entry. It would be impossible to generate a
cert ahead of time and pass it to the thunk because doing so would change the
hash!

[`with-tls`]: https://bass-lang.org/stdlib.html#binding-with-tls

0 comments on commit 958712d

Please sign in to comment.