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

feat: improvements & gateway-conformance support (light) #57

Merged
merged 27 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4a95ee3
ci: add gateway-conformance tests
aschmahmann Dec 4, 2023
db993fa
ci(gateway-conformance): use minimal specs for websites (no _redirects)
aschmahmann Dec 4, 2023
46c4ad9
feat: enable gateway conformance testing locally
SgtPooki Dec 4, 2023
a57d76c
docs: gwc info added to DEVELOPER-NOTES.md
SgtPooki Dec 4, 2023
98afa15
fix(test:gwc): test:gwc-setup split out from test:gwc
SgtPooki Dec 4, 2023
5549c41
fix: use proper env var and cleanup scripts
SgtPooki Dec 4, 2023
0778d65
chore(ci:gwc): enable only subdomain ipfs and ipns
SgtPooki Dec 4, 2023
daefd4f
fix: enable kubo routing-v1 for ipns
SgtPooki Dec 4, 2023
8722856
chore: kubo-init daemon starting line
SgtPooki Dec 4, 2023
13ed71a
fix(ci:gwc): set subdomain-url arg
SgtPooki Dec 4, 2023
4b00467
fix(ci:gwc): skip dir list and gateway cache tests
SgtPooki Dec 4, 2023
d39a3db
chore(ci:gcw): don't use bitswap
SgtPooki Dec 4, 2023
ad5be2e
docs(ci:gwc): add more details about gwc local testing
SgtPooki Dec 4, 2023
b137aac
docs(ci:gwc): more documentation of things
SgtPooki Dec 5, 2023
fc3e4f3
chore: add ECHO_HEADERS & notes
SgtPooki Dec 5, 2023
337bf7e
chore: some more things
SgtPooki Dec 5, 2023
25cd97a
Merge branch 'main' into ci/gateway-conformance
SgtPooki Dec 5, 2023
0e81d25
fix: webrtc errors
SgtPooki Dec 5, 2023
b047f52
feat: use custom libp2p node
SgtPooki Dec 5, 2023
1317ada
fix: custom libp2p & playwright config
SgtPooki Dec 6, 2023
a520039
chore: add fastify/cors patch
SgtPooki Dec 6, 2023
f3557a3
feat: use @helia/ipns
SgtPooki Dec 6, 2023
2fe9ce3
chore: remove RESOLVE_REDIRECTS
SgtPooki Dec 6, 2023
ad50a77
chore: various refactorings to support more gateway stuff
SgtPooki Dec 6, 2023
82a19d4
chore: some notes
SgtPooki Dec 6, 2023
ce971eb
fix: minor fix to using delegated routing
SgtPooki Dec 6, 2023
a2bd0dc
chore: some env var setup, patches, and notes
SgtPooki Dec 6, 2023
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
18 changes: 18 additions & 0 deletions .env-all
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ENV vars recommended for running with everything enabled:
# * trustless gateways
# * delegated routing
# * libp2p
# * bitswap
USE_LIBP2P=true
USE_BITSWAP=true
DEBUG='helia-http-gateway*,*helia-fetch*'
USE_TRUSTLESS_GATEWAYS=true
USE_DELEGATED_ROUTING=true

# Uncomment the two below to save blockstore and datastore to disk
# FILE_DATASTORE_PATH=./data/datastore
# FILE_BLOCKSTORE_PATH=./data/blockstore

# If you want to run the gateway with a local trustless gateway, uncomment the below
# PORT=8090 # or whatever port you want to run helia-http-gateway on
# TRUSTLESS_GATEWAYS=http://127.0.0.1:8080
16 changes: 16 additions & 0 deletions .env-delegated-routing
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# ENV vars recommended for running with only delegated-routing-v1-http
USE_LIBP2P=false
# needed to request blocks from peers we discover with delegated routing
USE_BITSWAP=true
# TRUSTLESS_GATEWAYS=http://127.0.0.1:8080
DEBUG='helia-http-gateway*,*helia-fetch*,*delegated-routing-v1-http-api-client*'
USE_TRUSTLESS_GATEWAYS=false
USE_DELEGATED_ROUTING=true

# IF you're delegating to kubo running locally you should uncomment the two below:
# PORT=8090
# DELEGATED_ROUTING_V1_HOST=http://127.0.0.1:8080

