Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add release notes for v0.2.0 #33

Merged
merged 2 commits into from
May 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 211 additions & 0 deletions docs/release-notes/2024-04-29-v0.2.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# River v0.2.0

River is a reverse proxy application written in Rust, supported as a [Prossimo Initiative],
built on top of the [Pingora engine] from Cloudflare. River began development in Q1 2024,
and is currently in an early developer preview state.

[Prossimo Initiative]: https://www.memorysafety.org/initiative/reverse-proxy/
[Pingora engine]: https://github.com/cloudflare/pingora

This announcement covers the v0.2.0 release of River, the first development release made
public. This release was intended to set up the first working binary of River, and allow
for basic functionality and user testing. This release was led by [OneVariable UG], and
sponsored by [Prossimo][Prossimo Initiative].

[OneVariable UG]: https://onevariable.com/

For installation instructions, see [the release details on GitHub]. This release includes
binaries for x86_64 Linux (GNU and MUSL builds), as well as a release for aarch64 MacOS
(M-series Macs). Binaries are provided, as well as an installation script. Release tooling
is provided by [`cargo-dist`].

[the release details on GitHub]: https://github.com/memorysafety/river/releases/tag/v0.2.0
[`cargo-dist`]: https://github.com/axodotdev/cargo-dist

## Notable features

The following are the notable features included in the v0.2.0 release. For a full list of
changes, please refer to [the release details on GitHub].

This initial milestone was about getting an initial version of the River application up and
running. The goal is to achieve a "demo-ready" version of River that is possible to
experiment with.

Primary objectives included:

1. Getting the `river` application up and running as a Linux binary
2. Getting enough configuration options working to allow for basic operation
3. Integrating the `pingora` library and getting basic reverse proxy operation working
4. Start setting up build and release infrastructure
5. Start working on observability, including structured logging

### Basic Application Infrastructure

This is the first release, so it was necessary to set up the basics of River as a console
based application. This includes defining the CLI interface, tracing/logging support, and
configuration file support.

CLI argument information is available with `--help`. Tracing logs (using the `fmt` subscriber)
are present by default.

```bash
$ river --help
2024-04-30T09:11:16.907289Z INFO river::config: Parsing CLI options
River: A reverse proxy from Prossimo

Usage: river [OPTIONS]

Options:
--validate-configs
Validate all configuration data and exit
--config-toml <CONFIG_TOML>
Path to the configuration file in TOML format
--threads-per-service <THREADS_PER_SERVICE>
Number of threads used in the worker pool for EACH service
-h, --help
Print help

$ river --validate-configs
2024-04-30T09:11:51.470932Z INFO river::config: Parsing CLI options
2024-04-30T09:11:51.471342Z INFO river::config: CLI config config=Cli { validate_configs: true, config_toml: None, threads_per_service: None }
2024-04-30T09:11:51.471351Z INFO river::config: No TOML file provided
2024-04-30T09:11:51.471353Z INFO river::config: Applying CLI options
2024-04-30T09:11:51.471355Z INFO river::config: Full configuration config=Config { validate_configs: true, threads_per_service: 8, basic_proxies: [] }
2024-04-30T09:11:51.471376Z INFO river: Applying Basic Proxies...
2024-04-30T09:11:51.471379Z INFO river: Bootstrapping...
2024-04-30T09:11:51.471382Z INFO pingora_core::server: Bootstrap starting
2024-04-30T09:11:51.471392Z INFO pingora_core::server: Server Test passed, exiting
```

### Configuration File Support

As discussed in [the Configuration RFC], River will likely need a more extensive configuration file
format in the future, allowing for complex configuration. However for early development, we'll need
a simple and familiar configuration file format for initial development. We've integrated TOML file
support as part of the 0.2.0 release.

TOML file configuration can be used by providing the path to your configuration file at command run
time, e.g. `river --config-toml path/to/your/config.toml`.

[the Configuration RFC]: https://github.com/memorysafety/river/issues/13

Here is a snippet of [a configuration file] showing what is currently possible in the configuration
file:

[a configuration file]: https://github.com/memorysafety/river/blob/1c443ae88b5249b1bacefd9160e7659448b476d5/source/river/assets/test-config.toml

