carboneio / carbone

Fast and simple report generator, from JSON to pdf, xslx, docx, odt...
https://carbone.io
Other
1.3k stars 190 forks source link

[Feature Request]: FS permissions for persistent volumes on Kubernetes #202

Open graycrow opened 6 months ago

graycrow commented 6 months ago

Environment Carbone Version: Carbone On-Premise: v4.20.0 (5.15.0-1056-azure #64-Ubuntu SMP Tue Feb 6 19:23:34 UTC 2024 x86_64 GNU/Linux)

Problem to solve In my containerized environment (Azure Kubernetes cluster), a permanent storage volume is attached to a pod running a carbone-ee container with the FS owner set to root:root. I'm not sure about other clouds or docker installations, but I think this is the default. As a result, the carbone server running as carbone:nogroup has no write access to the app/render and app/template directories. This is a listing of the `app' directory:

total 67256
drwxr-xr-x 1 carbone nogroup     4096 Mar 10 16:29 .
drwxr-xr-x 1 root    root        4096 Mar 10 16:23 ..
-rw------- 1 carbone nogroup       67 Mar 10 16:29 .bash_history
drwxr-xr-x 1 carbone nogroup     4096 Mar 10 16:23 .cache
drwx------ 2 carbone nogroup     4096 Mar 10 16:23 .config
drwxr-x--- 2 carbone nogroup     4096 Mar 10 16:23 asset
-rwxr-xr-x 1 carbone nogroup 68819919 Mar  1 15:51 carbone-ee-linux
drwxr-xr-x 1 carbone nogroup     4096 Mar 10 16:23 config
drwxr-xr-x 2 carbone nogroup     4096 Mar  1 15:52 plugin
drwxr-x--- 2 carbone nogroup     4096 Mar 10 16:23 queue
drwxr-xr-x 3 root    root        4096 Mar 10 16:23 render
drwxr-xr-x 3 root    root        4096 Mar 10 16:23 template

And the server is complaining about it:

Carbone On-Premise: v4.20.0
- Publication date (UTC): 2024-02-26T14:00:43.930Z
- Proprietary software made by CarboneIO SAS - France - 899 106 785 00012
- Process ID: 7
- Licensee: 
  - name       : [redacted]
  - expired at : 2024-04-07T08:48:43.000Z
  - address    : undefined
  - email      : [redacted]
  - plan       : trial

Carbone: Starting server...

Authentication is on
Studio is on
Carbone webserver is started and listens on port 4000
Keys generated
LibreOffice converter is ready
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Automatic clean of /app/render
Automatic clean directory error:  Error: Command failed: find /app/render -type f -mmin +50 -delete;
find: ‘/app/render/lost+found’: Permission denied

    at ChildProcess.exithandler (node:child_process:422:12)
    at ChildProcess.emit (node:events:517:28)
    at maybeClose (node:internal/child_process:1098:16)
    at ChildProcess._handle.onexit (node:internal/child_process:303:5) {
  code: 1,
  killed: false,
  signal: null,
  cmd: 'find /app/render -type f -mmin +50 -delete;'
} find: ‘/app/render/lost+found’: Permission denied

Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk
Internal self-check status error:  Cannot write rendered file on disk

Proposed solution Now, is it too much to ask to have carbone run on behalf of root:root? ;) Or it's a good idea to mention this issue in the documentation.

Describe alternatives you've considered I've found that it is possible to set the fsGroup field in the security context of the deployment specification. The fsGroup field is a special supplemental group that applies to all containers in the pod. This group ID is added to the container's supplemental groups. The volume will then be owned by this group and will have permissions set accordingly. So I fixed it by modifying my deployment settings (see below) to set fsGroup to 65534, which is the id of the group to which carbone user belongs. This solution works as long as the group id is the same. Maybe it's worth to add this to documentation?

apiVersion: v1
kind: Service
metadata:
  name: carbone-service
spec:
  selector:
    app: carbone
  ports:
    - protocol: TCP
      port: 4000
      targetPort: 4000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: carbone-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: carbone
  template:
    metadata:
      labels:
        app: carbone
    spec:
      securityContext:
        fsGroup: 65534
      containers:
        - name: carbone
          image: carbone/carbone-ee:latest
          ports:
            - containerPort: 4000
          env:
            - name: CARBONE_EE_PORT
              value: "4000"
            - name: CARBONE_EE_STUDIO
              value: "true"
            - name: CARBONE_EE_AUTHENTICATION
              value: "true"
            - name: CARBONE_EE_LICENSE
              valueFrom:
                secretKeyRef:
                  name: carbone-secret
                  key: carbone-license
            - name: LANG
              value: "C.UTF-8"
          volumeMounts:
            - name: carbone-templates-volume
              mountPath: /app/template
            - name: carbone-renders-volume
              mountPath: /app/render
      volumes:
        - name: carbone-templates-volume
          persistentVolumeClaim:
            claimName: carbone-templates-storage
        - name: carbone-renders-volume
          persistentVolumeClaim:
            claimName: carbone-renders-storage