From 6556d7e595070b5ed8e802e847f9b67a951e963f Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 17 Apr 2024 19:48:23 -0400 Subject: [PATCH] build: use Task (#1535) --- .github/workflows/build_and_test_debug.yml | 16 +- .gitignore | 11 +- CONTRIBUTING.md | 24 +-- README.md | 5 +- Taskfile.yml | 53 +++++ go.mod | 46 ++++ go.sum | 117 ++++++++++ package.json | 17 +- scripts/run_action.sh | 67 ------ src/metrics_server/README.md | 12 +- src/metrics_server/Taskfile.yml | 65 ++++++ src/metrics_server/build.action.sh | 17 -- src/metrics_server/deploy_dev.action.sh | 29 --- src/metrics_server/deploy_prod.action.sh | 29 --- src/metrics_server/start.action.sh | 25 --- src/metrics_server/test.action.sh | 23 -- ...egration.action.sh => test_integration.sh} | 0 src/sentry_webhook/README.md | 4 +- src/sentry_webhook/Taskfile.yml | 39 ++++ src/sentry_webhook/build.action.sh | 17 -- src/sentry_webhook/deploy.action.sh | 25 --- src/sentry_webhook/test.action.sh | 26 --- src/sentry_webhook/tsconfig.json | 1 - src/shadowbox/README.md | 43 ++-- src/shadowbox/Taskfile.yml | 198 +++++++++++++++++ src/shadowbox/docker/Dockerfile | 39 +--- src/shadowbox/docker/build.action.sh | 51 ----- src/shadowbox/docker/start.action.sh | 60 ------ src/shadowbox/integration_test/README.md | 10 +- src/shadowbox/integration_test/run.action.sh | 38 ---- src/shadowbox/integration_test/test.sh | 78 +++---- .../integration_test/util/Dockerfile | 2 +- src/shadowbox/server/build.action.sh | 40 ---- src/shadowbox/server/start.action.sh | 38 ---- src/shadowbox/test.action.sh | 23 -- third_party/outline-ss-server/.gitignore | 1 - third_party/outline-ss-server/LICENSE | 201 ------------------ third_party/outline-ss-server/METADATA | 15 -- third_party/outline-ss-server/Makefile | 28 --- third_party/prometheus/Makefile | 14 +- tools.go | 26 +++ 41 files changed, 653 insertions(+), 920 deletions(-) create mode 100644 Taskfile.yml create mode 100644 go.mod create mode 100644 go.sum delete mode 100755 scripts/run_action.sh create mode 100644 src/metrics_server/Taskfile.yml delete mode 100755 src/metrics_server/build.action.sh delete mode 100755 src/metrics_server/deploy_dev.action.sh delete mode 100755 src/metrics_server/deploy_prod.action.sh delete mode 100755 src/metrics_server/start.action.sh delete mode 100755 src/metrics_server/test.action.sh rename src/metrics_server/{test_integration.action.sh => test_integration.sh} (100%) create mode 100644 src/sentry_webhook/Taskfile.yml delete mode 100755 src/sentry_webhook/build.action.sh delete mode 100755 src/sentry_webhook/deploy.action.sh delete mode 100755 src/sentry_webhook/test.action.sh create mode 100644 src/shadowbox/Taskfile.yml delete mode 100755 src/shadowbox/docker/build.action.sh delete mode 100755 src/shadowbox/docker/start.action.sh delete mode 100755 src/shadowbox/integration_test/run.action.sh delete mode 100755 src/shadowbox/server/build.action.sh delete mode 100755 src/shadowbox/server/start.action.sh delete mode 100755 src/shadowbox/test.action.sh delete mode 100644 third_party/outline-ss-server/.gitignore delete mode 100644 third_party/outline-ss-server/LICENSE delete mode 100644 third_party/outline-ss-server/METADATA delete mode 100644 third_party/outline-ss-server/Makefile create mode 100644 tools.go diff --git a/.github/workflows/build_and_test_debug.yml b/.github/workflows/build_and_test_debug.yml index 261d0627..cbe321a6 100644 --- a/.github/workflows/build_and_test_debug.yml +++ b/.github/workflows/build_and_test_debug.yml @@ -31,7 +31,7 @@ jobs: run: npm ci - name: Lint - run: npm run lint + run: ./task lint shadowbox: name: Shadowbox @@ -51,13 +51,13 @@ jobs: run: npm ci - name: Shadowbox Debug Build - run: npm run action shadowbox/server/build + run: ./task shadowbox:build - name: Shadowbox Unit Test - run: npm run action shadowbox/test + run: ./task shadowbox:test - name: Shadowbox Integration Test - run: npm run action shadowbox/integration_test/run + run: ./task shadowbox:integration_test manual-install-script: name: Manual Install Script @@ -90,10 +90,10 @@ jobs: run: npm ci - name: Metrics Server Debug Build - run: npm run action metrics_server/build + run: ./task metrics_server:build - name: Metrics Server Test - run: npm run action metrics_server/test + run: ./task metrics_server:test sentry-webhook: name: Sentry Webhook @@ -113,7 +113,7 @@ jobs: run: npm ci - name: Sentry Webhook Debug Build - run: npm run action sentry_webhook/build + run: ./task sentry_webhook:build - name: Sentry Webhook Test - run: npm run action sentry_webhook/test + run: ./task sentry_webhook:test diff --git a/.gitignore b/.gitignore index 4b647d93..5cd442a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ .DS_Store +.idea/ +.vscode/ /build/ -node_modules/ /src/server_manager/install_scripts/do_install_script.ts /src/server_manager/install_scripts/gcp_install_script.ts -.vscode/ -.idea/ -third_party/shellcheck/download/ -macos-signing-certificate.p12 \ No newline at end of file +/task +macos-signing-certificate.p12 +node_modules/ +third_party/shellcheck/download/ \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cc7b071c..b9384f0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,26 +24,16 @@ use GitHub pull requests for this purpose. Consult [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more information on using pull requests. -## Build Actions +## Build Tasks -We have a very simple build system based on package.json scripts that are called using `npm run` -and a thin wrapper for what we call build "actions". - -We've defined a package.json script called `action` whose parameter is a relative path: +We use [Task](https://taskfile.dev/) to run tasks. [Install Task](https://taskfile.dev/installation/) and make sure it's in your `PATH`. Then you can run tasks with: ```sh -npm run action $ACTION +task [task_name] ``` -This command will define a `run_action()` function and call `${ACTION}.action.sh`, which must exist. -The called action script can use `run_action` to call its dependencies. The $ACTION parameter is -always resolved from the project root, regardless of the caller location. +To list all available tasks: -The idea of `run_action` is to keep the build logic next to where the relevant code is. -It also defines two environmental variables: - -- `ROOT_DIR`: the root directory of the project, as an absolute path. -- `BUILD_DIR`: where the build output should go, as an absolute path. - -> [!TIP] -> To find all the actions in this project, run `npm run action:list` +```sh +task -a +``` diff --git a/README.md b/README.md index d79e25f9..9ab5ac45 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ See [Shadowsocks resistance against detection and blocking](docs/shadowsocks.md) - [Node](https://nodejs.org/en/download/) LTS (`lts/hydrogen`, version `18.16.0`) - [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) (version `9.5.1`) +- [Go](https://go.dev/dl/) 1.21+ 1. **Install dependencies** @@ -41,7 +42,7 @@ See [Shadowsocks resistance against detection and blocking](docs/shadowsocks.md) 1. **Start the server** ```sh - npm run action shadowbox/server/start + ./task shadowbox:start ``` Exploring further options: @@ -52,5 +53,5 @@ See [Shadowsocks resistance against detection and blocking](docs/shadowsocks.md) 1. **To clean up** ```sh - npm run clean + ./task clean ``` diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 00000000..afc5efd9 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,53 @@ +version: '3' + +set: [pipefail] + +run: when_changed + +vars: + REPO_ROOT: "{{.ROOT_DIR}}" + BUILD_ROOT: "{{.ROOT_DIR}}/build" + DOCKER: '{{.DOCKER | default "docker"}}' + +includes: + metrics_server: + taskfile: ./src/metrics_server/Taskfile.yml + vars: {OUTPUT_BASE: '{{joinPath .BUILD_ROOT "metrics_server"}}'} + + sentry_webhook: + taskfile: ./src/sentry_webhook/Taskfile.yml + vars: {OUTPUT_BASE: '{{joinPath .BUILD_ROOT "sentry_webhook"}}'} + + shadowbox: + taskfile: ./src/shadowbox/Taskfile.yml + vars: {OUTPUT_BASE: '{{joinPath .BUILD_ROOT "shadowbox"}}'} + +tasks: + clean: + desc: Clean output files + cmds: + - rm -rf .task task src/*/node_modules/ build/ node_modules/ third_party/shellcheck/download/ third_party/*/bin third_party/jsign/*.jar + + format: + desc: Format staged files + cmds: ['npx pretty-quick --staged --pattern "**/*.{cjs,html,js,json,md,ts}"'] + + format:all: + desc: Format all files in the repository + cmds: ['npx prettier --write "**/*.{cjs,html,js,json,md,ts}"'] + + lint: + desc: Lint all files + deps: [lint:sh, lint:ts] + + lint:sh: + desc: Lint all shell files + cmds: [bash ./scripts/shellcheck.sh] + + lint:ts: + desc: Lint all .ts and .js files + cmds: ['npx eslint "**/*.{js,ts}"'] + + test: + desc: Run all the repository tests + deps: [lint, metrics_server:test, sentry_webhook:test, shadowbox:test] diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..f91024c3 --- /dev/null +++ b/go.mod @@ -0,0 +1,46 @@ +module localhost + +go 1.21 + +require ( + github.com/Jigsaw-Code/outline-ss-server v1.5.0 + github.com/go-task/task/v3 v3.36.0 +) + +require ( + github.com/Jigsaw-Code/outline-sdk v0.0.14 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-zglob v0.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect + github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect + github.com/oschwald/geoip2-golang v1.8.0 // indirect + github.com/oschwald/maxminddb-golang v1.10.0 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/radovskyb/watcher v1.0.7 // indirect + github.com/sajari/fuzzy v1.0.0 // indirect + github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/zeebo/xxh3 v1.0.2 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + mvdan.cc/sh/v3 v3.8.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..8ada127b --- /dev/null +++ b/go.sum @@ -0,0 +1,117 @@ +github.com/Jigsaw-Code/outline-sdk v0.0.14 h1:uJLvIne7YJNolbX7KDacd8gLidrUzRuweBO2APmQEmI= +github.com/Jigsaw-Code/outline-sdk v0.0.14/go.mod h1:9cEaF6sWWMzY8orcUI9pV5D0oFp2FZArTSyJiYtMQQs= +github.com/Jigsaw-Code/outline-ss-server v1.5.0 h1:Vz+iS0xR7i3PrLD82pzFFwZ9fsh6zrNawMeYERR8VTc= +github.com/Jigsaw-Code/outline-ss-server v1.5.0/go.mod h1:KaebwBiCWDSkgsJrJIbGH0szON8CZq4LgQaFV8v3RM4= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= +github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-task/task/v3 v3.36.0 h1:XVJ5hQ5hdzTAulHpAGzbUMUuYr9MUOEQFOFazI3hUsY= +github.com/go-task/task/v3 v3.36.0/go.mod h1:XBCIAzuyG/mgZVHMUm3cCznz4+IpsBQRlW1gw7OA5sA= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM= +github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= +github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/oschwald/geoip2-golang v1.8.0 h1:KfjYB8ojCEn/QLqsDU0AzrJ3R5Qa9vFlx3z6SLNcKTs= +github.com/oschwald/geoip2-golang v1.8.0/go.mod h1:R7bRvYjOeaoenAp9sKRS8GX5bJWcZ0laWO5+DauEktw= +github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= +github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= +github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= +github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= +github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY= +github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo= +github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28= +github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8= +mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY= diff --git a/package.json b/package.json index b70a4489..525ae068 100644 --- a/package.json +++ b/package.json @@ -24,27 +24,18 @@ "pretty-quick": "^3.1.1", "typescript": "^4.9.5" }, + "scripts": { + "postinstall": "go build github.com/go-task/task/v3/cmd/task" + }, "engines": { "node": "18.x.x" }, - "scripts": { - "action": "bash ./scripts/run_action.sh", - "action:help": "npm run action", - "action:list": "npm run action", - "clean": "rm -rf src/*/node_modules/ build/ node_modules/ src/server_manager/install_scripts/do_install_script.ts src/server_manager/install_scripts/gcp_install_script.ts third_party/shellcheck/download/ third_party/*/bin third_party/jsign/*.jar", - "format": "pretty-quick --staged --pattern \"**/*.{cjs,html,js,json,md,ts}\"", - "format:all": "prettier --write \"**/*.{cjs,html,js,json,md,ts}\"", - "lint": "npm run lint:sh && npm run lint:ts", - "lint:sh": "bash ./scripts/shellcheck.sh", - "lint:ts": "eslint \"**/*.{js,ts}\"", - "test": "npm run lint && npm run action metrics_server/test && npm run action sentry_webhook/build && npm run action server_manager/test && npm run action shadowbox/test" - }, "workspaces": [ "src/*" ], "husky": { "hooks": { - "pre-commit": "npm run lint && npm run format" + "pre-commit": "./task lint format" } } } diff --git a/scripts/run_action.sh b/scripts/run_action.sh deleted file mode 100755 index f8861b28..00000000 --- a/scripts/run_action.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eu - -# TODO: Because Node.js on Cygwin doesn't handle absolute paths very -# well, it would be worth pushd-ing to ROOT_DIR before invoking -# them and making BUILD_DIR a relative path, viz. just "build". - -readonly ROOT_DIR=${ROOT_DIR:-$(pwd)/$(git rev-parse --show-cdup)} -readonly BUILD_DIR=${BUILD_DIR:-${ROOT_DIR}/build} - -export ROOT_DIR -export BUILD_DIR - -export run_action_indent='' - -function run_action() { - local -r STYLE_BOLD_WHITE='\033[1;37m' - local -r STYLE_BOLD_GREEN='\033[1;32m' - local -r STYLE_BOLD_RED='\033[1;31m' - local -r STYLE_RESET='\033[0m' - - local -r action="${1:-""}" - local -r old_indent="${run_action_indent}" - - run_action_indent="=> ${run_action_indent}" - - if [[ -z "${action}" ]]; then - echo -e "Please provide an action to run. ${STYLE_BOLD_WHITE}List of valid actions:${STYLE_RESET}\n" - find . -name '*.action.sh' | sed -E 's:\./src/(.*)\.action\.sh:\1:' - exit 0 - fi - - echo -e "${old_indent}${STYLE_BOLD_WHITE}[Running ${action}]${STYLE_RESET}" - shift - - "${ROOT_DIR}src/${action}.action.sh" "$@" - - local -ir status="$?" - if (( status == 0 )); then - echo -e "${old_indent}${STYLE_BOLD_GREEN}[${action}: Finished]${STYLE_RESET}" - else - echo -e "${old_indent}${STYLE_BOLD_RED}[${action}: Failed]${STYLE_RESET}" - fi - - run_action_indent="${old_indent}" - - return "${status}" -} - -export -f run_action - -run_action "$@" diff --git a/src/metrics_server/README.md b/src/metrics_server/README.md index e1c6ed77..aa5cb784 100644 --- a/src/metrics_server/README.md +++ b/src/metrics_server/README.md @@ -48,7 +48,7 @@ The metrics server supports two URL paths: ## Build ```sh -npm run action metrics_server/build +task metrics_server:build ``` ## Run @@ -56,7 +56,7 @@ npm run action metrics_server/build Run a local development metrics server: ```sh -npm run action metrics_server/start +task metrics_server:start ``` ## Deploy @@ -67,20 +67,20 @@ npm run action metrics_server/start ``` - To deploy to dev: ```sh - npm run action metrics_server/deploy_dev + task metrics_server:deploy:dev ``` - To deploy to prod: ```sh - npm run action metrics_server/deploy_prod + task metrics_server:deploy:prod ``` ## Test - Unit test ```sh - npm run action metrics_server/test + task metrics_server:test ``` - Integration test ```sh - npm run action metrics_server/test_integration + task metrics_server:integration_test ``` diff --git a/src/metrics_server/Taskfile.yml b/src/metrics_server/Taskfile.yml new file mode 100644 index 00000000..f9cdc4ca --- /dev/null +++ b/src/metrics_server/Taskfile.yml @@ -0,0 +1,65 @@ +version: '3' + +requires: + vars: [OUTPUT_BASE] + +tasks: + clean: + desc: Clean metrics server output + cmds: + - rm -rf "{{.OUTPUT_BASE}}" + + build: + desc: Build the metrics server + vars: + BUILD_MODE: '{{.BUILD_MODE | default "dev"}}' + TARGET_DIR: &default-target-dir '{{joinPath .OUTPUT_BASE .BUILD_MODE}}' + cmds: + - rm -rf '{{.TARGET_DIR}}' + - npx tsc --project '{{.TASKFILE_DIR}}' --outDir '{{.TARGET_DIR}}' + - cp '{{joinPath .TASKFILE_DIR "package.json"}}' '{{.TARGET_DIR}}' + - cp '{{joinPath .USER_WORKING_DIR "package-lock.json"}}' '{{.TARGET_DIR}}' + - cp '{{.TASKFILE_DIR}}/app_{{.BUILD_MODE}}.yaml' '{{.TARGET_DIR}}/app.yaml' + - cp '{{.TASKFILE_DIR}}/config_{{.BUILD_MODE}}.json' '{{.TARGET_DIR}}/config.json' + + deploy:dev: + desc: Deploy the development metrics server + vars: + BUILD_MODE: "dev" + TARGET_DIR: *default-target-dir + deps: [{task: build, vars: {BUILD_MODE: "{{.BUILD_MODE}}", TARGET_DIR: "{{.TARGET_DIR}}"}}] + cmds: + - gcloud app deploy '{{.TASKFILE_DIR}}/dispatch.yaml' '{{.TARGET_DIR}}' --project uproxysite --verbosity info --promote --stop-previous-version + + deploy:prod: + desc: Deploy the production metrics server + vars: + BUILD_MODE: "prod" + TARGET_DIR: *default-target-dir + deps: [{task: build, vars: {BUILD_MODE: "{{.BUILD_MODE}}", TARGET_DIR: "{{.TARGET_DIR}}"}}] + cmds: + - gcloud app deploy '{{.TASKFILE_DIR}}/dispatch.yaml' '{{joinPath .OUTPUT_BASE "prod"}}' --project uproxysite --verbosity info --no-promote --no-stop-previous-version + + start: + desc: Start the metrics server locally + vars: + BUILD_MODE: '{{.BUILD_MODE | default "dev"}}' + TARGET_DIR: *default-target-dir + deps: [{task: build, vars: {BUILD_MODE: "{{.BUILD_MODE}}", TARGET_DIR: "{{.TARGET_DIR}}"}}] + cmds: + - node '{{joinPath .TARGET_DIR "index.js"}}' + + integration_test: + desc: Test the deployed dev metrics server + cmds: + - '{{.TASKFILE_DIR}}/test_integration.sh' + + test: + desc: Run the unit tests for the metrics server + vars: + TEST_DIR: + sh: "mktemp -d" + cmds: + - defer: rm -rf "{{.TEST_DIR}}" + - npx tsc -p '{{.TASKFILE_DIR}}' --outDir '{{.TEST_DIR}}' + - npx jasmine '{{.TEST_DIR}}/**/*.spec.js' diff --git a/src/metrics_server/build.action.sh b/src/metrics_server/build.action.sh deleted file mode 100755 index 5ed513fc..00000000 --- a/src/metrics_server/build.action.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -tsc -p "$(dirname "$0")" diff --git a/src/metrics_server/deploy_dev.action.sh b/src/metrics_server/deploy_dev.action.sh deleted file mode 100755 index 1abc7243..00000000 --- a/src/metrics_server/deploy_dev.action.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly SRC_DIR="src/metrics_server" -readonly BUILD_DIR="build/metrics_server" - -rm -rf "${BUILD_DIR}" - -npm run action metrics_server/build - -cp "${SRC_DIR}/app_dev.yaml" "${BUILD_DIR}/app.yaml" -cp "${SRC_DIR}/config_dev.json" "${BUILD_DIR}/config.json" -cp "${SRC_DIR}/package.json" "${BUILD_DIR}/" -cp "./package-lock.json" "${BUILD_DIR}/" - -gcloud app deploy "${SRC_DIR}/dispatch.yaml" "${BUILD_DIR}" --project uproxysite --verbosity info --promote --stop-previous-version diff --git a/src/metrics_server/deploy_prod.action.sh b/src/metrics_server/deploy_prod.action.sh deleted file mode 100755 index 880cade0..00000000 --- a/src/metrics_server/deploy_prod.action.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly SRC_DIR="src/metrics_server" -readonly BUILD_DIR="build/metrics_server" - -rm -rf "${BUILD_DIR}" - -npm run action metrics_server/build - -cp "${SRC_DIR}/app_prod.yaml" "${BUILD_DIR}/app.yaml" -cp "${SRC_DIR}/config_prod.json" "${BUILD_DIR}/config.json" -cp "${SRC_DIR}/package.json" "${BUILD_DIR}/" -cp "./package-lock.json" "${BUILD_DIR}/" - -gcloud app deploy "${SRC_DIR}/dispatch.yaml" "${BUILD_DIR}" --project uproxysite --verbosity info --no-promote --no-stop-previous-version diff --git a/src/metrics_server/start.action.sh b/src/metrics_server/start.action.sh deleted file mode 100755 index 974b1d04..00000000 --- a/src/metrics_server/start.action.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2020 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly SRC_DIR="src/metrics_server" -readonly BUILD_DIR="build/metrics_server" - -npm run action metrics_server/build - -cp "${SRC_DIR}/config_dev.json" "${BUILD_DIR}/config.json" -cp "${SRC_DIR}/package.json" "${BUILD_DIR}/" - -npx node "${BUILD_DIR}/index.js" diff --git a/src/metrics_server/test.action.sh b/src/metrics_server/test.action.sh deleted file mode 100755 index 844aed2e..00000000 --- a/src/metrics_server/test.action.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly TEST_DIR="${BUILD_DIR}/js/metrics_server/" -rm -rf "${TEST_DIR}" - -tsc -p "${ROOT_DIR}/src/metrics_server" --outDir "${TEST_DIR}" -jasmine --config="${ROOT_DIR}/jasmine.json" - -rm -rf "${TEST_DIR}" diff --git a/src/metrics_server/test_integration.action.sh b/src/metrics_server/test_integration.sh similarity index 100% rename from src/metrics_server/test_integration.action.sh rename to src/metrics_server/test_integration.sh diff --git a/src/sentry_webhook/README.md b/src/sentry_webhook/README.md index 9a92f41e..4888005d 100644 --- a/src/sentry_webhook/README.md +++ b/src/sentry_webhook/README.md @@ -10,7 +10,7 @@ The Outline Sentry webhook is a [Google Cloud Function](https://cloud.google.com ## Build ```sh -npm run action sentry_webhook/build +task sentry_webhook:build ``` ## Deploy @@ -24,7 +24,7 @@ gcloud auth login To deploy: ```sh -npm run action sentry_webhook/deploy +task sentry_webhook:deploy ``` ## Configure Sentry Webhooks diff --git a/src/sentry_webhook/Taskfile.yml b/src/sentry_webhook/Taskfile.yml new file mode 100644 index 00000000..014b7a0d --- /dev/null +++ b/src/sentry_webhook/Taskfile.yml @@ -0,0 +1,39 @@ +version: '3' + +requires: + vars: [OUTPUT_BASE] + +tasks: + clean: + desc: Clean Sentry webhook output + cmds: + - rm -rf "{{.OUTPUT_BASE}}" + + build: + desc: Build the Sentry webhook + cmds: + - npx tsc --project '{{.TASKFILE_DIR}}/tsconfig.prod.json' --outDir '{{.OUTPUT_BASE}}' + - cp '{{.TASKFILE_DIR}}/package.json' '{{.OUTPUT_BASE}}' + + deploy: + desc: Deploy the Sentry webhook to GCP Cloud Functions + deps: [build] + cmds: + - gcloud functions deploy postSentryEventToSalesforce + --project=uproxysite + --runtime=nodejs18 + --trigger-http + --source='{{.OUTPUT_BASE}}' + --entry-point=postSentryEventToSalesforce + + test: + desc: Run the unit tests for the Sentry webhook + vars: + TEST_DIR: + sh: "mktemp -d" + cmds: + - defer: rm -rf "{{.TEST_DIR}}" + # Use commonjs modules, jasmine runs in node. + - npx tsc -p '{{.TASKFILE_DIR}}' --outDir '{{.TEST_DIR}}' --module commonjs + - npx jasmine '{{.TEST_DIR}}/**/*.spec.js' + - npx karma start '{{.TASKFILE_DIR}}/karma.conf.js' diff --git a/src/sentry_webhook/build.action.sh b/src/sentry_webhook/build.action.sh deleted file mode 100755 index c989235e..00000000 --- a/src/sentry_webhook/build.action.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -tsc --project "${ROOT_DIR}"src/sentry_webhook/tsconfig.prod.json diff --git a/src/sentry_webhook/deploy.action.sh b/src/sentry_webhook/deploy.action.sh deleted file mode 100755 index 6899f8d4..00000000 --- a/src/sentry_webhook/deploy.action.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -npm run action sentry_webhook/build - -cp src/sentry_webhook/package.json build/sentry_webhook/ -gcloud functions deploy postSentryEventToSalesforce \ - --project=uproxysite \ - --runtime=nodejs18 \ - --trigger-http \ - --source=build/sentry_webhook \ - --entry-point=postSentryEventToSalesforce diff --git a/src/sentry_webhook/test.action.sh b/src/sentry_webhook/test.action.sh deleted file mode 100755 index e151b7ab..00000000 --- a/src/sentry_webhook/test.action.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2023 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly TEST_DIR="${BUILD_DIR}/js/sentry_webhook/" -rm -rf "${TEST_DIR}" - -# Use commonjs modules, jasmine runs in node. -tsc -p "${ROOT_DIR}/src/sentry_webhook" --outDir "${TEST_DIR}" --module commonjs -jasmine --config="${ROOT_DIR}/jasmine.json" - -npx karma start "${ROOT_DIR}/src/sentry_webhook/karma.conf.js" - -rm -rf "${TEST_DIR}" diff --git a/src/sentry_webhook/tsconfig.json b/src/sentry_webhook/tsconfig.json index 75987142..80b92543 100644 --- a/src/sentry_webhook/tsconfig.json +++ b/src/sentry_webhook/tsconfig.json @@ -4,7 +4,6 @@ "removeComments": false, "strict": true, "module": "commonjs", - "outDir": "../../build/sentry_webhook", "skipLibCheck": true }, "include": ["**/*.ts"] diff --git a/src/shadowbox/README.md b/src/shadowbox/README.md index 74c831fb..6bcbf6eb 100644 --- a/src/shadowbox/README.md +++ b/src/shadowbox/README.md @@ -43,13 +43,13 @@ The Outline Server, internal name "Shadowbox," is designed to streamline the set - **Node.js App** ```sh - npm run action shadowbox/server/start + task shadowbox:start ``` - **Docker Container** ```sh - npm run action shadowbox/docker/start + task shadowbox:docker:start ``` > [!TIP] @@ -119,38 +119,25 @@ The Outline Server provides a REST API for access key management. If you know th ### Manual -1. Prerequisites +Build and run your image with: - - A locally built Docker image containing your modifications. - - Your Docker image uploaded to a registry (e.g., Docker Hub, Quay.io). +```sh +task shadowbox:docker:start +``` -1. Setup +### Integration Test - - **Environment Variable:** Set `SB_IMAGE` to the uploaded image location. Example: +The integration test will not only build and run your image, but also run a number of automated tests. - ```sh - export SB_IMAGE=yourdockerhubusername/shadowbox - ``` +```sh +task shadowbox:integration_test +``` - - **Start the Server:** +This does the following: - ```sh - npm run action shadowbox/docker/start - ``` - -### Automated - -1. **Build and Run:** - - ```sh - npm run action shadowbox/integration_test/run - ``` - - This does the following: - - - Sets up three containers (`client`, `shadowbox`, `target`) and two networks. - - Creates a user on `shadowbox`. - - Connects to `target` through `shadowbox` using a Shadowsocks `client`: `client <-> shadowbox <-> target` +- Sets up three containers (`client`, `shadowbox`, `target`) and two networks. +- Creates a user on `shadowbox`. +- Connects to `target` through `shadowbox` using a Shadowsocks `client`: `client <-> shadowbox <-> target` 1. **Testing Changes to the Server Config:** diff --git a/src/shadowbox/Taskfile.yml b/src/shadowbox/Taskfile.yml new file mode 100644 index 00000000..43a6e9f4 --- /dev/null +++ b/src/shadowbox/Taskfile.yml @@ -0,0 +1,198 @@ +version: '3' + +requires: + vars: [OUTPUT_BASE] + +tasks: + build: + desc: Build the Outline Server Node.js app + vars: + TARGET_OS: '{{.TARGET_OS | default "linux"}}' + TARGET_ARCH: '{{.TARGET_ARCH | default "x86_64"}}' + GOOS: '{{get (dict "macos" "darwin") .TARGET_OS | default .TARGET_OS}}' + GOARCH: '{{get (dict "x86_64" "amd64") .TARGET_ARCH | default .TARGET_ARCH}}' + TARGET_DIR: '{{.TARGET_DIR | default (joinPath .OUTPUT_BASE .TARGET_OS .TARGET_ARCH)}}' + NODE_DIR: '{{joinPath .TARGET_DIR "app"}}' + BIN_DIR: '{{joinPath .TARGET_DIR "bin"}}' + cmds: + - echo Target platform is {{.TARGET_OS}}/{{.TARGET_ARCH}} + - rm -rf '{{.TARGET_DIR}}' + - mkdir -p '{{.TARGET_DIR}}' + - cp '{{joinPath .TASKFILE_DIR "package.json"}}' '{{.TARGET_DIR}}' + # Build Node.js app + - npx webpack --config='{{joinPath .TASKFILE_DIR "webpack.config.js"}}' --output-path='{{.NODE_DIR}}' ${BUILD_ENV:+--mode="${BUILD_ENV}"} + # Copy third_party dependencies + - mkdir -p '{{.BIN_DIR}}' + - | + { + cd '{{joinPath .USER_WORKING_DIR "third_party" "prometheus"}}' + make 'bin/{{.TARGET_OS}}-{{.TARGET_ARCH}}/prometheus' + cp 'bin/{{.TARGET_OS}}-{{.TARGET_ARCH}}/prometheus' '{{.BIN_DIR}}/' + } + # Set CGO_ENABLED=0 to force static linkage. See https://mt165.co.uk/blog/static-link-go/. + - GOOS={{.GOOS}} GOARCH={{.GOARCH}} CGO_ENABLED=0 go build -ldflags='-s -w -X main.version=embedded' -o '{{.BIN_DIR}}/' github.com/Jigsaw-Code/outline-ss-server/cmd/outline-ss-server + + start: + desc: Run the Outline server locally + deps: [{task: build, vars: {TARGET_OS: '{{.TARGET_OS}}', TARGET_ARCH: '{{.TARGET_ARCH}}'}}] + vars: + UNAME_OS: {sh: 'uname -s'} + TARGET_OS: '{{get (dict "Linux" "linux" "Darwin" "macos") .UNAME_OS}}' + TARGET_ARCH: {sh: 'uname -m'} + RUN_ID: '{{.RUN_ID | default (now | date "2006-01-02-150405")}}' + RUN_DIR: '{{joinPath "/tmp/outline" .RUN_ID}}' + STATE_DIR: '{{joinPath .RUN_DIR "persisted-state"}}' + STATE_CONFIG: '{{joinPath .STATE_DIR "shadowbox_server_config.json"}}' + LOG_LEVEL: '{{.LOG_LEVEL | default "debug"}}' + env: + # WARNING: The SB_API_PREFIX should be kept secret! + SB_API_PREFIX: TestApiPrefix + SB_METRICS_URL: https://dev.metrics.getoutline.org + SB_STATE_DIR: '{{.STATE_DIR}}' + SB_PUBLIC_IP: localhost + SB_CERTIFICATE_FILE: '{{joinPath .RUN_DIR "/shadowbox-selfsigned-dev.crt"}}' + SB_PRIVATE_KEY_FILE: '{{joinPath .RUN_DIR "/shadowbox-selfsigned-dev.key"}}' + cmds: + - echo Target platform is {{.TARGET_OS}}/{{.TARGET_ARCH}} + - echo "Using directory {{.RUN_DIR}}" + - mkdir -p '{{.STATE_DIR}}' + - echo '{"hostname":"127.0.0.1"}' > "{{.STATE_CONFIG}}" + - task: make_test_certificate + vars: {OUTPUT_DIR: '{{.RUN_DIR}}'} + - node '{{joinPath .OUTPUT_BASE .TARGET_OS .TARGET_ARCH "app/main.js"}}' + + docker:build: + desc: Build the Outline Server Docker image + vars: + VERSION: '{{.IMAGE_VERSION | default "dev"}}' + IMAGE_NAME: '{{.IMAGE_NAME | default "localhost/outline/shadowbox"}}' + TARGET_ARCH: '{{.TARGET_ARCH | default "x86_64"}}' + IMAGE_ROOT: '{{joinPath .OUTPUT_BASE "image_root" .TARGET_ARCH}}' + # Newer node images have no valid content trust data. + # Pin the image node:16.18.0-alpine3.16 by hash. + # See image at https://hub.docker.com/_/node/tags?page=1&name=18.18.0-alpine3.18 + NODE_IMAGE: '{{get + (dict + "x86_64" "node@sha256:a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097" + "arm64" "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" + ) .TARGET_ARCH + }}' + env: + DOCKER_CONTENT_TRUST: '{{.DOCKER_CONTENT_TRUST | default "1"}}' + # Enable Docker BuildKit (https://docs.docker.com/develop/develop-images/build_enhancements) + DOCKER_BUILDKIT: 1 + cmds: + - rm -rf '{{.IMAGE_ROOT}}' + - mkdir -p '{{.IMAGE_ROOT}}' + - {task: build, vars: {TARGET_OS: linux, TARGET_ARCH: '{{.TARGET_ARCH}}', TARGET_DIR: '{{joinPath .IMAGE_ROOT "/opt/outline-server"}}'}} + - cp -R '{{joinPath .TASKFILE_DIR "scripts"}}' '{{.IMAGE_ROOT}}/scripts' + - mkdir -p '{{joinPath .IMAGE_ROOT "/etc/periodic/weekly"}}' + - cp '{{joinPath .TASKFILE_DIR "scripts" "update_mmdb.sh"}}' '{{joinPath .IMAGE_ROOT "/etc/periodic/weekly/"}}' + # Create default state directory + - mkdir -p '{{joinPath .IMAGE_ROOT "/root/shadowbox/persisted-state"}}' + # Copy entrypoint command + - cp '{{joinPath .TASKFILE_DIR "docker/cmd.sh"}}' '{{.IMAGE_ROOT}}/' + # Build image with given root + - | + "${DOCKER:-docker}" build --force-rm \ + --build-arg NODE_IMAGE='{{.NODE_IMAGE}}' \ + --build-arg VERSION='{{.VERSION}}' \ + -f '{{joinPath .TASKFILE_DIR "docker" "Dockerfile"}}' \ + -t '{{.IMAGE_NAME}}' \ + '{{.IMAGE_ROOT}}' + + docker:start: + desc: Build and run the Outline Server Docker image + interactive: true + requires: + vars: [DOCKER] + deps: [{task: docker:build, vars: {TARGET_ARCH: {sh: 'uname -m'}}}] + vars: + RUN_DIR: '{{joinPath .OUTPUT_BASE "docker_start"}}' + IMAGE_NAME: '{{.IMAGE_NAME | default "localhost/outline/shadowbox"}}' + API_PORT: '8081' + ACCESS_KEY_PORT: '9999' + CERTIFICATE_FILE: 'shadowbox-selfsigned-dev.crt' + PRIVATE_KEY_FILE: 'shadowbox-selfsigned-dev.key' + HOST_STATE_DIR: '{{joinPath .RUN_DIR "persisted-state"}}' + CONTAINER_STATE_DIR: '/opt/outline/pesisted-state' + STATE_CONFIG: '{{joinPath .HOST_STATE_DIR "shadowbox_server_config.json"}}' + cmds: + - rm -rf '{{.RUN_DIR}}' + - mkdir -p '{{.HOST_STATE_DIR}}' + - echo '{"hostname":"127.0.0.1"}' > "{{.STATE_CONFIG}}" + - task: make_test_certificate + vars: {OUTPUT_DIR: '{{.HOST_STATE_DIR}}'} + - | + docker_command=( + '{{.DOCKER}}' run -it --rm --name 'shadowbox' + {{if eq OS "linux" -}} + --net host + {{else}} + -p '{{.API_PORT}}:{{.API_PORT}}' + -p '{{.ACCESS_KEY_PORT}}:{{.ACCESS_KEY_PORT}}' + -p '{{.ACCESS_KEY_PORT}}:{{.ACCESS_KEY_PORT}}/udp' + -p '9090-9092:9090-9092' + {{- end}} + + # Where the container keeps its persistent state. + -v "{{.HOST_STATE_DIR}}:{{.CONTAINER_STATE_DIR}}" + -e "SB_STATE_DIR={{.CONTAINER_STATE_DIR}}" + + # Port number and path prefix used by the server manager API. + -e "SB_API_PORT={{.API_PORT}}" + -e "SB_API_PREFIX=TestApiPrefix" + + # Location of the API TLS certificate and key. + -e "SB_CERTIFICATE_FILE={{joinPath .CONTAINER_STATE_DIR .CERTIFICATE_FILE}}" + -e "SB_PRIVATE_KEY_FILE={{joinPath .CONTAINER_STATE_DIR .PRIVATE_KEY_FILE}}" + + # Where to report metrics to, if opted-in. + -e "SB_METRICS_URL={{.METRICS_URL | default "https://dev.metrics.getoutline.org"}}" + + # The Outline server image to run. + '{{.IMAGE_NAME}}' + ) + "${docker_command[@]}" + + integration_test: + desc: Run the integration test + cmds: + - task: docker:build + - task: test_image + vars: + IMAGE_NAME: localhost/outline/shadowbox:latest + OUTPUT_DIR: '{{joinPath .OUTPUT_BASE "integration_test"}}' + + test_image: + desc: Test a specific image by name + requires: + vars: [IMAGE_NAME] + vars: + OUTPUT_DIR: '{{joinPath .OUTPUT_BASE "image_test"}}' + cmds: + - rm -rf '{{.OUTPUT_DIR}}' + - OUTPUT_DIR='{{.OUTPUT_DIR}}' '{{joinPath .TASKFILE_DIR "integration_test/test.sh"}}' '{{.IMAGE_NAME}}' + + + test: + desc: Run the unit tests for the Outline Server + vars: + TEST_DIR: '{{joinPath .OUTPUT_BASE "test"}}' + cmds: + - defer: rm -rf "{{.TEST_DIR}}" + - npx tsc -p '{{.TASKFILE_DIR}}' --outDir '{{.TEST_DIR}}' + - npx jasmine '{{.TEST_DIR}}/**/*.spec.js' + + make_test_certificate: + internal: true + requires: {vars: [OUTPUT_DIR]} + vars: + CERTIFICATE_FILE: '{{joinPath .OUTPUT_DIR "shadowbox-selfsigned-dev.crt"}}' + PRIVATE_KEY_FILE: '{{joinPath .OUTPUT_DIR "shadowbox-selfsigned-dev.key"}}' + cmds: + - mkdir -p '{{.OUTPUT_DIR}}' + - > + openssl req -x509 -nodes -days 36500 -newkey rsa:4096 + -subj "/CN=localhost" + -keyout "{{.PRIVATE_KEY_FILE}}" -out "{{.CERTIFICATE_FILE}}" \ No newline at end of file diff --git a/src/shadowbox/docker/Dockerfile b/src/shadowbox/docker/Dockerfile index f6075ab7..b1aa160c 100644 --- a/src/shadowbox/docker/Dockerfile +++ b/src/shadowbox/docker/Dockerfile @@ -13,32 +13,8 @@ # limitations under the License. ARG NODE_IMAGE - -# Multi-stage build: use a build image to prevent bloating the shadowbox image with dependencies. -# Run `npm ci` and build inside the container to package the right dependencies for the image. -FROM ${NODE_IMAGE} AS build - -# make for building third_party/prometheus and perl-utils for shasum. -RUN apk add --no-cache --upgrade bash make perl-utils -WORKDIR / - -# Don't copy node_modules and other things not needed for install. -COPY package.json package-lock.json ./ -COPY src/shadowbox/package.json src/shadowbox/ -RUN --mount=type=cache,target=/root/.npm npm ci - -# We copy the source code only after npm ci, so that source code changes don't trigger re-installs. -COPY scripts scripts/ -COPY src src/ -COPY tsconfig.json ./ -COPY third_party third_party - -ARG ARCH ARG VERSION -RUN ARCH=${ARCH} ROOT_DIR=/ SB_VERSION=${VERSION} npm run action shadowbox/server/build - -# shadowbox image FROM ${NODE_IMAGE} # Save metadata on the software versions we are using. @@ -53,22 +29,11 @@ STOPSIGNAL SIGKILL # safely grab the ip-to-country database. RUN apk add --no-cache --upgrade coreutils curl -COPY src/shadowbox/scripts scripts/ -COPY src/shadowbox/scripts/update_mmdb.sh /etc/periodic/weekly/update_mmdb +COPY . / -RUN /etc/periodic/weekly/update_mmdb - -# Create default state directory. -RUN mkdir -p /root/shadowbox/persisted-state +RUN /etc/periodic/weekly/update_mmdb.sh # Install shadowbox. WORKDIR /opt/outline-server -# The shadowbox build directory has the following structure: -# - app/ (bundled node app) -# - bin/ (binary dependencies) -# - package.json (shadowbox package.json) -COPY --from=build /build/shadowbox/ . - -COPY src/shadowbox/docker/cmd.sh / CMD /cmd.sh diff --git a/src/shadowbox/docker/build.action.sh b/src/shadowbox/docker/build.action.sh deleted file mode 100755 index f24a31cf..00000000 --- a/src/shadowbox/docker/build.action.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Environment inputs: -# - SB_VERSION -# - SB_IMAGE -# - ARCH -# - NODE_IMAGE -# - ROOT_DIR - -export DOCKER_CONTENT_TRUST="${DOCKER_CONTENT_TRUST:-1}" -# Enable Docker BuildKit (https://docs.docker.com/develop/develop-images/build_enhancements) -export DOCKER_BUILDKIT=1 - -# Docker image build architecture. Supported architectures: x86_64, arm64 -export ARCH=${ARCH:-x86_64} - -# Newer node images have no valid content trust data. -# Pin the image node:16.18.0-alpine3.16 by hash. -# See image at https://hub.docker.com/_/node/tags?page=1&name=18.18.0-alpine3.18 -readonly NODE_IMAGE=$( - if [[ "${ARCH}" == "x86_64" ]]; then - echo "node@sha256:a0b787b0d53feacfa6d606fb555e0dbfebab30573277f1fe25148b05b66fa097" - elif [[ "${ARCH}" == "arm64" ]]; then - echo "node@sha256:b4b7a1dd149c65ee6025956ac065a843b4409a62068bd2b0cbafbb30ca2fab3b" - else - echo "Unsupported architecture" - exit 1 - fi -) - -docker build --force-rm \ - --build-arg ARCH="${ARCH}" \ - --build-arg NODE_IMAGE="${NODE_IMAGE}" \ - --build-arg VERSION="${SB_VERSION:-dev}" \ - -f src/shadowbox/docker/Dockerfile \ - -t "${SB_IMAGE:-localhost/outline/shadowbox}" \ - "${ROOT_DIR}" diff --git a/src/shadowbox/docker/start.action.sh b/src/shadowbox/docker/start.action.sh deleted file mode 100755 index 637ccaf1..00000000 --- a/src/shadowbox/docker/start.action.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -run_action shadowbox/docker/build - -RUN_ID="${RUN_ID:-$(date +%Y-%m-%d-%H%M%S)}" -readonly RUN_ID -readonly RUN_DIR="/tmp/outline/${RUN_ID}" -echo "Using directory ${RUN_DIR}" - -readonly HOST_STATE_DIR="${RUN_DIR}/persisted-state" -readonly CONTAINER_STATE_DIR='/root/shadowbox/persisted-state' -readonly STATE_CONFIG="${HOST_STATE_DIR}/shadowbox_server_config.json" - -declare -ir ACCESS_KEY_PORT=${ACCESS_KEY_PORT:-9999} -declare -ir SB_API_PORT=${SB_API_PORT:-8081} - -[[ -d "${HOST_STATE_DIR}" ]] || mkdir -p "${HOST_STATE_DIR}" -[[ -e "${STATE_CONFIG}" ]] || echo "{\"hostname\":\"127.0.0.1\", \"portForNewAccessKeys\": ${ACCESS_KEY_PORT}}" > "${STATE_CONFIG}" -# shellcheck source=../scripts/make_test_certificate.sh -source "${ROOT_DIR}/src/shadowbox/scripts/make_test_certificate.sh" "${RUN_DIR}" - -# TODO: mount a folder rather than individual files. -declare -ar docker_bindings=( - -v "${HOST_STATE_DIR}:${CONTAINER_STATE_DIR}" - -e "SB_STATE_DIR=${CONTAINER_STATE_DIR}" - -v "${SB_CERTIFICATE_FILE}:${SB_CERTIFICATE_FILE}" - -v "${SB_PRIVATE_KEY_FILE}:${SB_PRIVATE_KEY_FILE}" - -e "LOG_LEVEL=${LOG_LEVEL:-debug}" - -e "SB_API_PORT=${SB_API_PORT}" - -e "SB_API_PREFIX=TestApiPrefix" - -e "SB_CERTIFICATE_FILE=${SB_CERTIFICATE_FILE}" - -e "SB_PRIVATE_KEY_FILE=${SB_PRIVATE_KEY_FILE}" - -e "SB_METRICS_URL=${SB_METRICS_URL:-https://dev.metrics.getoutline.org}" -) - -readonly IMAGE="${SB_IMAGE:-localhost/outline/shadowbox}" -echo "Running image ${IMAGE}" - -declare -a NET_BINDINGS=("--network=host") -if [[ "$(uname)" == "Darwin" ]]; then - # Docker does not support the --network=host option on macOS. Instead, publish the management API - # and access key ports to the host. - NET_BINDINGS=(-p "${SB_API_PORT}:${SB_API_PORT}" -p "${ACCESS_KEY_PORT}:${ACCESS_KEY_PORT}" -p "${ACCESS_KEY_PORT}:${ACCESS_KEY_PORT}/udp") -fi; - -docker run --rm -it "${NET_BINDINGS[@]}" --name shadowbox "${docker_bindings[@]}" "${IMAGE}" diff --git a/src/shadowbox/integration_test/README.md b/src/shadowbox/integration_test/README.md index 27bdb9b3..17f9497a 100644 --- a/src/shadowbox/integration_test/README.md +++ b/src/shadowbox/integration_test/README.md @@ -5,11 +5,17 @@ This folder contains the integration test for the Outline Server image. To build and test the image: ```sh -npm run action shadowbox/integration_test/run +task shadowbox:integration_test ``` For development of the test, or to test a specific image, you may prefer calling the test directly, without the build step: ```sh -./src/shadowbox/integration_test/test.sh localhost/outline/shadowbox:latest +./task shadowbox:test_image IMAGE_NAME=quay.io/outline/shadowbox:stable +``` + +If you prefer to use Podman instead of Docker, set the `DOCKER=podman` environment variable: + +```sh +DOCKER=podman task shadowbox:integration_test ``` diff --git a/src/shadowbox/integration_test/run.action.sh b/src/shadowbox/integration_test/run.action.sh deleted file mode 100755 index 5d094712..00000000 --- a/src/shadowbox/integration_test/run.action.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -run_action shadowbox/docker/build - -LOGFILE="$(mktemp)" -readonly LOGFILE -echo "Running Shadowbox integration test. Logs at ${LOGFILE}" - -cd src/shadowbox/integration_test - -declare -i result=0 - -if ./test.sh "${SB_IMAGE:-localhost/outline/shadowbox:latest}" > "${LOGFILE}" 2>&1 ; then - echo "Test Passed!" - # Removing the log file sometimes fails on Travis. There's no point in us cleaning it up - # on a CI build anyways. - rm -f "${LOGFILE}" -else - result=$? - echo "Test Failed! Logs:" - cat "${LOGFILE}" -fi - -exit "${result}" diff --git a/src/shadowbox/integration_test/test.sh b/src/shadowbox/integration_test/test.sh index 313dc5a3..4e7c40a0 100755 --- a/src/shadowbox/integration_test/test.sh +++ b/src/shadowbox/integration_test/test.sh @@ -32,8 +32,12 @@ set -x -OUTPUT_DIR="$(mktemp -d)" +OUTPUT_DIR="${OUTPUT_DIR:-$(mktemp -d)}" readonly OUTPUT_DIR + +# Set DOCKER=podman to use Podman instead of Docker. +readonly DOCKER="${DOCKER:-docker}" + # TODO(fortuna): Make it possible to run multiple tests in parallel by adding a # run id to the container names. readonly NAMESPACE='integrationtest' @@ -62,7 +66,7 @@ function wait_for_resource() { } function util_jq() { - docker run --rm -i --entrypoint jq "${UTIL_IMAGE}" "$@" + "${DOCKER}" run --rm -i --entrypoint jq "${UTIL_IMAGE}" "$@" } # Takes the JSON from a /access-keys POST request and returns the appropriate @@ -78,7 +82,7 @@ function ss_arguments_for_user() { # Runs curl on the client container. function client_curl() { - docker exec "${CLIENT_CONTAINER}" curl --silent --show-error --connect-timeout 5 --retry 5 "$@" + "${DOCKER}" exec "${CLIENT_CONTAINER}" curl --silent --show-error --connect-timeout 5 --retry 5 "$@" } function fail() { @@ -89,12 +93,12 @@ function fail() { function setup() { remove_containers - docker network create -d bridge "${NET_OPEN}" - docker network create -d bridge --internal "${NET_BLOCKED}" + "${DOCKER}" network create -d bridge "${NET_OPEN}" + "${DOCKER}" network create -d bridge --internal "${NET_BLOCKED}" # Target service. - docker build --force-rm -t "${TARGET_IMAGE}" "$(dirname "$0")/target" - docker run -d --rm -p "10080:80" --network="${NET_OPEN}" --network-alias="target" --name="${TARGET_CONTAINER}" "${TARGET_IMAGE}" + "${DOCKER}" build --force-rm -t "${TARGET_IMAGE}" "$(dirname "$0")/target" + "${DOCKER}" run -d --rm -p "10080:80" --network="${NET_OPEN}" --network-alias="target" --name="${TARGET_CONTAINER}" "${TARGET_IMAGE}" # Shadowsocks service. declare -ar shadowbox_flags=( @@ -110,38 +114,38 @@ function setup() { -e "SB_PRIVATE_KEY_FILE=/root/shadowbox/test.key" -v "${SB_CERTIFICATE_FILE}:/root/shadowbox/test.crt" -v "${SB_PRIVATE_KEY_FILE}:/root/shadowbox/test.key" - -v "${TMP_STATE_DIR}:/root/shadowbox/persisted-state" + -v "${STATE_DIR}:/root/shadowbox/persisted-state" --name "${SHADOWBOX_CONTAINER}" "${SHADOWBOX_IMAGE}" ) - docker run "${shadowbox_flags[@]}" - # docker network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" - docker network connect "${NET_OPEN}" "${SHADOWBOX_CONTAINER}" + "${DOCKER}" run "${shadowbox_flags[@]}" + # "${DOCKER}" network connect --alias shadowbox "${NET_BLOCKED}" "${SHADOWBOX_CONTAINER}" + "${DOCKER}" network connect "${NET_OPEN}" "${SHADOWBOX_CONTAINER}" # Client service. - docker build --force-rm -t "${CLIENT_IMAGE}" "$(dirname "$0")/client" + "${DOCKER}" build --force-rm -t "${CLIENT_IMAGE}" "$(dirname "$0")/client" # Use -i to keep the container running. - docker run -d --rm -it -p "30555:555" --network "${NET_BLOCKED}" --name "${CLIENT_CONTAINER}" "${CLIENT_IMAGE}" + "${DOCKER}" run -d --rm -it --network "${NET_BLOCKED}" --name "${CLIENT_CONTAINER}" "${CLIENT_IMAGE}" # Utilities - docker build --force-rm -t "${UTIL_IMAGE}" "$(dirname "$0")/util" + "${DOCKER}" build --force-rm -t "${UTIL_IMAGE}" "$(dirname "$0")/util" } function remove_containers() { # Force remove (-f) running containers and `|| true` to not trigger a shell error # in case the container or network doesn't exist. - docker rm -f -v "${TARGET_CONTAINER}" || true - docker rm -f -v "${SHADOWBOX_CONTAINER}" || true - docker rm -f -v "${CLIENT_CONTAINER}" || true - docker network rm "${NET_OPEN}" || true - docker network rm "${NET_BLOCKED}" || true + "${DOCKER}" rm -f -v "${TARGET_CONTAINER}" || true + "${DOCKER}" rm -f -v "${SHADOWBOX_CONTAINER}" || true + "${DOCKER}" rm -f -v "${CLIENT_CONTAINER}" || true + "${DOCKER}" network rm "${NET_OPEN}" || true + "${DOCKER}" network rm "${NET_BLOCKED}" || true } function cleanup() { local -i status=$? if ((DEBUG != 1)); then remove_containers - rm -rf "${TMP_STATE_DIR}" || echo "Failed to cleanup files at ${TMP_STATE_DIR}" + rm -rf "${STATE_DIR}" || echo "Failed to cleanup files at ${STATE_DIR}" fi return "${status}" } @@ -157,33 +161,33 @@ function cleanup() { # Sets everything up export SB_API_PREFIX='TestApiPrefix' readonly SB_API_URL="https://shadowbox/${SB_API_PREFIX}" - TMP_STATE_DIR="$(mktemp -d)" - export TMP_STATE_DIR - echo '{"hostname": "shadowbox"}' > "${TMP_STATE_DIR}/shadowbox_server_config.json" + export STATE_DIR="${OUTPUT_DIR}/container_state" + mkdir -p "${STATE_DIR}" + echo '{"hostname": "shadowbox"}' > "${STATE_DIR}/shadowbox_server_config.json" # Make the certificates. This exports SB_CERTIFICATE_FILE and SB_PRIVATE_KEY_FILE. # shellcheck source=../scripts/make_test_certificate.sh - source "$(dirname "$0")/../scripts/make_test_certificate.sh" "${TMP_STATE_DIR}" + source "$(dirname "$0")/../scripts/make_test_certificate.sh" "${STATE_DIR}" setup # Wait for target to come up. - wait_for_resource localhost:10080 - TARGET_IP="$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${TARGET_CONTAINER}")" + wait_for_resource 127.0.0.1:10080 + TARGET_IP="$("${DOCKER}" inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${TARGET_CONTAINER}")" readonly TARGET_IP # Verify that the client cannot access or even resolve the target # Exit code 7 is "Failed to connect to host" and 28 is "Connection timed out". - (docker exec "${CLIENT_CONTAINER}" curl --silent --connect-timeout 5 "http://${TARGET_IP}" > /dev/null && \ + ("${DOCKER}" exec "${CLIENT_CONTAINER}" curl --silent --connect-timeout 5 "http://${TARGET_IP}" > /dev/null && \ fail "Client should not have access to target IP") || (($? == 7 || $? == 28)) # Exit code 6 for "Could not resolve host". In some environments, curl reports a timeout # error (28) instead, which is surprising. TODO: Investigate and fix. - (docker exec "${CLIENT_CONTAINER}" curl --silent --connect-timeout 5 http://target > /dev/null && \ + ("${DOCKER}" exec "${CLIENT_CONTAINER}" curl --silent --connect-timeout 5 http://target > /dev/null && \ fail "Client should not have access to target host") || (($? == 6 || $? == 28)) # Wait for shadowbox to come up. - wait_for_resource https://localhost:20443/access-keys + wait_for_resource https://127.0.0.1:20443/access-keys # Verify that the shadowbox can access the target - docker exec "${SHADOWBOX_CONTAINER}" wget --spider http://target + "${DOCKER}" exec "${SHADOWBOX_CONTAINER}" wget --spider http://target # Create new shadowbox user. # TODO(bemasc): Verify that the server is using the right certificate @@ -199,27 +203,27 @@ function cleanup() { # Start Shadowsocks client and wait for it to be ready declare -ir LOCAL_SOCKS_PORT=5555 - docker exec -d "${CLIENT_CONTAINER}" \ - /go/bin/go-shadowsocks2 "${SS_USER_ARGUMENTS[@]}" -socks "localhost:${LOCAL_SOCKS_PORT}" -verbose \ + "${DOCKER}" exec -d "${CLIENT_CONTAINER}" \ + /go/bin/go-shadowsocks2 "${SS_USER_ARGUMENTS[@]}" -socks "127.0.0.1:${LOCAL_SOCKS_PORT}" -verbose \ || fail "Could not start shadowsocks client" - while ! docker exec "${CLIENT_CONTAINER}" nc -z localhost "${LOCAL_SOCKS_PORT}"; do + while ! "${DOCKER}" exec "${CLIENT_CONTAINER}" nc -z 127.0.0.1 "${LOCAL_SOCKS_PORT}"; do sleep 0.1 done function test_networking() { # Verify the server blocks requests to hosts on private addresses. # Exit code 52 is "Empty server response". - (client_curl -x "socks5h://localhost:${LOCAL_SOCKS_PORT}" "${TARGET_IP}" &> /dev/null \ + (client_curl -x "socks5h://127.0.0.1:${LOCAL_SOCKS_PORT}" "${TARGET_IP}" \ && fail "Target host in a private network accessible through shadowbox") || (($? == 52)) # Verify we can retrieve the internet target URL. - client_curl -x "socks5h://localhost:${LOCAL_SOCKS_PORT}" "${INTERNET_TARGET_URL}" \ + client_curl -x "socks5h://127.0.0.1:${LOCAL_SOCKS_PORT}" "${INTERNET_TARGET_URL}" \ || fail "Could not fetch ${INTERNET_TARGET_URL} through shadowbox." # Verify we can't access the URL anymore after the key is deleted client_curl --insecure -X DELETE "${SB_API_URL}/access-keys/0" > /dev/null # Exit code 56 is "Connection reset by peer". - (client_curl -x "socks5h://localhost:${LOCAL_SOCKS_PORT}" "${INTERNET_TARGET_URL}" &> /dev/null \ + (client_curl -x "socks5h://127.0.0.1:${LOCAL_SOCKS_PORT}" "${INTERNET_TARGET_URL}" &> /dev/null \ && fail "Deleted access key is still active") || (($? == 56)) } @@ -319,7 +323,7 @@ function cleanup() { # Verify no errors occurred. readonly SHADOWBOX_LOG="${OUTPUT_DIR}/shadowbox-log.txt" - if docker logs "${SHADOWBOX_CONTAINER}" 2>&1 | tee "${SHADOWBOX_LOG}" | grep -Eq "^E|level=error|ERROR:"; then + if "${DOCKER}" logs "${SHADOWBOX_CONTAINER}" 2>&1 | tee "${SHADOWBOX_LOG}" | grep -Eq "^E|level=error|ERROR:"; then cat "${SHADOWBOX_LOG}" fail "Found errors in Shadowbox logs (see above, also saved to ${SHADOWBOX_LOG})" fi diff --git a/src/shadowbox/integration_test/util/Dockerfile b/src/shadowbox/integration_test/util/Dockerfile index 29ca1758..e5098dbf 100644 --- a/src/shadowbox/integration_test/util/Dockerfile +++ b/src/shadowbox/integration_test/util/Dockerfile @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.5 +FROM alpine:3.19.1 RUN apk add --no-cache jq ENTRYPOINT [ "sh" ] diff --git a/src/shadowbox/server/build.action.sh b/src/shadowbox/server/build.action.sh deleted file mode 100755 index bcc05f60..00000000 --- a/src/shadowbox/server/build.action.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly OUT_DIR="${BUILD_DIR}/shadowbox" -rm -rf "${OUT_DIR}" -mkdir -p "${OUT_DIR}" - -webpack --config=src/shadowbox/webpack.config.js ${BUILD_ENV:+--mode="${BUILD_ENV}"} - -# Install third_party dependencies -readonly OS="$([[ "$(uname)" == "Darwin" ]] && echo "macos" || echo "linux")" -export ARCH=${ARCH:-x86_64} -readonly BIN_DIR="${OUT_DIR}/bin" -mkdir -p "${BIN_DIR}" -{ - cd "${ROOT_DIR}/third_party/prometheus" - make "bin/${OS}-${ARCH}/prometheus" - cp "bin/${OS}-${ARCH}/prometheus" "${BIN_DIR}/" -} -{ - cd "${ROOT_DIR}/third_party/outline-ss-server" - make "bin/${OS}-${ARCH}/outline-ss-server" - cp "bin/${OS}-${ARCH}/outline-ss-server" "${BIN_DIR}/" -} - -# Copy shadowbox package.json -cp "${ROOT_DIR}/src/shadowbox/package.json" "${OUT_DIR}/" diff --git a/src/shadowbox/server/start.action.sh b/src/shadowbox/server/start.action.sh deleted file mode 100755 index b36e2b0e..00000000 --- a/src/shadowbox/server/start.action.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -run_action shadowbox/server/build - -RUN_ID="${RUN_ID:-$(date +%Y-%m-%d-%H%M%S)}" -readonly RUN_DIR="/tmp/outline/${RUN_ID}" -echo "Using directory ${RUN_DIR}" - -export LOG_LEVEL="${LOG_LEVEL:-debug}" -SB_PUBLIC_IP="${SB_PUBLIC_IP:-$(curl https://ipinfo.io/ip)}" -export SB_PUBLIC_IP -# WARNING: The SB_API_PREFIX should be kept secret! -export SB_API_PREFIX='TestApiPrefix' -export SB_METRICS_URL='https://dev.metrics.getoutline.org' -export SB_STATE_DIR="${RUN_DIR}/persisted-state" -readonly STATE_CONFIG="${SB_STATE_DIR}/shadowbox_server_config.json" - -[[ -d "${SB_STATE_DIR}" ]] || mkdir -p "${SB_STATE_DIR}" -[[ -e "${STATE_CONFIG}" ]] || echo '{"hostname":"127.0.0.1"}' > "${STATE_CONFIG}" - -# shellcheck source=../scripts/make_test_certificate.sh -source "${ROOT_DIR}/src/shadowbox/scripts/make_test_certificate.sh" "${RUN_DIR}" - -node "${BUILD_DIR}/shadowbox/app/main.js" diff --git a/src/shadowbox/test.action.sh b/src/shadowbox/test.action.sh deleted file mode 100755 index 73b8421d..00000000 --- a/src/shadowbox/test.action.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -eu -# -# Copyright 2018 The Outline Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -readonly TEST_DIR="${BUILD_DIR}/js/shadowbox/" -rm -rf "${TEST_DIR}" - -tsc -p "${ROOT_DIR}/src/shadowbox" --outDir "${TEST_DIR}" -jasmine --config="${ROOT_DIR}/jasmine.json" - -rm -rf "${TEST_DIR}" diff --git a/third_party/outline-ss-server/.gitignore b/third_party/outline-ss-server/.gitignore deleted file mode 100644 index ae3c1726..00000000 --- a/third_party/outline-ss-server/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bin/ diff --git a/third_party/outline-ss-server/LICENSE b/third_party/outline-ss-server/LICENSE deleted file mode 100644 index f49a4e16..00000000 --- a/third_party/outline-ss-server/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/third_party/outline-ss-server/METADATA b/third_party/outline-ss-server/METADATA deleted file mode 100644 index babb4cac..00000000 --- a/third_party/outline-ss-server/METADATA +++ /dev/null @@ -1,15 +0,0 @@ -name: "outline-ss-server" -description: "outline-ss-server is an open-source Outline Shadowsocks server" - -third_party { - url { - type: HOMEPAGE - value: "https://getoutline.org/" - } - url { - type: ARCHIVE - value: "https://github.com/Jigsaw-Code/outline-ss-server/releases/tag/v1.4.0" - } - version: "1.4.0" - last_upgrade_date { year: 2022 month: 10 day: 24 } -} diff --git a/third_party/outline-ss-server/Makefile b/third_party/outline-ss-server/Makefile deleted file mode 100644 index 3bc26c30..00000000 --- a/third_party/outline-ss-server/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -VERSION=1.5.0 - -.PHONY: all -all: bin/linux-x86_64/outline-ss-server bin/linux-arm64/outline-ss-server bin/macos-x86_64/outline-ss-server bin/macos-arm64/outline-ss-server - -bin/linux-x86_64/outline-ss-server: OS=linux -bin/linux-x86_64/outline-ss-server: SHA256=0c6439242afbea191281404f08ef33490b01d6d0413ccca00004c8a1927de49a - -bin/linux-arm64/outline-ss-server: OS=linux -bin/linux-arm64/outline-ss-server: SHA256=a643b28c2a894af6ceb1d309bf742092719877ede85ead6e8cbbc7b64b35a7ab - -bin/macos-x86_64/outline-ss-server: OS=macos -bin/macos-x86_64/outline-ss-server: SHA256=f4b034f74701e9dae52bc7c8660e875f81473ef6d535a1470967e887f5beb9c6 - -bin/macos-arm64/outline-ss-server: OS=macos -bin/macos-arm64/outline-ss-server: SHA256=1f1d1833935ba363a8c468cd61e90d42de7f16e7332346b3c80f389c914192d3 - -TEMPFILE := $(shell mktemp) -bin/%/outline-ss-server: - node ../../src/build/download_file.mjs --url="https://github.com/Jigsaw-Code/outline-ss-server/releases/download/v$(VERSION)/outline-ss-server_$(VERSION)_$(OS)_$(ARCH).tar.gz" --out="$(TEMPFILE)" --sha256=$(SHA256) - mkdir -p "$(dir $@)" - tar -zx -f "$(TEMPFILE)" -C "$(dir $@)" "$(notdir $@)" - chmod +x "$@" - rm -f $(TEMPFILE) - -.PHONY: clean -clean: - rm -rf bin diff --git a/third_party/prometheus/Makefile b/third_party/prometheus/Makefile index d00624ef..89cf4a4a 100644 --- a/third_party/prometheus/Makefile +++ b/third_party/prometheus/Makefile @@ -1,31 +1,29 @@ VERSION=2.37.1 -ifeq ($(ARCH),x86_64) - APP_ARCH=amd64 -else - APP_ARCH=arm64 -endif - .PHONY: all all: bin/linux-x86_64/prometheus bin/linux-arm64/prometheus bin/macos-x86_64/prometheus bin/macos-arm64/prometheus bin/linux-x86_64/prometheus: OS=linux +bin/linux-x86_64/prometheus: GOARCH=amd64 bin/linux-x86_64/prometheus: SHA256=753f66437597cf52ada98c2f459aa8c03745475c249c9f2b40ac7b3919131ba6 bin/linux-arm64/prometheus: OS=linux +bin/linux-arm64/prometheus: GOARCH=arm64 bin/linux-arm64/prometheus: SHA256=b59a66fb5c7ec5acf6bf426793528a5789a1478a0dad8c64edc2843caf31b1b8 bin/macos-x86_64/prometheus: OS=darwin +bin/macos-x86_64/prometheus: GOARCH=amd64 bin/macos-x86_64/prometheus: SHA256=e03a43d98955ac3500f57353ea74b5df829074205f195ea6b3b88f55c4575c79 bin/macos-arm64/prometheus: OS=darwin +bin/macos-arm64/prometheus: GOARCH=arm64 bin/macos-arm64/prometheus: SHA256=eb8a174c82a0fb6c84e81d9a73214318fb4a605115ad61505d7883d02e5a6f52 bin/%/prometheus: TEMPFILE := $(shell mktemp) bin/%/prometheus: - node ../../src/build/download_file.mjs --url="https://github.com/prometheus/prometheus/releases/download/v$(VERSION)/prometheus-$(VERSION).$(OS)-$(APP_ARCH).tar.gz" --out="$(TEMPFILE)" --sha256=$(SHA256) + node ../../src/build/download_file.mjs --url="https://github.com/prometheus/prometheus/releases/download/v$(VERSION)/prometheus-$(VERSION).$(OS)-$(GOARCH).tar.gz" --out="$(TEMPFILE)" --sha256=$(SHA256) mkdir -p "$(dir $@)" - tar -zx -f "$(TEMPFILE)" --strip-components=1 -C "$(dir $@)" prometheus-$(VERSION).$(OS)-$(APP_ARCH)/prometheus + tar -zx -f "$(TEMPFILE)" --strip-components=1 -C "$(dir $@)" prometheus-$(VERSION).$(OS)-$(GOARCH)/prometheus chmod +x "$@" rm -f $(TEMPFILE) diff --git a/tools.go b/tools.go new file mode 100644 index 00000000..4e6a2ae0 --- /dev/null +++ b/tools.go @@ -0,0 +1,26 @@ +// Copyright 2024 The Outline Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build tools +// +build tools + +// See https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module +// and https://github.com/go-modules-by-example/index/blob/master/010_tools/README.md + +package tools + +import ( + _ "github.com/Jigsaw-Code/outline-ss-server/cmd/outline-ss-server" + _ "github.com/go-task/task/v3/cmd/task" +)