# Uncomment the two below to save blockstore and datastore to disk
# FILE_DATASTORE_PATH=./data/datastore
# FILE_BLOCKSTORE_PATH=./data/blockstore
16 changes: 16 additions & 0 deletions .env-gwc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# ENV vars recommended for running gateway-conformance tests
USE_LIBP2P=false
USE_BITSWAP=true
PORT=8090 # helia-http-gateway should be running here
TRUSTLESS_GATEWAYS=http://127.0.0.1:8080 # Kubo should be running here
DELEGATED_ROUTING_V1_HOST=http://127.0.0.1:8080 # Kubo should be running here
DEBUG='helia-http-gateway*,*helia-fetch*,*helia:trustless-gateway-block-broker*'
USE_TRUSTLESS_GATEWAYS=true
USE_DELEGATED_ROUTING=true

# Uncomment the two below to save blockstore and datastore to disk
# FILE_DATASTORE_PATH=./data/datastore
# FILE_BLOCKSTORE_PATH=./data/blockstore

# Uncomment the below to see request & response headers in the logs
# ECHO_HEADERS=true
14 changes: 14 additions & 0 deletions .env-trustless-only
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# ENV vars recommended for running with trustless gateways only
USE_LIBP2P=false
USE_BITSWAP=false
DEBUG='helia-http-gateway*,*helia-fetch*,*helia:trustless-gateway-block-broker*'
USE_TRUSTLESS_GATEWAYS=true
USE_DELEGATED_ROUTING=false

# Uncomment the two below to save blockstore and datastore to disk
# FILE_DATASTORE_PATH=./data/datastore
# FILE_BLOCKSTORE_PATH=./data/blockstore

# If you want to run the gateway with a local trustless gateway, uncomment the below
# PORT=8090 # or whatever port you want to run helia-http-gateway on
# TRUSTLESS_GATEWAYS=http://127.0.0.1:8080
121 changes: 121 additions & 0 deletions .github/workflows/gateway-conformance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Gateway Conformance

on:
push:
branches:
- main
pull_request:

jobs:
gateway-conformance:
runs-on: ubuntu-latest
steps:
# 1. Start the Kubo gateway
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: 1.21.x

- name: Install Kubo gateway from source
#uses: ipfs/download-ipfs-distribution-action@v1
run: |
go install github.com/ipfs/kubo/cmd/ipfs@v0.24.0
- name: Setup kubo config
run: |
ipfs init --profile=test
ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8080"

# 2. Download the gateway-conformance fixtures
- name: Download gateway-conformance fixtures
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.4.1
with:
output: fixtures

- name: Start Kubo gateway
uses: ipfs/start-ipfs-daemon-action@v1

# 3. Populate the Kubo gateway with the gateway-conformance fixtures
- name: Import fixtures
run: |
# Import car files
find ./fixtures -name '*.car' -exec ipfs dag import --pin-roots=false --offline {} \;

# Import ipns records
records=$(find ./fixtures -name '*.ipns-record')
for record in $records
do
key=$(basename -s .ipns-record "$record" | cut -d'_' -f1)
ipfs routing put --allow-offline "/ipns/$key" "$record"
done

# Import dnslink records
# the IPFS_NS_MAP env will be used by the daemon
export IPFS_NS_MAP=$(cat "./fixtures/dnslinks.json" | jq -r '.subdomains | to_entries | map("\(.key).example.com:\(.value)") | join(",")')
export IPFS_NS_MAP="$(cat "./fixtures/dnslinks.json" | jq -r '.domains | to_entries | map("\(.key):\(.value)") | join(",")'),${IPFS_NS_MAP}"
echo "IPFS_NS_MAP=${IPFS_NS_MAP}" >> $GITHUB_ENV

# 4. Build helia-http-gateway
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 20

- name: Checkout helia-http-gateway
uses: actions/checkout@v3
with:
path: helia-http-gateway

- name: Install dependencies
run: npm ci
working-directory: helia-http-gateway

- name: Build helia-http-gateway
run: npm run build
working-directory: helia-http-gateway

# 5. Start helia-http-gateway
- name: Start helia-http-gateway
env:
GATEWAY_CONFORMANCE_TEST: true
TRUSTLESS_GATEWAYS: "http://127.0.0.1:8080"
USE_LIBP2P: false
PORT: 8090
run: |
# run gw
node dist/src/index.js &
working-directory: helia-http-gateway

# 6. Run the gateway-conformance tests
- name: Run gateway-conformance tests
uses: ipfs/gateway-conformance/.github/actions/test@v0.4.1
with:
gateway-url: http://127.0.0.1:8090
subdomain-url: http://127.0.0.1:8090
json: output.json
xml: output.xml
html: output.html
markdown: output.md
# specs: subdomain-ipfs-gateway,subdomain-ipns-gateway
# use below to skip specific test if needed
# args: -skip 'TestFooBr/GET_response_for_something'
#
# only-if-cached: helia-ht does not guarantee local cache, we will adjust upstream test (which was Kubo-specific)
# for now disabling these test cases
args: -skip '^.*(DirectoryListing|TestGatewayCache|TestSubdomainGatewayDNSLinkInlining|proxy|TestGatewaySubdomainAndIPNS|TestGatewaySubdomains|Trustless|TestGatewayIPNSRecord|RedirectsFile|TestGatewayUnixFSFileRanges|TestGatewayJSONCborAndIPNS|TestTar|Symlink|TestPathGatewayMiscellaneous|TestGatewayBlock|TestRedirectCanonicalIPNS|TestGatewayIPNSPath|TestNativeDag|TestPathing|TestPlainCodec|TestDagPbConversion|TestGatewayJsonCbor|TestCors).*$'

