From 75d88fbfad82ec0e737e579bbe329d8e54c17dc5 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Fri, 20 Jun 2025 09:43:17 -0400 Subject: [PATCH 01/21] Adding ENV[TIMEOUT] for Uptime-Kuma mod. --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index ff45813f..83f45dde 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -33,7 +33,7 @@ def connect(self, url, username, password): ) return False - self.api = UptimeKumaApi(url) + self.api = UptimeKumaApi(url, ENV[TIMEOUT]) self.api.login(username, password) return True From a06c1d7c2d9c9235e9c13c777def9b5257a47cc1 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Fri, 20 Jun 2025 10:41:53 -0400 Subject: [PATCH 02/21] Changing pipeline for testing. --- .github/workflows/BuildImage.yml | 90 ++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/.github/workflows/BuildImage.yml b/.github/workflows/BuildImage.yml index 37850f08..8d7545fe 100644 --- a/.github/workflows/BuildImage.yml +++ b/.github/workflows/BuildImage.yml @@ -1,49 +1,61 @@ name: Build Image -on: [push, pull_request_target, workflow_dispatch] +on: [push, pull_request, workflow_dispatch] env: - GITHUB_REPO: "linuxserver/docker-mods" #don't modify - ENDPOINT: "linuxserver/mods" #don't modify - BASEIMAGE: "swag" #replace - MODNAME: "auto-uptime-kuma" #replace - MULTI_ARCH: "false" #set to false if not needed + ENDPOINT: "TrezOne/swag-auto-uptime-kuma" + BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" jobs: - set-vars: + build: runs-on: ubuntu-latest steps: - - name: Set Vars - id: outputs + - uses: actions/checkout@v3 + + - name: Build image run: | - echo "GITHUB_REPO=${{ env.GITHUB_REPO }}" >> $GITHUB_OUTPUT - echo "ENDPOINT=${{ env.ENDPOINT }}" >> $GITHUB_OUTPUT - echo "BASEIMAGE=${{ env.BASEIMAGE }}" >> $GITHUB_OUTPUT - echo "MODNAME=${{ env.MODNAME }}" >> $GITHUB_OUTPUT - echo "MULTI_ARCH=${{ env.MULTI_ARCH }}" >> $GITHUB_OUTPUT - # **** If the mod needs to be versioned, set the versioning logic below. Otherwise leave as is. **** - MOD_VERSION="" - echo "MOD_VERSION=${MOD_VERSION}" >> $GITHUB_OUTPUT - outputs: - GITHUB_REPO: ${{ steps.outputs.outputs.GITHUB_REPO }} - ENDPOINT: ${{ steps.outputs.outputs.ENDPOINT }} - BASEIMAGE: ${{ steps.outputs.outputs.BASEIMAGE }} - MODNAME: ${{ steps.outputs.outputs.MODNAME }} - MULTI_ARCH: ${{ steps.outputs.outputs.MULTI_ARCH }} - MOD_VERSION: ${{ steps.outputs.outputs.MOD_VERSION }} + docker build --no-cache -t ${{ github.sha }} . - build: - uses: linuxserver/github-workflows/.github/workflows/docker-mod-builder.yml@v1 - needs: set-vars - secrets: - CR_USER: ${{ secrets.CR_USER }} - CR_PAT: ${{ secrets.CR_PAT }} - DOCKERUSER: ${{ secrets.DOCKERUSER }} - DOCKERPASS: ${{ secrets.DOCKERPASS }} - with: - GITHUB_REPO: ${{ needs.set-vars.outputs.GITHUB_REPO }} - ENDPOINT: ${{ needs.set-vars.outputs.ENDPOINT }} - BASEIMAGE: ${{ needs.set-vars.outputs.BASEIMAGE }} - MODNAME: ${{ needs.set-vars.outputs.MODNAME }} - MULTI_ARCH: ${{ needs.set-vars.outputs.MULTI_ARCH }} - MOD_VERSION: ${{ needs.set-vars.outputs.MOD_VERSION }} + - name: Tag image + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + docker tag ${{ github.sha }} ${ENDPOINT} + docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} + + - name: Credential check + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV + echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV + echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV + echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV + if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then + echo "::error::Push credential secrets missing." + echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." + echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." + exit 1 + fi + + - name: Login to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin + + - name: Push tags to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ghcr.io/${ENDPOINT}:${{ github.sha }} + docker push ghcr.io/${ENDPOINT} + + - name: Login to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin + + - name: Push tags to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ${ENDPOINT}:${{ github.sha }} + docker push ${ENDPOINT} \ No newline at end of file From 8ed1b26a4858a9f3828a0b432c016898e3358a61 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Fri, 20 Jun 2025 10:42:33 -0400 Subject: [PATCH 03/21] Typo fix for endpoint. --- .github/workflows/BuildImage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/BuildImage.yml b/.github/workflows/BuildImage.yml index 8d7545fe..6a5bd2b8 100644 --- a/.github/workflows/BuildImage.yml +++ b/.github/workflows/BuildImage.yml @@ -3,7 +3,7 @@ name: Build Image on: [push, pull_request, workflow_dispatch] env: - ENDPOINT: "TrezOne/swag-auto-uptime-kuma" + ENDPOINT: "trezone/swag-auto-uptime-kuma" BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" jobs: From a443b8542f7d033fb99d2dde3782497534bd7508 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Fri, 20 Jun 2025 15:18:54 -0400 Subject: [PATCH 04/21] Adding separate workflow for testing. --- .github/workflows/BuildImage.yml | 90 ++++++++++++++------------------ .github/workflows/BuildTest.yml | 61 ++++++++++++++++++++++ 2 files changed, 100 insertions(+), 51 deletions(-) create mode 100644 .github/workflows/BuildTest.yml diff --git a/.github/workflows/BuildImage.yml b/.github/workflows/BuildImage.yml index 6a5bd2b8..37850f08 100644 --- a/.github/workflows/BuildImage.yml +++ b/.github/workflows/BuildImage.yml @@ -1,61 +1,49 @@ name: Build Image -on: [push, pull_request, workflow_dispatch] +on: [push, pull_request_target, workflow_dispatch] env: - ENDPOINT: "trezone/swag-auto-uptime-kuma" - BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" + GITHUB_REPO: "linuxserver/docker-mods" #don't modify + ENDPOINT: "linuxserver/mods" #don't modify + BASEIMAGE: "swag" #replace + MODNAME: "auto-uptime-kuma" #replace + MULTI_ARCH: "false" #set to false if not needed jobs: - build: + set-vars: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - name: Build image - run: | - docker build --no-cache -t ${{ github.sha }} . - - - name: Tag image - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - docker tag ${{ github.sha }} ${ENDPOINT} - docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} - - - name: Credential check - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV - echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV - echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV - echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV - if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then - echo "::error::Push credential secrets missing." - echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." - echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." - exit 1 - fi - - - name: Login to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin - - - name: Push tags to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + - name: Set Vars + id: outputs run: | - docker push ghcr.io/${ENDPOINT}:${{ github.sha }} - docker push ghcr.io/${ENDPOINT} + echo "GITHUB_REPO=${{ env.GITHUB_REPO }}" >> $GITHUB_OUTPUT + echo "ENDPOINT=${{ env.ENDPOINT }}" >> $GITHUB_OUTPUT + echo "BASEIMAGE=${{ env.BASEIMAGE }}" >> $GITHUB_OUTPUT + echo "MODNAME=${{ env.MODNAME }}" >> $GITHUB_OUTPUT + echo "MULTI_ARCH=${{ env.MULTI_ARCH }}" >> $GITHUB_OUTPUT + # **** If the mod needs to be versioned, set the versioning logic below. Otherwise leave as is. **** + MOD_VERSION="" + echo "MOD_VERSION=${MOD_VERSION}" >> $GITHUB_OUTPUT + outputs: + GITHUB_REPO: ${{ steps.outputs.outputs.GITHUB_REPO }} + ENDPOINT: ${{ steps.outputs.outputs.ENDPOINT }} + BASEIMAGE: ${{ steps.outputs.outputs.BASEIMAGE }} + MODNAME: ${{ steps.outputs.outputs.MODNAME }} + MULTI_ARCH: ${{ steps.outputs.outputs.MULTI_ARCH }} + MOD_VERSION: ${{ steps.outputs.outputs.MOD_VERSION }} - - name: Login to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin - - - name: Push tags to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - docker push ${ENDPOINT}:${{ github.sha }} - docker push ${ENDPOINT} \ No newline at end of file + build: + uses: linuxserver/github-workflows/.github/workflows/docker-mod-builder.yml@v1 + needs: set-vars + secrets: + CR_USER: ${{ secrets.CR_USER }} + CR_PAT: ${{ secrets.CR_PAT }} + DOCKERUSER: ${{ secrets.DOCKERUSER }} + DOCKERPASS: ${{ secrets.DOCKERPASS }} + with: + GITHUB_REPO: ${{ needs.set-vars.outputs.GITHUB_REPO }} + ENDPOINT: ${{ needs.set-vars.outputs.ENDPOINT }} + BASEIMAGE: ${{ needs.set-vars.outputs.BASEIMAGE }} + MODNAME: ${{ needs.set-vars.outputs.MODNAME }} + MULTI_ARCH: ${{ needs.set-vars.outputs.MULTI_ARCH }} + MOD_VERSION: ${{ needs.set-vars.outputs.MOD_VERSION }} diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml new file mode 100644 index 00000000..57e8f9ef --- /dev/null +++ b/.github/workflows/BuildTest.yml @@ -0,0 +1,61 @@ +name: Build Image + +on: [push, pull_request, workflow_dispatch] + +env: + ENDPOINT: "trezone/swag-auto-uptime-kuma" + BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.3 + + - name: Build image + run: | + docker build --no-cache -t ${{ github.sha }} . + + - name: Tag image + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + docker tag ${{ github.sha }} ${ENDPOINT} + docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} + + - name: Credential check + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV + echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV + echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV + echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV + if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then + echo "::error::Push credential secrets missing." + echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." + echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." + exit 1 + fi + + - name: Login to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin + + - name: Push tags to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ghcr.io/${ENDPOINT}:${{ github.sha }} + docker push ghcr.io/${ENDPOINT} + + - name: Login to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin + + - name: Push tags to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ${ENDPOINT}:${{ github.sha }} + docker push ${ENDPOINT} \ No newline at end of file From 6c87eb91f69034af6fbe62d2dc68ef361cec32b2 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Fri, 20 Jun 2025 15:58:04 -0400 Subject: [PATCH 05/21] Removing test workflow. --- .github/workflows/BuildTest.yml | 61 --------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 .github/workflows/BuildTest.yml diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml deleted file mode 100644 index 57e8f9ef..00000000 --- a/.github/workflows/BuildTest.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Build Image - -on: [push, pull_request, workflow_dispatch] - -env: - ENDPOINT: "trezone/swag-auto-uptime-kuma" - BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.3.3 - - - name: Build image - run: | - docker build --no-cache -t ${{ github.sha }} . - - - name: Tag image - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - docker tag ${{ github.sha }} ${ENDPOINT} - docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} - - - name: Credential check - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV - echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV - echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV - echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV - if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then - echo "::error::Push credential secrets missing." - echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." - echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." - exit 1 - fi - - - name: Login to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin - - - name: Push tags to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} - run: | - docker push ghcr.io/${ENDPOINT}:${{ github.sha }} - docker push ghcr.io/${ENDPOINT} - - - name: Login to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin - - - name: Push tags to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - docker push ${ENDPOINT}:${{ github.sha }} - docker push ${ENDPOINT} \ No newline at end of file From 888b871874318198a2b4881117c7576228ba22fa Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 09:23:02 -0400 Subject: [PATCH 06/21] New class methods. --- .../auto_uptime_kuma/uptime_kuma_service.py | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 83f45dde..20aee9ad 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -24,19 +24,50 @@ class UptimeKumaService: def __init__(self, config_service): self.config_service = config_service - def connect(self, url, username, password): - response = requests.get(url, allow_redirects=True, timeout=5) - if response.status_code != 200: + def _retry_api_call(self, func, *args, retries=5, delay=5, **kwargs): + """ + Generic retry wrapper for Uptime Kuma API calls that may timeout. + """ + for attempt in range(1, retries + 1): + try: + return func(*args, **kwargs) + except socketio.exceptions.TimeoutError: + if attempt == retries: + Log.info(f"[auto-uptime-kuma] Final attempt {attempt} failed. Giving up.") + raise + Log.info( + f"[auto-uptime-kuma] Attempt {attempt} failed with TimeoutError. Retrying in {delay} seconds..." + ) + time.sleep(delay) + + def create_monitor(self, container_name, monitor_data): + monitor_data = self.build_monitor_data(container_name, monitor_data) + if self.monitor_exists(container_name): Log.info( - f"Unable to connect to UptimeKuma at '{url}' (Status code: {response.status_code})." - " Please check if the host is running." + f"Uptime Kuma already contains Monitor '{monitor_data['name']}'" + f" for container '{container_name}', skipping..." ) - return False + return None + + Log.info( + f"Adding Monitor '{monitor_data['name']}' for container '{container_name}'" + ) + + monitor = self._retry_api_call(self.api.add_monitor, **monitor_data) + + self._retry_api_call( + self.api.add_monitor_tag, + tag_id=self.get_swag_tag()["id"], + monitor_id=monitor["monitorID"], + value=container_name.lower(), + ) + + self.config_service.create_config(container_name, monitor_data) - self.api = UptimeKumaApi(url, ENV[TIMEOUT]) - self.api.login(username, password) + monitor = self._retry_api_call(self.api.get_monitor, monitor["monitorID"]) + self.monitors.append(monitor) - return True + return monitor def disconnect(self): """ From 5dd591b368eb91444a0e233594d17d0de5ff3b6d Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 09:23:02 -0400 Subject: [PATCH 07/21] Adding test workflow. --- .github/workflows/BuildTest.yml | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/BuildTest.yml diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml new file mode 100644 index 00000000..57e8f9ef --- /dev/null +++ b/.github/workflows/BuildTest.yml @@ -0,0 +1,61 @@ +name: Build Image + +on: [push, pull_request, workflow_dispatch] + +env: + ENDPOINT: "trezone/swag-auto-uptime-kuma" + BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.3 + + - name: Build image + run: | + docker build --no-cache -t ${{ github.sha }} . + + - name: Tag image + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + docker tag ${{ github.sha }} ${ENDPOINT} + docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} + + - name: Credential check + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV + echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV + echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV + echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV + if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then + echo "::error::Push credential secrets missing." + echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." + echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." + exit 1 + fi + + - name: Login to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin + + - name: Push tags to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ghcr.io/${ENDPOINT}:${{ github.sha }} + docker push ghcr.io/${ENDPOINT} + + - name: Login to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin + + - name: Push tags to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ${ENDPOINT}:${{ github.sha }} + docker push ${ENDPOINT} \ No newline at end of file From 7db3ec8ca6d895711f864f326d03eefba8749e83 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 12:54:48 -0400 Subject: [PATCH 08/21] Test #3. --- .../auto_uptime_kuma/uptime_kuma_service.py | 66 ++++++------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 20aee9ad..71042253 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -24,50 +24,19 @@ class UptimeKumaService: def __init__(self, config_service): self.config_service = config_service - def _retry_api_call(self, func, *args, retries=5, delay=5, **kwargs): - """ - Generic retry wrapper for Uptime Kuma API calls that may timeout. - """ - for attempt in range(1, retries + 1): - try: - return func(*args, **kwargs) - except socketio.exceptions.TimeoutError: - if attempt == retries: - Log.info(f"[auto-uptime-kuma] Final attempt {attempt} failed. Giving up.") - raise - Log.info( - f"[auto-uptime-kuma] Attempt {attempt} failed with TimeoutError. Retrying in {delay} seconds..." - ) - time.sleep(delay) - - def create_monitor(self, container_name, monitor_data): - monitor_data = self.build_monitor_data(container_name, monitor_data) - if self.monitor_exists(container_name): + def connect(self, url, username, password): + response = requests.get(url, allow_redirects=True, timeout=5) + if response.status_code != 200: Log.info( - f"Uptime Kuma already contains Monitor '{monitor_data['name']}'" - f" for container '{container_name}', skipping..." + f"Unable to connect to UptimeKuma at '{url}' (Status code: {response.status_code})." + " Please check if the host is running." ) - return None + return False - Log.info( - f"Adding Monitor '{monitor_data['name']}' for container '{container_name}'" - ) + self.api = UptimeKumaApi(url) + self.api.login(username, password) - monitor = self._retry_api_call(self.api.add_monitor, **monitor_data) - - self._retry_api_call( - self.api.add_monitor_tag, - tag_id=self.get_swag_tag()["id"], - monitor_id=monitor["monitorID"], - value=container_name.lower(), - ) - - self.config_service.create_config(container_name, monitor_data) - - monitor = self._retry_api_call(self.api.get_monitor, monitor["monitorID"]) - self.monitors.append(monitor) - - return monitor + return True def disconnect(self): """ @@ -152,6 +121,8 @@ def monitor_exists(self, container_name): def create_monitor(self, container_name, monitor_data): monitor_data = self.build_monitor_data(container_name, monitor_data) + self.validate_monitor_data(monitor_data) + if self.monitor_exists(container_name): Log.info( f"Uptime Kuma already contains Monitor '{monitor_data['name']}'" @@ -159,11 +130,17 @@ def create_monitor(self, container_name, monitor_data): ) return None - Log.info( - f"Adding Monitor '{monitor_data['name']}' for container '{container_name}'" - ) + Log.info(f"Adding Monitor '{monitor_data['name']}' for container '{container_name}'") + Log.debug(f"Sending monitor data: {monitor_data}") - monitor = self.api.add_monitor(**monitor_data) + try: + monitor = self.api.add_monitor(**monitor_data) + except socketio.exceptions.TimeoutError: + Log.error("Timeout while trying to add monitor to Uptime Kuma. Is the server responsive?") + return None + except Exception as e: + Log.error(f"Failed to create monitor due to unexpected error: {e}") + return None self.api.add_monitor_tag( tag_id=self.get_swag_tag()["id"], @@ -172,7 +149,6 @@ def create_monitor(self, container_name, monitor_data): ) self.config_service.create_config(container_name, monitor_data) - monitor = self.api.get_monitor(monitor["monitorID"]) self.monitors.append(monitor) From 4a341094902fbb404e2bb4eba918c9f633ca36f3 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:00:44 -0400 Subject: [PATCH 09/21] Test #4. --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 71042253..be54c7c3 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -116,6 +116,15 @@ def get_monitor(self, container_name): return monitor return None + def validate_monitor_data(self, monitor_data): + required_keys = ["type", "name", "url"] + for key in required_keys: + if key not in monitor_data: + raise ValueError(f"Missing required monitor field: {key}") + + if not isinstance(monitor_data.get("notificationIDList", []), list): + raise ValueError("notificationIDList must be a list") + def monitor_exists(self, container_name): return self.get_monitor(container_name) is not None From 4273a3265bdb97f2010d6d431ae5e311b205e7c5 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:05:26 -0400 Subject: [PATCH 10/21] Test #5 - debug() method undefined, so removing... --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index be54c7c3..4d95a3fa 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -140,7 +140,7 @@ def create_monitor(self, container_name, monitor_data): return None Log.info(f"Adding Monitor '{monitor_data['name']}' for container '{container_name}'") - Log.debug(f"Sending monitor data: {monitor_data}") + Log.info(f"Sending monitor data: {monitor_data}") try: monitor = self.api.add_monitor(**monitor_data) From 1d68872fe051120008566e65595697ae278bbb88 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:10:40 -0400 Subject: [PATCH 11/21] Test #6 - importing TimeoutError from socketio.exceptions... --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 4d95a3fa..0e873033 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -2,7 +2,7 @@ from uptime_kuma_api.api import UptimeKumaApi, MonitorType from auto_uptime_kuma.log import Log from auto_uptime_kuma.config_service import ConfigService - +from socketio.exceptions import TimeoutError class UptimeKumaService: @@ -144,7 +144,7 @@ def create_monitor(self, container_name, monitor_data): try: monitor = self.api.add_monitor(**monitor_data) - except socketio.exceptions.TimeoutError: + except TimeoutError: Log.error("Timeout while trying to add monitor to Uptime Kuma. Is the server responsive?") return None except Exception as e: From 53c70bd3cd8b276a9894c83e6f3d9f61b1a53d21 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:19:40 -0400 Subject: [PATCH 12/21] Test #6 - Log.error method does not exist (more caffeine needed)... --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 0e873033..5b416184 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -145,10 +145,10 @@ def create_monitor(self, container_name, monitor_data): try: monitor = self.api.add_monitor(**monitor_data) except TimeoutError: - Log.error("Timeout while trying to add monitor to Uptime Kuma. Is the server responsive?") + Log.info("Timeout while trying to add monitor to Uptime Kuma. Is the server responsive?") return None except Exception as e: - Log.error(f"Failed to create monitor due to unexpected error: {e}") + Log.info(f"Failed to create monitor due to unexpected error: {e}") return None self.api.add_monitor_tag( From 98a151d93cc4a32f2de248913113cde7ce7bb5d3 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:28:49 -0400 Subject: [PATCH 13/21] Test #7 - Updating delete_monitor method... --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 5b416184..ab22f1f4 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -191,7 +191,19 @@ def delete_monitor(self, container_name: str): monitor_data = self.get_monitor(container_name) if monitor_data is not None: Log.info(f"Deleting Monitor {monitor_data['id']}:{monitor_data['name']}") - self.api.delete_monitor(monitor_data["id"]) + try: + self.api.delete_monitor(monitor_data["id"]) + except socketio.exceptions.TimeoutError: + Log.info(f"Timeout while deleting monitor ID {monitor_data['id']}") + return + except Exception as e: + Log.info(f"Error while deleting monitor ID {monitor_data['id']}: {e}") + return + + for i, monitor in enumerate(self.monitors): + if monitor["id"] == monitor_data["id"]: + del self.monitors[i] + break for i, monitor in enumerate(self.monitors): if monitor["id"] == monitor_data["id"]: From a94dcf5b418378d6de97bfd8feb7f1a543b21729 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:30:04 -0400 Subject: [PATCH 14/21] Test #7 - Duplicate loop. --- .../auto_uptime_kuma/uptime_kuma_service.py | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index ab22f1f4..287642ce 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -188,27 +188,22 @@ def edit_monitor(self, container_name, monitor_data): ) def delete_monitor(self, container_name: str): - monitor_data = self.get_monitor(container_name) - if monitor_data is not None: - Log.info(f"Deleting Monitor {monitor_data['id']}:{monitor_data['name']}") - try: - self.api.delete_monitor(monitor_data["id"]) - except socketio.exceptions.TimeoutError: - Log.info(f"Timeout while deleting monitor ID {monitor_data['id']}") - return - except Exception as e: - Log.info(f"Error while deleting monitor ID {monitor_data['id']}: {e}") - return - - for i, monitor in enumerate(self.monitors): - if monitor["id"] == monitor_data["id"]: - del self.monitors[i] - break + monitor_data = self.get_monitor(container_name) + if monitor_data is not None: + Log.info(f"Deleting Monitor {monitor_data['id']}:{monitor_data['name']}") + try: + self.api.delete_monitor(monitor_data["id"]) + except socketio.exceptions.TimeoutError: + Log.error(f"Timeout while deleting monitor ID {monitor_data['id']}") + return + except Exception as e: + Log.error(f"Error while deleting monitor ID {monitor_data['id']}: {e}") + return - for i, monitor in enumerate(self.monitors): - if monitor["id"] == monitor_data["id"]: - del self.monitors[i] - break + for i, monitor in enumerate(self.monitors): + if monitor["id"] == monitor_data["id"]: + del self.monitors[i] + break def delete_monitors(self, container_names: list[str]): if container_names: From b17580ff3faa197c262cce9b8994f5e85627394b Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:30:35 -0400 Subject: [PATCH 15/21] Test #7 - Duplicate loop. --- .../auto_uptime_kuma/uptime_kuma_service.py | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 287642ce..f6a149c4 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -188,22 +188,22 @@ def edit_monitor(self, container_name, monitor_data): ) def delete_monitor(self, container_name: str): - monitor_data = self.get_monitor(container_name) - if monitor_data is not None: - Log.info(f"Deleting Monitor {monitor_data['id']}:{monitor_data['name']}") - try: - self.api.delete_monitor(monitor_data["id"]) - except socketio.exceptions.TimeoutError: - Log.error(f"Timeout while deleting monitor ID {monitor_data['id']}") - return - except Exception as e: - Log.error(f"Error while deleting monitor ID {monitor_data['id']}: {e}") - return - - for i, monitor in enumerate(self.monitors): - if monitor["id"] == monitor_data["id"]: - del self.monitors[i] - break + monitor_data = self.get_monitor(container_name) + if monitor_data is not None: + Log.info(f"Deleting Monitor {monitor_data['id']}:{monitor_data['name']}") + try: + self.api.delete_monitor(monitor_data["id"]) + except socketio.exceptions.TimeoutError: + Log.error(f"Timeout while deleting monitor ID {monitor_data['id']}") + return + except Exception as e: + Log.error(f"Error while deleting monitor ID {monitor_data['id']}: {e}") + return + + for i, monitor in enumerate(self.monitors): + if monitor["id"] == monitor_data["id"]: + del self.monitors[i] + break def delete_monitors(self, container_names: list[str]): if container_names: From fdc7a2a590eeb09b7c0232df0fe33e0b326e7cbc Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:34:47 -0400 Subject: [PATCH 16/21] Test #8 - Updated delete_monitor. --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index f6a149c4..e017441c 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -193,7 +193,7 @@ def delete_monitor(self, container_name: str): Log.info(f"Deleting Monitor {monitor_data['id']}:{monitor_data['name']}") try: self.api.delete_monitor(monitor_data["id"]) - except socketio.exceptions.TimeoutError: + except TimeoutError: Log.error(f"Timeout while deleting monitor ID {monitor_data['id']}") return except Exception as e: From b8e9159b8f4f03a5e5cd7594b3c05dc38d87d00b Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:38:49 -0400 Subject: [PATCH 17/21] .... Sleeeeep.... --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index e017441c..3c4c4904 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -194,10 +194,10 @@ def delete_monitor(self, container_name: str): try: self.api.delete_monitor(monitor_data["id"]) except TimeoutError: - Log.error(f"Timeout while deleting monitor ID {monitor_data['id']}") + Log.info(f"Timeout while deleting monitor ID {monitor_data['id']}") return except Exception as e: - Log.error(f"Error while deleting monitor ID {monitor_data['id']}: {e}") + Log.info(f"Error while deleting monitor ID {monitor_data['id']}: {e}") return for i, monitor in enumerate(self.monitors): From 697568b26082f234abccd730f8ff6e0f1cf1cfef Mon Sep 17 00:00:00 2001 From: TrezOne Date: Wed, 6 Aug 2025 13:57:04 -0400 Subject: [PATCH 18/21] Removing BuildTest pipeline. --- .github/workflows/BuildTest.yml | 61 --------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 .github/workflows/BuildTest.yml diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml deleted file mode 100644 index 57e8f9ef..00000000 --- a/.github/workflows/BuildTest.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Build Image - -on: [push, pull_request, workflow_dispatch] - -env: - ENDPOINT: "trezone/swag-auto-uptime-kuma" - BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.3.3 - - - name: Build image - run: | - docker build --no-cache -t ${{ github.sha }} . - - - name: Tag image - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - docker tag ${{ github.sha }} ${ENDPOINT} - docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} - - - name: Credential check - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV - echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV - echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV - echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV - if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then - echo "::error::Push credential secrets missing." - echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." - echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." - exit 1 - fi - - - name: Login to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin - - - name: Push tags to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} - run: | - docker push ghcr.io/${ENDPOINT}:${{ github.sha }} - docker push ghcr.io/${ENDPOINT} - - - name: Login to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin - - - name: Push tags to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - docker push ${ENDPOINT}:${{ github.sha }} - docker push ${ENDPOINT} \ No newline at end of file From 7d423dd281941af63995eb8e6d77c81f55cdca9f Mon Sep 17 00:00:00 2001 From: TrezOne Date: Thu, 7 Aug 2025 10:46:57 -0400 Subject: [PATCH 19/21] Re-adding temp workflow. --- .github/workflows/BuildTest.yml | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/BuildTest.yml diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml new file mode 100644 index 00000000..9b5f0fc8 --- /dev/null +++ b/.github/workflows/BuildTest.yml @@ -0,0 +1,61 @@ +name: Temporary Build Test + +on: [push, pull_request, workflow_dispatch] + +env: + ENDPOINT: "trezone/swag-auto-uptime-kuma" + BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.3 + + - name: Build image + run: | + docker build --no-cache -t ${{ github.sha }} . + + - name: Tag image + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + docker tag ${{ github.sha }} ${ENDPOINT} + docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} + docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} + + - name: Credential check + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV + echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV + echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV + echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV + if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then + echo "::error::Push credential secrets missing." + echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." + echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." + exit 1 + fi + + - name: Login to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin + + - name: Push tags to GitHub Container Registry + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ghcr.io/${ENDPOINT}:${{ github.sha }} + docker push ghcr.io/${ENDPOINT} + + - name: Login to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin + + - name: Push tags to DockerHub + if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} + run: | + docker push ${ENDPOINT}:${{ github.sha }} + docker push ${ENDPOINT} \ No newline at end of file From d84284c8fbec305e94a6c2f6b825e8e3430d9569 Mon Sep 17 00:00:00 2001 From: TrezOne Date: Thu, 7 Aug 2025 10:46:57 -0400 Subject: [PATCH 20/21] Updating edit_monitor{) to let SWAG start even with broken monitor. --- root/app/auto_uptime_kuma/uptime_kuma_service.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/root/app/auto_uptime_kuma/uptime_kuma_service.py b/root/app/auto_uptime_kuma/uptime_kuma_service.py index 3c4c4904..18831179 100644 --- a/root/app/auto_uptime_kuma/uptime_kuma_service.py +++ b/root/app/auto_uptime_kuma/uptime_kuma_service.py @@ -169,7 +169,13 @@ def edit_monitor(self, container_name, monitor_data): is actually "delete" followed by "add" so that in the end the monitors are actually recreated """ - new_monitor_data = self.build_monitor_data(container_name, monitor_data) + try: + new_monitor_data = self.build_monitor_data(container_name, monitor_data) + self.validate_monitor_data(new_monitor_data) + except Exception as e: + Log.info(f"Invalid monitor data for '{container_name}'. Skipping edit. Reason: {e}") + return + existing_monitor_data = self.get_monitor(container_name) old_content = self.config_service.read_config_content(container_name) new_content = self.config_service.build_config_content(new_monitor_data) From 0810e7491f55d77c65378351bca9ea5bf925486e Mon Sep 17 00:00:00 2001 From: TrezOne Date: Thu, 7 Aug 2025 19:58:56 -0400 Subject: [PATCH 21/21] Removing temporary build workflow. --- .github/workflows/BuildTest.yml | 61 --------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 .github/workflows/BuildTest.yml diff --git a/.github/workflows/BuildTest.yml b/.github/workflows/BuildTest.yml deleted file mode 100644 index 9b5f0fc8..00000000 --- a/.github/workflows/BuildTest.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Temporary Build Test - -on: [push, pull_request, workflow_dispatch] - -env: - ENDPOINT: "trezone/swag-auto-uptime-kuma" - BRANCH: "swag-auto-uptime-kuma-timeout-fix_2025-06-20T09-38-36" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.3.3 - - - name: Build image - run: | - docker build --no-cache -t ${{ github.sha }} . - - - name: Tag image - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - docker tag ${{ github.sha }} ${ENDPOINT} - docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT} - docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }} - - - name: Credential check - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV - echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV - echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV - echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV - if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then - echo "::error::Push credential secrets missing." - echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings." - echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions." - exit 1 - fi - - - name: Login to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} - run: | - echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin - - - name: Push tags to GitHub Container Registry - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.CR_USER && env.CR_PAT && env.ENDPOINT != 'user/endpoint' }} - run: | - docker push ghcr.io/${ENDPOINT}:${{ github.sha }} - docker push ghcr.io/${ENDPOINT} - - - name: Login to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin - - - name: Push tags to DockerHub - if: ${{ github.ref == format('refs/heads/{0}', env.BRANCH) && env.DOCKERUSER && env.DOCKERPASS && env.ENDPOINT != 'user/endpoint' }} - run: | - docker push ${ENDPOINT}:${{ github.sha }} - docker push ${ENDPOINT} \ No newline at end of file