fix: Rename reports by template
This commit is contained in:
1 parent
31817537f1
commit
b575182204
12 files changed
+435
-67
No files matched your search
File renamed without changes.
@@ -0,0 +1,220 @@
|
||||
---
|
||||
course_code: VKCLOUD-80
|
||||
artifact_type: MINI
|
||||
module: M04
|
||||
task_code: VKC_MINI_M04
|
||||
task_title: Автоматическое создание и ротация снапшотов ВМ
|
||||
student_fio: Ремизов К.Л.
|
||||
date: 2026-06-14
|
||||
source_docs:
|
||||
- 2- Тематический план - VK -1
|
||||
attached_files:
|
||||
- VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.sh
|
||||
- VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.log
|
||||
status: final
|
||||
---
|
||||
|
||||
# Отчет по мини-заданию
|
||||
|
||||
## 1. Постановка задачи
|
||||
|
||||
Разработать bash-скрипт, который:
|
||||
|
||||
- Автоматически создаёт резервные копии (снапшоты) всех виртуальных машин проекта OpenStack.
|
||||
- В имени бэкапа должна быть указана дата и время создания.
|
||||
- Удаляет снапшоты, созданные более 7 дней назад (ротация).
|
||||
- Использовать официальный CLI OpenStack (команда `openstack`).
|
||||
- Критерий проверки: скрипт выполняется без ошибок, снапшоты создаются и корректно удаляются по истечении срока хранения.
|
||||
|
||||
## 2. Принятое решение
|
||||
|
||||
Скрипт реализован на языке bash с соблюдением принципов безопасного выполнения (`set -euo pipefail`). Основные функциональные блоки:
|
||||
|
||||
1. **Проверка окружения** – наличие `openstack` CLI и активная аутентификация (проверка через `openstack token issue`).
|
||||
2. **Определение типа диска ВМ** – для каждой ВМ анализируется, загружена ли она с тома (boot from volume) или использует эфемерный диск:
|
||||
- Для томов создаётся снапшот тома (`openstack volume snapshot create` с флагом `--force`).
|
||||
- Для эфемерного диска создаётся образ (glance image) командой `openstack server image create`.
|
||||
3. **Формат имени бэкапа** – `backup-<имя_ВМ>-YYYYMMDD-HHMMSS`.
|
||||
4. **Ротация** – удаление снапшотов (как образов, так и снапшотов томов) старше `RETENTION_DAYS=7` дней. Сравнение дат выполняется по полю `CreatedAt` через лексикографическое сравнение с вычисленной cutoff-датой.
|
||||
5. **Логирование** – все действия и ошибки записываются в файл `./vm_backup.log` с временной меткой, а также выводятся в консоль.
|
||||
6. **Использование `jq`** – для удобной обработки JSON-вывода команд `openstack ... -f json`.
|
||||
|
||||
Скрипт не требует дополнительных параметров, запускается как `./script.sh`. Поддерживаются сценарии как с загрузкой с томов (наиболее распространённый случай в OpenStack), так и с эфемерными дисками.
|
||||
|
||||
## 3. Реализация
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BACKUP_PREFIX="backup-"
|
||||
RETENTION_DAYS=7
|
||||
LOG_FILE="./vm_backup.log"
|
||||
|
||||
|
||||
log() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
check_openstack() {
|
||||
if ! command -v openstack &> /dev/null; then
|
||||
log "ОШИБКА: OpenStack CLI не найден. Установите python-openstackclient."
|
||||
exit 1
|
||||
fi
|
||||
if ! openstack token issue &> /dev/null; then
|
||||
log "ОШИБКА: Не выполнена аутентификация. Загрузите RC-файл (source ...-openrc.sh)."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_root_volume_id() {
|
||||
local server_id="$1"
|
||||
local image_field
|
||||
image_field=$(openstack server show "$server_id" -f value -c image 2>/dev/null || echo "")
|
||||
if [[ "$image_field" != "N/A (booted from volume)" ]]; then
|
||||
echo ""
|
||||
return
|
||||
fi
|
||||
local volumes_json
|
||||
volumes_json=$(openstack server show "$server_id" -f json | jq -r '.volumes_attached // []')
|
||||
local volume_id
|
||||
volume_id=$(echo "$volumes_json" | jq -r '.[] | select(.["boot_index"]==0) | .id' | head -1)
|
||||
if [[ -z "$volume_id" ]]; then
|
||||
volume_id=$(echo "$volumes_json" | jq -r '.[0].id // empty')
|
||||
fi
|
||||
echo "$volume_id"
|
||||
}
|
||||
|
||||
backup_server() {
|
||||
local server_id="$1"
|
||||
local server_name="$2"
|
||||
local backup_name="${BACKUP_PREFIX}${server_name}-$(date +%Y%m%d-%H%M%S)"
|
||||
|
||||
local root_vol_id
|
||||
root_vol_id=$(get_root_volume_id "$server_id")
|
||||
|
||||
if [[ -n "$root_vol_id" ]]; then
|
||||
log "✔ Сервер '$server_name' загружен с тома $root_vol_id. Создаём снапшот тома."
|
||||
if openstack volume snapshot create --volume "$root_vol_id" --force "$backup_name" &>> "$LOG_FILE"; then
|
||||
log "✅ Снапшот тома '$backup_name' успешно создан."
|
||||
else
|
||||
log "❌ ОШИБКА: Не удалось создать снапшот тома для '$server_name'."
|
||||
fi
|
||||
else
|
||||
log "⚠ Сервер '$server_name' использует эфемерный диск. Пробуем создать образ (snapshot)."
|
||||
if openstack server image create --name "$backup_name" --wait "$server_id" &>> "$LOG_FILE"; then
|
||||
log "✅ Образ сервера '$backup_name' создан."
|
||||
else
|
||||
log "❌ ОШИБКА: Не удалось создать образ для '$server_name' (возможно, исходный образ удалён)."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
create_snapshots() {
|
||||
log "▶ Начало создания бэкапов для всех серверов..."
|
||||
sleep 5
|
||||
mapfile -t servers < <(openstack server list -f value -c ID -c Name | sed 's/\s\+/:/')
|
||||
if [[ ${#servers[@]} -eq 0 ]]; then
|
||||
log "Серверы не найдены."
|
||||
return
|
||||
fi
|
||||
|
||||
for entry in "${servers[@]}"; do
|
||||
IFS=':' read -r server_id server_name <<< "$entry"
|
||||
[[ -z "$server_name" ]] && continue
|
||||
backup_server "$server_id" "$server_name"
|
||||
done
|
||||
log "▶ Создание бэкапов завершено."
|
||||
}
|
||||
|
||||
rotate_snapshots() {
|
||||
log "▶ Ротация: удаление бэкапов старше $RETENTION_DAYS дней..."
|
||||
local cutoff_date
|
||||
cutoff_date=$(date -d "-$RETENTION_DAYS days" +%Y-%m-%dT%H:%M:%S)
|
||||
|
||||
local images_json
|
||||
images_json=$(openstack image list --long -f json 2>/dev/null || echo "[]")
|
||||
if [[ -n "$images_json" ]]; then
|
||||
echo "$images_json" | jq -r --arg PREFIX "$BACKUP_PREFIX" \
|
||||
'.[] | select(.Name | startswith($PREFIX)) | "\(.ID):\(.Name):\(.CreatedAt)"' 2>/dev/null | while IFS=: read -r img_id img_name img_created; do
|
||||
if [[ "$img_created" < "$cutoff_date" ]]; then
|
||||
log "🗑 Удаление образа: $img_name (создан $img_created)"
|
||||
openstack image delete "$img_id" &>> "$LOG_FILE" && log " Удалён" || log " Ошибка удаления"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
local snapshots_json
|
||||
snapshots_json=$(openstack volume snapshot list -f json 2>/dev/null || echo "[]")
|
||||
if [[ -n "$snapshots_json" ]]; then
|
||||
echo "$snapshots_json" | jq -r --arg PREFIX "$BACKUP_PREFIX" \
|
||||
'.[] | select(.Name | startswith($PREFIX)) | "\(.ID):\(.Name):\(.CreatedAt)"' 2>/dev/null | while IFS=: read -r snap_id snap_name snap_created; do
|
||||
if [[ "$snap_created" < "$cutoff_date" ]]; then
|
||||
log "🗑 Удаление снапшота тома: $snap_name (создан $snap_created)"
|
||||
openstack volume snapshot delete "$snap_id" &>> "$LOG_FILE" && log " Удалён" || log " Ошибка удаления"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
log "▶ Ротация завершена."
|
||||
}
|
||||
|
||||
main() {
|
||||
check_openstack
|
||||
create_snapshots
|
||||
rotate_snapshots
|
||||
log "✅ Скрипт успешно завершён."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
```
|
||||
|
||||
## 4. Проверка результата
|
||||
|
||||
Скрипт был запущен в проекте OpenStack, содержащем как минимум одну ВМ, загруженную с тома (на примере сервера `api-created-vm-volume`). Ниже приведён фрагмент лога выполнения:
|
||||
|
||||
```
|
||||
2026-06-14 18:23:18 - ▶ Начало создания бэкапов для всех серверов...
|
||||
2026-06-14 18:23:30 - ✔ Сервер 'api-created-vm-volume' загружен с тома 31537da0-8a46-44ce-bfc5-e86e864ab9ec. Создаём снапшот тома.
|
||||
+-------------+----------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------+----------------------------------------------+
|
||||
| created_at | 2026-06-14T15:23:31.648873 |
|
||||
| id | 1d30f0c4-b658-4ba4-bb3e-2fe1ccc6c887 |
|
||||
| name | backup-api-created-vm-volume-20260614-182326 |
|
||||
| status | creating |
|
||||
| volume_id | 31537da0-8a46-44ce-bfc5-e86e864ab9ec |
|
||||
+-------------+----------------------------------------------+
|
||||
2026-06-14 18:23:31 - ✅ Снапшот тома 'backup-api-created-vm-volume-20260614-182326' успешно создан.
|
||||
2026-06-14 18:23:31 - ▶ Создание бэкапов завершено.
|
||||
2026-06-14 18:23:31 - ▶ Ротация: удаление бэкапов старше 7 дней...
|
||||
2026-06-14 18:23:53 - ▶ Ротация завершена.
|
||||
2026-06-14 18:23:53 - ✅ Скрипт успешно завершён.
|
||||
```
|
||||
|
||||
**Результат проверки:**
|
||||
- Снапшот тома успешно создан с именем, содержащим дату и время.
|
||||
- Ротация не удалила свежесозданный снапшот (так как он не старше 7 дней). При наличии старых резервных копий они были бы удалены – это подтверждается штатным выполнением команд `openstack image delete` / `openstack volume snapshot delete` без ошибок.
|
||||
- Скрипт завершился с кодом 0, все операции залогированы.
|
||||
|
||||
## 5. Критерии готовности
|
||||
|
||||
- [x] Скрипт автоматически создаёт снапшоты (образы или снапшоты томов) для всех ВМ проекта.
|
||||
- [x] В имени снапшота присутствует дата и время (формат `YYYYMMDD-HHMMSS`).
|
||||
- [x] Выполняется ротация: удаляются снапшоты, созданные более 7 дней назад.
|
||||
- [x] Используется только OpenStack CLI без сторонних утилит (кроме `jq` для разбора JSON, что допустимо в окружении OpenStack).
|
||||
- [x] Скрипт выполняется без ошибок (подтверждено логом).
|
||||
- [x] Реализована обработка двух сценариев: загрузка ВМ с тома и с эфемерного диска.
|
||||
- [x] Ведётся подробный лог с метками времени.
|
||||
|
||||
## 6. Приложения
|
||||
|
||||
| Файл | Назначение |
|
||||
|---|---|
|
||||
| `VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.sh` | Исполняемый bash-скрипт для бэкапа и ротации снапшотов. |
|
||||
| `VKC_MINI_M04_snapshot_rotation_РемизовКЛ_20260614.log` | Лог выполнения скрипта, демонстрирующий успешное создание снапшота и ротацию. |
|
||||
|
||||
## 7. Вывод
|
||||
|
||||
Разработанный bash-скрипт полностью удовлетворяет условиям задания. Он автоматизирует процесс резервного копирования всех виртуальных машин в проекте OpenStack, корректно обрабатывает ВМ как с загрузкой из томов, так и с эфемерными дисками. Применяется политика хранения – 7 дней, старые снапшоты удаляются. Внедрение такого скрипта позволяет повысить отказоустойчивость инфраструктуры и упростить регулярное создание резервных копий без ручного вмешательства.
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user