chore: staged files from prev session (gitignore, examples, harbor guide)
This commit is contained in:
+12
@@ -45,3 +45,15 @@ test.token
|
|||||||
*.tfvars
|
*.tfvars
|
||||||
.e2e-logs/
|
.e2e-logs/
|
||||||
.stress-logs/
|
.stress-logs/
|
||||||
|
|
||||||
|
# Доп. правила: исключаем сгенерированные провайдеры, плагины и артефакты Terraform
|
||||||
|
# каталоги и плагины провайдеров
|
||||||
|
**/.terraform/plugins/
|
||||||
|
**/.terraform/providers/
|
||||||
|
# иногда плагины лежат в user-terraform
|
||||||
|
.terraform.d/
|
||||||
|
# собранные архивы и артефакты
|
||||||
|
*.zip
|
||||||
|
**/dist/
|
||||||
|
# дополнительные вариации переменных/файлов конфигурации
|
||||||
|
*.tfvars.json
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
# Руководство по использованию PearlHarbor registry
|
||||||
|
# 2026-03-11 12:45
|
||||||
|
|
||||||
|
Цель: документ описывает как собирать/тегировать/пушить образы в реестр PearlHarbor, как запускать тестовый набор пушей из репозитория, какие ошибки встречаются и как их устранять.
|
||||||
|
|
||||||
|
Файлы в репе, полезные для работы:
|
||||||
|
- [examples/push-sample/Dockerfile](examples/push-sample/Dockerfile) — минимальный Dockerfile для теста.
|
||||||
|
- [examples/push-sample/build_and_push.sh](examples/push-sample/build_and_push.sh) — простая утилита сборки и опционального пуша (DO_PUSH=true).
|
||||||
|
- [test_pearlharbor_push.sh](test_pearlharbor_push.sh) — расширенный тестовый скрипт для многократных пушей и опциональной очистки (CLEANUP=true).
|
||||||
|
- `secrets/pearlharbor_registry.txt` — локальный файл с настройками/паролем (не ложить в публичные места).
|
||||||
|
|
||||||
|
1) Быстрый старт (ручной, один образ)
|
||||||
|
|
||||||
|
1.1. Подготовка
|
||||||
|
|
||||||
|
- Убедитесь, что у вас есть `docker` и вы можете запускать `docker build` и `docker push`.
|
||||||
|
- Проверьте `secrets/pearlharbor_registry.txt` — в нём должно быть поле `connection_url` и `admin_pass`.
|
||||||
|
|
||||||
|
1.2. Собрать образ локально
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t sless-sample:local -f examples/push-sample/Dockerfile examples/push-sample
|
||||||
|
```
|
||||||
|
|
||||||
|
1.3. Тег и push (пример)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
registry=$(grep -E '^connection_url=' secrets/pearlharbor_registry.txt | cut -d'=' -f2- | sed -E 's~https?://~~; s~/$~~')
|
||||||
|
admin_pass=$(grep -E '^admin_pass=' secrets/pearlharbor_registry.txt | cut -d'=' -f2-)
|
||||||
|
echo "$admin_pass" | docker login "$registry" -u admin --password-stdin
|
||||||
|
docker tag sless-sample:local "$registry/pearlharbor/sless-sample:mytag"
|
||||||
|
docker push "$registry/pearlharbor/sless-sample:mytag"
|
||||||
|
```
|
||||||
|
|
||||||
|
2) Тестовый набор пушей (рекомендуется запускать без VPN)
|
||||||
|
|
||||||
|
- Скрипт: [test_pearlharbor_push.sh](test_pearlharbor_push.sh)
|
||||||
|
- Пример запуска (5 пушей, с очисткой тегов):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CLEANUP=true ./test_pearlharbor_push.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- Параметры (переменные окружения):
|
||||||
|
- `NUM_PUSHES` — число пушей (по умолчанию 5)
|
||||||
|
- `RETRIES_PER_PUSH` — попыток на пуш (по умолчанию 3)
|
||||||
|
- `BACKOFF` — базовый множитель паузы между попытками
|
||||||
|
- `PROJECT` — проект/неймспейс в Harbor (по умолчанию `pearlharbor`)
|
||||||
|
- `CREATE_PROJECT=true` — создать проект автоматически (если у вас есть права)
|
||||||
|
- `CLEANUP=true` — после тестов удалит созданные теги (по API)
|
||||||
|
|
||||||
|
3) Частые ошибки и как их исправлять
|
||||||
|
|
||||||
|
- Ошибка: "invalid repository name: sless-sample"
|
||||||
|
- Причина: формат тега не содержит проект/неймспейс. В Harbor теги должны быть `registry/PROJECT/REPO:TAG`.
|
||||||
|
- Решение: используйте `registry/pearlharbor/sless-sample:tag`.
|
||||||
|
|
||||||
|
- Ошибка: "project pearlharbor not found"
|
||||||
|
- Причина: проект (namespace) ещё не создан в Harbor.
|
||||||
|
- Решение: создайте проект через UI или API (пример ниже) или запустите `CREATE_PROJECT=true` в `test_pearlharbor_push.sh`.
|
||||||
|
|
||||||
|
- Ошибка: TLS handshake timeout / docker login failed
|
||||||
|
- Причина: нестабильная сеть, прокси или VPN мешают TLS. На наших тестах VPN приводил к таймаутам.
|
||||||
|
- Решение: временно отключите VPN, проверьте сетевую связность (`ping`, `curl https://.../v2/`), повторите попытку.
|
||||||
|
|
||||||
|
- Предупреждение: "Your password will be stored unencrypted in ~/.docker/config.json"
|
||||||
|
- Причина: Docker по умолчанию хранит креды в открытом виде, если не настроен credential helper.
|
||||||
|
- Решение: установить `docker-credential-helpers` или игнорировать на тестовой машине.
|
||||||
|
|
||||||
|
4) Harbor API — полезные команды
|
||||||
|
|
||||||
|
- Создать проект `pearlharbor`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
registry=pearlharbor.registryk8s.services.ngcloud.ru
|
||||||
|
admin_pass=$(grep -E '^admin_pass=' secrets/pearlharbor_registry.txt | cut -d'=' -f2-)
|
||||||
|
curl -u "admin:$admin_pass" -X POST "https://$registry/api/v2.0/projects" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{"project_name":"pearlharbor","metadata":{"public":"true"}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Список проектов:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -u "admin:$admin_pass" "https://$registry/api/v2.0/projects"
|
||||||
|
```
|
||||||
|
|
||||||
|
- Удалить репозиторий (удаляет все артефакты/теги в репозитории):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -u "admin:$admin_pass" -X DELETE "https://$registry/api/v2.0/projects/pearlharbor/repositories/sless-sample"
|
||||||
|
```
|
||||||
|
|
||||||
|
5) Советы при отладке
|
||||||
|
|
||||||
|
- Всегда проверяйте `https://$REGISTRY/v2/` — корректный ответ `200` или `401` означает, что эндпоинт доступен.
|
||||||
|
- Если `docker login` выдаёт TLS ошибки — сначала проверьте `curl -v https://$REGISTRY/v2/` и трассу до хоста.
|
||||||
|
- Для массовых тестов используйте `test_pearlharbor_push.sh`, но запускайте его без VPN.
|
||||||
|
- Логинимся перед серией пушей и переиспользуем сессию.
|
||||||
|
|
||||||
|
6) Права и безопасность
|
||||||
|
|
||||||
|
- Для создания проекта и удаления репозиториев нужен административный доступ (`admin`), либо пользователь с соответствующими правами.
|
||||||
|
- Никогда не встраивайте пароли в публичные репозитории. Используйте `secrets/pearlharbor_registry.txt` только локально и добавьте его в `.gitignore`.
|
||||||
|
|
||||||
|
7) Что я изменил в репозитории (для истории)
|
||||||
|
|
||||||
|
- Добавлены: `examples/push-sample/Dockerfile`, `examples/push-sample/build_and_push.sh`, `test_pearlharbor_push.sh` (инструмент для тестирования пушей и очистки).
|
||||||
|
- Временные/фоновые скрипты использовались в ходе отладки и затем удалялись.
|
||||||
|
|
||||||
|
8) Быстрый чек-лист перед пушем
|
||||||
|
|
||||||
|
- 1) Отключить VPN (если есть)
|
||||||
|
- 2) Убедиться, что `docker` запущен и вы можете выполнять `docker build`.
|
||||||
|
- 3) Убедиться, что `secrets/pearlharbor_registry.txt` на месте и содержит `connection_url` + `admin_pass`.
|
||||||
|
- 4) Выполнить `docker login $REGISTRY`.
|
||||||
|
- 5) Тегировать как `REGISTRY/PROJECT/REPO:TAG` и `docker push`.
|
||||||
|
|
||||||
|
Если нужно, могу дополнить этот документ примерами вывода команд/raw-логами или добавить скрипты для CI/CD (pipeline), которые будут автоматически создавать проект при деплое и чистить тестовые теги.
|
||||||
@@ -8,7 +8,7 @@ resource "sless_function" "time_getter" {
|
|||||||
name = "simple-node-time-getter" # уникальное имя в namespace
|
name = "simple-node-time-getter" # уникальное имя в namespace
|
||||||
runtime = "nodejs20"
|
runtime = "nodejs20"
|
||||||
entrypoint = "time_getter.getTime" # файл.функция в code/time_getter/
|
entrypoint = "time_getter.getTime" # файл.функция в code/time_getter/
|
||||||
memory_mb = 64
|
memory_mb = 128
|
||||||
|
|
||||||
source_dir = "${path.module}/code/time_getter"
|
source_dir = "${path.module}/code/time_getter"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ resource "sless_function" "time_getter" {
|
|||||||
name = "simple-py-time-getter" # уникальное имя в namespace
|
name = "simple-py-time-getter" # уникальное имя в namespace
|
||||||
runtime = "python3.11"
|
runtime = "python3.11"
|
||||||
entrypoint = "time_getter.get_time" # файл.функция в code/time_getter/
|
entrypoint = "time_getter.get_time" # файл.функция в code/time_getter/
|
||||||
memory_mb = 64
|
memory_mb = 128
|
||||||
|
|
||||||
source_dir = "${path.module}/code/time_getter"
|
source_dir = "${path.module}/code/time_getter"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ BACKOFF=${BACKOFF:-2}
|
|||||||
PROJECT=${PROJECT:-pearlharbor}
|
PROJECT=${PROJECT:-pearlharbor}
|
||||||
REGISTRY_USER=${REGISTRY_USER:-admin}
|
REGISTRY_USER=${REGISTRY_USER:-admin}
|
||||||
CREATE_PROJECT=${CREATE_PROJECT:-false}
|
CREATE_PROJECT=${CREATE_PROJECT:-false}
|
||||||
|
CLEANUP=${CLEANUP:-false}
|
||||||
|
|
||||||
connection_url=$(grep -E '^connection_url=' "$SECRETS_FILE" | cut -d'=' -f2-)
|
connection_url=$(grep -E '^connection_url=' "$SECRETS_FILE" | cut -d'=' -f2-)
|
||||||
admin_pass=$(grep -E '^admin_pass=' "$SECRETS_FILE" | cut -d'=' -f2-)
|
admin_pass=$(grep -E '^admin_pass=' "$SECRETS_FILE" | cut -d'=' -f2-)
|
||||||
@@ -47,6 +48,7 @@ if ! echo "$admin_pass" | docker login "$registry" -u "$REGISTRY_USER" --passwor
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
results=()
|
results=()
|
||||||
|
pushed_tags=()
|
||||||
start_all=$(date +%s.%N)
|
start_all=$(date +%s.%N)
|
||||||
for i in $(seq 1 "$NUM_PUSHES"); do
|
for i in $(seq 1 "$NUM_PUSHES"); do
|
||||||
tag="test-$(date +%Y%m%d%H%M%S)-$i"
|
tag="test-$(date +%Y%m%d%H%M%S)-$i"
|
||||||
@@ -74,6 +76,7 @@ for i in $(seq 1 "$NUM_PUSHES"); do
|
|||||||
t_end=$(date +%s.%N)
|
t_end=$(date +%s.%N)
|
||||||
elapsed=$(printf "%.3f" "$(echo "$t_end - $t_start" | bc -l)")
|
elapsed=$(printf "%.3f" "$(echo "$t_end - $t_start" | bc -l)")
|
||||||
results+=("$remote|$success|$attempt|$elapsed|$last_err")
|
results+=("$remote|$success|$attempt|$elapsed|$last_err")
|
||||||
|
pushed_tags+=("$tag")
|
||||||
done
|
done
|
||||||
end_all=$(date +%s.%N)
|
end_all=$(date +%s.%N)
|
||||||
total_time=$(printf "%.3f" "$(echo "$end_all - $start_all" | bc -l)")
|
total_time=$(printf "%.3f" "$(echo "$end_all - $start_all" | bc -l)")
|
||||||
@@ -94,6 +97,27 @@ for r in "${results[@]}"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo "Failures: $fail_count / $NUM_PUSHES"
|
echo "Failures: $fail_count / $NUM_PUSHES"
|
||||||
|
|
||||||
|
if [ "$CLEANUP" = "true" ]; then
|
||||||
|
echo "\nCleaning up pushed tags..."
|
||||||
|
del_fail=0
|
||||||
|
for t in "${pushed_tags[@]}"; do
|
||||||
|
echo "Deleting tag: $t"
|
||||||
|
code=$(curl -s -u "$REGISTRY_USER:$admin_pass" -o /dev/null -w "%{http_code}" -X DELETE "https://$registry/api/v2.0/projects/$PROJECT/repositories/sless-sample/artifacts/$t" ) || code=0
|
||||||
|
if [ "$code" = "200" ] || [ "$code" = "202" ] || [ "$code" = "204" ]; then
|
||||||
|
echo " -> deleted (HTTP $code)"
|
||||||
|
else
|
||||||
|
echo " -> delete failed (HTTP $code)"
|
||||||
|
del_fail=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $del_fail -ne 0 ]; then
|
||||||
|
echo "Cleanup had failures" >&2
|
||||||
|
else
|
||||||
|
echo "Cleanup completed"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$fail_count" -ne 0 ]; then
|
if [ "$fail_count" -ne 0 ]; then
|
||||||
exit 4
|
exit 4
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user