-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* import configuration from bifrost-gateway * add Kubo RPC URL env vars and /api/v0 support via delegation/forwarding * add support for executing routing locally if no delegated endpoint * add DNS resolution caching layer * add tracing and metrics * add debugging and metrics endpoints * add Dockerfile * switched cli flags to only expose the port and always run on localhost * add more standard ignores to .gitignore * add http user agent
- Loading branch information
1 parent
64c73a2
commit dad528b
Showing
18 changed files
with
1,652 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.20-bullseye AS builder | ||
# This builds rainbow | ||
|
||
ARG TARGETPLATFORM TARGETOS TARGETARCH | ||
|
||
ENV GOPATH /go | ||
ENV SRC_PATH $GOPATH/src/github.com/ipfs/rainbow | ||
ENV GO111MODULE on | ||
ENV GOPROXY https://proxy.golang.org | ||
|
||
COPY go.* $SRC_PATH/ | ||
WORKDIR $SRC_PATH | ||
RUN go mod download | ||
|
||
COPY . $SRC_PATH | ||
RUN git config --global --add safe.directory /go/src/github.com/ipfs/rainbow | ||
|
||
RUN --mount=target=. \ | ||
--mount=type=cache,target=/root/.cache/go-build \ | ||
--mount=type=cache,target=/go/pkg \ | ||
CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o $GOPATH/bin/rainbow | ||
|
||
#------------------------------------------------------ | ||
FROM alpine:3.18 | ||
|
||
# This runs rainbow | ||
|
||
# Instal binaries for $TARGETARCH | ||
RUN apk add --no-cache tini su-exec ca-certificates | ||
|
||
ENV GOPATH /go | ||
ENV SRC_PATH $GOPATH/src/github.com/ipfs/rainbow | ||
ENV RAINBOW_GATEWAY_PATH /data/rainbow | ||
ENV KUBO_RPC_URL https://node0.delegate.ipfs.io,https://node1.delegate.ipfs.io,https://node2.delegate.ipfs.io,https://node3.delegate.ipfs.io | ||
|
||
COPY --from=builder $GOPATH/bin/rainbow /usr/local/bin/rainbow | ||
COPY --from=builder $SRC_PATH/docker/entrypoint.sh /usr/local/bin/entrypoint.sh | ||
|
||
RUN mkdir -p $RAINBOW_GATEWAY_PATH && \ | ||
adduser -D -h $RAINBOW_GATEWAY_PATH -u 1000 -G users ipfs && \ | ||
chown ipfs:users $RAINBOW_GATEWAY_PATH | ||
VOLUME $RAINBOW_GATEWAY_PATH | ||
|
||
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/entrypoint.sh"] | ||
|
||
CMD ["--gateway-port", "8080", "--api-port", "8081"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"time" | ||
|
||
"github.com/rs/dnscache" | ||
) | ||
|
||
// How often should we check for successful updates to cached entries | ||
const dnsCacheRefreshInterval = 5 * time.Minute | ||
|
||
// Local DNS cache because in this world things are ephemeral | ||
type cachedDNS struct { | ||
resolver *dnscache.Resolver | ||
refresher *time.Ticker | ||
} | ||
|
||
func newCachedDNS(refreshInterval time.Duration) *cachedDNS { | ||
cache := &cachedDNS{ | ||
resolver: &dnscache.Resolver{}, | ||
refresher: time.NewTicker(refreshInterval), | ||
} | ||
|
||
// Configure DNS cache to not remove stale records to protect gateway from | ||
// catastrophic failures like https://github.com/ipfs/bifrost-gateway/issues/34 | ||
options := dnscache.ResolverRefreshOptions{} | ||
options.ClearUnused = false | ||
options.PersistOnFailure = true | ||
|
||
// Every refreshInterval we check for updates, but if there is | ||
// none, or if domain disappears, we keep the last cached version | ||
go func(cdns *cachedDNS) { | ||
defer cdns.refresher.Stop() | ||
for range cdns.refresher.C { | ||
cdns.resolver.RefreshWithOptions(options) | ||
} | ||
}(cache) | ||
|
||
return cache | ||
} | ||
|
||
// dialWithCachedDNS implements DialContext that uses cachedDNS | ||
func (cdns *cachedDNS) dialWithCachedDNS(ctx context.Context, network string, addr string) (conn net.Conn, err error) { | ||
host, port, err := net.SplitHostPort(addr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
ips, err := cdns.resolver.LookupHost(ctx, host) | ||
if err != nil { | ||
return nil, err | ||
} | ||
// Try all IPs returned by DNS | ||
for _, ip := range ips { | ||
var dialer net.Dialer | ||
conn, err = dialer.DialContext(ctx, network, net.JoinHostPort(ip, port)) | ||
if err == nil { | ||
break | ||
} | ||
} | ||
return | ||
} | ||
|
||
func (cdns *cachedDNS) Close() error { | ||
cdns.refresher.Stop() | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/sh | ||
|
||
set -e | ||
user=ipfs | ||
|
||
if [ -n "$DOCKER_DEBUG" ]; then | ||
set -x | ||
fi | ||
|
||
if [ `id -u` -eq 0 ]; then | ||
echo "Changing user to $user" | ||
exec su-exec "$user" "$0" $@ | ||
fi | ||
|
||
# Only ipfs user can get here | ||
rainbow --version | ||
|
||
exec rainbow $@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#!/usr/bin/env bash | ||
|
||
# get-docker-tags.sh produces Docker tags for the current build | ||
# | ||
# Usage: | ||
# ./get-docker-tags.sh <build number> <git commit sha1> <git branch name> [git tag name] | ||
# | ||
# Example: | ||
# | ||
# # get tag for the main branch | ||
# ./get-docker-tags.sh $(date -u +%F) testingsha main | ||
# | ||
# # get tag for a release tag | ||
# ./get-docker-tags.sh $(date -u +%F) testingsha release v0.5.0 | ||
# | ||
# # Serving suggestion in CI | ||
# ./get-docker-tags.sh $(date -u +%F) "$CI_SHA1" "$CI_BRANCH" "$CI_TAG" | ||
# | ||
set -euo pipefail | ||
|
||
if [[ $# -lt 1 ]] ; then | ||
echo 'At least 1 arg required.' | ||
echo 'Usage:' | ||
echo './get-docker-tags.sh <build number> [git commit sha1] [git branch name] [git tag name]' | ||
exit 1 | ||
fi | ||
|
||
BUILD_NUM=$1 | ||
GIT_SHA1=${2:-$(git rev-parse HEAD)} | ||
GIT_SHA1_SHORT=$(echo "$GIT_SHA1" | cut -c 1-7) | ||
GIT_BRANCH=${3:-$(git symbolic-ref -q --short HEAD || echo "unknown")} | ||
GIT_TAG=${4:-$(git describe --tags --exact-match 2> /dev/null || echo "")} | ||
|
||
IMAGE_NAME=${IMAGE_NAME:-ipfs/rainbow} | ||
|
||
echoImageName () { | ||
local IMAGE_TAG=$1 | ||
echo "$IMAGE_NAME:$IMAGE_TAG" | ||
} | ||
|
||
if [[ $GIT_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc ]]; then | ||
echoImageName "$GIT_TAG" | ||
|
||
elif [[ $GIT_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | ||
echoImageName "$GIT_TAG" | ||
echoImageName "latest" | ||
|
||
elif [ "$GIT_BRANCH" = "main" ]; then | ||
echoImageName "main-${BUILD_NUM}-${GIT_SHA1_SHORT}" | ||
echoImageName "main-latest" | ||
|
||
|
||
else | ||
echo "Nothing to do. No docker tag defined for branch: $GIT_BRANCH, tag: $GIT_TAG" | ||
|
||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# Rainbow Environment Variables | ||
|
||
`rainbow` ships with some implicit defaults that can be adjusted via env variables below. | ||
|
||
- [Configuration](#configuration) | ||
- [`KUBO_RPC_URL`](#kubo_rpc_url) | ||
- [Logging](#logging) | ||
- [`GOLOG_LOG_LEVEL`](#golog_log_level) | ||
- [`GOLOG_LOG_FMT`](#golog_log_fmt) | ||
- [`GOLOG_FILE`](#golog_file) | ||
- [`GOLOG_TRACING_FILE`](#golog_tracing_file) | ||
- [Testing](#testing) | ||
- [`GATEWAY_CONFORMANCE_TEST`](#gateway_conformance_test) | ||
- [`IPFS_NS_MAP`](#ipfs_ns_map) | ||
|
||
## Configuration | ||
|
||
|
||
### `KUBO_RPC_URL` | ||
|
||
Default: see `DefaultKuboRPC` | ||
|
||
Single URL or a comma separated list of RPC endpoints that provide `/api/v0` from Kubo. | ||
|
||
We use this to redirect some legacy `/api/v0` commands that need to be handled on `ipfs.io`. | ||
|
||
## Logging | ||
|
||
### `GOLOG_LOG_LEVEL` | ||
|
||
Specifies the log-level, both globally and on a per-subsystem basis. Level can | ||
be one of: | ||
|
||
* `debug` | ||
* `info` | ||
* `warn` | ||
* `error` | ||
* `dpanic` | ||
* `panic` | ||
* `fatal` | ||
|
||
Per-subsystem levels can be specified with `subsystem=level`. One global level | ||
and one or more per-subsystem levels can be specified by separating them with | ||
commas. | ||
|
||
Default: `error` | ||
|
||
Example: | ||
|
||
```console | ||
GOLOG_LOG_LEVEL="error,bifrost-gateway=debug,caboose=debug" bifrost-gateway | ||
``` | ||
|
||
### `GOLOG_LOG_FMT` | ||
|
||
Specifies the log message format. It supports the following values: | ||
|
||
- `color` -- human readable, colorized (ANSI) output | ||
- `nocolor` -- human readable, plain-text output. | ||
- `json` -- structured JSON. | ||
|
||
For example, to log structured JSON (for easier parsing): | ||
|
||
```bash | ||
export GOLOG_LOG_FMT="json" | ||
``` | ||
The logging format defaults to `color` when the output is a terminal, and | ||
`nocolor` otherwise. | ||
|
||
### `GOLOG_FILE` | ||
|
||
Sets the file to which the Bifrost Gateway logs. By default, the Bifrost Gateway | ||
logs to the standard error output. | ||
|
||
### `GOLOG_TRACING_FILE` | ||
|
||
Sets the file to which the Bifrost Gateway sends tracing events. By default, | ||
tracing is disabled. | ||
|
||
Warning: Enabling tracing will likely affect performance. | ||
|
||
|
||
## Testing | ||
|
||
### `GATEWAY_CONFORMANCE_TEST` | ||
|
||
Setting to `true` enables support for test fixtures required by [ipfs/gateway-conformance](https://github.com/ipfs/gateway-conformance) test suite. | ||
|
||
### `IPFS_NS_MAP` | ||
|
||
Adds static namesys records for deterministic tests and debugging. | ||
Useful for testing `/ipns/` support without having to do real IPNS/DNS lookup. | ||
|
||
Example: | ||
|
||
```console | ||
$ IPFS_NS_MAP="dnslink-test1.example.com:/ipfs/bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am,dnslink-test2.example.com:/ipns/dnslink-test1.example.com" ./gateway-binary | ||
... | ||
$ curl -is http://127.0.0.1:8081/dnslink-test2.example.com/ | grep Etag | ||
Etag: "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.