Добавление режима для учителя

This commit is contained in:
Anton Dzyk
2025-12-24 12:06:53 +03:00
parent 05c04c49ed
commit 23ea2ed09f
5 changed files with 522 additions and 13 deletions
+287
View File
@@ -0,0 +1,287 @@
#!/bin/bash
# Скрипт для создания группы, репозитория и копирования кода в GitLab
# с назначением прав пользователю из Keycloak
set -e # Прерывать выполнение при ошибках
# === КОНФИГУРАЦИЯ ===
# GitLab Private Token с правами администратора
PRIVATE_TOKEN=$1
# Пользователь из Keycloak (должен существовать в GitLab)
KEYCLOAK_USERNAME=$2
USER_ID=${KEYCLOAK_USERNAME}
GITLAB_URL="https://gitlab.oa2.ru" # URL вашего GitLab
# Данные для новой группы и репозитория
GROUP_NAME="group-${USER_ID}"
GROUP_PATH="group-${USER_ID}" # Может отличаться от имени
GROUP_DESCRIPTION="Группа для пользователя ${USER_ID}"
# Данные для нового репозитория
PROJECT_NAME="task1"
PROJECT_DESCRIPTION="Репозиторий с кодом task1"
# Внешний репозиторий для копирования
SOURCE_REPO_URL="https://git.oa2.ru/dzyk/task1" # Замените на реальный URL
# Уровень доступа для пользователя (owner = 50)
ACCESS_LEVEL=50
# Временная директория для клонирования
TEMP_DIR="/tmp/gitlab-migration-$(date +%s)"
# === ФУНКЦИИ ===
# Функция для логирования
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# Функция для выполнения HTTP запросов к GitLab API
gitlab_api() {
local method=$1
local endpoint=$2
local data=$3
local curl_cmd="curl -s -X $method \
'$GITLAB_URL/api/v4$endpoint' \
-H 'Private-Token: $PRIVATE_TOKEN' \
-H 'Content-Type: application/json'"
if [ ! -z "$data" ]; then
curl_cmd="$curl_cmd -d '$data'"
fi
eval $curl_cmd
}
# Функция для проверки ошибок API
check_api_error() {
local response=$1
local operation=$2
if echo "$response" | jq -e '.error' > /dev/null 2>&1; then
error_msg=$(echo "$response" | jq -r '.error')
log "Ошибка при $operation: $error_msg"
return 1
fi
if echo "$response" | jq -e '.message' > /dev/null 2>&1; then
error_msg=$(echo "$response" | jq -r '.message')
if [ "$error_msg" != "null" ] && [ ! -z "$error_msg" ]; then
log "Ошибка при $operation: $error_msg"
return 1
fi
fi
return 0
}
# === ОСНОВНОЙ СКРИПТ ===
log "Начало выполнения скрипта"
# 1. Проверка зависимостей
log "Проверка зависимостей..."
for cmd in curl jq git; do
if ! command -v $cmd &> /dev/null; then
log "Ошибка: $cmd не установлен"
exit 1
fi
done
log "Все зависимости установлены"
# 2. Поиск пользователя из Keycloak
log "Поиск пользователя '$KEYCLOAK_USERNAME' в GitLab..."
user_search=$(gitlab_api "GET" "/users?username=$KEYCLOAK_USERNAME")
if ! check_api_error "$user_search" "поиске пользователя"; then
exit 1
fi
user_id=$(echo "$user_search" | jq -r '.[0].id')
user_username=$(echo "$user_search" | jq -r '.[0].username')
if [ "$user_id" = "null" ] || [ -z "$user_id" ]; then
log "Ошибка: Пользователь '$KEYCLOAK_USERNAME' не найден в GitLab"
log "Убедитесь, что пользователь вошел через Keycloak хотя бы один раз"
exit 1
fi
log "Найден пользователь: $user_username (ID: $user_id)"
# 4. Создание группы
log "Проверка существования группы '$GROUP_NAME'..."
group_check=$(gitlab_api "GET" "/groups/$GROUP_PATH")
if echo "$group_check" | jq -e '.id' > /dev/null 2>&1; then
group_id=$(echo "$group_check" | jq -r '.id')
log "Группа '$GROUP_NAME' уже существует (ID: $group_id)"
else
log "Создание группы '$GROUP_NAME'..."
group_data=$(jq -n \
--arg name "$GROUP_NAME" \
--arg path "$GROUP_PATH" \
--arg desc "$GROUP_DESCRIPTION" \
--arg visibility "private" \
'{
name: $name,
path: $path,
description: $desc,
visibility: $visibility,
lfs_enabled: true,
request_access_enabled: true
}')
create_group=$(gitlab_api "POST" "/groups" "$group_data")
if ! check_api_error "$create_group" "создании группы"; then
exit 1
fi
group_id=$(echo "$create_group" | jq -r '.id')
log "Группа создана успешно (ID: $group_id)"
fi
# 5. Создание проекта в группе
log "Проверка существования проекта '$PROJECT_NAME' в группе..."
project_check=$(gitlab_api "GET" "/projects/$GROUP_PATH%2F$PROJECT_NAME")
if echo "$project_check" | jq -e '.id' > /dev/null 2>&1; then
project_id=$(echo "$project_check" | jq -r '.id')
log "Проект '$PROJECT_NAME' уже существует (ID: $project_id)"
else
log "Создание проекта '$PROJECT_NAME' в группе..."
project_data=$(jq -n \
--arg name "$PROJECT_NAME" \
--arg path "$PROJECT_NAME" \
--arg desc "$PROJECT_DESCRIPTION" \
--arg namespace_id "$group_id" \
--arg visibility "private" \
'{
name: $name,
path: $path,
description: $desc,
namespace_id: $namespace_id,
visibility: $visibility,
initialize_with_readme: false,
lfs_enabled: true,
container_registry_enabled: true
}')
create_project=$(gitlab_api "POST" "/projects" "$project_data")
if ! check_api_error "$create_project" "создании проекта"; then
exit 1
fi
project_id=$(echo "$create_project" | jq -r '.id')
project_ssh_url=$(echo "$create_project" | jq -r '.ssh_url_to_repo')
project_http_url=$(echo "$create_project" | jq -r '.http_url_to_repo')
log "Проект создан успешно (ID: $project_id)"
log "URL проекта: $project_http_url"
fi
# 6. Назначение прав пользователю как owner группы
log "Проверка прав пользователя $user_username в группе..."
group_members=$(gitlab_api "GET" "/groups/$group_id/members")
user_in_group=$(echo "$group_members" | jq --arg user_id "$user_id" '.[] | select(.id == ($user_id|tonumber))')
if [ -z "$user_in_group" ]; then
log "Назначение прав owner пользователю $user_username в группе..."
member_data=$(jq -n \
--arg user_id "$user_id" \
--arg access_level "$ACCESS_LEVEL" \
'{
user_id: $user_id,
access_level: ($access_level|tonumber)
}')
add_member=$(gitlab_api "POST" "/groups/$group_id/members" "$member_data")
if ! check_api_error "$add_member" "добавлении пользователя в группу"; then
exit 1
fi
log "Пользователю $user_username назначены права owner в группе"
else
current_access=$(echo "$user_in_group" | jq -r '.access_level')
if [ "$current_access" != "$ACCESS_LEVEL" ]; then
log "Обновление прав пользователя $user_username с уровня $current_access на $ACCESS_LEVEL..."
member_data=$(jq -n \
--arg access_level "$ACCESS_LEVEL" \
'{
access_level: ($access_level|tonumber)
}')
update_member=$(gitlab_api "PUT" "/groups/$group_id/members/$user_id" "$member_data")
if ! check_api_error "$update_member" "обновлении прав пользователя"; then
exit 1
fi
log "Права пользователя обновлены"
else
log "Пользователь $user_username уже имеет права owner в группе"
fi
fi
# 7. Клонирование и копирование кода
log "Создание временной директории: $TEMP_DIR"
mkdir -p "$TEMP_DIR"
cd "$TEMP_DIR"
log "Клонирование исходного репозитория: $SOURCE_REPO_URL"
if ! git clone --bare "$SOURCE_REPO_URL" source-repo.git; then
log "Ошибка при клонировании исходного репозитория"
exit 1
fi
log "Клонирование целевого репозитория GitLab"
# Получаем URL репозитория с токеном для записи
repo_url_with_token=$(echo "$project_http_url" | sed "s|https://|https://gitlab-ci-token:$PRIVATE_TOKEN@|")
if ! git clone "$repo_url_with_token" target-repo; then
log "Ошибка при клонировании целевого репозитория"
exit 1
fi
cd target-repo
log "Добавление remote исходного репозитория"
git remote add source ../source-repo.git
log "Получение данных из исходного репозитория"
git fetch source
log "Объединение всех веток из исходного репозитория"
for branch in $(git branch -r | grep 'source/' | sed 's|source/||'); do
if [ "$branch" != "HEAD" ] && [ "$branch" != "->" ]; then
log " Копирование ветки: $branch"
git checkout -b "$branch" "source/$branch" 2>/dev/null || git branch "$branch" "source/$branch"
fi
done
# Возвращаемся в основную ветку (если есть)
if git show-ref --verify --quiet refs/heads/main; then
git checkout main
elif git show-ref --verify --quiet refs/heads/master; then
git checkout master
fi
log "Отправка всех веток в GitLab"
git push --all origin
git push --tags origin
log "Очистка временных файлов"
cd /
rm -rf "$TEMP_DIR"
# 8. Проверка результата
log "Проверка созданной структуры..."
final_check=$(gitlab_api "GET" "/projects/$project_id")
project_name=$(echo "$final_check" | jq -r '.name_with_namespace')
web_url=$(echo "$final_check" | jq -r '.web_url')
log "=== ОТЧЕТ ==="
log "Группа: $GROUP_NAME (ID: $group_id)"
log "Проект: $project_name (ID: $project_id)"
log "URL проекта: $web_url"
log "Пользователь с правами owner: $user_username"
log "Код скопирован из: $SOURCE_REPO_URL"
log ""
log "Скрипт успешно выполнен!"