diff --git a/.gitea/workflows/build-deploy.yml b/.gitea/workflows/build-deploy.yml index 9a0fc9d..8220083 100644 --- a/.gitea/workflows/build-deploy.yml +++ b/.gitea/workflows/build-deploy.yml @@ -43,10 +43,28 @@ jobs: - name: Сборка и публикация образа run: | + # docker build/push ходят наружу (Docker Hub, при первой сборке слоя — ещё и Maven + # Central) по тому же нестабильному пути, что раньше ронял пул образа раннера — там + # были TCP-таймауты/обрывы, которые лечатся повтором, а не переделкой шага. Поэтому + # оборачиваем оба во retry с паузой: 5 попыток, между ними 15с. + retry() { + local attempt=1 + local max=5 + until "$@"; do + if [ "$attempt" -ge "$max" ]; then + echo "::error::'$*' не удалось за $max попыток(ки), сдаюсь" + return 1 + fi + echo "'$*' — попытка $attempt из $max не удалась, жду 15с и повторяю..." + attempt=$((attempt + 1)) + sleep 15 + done + } + IMAGE="docker.io/$DOCKERHUB_USER/iot-hub" - docker build -t "$IMAGE:${GITHUB_SHA}" -t "$IMAGE:latest" . - docker push "$IMAGE:${GITHUB_SHA}" - docker push "$IMAGE:latest" + retry docker build -t "$IMAGE:${GITHUB_SHA}" -t "$IMAGE:latest" . + retry docker push "$IMAGE:${GITHUB_SHA}" + retry docker push "$IMAGE:latest" env: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} @@ -71,7 +89,11 @@ jobs: - name: Установка Helm run: | - curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 + # raw.githubusercontent.com — тот же ненадёжный путь. --retry у curl умеет повторять + # сам, без ручного цикла: 5 попыток, экспоненциальная задержка, повтор и на сетевых + # обрывах (--retry-all-errors), не только на HTTP-кодах. + curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors \ + -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod +x get_helm.sh ./get_helm.sh rm get_helm.sh diff --git a/adapters/adapter-keenetic/src/main/java/ru/kayashov/iot/hub/adapter/keenetic/KeeneticRouterClient.java b/adapters/adapter-keenetic/src/main/java/ru/kayashov/iot/hub/adapter/keenetic/KeeneticRouterClient.java index 3d4e1ea..20a2ff8 100644 --- a/adapters/adapter-keenetic/src/main/java/ru/kayashov/iot/hub/adapter/keenetic/KeeneticRouterClient.java +++ b/adapters/adapter-keenetic/src/main/java/ru/kayashov/iot/hub/adapter/keenetic/KeeneticRouterClient.java @@ -133,15 +133,22 @@ public class KeeneticRouterClient { "Keenetic RCI: роутер не прислал X-NDM-Challenge/X-NDM-Realm в ответ на GET /auth — " + "формат авторизации мог снова измениться"); } + // Диагностика (X-Detail: "0x2021, no session") показала: 401 на GET /auth сам по себе + // ставит pre-auth сессионную куку, к которой привязан именно этот challenge. Раньше мы + // её игнорировали и слали POST /auth вообще без Cookie — роутер не мог сопоставить + // решённый challenge ни с какой сессией и отвечал 400. Сохраняем куку из 401 и шлём + // её на POST — так же, как обычный запрос уже шлёт actualную сессионную куку. + storeCookie(challengeHeaders); String hash = sha256Hex(challenge + md5Hex(properties.getLogin() + ":" + realm + ":" + properties.getPassword())); Map body = Map.of("login", properties.getLogin(), "password", hash); // Хэш — SHA-256, необратимый, логировать его безопасно (в отличие от самого пароля). // INFO, а не DEBUG — это временная диагностика (400 Bad Request на POST /auth не даёт // тела ответа, причина пока не установлена), чтобы не пришлось менять уровень логов. - log.info("Keenetic RCI: POST {} login={} challenge={} realm={} hash={}", - authUrl, properties.getLogin(), challenge, realm, hash); + log.info("Keenetic RCI: POST {} login={} challenge={} realm={} hash={} cookie={}", + authUrl, properties.getLogin(), challenge, realm, hash, sessionCookie); try { - ResponseEntity authResponse = restTemplate.postForEntity(authUrl, body, Void.class); + HttpEntity entity = new HttpEntity<>(body, authHeaders()); + ResponseEntity authResponse = restTemplate.postForEntity(authUrl, entity, Void.class); storeCookie(authResponse.getHeaders()); } catch (HttpStatusCodeException authError) { log.error("Keenetic RCI: POST /auth -> {} ({}); заголовки ответа: {}; тело ответа: '{}'", diff --git a/deployment/iot-hub/values.yaml b/deployment/iot-hub/values.yaml index 7ed411b..1a5b05d 100644 --- a/deployment/iot-hub/values.yaml +++ b/deployment/iot-hub/values.yaml @@ -42,7 +42,7 @@ resources: # в то, что здесь — см. README.md, раздел "Конфигурация без Helm-редеплоя". adapters: camera: - enabled: true + enabled: false urls: [] # - "https://example.com/stream1/master.m3u8" keenetic: