thor0215 / hassio-xfinity-usage

Fetch Xfinity Internet Service Usage Data and publish it to Home Assistant sensor
Apache License 2.0
11 stars 3 forks source link

Improve the usage of the addon by non-hassio consumers (docker and kubernetes) #36

Closed csobrinho closed 4 weeks ago

csobrinho commented 2 months ago

Hi @thor0215, I'm planning to send you a PR to make the code a little easier to be used by external docker or kubernetes. This would translate into:

  1. bypass the run.sh and instead jump right into the xfinity_usage_addon.py with the right environment variables. Alternative would be a new environment variable named MANUAL or BYPASS or something else that allows the run.sh to just bypass all HA/bashio code.
  2. define an extra docker volume for the browser persistent shared storage (not sure if your plan is to support this or not so let me know)
  3. allow oneshot/no pooling. Kubernetes already has a strong CronJob subsystem so it's better to just have it reschedule a new run if needed (backoffPolicy) but also when it runs. We could for instance say, run every 30m but only from hour x to y. Kubernetes also allows the definition of a total deadline.
  4. potentially run the image without root.
  5. precreate the /config/xfinity.log log file if it doesn't exist.

Example of a kubernetes cronjob:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: xfinity-usage
  namespace: tools
spec:
  schedule: "0/30 * * * *"
  concurrencyPolicy: Forbid
  failedJobsHistoryLimit: 3
  successfulJobsHistoryLimit: 1
  startingDeadlineSeconds: 360 # 6 min
  jobTemplate:
    spec:
      backoffLimit: 0 # Don't retry.
      template:
        spec:
          initContainers:
            - name: create-log
              image: busybox
              command: ["touch", "/config/xfinity.log"] # Create the log file.
              volumeMounts:
                - mountPath: /config
                  name: config
          containers:
            - name: xfinity-usage
              image: ghcr.io/thor0215/hassio-xfinity-usage-aarch64:0.0.12.7.2.2@sha256:897360c2f9e8e85d040f6da18ae11c1b524f80dec5c40b703e717df69272bba9
              imagePullPolicy: IfNotPresent
              command: ["/bin/bash"]
              args: ["-c", "python3 -Wignore xfinity_usage_addon.py || true"] # Always return true while oneshot mode is not supported.
              resources:
                limits:
                  memory: 4Gi
                  cpu: 1000m
                requests:
                  memory: 2Gi
                  cpu: 200m
              env:
                - name: TZ
                  value: America/Los_Angeles
                - name: POLLING_RATE
                  value: "3600"
                - name: PAGE_TIMEOUT
                  value: "60"
                - name: LOGLEVEL
                  value: "debug_support" # Abuse debug_support to support oneshot mode.
                - name: MQTT_SERVICE
                  value: "true"
                - name: MQTT_USERNAME
                  valueFrom:
                    secretKeyRef:
                      key: MQTT_USERNAME
                      name: xfinity-usage-secret
                - name: MQTT_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      key: MQTT_PASSWORD
                      name: xfinity-usage-secret
                - name: MQTT_HOST
                  value: "mqtt.example.com"
                - name: MQTT_PORT
                  value: "443" # Or 1883 for unencrypted mqtt.
                - name: XFINITY_USERNAME
                  valueFrom:
                    secretKeyRef:
                      key: XFINITY_USERNAME
                      name: xfinity-usage-secret
                - name: XFINITY_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      key: XFINITY_PASSWORD
                      name: xfinity-usage-secret
              volumeMounts:
                - mountPath: /config
                  name: config
          volumes:
            - emptyDir:
                medium: Memory
                sizeLimit: 1Gi
              name: config
          restartPolicy: Never
          securityContext:
            runAsNonRoot: false
thor0215 commented 1 month ago

I am making some changes to that the HA bashio part of the run script runs if it detects bashio it will execute the bashio code. I'm not sure if I fully understand the non-root request. Would you need the dockerfile to be something like this: Do all the system stuff as root then add the non-root user and run the script as non-root?

apt-get blah blah setup non-root user USER non-root RUN shell script

I also made adjusts to the python script so that polling only happens in a bashio environment.

Take a look at my run.sh script I'm upload to the branch for this issue and let me know your thoughts on everything.

thor0215 commented 1 month ago

Let me know if you want to keep this open or if the last few releases address most of your issues.

derp90 commented 1 month ago

@thor0215 Was there an env var created to address the first point?

csobrinho commented 1 month ago

Let me know if you want to keep this open or if the last few releases address most of your issues.

Sorry, I've been swamped. I'll test this during the weekend.

thor0215 commented 1 month ago

@thor0215 Was there an env var created to address the first point?

The Dockerfile still has CMD ["/run.sh" ]. I don't know how to make the Dockerfile only do that for HA Addon setups. If someone has some way to do that, let me know.

csobrinho commented 1 month ago

The easiest way is to put that logic inside the /run.sh then just do if hassio do X, if not do Y. There might be some sort of env variable that hint to being inside hassio before calling hassio shell scripts.

Another option is to have a new entrypoint.sh, do the check there then call run_hassio.sh or run_standalone.sh but your run.sh is pretty simple so that might be overkill.

thor0215 commented 1 month ago

So right now run.sh should only do the HA stuff if it sees the /config/options.json file, but always run the python script. Does that solve request number 1?

csobrinho commented 1 month ago

I think so, you can also complement with the env. There's should be something there to say I'm HA. Thanks for looking into this!