From ace373283be390742b7beb46efae881d3203ad78 Mon Sep 17 00:00:00 2001 From: CJ_Clippy Date: Wed, 26 Jun 2024 20:41:16 -0800 Subject: [PATCH] remove cert manager in favor of traefik --- .vscode/settings.json | 8 + Makefile | 42 ++-- README.md | 5 +- charts/fp/Chart.yaml | 7 +- charts/fp/templates/certresolver.yaml.old | 15 -- charts/fp/templates/echo.yaml | 88 +++++++ charts/fp/templates/external-dns.yaml | 82 +++++++ charts/fp/templates/letsencrypt.yaml | 6 +- charts/fp/templates/next.yaml | 104 ++++---- charts/fp/templates/roles.yaml | 2 +- charts/fp/templates/strapi.yaml | 61 +++-- charts/fp/templates/traefik.yaml | 40 +++ charts/fp/values-dev.yaml | 12 +- charts/fp/values-prod.yaml | 1 + ...ert-manager.yaml => cert-manager.yaml.old} | 2 + .../controllers/kube-prometheus-stack.yaml | 2 +- infrastructure/controllers/kustomization.yaml | 2 +- packages/scout/package.json | 3 +- packages/scout/pnpm-lock.yaml | 165 ++++++++++++- packages/scout/src/image.js | 21 +- packages/scout/src/image.spec.js | 10 +- packages/scout/src/utils.js | 4 +- packages/strapi/database/devDb.sh | 1 - scripts/flux-bootstrap-staging.sh | 20 -- ...ux-bootstrap-prod.sh => flux-bootstrap.sh} | 7 +- scripts/k8s-namespaces.sh | 2 - scripts/k8s-secrets.sh | 8 +- t.wip.tiltfile | 231 ++++++++++-------- 28 files changed, 685 insertions(+), 266 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 charts/fp/templates/certresolver.yaml.old create mode 100644 charts/fp/templates/echo.yaml create mode 100644 charts/fp/templates/external-dns.yaml create mode 100644 charts/fp/templates/traefik.yaml rename infrastructure/controllers/{cert-manager.yaml => cert-manager.yaml.old} (92%) delete mode 100755 scripts/flux-bootstrap-staging.sh rename scripts/{flux-bootstrap-prod.sh => flux-bootstrap.sh} (70%) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b6f567b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "yaml.schemas": { + "https://json.schemastore.org/yamllint.json": [ + "file:///home/cj/Documents/futureporn-monorepo/charts/fp/templates/next.yaml", + "file:///home/cj/Documents/futureporn-monorepo/charts/fp/templates/strapi.yaml" + ] + } +} \ No newline at end of file diff --git a/Makefile b/Makefile index 8a81b69..4c45395 100644 --- a/Makefile +++ b/Makefile @@ -1,23 +1,22 @@ -include .env - +ifeq ($(ENV),) +$(error ENV variable is not defined. Please set it to one of development|staging|production) +endif namespaces: ./scripts/k8s-namespaces.sh secrets: - ./scripts/k8s-secrets.sh + dotenvx run -f .env.$(ENV) -- ./scripts/k8s-secrets.sh -flux-prod: - ./scripts/flux-bootstrap-prod.sh -flux-staging: - (cd ./scripts; ./flux-bootstrap-staging.expect) +flux: + ./scripts/flux-bootstrap.sh dev: kind namespaces secrets chisel velero -prod: namespaces secrets velero chisel flux-prod +prod: export ENV=production namespaces secrets velero chisel flux -staging: namespaces secrets velero chisel flux-staging +staging: export ENV=staging namespaces secrets velero chisel flux velero: ./scripts/velero-create.sh @@ -26,23 +25,6 @@ tilt: kind get kubeconfig > ~/.kube/kind.yaml KUBECONFIG=~/.kube/kind.yaml tilt up -f ./t.wip.tiltfile - -define _script -cat <<'EOF' | ctlptl apply -f - -apiVersion: ctlptl.dev/v1alpha1 -kind: Cluster -product: minikube -registry: ctlptl-registry -kubernetesVersion: v1.28.3 -EOF -endef -export script = $(value _script) -minikube: - @ eval "$$script" - minikube addons enable volumesnapshots - minikube addons enable csi-hostpath-driver - minikube addons enable metrics-server - kind: ./scripts/kind-with-local-registry.sh @@ -50,10 +32,12 @@ chisel: ./scripts/k8s-chisel-operator.sh clean: - ./packages/infra/vultr-delete-orphaned-resources.js + kind delete cluster + dotenvx run -f .env.$(ENV) -- node ./packages/infra/vultr-delete-orphaned-resources.js deps: - sudo pamac install make entr nvm minikube kubectl docker helm expect + echo "Some of the install methods for these dependencies are not cross-platform compatible. Some of the install methods are not well-tested. Expect this to fail. Please consult the Makefile for URLs to project sources." + sudo pamac install make entr nvm kubectl docker helm expect curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash echo "go to https://github.com/txn2/kubefwd/releases/latest to get kubefwd" @@ -63,6 +47,8 @@ deps: usermod -aG docker cj newgrp docker curl -OL 'https://github.com/vmware-tanzu/velero/releases/download/v1.13.2/velero-v1.13.2-linux-amd64.tar.gz' + npm install -g @dotenvx/dotenvx + # A gitea act runner which runs locally # https://docs.gitea.com/next/usage/actions/overview diff --git a/README.md b/README.md index 9694d9c..21b498e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # futureporn.net +Source Code for https://futureporn.net + See ./ARCHITECTURE.md for overview -Code for https://futureporn.net ## Jun update todo list -* [ ] bunny support for external-dns +* [x] external-dns gameplan * [ ] traefik well understood * [ ] staging test with *.futureporn.net domains diff --git a/charts/fp/Chart.yaml b/charts/fp/Chart.yaml index 11f6642..31e7dd0 100644 --- a/charts/fp/Chart.yaml +++ b/charts/fp/Chart.yaml @@ -1,9 +1,12 @@ +apiVersion: v1 name: fp description: The Galaxy's Best VTuber Hentai Site -version: 0.0.3 -apiVersion: v1 +version: 0.0.4 keywords: - fp - futureporn + - hentai + - porn + - r18 sources: [] home: 'https://gitea.futureporn.net/futureporn' diff --git a/charts/fp/templates/certresolver.yaml.old b/charts/fp/templates/certresolver.yaml.old deleted file mode 100644 index 539a76e..0000000 --- a/charts/fp/templates/certresolver.yaml.old +++ /dev/null @@ -1,15 +0,0 @@ -# acme.caserver: "{{ .Values.letsencrypt.caServer }}" - - -## traefik certresolver ---- - -# acme.caserver: "{{ .Values.letsencrypt.caServer }}" -## staging -https://acme-staging-v02.api.letsencrypt.org/directory - - - ---- -## production -https://acme-v02.api.letsencrypt.org/directory \ No newline at end of file diff --git a/charts/fp/templates/echo.yaml b/charts/fp/templates/echo.yaml new file mode 100644 index 0000000..ee4f1d0 --- /dev/null +++ b/charts/fp/templates/echo.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: echo + namespace: futureporn +spec: + selector: + matchLabels: + app: echo + template: + metadata: + labels: + app: echo + spec: + containers: + - image: hashicorp/http-echo + name: echo + ports: + - containerPort: 5678 + args: + - -text="Hello, choom!" + +--- +apiVersion: v1 +kind: Service +metadata: + name: echo + namespace: futureporn + annotations: + external-dns.alpha.kubernetes.io/hostname: "{{ .Values.echo.hostname }}" + # chisel-operator.io/exit-node-name: "echo-exit-node" +spec: + selector: + app: echo + type: LoadBalancer + ports: + - protocol: TCP + port: 8001 + targetPort: 5678 + +--- +apiVersion: chisel-operator.io/v1 +kind: ExitNode +metadata: + name: echo-exit-node + namespace: futureporn +spec: + host: "{{ .Values.chisel.exitNodeIp }}" + port: 9090 + auth: chisel + + +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: echo + namespace: futureporn + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web + traefik.ingress.kubernetes.io/router.tls: "false" + traefik.ingress.kubernetes.io/router.tls.certresolver: le +spec: + rules: + - host: "{{ .Values.echo.hostname }}" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: echo + port: + number: 8001 + +# --- +# apiVersion: traefik.io/v1alpha1 +# kind: IngressRoute +# metadata: +# name: echo +# namespace: futureporn +# spec: +# routes: +# - match: Host(`echo.sbtp.xyz`) +# kind: Rule +# services: +# - name: echo +# port: 8001 diff --git a/charts/fp/templates/external-dns.yaml b/charts/fp/templates/external-dns.yaml new file mode 100644 index 0000000..2cfa072 --- /dev/null +++ b/charts/fp/templates/external-dns.yaml @@ -0,0 +1,82 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-dns + namespace: futureporn + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: external-dns +rules: +- apiGroups: [""] + resources: ["services","endpoints","pods"] + verbs: ["get","watch","list"] +- apiGroups: ["extensions","networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get","watch","list"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["list"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: external-dns-viewer +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: external-dns +subjects: +- kind: ServiceAccount + name: external-dns + namespace: futureporn + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: external-dns + namespace: futureporn +spec: + strategy: + type: Recreate + selector: + matchLabels: + app: external-dns + template: + metadata: + labels: + app: external-dns + spec: + serviceAccountName: external-dns + containers: + - name: external-dns + resources: + limits: + memory: "1024Mi" + cpu: "100m" + image: registry.k8s.io/external-dns/external-dns:v0.14.1 + args: + - --source=service + - --source=ingress + - --provider=exoscale + - --domain-filter=.sbtp.xyz + - --policy=sync # if you want DNS entries to get deleted as well + - --txt-owner-id=futureporn + - --exoscale-apizone=de-fra-1 + - --exoscale-apienv=api + env: + - name: EXTERNAL_DNS_EXOSCALE_APIKEY + valueFrom: + secretKeyRef: + name: exoscale + key: apiKey + - name: EXTERNAL_DNS_EXOSCALE_APISECRET + valueFrom: + secretKeyRef: + name: exoscale + key: apiSecret diff --git a/charts/fp/templates/letsencrypt.yaml b/charts/fp/templates/letsencrypt.yaml index 3a83d66..c61d30a 100644 --- a/charts/fp/templates/letsencrypt.yaml +++ b/charts/fp/templates/letsencrypt.yaml @@ -1,4 +1,4 @@ -{{ if eq .Release.Service "Helm" }} +{{ if ne .Values.environment "production" }} apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: @@ -22,8 +22,9 @@ spec: apiKeySecretRef: key: apiKey name: vultr +{{ end }} - +{{ if eq .Values.environment "production" }} --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer @@ -45,5 +46,4 @@ spec: apiKeySecretRef: key: apiKey name: vultr - {{ end }} \ No newline at end of file diff --git a/charts/fp/templates/next.yaml b/charts/fp/templates/next.yaml index 19bcbf0..38795ee 100644 --- a/charts/fp/templates/next.yaml +++ b/charts/fp/templates/next.yaml @@ -1,39 +1,3 @@ -{{ if eq .Values.managedBy "tilt" }} ---- -apiVersion: chisel-operator.io/v1 -kind: ExitNode -metadata: - name: next-exit-node - namespace: futureporn -spec: - host: "{{ .Values.chisel.exitNodeIp }}" - port: 9090 - auth: chisel -{{ end }} - - ---- -apiVersion: v1 -kind: Service -metadata: - name: next - namespace: futureporn - {{ if eq .Values.managedBy "tilt" }} - # create a tunnel to chisel-exit-node (chisel server) - # this allows us to have SSL in development - annotations: - chisel-operator.io/exit-node-name: "next-exit-node" - {{ end }} -spec: - selector: - app.kubernetes.io/name: next - ports: - - name: web - port: 3000 - targetPort: web - protocol: TCP - type: LoadBalancer - --- apiVersion: v1 kind: Pod @@ -56,7 +20,28 @@ spec: restartPolicy: OnFailure -{{ if eq .Release.Service "Helm" }} +--- +apiVersion: v1 +kind: Service +metadata: + name: next + namespace: futureporn + annotations: + external-dns.alpha.kubernetes.io/hostname: "{{ .Values.next.hostname }}" + chisel-operator.io/exit-node-name: "next-exit-node" +spec: + selector: + app.kubernetes.io/name: next + ports: + - name: web + port: 3000 + targetPort: web + protocol: TCP + type: LoadBalancer + + + +{{ if eq .Values.environment "production" }} --- apiVersion: networking.k8s.io/v1 kind: Ingress @@ -66,11 +51,11 @@ metadata: annotations: traefik.ingress.kubernetes.io/router.entrypoints: http traefik.ingress.kubernetes.io/router.tls: "true" - traefik.ingress.kubernetes.io/tls.certresolver: "{{ .Values.next.certResolver }}" + traefik.ingress.kubernetes.io/tls.certresolver: le kubernetes.io/ingress.class: traefik - cert-manager.io/cluster-issuer: "{{ .Values.next.certIssuer }}" + external-dns.alpha.kubernetes.io/hostname: "{{ .Values.next.hostname }}" spec: - ingressClassName: "{{ .Values.next.ingressClassName }}" + ingressClassName: traefik backend: serviceName: next servicePort: 3000 @@ -89,4 +74,41 @@ spec: name: next port: number: 3000 -{{ end }} \ No newline at end of file +{{ end }} + +{{ if eq .Values.environment "development" }} +--- +apiVersion: chisel-operator.io/v1 +kind: ExitNode +metadata: + name: next-exit-node + namespace: futureporn +spec: + host: "{{ .Values.chisel.exitNodeIp }}" + port: 9090 + auth: chisel +{{ end }} + + +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: next + namespace: futureporn + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web + traefik.ingress.kubernetes.io/router.tls: "false" + traefik.ingress.kubernetes.io/router.tls.certresolver: le +spec: + rules: + - host: next.fp.sbtp.xyz + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: next + port: + number: 3000 diff --git a/charts/fp/templates/roles.yaml b/charts/fp/templates/roles.yaml index b8d4834..183ef63 100644 --- a/charts/fp/templates/roles.yaml +++ b/charts/fp/templates/roles.yaml @@ -1,4 +1,4 @@ -{{ if eq .Release.Service "Helm" }} +{{ if eq .Values.environment "development" }} apiVersion: rbac.authorization.k8s.io/v1 kind: Role diff --git a/charts/fp/templates/strapi.yaml b/charts/fp/templates/strapi.yaml index dc07d6a..e3dd84f 100644 --- a/charts/fp/templates/strapi.yaml +++ b/charts/fp/templates/strapi.yaml @@ -1,28 +1,12 @@ -{{ if eq .Values.managedBy "tilt" }} ---- -apiVersion: chisel-operator.io/v1 -kind: ExitNode -metadata: - name: strapi-exit-node - namespace: futureporn -spec: - host: "{{ .Values.chisel.exitNodeIp }}" - port: 9090 - auth: chisel -{{ end }} - --- apiVersion: v1 kind: Service metadata: name: strapi - namespace: futureporn - {{ if eq .Values.managedBy "tilt" }} - # create a tunnel to chisel-exit-node (chisel server) - # this allows us to have SSL in development + namespace: futureporn annotations: + external-dns.alpha.kubernetes.io/hostname: "{{ .Values.strapi.hostname }}" chisel-operator.io/exit-node-name: "strapi-exit-node" - {{ end }} spec: selector: app.kubernetes.io/name: strapi @@ -170,7 +154,6 @@ spec: -{{ if eq .Release.Service "Helm" }} --- apiVersion: networking.k8s.io/v1 kind: Ingress @@ -178,18 +161,19 @@ metadata: name: strapi namespace: futureporn annotations: - sbtp.xyz/managed-by: "{{ .Values.managedBy }}" kubernetes.io/ingress.class: traefik - cert-manager.io/cluster-issuer: "{{ .Values.strapi.certIssuer }}" + traefik.ingress.kubernetes.io/router.entrypoints: web + traefik.ingress.kubernetes.io/router.tls: "false" + traefik.ingress.kubernetes.io/router.tls.certresolver: le spec: ingressClassName: "{{ .Values.strapi.ingressClassName }}" backend: serviceName: strapi servicePort: 1339 - tls: - - secretName: strapi-tls - hosts: - - "{{ .Values.strapi.hostname }}" + # tls: + # - secretName: strapi-tls + # hosts: + # - "{{ .Values.strapi.hostname }}" rules: - host: "{{ .Values.strapi.hostname }}" http: @@ -201,4 +185,31 @@ spec: name: strapi port: number: 1339 + +{{ if eq .Values.environment "development" }} +--- +apiVersion: chisel-operator.io/v1 +kind: ExitNode +metadata: + name: strapi-exit-node + namespace: futureporn +spec: + host: "{{ .Values.chisel.exitNodeIp }}" + port: 9090 + auth: chisel {{ end }} + +# annotations: + +# spec: +# rules: +# - host: echo.sbtp.xyz +# http: +# paths: +# - path: / +# pathType: Prefix +# backend: +# service: +# name: echo +# port: +# number: 8001 \ No newline at end of file diff --git a/charts/fp/templates/traefik.yaml b/charts/fp/templates/traefik.yaml new file mode 100644 index 0000000..a808d6a --- /dev/null +++ b/charts/fp/templates/traefik.yaml @@ -0,0 +1,40 @@ + +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + {{ if eq .Values.environment "development" }} + chisel-operator.io/exit-node-name: "traefik-exit-node" + {{ end }} + name: traefik + namespace: futureporn +spec: + ports: + - name: web + port: 80 + targetPort: web + protocol: TCP + - name: websecure + port: 443 + protocol: TCP + selector: + app.kubernetes.io/name: traefik + app.kubernetes.io/instance: traefik-futureporn + type: LoadBalancer + + + +{{ if eq .Values.environment "development" }} +--- +apiVersion: chisel-operator.io/v1 +kind: ExitNode +metadata: + name: traefik-exit-node + namespace: futureporn +spec: + host: "{{ .Values.chisel.exitNodeIp }}" + port: 9090 + auth: chisel + +{{ end }} \ No newline at end of file diff --git a/charts/fp/values-dev.yaml b/charts/fp/values-dev.yaml index 0bd8cb0..0bd9946 100644 --- a/charts/fp/values-dev.yaml +++ b/charts/fp/values-dev.yaml @@ -1,12 +1,12 @@ +environment: development # storageClassName: csi-hostpath-sc # used by minikube storageClassName: standard # used by Kind -managedBy: tilt link2cid: imageName: fp/link2cid next: imageName: fp/next certIssuer: letsencrypt-staging - hostname: next.futureporn.svc.cluster.local + hostname: next.fp.sbtp.xyz ingressClassName: traefik capture: imageName: fp/capture @@ -24,9 +24,9 @@ scout: strapi: imageName: fp/strapi port: 1339 - url: https://strapi.piko.sbtp.xyz + url: https://strapi.fp.sbtp.xyz certIssuer: letsencrypt-staging - hostname: strapi.futureporn.svc.cluster.local + hostname: strapi.fp.sbtp.xyz ingressClassName: traefik ngrok: hostname: grateful-engaging-cicada.ngrok-free.app @@ -34,4 +34,6 @@ realtime: imageName: fp/realtime adminEmail: cj@futureporn.net chisel: - exitNodeIp: "155.138.254.201" \ No newline at end of file + exitNodeIp: "155.138.254.201" +echo: + hostname: echo.fp.sbtp.xyz \ No newline at end of file diff --git a/charts/fp/values-prod.yaml b/charts/fp/values-prod.yaml index e693819..d09e34f 100644 --- a/charts/fp/values-prod.yaml +++ b/charts/fp/values-prod.yaml @@ -1,3 +1,4 @@ +environment: production storageClassName: vultr-block-storage-hdd link2cid: imageName: gitea.futureporn.net/futureporn/link2cid:latest diff --git a/infrastructure/controllers/cert-manager.yaml b/infrastructure/controllers/cert-manager.yaml.old similarity index 92% rename from infrastructure/controllers/cert-manager.yaml rename to infrastructure/controllers/cert-manager.yaml.old index 85d17e2..63ee890 100644 --- a/infrastructure/controllers/cert-manager.yaml +++ b/infrastructure/controllers/cert-manager.yaml.old @@ -1,3 +1,5 @@ +## DEPRECATED. We are using traefik to get certs + --- apiVersion: v1 kind: Namespace diff --git a/infrastructure/controllers/kube-prometheus-stack.yaml b/infrastructure/controllers/kube-prometheus-stack.yaml index 1cdad5c..53969e1 100644 --- a/infrastructure/controllers/kube-prometheus-stack.yaml +++ b/infrastructure/controllers/kube-prometheus-stack.yaml @@ -55,7 +55,7 @@ spec: service: annotations: - chisel-operator.io/exit-node-name: "grafana-exit-node" + # chisel-operator.io/exit-node-name: "grafana-exit-node" admin: existingSecret: grafana diff --git a/infrastructure/controllers/kustomization.yaml b/infrastructure/controllers/kustomization.yaml index 4c01500..77a8f3c 100644 --- a/infrastructure/controllers/kustomization.yaml +++ b/infrastructure/controllers/kustomization.yaml @@ -2,7 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - external-dns.yaml - - cert-manager.yaml + # - cert-manager.yaml - ingress-traefik.yaml - grafana-k8s-dashboards.yaml - kube-prometheus-stack.yaml \ No newline at end of file diff --git a/packages/scout/package.json b/packages/scout/package.json index 6b6223b..344d4a1 100644 --- a/packages/scout/package.json +++ b/packages/scout/package.json @@ -34,10 +34,11 @@ "imapflow": "^1.0.160", "limiter": "2.0.1", "mailparser": "^3.7.1", + "next": "workspace:*", "node-fetch": "^3.3.0", "nodemon": "^3.1.3", "p-retry": "^5.1.2", - "next": "workspace:*", + "prevvy": "^7.0.1", "qs": "^6.12.1", "sharp": "^0.33.4", "slugify": "^1.6.6", diff --git a/packages/scout/pnpm-lock.yaml b/packages/scout/pnpm-lock.yaml index baa2002..0fb0c70 100644 --- a/packages/scout/pnpm-lock.yaml +++ b/packages/scout/pnpm-lock.yaml @@ -77,6 +77,9 @@ importers: p-retry: specifier: ^5.1.2 version: 5.1.2 + prevvy: + specifier: ^7.0.1 + version: 7.0.1 qs: specifier: ^6.12.1 version: 6.12.1 @@ -88,7 +91,7 @@ importers: version: 1.6.6 ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.5.25)(@types/node@16.9.1)(typescript@5.4.5) + version: 10.9.2(@swc/core@1.5.25)(@types/node@20.14.8)(typescript@5.4.5) tsx: specifier: ^4.7.2 version: 4.15.1 @@ -968,6 +971,9 @@ packages: '@types/node@16.9.1': resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} + '@types/node@20.14.8': + resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==} + '@types/retry@0.12.1': resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==} @@ -1080,6 +1086,9 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + async@0.2.10: + resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -1094,6 +1103,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -1204,6 +1216,10 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + csprng@0.1.2: resolution: {integrity: sha512-D3WAbvvgUVIqSxUfdvLeGjuotsB32bvfVPd+AaaTWMtyUeC9zgCnw5xs94no89yFLVsafvY9dMZEhTwsY/ZecA==} engines: {node: '>=0.6.0'} @@ -1350,6 +1366,10 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + execa@0.10.0: + resolution: {integrity: sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==} + engines: {node: '>=4'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1391,6 +1411,10 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true + fluent-ffmpeg@2.1.3: + resolution: {integrity: sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==} + engines: {node: '>=18'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -1420,6 +1444,10 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + get-stream@3.0.0: + resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} + engines: {node: '>=4'} + get-tsconfig@4.7.5: resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} @@ -1539,10 +1567,17 @@ packages: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} @@ -1618,6 +1653,9 @@ packages: loupe@3.1.1: resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + luxon@1.28.1: + resolution: {integrity: sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==} + mailparser@3.7.1: resolution: {integrity: sha512-RCnBhy5q8XtB3mXzxcAfT1huNqN93HTYYyL6XawlIKycfxM/rXPg9tXoZ7D46+SgCS1zxKzw+BayDQSvncSTTw==} @@ -1667,6 +1705,9 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -1691,6 +1732,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -1704,6 +1749,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -1729,6 +1778,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -1753,6 +1806,9 @@ packages: resolution: {integrity: sha512-uI1ThkzTShNSwvsUM6b4ND8ANzWURk9zTELMztFkmnCQeR/4wkomJ+echHee5GMWGovoSfjwdeu80DsFIt7mbA==} hasBin: true + prevvy@7.0.1: + resolution: {integrity: sha512-SYkduORxa08l8UNQEn6FE0XDSOeNyVqMLhvWkHJ4Q+77HvY8Db8TKCMUnt0K0Xzm6h3lVMWXGuUScpAPBCxFHg==} + process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} @@ -1852,6 +1908,10 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@7.6.2: resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} @@ -1875,6 +1935,14 @@ packages: resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==} engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + shell-quote@1.8.1: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} @@ -1882,6 +1950,9 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -1955,6 +2026,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2079,6 +2154,9 @@ packages: undefsafe@2.0.5: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + unionfs@4.5.4: resolution: {integrity: sha512-qI3RvJwwdFcWUdZz1dWgAyLSfGlY2fS2pstvwkZBUTnkxjcnIvzriBLtqJTKz9FtArAvJeiVCqHlxhOw8Syfyw==} @@ -2138,6 +2216,10 @@ packages: resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} engines: {node: '>=0.8.0'} + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + which@4.0.0: resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} engines: {node: ^16.13.0 || >=18.0.0} @@ -3432,6 +3514,10 @@ snapshots: '@types/node@16.9.1': {} + '@types/node@20.14.8': + dependencies: + undici-types: 5.26.5 + '@types/retry@0.12.1': {} '@webassemblyjs/ast@1.12.1': @@ -3560,6 +3646,8 @@ snapshots: assertion-error@2.0.1: {} + async@0.2.10: {} + atomic-sleep@1.0.0: {} balanced-match@1.0.2: {} @@ -3568,6 +3656,8 @@ snapshots: binary-extensions@2.3.0: {} + bluebird@3.7.2: {} + boolbase@1.0.0: {} bowser@2.11.0: {} @@ -3714,6 +3804,14 @@ snapshots: create-require@1.1.1: {} + cross-spawn@6.0.5: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + csprng@0.1.2: dependencies: sequin: 0.1.1 @@ -3856,6 +3954,16 @@ snapshots: events@3.3.0: {} + execa@0.10.0: + dependencies: + cross-spawn: 6.0.5 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + fast-deep-equal@3.1.3: {} fast-json-stable-stringify@2.1.0: {} @@ -3899,6 +4007,11 @@ snapshots: flat@5.0.2: {} + fluent-ffmpeg@2.1.3: + dependencies: + async: 0.2.10 + which: 1.3.1 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -3924,6 +4037,8 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.2 + get-stream@3.0.0: {} + get-tsconfig@4.7.5: dependencies: resolve-pkg-maps: 1.0.0 @@ -4044,8 +4159,12 @@ snapshots: is-plain-obj@2.1.0: {} + is-stream@1.1.0: {} + is-unicode-supported@0.1.0: {} + isexe@2.0.0: {} + isexe@3.1.1: {} jest-worker@27.5.1: @@ -4119,6 +4238,8 @@ snapshots: dependencies: get-func-name: 2.0.2 + luxon@1.28.1: {} + mailparser@3.7.1: dependencies: encoding-japanese: 2.1.0 @@ -4194,6 +4315,8 @@ snapshots: neo-async@2.6.2: {} + nice-try@1.0.5: {} + node-domexception@1.0.0: {} node-fetch@3.3.2: @@ -4221,6 +4344,10 @@ snapshots: normalize-path@3.0.0: {} + npm-run-path@2.0.2: + dependencies: + path-key: 2.0.1 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -4233,6 +4360,8 @@ snapshots: dependencies: wrappy: 1.0.2 + p-finally@1.0.0: {} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -4262,6 +4391,8 @@ snapshots: path-exists@4.0.0: {} + path-key@2.0.1: {} + pathval@2.0.0: {} peberminta@0.9.0: {} @@ -4291,6 +4422,16 @@ snapshots: sonic-boom: 3.8.1 thread-stream: 2.7.0 + prevvy@7.0.1: + dependencies: + bluebird: 3.7.2 + debug: 4.3.4(supports-color@5.5.0) + execa: 0.10.0 + fluent-ffmpeg: 2.1.3 + luxon: 1.28.1 + transitivePeerDependencies: + - supports-color + process-warning@3.0.0: {} process@0.11.10: {} @@ -4386,6 +4527,8 @@ snapshots: dependencies: parseley: 0.12.1 + semver@5.7.2: {} + semver@7.6.2: {} sequin@0.1.1: {} @@ -4433,6 +4576,12 @@ snapshots: '@img/sharp-win32-ia32': 0.33.4 '@img/sharp-win32-x64': 0.33.4 + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-regex@1.0.0: {} + shell-quote@1.8.1: {} side-channel@1.0.6: @@ -4442,6 +4591,8 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.1 + signal-exit@3.0.7: {} + simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 @@ -4510,6 +4661,8 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-eof@1.0.0: {} + strip-json-comments@3.1.1: {} strnum@1.0.5: {} @@ -4581,14 +4734,14 @@ snapshots: tree-kill@1.2.2: {} - ts-node@10.9.2(@swc/core@1.5.25)(@types/node@16.9.1)(typescript@5.4.5): + ts-node@10.9.2(@swc/core@1.5.25)(@types/node@20.14.8)(typescript@5.4.5): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 16.9.1 + '@types/node': 20.14.8 acorn: 8.11.3 acorn-walk: 8.3.2 arg: 4.1.3 @@ -4622,6 +4775,8 @@ snapshots: undefsafe@2.0.5: {} + undici-types@5.26.5: {} + unionfs@4.5.4: dependencies: fs-monkey: 1.0.6 @@ -4697,6 +4852,10 @@ snapshots: websocket-extensions@0.1.4: {} + which@1.3.1: + dependencies: + isexe: 2.0.0 + which@4.0.0: dependencies: isexe: 3.1.1 diff --git a/packages/scout/src/image.js b/packages/scout/src/image.js index fa085d3..eda7695 100644 --- a/packages/scout/src/image.js +++ b/packages/scout/src/image.js @@ -1,7 +1,8 @@ // import ColorThief from 'colorthief' import sharp from 'sharp' - - +import Prevvy from 'prevvy' +import path from 'path' +import { getTmpFile } from './utils.js'; @@ -13,4 +14,20 @@ export async function getProminentColor(imageFile) { export function rgbToHex(r, g, b) { return "#" + (1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1); +} + + +export async function getStoryboard(imageFileOrUrl) { + let base = path.basename(imageFileOrUrl) + let outputImagePath = getTmpFile(base) + let options = { + input: imageFileOrUrl, + output: outputImagePath, + width: 265, + cols: 5, + rows: 5 + }; + let prevvy = new Prevvy(options) + await prevvy.generate() + return outputImagePath } \ No newline at end of file diff --git a/packages/scout/src/image.spec.js b/packages/scout/src/image.spec.js index 09cbb46..af3167d 100644 --- a/packages/scout/src/image.spec.js +++ b/packages/scout/src/image.spec.js @@ -1,5 +1,5 @@ -import { getProminentColor, rgbToHex } from './image.js' +import { getProminentColor, rgbToHex, getStoryboard } from './image.js' import { expect } from 'chai' import { describe } from 'mocha' import path from 'node:path' @@ -22,4 +22,12 @@ describe('image', function () { expect(rgbToHex(...amaranth)).to.equal('#e34051') }) }) + describe('getStoryboard', function () { + this.timeout(1000*60*15) + it('should accept a URL and return a path to image on disk', async function () { + const url = 'https://futureporn-b2.b-cdn.net/projektmelody-chaturbate-2024-06-25.mp4' + const imagePath = await getStoryboard(url) + expect(imagePath).to.match(/\.png/) + }) + }) }) \ No newline at end of file diff --git a/packages/scout/src/utils.js b/packages/scout/src/utils.js index 9295c1c..40fb11b 100644 --- a/packages/scout/src/utils.js +++ b/packages/scout/src/utils.js @@ -64,4 +64,6 @@ export async function download({ url, filePath }) { } -export const tmpFileRegex = /^\/tmp\/.*\.jpg$/ \ No newline at end of file +export const tmpFileRegex = /^\/tmp\/.*\.jpg$/ + + diff --git a/packages/strapi/database/devDb.sh b/packages/strapi/database/devDb.sh index a293e46..d33e117 100755 --- a/packages/strapi/database/devDb.sh +++ b/packages/strapi/database/devDb.sh @@ -1,6 +1,5 @@ #!/bin/bash -. .env # Check if the containers already exist pgadmin_exists=$(docker ps -a --filter "name=pgadmin" --format '{{.Names}}') diff --git a/scripts/flux-bootstrap-staging.sh b/scripts/flux-bootstrap-staging.sh deleted file mode 100755 index 2f12cd3..0000000 --- a/scripts/flux-bootstrap-staging.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/sh - - - -## this way is annoying because deployment asks for git password -# flux bootstrap git \ -# --kubeconfig /home/cj/.kube/vke.yaml \ -# --url=https://gitea.futureporn.net/futureporn/fp.git \ -# --branch=main \ -# --username=cj_clippy \ -# --token-auth=true \ -# --path=clusters/staging - - -## this way is more automatic although it does ask for yes/no confirmation that the ssh key has repo access -flux bootstrap git \ - --url="ssh://git@gitea.futureporn.net:2222/futureporn/fp" \ - --branch=main \ - --path="clusters/staging" \ - --private-key-file=/home/cj/.ssh/fp-flux diff --git a/scripts/flux-bootstrap-prod.sh b/scripts/flux-bootstrap.sh similarity index 70% rename from scripts/flux-bootstrap-prod.sh rename to scripts/flux-bootstrap.sh index a92698e..ef9fdc5 100644 --- a/scripts/flux-bootstrap-prod.sh +++ b/scripts/flux-bootstrap.sh @@ -1,5 +1,9 @@ #!/bin/bash +if [ -z "$(ENV)" ]; then \ + echo "Error: ENV variable is not defined. Please set to one of development|staging|production"; exit 1; \ +fi + ## this way is annoying because deployment asks for git password # flux bootstrap git \ # --kubeconfig /home/cj/.kube/vke.yaml \ @@ -11,7 +15,8 @@ ## this way is more automatic although it does ask for yes/no confirmation that the ssh key has repo access flux bootstrap git \ + --yes \ --url="ssh://git@gitea.futureporn.net:2222/futureporn/fp" \ --branch=main \ - --path="clusters/production" \ + --path="clusters/$ENV" \ --private-key-file=/home/cj/.ssh/fp-flux \ No newline at end of file diff --git a/scripts/k8s-namespaces.sh b/scripts/k8s-namespaces.sh index 662f3e1..0bf56ef 100755 --- a/scripts/k8s-namespaces.sh +++ b/scripts/k8s-namespaces.sh @@ -1,7 +1,5 @@ #!/bin/bash -source .env - kubectl create namespace cert-manager kubectl create namespace futureporn kubectl create namespace velero diff --git a/scripts/k8s-secrets.sh b/scripts/k8s-secrets.sh index ba4c324..4d176dc 100755 --- a/scripts/k8s-secrets.sh +++ b/scripts/k8s-secrets.sh @@ -1,8 +1,5 @@ #!/bin/bash -source .env - - kubectl --namespace=velero delete secret velero --ignore-not-found ## we do this so helm can adopt our pre-made secret @see https://github.com/helm/helm/pull/7649 @@ -23,6 +20,11 @@ data: aws_secret_access_key: $(echo -n $VELERO_S3_ACCESS_KEY | base64) EOF +# kubectl --namespace futureporn delete secret traefik --ignore-not-found +# kubectl --namespace futureporn create secret generic traefik \ +# --from-literal=username=${TRAEFIK_USERNAME} \ +# --from-literal=password=${TRAEFIK_PASSWORD} + kubectl --namespace futureporn delete secret exoscale --ignore-not-found kubectl --namespace futureporn create secret generic exoscale \ --from-literal=apiKey=${EXOSCALE_API_KEY} \ diff --git a/t.wip.tiltfile b/t.wip.tiltfile index 957d009..52f8ca5 100644 --- a/t.wip.tiltfile +++ b/t.wip.tiltfile @@ -1,12 +1,16 @@ # Tiltfile for working with Next and Strapi locally - +## cert-manager slows down Tilt updates so I prefer to keep it commented unless I specifically need to test certs # load('ext://cert_manager', 'deploy_cert_manager') -# deploy_cert_manager() -load('ext://dotenv', 'dotenv') -dotenv(fn='.env') +# deploy_cert_manager( +# load_to_kind=True, +# # registry='localhost:5001' +# ) + default_registry('localhost:5001') load('ext://helm_remote', 'helm_remote') +# load('ext://dotenv', 'dotenv') +# dotenv(fn='.env') # allow_k8s_contexts('vke-e41885d3-7f93-4f01-bfaa-426f20bf9f3f') @@ -41,34 +45,23 @@ load('ext://helm_remote', 'helm_remote') # ) helm_remote( - 'temporal', - repo_name='temporal', - repo_url='https://charts.lemontech.engineering', + 'traefik', + repo_name='traefik', + repo_url='https://traefik.github.io/charts', namespace='futureporn', - version='0.37.0', + version='28.3.0', set=[ - 'admintools.image.tag=1.24.1-tctl-1.18.1-cli-0.12.0', - 'web.image.tag=2.27.2', - 'prometheus.enabled=false', - 'grafana.enabled=false', - 'elasticsearch.enabled=false', - 'web.config.auth.enabled=true', - 'cassandra.enabled=false', - 'server.config.persistence.default.driver=sql', - 'server.config.persistence.default.sql.driver=postgres12', - 'server.config.persistence.default.sql.host=%s' % os.getenv('POSTGRES_HOST'), - 'server.config.persistence.default.sql.port=5432', - 'server.config.persistence.default.sql.user=%s' % os.getenv('POSTGRES_USER'), - 'server.config.persistence.default.sql.password=%s' % os.getenv('POSTGRES_PASSWORD'), - 'server.config.persistence.visibility.driver=sql', - 'server.config.persistence.visibility.sql.driver=postgres12', - 'server.config.persistence.visibility.sql.host=%s' % os.getenv('POSTGRES_HOST'), - 'server.config.persistence.visibility.sql.port=5432', - 'server.config.persistence.visibility.sql.user=%s' % os.getenv('POSTGRES_USER'), - 'server.config.persistence.visibility.sql.password=%s' % os.getenv('POSTGRES_PASSWORD'), + 'globalArguments[0]=--global.sendanonymoususage=false', + 'globalArguments[1]=--certificatesresolvers.le.acme.email=cj@futureporn.net', + 'globalArguments[2]=--certificatesresolvers.le.acme.storage=/data/acme.json', + 'globalArguments[3]=--certificatesresolvers.le.acme.tlschallenge=true', + 'globalArguments[4]=--certificatesresolvers.le.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory', + 'service.enabled=false', + 'logs.access.enabled=true' ] ) + # helm_remote( # 'nitter', # repo_name='truecharts', @@ -206,7 +199,7 @@ docker_build( dockerfile='d.next.dockerfile', target='dev', build_args={ - 'NEXT_PUBLIC_STRAPI_URL': 'https://strapi.piko.sbtp.xyz' + 'NEXT_PUBLIC_STRAPI_URL': 'https://strapi.fp.sbtp.xyz' }, live_update=[ sync('./packages/next', '/app') @@ -260,15 +253,15 @@ docker_build( # workload='frp-operator-controller-manager', # labels='tunnel' # ) -# k8s_resource( -# workload='echo-deployment', -# port_forwards=['8080'], -# links=[ -# link('https://echo.piko.sbtp.xyz'), -# link('http://echo.futureporn.svc.cluster.local:8080') -# ], -# labels='debug' -# ) +k8s_resource( + workload='echo', + port_forwards=['8080'], + links=[ + link('https://echo.fp.sbtp.xyz'), + link('http://echo.futureporn.svc.cluster.local:8001') + ], + labels='debug' +) # k8s_resource( # workload='snake', # port_forwards=['8080'], @@ -284,7 +277,7 @@ k8s_resource( workload='next', port_forwards=['3000'], links=[ - link('https://next.piko.sbtp.xyz'), + link('https://next.fp.sbtp.xyz'), ], resource_deps=['strapi', 'postgres'] ) @@ -293,29 +286,25 @@ k8s_resource( port_forwards=['1339'], links=[ link('http://localhost:1339/admin'), - link('https://strapi.piko.sbtp.xyz'), + link('https://strapi.fp.sbtp.xyz'), ], resource_deps=['postgres'] ) -# k8s_resource( -# workload='strapi-app', -# port_forwards=['1338'] -# ) k8s_resource( workload='postgres', port_forwards=['5432'] ) -k8s_resource( - workload='scout-worker', - resource_deps=['postgres', 'strapi', 'temporal-frontend', 'scout-manager'] -) +# k8s_resource( +# workload='scout-worker', +# resource_deps=['postgres', 'strapi', 'temporal-frontend', 'scout-manager'] +# ) -k8s_resource( - workload='scout-manager', - resource_deps=['postgres', 'strapi', 'temporal-frontend'] -) +# k8s_resource( +# workload='scout-manager', +# resource_deps=['postgres', 'strapi', 'temporal-frontend'] +# ) # k8s_resource( # workload='pgadmin', @@ -329,59 +318,87 @@ k8s_resource( # ) -k8s_resource( - workload='temporal-admintools', - labels='temporal', - resource_deps=[ - 'postgres', - 'strapi' - ]) -k8s_resource( - workload='temporal-frontend', - labels='temporal', port_forwards=['7233'], - resource_deps=[ - 'postgres', - 'strapi' - ]) -k8s_resource( - workload='temporal-history', - labels='temporal', - resource_deps=[ - 'postgres', - 'strapi' - ]) -k8s_resource( - workload='temporal-worker', - labels='temporal', - resource_deps=[ - 'postgres', - 'strapi' - ]) -k8s_resource( - workload='temporal-web', - labels='temporal', port_forwards=['8080'], - resource_deps=[ - 'postgres', - 'strapi' - ]) -k8s_resource( - workload='temporal-schema-setup', - labels='temporal', - resource_deps=[ - 'postgres', - 'strapi' - ]) -k8s_resource( - workload='temporal-schema-update', - labels='temporal', - resource_deps=[ - 'postgres', - 'strapi' - ]) -k8s_resource( - workload='temporal-matching', - labels='temporal', - resource_deps=[ - 'postgres', - 'strapi' - ]) \ No newline at end of file +# helm_remote( +# 'temporal', +# repo_name='temporal', +# repo_url='https://charts.lemontech.engineering', +# namespace='futureporn', +# version='0.37.0', +# set=[ +# 'admintools.image.tag=1.24.1-tctl-1.18.1-cli-0.12.0', +# 'web.image.tag=2.27.2', +# 'prometheus.enabled=false', +# 'grafana.enabled=false', +# 'elasticsearch.enabled=false', +# 'web.config.auth.enabled=true', +# 'cassandra.enabled=false', +# 'server.config.persistence.default.driver=sql', +# 'server.config.persistence.default.sql.driver=postgres12', +# 'server.config.persistence.default.sql.host=%s' % os.getenv('POSTGRES_HOST'), +# 'server.config.persistence.default.sql.port=5432', +# 'server.config.persistence.default.sql.user=%s' % os.getenv('POSTGRES_USER'), +# 'server.config.persistence.default.sql.password=%s' % os.getenv('POSTGRES_PASSWORD'), +# 'server.config.persistence.visibility.driver=sql', +# 'server.config.persistence.visibility.sql.driver=postgres12', +# 'server.config.persistence.visibility.sql.host=%s' % os.getenv('POSTGRES_HOST'), +# 'server.config.persistence.visibility.sql.port=5432', +# 'server.config.persistence.visibility.sql.user=%s' % os.getenv('POSTGRES_USER'), +# 'server.config.persistence.visibility.sql.password=%s' % os.getenv('POSTGRES_PASSWORD'), +# ] +# ) +# k8s_resource( +# workload='temporal-admintools', +# labels='temporal', +# resource_deps=[ +# 'postgres', +# 'strapi' +# ]) +# k8s_resource( +# workload='temporal-frontend', +# labels='temporal', port_forwards=['7233'], +# resource_deps=[ +# 'postgres', +# 'strapi' +# ]) +# k8s_resource( +# workload='temporal-history', +# labels='temporal', +# resource_deps=[ +# 'postgres', +# 'strapi' +# ]) +# k8s_resource( +# workload='temporal-worker', +# labels='temporal', +# resource_deps=[ +# 'postgres', +# 'strapi' +# ]) +# k8s_resource( +# workload='temporal-web', +# labels='temporal', port_forwards=['8080'], +# resource_deps=[ +# 'postgres', +# 'strapi' +# ]) +# k8s_resource( +# workload='temporal-schema-setup', +# labels='temporal', +# resource_deps=[ +# 'postgres', +# 'strapi' +# ]) +# k8s_resource( +# workload='temporal-schema-update', +# labels='temporal', +# resource_deps=[ +# 'postgres', +# 'strapi' +# ]) +# k8s_resource( +# workload='temporal-matching', +# labels='temporal', +# resource_deps=[ +# 'postgres', +# 'strapi' +# ])