From 4946ca2d918d959cbabd88462d7e6b3229a60b45 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 1 Apr 2022 00:08:29 +0200 Subject: [PATCH 01/46] Dockerfile for multiarch builds --- Dockerfile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5d0a8912b..90409e5be 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:16.14.0-alpine +FROM node:17-alpine RUN apk add --no-cache g++ cmake make python3 WORKDIR /app COPY package*.json . @@ -6,20 +6,18 @@ RUN yarn install COPY . . RUN yarn build -FROM node:16.14.0-alpine +FROM node:17-alpine WORKDIR /app - +ARG TARGETPLATFORM LABEL coolify.managed true - RUN apk add --no-cache git openssh-client curl jq cmake sqlite - RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@6 RUN pnpm add -g pnpm -RUN curl -fsSL "https://download.docker.com/linux/static/stable/x86_64/docker-20.10.9.tgz" | tar -xzvf - docker/docker -C . --strip-components 1 && mv docker /usr/bin/docker RUN mkdir -p ~/.docker/cli-plugins/ -RUN curl -SL https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose -RUN chmod +x ~/.docker/cli-plugins/docker-compose +RUN curl -SL https://cdn.coollabs.io/bin/docker-20.10.9-$TARGETPLATFORM -o /usr/bin/docker +RUN curl -SL https://cdn.coollabs.io/bin/docker-compose-linux-2.3.4-$TARGETPLATFORM -o ~/.docker/cli-plugins/docker-compose +RUN chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker COPY --from=0 /app/docker-compose.yaml . COPY --from=0 /app/build . From f56361c0ca4db1e8055a60ab8a5a8555b7125714 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 1 Apr 2022 14:25:55 +0200 Subject: [PATCH 02/46] updates for ARM --- Dockerfile | 44 ++++-- package.json | 3 +- pnpm-lock.yaml | 302 ++------------------------------------ src/lib/database/users.ts | 2 +- 4 files changed, 44 insertions(+), 307 deletions(-) diff --git a/Dockerfile b/Dockerfile index 90409e5be..28e7e820b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,41 @@ -FROM node:17-alpine -RUN apk add --no-cache g++ cmake make python3 +FROM node:16.14.2-alpine as install WORKDIR /app COPY package*.json . RUN yarn install -COPY . . -RUN yarn build -FROM node:17-alpine -WORKDIR /app + +FROM rust:1.58.1-alpine3.14 as prisma +WORKDIR /prisma +ENV RUSTFLAGS="-C target-feature=-crt-static" +RUN apk --no-cache add openssl direnv git musl-dev openssl-dev build-base perl protoc +RUN git clone --depth=1 --branch=3.11.x https://github.com/prisma/prisma-engines.git /prisma +RUN cargo build --release + +FROM node:16.14.2-alpine ARG TARGETPLATFORM -LABEL coolify.managed true -RUN apk add --no-cache git openssh-client curl jq cmake sqlite + +WORKDIR /app + +ENV PRISMA_QUERY_ENGINE_BINARY=/app/prisma-engines/query-engine \ + PRISMA_MIGRATION_ENGINE_BINARY=/app/prisma-engines/migration-engine \ + PRISMA_INTROSPECTION_ENGINE_BINARY=/app/prisma-engines/introspection-engine \ + PRISMA_FMT_BINARY=/app/prisma-engines/prisma-fmt \ + PRISMA_CLI_QUERY_ENGINE_TYPE=binary \ + PRISMA_CLIENT_ENGINE_TYPE=binary +COPY --from=prisma /prisma/target/release/query-engine /prisma/target/release/migration-engine /prisma/target/release/introspection-engine /prisma/target/release/prisma-fmt /app/prisma-engines/ + +COPY --from=install /app/node_modules ./node_modules +COPY . . + +RUN apk add --no-cache git openssh-client curl jq sqlite RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@6 RUN pnpm add -g pnpm RUN mkdir -p ~/.docker/cli-plugins/ -RUN curl -SL https://cdn.coollabs.io/bin/docker-20.10.9-$TARGETPLATFORM -o /usr/bin/docker -RUN curl -SL https://cdn.coollabs.io/bin/docker-compose-linux-2.3.4-$TARGETPLATFORM -o ~/.docker/cli-plugins/docker-compose +RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/docker-20.10.9 -o /usr/bin/docker +RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/docker-compose-linux-2.3.4 -o ~/.docker/cli-plugins/docker-compose RUN chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker -COPY --from=0 /app/docker-compose.yaml . -COPY --from=0 /app/build . -COPY --from=0 /app/package.json . -COPY --from=0 /app/node_modules ./node_modules -COPY --from=0 /app/prisma ./prisma - +RUN pnpm build EXPOSE 3000 CMD ["pnpm", "start"] \ No newline at end of file diff --git a/package.json b/package.json index 6c7237198..7dfd0f6e8 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "devDependencies": { "@sveltejs/adapter-node": "1.0.0-next.73", "@sveltejs/kit": "1.0.0-next.303", - "@types/bcrypt": "5.0.0", "@types/js-cookie": "3.0.1", "@types/js-yaml": "^4.0.5", "@types/node": "17.0.23", @@ -62,7 +61,7 @@ "@iarna/toml": "2.2.5", "@prisma/client": "3.11.1", "@sentry/node": "6.19.2", - "bcrypt": "5.0.1", + "bcryptjs": "^2.4.3", "bullmq": "1.78.1", "compare-versions": "4.1.3", "cookie": "0.4.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a89edbf25..29d97a688 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,7 +6,6 @@ specifiers: '@sentry/node': 6.19.2 '@sveltejs/adapter-node': 1.0.0-next.73 '@sveltejs/kit': 1.0.0-next.303 - '@types/bcrypt': 5.0.0 '@types/js-cookie': 3.0.1 '@types/js-yaml': ^4.0.5 '@types/node': 17.0.23 @@ -15,7 +14,7 @@ specifiers: '@typescript-eslint/parser': 4.31.1 '@zerodevx/svelte-toast': 0.7.1 autoprefixer: 10.4.4 - bcrypt: 5.0.1 + bcryptjs: ^2.4.3 bullmq: 1.78.1 compare-versions: 4.1.3 cookie: 0.4.2 @@ -59,7 +58,7 @@ dependencies: '@iarna/toml': 2.2.5 '@prisma/client': 3.11.1_prisma@3.11.1 '@sentry/node': 6.19.2 - bcrypt: 5.0.1 + bcryptjs: 2.4.3 bullmq: 1.78.1 compare-versions: 4.1.3 cookie: 0.4.2 @@ -83,7 +82,6 @@ dependencies: devDependencies: '@sveltejs/adapter-node': 1.0.0-next.73 '@sveltejs/kit': 1.0.0-next.303_svelte@3.46.4 - '@types/bcrypt': 5.0.0 '@types/js-cookie': 3.0.1 '@types/js-yaml': 4.0.5 '@types/node': 17.0.23 @@ -208,26 +206,6 @@ packages: } dev: false - /@mapbox/node-pre-gyp/1.0.6: - resolution: - { - integrity: sha512-qK1ECws8UxuPqOA8F5LFD90vyVU33W7N3hGfgsOVfrJaRVc8McC3JClTDHpeSbL9CBrOHly/4GsNPAvIgNZE+g== - } - hasBin: true - dependencies: - detect-libc: 1.0.3 - https-proxy-agent: 5.0.0 - make-dir: 3.1.0 - node-fetch: 2.6.6 - nopt: 5.0.0 - npmlog: 5.0.1 - rimraf: 3.0.2 - semver: 7.3.5 - tar: 6.1.11 - transitivePeerDependencies: - - supports-color - dev: false - /@nodelib/fs.scandir/2.1.5: resolution: { @@ -480,15 +458,6 @@ packages: } dev: true - /@types/bcrypt/5.0.0: - resolution: - { - integrity: sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw== - } - dependencies: - '@types/node': 17.0.23 - dev: true - /@types/cacheable-request/6.0.2: resolution: { @@ -718,13 +687,6 @@ packages: } dev: true - /abbrev/1.1.1: - resolution: - { - integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - } - dev: false - /acorn-jsx/5.3.2_acorn@7.4.1: resolution: { @@ -851,17 +813,13 @@ packages: engines: { node: '>=0.10.0' } dev: true - /ansi-regex/3.0.0: - resolution: { integrity: sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= } - engines: { node: '>=4' } - dev: false - /ansi-regex/5.0.1: resolution: { integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== } engines: { node: '>=8' } + dev: true /ansi-regex/6.0.1: resolution: @@ -915,24 +873,6 @@ packages: picomatch: 2.3.0 dev: true - /aproba/2.0.0: - resolution: - { - integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - } - dev: false - - /are-we-there-yet/2.0.0: - resolution: - { - integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - } - engines: { node: '>=10' } - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.0 - dev: false - /arg/4.1.3: resolution: { @@ -1652,18 +1592,8 @@ packages: tweetnacl: 0.14.5 dev: false - /bcrypt/5.0.1: - resolution: - { - integrity: sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw== - } - engines: { node: '>= 10.0.0' } - requiresBuild: true - dependencies: - '@mapbox/node-pre-gyp': 1.0.6 - node-addon-api: 3.2.1 - transitivePeerDependencies: - - supports-color + /bcryptjs/2.4.3: + resolution: { integrity: sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= } dev: false /binary-extensions/2.2.0: @@ -1870,14 +1800,6 @@ packages: } dev: false - /chownr/2.0.0: - resolution: - { - integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - } - engines: { node: '>=10' } - dev: false - /clean-stack/2.2.0: resolution: { @@ -1962,14 +1884,6 @@ packages: } dev: true - /color-support/1.1.3: - resolution: - { - integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - } - hasBin: true - dev: false - /colorette/2.0.16: resolution: { @@ -1995,10 +1909,6 @@ packages: /concat-map/0.0.1: resolution: { integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= } - /console-control-strings/1.1.0: - resolution: { integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= } - dev: false - /convert-source-map/1.8.0: resolution: { @@ -2202,10 +2112,6 @@ packages: resolution: { integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= } dev: true - /delegates/1.0.0: - resolution: { integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= } - dev: false - /denque/1.5.1: resolution: { @@ -2229,12 +2135,6 @@ packages: engines: { node: '>=8' } dev: true - /detect-libc/1.0.3: - resolution: { integrity: sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= } - engines: { node: '>=0.10' } - hasBin: true - dev: false - /detective/5.2.0: resolution: { @@ -2368,6 +2268,7 @@ packages: { integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== } + dev: true /emoji-regex/9.2.2: resolution: @@ -3010,16 +2911,6 @@ packages: } dev: false - /fs-minipass/2.1.0: - resolution: - { - integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - } - engines: { node: '>= 8' } - dependencies: - minipass: 3.1.5 - dev: false - /fs.realpath/1.0.0: resolution: { integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8= } @@ -3054,24 +2945,6 @@ packages: resolution: { integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= } dev: true - /gauge/3.0.1: - resolution: - { - integrity: sha512-6STz6KdQgxO4S/ko+AbjlFGGdGcknluoqU+79GOFCDqqyYj5OanQf9AjxwN0jCidtT+ziPMmPSt9E4hfQ0CwIQ== - } - engines: { node: '>=10' } - dependencies: - aproba: 2.0.0 - color-support: 1.1.3 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - object-assign: 4.1.1 - signal-exit: 3.0.5 - string-width: 2.1.1 - strip-ansi: 4.0.0 - wide-align: 1.1.5 - dev: false - /generate-password/1.7.0: resolution: { @@ -3241,10 +3114,6 @@ packages: engines: { node: '>=8' } dev: true - /has-unicode/2.0.1: - resolution: { integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= } - dev: false - /has/1.0.3: resolution: { @@ -3457,17 +3326,13 @@ packages: engines: { node: '>=0.10.0' } dev: true - /is-fullwidth-code-point/2.0.0: - resolution: { integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= } - engines: { node: '>=4' } - dev: false - /is-fullwidth-code-point/3.0.0: resolution: { integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== } engines: { node: '>=8' } + dev: true /is-fullwidth-code-point/4.0.0: resolution: @@ -3839,6 +3704,7 @@ packages: engines: { node: '>=10' } dependencies: yallist: 4.0.0 + dev: true /lru_map/0.3.3: resolution: { integrity: sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= } @@ -3860,16 +3726,6 @@ packages: sourcemap-codec: 1.4.8 dev: true - /make-dir/3.1.0: - resolution: - { - integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - } - engines: { node: '>=8' } - dependencies: - semver: 6.3.0 - dev: false - /make-error/1.3.6: resolution: { @@ -3950,27 +3806,6 @@ packages: } dev: true - /minipass/3.1.5: - resolution: - { - integrity: sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw== - } - engines: { node: '>=8' } - dependencies: - yallist: 4.0.0 - dev: false - - /minizlib/2.1.2: - resolution: - { - integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - } - engines: { node: '>= 8' } - dependencies: - minipass: 3.1.5 - yallist: 4.0.0 - dev: false - /mkdirp-classic/0.5.3: resolution: { @@ -3988,15 +3823,6 @@ packages: minimist: 1.2.5 dev: true - /mkdirp/1.0.4: - resolution: - { - integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - } - engines: { node: '>=10' } - hasBin: true - dev: false - /mri/1.2.0: resolution: { @@ -4065,23 +3891,6 @@ packages: resolution: { integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= } dev: true - /node-addon-api/3.2.1: - resolution: - { - integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - } - dev: false - - /node-fetch/2.6.6: - resolution: - { - integrity: sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== - } - engines: { node: 4.x || >=6.0.0 } - dependencies: - whatwg-url: 5.0.0 - dev: false - /node-forge/1.3.0: resolution: { @@ -4113,17 +3922,6 @@ packages: } dev: false - /nopt/5.0.0: - resolution: - { - integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - } - engines: { node: '>=6' } - hasBin: true - dependencies: - abbrev: 1.1.1 - dev: false - /normalize-path/3.0.0: resolution: { @@ -4155,23 +3953,6 @@ packages: path-key: 3.1.1 dev: true - /npmlog/5.0.1: - resolution: - { - integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - } - dependencies: - are-we-there-yet: 2.0.0 - console-control-strings: 1.1.0 - gauge: 3.0.1 - set-blocking: 2.0.0 - dev: false - - /object-assign/4.1.1: - resolution: { integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= } - engines: { node: '>=0.10.0' } - dev: false - /object-hash/2.2.0: resolution: { @@ -4706,6 +4487,7 @@ packages: hasBin: true dependencies: glob: 7.2.0 + dev: true /rollup/2.61.1: resolution: @@ -4801,10 +4583,7 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - - /set-blocking/2.0.0: - resolution: { integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc= } - dev: false + dev: true /shebang-command/1.2.0: resolution: { integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= } @@ -4839,6 +4618,7 @@ packages: { integrity: sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== } + dev: true /slash/1.0.0: resolution: { integrity: sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= } @@ -4973,17 +4753,6 @@ packages: engines: { node: '>=0.6.19' } dev: true - /string-width/2.1.1: - resolution: - { - integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - } - engines: { node: '>=4' } - dependencies: - is-fullwidth-code-point: 2.0.0 - strip-ansi: 4.0.0 - dev: false - /string-width/4.2.3: resolution: { @@ -4994,6 +4763,7 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + dev: true /string-width/5.1.0: resolution: @@ -5023,13 +4793,6 @@ packages: ansi-regex: 2.1.1 dev: true - /strip-ansi/4.0.0: - resolution: { integrity: sha1-qEeQIusaw2iocTibY1JixQXuNo8= } - engines: { node: '>=4' } - dependencies: - ansi-regex: 3.0.0 - dev: false - /strip-ansi/6.0.1: resolution: { @@ -5038,6 +4801,7 @@ packages: engines: { node: '>=8' } dependencies: ansi-regex: 5.0.1 + dev: true /strip-ansi/7.0.1: resolution: @@ -5324,21 +5088,6 @@ packages: readable-stream: 3.6.0 dev: false - /tar/6.1.11: - resolution: - { - integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== - } - engines: { node: '>= 10' } - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 3.1.5 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: false - /text-table/0.2.0: resolution: { integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= } dev: true @@ -5372,10 +5121,6 @@ packages: is-number: 7.0.0 dev: true - /tr46/0.0.3: - resolution: { integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= } - dev: false - /trim-right/1.0.1: resolution: { integrity: sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= } engines: { node: '>=0.10.0' } @@ -5558,17 +5303,6 @@ packages: fsevents: 2.3.2 dev: true - /webidl-conversions/3.0.1: - resolution: { integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= } - dev: false - - /whatwg-url/5.0.0: - resolution: { integrity: sha1-lmRU6HZUYuN2RNNib2dCzotwll0= } - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - /which/1.3.1: resolution: { @@ -5589,15 +5323,6 @@ packages: dependencies: isexe: 2.0.0 - /wide-align/1.1.5: - resolution: - { - integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - } - dependencies: - string-width: 4.2.3 - dev: false - /word-wrap/1.2.3: resolution: { @@ -5650,6 +5375,7 @@ packages: { integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== } + dev: true /yaml/1.10.2: resolution: diff --git a/src/lib/database/users.ts b/src/lib/database/users.ts index 7e5cc481e..552b422b5 100644 --- a/src/lib/database/users.ts +++ b/src/lib/database/users.ts @@ -1,5 +1,5 @@ import cuid from 'cuid'; -import bcrypt from 'bcrypt'; +import bcrypt from 'bcryptjs'; import { prisma } from './common'; import { asyncExecShell, uniqueName } from '$lib/common'; From 823279fb60389009e6357b7731da19f034652aca Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 1 Apr 2022 17:16:11 +0200 Subject: [PATCH 03/46] Updates --- Dockerfile | 11 ++--------- .../haproxy-http.Dockerfile | 0 haproxy-tcp.Dockerfile => data/haproxy-tcp.Dockerfile | 0 haproxy.Dockerfile => data/haproxy.Dockerfile | 0 data/prisma-engine.Dockerfile | 10 ++++++++++ 5 files changed, 12 insertions(+), 9 deletions(-) rename haproxy-http.Dockerfile => data/haproxy-http.Dockerfile (100%) rename haproxy-tcp.Dockerfile => data/haproxy-tcp.Dockerfile (100%) rename haproxy.Dockerfile => data/haproxy.Dockerfile (100%) create mode 100644 data/prisma-engine.Dockerfile diff --git a/Dockerfile b/Dockerfile index 28e7e820b..5c95c5398 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,14 +3,6 @@ WORKDIR /app COPY package*.json . RUN yarn install - -FROM rust:1.58.1-alpine3.14 as prisma -WORKDIR /prisma -ENV RUSTFLAGS="-C target-feature=-crt-static" -RUN apk --no-cache add openssl direnv git musl-dev openssl-dev build-base perl protoc -RUN git clone --depth=1 --branch=3.11.x https://github.com/prisma/prisma-engines.git /prisma -RUN cargo build --release - FROM node:16.14.2-alpine ARG TARGETPLATFORM @@ -22,7 +14,8 @@ ENV PRISMA_QUERY_ENGINE_BINARY=/app/prisma-engines/query-engine \ PRISMA_FMT_BINARY=/app/prisma-engines/prisma-fmt \ PRISMA_CLI_QUERY_ENGINE_TYPE=binary \ PRISMA_CLIENT_ENGINE_TYPE=binary -COPY --from=prisma /prisma/target/release/query-engine /prisma/target/release/migration-engine /prisma/target/release/introspection-engine /prisma/target/release/prisma-fmt /app/prisma-engines/ + +COPY --from=coollabsio/prisma-engine:arm64 /prisma-engines/query-engine /prisma-engines/migration-engine /prisma-engines/introspection-engine /prisma-engines/prisma-fmt /app/prisma-engines/ COPY --from=install /app/node_modules ./node_modules COPY . . diff --git a/haproxy-http.Dockerfile b/data/haproxy-http.Dockerfile similarity index 100% rename from haproxy-http.Dockerfile rename to data/haproxy-http.Dockerfile diff --git a/haproxy-tcp.Dockerfile b/data/haproxy-tcp.Dockerfile similarity index 100% rename from haproxy-tcp.Dockerfile rename to data/haproxy-tcp.Dockerfile diff --git a/haproxy.Dockerfile b/data/haproxy.Dockerfile similarity index 100% rename from haproxy.Dockerfile rename to data/haproxy.Dockerfile diff --git a/data/prisma-engine.Dockerfile b/data/prisma-engine.Dockerfile new file mode 100644 index 000000000..086472e23 --- /dev/null +++ b/data/prisma-engine.Dockerfile @@ -0,0 +1,10 @@ +FROM rust:1.58.1-alpine3.14 as prisma +WORKDIR /prisma +ENV RUSTFLAGS="-C target-feature=-crt-static" +RUN apk --no-cache add openssl direnv git musl-dev openssl-dev build-base perl protoc +RUN git clone --depth=1 --branch=3.11.x https://github.com/prisma/prisma-engines.git /prisma +RUN cargo build --release + +FROM alpine +WORKDIR /prisma-engines +COPY --from=prisma /prisma/target/release/query-engine /prisma/target/release/migration-engine /prisma/target/release/introspection-engine /prisma/target/release/prisma-fmt /prisma-engines/ From 22ef0b5d29c30e39542d3f3549c20418f0afee6d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 1 Apr 2022 17:46:08 +0200 Subject: [PATCH 04/46] Update packages --- Dockerfile | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5c95c5398..4b7b67b85 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ ENV PRISMA_QUERY_ENGINE_BINARY=/app/prisma-engines/query-engine \ PRISMA_CLI_QUERY_ENGINE_TYPE=binary \ PRISMA_CLIENT_ENGINE_TYPE=binary -COPY --from=coollabsio/prisma-engine:arm64 /prisma-engines/query-engine /prisma-engines/migration-engine /prisma-engines/introspection-engine /prisma-engines/prisma-fmt /app/prisma-engines/ +COPY --from=coollabsio/prisma-engine:latest /prisma-engines/query-engine /prisma-engines/migration-engine /prisma-engines/introspection-engine /prisma-engines/prisma-fmt /app/prisma-engines/ COPY --from=install /app/node_modules ./node_modules COPY . . diff --git a/package.json b/package.json index 7dfd0f6e8..18c3a208e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "dev:stop": "docker-compose -f docker-compose-dev.yaml down", "dev:logs": "docker-compose -f docker-compose-dev.yaml logs -f --tail 10", "studio": "npx prisma studio", - "start": "npx prisma migrate deploy && npx prisma generate && npx prisma db seed && node index.js", + "start": "npx prisma migrate deploy && npx prisma generate && npx prisma db seed && node build/index.js", "build": "svelte-kit build", "preview": "svelte-kit preview", "check": "svelte-check --tsconfig ./tsconfig.json", From fe17e2eaba615cb83c154837e7b7b709d7c4b526 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 1 Apr 2022 17:57:37 +0200 Subject: [PATCH 05/46] Prisma Engine build script --- data/build-prisma-engine.sh | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/build-prisma-engine.sh diff --git a/data/build-prisma-engine.sh b/data/build-prisma-engine.sh new file mode 100644 index 000000000..42c2af608 --- /dev/null +++ b/data/build-prisma-engine.sh @@ -0,0 +1 @@ +nohup docker build -t coollabsio/prisma-engine: --push . & \ No newline at end of file From f6858a68e0f298ec34ba95240883534a92933fd8 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 1 Apr 2022 22:51:08 +0200 Subject: [PATCH 06/46] Update schema --- prisma/schema.prisma | 1 + 1 file changed, 1 insertion(+) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a849ae36f..b05a6a6a4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,5 +1,6 @@ generator client { provider = "prisma-client-js" + binaryTargets = ["linux-musl"] } datasource db { From 321fb019eb544946ce3ff54ab1b77dfbcc45ed20 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 1 Apr 2022 23:02:23 +0200 Subject: [PATCH 07/46] Update dockerfiles for arm --- data/haproxy-http.Dockerfile | 6 +++--- data/haproxy-tcp.Dockerfile | 6 +++--- data/haproxy.Dockerfile | 6 +++--- data/haproxy/haproxy.cfg-http.template | 8 ++++---- data/haproxy/haproxy.cfg.template | 8 ++++---- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/data/haproxy-http.Dockerfile b/data/haproxy-http.Dockerfile index 089ae0f96..de5246628 100644 --- a/data/haproxy-http.Dockerfile +++ b/data/haproxy-http.Dockerfile @@ -1,6 +1,6 @@ FROM haproxytech/haproxy-alpine:2.5 RUN mkdir -p /usr/local/etc/haproxy/ssl /usr/local/etc/haproxy/maps /usr/local/etc/haproxy/spoe -COPY data/haproxy/haproxy.cfg-http.template /usr/local/etc/haproxy/haproxy.cfg -COPY data/haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl -COPY data/haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem \ No newline at end of file +COPY haproxy/haproxy.cfg-http.template /usr/local/etc/haproxy/haproxy.cfg +COPY haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl +COPY haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem \ No newline at end of file diff --git a/data/haproxy-tcp.Dockerfile b/data/haproxy-tcp.Dockerfile index bddcbe541..9b9639777 100644 --- a/data/haproxy-tcp.Dockerfile +++ b/data/haproxy-tcp.Dockerfile @@ -1,6 +1,6 @@ FROM haproxytech/haproxy-alpine:2.5 RUN mkdir -p /usr/local/etc/haproxy/ssl /usr/local/etc/haproxy/maps /usr/local/etc/haproxy/spoe -COPY data/haproxy/haproxy.cfg-tcp.template /usr/local/etc/haproxy/haproxy.cfg -COPY data/haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl -COPY data/haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem \ No newline at end of file +COPY haproxy/haproxy.cfg-tcp.template /usr/local/etc/haproxy/haproxy.cfg +COPY haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl +COPY haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem \ No newline at end of file diff --git a/data/haproxy.Dockerfile b/data/haproxy.Dockerfile index 45e2d9d71..3ab520a65 100644 --- a/data/haproxy.Dockerfile +++ b/data/haproxy.Dockerfile @@ -1,6 +1,6 @@ FROM haproxytech/haproxy-alpine:2.5 RUN mkdir -p /usr/local/etc/haproxy/ssl /usr/local/etc/haproxy/maps /usr/local/etc/haproxy/spoe -COPY data/haproxy/haproxy.cfg.template /usr/local/etc/haproxy/haproxy.cfg -COPY data/haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl -COPY data/haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem \ No newline at end of file +COPY haproxy/haproxy.cfg.template /usr/local/etc/haproxy/haproxy.cfg +COPY haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl +COPY haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem \ No newline at end of file diff --git a/data/haproxy/haproxy.cfg-http.template b/data/haproxy/haproxy.cfg-http.template index 72fdece7a..f819e9be7 100644 --- a/data/haproxy/haproxy.cfg-http.template +++ b/data/haproxy/haproxy.cfg-http.template @@ -4,10 +4,10 @@ global defaults mode http log global - timeout http-request 60s - timeout connect 10s - timeout client 60s - timeout server 60s + timeout http-request 120s + timeout connect 20s + timeout client 120s + timeout server 120s frontend "${APP}" mode http diff --git a/data/haproxy/haproxy.cfg.template b/data/haproxy/haproxy.cfg.template index c39cb7878..35cb8a74d 100644 --- a/data/haproxy/haproxy.cfg.template +++ b/data/haproxy/haproxy.cfg.template @@ -5,10 +5,10 @@ global defaults mode http log global - timeout http-request 60s - timeout connect 10s - timeout client 60s - timeout server 60s + timeout http-request 120s + timeout connect 20s + timeout client 120s + timeout server 120s userlist haproxy-dataplaneapi user admin insecure-password "${HAPROXY_PASSWORD}" From 1b43976ff0b827c3d176b331a5056ee142373e1a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Sat, 2 Apr 2022 13:39:24 +0200 Subject: [PATCH 08/46] Update proxy build commands --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 18c3a208e..922ffc220 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,9 @@ "release:staging": "cross-var docker build -t coollabsio/coolify:$npm_package_version . && docker push coollabsio/coolify:$npm_package_version", "release:pre": "cross-var docker build -t coollabsio/coolify:$npm_package_version -t coollabsio/coolify:latest .", "release:coolify": "cross-var yarn release:pre && docker push coollabsio/coolify:$npm_package_version && docker push coollabsio/coolify:latest", - "release:haproxy": "docker build -f haproxy.Dockerfile -t coollabsio/coolify-haproxy-alpine:1.0.0 -t coollabsio/coolify-haproxy-alpine:latest . && docker image push --all-tags coollabsio/coolify-haproxy-alpine", - "release:haproxy:tcp": "docker build -f haproxy-tcp.Dockerfile -t coollabsio/coolify-haproxy-tcp-alpine:1.0.0 -t coollabsio/coolify-haproxy-tcp-alpine:latest . && docker image push --all-tags coollabsio/coolify-haproxy-tcp-alpine", - "release:haproxy:http": "docker build -f haproxy-http.Dockerfile -t coollabsio/coolify-haproxy-http-alpine:1.0.0 -t coollabsio/coolify-haproxy-http-alpine:latest . && docker image push --all-tags coollabsio/coolify-haproxy-http-alpine", + "release:haproxy": "docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify-haproxy-alpine:latest -t coollabsio/coolify-haproxy-alpine:1.1.0 -f haproxy.Dockerfile --push .", + "release:haproxy:tcp": "docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify-haproxy-tcp-alpine:latest -t coollabsio/coolify-haproxy-tcp-alpine:1.1.0 -f haproxy-tcp.Dockerfile --push .", + "release:haproxy:http": "docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify-haproxy-http-alpine:latest -t coollabsio/coolify-haproxy-http-alpine:1.1.0 -f haproxy-http.Dockerfile --push .", "prepare": "husky install" }, "devDependencies": { From e08ec12d261c6e18e7eb406777b39e54b92265e1 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Tue, 5 Apr 2022 20:11:19 +0200 Subject: [PATCH 09/46] Introduced typing for the buildJob and cleaned up common.ts --- src/lib/common.ts | 78 ++++++++++++++++++++---------------- src/lib/queues/builder.ts | 28 +++++++------ src/lib/types/builderJob.ts | 51 +++++++++++++++++++++++ src/routes/dashboard.json.ts | 2 +- 4 files changed, 111 insertions(+), 48 deletions(-) create mode 100644 src/lib/types/builderJob.ts diff --git a/src/lib/common.ts b/src/lib/common.ts index 49a637065..185cb8c6d 100644 --- a/src/lib/common.ts +++ b/src/lib/common.ts @@ -12,7 +12,8 @@ import { version as currentVersion } from '../../package.json'; import dayjs from 'dayjs'; import Cookie from 'cookie'; import os from 'os'; -import cuid from 'cuid'; +import type { RequestEvent } from '@sveltejs/kit/types/internal'; +import type { Job } from 'bullmq'; try { if (!dev) { @@ -45,30 +46,26 @@ const customConfig: Config = { export const version = currentVersion; export const asyncExecShell = util.promisify(child.exec); -export const asyncSleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)); +export const asyncSleep = (delay: number): Promise => + new Promise((resolve) => setTimeout(resolve, delay)); export const sentry = Sentry; -export const uniqueName = () => uniqueNamesGenerator(customConfig); +export const uniqueName = (): string => uniqueNamesGenerator(customConfig); -export const saveBuildLog = async ({ line, buildId, applicationId }) => { +export const saveBuildLog = async ({ + line, + buildId, + applicationId +}: { + line: string; + buildId: string; + applicationId: string; +}): Promise => { const addTimestamp = `${generateTimestamp()} ${line}`; return await buildLogQueue.add(buildId, { buildId, line: addTimestamp, applicationId }); }; -export const isTeamIdTokenAvailable = (request) => { - const cookie = request.headers.cookie - ?.split(';') - .map((s) => s.trim()) - .find((s) => s.startsWith('teamId=')) - ?.split('=')[1]; - if (!cookie) { - return getTeam(request); - } else { - return cookie; - } -}; - -export const getTeam = (event) => { +export const getTeam = (event: RequestEvent): string | null => { const cookies = Cookie.parse(event.request.headers.get('cookie')); if (cookies?.teamId) { return cookies.teamId; @@ -78,7 +75,16 @@ export const getTeam = (event) => { return null; }; -export const getUserDetails = async (event, isAdminRequired = true) => { +export const getUserDetails = async ( + event: RequestEvent, + isAdminRequired = true +): Promise<{ + teamId: string; + userId: string; + permission: string; + status: number; + body: { message: string }; +}> => { const teamId = getTeam(event); const userId = event?.locals?.session?.data?.userId || null; const { permission = 'read' } = await db.prisma.permission.findFirst({ @@ -104,11 +110,11 @@ export const getUserDetails = async (event, isAdminRequired = true) => { return payload; }; -export function getEngine(engine) { +export function getEngine(engine: string): string { return engine === '/var/run/docker.sock' ? 'unix:///var/run/docker.sock' : engine; } -export async function removeContainer(id, engine) { +export async function removeContainer(id: string, engine: string): Promise { const host = getEngine(engine); try { const { stdout } = await asyncExecShell( @@ -124,11 +130,23 @@ export async function removeContainer(id, engine) { } } -export const removeDestinationDocker = async ({ id, engine }) => { +export const removeDestinationDocker = async ({ + id, + engine +}: { + id: string; + engine: string; +}): Promise => { return await removeContainer(id, engine); }; -export const createDirectories = async ({ repository, buildId }) => { +export const createDirectories = async ({ + repository, + buildId +}: { + repository: string; + buildId: string; +}): Promise<{ workdir: string; repodir: string }> => { const repodir = `/tmp/build-sources/${repository}/`; const workdir = `/tmp/build-sources/${repository}/${buildId}`; @@ -140,20 +158,10 @@ export const createDirectories = async ({ repository, buildId }) => { }; }; -export function generateTimestamp() { +export function generateTimestamp(): string { return `${dayjs().format('HH:mm:ss.SSS')} `; } -export function getDomain(domain) { +export function getDomain(domain: string): string { return domain?.replace('https://', '').replace('http://', ''); } - -export function dashify(str: string, options?: any): string { - if (typeof str !== 'string') return str; - return str - .trim() - .replace(/\W/g, (m) => (/[À-ž]/.test(m) ? m : '-')) - .replace(/^-+|-+$/g, '') - .replace(/-{2,}/g, (m) => (options && options.condense ? '-' : m)) - .toLowerCase(); -} diff --git a/src/lib/queues/builder.ts b/src/lib/queues/builder.ts index 0ef207f2a..e7c0e6469 100644 --- a/src/lib/queues/builder.ts +++ b/src/lib/queues/builder.ts @@ -20,30 +20,24 @@ import { setDefaultConfiguration } from '$lib/buildPacks/common'; import yaml from 'js-yaml'; +import type { Job } from 'bullmq'; +import type { BuilderJob } from '$lib/types/builderJob'; -export default async function (job) { +export default async function (job: Job): Promise { /* Edge cases: 1 - Change build pack and redeploy, what should happen? */ - let { + const { id: applicationId, repository, - branch, - buildPack, name, destinationDocker, destinationDockerId, gitSource, build_id: buildId, configHash, - port, - installCommand, - buildCommand, - startCommand, fqdn, - baseDirectory, - publishDirectory, projectId, secrets, phpModules, @@ -56,6 +50,16 @@ export default async function (job) { pythonModule, pythonVariable } = job.data; + let { + branch, + buildPack, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory + } = job.data; const { debug } = settings; await asyncSleep(500); @@ -70,7 +74,7 @@ export default async function (job) { }); let imageId = applicationId; let domain = getDomain(fqdn); - let volumes = + const volumes = persistentStorage?.map((storage) => { return `${applicationId}${storage.path.replace(/\//gi, '-')}:${ buildPack !== 'docker' ? '/app' : '' @@ -106,7 +110,7 @@ export default async function (job) { publishDirectory = configuration.publishDirectory; baseDirectory = configuration.baseDirectory; - let commit = await importers[gitSource.type]({ + const commit = await importers[gitSource.type]({ applicationId, debug, workdir, diff --git a/src/lib/types/builderJob.ts b/src/lib/types/builderJob.ts new file mode 100644 index 000000000..0f96520e5 --- /dev/null +++ b/src/lib/types/builderJob.ts @@ -0,0 +1,51 @@ +import type { DestinationDocker, GithubApp, GitlabApp, GitSource, Secret } from '@prisma/client'; + +export type BuilderJob = { + build_id: string; + type: BuildType; + id: string; + name: string; + fqdn: string; + repository: string; + configHash: unknown; + branch: string; + buildPack: BuildPackName; + projectId: number; + port: number; + installCommand: string; + buildCommand?: string; + startCommand?: string; + baseDirectory: string; + publishDirectory: string; + phpModules: unknown; // probably an array of some type; + pythonWSGI: unknown; // probably a string?; + pythonModule: unknown; // probably a string?; + pythonVariable: unknown; // probably a string?; + createdAt: string; + updatedAt: string; + destinationDockerId: string; + destinationDocker: DestinationDocker; + gitSource: GitSource & { githubApp?: GithubApp; gitlabApp?: GitlabApp }; + settings: BuilderJobSettings; + secrets: Secret[]; + persistentStorage: { path: string }[]; + pullmergeRequestId?: unknown; + sourceBranch?: string; +}; + +// TODO: Add the other build types +export type BuildType = 'manual'; + +// TODO: Add the other buildpack names +export type BuildPackName = 'node' | 'docker'; + +export type BuilderJobSettings = { + id: string; + applicationId: string; + dualCerts: boolean; + debug: boolean; + previews: boolean; + autodeploy: boolean; + createdAt: string; + updatedAt: string; +}; diff --git a/src/routes/dashboard.json.ts b/src/routes/dashboard.json.ts index 4c3ed3097..077ffe2df 100644 --- a/src/routes/dashboard.json.ts +++ b/src/routes/dashboard.json.ts @@ -1,4 +1,4 @@ -import { getTeam, getUserDetails } from '$lib/common'; +import { getUserDetails } from '$lib/common'; import * as db from '$lib/database'; import { ErrorHandler } from '$lib/database'; import type { RequestHandler } from '@sveltejs/kit'; From 9fdac2741ad990cad3de88db9993cba2916a9b86 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Tue, 5 Apr 2022 20:48:33 +0200 Subject: [PATCH 10/46] Improved typing and quality of applications.ts --- src/lib/database/applications.ts | 170 ++++++++++++++++++------------- src/lib/types/builderJob.ts | 8 +- 2 files changed, 105 insertions(+), 73 deletions(-) diff --git a/src/lib/database/applications.ts b/src/lib/database/applications.ts index 1d8140144..42887905e 100644 --- a/src/lib/database/applications.ts +++ b/src/lib/database/applications.ts @@ -1,14 +1,29 @@ import { decrypt, encrypt } from '$lib/crypto'; import { asyncExecShell, getEngine } from '$lib/common'; -import { getDomain, removeDestinationDocker } from '$lib/common'; +import { removeDestinationDocker } from '$lib/common'; import { prisma } from './common'; -export async function listApplications(teamId) { +import type { + DestinationDocker, + GitSource, + Secret, + ApplicationSettings, + Application, + ApplicationPersistentStorage +} from '@prisma/client'; + +export async function listApplications(teamId: string): Promise { return await prisma.application.findMany({ where: { teams: { some: { id: teamId } } } }); } -export async function newApplication({ name, teamId }) { +export async function newApplication({ + name, + teamId +}: { + name: string; + teamId: string; +}): Promise { return await prisma.application.create({ data: { name, @@ -18,34 +33,17 @@ export async function newApplication({ name, teamId }) { }); } -export async function importApplication({ - name, - teamId, - fqdn, - port, - buildCommand, - startCommand, - installCommand -}) { - return await prisma.application.create({ - data: { - name, - fqdn, - port, - buildCommand, - startCommand, - installCommand, - teams: { connect: { id: teamId } } - } - }); -} - -export async function removeApplication({ id, teamId }) { - const { fqdn, destinationDockerId, destinationDocker } = await prisma.application.findUnique({ +export async function removeApplication({ + id, + teamId +}: { + id: string; + teamId: string; +}): Promise { + const { destinationDockerId, destinationDocker } = await prisma.application.findUnique({ where: { id }, include: { destinationDocker: true } }); - const domain = getDomain(fqdn); if (destinationDockerId) { const host = getEngine(destinationDocker.engine); const { stdout: containers } = await asyncExecShell( @@ -56,7 +54,6 @@ export async function removeApplication({ id, teamId }) { for (const container of containersArray) { const containerObj = JSON.parse(container); const id = containerObj.ID; - const preview = containerObj.Image.split('-')[1]; await removeDestinationDocker({ id, engine: destinationDocker.engine }); } } @@ -70,9 +67,23 @@ export async function removeApplication({ id, teamId }) { await prisma.application.deleteMany({ where: { id, teams: { some: { id: teamId } } } }); } -export async function getApplicationWebhook({ projectId, branch }) { +export async function getApplicationWebhook({ + projectId, + branch +}: { + projectId: number; + branch: string; +}): Promise< + Application & { + destinationDocker: DestinationDocker; + settings: ApplicationSettings; + gitSource: GitSource; + secrets: Secret[]; + persistentStorage: ApplicationPersistentStorage[]; + } +> { try { - let application = await prisma.application.findFirst({ + const application = await prisma.application.findFirst({ where: { projectId, branch, settings: { autodeploy: true } }, include: { destinationDocker: true, @@ -121,16 +132,23 @@ export async function getApplicationWebhook({ projectId, branch }) { throw { status: 404, body: { message: e.message } }; } } -export async function getApplicationById({ id }) { - const body = await prisma.application.findFirst({ - where: { id }, - include: { destinationDocker: true } - }); - return { ...body }; -} -export async function getApplication({ id, teamId }) { - let body = await prisma.application.findFirst({ +export async function getApplication({ + id, + teamId +}: { + id: string; + teamId: string; +}): Promise< + Application & { + destinationDocker: DestinationDocker; + settings: ApplicationSettings; + gitSource: GitSource; + secrets: Secret[]; + persistentStorage: ApplicationPersistentStorage[]; + } +> { + const body = await prisma.application.findFirst({ where: { id, teams: { some: { id: teamId } } }, include: { destinationDocker: true, @@ -170,7 +188,14 @@ export async function configureGitRepository({ projectId, webhookToken, autodeploy -}) { +}: { + id: string; + repository: string; + branch: string; + projectId: number; + webhookToken: string; + autodeploy: boolean; +}): Promise { if (webhookToken) { const encryptedWebhookToken = encrypt(webhookToken); await prisma.application.update({ @@ -200,7 +225,10 @@ export async function configureGitRepository({ } } -export async function configureBuildPack({ id, buildPack }) { +export async function configureBuildPack({ + id, + buildPack +}: Pick): Promise { return await prisma.application.update({ where: { id }, data: { buildPack } }); } @@ -218,7 +246,21 @@ export async function configureApplication({ pythonWSGI, pythonModule, pythonVariable -}) { +}: { + id: string; + buildPack: string; + name: string; + fqdn: string; + port: number; + installCommand: string; + buildCommand: string; + startCommand: string; + baseDirectory: string; + publishDirectory: string; + pythonWSGI: string; + pythonModule: string; + pythonVariable: string; +}): Promise { return await prisma.application.update({ where: { id }, data: { @@ -238,11 +280,24 @@ export async function configureApplication({ }); } -export async function checkDoubleBranch(branch, projectId) { +export async function checkDoubleBranch(branch: string, projectId: number): Promise { const applications = await prisma.application.findMany({ where: { branch, projectId } }); return applications.length > 1; } -export async function setApplicationSettings({ id, debug, previews, dualCerts, autodeploy }) { + +export async function setApplicationSettings({ + id, + debug, + previews, + dualCerts, + autodeploy +}: { + id: string; + debug: boolean; + previews: boolean; + dualCerts: boolean; + autodeploy: boolean; +}): Promise { return await prisma.application.update({ where: { id }, data: { settings: { update: { debug, previews, dualCerts, autodeploy } } }, @@ -250,29 +305,6 @@ export async function setApplicationSettings({ id, debug, previews, dualCerts, a }); } -export async function createBuild({ - id, - applicationId, - destinationDockerId, - gitSourceId, - githubAppId, - gitlabAppId, - type -}) { - return await prisma.build.create({ - data: { - id, - applicationId, - destinationDockerId, - gitSourceId, - githubAppId, - gitlabAppId, - status: 'running', - type - } - }); -} - -export async function getPersistentStorage(id) { +export async function getPersistentStorage(id: string): Promise { return await prisma.applicationPersistentStorage.findMany({ where: { applicationId: id } }); } diff --git a/src/lib/types/builderJob.ts b/src/lib/types/builderJob.ts index 0f96520e5..1a1652f8a 100644 --- a/src/lib/types/builderJob.ts +++ b/src/lib/types/builderJob.ts @@ -17,10 +17,10 @@ export type BuilderJob = { startCommand?: string; baseDirectory: string; publishDirectory: string; - phpModules: unknown; // probably an array of some type; - pythonWSGI: unknown; // probably a string?; - pythonModule: unknown; // probably a string?; - pythonVariable: unknown; // probably a string?; + phpModules: string; + pythonWSGI: string; + pythonModule: string; + pythonVariable: string; createdAt: string; updatedAt: string; destinationDockerId: string; From 82f7633c3a29d363caeb46d4e1263aa8d936909b Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Tue, 5 Apr 2022 21:15:02 +0200 Subject: [PATCH 11/46] Improved typing and quality of database/checks and database/common code --- src/lib/database/checks.ts | 46 +++++++++++++--- src/lib/database/common.ts | 108 ++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 39 deletions(-) diff --git a/src/lib/database/checks.ts b/src/lib/database/checks.ts index 534d81966..bbe773ae5 100644 --- a/src/lib/database/checks.ts +++ b/src/lib/database/checks.ts @@ -1,7 +1,16 @@ import { getDomain } from '$lib/common'; import { prisma } from './common'; +import type { Application, ServiceSecret, DestinationDocker, Secret } from '@prisma/client'; -export async function isBranchAlreadyUsed({ repository, branch, id }) { +export async function isBranchAlreadyUsed({ + repository, + branch, + id +}: { + id: string; + repository: string; + branch: string; +}): Promise { const application = await prisma.application.findUnique({ where: { id }, include: { gitSource: true } @@ -11,18 +20,42 @@ export async function isBranchAlreadyUsed({ repository, branch, id }) { }); } -export async function isDockerNetworkExists({ network }) { +export async function isDockerNetworkExists({ + network +}: { + network: string; +}): Promise { return await prisma.destinationDocker.findFirst({ where: { network } }); } -export async function isServiceSecretExists({ id, name }) { +export async function isServiceSecretExists({ + id, + name +}: { + id: string; + name: string; +}): Promise { return await prisma.serviceSecret.findFirst({ where: { name, serviceId: id } }); } -export async function isSecretExists({ id, name, isPRMRSecret }) { +export async function isSecretExists({ + id, + name, + isPRMRSecret +}: { + id: string; + name: string; + isPRMRSecret: boolean; +}): Promise { return await prisma.secret.findFirst({ where: { name, applicationId: id, isPRMRSecret } }); } -export async function isDomainConfigured({ id, fqdn }) { +export async function isDomainConfigured({ + id, + fqdn +}: { + id: string; + fqdn: string; +}): Promise { const domain = getDomain(fqdn); const nakedDomain = domain.replace('www.', ''); const foundApp = await prisma.application.findFirst({ @@ -55,6 +88,5 @@ export async function isDomainConfigured({ id, fqdn }) { }, select: { fqdn: true } }); - if (foundApp || foundService || coolifyFqdn) return true; - return false; + return !!(foundApp || foundService || coolifyFqdn); } diff --git a/src/lib/database/common.ts b/src/lib/database/common.ts index 3e473f094..7c34aa235 100644 --- a/src/lib/database/common.ts +++ b/src/lib/database/common.ts @@ -2,11 +2,11 @@ import { dev } from '$app/env'; import { sentry } from '$lib/common'; import * as Prisma from '@prisma/client'; import { default as ProdPrisma } from '@prisma/client'; -import type { PrismaClientOptions } from '@prisma/client/runtime'; +import type { Database, DatabaseSettings } from '@prisma/client'; import generator from 'generate-password'; import forge from 'node-forge'; -export function generatePassword(length = 24) { +export function generatePassword(length = 24): string { return generator.generate({ length, numbers: true, @@ -26,8 +26,14 @@ export const prisma = new PrismaClient({ rejectOnNotFound: false }); -export function ErrorHandler(e) { - if (e! instanceof Error) { +export function ErrorHandler(e: { + stdout?; + message?: string; + status?: number; + name?: string; + error?: string; +}): { status: number; body: { message: string; error: string } } { + if (e && e instanceof Error) { e = new Error(e.toString()); } let truncatedError = e; @@ -35,8 +41,7 @@ export function ErrorHandler(e) { truncatedError = e.stdout; } if (e.message?.includes('docker run')) { - let truncatedArray = []; - truncatedArray = truncatedError.message.split('-').filter((line) => { + const truncatedArray: string[] = truncatedError.message.split('-').filter((line) => { if (!line.startsWith('e ')) { return line; } @@ -64,11 +69,11 @@ export function ErrorHandler(e) { payload.body.message = 'Already exists. Choose another name.'; } } - // console.error(e) return payload; } + export async function generateSshKeyPair(): Promise<{ publicKey: string; privateKey: string }> { - return await new Promise(async (resolve, reject) => { + return await new Promise((resolve, reject) => { forge.pki.rsa.generateKeyPair({ bits: 4096, workers: -1 }, function (err, keys) { if (keys) { resolve({ @@ -210,35 +215,93 @@ export const supportedServiceTypesAndVersions = [ } ]; -export function getVersions(type) { +export function getVersions(type: string): string[] { const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); if (found) { return found.versions; } return []; } -export function getDatabaseImage(type) { + +export function getDatabaseImage(type: string): string { const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type); if (found) { return found.baseImage; } return ''; } -export function getServiceImage(type) { + +export function getServiceImage(type: string): string { const found = supportedServiceTypesAndVersions.find((t) => t.name === type); if (found) { return found.baseImage; } return ''; } -export function getServiceImages(type) { + +export function getServiceImages(type: string): string[] { const found = supportedServiceTypesAndVersions.find((t) => t.name === type); if (found) { return found.images; } return []; } -export function generateDatabaseConfiguration(database) { + +export function generateDatabaseConfiguration(database: Database & { settings: DatabaseSettings }): + | { + volume: string; + image: string; + ulimits: Record; + privatePort: number; + environmentVariables: { + MYSQL_DATABASE: string; + MYSQL_PASSWORD: string; + MYSQL_ROOT_USER: string; + MYSQL_USER: string; + MYSQL_ROOT_PASSWORD: string; + }; + } + | { + volume: string; + image: string; + ulimits: Record; + privatePort: number; + environmentVariables: { + MONGODB_ROOT_USER: string; + MONGODB_ROOT_PASSWORD: string; + }; + } + | { + volume: string; + image: string; + ulimits: Record; + privatePort: number; + environmentVariables: { + POSTGRESQL_USERNAME: string; + POSTGRESQL_PASSWORD: string; + POSTGRESQL_DATABASE: string; + }; + } + | { + volume: string; + image: string; + ulimits: Record; + privatePort: number; + environmentVariables: { + REDIS_AOF_ENABLED: string; + REDIS_PASSWORD: string; + }; + } + | { + volume: string; + image: string; + ulimits: Record; + privatePort: number; + environmentVariables: { + COUCHDB_PASSWORD: string; + COUCHDB_USER: string; + }; + } { const { id, dbUser, @@ -253,7 +316,6 @@ export function generateDatabaseConfiguration(database) { const baseImage = getDatabaseImage(type); if (type === 'mysql') { return { - // url: `mysql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 3306}/${defaultDatabase}`, privatePort: 3306, environmentVariables: { MYSQL_USER: dbUser, @@ -268,7 +330,6 @@ export function generateDatabaseConfiguration(database) { }; } else if (type === 'mongodb') { return { - // url: `mongodb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 27017}/${defaultDatabase}`, privatePort: 27017, environmentVariables: { MONGODB_ROOT_USER: rootUser, @@ -280,7 +341,6 @@ export function generateDatabaseConfiguration(database) { }; } else if (type === 'postgresql') { return { - // url: `psql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5432}/${defaultDatabase}`, privatePort: 5432, environmentVariables: { POSTGRESQL_PASSWORD: dbUserPassword, @@ -293,7 +353,6 @@ export function generateDatabaseConfiguration(database) { }; } else if (type === 'redis') { return { - // url: `redis://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 6379}/${defaultDatabase}`, privatePort: 6379, environmentVariables: { REDIS_PASSWORD: dbUserPassword, @@ -305,7 +364,6 @@ export function generateDatabaseConfiguration(database) { }; } else if (type === 'couchdb') { return { - // url: `couchdb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5984}/${defaultDatabase}`, privatePort: 5984, environmentVariables: { COUCHDB_PASSWORD: dbUserPassword, @@ -316,18 +374,4 @@ export function generateDatabaseConfiguration(database) { ulimits: {} }; } - // } else if (type === 'clickhouse') { - // return { - // url: `clickhouse://${dbUser}:${dbUserPassword}@${id}:${port}/${defaultDatabase}`, - // privatePort: 9000, - // image: `bitnami/clickhouse-server:${version}`, - // volume: `${id}-${type}-data:/var/lib/clickhouse`, - // ulimits: { - // nofile: { - // soft: 262144, - // hard: 262144 - // } - // } - // } - // } } From fd652bfce6aa18344049e6c01d1690541e1cad2f Mon Sep 17 00:00:00 2001 From: Philip Schmidt Date: Wed, 6 Apr 2022 18:33:02 +0200 Subject: [PATCH 12/46] write args at the beginning of dockerfile and inherit them for each stage --- src/lib/buildPacks/docker.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/lib/buildPacks/docker.ts b/src/lib/buildPacks/docker.ts index 371ffed82..2db5d567c 100644 --- a/src/lib/buildPacks/docker.ts +++ b/src/lib/buildPacks/docker.ts @@ -26,14 +26,17 @@ export default async function ({ if (secrets.length > 0) { secrets.forEach((secret) => { if (secret.isBuildSecret) { - if (pullmergeRequestId) { - if (secret.isPRMRSecret) { - Dockerfile.push(`ARG ${secret.name}=${secret.value}`); - } - } else { - if (!secret.isPRMRSecret) { - Dockerfile.push(`ARG ${secret.name}=${secret.value}`); - } + if ( + (pullmergeRequestId && secret.isPRMRSecret) || + (!pullmergeRequestId && !secret.isPRMRSecret) + ) { + Dockerfile.unshift(`ARG ${secret.name}=${secret.value}`); + + Dockerfile.forEach((line, index) => { + if (line.startsWith('FROM')) { + Dockerfile.splice(index + 1, 0, `ARG ${secret.name}`); + } + }); } } }); From faeae8fd6cf6cc764497edde8b4f2823dac4b8f2 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 19:34:17 +0200 Subject: [PATCH 13/46] Added typings for database/destinations --- src/lib/database/destinations.ts | 93 +++++++++++++++-------- src/lib/types/destinations.ts | 8 ++ src/routes/new/destination/docker.json.ts | 39 +++------- 3 files changed, 79 insertions(+), 61 deletions(-) create mode 100644 src/lib/types/destinations.ts diff --git a/src/lib/database/destinations.ts b/src/lib/database/destinations.ts index 3f3aadec5..b3f9679c4 100644 --- a/src/lib/database/destinations.ts +++ b/src/lib/database/destinations.ts @@ -1,27 +1,48 @@ import { asyncExecShell, getEngine } from '$lib/common'; -import { decrypt, encrypt } from '$lib/crypto'; +import { decrypt } from '$lib/crypto'; import { dockerInstance } from '$lib/docker'; import { startCoolifyProxy } from '$lib/haproxy'; import { getDatabaseImage } from '.'; import { prisma } from './common'; +import type { DestinationDocker, Service, Application, Prisma } from '@prisma/client'; +import type { CreateDockerDestination } from '$lib/types/destinations'; -export async function listDestinations(teamId) { +type DestinationConfigurationObject = { + id: string; + destinationId: string; +}; + +type FindDestinationFromTeam = { + id: string; + teamId: string; +}; + +export async function listDestinations(teamId: string): Promise { return await prisma.destinationDocker.findMany({ where: { teams: { some: { id: teamId } } } }); } -export async function configureDestinationForService({ id, destinationId }) { +export async function configureDestinationForService({ + id, + destinationId +}: DestinationConfigurationObject): Promise { return await prisma.service.update({ where: { id }, data: { destinationDocker: { connect: { id: destinationId } } } }); } -export async function configureDestinationForApplication({ id, destinationId }) { +export async function configureDestinationForApplication({ + id, + destinationId +}: DestinationConfigurationObject): Promise { return await prisma.application.update({ where: { id }, data: { destinationDocker: { connect: { id: destinationId } } } }); } -export async function configureDestinationForDatabase({ id, destinationId }) { +export async function configureDestinationForDatabase({ + id, + destinationId +}: DestinationConfigurationObject): Promise { await prisma.database.update({ where: { id }, data: { destinationDocker: { connect: { id: destinationId } } } @@ -38,13 +59,18 @@ export async function configureDestinationForDatabase({ id, destinationId }) { const host = getEngine(engine); if (type && version) { const baseImage = getDatabaseImage(type); - asyncExecShell( + await asyncExecShell( `DOCKER_HOST=${host} docker pull ${baseImage}:${version} && echo "FROM ${baseImage}:${version}" | docker build --label coolify.image="true" -t "${baseImage}:${version}" -` ); } } } -export async function updateDestination({ id, name, engine, network }) { +export async function updateDestination({ + id, + name, + engine, + network +}: Pick): Promise { return await prisma.destinationDocker.update({ where: { id }, data: { name, engine, network } }); } @@ -54,13 +80,8 @@ export async function newRemoteDestination({ engine, network, isCoolifyProxyUsed, - remoteEngine, - ipAddress, - user, - port, - sshPrivateKey -}) { - const encryptedPrivateKey = encrypt(sshPrivateKey); + remoteEngine +}: CreateDockerDestination): Promise { const destination = await prisma.destinationDocker.create({ data: { name, @@ -68,16 +89,18 @@ export async function newRemoteDestination({ engine, network, isCoolifyProxyUsed, - remoteEngine, - ipAddress, - user, - port, - sshPrivateKey: encryptedPrivateKey + remoteEngine } }); return destination.id; } -export async function newLocalDestination({ name, teamId, engine, network, isCoolifyProxyUsed }) { +export async function newLocalDestination({ + name, + teamId, + engine, + network, + isCoolifyProxyUsed +}: CreateDockerDestination): Promise { const host = getEngine(engine); const docker = dockerInstance({ destinationDocker: { engine, network } }); const found = await docker.engine.listNetworks({ filters: { name: [`^${network}$`] } }); @@ -95,18 +118,14 @@ export async function newLocalDestination({ name, teamId, engine, network, isCoo (destination) => destination.network !== network && destination.isCoolifyProxyUsed === true ); if (proxyConfigured) { - if (proxyConfigured.isCoolifyProxyUsed) { - isCoolifyProxyUsed = true; - } else { - isCoolifyProxyUsed = false; - } + isCoolifyProxyUsed = !!proxyConfigured.isCoolifyProxyUsed; } await prisma.destinationDocker.updateMany({ where: { engine }, data: { isCoolifyProxyUsed } }); } if (isCoolifyProxyUsed) await startCoolifyProxy(engine); return destination.id; } -export async function removeDestination({ id }) { +export async function removeDestination({ id }: Pick): Promise { const destination = await prisma.destinationDocker.delete({ where: { id } }); if (destination.isCoolifyProxyUsed) { const host = getEngine(destination.engine); @@ -123,22 +142,34 @@ export async function removeDestination({ id }) { } } -export async function getDestination({ id, teamId }) { - let destination = await prisma.destinationDocker.findFirst({ +export async function getDestination({ + id, + teamId +}: FindDestinationFromTeam): Promise { + const destination = (await prisma.destinationDocker.findFirst({ where: { id, teams: { some: { id: teamId } } } - }); + })) as DestinationDocker & { sshPrivateKey?: string }; if (destination.remoteEngine) { destination.sshPrivateKey = decrypt(destination.sshPrivateKey); } return destination; } -export async function getDestinationByApplicationId({ id, teamId }) { +export async function getDestinationByApplicationId({ + id, + teamId +}: FindDestinationFromTeam): Promise { return await prisma.destinationDocker.findFirst({ where: { application: { some: { id } }, teams: { some: { id: teamId } } } }); } -export async function setDestinationSettings({ engine, isCoolifyProxyUsed }) { +export async function setDestinationSettings({ + engine, + isCoolifyProxyUsed +}: { + engine: string; + isCoolifyProxyUsed: boolean; +}): Promise { return await prisma.destinationDocker.updateMany({ where: { engine }, data: { isCoolifyProxyUsed } diff --git a/src/lib/types/destinations.ts b/src/lib/types/destinations.ts new file mode 100644 index 000000000..c5a56d772 --- /dev/null +++ b/src/lib/types/destinations.ts @@ -0,0 +1,8 @@ +export type CreateDockerDestination = { + name: string; + engine: string; + remoteEngine: boolean; + network: string; + isCoolifyProxyUsed: boolean; + teamId: string; +}; diff --git a/src/routes/new/destination/docker.json.ts b/src/routes/new/destination/docker.json.ts index 871efe949..f3941e025 100644 --- a/src/routes/new/destination/docker.json.ts +++ b/src/routes/new/destination/docker.json.ts @@ -1,43 +1,22 @@ -import { asyncExecShell, getUserDetails } from '$lib/common'; +import { getUserDetails } from '$lib/common'; import * as db from '$lib/database'; import { ErrorHandler } from '$lib/database'; -import { dockerInstance } from '$lib/docker'; import type { RequestHandler } from '@sveltejs/kit'; +import type { CreateDockerDestination } from '$lib/types/destinations'; export const post: RequestHandler = async (event) => { const { teamId, status, body } = await getUserDetails(event); if (status === 401) return { status, body }; - const { - name, - engine, - network, - isCoolifyProxyUsed, - remoteEngine, - ipAddress, - user, - port, - sshPrivateKey - } = await event.request.json(); + const dockerDestinationProps = { + ...((await event.request.json()) as Omit), + teamId + }; try { - let id = null; - if (remoteEngine) { - id = await db.newRemoteDestination({ - name, - teamId, - engine, - network, - isCoolifyProxyUsed, - remoteEngine, - ipAddress, - user, - port, - sshPrivateKey - }); - } else { - id = await db.newLocalDestination({ name, teamId, engine, network, isCoolifyProxyUsed }); - } + const id = dockerDestinationProps.remoteEngine + ? await db.newRemoteDestination(dockerDestinationProps) + : await db.newLocalDestination(dockerDestinationProps); return { status: 200, body: { id } }; } catch (error) { return ErrorHandler(error); From e042c5cfde6007134a53383860bdadb640dd0697 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 19:45:47 +0200 Subject: [PATCH 14/46] Added types for database/databases --- src/lib/database/databases.ts | 53 +++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/src/lib/database/databases.ts b/src/lib/database/databases.ts index be5ddacd3..6080b5a20 100644 --- a/src/lib/database/databases.ts +++ b/src/lib/database/databases.ts @@ -1,15 +1,21 @@ import { decrypt, encrypt } from '$lib/crypto'; -import * as db from '$lib/database'; import cuid from 'cuid'; import { generatePassword } from '.'; -import { prisma, ErrorHandler } from './common'; -import getPort, { portNumbers } from 'get-port'; +import { prisma } from './common'; import { asyncExecShell, getEngine, removeContainer } from '$lib/common'; +import type { Database, DatabaseSettings, DestinationDocker } from '@prisma/client'; -export async function listDatabases(teamId) { +export async function listDatabases(teamId: string): Promise { return await prisma.database.findMany({ where: { teams: { some: { id: teamId } } } }); } -export async function newDatabase({ name, teamId }) { + +export async function newDatabase({ + name, + teamId +}: { + name: string; + teamId: string; +}): Promise { const dbUser = cuid(); const dbUserPassword = encrypt(generatePassword()); const rootUser = cuid(); @@ -30,7 +36,13 @@ export async function newDatabase({ name, teamId }) { }); } -export async function getDatabase({ id, teamId }) { +export async function getDatabase({ + id, + teamId +}: { + id: string; + teamId: string; +}): Promise { const body = await prisma.database.findFirst({ where: { id, teams: { some: { id: teamId } } }, include: { destinationDocker: true, settings: true } @@ -39,16 +51,22 @@ export async function getDatabase({ id, teamId }) { if (body.dbUserPassword) body.dbUserPassword = decrypt(body.dbUserPassword); if (body.rootUserPassword) body.rootUserPassword = decrypt(body.rootUserPassword); - return { ...body }; + return body; } -export async function removeDatabase({ id }) { +export async function removeDatabase({ id }: { id: string }): Promise { await prisma.databaseSettings.deleteMany({ where: { databaseId: id } }); await prisma.database.delete({ where: { id } }); return; } -export async function configureDatabaseType({ id, type }) { +export async function configureDatabaseType({ + id, + type +}: { + id: string; + type: string; +}): Promise { return await prisma.database.update({ where: { id }, data: { type } @@ -64,7 +82,7 @@ export async function setDatabase({ version?: string; isPublic?: boolean; appendOnly?: boolean; -}) { +}): Promise { return await prisma.database.update({ where: { id }, data: { @@ -82,7 +100,16 @@ export async function updateDatabase({ rootUser, rootUserPassword, version -}) { +}: { + id: string; + name: string; + defaultDatabase: string; + dbUser: string; + dbUserPassword: string; + rootUser: string; + rootUserPassword: string; + version: string; +}): Promise { const encryptedDbUserPassword = dbUserPassword && encrypt(dbUserPassword); const encryptedRootUserPassword = rootUserPassword && encrypt(rootUserPassword); return await prisma.database.update({ @@ -99,7 +126,9 @@ export async function updateDatabase({ }); } -export async function stopDatabase(database) { +export async function stopDatabase( + database: Database & { destinationDocker: DestinationDocker } +): Promise { let everStarted = false; const { id, From b4f98e24a18b0d03b06a6973b18f870f88b7c01d Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 19:56:47 +0200 Subject: [PATCH 15/46] Added types to database/github --- src/lib/database/github.ts | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/lib/database/github.ts b/src/lib/database/github.ts index 339b8e008..182ad4529 100644 --- a/src/lib/database/github.ts +++ b/src/lib/database/github.ts @@ -1,7 +1,15 @@ import { decrypt, encrypt } from '$lib/crypto'; import { prisma } from './common'; +import type { GithubApp } from '@prisma/client'; -export async function addInstallation({ gitSourceId, installation_id }) { +// TODO: We should change installation_id to be camelCase +export async function addInstallation({ + gitSourceId, + installation_id +}: { + gitSourceId: string; + installation_id: string; +}): Promise { const source = await prisma.gitSource.findUnique({ where: { id: gitSourceId }, include: { githubApp: true } @@ -12,8 +20,12 @@ export async function addInstallation({ gitSourceId, installation_id }) { }); } -export async function getUniqueGithubApp({ githubAppId }) { - let body = await prisma.githubApp.findUnique({ where: { id: githubAppId } }); +export async function getUniqueGithubApp({ + githubAppId +}: { + githubAppId: string; +}): Promise { + const body = await prisma.githubApp.findUnique({ where: { id: githubAppId } }); if (body.privateKey) body.privateKey = decrypt(body.privateKey); return body; } @@ -26,7 +38,15 @@ export async function createGithubApp({ pem, webhook_secret, state -}) { +}: { + id: number; + client_id: string; + slug: string; + client_secret: string; + pem: string; + webhook_secret: string; + state: string; +}): Promise { const encryptedClientSecret = encrypt(client_secret); const encryptedWebhookSecret = encrypt(webhook_secret); const encryptedPem = encrypt(pem); From c390f82246d310e4e6bf239722a8934cf6d0b640 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:01:35 +0200 Subject: [PATCH 16/46] Added types to database/gitlab --- src/lib/database/gitlab.ts | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/lib/database/gitlab.ts b/src/lib/database/gitlab.ts index eb9bdfb1b..8bb6a9c9b 100644 --- a/src/lib/database/gitlab.ts +++ b/src/lib/database/gitlab.ts @@ -1,7 +1,14 @@ import { encrypt } from '$lib/crypto'; import { generateSshKeyPair, prisma } from './common'; +import type { GitlabApp } from '@prisma/client'; -export async function updateDeployKey({ id, deployKeyId }) { +export async function updateDeployKey({ + id, + deployKeyId +}: { + id: string; + deployKeyId: number; +}): Promise { const application = await prisma.application.findUnique({ where: { id }, include: { gitSource: { include: { gitlabApp: true } } } @@ -11,14 +18,24 @@ export async function updateDeployKey({ id, deployKeyId }) { data: { deployKeyId } }); } -export async function getSshKey({ id }) { +export async function getSshKey({ + id +}: { + id: string; +}): Promise<{ status: number; body: { publicKey: string } }> { const application = await prisma.application.findUnique({ where: { id }, include: { gitSource: { include: { gitlabApp: true } } } }); return { status: 200, body: { publicKey: application.gitSource.gitlabApp.publicSshKey } }; } -export async function generateSshKey({ id }) { +export async function generateSshKey({ + id +}: { + id: string; +}): Promise< + { status: number; body: { publicKey: string } } | { status: number; body?: undefined } +> { const application = await prisma.application.findUnique({ where: { id }, include: { gitSource: { include: { gitlabApp: true } } } From c4cb92c78dc665cd4733e934a1f019ad54af20ee Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:15:15 +0200 Subject: [PATCH 17/46] Added types for database/gitSource --- src/lib/database/gitSources.ts | 69 +++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/src/lib/database/gitSources.ts b/src/lib/database/gitSources.ts index 927907964..2d165b974 100644 --- a/src/lib/database/gitSources.ts +++ b/src/lib/database/gitSources.ts @@ -1,14 +1,31 @@ import { decrypt, encrypt } from '$lib/crypto'; import { prisma } from './common'; +import type { GithubApp, GitlabApp, GitSource, Prisma, Application } from '@prisma/client'; -export async function listSources(teamId) { +export async function listSources( + teamId: string | Prisma.StringFilter +): Promise<(GitSource & { githubApp?: GithubApp; gitlabApp?: GitlabApp })[]> { return await prisma.gitSource.findMany({ where: { teams: { some: { id: teamId } } }, include: { githubApp: true, gitlabApp: true } }); } -export async function newSource({ name, teamId, type, htmlUrl, apiUrl, organization }) { +export async function newSource({ + name, + teamId, + type, + htmlUrl, + apiUrl, + organization +}: { + name: string; + teamId: string; + type: string; + htmlUrl: string; + apiUrl: string; + organization: string; +}): Promise { return await prisma.gitSource.create({ data: { teams: { connect: { id: teamId } }, @@ -20,7 +37,7 @@ export async function newSource({ name, teamId, type, htmlUrl, apiUrl, organizat } }); } -export async function removeSource({ id }) { +export async function removeSource({ id }: { id: string }): Promise { // TODO: Disconnect application with this sourceId! Maybe not needed? const source = await prisma.gitSource.delete({ where: { id }, @@ -30,8 +47,14 @@ export async function removeSource({ id }) { if (source.gitlabAppId) await prisma.gitlabApp.delete({ where: { id: source.gitlabAppId } }); } -export async function getSource({ id, teamId }) { - let body = await prisma.gitSource.findFirst({ +export async function getSource({ + id, + teamId +}: { + id: string; + teamId: string; +}): Promise { + const body = await prisma.gitSource.findFirst({ where: { id, teams: { some: { id: teamId } } }, include: { githubApp: true, gitlabApp: true } }); @@ -43,27 +66,53 @@ export async function getSource({ id, teamId }) { if (body?.gitlabApp?.appSecret) body.gitlabApp.appSecret = decrypt(body.gitlabApp.appSecret); return body; } -export async function addSource({ id, appId, teamId, oauthId, groupName, appSecret }) { - const encrptedAppSecret = encrypt(appSecret); +export async function addSource({ + id, + appId, + teamId, + oauthId, + groupName, + appSecret +}: { + id: string; + appId: string; + teamId: string; + oauthId: number; + groupName: string; + appSecret: string; +}): Promise { + const encryptedAppSecret = encrypt(appSecret); return await prisma.gitlabApp.create({ data: { teams: { connect: { id: teamId } }, appId, oauthId, groupName, - appSecret: encrptedAppSecret, + appSecret: encryptedAppSecret, gitSource: { connect: { id } } } }); } -export async function configureGitsource({ id, gitSourceId }) { +export async function configureGitsource({ + id, + gitSourceId +}: { + id: string; + gitSourceId: string; +}): Promise { return await prisma.application.update({ where: { id }, data: { gitSource: { connect: { id: gitSourceId } } } }); } -export async function updateGitsource({ id, name }) { +export async function updateGitsource({ + id, + name +}: { + id: string; + name: string; +}): Promise { return await prisma.gitSource.update({ where: { id }, data: { name } From ec3b94cf96467898c190a1dc6299a70e919ba059 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:16:21 +0200 Subject: [PATCH 18/46] added types for database/logs --- src/lib/database/logs.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib/database/logs.ts b/src/lib/database/logs.ts index 9a71f51e4..74f50b50b 100644 --- a/src/lib/database/logs.ts +++ b/src/lib/database/logs.ts @@ -1,6 +1,13 @@ +import type { BuildLog } from '@prisma/client'; import { prisma, ErrorHandler } from './common'; -export async function listLogs({ buildId, last = 0 }) { +export async function listLogs({ + buildId, + last = 0 +}: { + buildId: string; + last: number; +}): Promise { try { const body = await prisma.buildLog.findMany({ where: { buildId, time: { gt: last } }, From 9973197fa52b1a09c4bd51b147c4ebcc26a0dddc Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:23:27 +0200 Subject: [PATCH 19/46] Added types for database/secrets --- src/lib/database/secrets.ts | 69 ++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/src/lib/database/secrets.ts b/src/lib/database/secrets.ts index 835eb4def..2aade4a2f 100644 --- a/src/lib/database/secrets.ts +++ b/src/lib/database/secrets.ts @@ -1,7 +1,8 @@ import { encrypt, decrypt } from '$lib/crypto'; import { prisma } from './common'; +import type { ServiceSecret, Secret, Prisma } from '@prisma/client'; -export async function listServiceSecrets(serviceId: string) { +export async function listServiceSecrets(serviceId: string): Promise { let secrets = await prisma.serviceSecret.findMany({ where: { serviceId }, orderBy: { createdAt: 'desc' } @@ -14,7 +15,7 @@ export async function listServiceSecrets(serviceId: string) { return secrets; } -export async function listSecrets(applicationId: string) { +export async function listSecrets(applicationId: string): Promise { let secrets = await prisma.secret.findMany({ where: { applicationId }, orderBy: { createdAt: 'desc' } @@ -27,20 +28,48 @@ export async function listSecrets(applicationId: string) { return secrets; } -export async function createServiceSecret({ id, name, value }) { +export async function createServiceSecret({ + id, + name, + value +}: { + id: string; + name: string; + value: string; +}): Promise { value = encrypt(value); return await prisma.serviceSecret.create({ data: { name, value, service: { connect: { id } } } }); } -export async function createSecret({ id, name, value, isBuildSecret, isPRMRSecret }) { +export async function createSecret({ + id, + name, + value, + isBuildSecret, + isPRMRSecret +}: { + id: string; + name: string; + value: string; + isBuildSecret: boolean; + isPRMRSecret: boolean; +}): Promise { value = encrypt(value); return await prisma.secret.create({ data: { name, value, isBuildSecret, isPRMRSecret, application: { connect: { id } } } }); } -export async function updateServiceSecret({ id, name, value }) { +export async function updateServiceSecret({ + id, + name, + value +}: { + id: string; + name: string; + value: string; +}): Promise { value = encrypt(value); const found = await prisma.serviceSecret.findFirst({ where: { serviceId: id, name } }); @@ -55,7 +84,19 @@ export async function updateServiceSecret({ id, name, value }) { }); } } -export async function updateSecret({ id, name, value, isBuildSecret, isPRMRSecret }) { +export async function updateSecret({ + id, + name, + value, + isBuildSecret, + isPRMRSecret +}: { + id: string; + name: string; + value: string; + isBuildSecret: boolean; + isPRMRSecret: boolean; +}): Promise { value = encrypt(value); const found = await prisma.secret.findFirst({ where: { applicationId: id, name, isPRMRSecret } }); @@ -71,10 +112,22 @@ export async function updateSecret({ id, name, value, isBuildSecret, isPRMRSecre } } -export async function removeServiceSecret({ id, name }) { +export async function removeServiceSecret({ + id, + name +}: { + id: string; + name: string; +}): Promise { return await prisma.serviceSecret.deleteMany({ where: { serviceId: id, name } }); } -export async function removeSecret({ id, name }) { +export async function removeSecret({ + id, + name +}: { + id: string; + name: string; +}): Promise { return await prisma.secret.deleteMany({ where: { applicationId: id, name } }); } From 008cfdba093a7f0485fb5350461f94c8ad8d7caf Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:30:29 +0200 Subject: [PATCH 20/46] Added types to database/services --- src/lib/database/services.ts | 138 ++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 17 deletions(-) diff --git a/src/lib/database/services.ts b/src/lib/database/services.ts index c5d221e9e..359722bf8 100644 --- a/src/lib/database/services.ts +++ b/src/lib/database/services.ts @@ -1,18 +1,24 @@ -import { asyncExecShell, getEngine } from '$lib/common'; import { decrypt, encrypt } from '$lib/crypto'; +import type { Minio, Service } from '@prisma/client'; import cuid from 'cuid'; import { generatePassword } from '.'; import { prisma } from './common'; -export async function listServices(teamId) { +export async function listServices(teamId: string): Promise { return await prisma.service.findMany({ where: { teams: { some: { id: teamId } } } }); } -export async function newService({ name, teamId }) { +export async function newService({ + name, + teamId +}: { + name: string; + teamId: string; +}): Promise { return await prisma.service.create({ data: { name, teams: { connect: { id: teamId } } } }); } -export async function getService({ id, teamId }) { +export async function getService({ id, teamId }: { id: string; teamId: string }): Promise { const body = await prisma.service.findFirst({ where: { id, teams: { some: { id: teamId } } }, include: { @@ -63,7 +69,13 @@ export async function getService({ id, teamId }) { return { ...body }; } -export async function configureServiceType({ id, type }) { +export async function configureServiceType({ + id, + type +}: { + id: string; + type: string; +}): Promise { if (type === 'plausibleanalytics') { const password = encrypt(generatePassword()); const postgresqlUser = cuid(); @@ -179,56 +191,148 @@ export async function configureServiceType({ id, type }) { }); } } -export async function setServiceVersion({ id, version }) { +export async function setServiceVersion({ + id, + version +}: { + id: string; + version: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { version } }); } -export async function setServiceSettings({ id, dualCerts }) { +export async function setServiceSettings({ + id, + dualCerts +}: { + id: string; + dualCerts: boolean; +}): Promise { return await prisma.service.update({ where: { id }, data: { dualCerts } }); } -export async function updatePlausibleAnalyticsService({ id, fqdn, email, username, name }) { +export async function updatePlausibleAnalyticsService({ + id, + fqdn, + email, + username, + name +}: { + id: string; + fqdn: string; + name: string; + email: string; + username: string; +}): Promise { await prisma.plausibleAnalytics.update({ where: { serviceId: id }, data: { email, username } }); await prisma.service.update({ where: { id }, data: { name, fqdn } }); } -export async function updateService({ id, fqdn, name }) { +export async function updateService({ + id, + fqdn, + name +}: { + id: string; + fqdn: string; + name: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { fqdn, name } }); } -export async function updateLanguageToolService({ id, fqdn, name }) { +export async function updateLanguageToolService({ + id, + fqdn, + name +}: { + id: string; + fqdn: string; + name: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { fqdn, name } }); } -export async function updateMeiliSearchService({ id, fqdn, name }) { +export async function updateMeiliSearchService({ + id, + fqdn, + name +}: { + id: string; + fqdn: string; + name: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { fqdn, name } }); } -export async function updateVaultWardenService({ id, fqdn, name }) { +export async function updateVaultWardenService({ + id, + fqdn, + name +}: { + id: string; + fqdn: string; + name: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { fqdn, name } }); } -export async function updateVsCodeServer({ id, fqdn, name }) { +export async function updateVsCodeServer({ + id, + fqdn, + name +}: { + id: string; + fqdn: string; + name: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { fqdn, name } }); } -export async function updateWordpress({ id, fqdn, name, mysqlDatabase, extraConfig }) { +export async function updateWordpress({ + id, + fqdn, + name, + mysqlDatabase, + extraConfig +}: { + id: string; + fqdn: string; + name: string; + mysqlDatabase: string; + extraConfig: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { fqdn, name, wordpress: { update: { mysqlDatabase, extraConfig } } } }); } -export async function updateMinioService({ id, publicPort }) { +export async function updateMinioService({ + id, + publicPort +}: { + id: string; + publicPort: number; +}): Promise { return await prisma.minio.update({ where: { serviceId: id }, data: { publicPort } }); } -export async function updateGhostService({ id, fqdn, name, mariadbDatabase }) { +export async function updateGhostService({ + id, + fqdn, + name, + mariadbDatabase +}: { + id: string; + fqdn: string; + name: string; + mariadbDatabase: string; +}): Promise { return await prisma.service.update({ where: { id }, data: { fqdn, name, ghost: { update: { mariadbDatabase } } } }); } -export async function removeService({ id }) { +export async function removeService({ id }: { id: string }): Promise { await prisma.meiliSearch.deleteMany({ where: { serviceId: id } }); await prisma.ghost.deleteMany({ where: { serviceId: id } }); await prisma.plausibleAnalytics.deleteMany({ where: { serviceId: id } }); From e9e92c6e9ec933bf96f4b188e25445939a8afa5f Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:31:51 +0200 Subject: [PATCH 21/46] Added types to databse/settings --- src/lib/database/settings.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/database/settings.ts b/src/lib/database/settings.ts index 31d6b3c04..2d0395d88 100644 --- a/src/lib/database/settings.ts +++ b/src/lib/database/settings.ts @@ -1,8 +1,9 @@ import { decrypt } from '$lib/crypto'; import { prisma } from './common'; +import type { Setting } from '@prisma/client'; -export async function listSettings() { - let settings = await prisma.setting.findFirst({}); +export async function listSettings(): Promise { + const settings = await prisma.setting.findFirst({}); if (settings.proxyPassword) settings.proxyPassword = decrypt(settings.proxyPassword); return settings; } From 68f9bca0540b0144f1c604a12a1ef39f85715c8e Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:34:22 +0200 Subject: [PATCH 22/46] Added types to database/teams --- src/lib/database/teams.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/lib/database/teams.ts b/src/lib/database/teams.ts index dd9a14cff..45d8fb5db 100644 --- a/src/lib/database/teams.ts +++ b/src/lib/database/teams.ts @@ -1,9 +1,10 @@ +import type { Team, Permission } from '@prisma/client'; import { prisma } from './common'; -export async function listTeams() { +export async function listTeams(): Promise { return await prisma.team.findMany(); } -export async function newTeam({ name, userId }) { +export async function newTeam({ name, userId }: { name: string; userId: string }): Promise { return await prisma.team.create({ data: { name, @@ -12,7 +13,11 @@ export async function newTeam({ name, userId }) { } }); } -export async function getMyTeams({ userId }) { +export async function getMyTeams({ + userId +}: { + userId: string; +}): Promise<(Permission & { team: Team & { _count: { users: number } } })[]> { return await prisma.permission.findMany({ where: { userId }, include: { team: { include: { _count: { select: { users: true } } } } } From 51a5b3b602e4009580f6fbeab2765838d040811b Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:36:51 +0200 Subject: [PATCH 23/46] Added types to database/users --- src/lib/database/users.ts | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/lib/database/users.ts b/src/lib/database/users.ts index 7e5cc481e..af7d11d3a 100644 --- a/src/lib/database/users.ts +++ b/src/lib/database/users.ts @@ -6,11 +6,26 @@ import { asyncExecShell, uniqueName } from '$lib/common'; import * as db from '$lib/database'; import { startCoolifyProxy } from '$lib/haproxy'; -export async function hashPassword(password: string) { +import type { User } from '@prisma/client'; + +export async function hashPassword(password: string): Promise { const saltRounds = 15; return bcrypt.hash(password, saltRounds); } -export async function login({ email, password, isLogin }) { + +export async function login({ + email, + password, + isLogin +}: { + email: string; + password: string; + isLogin: boolean; +}): Promise<{ + status: number; + headers: { 'Set-Cookie': string }; + body: { userId: string; teamId: string; permission: string; isAdmin: boolean }; +}> { const users = await prisma.user.count(); const userFound = await prisma.user.findUnique({ where: { email }, @@ -52,7 +67,7 @@ export async function login({ email, password, isLogin }) { if (userFound) { if (userFound.type === 'email') { - const passwordMatch = await bcrypt.compare(password, userFound.password); + const passwordMatch = bcrypt.compare(password, userFound.password); if (!passwordMatch) { throw { error: 'Wrong password or email address.' @@ -124,6 +139,6 @@ export async function login({ email, password, isLogin }) { }; } -export async function getUser({ userId }) { +export async function getUser({ userId }: { userId: string }): Promise { return await prisma.user.findUnique({ where: { id: userId } }); } From 8a401f50cbe795c4be60b0bb559b74207e97c91c Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:40:25 +0200 Subject: [PATCH 24/46] Added types for haproxy/configuration --- src/lib/database/users.ts | 2 - src/lib/haproxy/configuration.ts | 248 +++++++++++++++---------------- 2 files changed, 122 insertions(+), 128 deletions(-) diff --git a/src/lib/database/users.ts b/src/lib/database/users.ts index af7d11d3a..9fd46b932 100644 --- a/src/lib/database/users.ts +++ b/src/lib/database/users.ts @@ -1,9 +1,7 @@ import cuid from 'cuid'; import bcrypt from 'bcrypt'; - import { prisma } from './common'; import { asyncExecShell, uniqueName } from '$lib/common'; - import * as db from '$lib/database'; import { startCoolifyProxy } from '$lib/haproxy'; import type { User } from '@prisma/client'; diff --git a/src/lib/haproxy/configuration.ts b/src/lib/haproxy/configuration.ts index a7f223e0e..9fba173fb 100644 --- a/src/lib/haproxy/configuration.ts +++ b/src/lib/haproxy/configuration.ts @@ -1,15 +1,14 @@ import { dev } from '$app/env'; -import got from 'got'; +import got, { type Got } from 'got'; import mustache from 'mustache'; import crypto from 'crypto'; - import * as db from '$lib/database'; import { checkContainer, checkHAProxy } from '.'; import { asyncExecShell, getDomain, getEngine } from '$lib/common'; const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555'; -let template = `program api +const template = `program api command /usr/bin/dataplaneapi -f /usr/local/etc/haproxy/dataplaneapi.hcl --userlist haproxy-dataplaneapi no option start-on-reload @@ -127,7 +126,8 @@ backend {{domain}} server {{id}} {{id}}:{{port}} check fall 10 {{/coolify}} `; -export async function haproxyInstance() { + +export async function haproxyInstance(): Promise { const { proxyPassword } = await db.listSettings(); return got.extend({ prefixUrl: url, @@ -136,31 +136,96 @@ export async function haproxyInstance() { }); } -export async function configureHAProxy() { +export async function configureHAProxy(): Promise { const haproxy = await haproxyInstance(); await checkHAProxy(haproxy); - try { - const data = { - applications: [], - services: [], - coolify: [] - }; - const applications = await db.prisma.application.findMany({ - include: { destinationDocker: true, settings: true } - }); - for (const application of applications) { - const { - fqdn, - id, - port, - destinationDocker, - destinationDockerId, - settings: { previews }, - updatedAt - } = application; - if (destinationDockerId) { - const { engine, network } = destinationDocker; + const data = { + applications: [], + services: [], + coolify: [] + }; + const applications = await db.prisma.application.findMany({ + include: { destinationDocker: true, settings: true } + }); + for (const application of applications) { + const { + fqdn, + id, + port, + destinationDocker, + destinationDockerId, + settings: { previews }, + updatedAt + } = application; + if (destinationDockerId) { + const { engine, network } = destinationDocker; + const isRunning = await checkContainer(engine, id); + if (fqdn) { + const domain = getDomain(fqdn); + const isHttps = fqdn.startsWith('https://'); + const isWWW = fqdn.includes('www.'); + const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`; + if (isRunning) { + data.applications.push({ + id, + port: port || 3000, + domain, + isRunning, + isHttps, + redirectValue, + redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain, + updatedAt: updatedAt.getTime() + }); + } + if (previews) { + const host = getEngine(engine); + const { stdout } = await asyncExecShell( + `DOCKER_HOST=${host} docker container ls --filter="status=running" --filter="network=${network}" --filter="name=${id}-" --format="{{json .Names}}"` + ); + const containers = stdout + .trim() + .split('\n') + .filter((a) => a) + .map((c) => c.replace(/"/g, '')); + if (containers.length > 0) { + for (const container of containers) { + const previewDomain = `${container.split('-')[1]}.${domain}`; + data.applications.push({ + id: container, + port: port || 3000, + domain: previewDomain, + isRunning, + isHttps, + redirectValue, + redirectTo: isWWW ? previewDomain.replace('www.', '') : 'www.' + previewDomain, + updatedAt: updatedAt.getTime() + }); + } + } + } + } + } + } + const services = await db.prisma.service.findMany({ + include: { + destinationDocker: true, + minio: true, + plausibleAnalytics: true, + vscodeserver: true, + wordpress: true, + ghost: true + } + }); + + for (const service of services) { + const { fqdn, id, type, destinationDocker, destinationDockerId, updatedAt } = service; + if (destinationDockerId) { + const { engine } = destinationDocker; + const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type); + if (found) { + const port = found.ports.main; + const publicPort = service[type]?.publicPort; const isRunning = await checkContainer(engine, id); if (fqdn) { const domain = getDomain(fqdn); @@ -168,9 +233,10 @@ export async function configureHAProxy() { const isWWW = fqdn.includes('www.'); const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`; if (isRunning) { - data.applications.push({ + data.services.push({ id, - port: port || 3000, + port, + publicPort, domain, isRunning, isHttps, @@ -179,108 +245,38 @@ export async function configureHAProxy() { updatedAt: updatedAt.getTime() }); } - if (previews) { - const host = getEngine(engine); - const { stdout } = await asyncExecShell( - `DOCKER_HOST=${host} docker container ls --filter="status=running" --filter="network=${network}" --filter="name=${id}-" --format="{{json .Names}}"` - ); - const containers = stdout - .trim() - .split('\n') - .filter((a) => a) - .map((c) => c.replace(/"/g, '')); - if (containers.length > 0) { - for (const container of containers) { - let previewDomain = `${container.split('-')[1]}.${domain}`; - data.applications.push({ - id: container, - port: port || 3000, - domain: previewDomain, - isRunning, - isHttps, - redirectValue, - redirectTo: isWWW ? previewDomain.replace('www.', '') : 'www.' + previewDomain, - updatedAt: updatedAt.getTime() - }); - } - } - } } } } - const services = await db.prisma.service.findMany({ - include: { - destinationDocker: true, - minio: true, - plausibleAnalytics: true, - vscodeserver: true, - wordpress: true, - ghost: true + } + const { fqdn } = await db.prisma.setting.findFirst(); + if (fqdn) { + const domain = getDomain(fqdn); + const isHttps = fqdn.startsWith('https://'); + const isWWW = fqdn.includes('www.'); + const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`; + data.coolify.push({ + id: dev ? 'host.docker.internal' : 'coolify', + port: 3000, + domain, + isHttps, + redirectValue, + redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain + }); + } + const output = mustache.render(template, data); + const newHash = crypto.createHash('md5').update(output).digest('hex'); + const { proxyHash, id } = await db.listSettings(); + if (proxyHash !== newHash) { + await db.prisma.setting.update({ where: { id }, data: { proxyHash: newHash } }); + await haproxy.post(`v2/services/haproxy/configuration/raw`, { + searchParams: { + skip_version: true + }, + body: output, + headers: { + 'Content-Type': 'text/plain' } }); - - for (const service of services) { - const { fqdn, id, type, destinationDocker, destinationDockerId, updatedAt } = service; - if (destinationDockerId) { - const { engine } = destinationDocker; - const found = db.supportedServiceTypesAndVersions.find((a) => a.name === type); - if (found) { - const port = found.ports.main; - const publicPort = service[type]?.publicPort; - const isRunning = await checkContainer(engine, id); - if (fqdn) { - const domain = getDomain(fqdn); - const isHttps = fqdn.startsWith('https://'); - const isWWW = fqdn.includes('www.'); - const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`; - if (isRunning) { - data.services.push({ - id, - port, - publicPort, - domain, - isRunning, - isHttps, - redirectValue, - redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain, - updatedAt: updatedAt.getTime() - }); - } - } - } - } - } - const { fqdn } = await db.prisma.setting.findFirst(); - if (fqdn) { - const domain = getDomain(fqdn); - const isHttps = fqdn.startsWith('https://'); - const isWWW = fqdn.includes('www.'); - const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`; - data.coolify.push({ - id: dev ? 'host.docker.internal' : 'coolify', - port: 3000, - domain, - isHttps, - redirectValue, - redirectTo: isWWW ? domain.replace('www.', '') : 'www.' + domain - }); - } - const output = mustache.render(template, data); - const newHash = crypto.createHash('md5').update(output).digest('hex'); - const { proxyHash, id } = await db.listSettings(); - if (proxyHash !== newHash) { - await db.prisma.setting.update({ where: { id }, data: { proxyHash: newHash } }); - await haproxy.post(`v2/services/haproxy/configuration/raw`, { - searchParams: { - skip_version: true - }, - body: output, - headers: { - 'Content-Type': 'text/plain' - } - }); - } - } catch (error) { - throw error; } } From 18cf57f33cde71b2b14b359cf85fb60dfffddca2 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:47:22 +0200 Subject: [PATCH 25/46] Added types for haproxy/index --- src/lib/haproxy/index.ts | 65 ++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/src/lib/haproxy/index.ts b/src/lib/haproxy/index.ts index c1d65f10c..c0c5bff04 100644 --- a/src/lib/haproxy/index.ts +++ b/src/lib/haproxy/index.ts @@ -1,7 +1,8 @@ import { dev } from '$app/env'; import { asyncExecShell, getEngine } from '$lib/common'; -import got from 'got'; +import got, { type Got, type Response } from 'got'; import * as db from '$lib/database'; +import type { DestinationDocker } from '@prisma/client'; const url = dev ? 'http://localhost:5555' : 'http://coolify-haproxy:5555'; @@ -9,7 +10,7 @@ export const defaultProxyImage = `coolify-haproxy-alpine:latest`; export const defaultProxyImageTcp = `coolify-haproxy-tcp-alpine:latest`; export const defaultProxyImageHttp = `coolify-haproxy-http-alpine:latest`; -export async function haproxyInstance() { +export async function haproxyInstance(): Promise { const { proxyPassword } = await db.listSettings(); return got.extend({ prefixUrl: url, @@ -17,6 +18,7 @@ export async function haproxyInstance() { password: proxyPassword }); } + export async function getRawConfiguration(): Promise { return await (await haproxyInstance()).get(`v2/services/haproxy/configuration/raw`).json(); } @@ -43,11 +45,12 @@ export async function getNextTransactionId(): Promise { return newTransaction.id; } -export async function completeTransaction(transactionId) { +export async function completeTransaction(transactionId: string): Promise> { const haproxy = await haproxyInstance(); return await haproxy.put(`v2/services/haproxy/transactions/${transactionId}`); } -export async function deleteProxy({ id }) { + +export async function deleteProxy({ id }: { id: string }): Promise { const haproxy = await haproxyInstance(); await checkHAProxy(haproxy); @@ -77,11 +80,12 @@ export async function deleteProxy({ id }) { } } -export async function reloadHaproxy(engine) { +export async function reloadHaproxy(engine: string): Promise<{ stdout: string; stderr: string }> { const host = getEngine(engine); return await asyncExecShell(`DOCKER_HOST=${host} docker exec coolify-haproxy kill -HUP 1`); } -export async function checkHAProxy(haproxy?: any) { + +export async function checkHAProxy(haproxy?: Got): Promise { if (!haproxy) haproxy = await haproxyInstance(); try { await haproxy.get('v2/info'); @@ -93,7 +97,10 @@ export async function checkHAProxy(haproxy?: any) { } } -export async function stopTcpHttpProxy(destinationDocker, publicPort) { +export async function stopTcpHttpProxy( + destinationDocker: DestinationDocker, + publicPort: number +): Promise<{ stdout: string; stderr: string } | Error> { const { engine } = destinationDocker; const host = getEngine(engine); const containerName = `haproxy-for-${publicPort}`; @@ -108,7 +115,13 @@ export async function stopTcpHttpProxy(destinationDocker, publicPort) { return error; } } -export async function startTcpProxy(destinationDocker, id, publicPort, privatePort) { + +export async function startTcpProxy( + destinationDocker: DestinationDocker, + id: string, + publicPort: number, + privatePort: number +): Promise<{ stdout: string; stderr: string } | Error> { const { network, engine } = destinationDocker; const host = getEngine(engine); @@ -130,7 +143,13 @@ export async function startTcpProxy(destinationDocker, id, publicPort, privatePo return error; } } -export async function startHttpProxy(destinationDocker, id, publicPort, privatePort) { + +export async function startHttpProxy( + destinationDocker: DestinationDocker, + id: string, + publicPort: number, + privatePort: number +): Promise<{ stdout: string; stderr: string } | Error> { const { network, engine } = destinationDocker; const host = getEngine(engine); @@ -152,7 +171,8 @@ export async function startHttpProxy(destinationDocker, id, publicPort, privateP return error; } } -export async function startCoolifyProxy(engine) { + +export async function startCoolifyProxy(engine: string): Promise { const host = getEngine(engine); const found = await checkContainer(engine, 'coolify-haproxy'); const { proxyPassword, proxyUser, id } = await db.listSettings(); @@ -168,7 +188,8 @@ export async function startCoolifyProxy(engine) { } await configureNetworkCoolifyProxy(engine); } -export async function checkContainer(engine, container) { + +export async function checkContainer(engine: string, container: string): Promise { const host = getEngine(engine); let containerFound = false; @@ -178,7 +199,7 @@ export async function checkContainer(engine, container) { ); const parsedStdout = JSON.parse(stdout); const status = parsedStdout.Status; - const isRunning = status === 'running' ? true : false; + const isRunning = status === 'running'; if (status === 'exited' || status === 'created') { await asyncExecShell(`DOCKER_HOST="${host}" docker rm ${container}`); } @@ -191,7 +212,9 @@ export async function checkContainer(engine, container) { return containerFound; } -export async function stopCoolifyProxy(engine) { +export async function stopCoolifyProxy( + engine: string +): Promise<{ stdout: string; stderr: string } | Error> { const host = getEngine(engine); const found = await checkContainer(engine, 'coolify-haproxy'); await db.setDestinationSettings({ engine, isCoolifyProxyUsed: false }); @@ -208,16 +231,12 @@ export async function stopCoolifyProxy(engine) { } } -export async function configureNetworkCoolifyProxy(engine) { +export async function configureNetworkCoolifyProxy(engine: string): Promise { const host = getEngine(engine); const destinations = await db.prisma.destinationDocker.findMany({ where: { engine } }); - destinations.forEach(async (destination) => { - try { - await asyncExecShell( - `DOCKER_HOST="${host}" docker network connect ${destination.network} coolify-haproxy` - ); - } catch (err) { - // TODO: handle error - } - }); + for (const destination of destinations) { + await asyncExecShell( + `DOCKER_HOST="${host}" docker network connect ${destination.network} coolify-haproxy` + ); + } } From 4505ad37d880ca3c751b7b28d62c665be6bb181a Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:50:04 +0200 Subject: [PATCH 26/46] Added types for importers/github --- src/lib/importers/github.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/lib/importers/github.ts b/src/lib/importers/github.ts index 53754205e..a08fb87b4 100644 --- a/src/lib/importers/github.ts +++ b/src/lib/importers/github.ts @@ -2,11 +2,9 @@ import { asyncExecShell, saveBuildLog } from '$lib/common'; import got from 'got'; import jsonwebtoken from 'jsonwebtoken'; import * as db from '$lib/database'; -import { ErrorHandler } from '$lib/database'; export default async function ({ applicationId, - debug, workdir, githubAppId, repository, @@ -14,7 +12,16 @@ export default async function ({ htmlUrl, branch, buildId -}): Promise { +}: { + applicationId: string; + workdir: string; + githubAppId: string; + repository: string; + apiUrl: string; + htmlUrl: string; + branch: string; + buildId: string; +}): Promise { const url = htmlUrl.replace('https://', '').replace('http://', ''); await saveBuildLog({ line: 'GitHub importer started.', buildId, applicationId }); const { privateKey, appId, installationId } = await db.getUniqueGithubApp({ githubAppId }); From bcacefb8419a33ae02f479df4adc8d2f12e90771 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:50:57 +0200 Subject: [PATCH 27/46] Added types for importers/gitlab --- src/lib/importers/gitlab.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lib/importers/gitlab.ts b/src/lib/importers/gitlab.ts index 81ef54c10..b7eb6d47b 100644 --- a/src/lib/importers/gitlab.ts +++ b/src/lib/importers/gitlab.ts @@ -9,7 +9,16 @@ export default async function ({ branch, buildId, privateSshKey -}): Promise { +}: { + applicationId: string; + workdir: string; + repository: string; + htmlUrl: string; + branch: string; + buildId: string; + repodir: string; + privateSshKey: string; +}): Promise { const url = htmlUrl.replace('https://', '').replace('http://', ''); await saveBuildLog({ line: 'GitLab importer started.', buildId, applicationId }); await asyncExecShell(`echo '${privateSshKey}' > ${repodir}/id.rsa`); From 211aff71705ca6b3940883bdeed0b613ad75afcd Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 20:52:46 +0200 Subject: [PATCH 28/46] Added types for letsencrypt/index --- src/lib/letsencrypt/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/letsencrypt/index.ts b/src/lib/letsencrypt/index.ts index eb74aa252..a3417bb3c 100644 --- a/src/lib/letsencrypt/index.ts +++ b/src/lib/letsencrypt/index.ts @@ -5,7 +5,7 @@ import { dev } from '$app/env'; import cuid from 'cuid'; import getPort, { portNumbers } from 'get-port'; -export async function letsEncrypt(domain, id = null, isCoolify = false) { +export async function letsEncrypt(domain: string, id?: string, isCoolify = false): Promise { try { const data = await db.prisma.setting.findFirst(); const { minPort, maxPort } = data; @@ -96,7 +96,7 @@ export async function letsEncrypt(domain, id = null, isCoolify = false) { } } -export async function generateSSLCerts() { +export async function generateSSLCerts(): Promise { const ssls = []; const applications = await db.prisma.application.findMany({ include: { destinationDocker: true, settings: true }, @@ -129,7 +129,7 @@ export async function generateSSLCerts() { .map((c) => c.replace(/"/g, '')); if (containers.length > 0) { for (const container of containers) { - let previewDomain = `${container.split('-')[1]}.${domain}`; + const previewDomain = `${container.split('-')[1]}.${domain}`; if (isHttps) ssls.push({ domain: previewDomain, id, isCoolify: false }); } } From 76dc7ffb68f6579c31342a6fad278f50c5a824ad Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:01:47 +0200 Subject: [PATCH 29/46] Added types for queues/cleanup --- src/lib/queues/builder.ts | 2 -- src/lib/queues/cleanup.ts | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lib/queues/builder.ts b/src/lib/queues/builder.ts index da0bf95d5..2e788c019 100644 --- a/src/lib/queues/builder.ts +++ b/src/lib/queues/builder.ts @@ -217,9 +217,7 @@ export default async function (job: Job): Promise { const destinationDockers = await prisma.destinationDocker.findMany(); for (const destinationDocker of destinationDockers) { const host = getEngine(destinationDocker.engine); From 78e6a7d1d3793a68c8c5b5d92a0c695e047a2e72 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:03:20 +0200 Subject: [PATCH 30/46] Improved code quality of queues/index --- src/lib/queues/index.ts | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/lib/queues/index.ts b/src/lib/queues/index.ts index 736d76789..21a5b0330 100644 --- a/src/lib/queues/index.ts +++ b/src/lib/queues/index.ts @@ -1,11 +1,8 @@ import * as Bullmq from 'bullmq'; -import { default as ProdBullmq, Job, QueueEvents, QueueScheduler } from 'bullmq'; -import cuid from 'cuid'; +import { default as ProdBullmq, QueueScheduler } from 'bullmq'; import { dev } from '$app/env'; import { prisma } from '$lib/database'; - import builder from './builder'; -import logger from './logger'; import cleanup from './cleanup'; import proxy from './proxy'; import ssl from './ssl'; @@ -28,7 +25,7 @@ const connectionOptions = { } }; -const cron = async () => { +const cron = async (): Promise => { new QueueScheduler('proxy', connectionOptions); new QueueScheduler('cleanup', connectionOptions); new QueueScheduler('ssl', connectionOptions); @@ -89,18 +86,6 @@ const cron = async () => { await queue.ssl.add('ssl', {}, { repeat: { every: dev ? 10000 : 60000 } }); if (!dev) await queue.cleanup.add('cleanup', {}, { repeat: { every: 300000 } }); await queue.sslRenew.add('sslRenew', {}, { repeat: { every: 1800000 } }); - - const events = { - proxy: new QueueEvents('proxy', { ...connectionOptions }), - ssl: new QueueEvents('ssl', { ...connectionOptions }) - }; - - events.proxy.on('completed', (data) => { - // console.log(data) - }); - events.ssl.on('completed', (data) => { - // console.log(data) - }); }; cron().catch((error) => { console.log('cron failed to start'); @@ -157,9 +142,5 @@ buildWorker.on('failed', async (job: Bullmq.Job, failedReason) => { const buildLogQueueName = 'log_queue'; const buildLogQueue = new Queue(buildLogQueueName, connectionOptions); -const buildLogWorker = new Worker(buildLogQueueName, async (job) => await logger(job), { - concurrency: 1, - ...connectionOptions -}); export { buildQueue, buildLogQueue }; From 456b1b8074f23cb6a6480e3c34195331ebe3dbb2 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:04:14 +0200 Subject: [PATCH 31/46] Added types for queues/logger --- src/lib/queues/logger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/queues/logger.ts b/src/lib/queues/logger.ts index 14665b9ad..f751f8d6f 100644 --- a/src/lib/queues/logger.ts +++ b/src/lib/queues/logger.ts @@ -1,7 +1,8 @@ import { prisma } from '$lib/database'; import { dev } from '$app/env'; +import type { Job } from 'bullmq'; -export default async function (job) { +export default async function (job: Job): Promise { const { line, applicationId, buildId } = job.data; if (dev) console.debug(`[${applicationId}] ${line}`); await prisma.buildLog.create({ data: { line, buildId, time: Number(job.id), applicationId } }); From 94da008a473bae4d3709864c0ac25bb3319d9646 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:04:51 +0200 Subject: [PATCH 32/46] Added types for queues/proxy --- src/lib/queues/proxy.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/queues/proxy.ts b/src/lib/queues/proxy.ts index 339e60d60..db8742e74 100644 --- a/src/lib/queues/proxy.ts +++ b/src/lib/queues/proxy.ts @@ -1,7 +1,10 @@ import { ErrorHandler } from '$lib/database'; import { configureHAProxy } from '$lib/haproxy/configuration'; -export default async function () { +export default async function (): Promise { try { return await configureHAProxy(); } catch (error) { From 0358cf2de2f6718523f3099c17b10cb2005fa395 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:05:12 +0200 Subject: [PATCH 33/46] Added types for queues/ssl --- src/lib/queues/ssl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/queues/ssl.ts b/src/lib/queues/ssl.ts index f041153d6..84b608fae 100644 --- a/src/lib/queues/ssl.ts +++ b/src/lib/queues/ssl.ts @@ -1,6 +1,6 @@ import { generateSSLCerts } from '$lib/letsencrypt'; -export default async function () { +export default async function (): Promise { try { return await generateSSLCerts(); } catch (error) { From b44d8578d904db0de6aeef4b92e07d3c118f9fa4 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:05:36 +0200 Subject: [PATCH 34/46] Added types for queues/sslrenewal --- src/lib/queues/sslrenewal.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/lib/queues/sslrenewal.ts b/src/lib/queues/sslrenewal.ts index 807aa34c5..4af5bae64 100644 --- a/src/lib/queues/sslrenewal.ts +++ b/src/lib/queues/sslrenewal.ts @@ -1,13 +1,9 @@ import { asyncExecShell } from '$lib/common'; import { reloadHaproxy } from '$lib/haproxy'; -export default async function () { - try { - await asyncExecShell( - `docker run --rm --name certbot-renewal -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs renew` - ); - await reloadHaproxy('unix:///var/run/docker.sock'); - } catch (error) { - throw error; - } +export default async function (): Promise { + await asyncExecShell( + `docker run --rm --name certbot-renewal -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs renew` + ); + await reloadHaproxy('unix:///var/run/docker.sock'); } From 8212868b92efa542221dce478027af6e39217a59 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:09:15 +0200 Subject: [PATCH 35/46] Added types for api --- src/lib/api.ts | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/lib/api.ts b/src/lib/api.ts index 42fe10a1e..85d4ccf26 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,9 +1,15 @@ -async function send({ method, path, data = {}, headers, timeout = 30000 }) { +async function send({ + method, + path, + data = {}, + headers, + timeout = 30000 +}): Promise> { const controller = new AbortController(); const id = setTimeout(() => controller.abort(), timeout); const opts = { method, headers: {}, body: null, signal: controller.signal }; if (Object.keys(data).length > 0) { - let parsedData = data; + const parsedData = data; for (const [key, value] of Object.entries(data)) { if (value === '') { parsedData[key] = null; @@ -43,18 +49,33 @@ async function send({ method, path, data = {}, headers, timeout = 30000 }) { return responseData; } -export function get(path, headers = {}): Promise { +export function get( + path: string, + headers: Record +): Promise> { return send({ method: 'GET', path, headers }); } -export function del(path, data = {}, headers = {}): Promise { +export function del( + path: string, + data: Record, + headers: Record +): Promise> { return send({ method: 'DELETE', path, data, headers }); } -export function post(path, data, headers = {}): Promise { +export function post( + path: string, + data: Record, + headers: Record +): Promise> { return send({ method: 'POST', path, data, headers }); } -export function put(path, data, headers = {}): Promise { +export function put( + path: string, + data: Record, + headers: Record +): Promise> { return send({ method: 'PUT', path, data, headers }); } From de37ee9f1c2bed7118caf334d9c14f8434125aa4 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:10:37 +0200 Subject: [PATCH 36/46] Added types for crypto --- src/lib/api.ts | 2 ++ src/lib/crypto.ts | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib/api.ts b/src/lib/api.ts index 85d4ccf26..867ed338e 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,3 +1,5 @@ +// TODO: Make this functions generic + async function send({ method, path, diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts index 861a25510..dfb38991f 100644 --- a/src/lib/crypto.ts +++ b/src/lib/crypto.ts @@ -1,13 +1,13 @@ import crypto from 'crypto'; const algorithm = 'aes-256-ctr'; -export const base64Encode = (text: string) => { +export const base64Encode = (text: string): string => { return Buffer.from(text).toString('base64'); }; -export const base64Decode = (text: string) => { +export const base64Decode = (text: string): string => { return Buffer.from(text, 'base64').toString('ascii'); }; -export const encrypt = (text: string) => { +export const encrypt = (text: string): string => { if (text) { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(algorithm, process.env['COOLIFY_SECRET_KEY'], iv); @@ -19,7 +19,7 @@ export const encrypt = (text: string) => { } }; -export const decrypt = (hashString: string) => { +export const decrypt = (hashString: string): string => { if (hashString) { const hash: Hash = JSON.parse(hashString); const decipher = crypto.createDecipheriv( From a17b7a564e18ebc9c152b0939d4ea89a25d1ae1e Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:49:43 +0200 Subject: [PATCH 37/46] Added types for form --- src/lib/form.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/form.ts b/src/lib/form.ts index 08099576d..5a7d65e23 100644 --- a/src/lib/form.ts +++ b/src/lib/form.ts @@ -1,5 +1,6 @@ import { toast } from '@zerodevx/svelte-toast'; -export function errorNotification(message: string) { + +export function errorNotification(message: string): void { console.error(message); if (typeof message !== 'string') { toast.push('Ooops, something is not okay, are you okay?'); @@ -30,7 +31,7 @@ export function enhance( e.preventDefault(); let body = new FormData(form); - let parsedData = body; + const parsedData = body; body.forEach((data, key) => { if (data === '' || data === null) parsedData.delete(key); From be41c0dd0233e4001d2dd28b8a06776f9a0dab9f Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Wed, 6 Apr 2022 21:51:19 +0200 Subject: [PATCH 38/46] Added types for store --- src/lib/store.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib/store.ts b/src/lib/store.ts index d8d1be6ce..42cb12455 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -1,6 +1,7 @@ -import { writable } from 'svelte/store'; +import { writable, type Writable } from 'svelte/store'; -export const gitTokens = writable({ - githubToken: null, - gitlabToken: null -}); +export const gitTokens: Writable<{ githubToken: string | null; gitlabToken: string | null }> = + writable({ + githubToken: null, + gitlabToken: null + }); From 039953588ecfb65b160a9be60c161ed8968f35a0 Mon Sep 17 00:00:00 2001 From: Mads Bram Cordes Date: Fri, 8 Apr 2022 00:11:30 +0200 Subject: [PATCH 39/46] Add tooltip colours to correspond with colour of Icon --- src/routes/__layout.svelte | 22 ++++++++--------- src/tailwind.css | 50 +++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index ce9cd7c0f..17b7723a3 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -171,7 +171,7 @@ {:else if updateStatus.success} - {:else} - {/if}
diff --git a/src/tailwind.css b/src/tailwind.css index 20f67dd73..efdc9a13a 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -209,7 +209,55 @@ a { padding: 8px; color: #fff; content: attr(data-tooltip); - @apply min-w-[100px] rounded bg-coollabs text-center font-normal; + @apply min-w-[100px] rounded text-center font-normal; +} + +/* Base colours for tooltips */ + +/* coollabs - default */ +.tooltip:after, +[data-tooltip]:after { + @apply bg-coollabs; +} + +/* Green 500 */ +.tooltip-green-500:after { + @apply bg-green-500; +} + +/* Orange 500 */ +.tooltip-orange-500:after { + @apply bg-orange-500; +} + +/* Sky 500 */ +.tooltip-sky-500:after { + @apply bg-sky-500; +} + +/* Purple 500 */ +.tooltip-purple-500:after { + @apply bg-purple-500; +} + +/* Pink 500 */ +.tooltip-pink-500:after { + @apply bg-pink-500; +} + +/* Cyan 500 */ +.tooltip-cyan-500:after { + @apply bg-cyan-500; +} + +/* Yellow 500 */ +.tooltip-yellow-500:after { + @apply bg-yellow-500; +} + +/* Red-500 */ +.tooltip-red-500:after { + @apply bg-red-500; } /* Directions */ From f45ab067cefb201912eb89bbb512a4a955b8d881 Mon Sep 17 00:00:00 2001 From: Mads Bram Cordes Date: Mon, 11 Apr 2022 16:58:00 +0200 Subject: [PATCH 40/46] Add fuchsia for `IAM` --- src/routes/__layout.svelte | 2 +- src/tailwind.css | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index 2173c057d..ca6857c70 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -435,7 +435,7 @@ Date: Mon, 11 Apr 2022 20:36:03 +0200 Subject: [PATCH 41/46] fix: Remove unnecessary save button haha --- src/routes/applications/[id]/secrets/index.svelte | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/routes/applications/[id]/secrets/index.svelte b/src/routes/applications/[id]/secrets/index.svelte index 5ca2bbfcb..980e88177 100644 --- a/src/routes/applications/[id]/secrets/index.svelte +++ b/src/routes/applications/[id]/secrets/index.svelte @@ -61,9 +61,6 @@ await refreshSecrets(); toast.push('Secrets saved'); } - function asd() { - console.log(secrets); - }
@@ -164,7 +161,6 @@ -

Paste .env file