# 7. Upload the results
- name: Upload MD summary
if: failure() || success()
run: cat output.md >> $GITHUB_STEP_SUMMARY
- name: Upload HTML report
if: failure() || success()
uses: actions/upload-artifact@v3
with:
name: gateway-conformance.html
path: output.html
- name: Upload JSON report
if: failure() || success()
uses: actions/upload-artifact@v3
with:
name: gateway-conformance.json
path: output.json
19 changes: 19 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@ jobs:
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps

# Cache playwright binaries
- uses: actions/cache@v3
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('**/package-lock.json') }}
- run: npx playwright install --with-deps
if: steps.playwright-cache.outputs.cache-hit != 'true'

# Cache datastores
- uses: actions/cache@v3
id: e2e-datastore-and-blockstore
with:
path: |
./test/fixtures/e2e
key: ${{ runner.os }}-e2e-stores-${{ hashFiles('**/package-lock.json') }}

- name: Run Playwright tests
run: npm run test:e2e
env:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,6 @@ build
/playwright/.cache/
screenshots
.envrc
scripts/tmp/fixtures
scripts/tmp/kubo-path.txt
test/fixtures/e2e
84 changes: 84 additions & 0 deletions DEVELOPER-NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Developer notes

<!-- toc -->

## Gateway Conformance testing

We have some code enabled that makes running gateway-conformance testing against helia-http-gateway easy. Follow the instructions in this section to run gateway-conformance tests locally

### Prerequisites

