v0.10.0, at your service
This is a big release that overhauls the networking stack and adds a new kind of value: a thunk addr.
thunk ports & addrs
Thunks can now provide TCP ports using with-port
which can be referenced with addr
to construct a thunk addr:
(def srv
(-> ($ python -m http.server "80")
(with-image (linux/python))
(with-port :http 80)))
(-> ($ wget (addr srv :http "http://$host:$port"))
(with-image (linux/alpine))
run)
A thunk addr is a lot like a thunk path except it represents an address to another concurrently running thunk's port, instead of a completed thunk's 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.
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.
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
:
(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 piece 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!
What's Changed
Breaking Changes ⚠️
(with-env)
is additive,null
values act as tombstones by @vito in #228- bridge networking by @vito in #229
New Features ✨
- add services via thunk addrs by @vito in #225
- support multiple .locks in
bass --bump
, + backwards compat. fixes by @vito in #226 - use DNS for thunk addresses by @vito in #231
- reap zombies by @vito in #234
- automatic TLS by @vito in #236
Fixed Bugs 🐛
Other Changes
New Contributors
Full Changelog: v0.9.0...v0.10.0