diff --git a/.gitea/workflows/rssapp.yaml b/.gitea/workflows/rssapp.yaml new file mode 100644 index 0000000..30d01cc --- /dev/null +++ b/.gitea/workflows/rssapp.yaml @@ -0,0 +1,67 @@ +name: rssapp CI/CD + +on: + push: + branches: + - "main" + paths: + - "services/rssapp/**" + pull_request: + paths: + - "services/rssapp/**" + +jobs: + build: + runs-on: ubuntu-latest + environment: docker + + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Login to Gitea Docker Registry + uses: docker/login-action@v3 + with: + registry: gitea.futureporn.net + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and Push futureporn/rssapp + uses: docker/build-push-action@v6 + with: + context: ./services/rssapp + push: true + tags: gitea.futureporn.net/futureporn/rssapp:latest + build-args: | + NODE_ENV=production + labels: | + org.opencontainers.image.description=X.com RSS service for Futureporn internal tools + org.opencontainers.image.title=rssapp + org.opencontainers.image.licenses=unlicense + org.opencontainers.image.source=https://gitea.futureporn.net/futureporn/fp + org.opencontainers.image.url=https://gitea.futureporn.net/futureporn/-/packages/container/rssapp + + - name: Clean up unused docker networks + run: docker network prune --force + + # Optional: Trigger Dokploy Deployment + - name: Trigger Dokploy Deployment + if: github.ref == 'refs/heads/main' + run: | + curl -X POST \ + -H "Content-Type: application/json" \ + -H "x-gitea-event: Push Hook" \ + -d "{ + \"ref\": \"refs/heads/main\", + \"after\": \"${GITHUB_SHA}\", + \"commits\": [ + { + \"id\": \"${GITHUB_SHA}\", + \"message\": \"Deployment from Gitea Actions\", + \"author\": { \"name\": \"${GITHUB_ACTOR}\" } + } + ] + }" \ + "${{ secrets.WEBHOOK_URL }}" diff --git a/services/actor/.dockerignore b/services/actor/.dockerignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/services/actor/.dockerignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/services/actor/.gitignore b/services/actor/.gitignore new file mode 100644 index 0000000..3502ef7 --- /dev/null +++ b/services/actor/.gitignore @@ -0,0 +1,144 @@ +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/node diff --git a/services/actor/README.md b/services/actor/README.md new file mode 100644 index 0000000..4e84560 --- /dev/null +++ b/services/actor/README.md @@ -0,0 +1,10 @@ +# actor + +Spin up a powerful VPS to run act_runner workflows on demand + + +## vultr config + +vhp-8c-16gb +Ubuntu 24.04 LTS x64 +Chicago \ No newline at end of file diff --git a/services/actor/package-lock.json b/services/actor/package-lock.json new file mode 100644 index 0000000..2ca8f96 --- /dev/null +++ b/services/actor/package-lock.json @@ -0,0 +1,1010 @@ +{ + "name": "actor", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "actor", + "version": "0.0.1", + "license": "Unlicense", + "dependencies": { + "@dotenvx/dotenvx": "^1.48.4", + "fastify": "^5.5.0", + "nunjucks": "^3.2.4", + "zod": "^4.0.17" + } + }, + "node_modules/@dotenvx/dotenvx": { + "version": "1.48.4", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.48.4.tgz", + "integrity": "sha512-GpJWpGVI5JGhNzFlWOjCD3KMiN3xU1US4oLKQ7SiiGru4LvR7sUf3pDMpfjtlgzHStL5ydq4ekfZcRxWpHaJkA==", + "license": "BSD-3-Clause", + "dependencies": { + "commander": "^11.1.0", + "dotenv": "^17.2.1", + "eciesjs": "^0.4.10", + "execa": "^5.1.1", + "fdir": "^6.2.0", + "ignore": "^5.3.0", + "object-treeify": "1.1.33", + "picomatch": "^4.0.2", + "which": "^4.0.0" + }, + "bin": { + "dotenvx": "src/cli/dotenvx.js" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/@ecies/ciphers": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.4.tgz", + "integrity": "sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==", + "license": "MIT", + "engines": { + "bun": ">=1", + "deno": ">=2", + "node": ">=16" + }, + "peerDependencies": { + "@noble/ciphers": "^1.0.0" + } + }, + "node_modules/@fastify/ajv-compiler": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-4.0.2.tgz", + "integrity": "sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0" + } + }, + "node_modules/@fastify/error": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-4.2.0.tgz", + "integrity": "sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-5.0.3.tgz", + "integrity": "sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fast-json-stringify": "^6.0.0" + } + }, + "node_modules/@fastify/forwarded": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.0.0.tgz", + "integrity": "sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==", + "license": "MIT" + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz", + "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@fastify/proxy-addr": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.0.0.tgz", + "integrity": "sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==", + "license": "MIT", + "dependencies": { + "@fastify/forwarded": "^3.0.0", + "ipaddr.js": "^2.1.0" + } + }, + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "license": "MIT" + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/avvio": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-9.1.0.tgz", + "integrity": "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==", + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.0.0", + "fastq": "^1.17.1" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/dotenv": { + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", + "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/eciesjs": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.15.tgz", + "integrity": "sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==", + "license": "MIT", + "dependencies": { + "@ecies/ciphers": "^0.2.3", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "^1.9.1", + "@noble/hashes": "^1.8.0" + }, + "engines": { + "bun": ">=1", + "deno": ">=2", + "node": ">=16" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stringify": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.0.1.tgz", + "integrity": "sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/merge-json-schemas": "^0.2.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0", + "json-schema-ref-resolver": "^2.0.0", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "license": "MIT", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastify": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.5.0.tgz", + "integrity": "sha512-ZWSWlzj3K/DcULCnCjEiC2zn2FBPdlZsSA/pnPa/dbUfLvxkD/Nqmb0XXMXLrWkeM4uQPUvjdJpwtXmTfriXqw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/ajv-compiler": "^4.0.0", + "@fastify/error": "^4.0.0", + "@fastify/fast-json-stringify-compiler": "^5.0.0", + "@fastify/proxy-addr": "^5.0.0", + "abstract-logging": "^2.0.1", + "avvio": "^9.0.0", + "fast-json-stringify": "^6.0.0", + "find-my-way": "^9.0.0", + "light-my-request": "^6.0.0", + "pino": "^9.0.0", + "process-warning": "^5.0.0", + "rfdc": "^1.3.1", + "secure-json-parse": "^4.0.0", + "semver": "^7.6.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/find-my-way": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.3.0.tgz", + "integrity": "sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^5.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/json-schema-ref-resolver": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-2.0.1.tgz", + "integrity": "sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/light-my-request": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.6.0.tgz", + "integrity": "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "cookie": "^1.0.1", + "process-warning": "^4.0.0", + "set-cookie-parser": "^2.6.0" + } + }, + "node_modules/light-my-request/node_modules/process-warning": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz", + "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.9.0.tgz", + "integrity": "sha512-zxsRIQG9HzG+jEljmvmZupOMDUQ0Jpj0yAgE28jQvvrdYTlEaiGwelJpdndMl/MBuRr70heIj83QyqJUWaU8mQ==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "license": "MIT" + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ret": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", + "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/safe-regex2": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz", + "integrity": "sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/secure-json-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz", + "integrity": "sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sonic-boom": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", + "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/toad-cache": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/zod": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.0.17.tgz", + "integrity": "sha512-1PHjlYRevNxxdy2JZ8JcNAw7rX8V9P1AKkP+x/xZfxB0K5FYfuV+Ug6P/6NVSR2jHQ+FzDDoDHS04nYUsOIyLQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/services/actor/package.json b/services/actor/package.json new file mode 100644 index 0000000..7a4aba7 --- /dev/null +++ b/services/actor/package.json @@ -0,0 +1,19 @@ +{ + "name": "actor", + "version": "0.0.1", + "description": "Spin up a powerful VPS to run act_runner workflows on demand", + "license": "Unlicense", + "author": "", + "type": "module", + "main": "src/server.ts", + "scripts": { + "start": "tsx src/server.ts", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "@dotenvx/dotenvx": "^1.48.4", + "fastify": "^5.5.0", + "nunjucks": "^3.2.4", + "zod": "^4.0.17" + } +} \ No newline at end of file diff --git a/services/actor/src/env.ts b/services/actor/src/env.ts new file mode 100644 index 0000000..fc27c6d --- /dev/null +++ b/services/actor/src/env.ts @@ -0,0 +1,11 @@ +import '@dotenvx/dotenvx/config'; +import { z } from 'zod'; + +export const EnvSchema = z.object({ + VULTR_API_KEY: z.string(), + GITEA_RUNNER_REGISTRATION_TOKEN: z.string(), + VPS_SPEC: z.string().default('vhp-8c-16gb'), + WEBHOOK_PORT: z.coerce.number().default(3000), +}); + +export const env = EnvSchema.parse(process.env); diff --git a/services/actor/src/server.ts b/services/actor/src/server.ts new file mode 100644 index 0000000..cb97061 --- /dev/null +++ b/services/actor/src/server.ts @@ -0,0 +1,21 @@ +import Fastify from 'fastify'; +import { env } from './env.js'; +import { createVultrInstance } from './vultr.js'; + +const fastify = Fastify(); + +fastify.post('/webhook', async (request, reply) => { + try { + const instance = await createVultrInstance(); + console.log('Created instance:', instance); + return { status: 'ok', instance }; + } catch (err: any) { + console.error(err); + reply.status(500).send({ status: 'error', message: err.message }); + } +}); + +fastify.listen({ port: env.WEBHOOK_PORT }, (err, addr) => { + if (err) throw err; + console.log(`Server listening at ${addr}`); +}); diff --git a/services/actor/src/vultr.ts b/services/actor/src/vultr.ts new file mode 100644 index 0000000..e393d9a --- /dev/null +++ b/services/actor/src/vultr.ts @@ -0,0 +1,46 @@ +import { readFile } from 'fs/promises'; +import nunjucks from 'nunjucks'; +import { env } from './env.js'; + +nunjucks.configure({ autoescape: true }); + +export async function createVultrInstance(): Promise { + // Load cloud-init template + const template = await readFile('./user-data.j2', 'utf-8'); + + const hostname = `gitea-runner-${Date.now()}` + + // Render template with the runner token + const userData = nunjucks.renderString(template, { + GITEA_RUNNER_REGISTRATION_TOKEN: env.GITEA_RUNNER_REGISTRATION_TOKEN, + hostname, + }); + + const body = { + region: 'ord', + plan: env.VPS_SPEC, + os_id: 2284, // Ubuntu 22.04 x64 + user_data: Buffer.from(userData).toString('base64'), + label: hostname, + hostname, + sshkey_id: null, + enable_ipv6: true, + enable_private_network: true, + }; + + const res = await fetch('https://api.vultr.com/v2/instances', { + method: 'POST', + headers: { + 'Authorization': `Bearer ${env.VULTR_API_KEY}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + const text = await res.text(); + throw new Error(`Failed to create VPS: ${res.status} ${text}`); + } + + return res.json(); +} diff --git a/services/actor/user-data.j2 b/services/actor/user-data.j2 new file mode 100644 index 0000000..e1cbaa8 --- /dev/null +++ b/services/actor/user-data.j2 @@ -0,0 +1,51 @@ +#cloud-config +package_update: true +packages: + - docker.io + - curl + - jq + +write_files: + + + - path: /etc/act_runner/config.yaml + permissions: '0644' + owner: root:root + content: | + runner: + labels: + - "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest" + - "ubuntu-24.04:docker://gitea/runner-images:ubuntu-24.04" + - "ubuntu-22.04:docker://gitea/runner-images:ubuntu-22.04" + workdir: /var/lib/act_runner + max_parallel: 1 + + - path: /etc/systemd/system/act_runner.service + permissions: '0644' + owner: root:root + content: | + [Unit] + Description=Gitea Actions act_runner service + After=docker.service + Wants=docker.service + + [Service] + Type=simple + ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml + WorkingDirectory=/var/lib/act_runner + User=root + Restart=always + RestartSec=10 + + [Install] + WantedBy=multi-user.target + +runcmd: + + - mkdir -p /var/lib/act_runner + - curl -L https://gitea.com/gitea/act_runner/releases/download/v0.2.12/act_runner-0.2.12-linux-amd64 -o /usr/local/bin/act_runner + - chmod +x /usr/local/bin/act_runner + - cd /var/lib/act_runner && /usr/local/bin/act_runner register --no-interactive --instance "https://gitea.futureporn.net" --token "{{ GITEA_RUNNER_REGISTRATION_TOKEN }}" --name "{{ hostname }}" --labels "ubuntu-22.04:docker" + - systemctl daemon-reload + - systemctl enable act_runner + - systemctl start act_runner diff --git a/services/our/.dockerignore b/services/our/.dockerignore index eef653a..27a5b55 100644 --- a/services/our/.dockerignore +++ b/services/our/.dockerignore @@ -1,3 +1,5 @@ +experiments + vibeui venv src/test diff --git a/services/our/Dockerfile.old b/services/our/Dockerfile.old new file mode 100644 index 0000000..d22d106 --- /dev/null +++ b/services/our/Dockerfile.old @@ -0,0 +1,67 @@ +FROM node:22 + +# Set working directory +WORKDIR /app + +# Install system-level dependencies +RUN apt-get update -y && \ + apt-get install -y --no-install-recommends \ + build-essential \ + git \ + inotify-tools \ + ffmpeg \ + mktorrent \ + python3 \ + python3-pip \ + python3-venv \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Install Shaka Packager +RUN wget -q https://github.com/shaka-project/shaka-packager/releases/download/v3.4.2/packager-linux-x64 \ + -O /usr/local/bin/packager \ + && chmod +x /usr/local/bin/packager \ + && packager --version + +# Install IPFS Kubo +COPY --from=ipfs/kubo:v0.36.0 /usr/local/bin/ipfs /usr/local/bin/ipfs +RUN ipfs init + +# Bundle the vibeui pytorch model +RUN mkdir -p /app/vibeui \ + && wget -q https://gitea.futureporn.net/futureporn/fp/raw/branch/main/apps/vibeui/public/vibeui.pt -O /app/vibeui/vibeui.pt \ + && wget -q https://gitea.futureporn.net/futureporn/fp/raw/branch/main/apps/vibeui/public/data.yaml -O /app/vibeui/data.yaml + +# Install openwhisper +COPY --from=ghcr.io/ggml-org/whisper.cpp:main-e7bf0294ec9099b5fc21f5ba969805dfb2108cea /app /app/whisper.cpp +ENV PATH="$PATH:/app/whisper.cpp/build/bin" +ENV LD_LIBRARY_PATH="/app/whisper.cpp/build/src:/app/whisper.cpp/build/ggml/src:/usr/local/lib:/usr/lib" + +# Install b2-cli +RUN wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/download/v4.4.1/b2-linux -O /usr/local/bin/b2 && chmod +x /usr/local/bin/b2 + +# Copy and install dependencies +COPY package.json package-lock.json ./ +RUN --mount=type=cache,target=/root/.npm npm install --ignore-scripts=false --foreground-scripts --verbose + +# Copy Prisma schema and generate client +COPY prisma ./prisma +RUN npx prisma generate + +# Copy the rest of the code +COPY . . + +# Build the app +RUN npm run build + +# Setup Python virtualenv +RUN python3 -m venv /app/venv +ENV PATH="/app/venv/bin:$PATH" + +# Install python deps +RUN ./venv/bin/pip install --no-cache-dir -r requirements.txt + +# Expose the port +EXPOSE 5000 + +# Start the app +CMD ["npm", "run", "start:server"] diff --git a/services/our/scripts/analyze.ts b/services/our/experiments/analyze.ts similarity index 96% rename from services/our/scripts/analyze.ts rename to services/our/experiments/analyze.ts index 16724b9..8541f25 100644 --- a/services/our/scripts/analyze.ts +++ b/services/our/experiments/analyze.ts @@ -1,3 +1,8 @@ +/** + * This is an experiment to see if we can analyze the audio of a video + */ + + import { spawn } from "child_process"; export interface AudioStats { diff --git a/services/our/graphile.config.ts b/services/our/graphile.config.ts index 4d7fa3a..5a4dcd9 100644 --- a/services/our/graphile.config.ts +++ b/services/our/graphile.config.ts @@ -1,10 +1,12 @@ -import { WorkerPreset } from "graphile-worker" +import { LoadTaskFromJsPlugin } from "graphile-worker/dist/plugins/LoadTaskFromJsPlugin.js"; import { env } from "./src/config/env" + import path from 'node:path' const __dirname = import.meta.dirname; + const preset: GraphileConfig.Preset = { - extends: [WorkerPreset], + plugins: [LoadTaskFromJsPlugin], // here we override the WorkerPreset plugins which included the undesirable LoadTaskFromExecutableFilePlugin worker: { connectionString: env.DATABASE_URL, maxPoolSize: 10, @@ -17,7 +19,6 @@ const preset: GraphileConfig.Preset = { taskDirectory: path.join(__dirname, 'dist', 'tasks'), // to log debug messages, set GRAPHILE_LOGGER_DEBUG=1 in env @see https://worker.graphile.org/docs/library/logger }, - }; diff --git a/services/our/scripts/2025-08-12-migrate-from-v1.ts b/services/our/scripts/2025-08-12-migrate-from-v1.ts index 1d83c46..bbf2980 100644 --- a/services/our/scripts/2025-08-12-migrate-from-v1.ts +++ b/services/our/scripts/2025-08-12-migrate-from-v1.ts @@ -1,3 +1,49 @@ +/** + * Migration Script: V1 → V2 Database + * ----------------------------------- + * This script migrates VTuber and VOD data from an old Postgres database (V1) into the new Prisma-backed database (V2). + * + * Usage: + * - Ensure environment variables are configured for both databases: + * V1_DB_HOST Hostname of the V1 database (default: "localhost") + * V1_DB_PORT Port of the V1 database (default: "5444") + * V1_DB_USER Username for the V1 database (default: "postgres") + * V1_DB_PASS Password for the V1 database (default: "password") + * V1_DB_NAME Database name for V1 (default: "restoredb") + * DEFAULT_UPLOADER_ID + * An existing user ID in the V2 database that will be set as the uploader for all migrated records. + * + * What it does: + * 1. Migrates VTubers: + * - Reads all rows from `vtubers` in V1. + * - Inserts each into V2’s `vtuber` table using Prisma. + * - Maps all known fields (social links, images, themeColor, etc.). + * - Combines `description_1` and `description_2` into a single `description` field. + * - Assigns the `DEFAULT_UPLOADER_ID` to each migrated VTuber. + * + * 2. Migrates VODs: + * - Reads all rows from `vods` in V1. + * - Resolves associated VTubers via `vods_vtuber_links` → `vtubers.slug`. + * - Finds related thumbnails and source video links via `vods_thumbnail_links` and `vods_video_src_b_2_links`. + * - Inserts each VOD into V2’s `vod` table, connecting it to the corresponding VTubers by slug. + * - Assigns the `DEFAULT_UPLOADER_ID` to each migrated VOD. + * + * Notes: + * - This script assumes schema compatibility between V1 and V2 (field names may differ slightly). + * - Thumbnails and video source links fall back to `cdn_url` or `url` if available. + * - Any V1 records with missing or null values are gracefully handled with `null` fallbacks. + * - Run this script once; re-running may cause duplicate records unless unique constraints prevent it. + * + * Execution: + * Run with Node.js: + * $ npx @dotenvx/dotenvx run -f ./.env -- tsx ./migrate.ts + * + * Cleanup: + * - Connections to both the V1 database (pg.Pool) and Prisma client are properly closed at the end of execution. + */ + + + import { PrismaClient } from '../generated/prisma'; import pg from 'pg'; diff --git a/services/our/src/client/vod.js b/services/our/src/client/vod.js index af445da..df802a4 100644 --- a/services/our/src/client/vod.js +++ b/services/our/src/client/vod.js @@ -12,24 +12,26 @@ window.HELP_IMPROVE_VIDEOJS = false; // disable videojs tracking const container = document.querySelector('.video-container') -const isSupporter = container.dataset.supporter === 'true' -const player = videojs('player'); +if (container) { + const isSupporter = container.dataset.supporter === 'true' + const player = videojs('player'); -player.ready(() => { - if (isSupporter) { - // set up plugins - const funscripts = collectFunscripts() - const funscriptsOptions = { - buttplugClientName: "future.porn", - debug: false, - funscripts, + player.ready(() => { + if (isSupporter) { + // set up plugins + const funscripts = collectFunscripts() + const funscriptsOptions = { + buttplugClientName: "future.porn", + debug: false, + funscripts, + } + + player.funscriptPlayer(funscriptsOptions); } - player.funscriptPlayer(funscriptsOptions); - } - - player.hlsQualitySelector({ - displayCurrentQuality: true, - }); -}) \ No newline at end of file + player.hlsQualitySelector({ + displayCurrentQuality: true, + }); + }) +} \ No newline at end of file diff --git a/services/our/src/config/env.ts b/services/our/src/config/env.ts index e27487d..b6f6449 100644 --- a/services/our/src/config/env.ts +++ b/services/our/src/config/env.ts @@ -36,7 +36,8 @@ const EnvSchema = z.object({ B2_APPLICATION_KEY: z.string(), SEEDBOX_SFTP_URL: z.string(), SEEDBOX_SFTP_USERNAME: z.string(), - SEEDBOX_SFTP_PASSWORD: z.string() + SEEDBOX_SFTP_PASSWORD: z.string(), + QBT_HOST: z.string().default('localhost'), }); const parsed = EnvSchema.safeParse(process.env); diff --git a/services/our/src/utils/qbittorrent/qbittorrent.ts b/services/our/src/utils/qbittorrent/qbittorrent.ts index bce8924..82126ce 100644 --- a/services/our/src/utils/qbittorrent/qbittorrent.ts +++ b/services/our/src/utils/qbittorrent/qbittorrent.ts @@ -379,5 +379,4 @@ export class QBittorrentClient { } } -const opts = env.NODE_ENV === 'production' ? { host: 'qbittorrent' } : { host: 'localhost' } -export const qbtClient = new QBittorrentClient(opts); +export const qbtClient = new QBittorrentClient({ host: env.QBT_HOST }); diff --git a/services/our/test.Dockerfile b/services/our/test.Dockerfile new file mode 100644 index 0000000..e2cbe41 --- /dev/null +++ b/services/our/test.Dockerfile @@ -0,0 +1,7 @@ + +FROM ultralytics/ultralytics:8.3.203-cpu AS base + + +COPY --from=google/shaka-packager:v3.4.2 /usr/bin /usr/local/bin + +ENTRYPOINT /bin/sh \ No newline at end of file diff --git a/terraform/main.tf b/terraform/main.tf index 96cf1c9..ebfa1c6 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -31,7 +31,7 @@ variable "site_url" { } variable "aws_bucket" { - default = "futureporn" + default = "fp-usc" } variable "aws_region" { @@ -90,11 +90,11 @@ resource "vultr_reserved_ip" "futureporn_v2_ip" { ip_type = "v4" } -resource "vultr_reserved_ip" "futureporn_tracker_ip" { - label = "futureporn-tracker" - region = "ord" - ip_type = "v4" -} +# resource "vultr_reserved_ip" "futureporn_tracker_ip" { +# label = "futureporn-tracker" +# region = "ord" +# ip_type = "v4" +# } # Virtual Private Cloud for connecting many VPS together on a private network @@ -124,31 +124,31 @@ resource "bunnynet_dns_zone" "future_porn" { # load balancing instance -# resource "vultr_instance" "load_balancer" { -# count = 1 -# hostname = "fp-lb-${count.index}" -# plan = "vc2-1c-2gb" -# region = "ord" -# backups = "disabled" -# ddos_protection = "false" -# os_id = 1743 -# enable_ipv6 = true -# label = "fp lb ${count.index}" -# tags = ["futureporn", "load_balancer", "our"] -# ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] -# user_data = base64encode(var.vps_user_data) -# vpc_ids = [ -# vultr_vpc.futureporn_vpc.id -# ] -# reserved_ip_id = vultr_reserved_ip.futureporn_v2_ip.id -# } +resource "vultr_instance" "load_balancer" { + count = 1 + hostname = "fp-lb-${count.index}" + plan = "vc2-1c-2gb" + region = "ord" + backups = "disabled" + ddos_protection = "false" + os_id = 1743 + enable_ipv6 = true + label = "fp lb ${count.index}" + tags = ["futureporn", "load_balancer", "our"] + ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] + user_data = base64encode(var.vps_user_data) + vpc_ids = [ + vultr_vpc.futureporn_vpc.id + ] + reserved_ip_id = vultr_reserved_ip.futureporn_v2_ip.id +} resource "bunnynet_dns_record" "future_porn_apex" { zone = bunnynet_dns_zone.future_porn.id name = "" type = "A" - value = vultr_instance.our_vps[0].main_ip + value = vultr_instance.our_loadbalancer[0].main_ip ttl = 3600 } @@ -166,78 +166,62 @@ resource "bunnynet_dns_record" "www_future_porn" { # vultr instance for running our app -# resource "vultr_instance" "our_server" { -# count = 1 -# hostname = "fp-our-server-${count.index}" -# plan = "vc2-2c-4gb" -# region = "ord" -# backups = "disabled" -# ddos_protection = "false" -# os_id = 1743 -# enable_ipv6 = true -# label = "fp our server ${count.index}" -# tags = ["futureporn", "our", "server"] -# ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] -# vpc_ids = [ -# vultr_vpc.futureporn_vpc.id -# ] -# user_data = base64encode(var.vps_user_data) -# } +resource "vultr_instance" "our_server" { + count = 1 + hostname = "fp-our-server-${count.index}" + plan = "vc2-2c-4gb" + region = "ord" + backups = "disabled" + ddos_protection = "false" + os_id = 1743 + enable_ipv6 = true + label = "fp our server ${count.index}" + tags = ["futureporn", "our", "server"] + ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] + vpc_ids = [ + vultr_vpc.futureporn_vpc.id + ] + user_data = base64encode(var.vps_user_data) +} # vultr instance for running our app's background task runners -# resource "vultr_instance" "our_worker" { -# count = 1 -# hostname = "fp-our-worker-${count.index}" -# plan = "vc2-2c-4gb" +resource "vultr_instance" "our_worker" { + count = 2 + hostname = "fp-our-worker-${count.index}" + plan = "vc2-2c-4gb" + region = "ord" + backups = "disabled" + ddos_protection = "false" + os_id = 1743 + enable_ipv6 = true + label = "fp our worker ${count.index}" + tags = ["futureporn", "our", "worker"] + ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] + vpc_ids = [ + vultr_vpc.futureporn_vpc.id + ] + user_data = base64encode(var.vps_user_data) +} + + +# # vultr instance meant for capturing VODs +# resource "vultr_instance" "capture_vps" { +# count = 0 +# hostname = "fp-cap-${count.index}" +# plan = "vc2-2c-2gb" # region = "ord" # backups = "disabled" # ddos_protection = "false" # os_id = 1743 # enable_ipv6 = true -# label = "fp our worker ${count.index}" -# tags = ["futureporn", "our", "worker"] +# vpc_ids = [vultr_vpc.futureporn_vpc.id] +# label = "fp capture ${count.index}" +# tags = ["futureporn", "capture"] # ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] -# vpc_ids = [ -# vultr_vpc.futureporn_vpc.id -# ] -# user_data = base64encode(var.vps_user_data) +# user_data = base64encode(var.vps_user_data) # } -# vultr instance meant for capturing VODs -resource "vultr_instance" "capture_vps" { - count = 1 - hostname = "fp-cap-${count.index}" - plan = "vc2-2c-2gb" - region = "ord" - backups = "disabled" - ddos_protection = "false" - os_id = 1743 - enable_ipv6 = true - vpc_ids = [vultr_vpc.futureporn_vpc.id] - label = "fp capture ${count.index}" - tags = ["futureporn", "capture"] - ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] - user_data = base64encode(var.vps_user_data) -} - -# vultr instance meant for running our future.porn app -resource "vultr_instance" "our_vps" { - count = 1 - hostname = "fp-our-${count.index}" - plan = "vc2-2c-2gb" - region = "ord" - backups = "disabled" - ddos_protection = "false" - os_id = 1743 - enable_ipv6 = true - vpc_ids = [vultr_vpc.futureporn_vpc.id] - label = "fp our ${count.index}" - tags = ["futureporn", "capture"] - ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] - user_data = base64encode(var.vps_user_data) -} - # vultr instance with a GPU. experimental. # resource "vultr_instance" "capture_vps" { @@ -261,54 +245,61 @@ resource "vultr_instance" "our_vps" { # } -# resource "vultr_instance" "database" { -# count = 1 -# hostname = "fp-db-${count.index}" -# plan = "vc2-1c-2gb" -# region = "ord" -# backups = "enabled" -# backups_schedule { -# hour = "2" -# type = "daily" -# } -# ddos_protection = "false" -# os_id = 1743 -# enable_ipv6 = true -# vpc_ids = [vultr_vpc.futureporn_vpc.id] -# label = "fp database ${count.index}" -# tags = ["futureporn", "database"] -# ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] -# user_data = base64encode(var.vps_user_data) -# } - -resource "vultr_instance" "tracker" { - count = 0 - hostname = "fp-tracker-${count.index}" - plan = "vc2-1c-2gb" - region = "ord" - backups = "disabled" +resource "vultr_instance" "database" { + count = 1 + hostname = "fp-db-${count.index}" + plan = "vc2-1c-2gb" + region = "ord" + backups = "enabled" + backups_schedule { + hour = "2" + type = "daily" + } ddos_protection = "false" os_id = 1743 enable_ipv6 = true vpc_ids = [vultr_vpc.futureporn_vpc.id] - label = "fp tracker ${count.index}" - tags = ["futureporn", "tracker"] + label = "fp database ${count.index}" + tags = ["futureporn", "database"] ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] user_data = base64encode(var.vps_user_data) - reserved_ip_id = vultr_reserved_ip.futureporn_tracker_ip.id } -# resource "ansible_host" "ipfs_vps" { -# for_each = { for idx, host in var.ipfs_hosts : idx => host } -# name = each.value -# groups = ["ipfs"] -# variables = { -# ansible_user = "root" -# ansible_host = each.value -# } + # backups = "enabled" + # backups_schedule { + # hour = "2" + # type = "daily" + # } + +# resource "vultr_instance" "tracker" { +# count = 0 +# hostname = "fp-tracker-${count.index}" +# plan = "vc2-1c-2gb" +# region = "ord" +# backups = "disabled" +# ddos_protection = "false" +# os_id = 1743 +# enable_ipv6 = true +# vpc_ids = [vultr_vpc.futureporn_vpc.id] +# label = "fp tracker ${count.index}" +# tags = ["futureporn", "tracker"] +# ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID] +# user_data = base64encode(var.vps_user_data) +# reserved_ip_id = vultr_reserved_ip.futureporn_tracker_ip.id # } +resource "ansible_host" "ipfs_vps" { + for_each = { for idx, host in var.ipfs_hosts : idx => host } + name = each.value + groups = ["ipfs"] + + variables = { + ansible_user = "root" + ansible_host = each.value + } +} + # resource "ansible_host" "capture_vps" { # for_each = { for idx, host in vultr_instance.capture_vps : idx => host } @@ -326,48 +317,48 @@ resource "vultr_instance" "tracker" { # } # } -# resource "ansible_host" "load_balancer" { -# for_each = { for idx, host in vultr_instance.load_balancer : idx => host } -# name = each.value.hostname -# groups = ["load_balancer"] -# variables = { -# ansible_host = each.value.main_ip -# internal_ip = each.value.internal_ip -# } -# } +resource "ansible_host" "load_balancer" { + for_each = { for idx, host in vultr_instance.load_balancer : idx => host } + name = each.value.hostname + groups = ["load_balancer"] + variables = { + ansible_host = each.value.main_ip + internal_ip = each.value.internal_ip + } +} -# resource "ansible_host" "database" { -# for_each = { for idx, host in vultr_instance.database : idx => host } -# name = each.value.hostname -# groups = ["database"] -# variables = { -# ansible_host = each.value.main_ip -# internal_ip = each.value.internal_ip -# } -# } +resource "ansible_host" "database" { + for_each = { for idx, host in vultr_instance.database : idx => host } + name = each.value.hostname + groups = ["database"] + variables = { + ansible_host = each.value.main_ip + internal_ip = each.value.internal_ip + } +} -# resource "ansible_host" "our_server" { -# for_each = { for idx, host in vultr_instance.our_server : idx => host } -# name = each.value.hostname -# groups = ["our-server"] -# variables = { -# ansible_host = each.value.main_ip -# internal_ip = each.value.internal_ip -# vultr_instance_id = each.value.id -# } -# } +resource "ansible_host" "our_server" { + for_each = { for idx, host in vultr_instance.our_server : idx => host } + name = each.value.hostname + groups = ["our-server"] + variables = { + ansible_host = each.value.main_ip + internal_ip = each.value.internal_ip + vultr_instance_id = each.value.id + } +} -# resource "ansible_host" "our_worker" { -# for_each = { for idx, host in vultr_instance.our_worker : idx => host } -# name = each.value.hostname -# groups = ["our-worker"] -# variables = { -# ansible_host = each.value.main_ip -# internal_ip = each.value.internal_ip -# vultr_instance_id = each.value.id -# } -# } +resource "ansible_host" "our_worker" { + for_each = { for idx, host in vultr_instance.our_worker : idx => host } + name = each.value.hostname + groups = ["our-worker"] + variables = { + ansible_host = each.value.main_ip + internal_ip = each.value.internal_ip + vultr_instance_id = each.value.id + } +} # resource "ansible_host" "tracker" { @@ -402,61 +393,42 @@ resource "vultr_virtual_file_system_storage" "vfs" { } -# resource "ansible_host" "periphery" { -# for_each = { for idx, host in vultr_instance.our_vps : idx => host } -# name = each.value.hostname -# groups = ["periphery"] - -# variables = { -# ansible_host = each.value.main_ip -# internal_ip = each.value.internal_ip -# vultr_instance_id = each.value.id -# } -# } # resource "ansible_group" "capture" { # name = "capture" # } -# resource "ansible_group" "our-server" { -# name = "our-server" -# } +resource "ansible_group" "our-server" { + name = "our-server" +} -# resource "ansible_group" "our-worker" { -# name = "our-worker" -# } +resource "ansible_group" "our-worker" { + name = "our-worker" +} -# resource "ansible_group" "tracker" { -# name = "tracker" -# } resource "ansible_group" "our" { name = "our" } -# resource "ansible_group" "periphery" { -# name = "periphery" -# } -# resource "ansible_group" "load_balancer" { -# name = "load_balancer" -# } +resource "ansible_group" "load_balancer" { + name = "load_balancer" +} -# resource "ansible_group" "database" { -# name = "database" -# } +resource "ansible_group" "database" { + name = "database" +} resource "ansible_group" "futureporn" { name = "futureporn" children = [ - # "load_balancer", - # "database", - # "capture", - # "our-server", - # "our-worker", - # "periphery", - # "tracker", + "load_balancer", + "database", + "capture", + "our-server", + "our-worker", "our" ] }