```toml
[system]
# Threads per service
threads-per-service = 8

# Specify a Basic Proxy service, which features minimal configuration.

[[basic-proxy]]
name = "Example1"

# Each `basic-proxy` can have one or more Listeners, or downstream
# connections. If you provide zero, the basic proxy will terminate
# immediately.
[[basic-proxy.listeners]]

[basic-proxy.listeners.source]
kind = "Tcp"

[basic-proxy.listeners.source.value]
addr = "0.0.0.0:4443"

# To enable TLS, specify the path to the certificate and key
[basic-proxy.listeners.source.value.tls]
cert_path = "./assets/test.crt"
key_path = "./assets/test.key"

# Each `basic proxy` must have exactly one "connector", or the upstream
# server they will proxy to.
#
# To use TLS for upstream connections, specify the SNI of the connection
[basic-proxy.connector]
proxy_addr = "91.107.223.4:443"
tls_sni = "onevariable.com"

# "Path Control" affects requests and responses as they are proxied
[basic-proxy.path-control]
# upstream request filters specifically allow for the cancellation or modification
# of requests, as they are being made.
#
# Filters are applied in the order they are specified. Multiple instances of
# each filter may be provided.
upstream-request-filters = [
# Remove any headers with keys matching `pattern`
{ kind = "remove-header-key-regex", pattern = ".*(secret|SECRET).*" },
# Add or replace (e.g. "Upsert") a fixed header with the given key and value
{ kind = "upsert-header", key = "x-proxy-friend", value = "river" },
]

upstream-response-filters = [
# Remove any headers with keys matching `pattern`
{ kind = "remove-header-key-regex", pattern = ".*ETag.*" },
# Add or replace (e.g. "Upsert") a fixed header with the given key and value
{ kind = "upsert-header", key = "x-with-love-from", value = "river" },
]
```

### `pingora` integration

As shown in the configuration file above, River has integrated basic support for the `pingora`
engine. It is now possible to specify multiple listeners (downstream listening ports),
and a single connector (upstream server).

Support for multiple connectors will be added in the future, once load balancing and health
check support from `pingora` has been integrated into River. It is also possible to terminate
TLS connections, forwarding on with or without TLS to proxied connections.

### "Path Control" support

The `pingora-proxy` library provides numerous points in the connection and proxying life cycle
to modify or reject proxied requests and responses. As a command line tool, River aims to
provide a set of configurable operators that can be selected via the TOML configuration file.

The 0.2.0 release includes the first of these "Path Control" operators, allowing the ability to
Add, Remove, or Replace HTML headers on both requests and responses. Users may select multiple
operators, which will be applied sequentially in the order they are specified. This allows users
to add or replace fixed text headers, or remove headers with keys matching a Regular Expression
pattern.

See the configuration file snippet examples for examples.

### Release Tooling support

In future releases, closer to a "1.0" release, River will need to be packaged for end user usage,
for example in operating system package managers, as a published container image, and other
commonly expected formats.

As River is in early developer preview, for now binaries are published as part of the tagged Github
release. These binaries are published with their SHA256sum, allowing for integrity checks.

Release tooling was provided using [`cargo-dist`]. This includes the release automation, as well
as installer scripts that can be used by developers or in container build tooling.

### Things that didn't make the cut during 0.2.0

There were a few items that were discussed for the 0.2.0 release. These will likely be included in
a future release:

1. A `crates-io` release. At the moment, we depend on a slightly patched version of `pingora` in
order to expose a few items not currently public. Once this has been resolved, we will also
publish future versions on crates-io, allowing for `cargo install river`.
2. CI testing for unit, integration, and/or benchmark testing. At the moment, there is only a
single active developer, and a minimal set of functionality. This will be prioritized in
the near future. We hope to track benchmark performance over time, but writing meaningful
benchmarks requires a non-trivial amount of effort, as well as potentially dedicated
infrastructure to obtain consistent results.
3. Support for `tracing` was included in this release, including capturing of `log` based logging
emitted by `pingora` itself. In the future, we may add increased observability functionality
including performance counters and request measurements. This was deferred due to the minimal
functionality added beyond baseline `pingora` support.

### Contributor thanks

We'd like to thank [@lperdereau] for their first contribution to River in this release.

[@lperdereau]: https://github.com/lperdereau