1. [Install docker](https://docs.docker.com/get-docker/)
2. [Install nodejs](https://nodejs.org/en/download/)

### Run gateway-conformance tests locally (once)

```sh
$ npm run test:gwc
```

### Continuously develop while running gateway-conformance tests

```sh
# terminal 1
$ npm run test:gwc-kubo
# You can also set up the kubo backing node with the instructions at https://github.com/ipfs/gateway-conformance/blob/main/docs/development.md#developing-against-kubo

# terminal 2
# you will need to stop and start this one in-between code changes. It's not watching for changes
$ DEBUG="helia-http-gateway*" FILE_DATASTORE_PATH=./tmp/datastore npm run test:gwc-helia

# terminal 3
$ npm run test:gwc-execute
# To skip some tests, run something like:
# npm run test:gwc-execute -- -skip '^.*(DirectoryListing|TestGatewayCache|TestSubdomainGatewayDNSLinkInlining|TestGatewaySubdomainAndIPNS).*$'

# OR from the gateway-conformance repo directly with something like:
go run ./cmd/gateway-conformance/main.go test --gateway-url 'http://localhost:8090' --subdomain-url 'http://localhost:8090' --specs subdomain-ipfs-gateway,subdomain-ipns-gateway --json gwc-report.json -- -timeout 30m

```



### Some callouts

1. You may want to set up an nginx proxy from `http://helia-http-gateway.localhost` to `http://localhost:8090`to help with the gateway-conformance tests. See [this issue](https://github.com/ipfs/gateway-conformance/issues/185)
1. You may want to run the gateway-conformance tests directly from the repo if you're on a macOS M1 due to some issues with docker and the proxying that the gateway-conformance testing tool uses. If you do this, you'll need to run `make gateway-conformance` in the `gateway-conformance` repo root, and then run the tests with something like `go run ./cmd/gateway-conformance/main.go test --gateway-url 'http://localhost:8090' --subdomain-url 'http://localhost:8090' --specs subdomain-ipfs-gateway,subdomain-ipns-gateway --json gwc-report.json -- -timeout 30m`.
- If you want to run a specific test, you can pass the `-run` gotest flag. e.g. `go run ./cmd/gateway-conformance/main.go test --gateway-url 'http://localhost:8090' --subdomain-url 'http://localhost:8090' --json gwc-report.json -- -timeout 30m -run 'TestGatewaySubdomains/request_for_example.com%2Fipfs%2F%7BCIDv1%7D_redirects_to_subdomain_%28HTTP_proxy_tunneling_via_CONNECT%29#01'`
1. The file `./scripts/kubo-init.js` executes kubo using `execa` instead of `ipfsd-ctl` so there may be some gotchas, but it should be as cross-platform and stable as the `execa` library.
1. The IPFS_PATH used is a temporary directory. Your OS should handle removing it when vital, but you can also remove it manually. The path to this directory is printed out when the tests start, and saved in a file at `./scripts/tmp/kubo-path.txt`.
1. The tests save gateway-conformance fixtures to `./scripts/tmp/fixtures`. You can remove this directory manually if you want to re-run the tests with a fresh set of fixtures.
1. The results of the gateway-conformance tests are saved to `./gwc-report.json`. This file is overwritten every time the tests are run.
1. The gateway-conformance tests are flaky and commands & documentation are not up to date. Running commands with CLI flags is supposed to work, and env vars aren't documented, but ENV_VARs are the only way to get the tests to run, but not when ran with docker. See [this issue](https://github.com/ipfs/gateway-conformance/issues/185#issuecomment-1839801366)


## Tiros info

### Deploying to Tiros

Go to https://github.com/plprobelab/probelab-infra/blob/main/aws/tf/tiros.tf

update helia stuff

run terraform apply (with AWS Config)

### Kick off helia-http-gateway task manually:

1. https://us-west-1.console.aws.amazon.com/ecs/v2/clusters/prod-usw1-ecs-cluster/run-task?region=us-west-1
1. select launch type FARGATE
1. select deployment configuration application type to be task
1. select task-helia family
1. select vpc (non-default)
1. select security group for tiros
1. Click create

### Todo

- [ ] Fix helia_health_cmd (https://github.com/plprobelab/probelab-infra/blob/7ec47f16e84113545cdb06b07f865a3bc5787a0b/aws/tf/tiros.tf#L5C4-L5C4) to use the new helia-health command
- [ ] fix node max memory for helia-http-gateway docker container to support at least 4GB

### Links

graphs for runs are at https://probelab.grafana.net/d/GpwxraxVk/tiros-ops?orgId=1&from=now-7d&to=now&inspect=8&inspectTab=error
AWS logs for runs are at https://us-west-1.console.aws.amazon.com/cloudwatch/home?region=us-west-1#logsV2:log-groups/log-group/prod-usw1-cmi-tiros-ipfs (you need to be logged in to AWS)

10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ $ docker run -it -p 8080:8080 -e DEBUG="helia-http-gateway*" helia-http-gateway:
| `USE_TRUSTLESS_GATEWAYS` | Whether to fetch content from trustless-gateways or not | `true` |
| `TRUSTLESS_GATEWAYS` | Comma separated list of trusted gateways to fetch content from | [Defined in Helia](https://github.com/ipfs/helia/blob/main/packages/helia/src/block-brokers/trustless-gateway/index.ts) |
| `USE_LIBP2P` | Whether to use libp2p networking | `true` |
| `RESOLVE_REDIRECTS` | Whether to resolve redirects before looking up dnslink entries | `true` |
| `ECHO_HEADERS` | A debug flag to indicate whether you want to output request and response headers | `false` |
| `DELEGATED_ROUTING_V1_HOST` | Hostname to use for delegated routing v1 | `https://delegated-ipfs.dev` |

<!--
TODO: currently broken when used in docker, but they work when running locally (you can cache datastore and blockstore locally to speed things up if you want)
Expand All @@ -63,6 +64,13 @@ TODO: currently broken when used in docker, but they work when running locally (

See the source of truth for all `process.env.<name>` environment variables at [src/constants.ts](src/constants.ts).

You can also see some recommended environment variable configurations at:

- [./.env-all](./.env-all)
- [./.env-delegated-routing](./.env-delegated-routing)
- [./.env-gwc](./.env-gwc)
- [./.env-trustless-only](./.env-trustless-only)

### Running with custom configurations

Note that any of the following calls to docker can be replaced with something like `MY_ENV_VAR="MY_VALUE" npm run start`
Expand Down
4 changes: 2 additions & 2 deletions e2e-tests/smoketest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const pages = [
'docs.ipfs.tech',
'docs.libp2p.io',
'drand.love',
'fil.org',
// 'fil.org', // timing out
// 'filecoin.io', // timing out
// 'green.filecoin.io', // timing out
'ipfs.tech',
Expand All @@ -36,7 +36,7 @@ test.beforeEach(async ({ context }) => {
})

test.afterEach(async ({ page }) => {
test.setTimeout(30000)
test.setTimeout(2 * 60 * 1000) // 2 minutes
const result = await page.request.post(`http://localhost:${PORT}/api/v0/repo/gc`)
expect(result?.status()).toBe(200)

Expand Down
Loading
Loading