531 lines
19 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# calista-manager - Менеджер компонентов Calista OS
# Конфигурация
SYSTEM_DIR="/calista"
REGISTRY_FILE="$SYSTEM_DIR/registry.db"
GPROXY_SCRIPT="/usr/local/bin/gproxy" # Путь к gproxy скрипту
GPROXY_CACHE=/calista/cache/gproxy/
# Цвета
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Логирование
log() {
echo -e "${GREEN}[+]${NC} $1"
}
error() {
echo -e "${RED}[!]${NC} $1" >&2
}
warn() {
echo -e "${YELLOW}[*]${NC} $1"
}
info() {
echo -e "${BLUE}[i]${NC} $1"
}
# Запись в лог реестра
log_to_registry() {
TYPE="$1"
USER="${SUDO_USER:-$USER}"
DETAILS="$2"
sqlite3 "$REGISTRY_FILE" "INSERT INTO calista_log (type, user, details) VALUES ('$TYPE', '$USER', '$DETAILS');" 2>/dev/null
}
# Проверка инициализации реестра
check_init() {
if [ ! -f "$REGISTRY_FILE" ]; then
error "Реестр не найден: $REGISTRY_FILE"
error "Сначала инициализируйте реестр Calista"
exit 1
fi
if [ ! -x "$GPROXY_SCRIPT" ]; then
error "Не найден gproxy скрипт: $GPROXY_SCRIPT"
error "Поместите calista-proxy.sh в текущий каталог"
exit 1
fi
}
# Проверка наличия компонента в реестре
is_installed() {
COMP_ID="$1"
RESULT=$(sqlite3 "$REGISTRY_FILE" "SELECT COUNT(*) FROM components WHERE name = '$COMP_ID';" 2>/dev/null)
[ "$RESULT" -gt 0 ] 2>/dev/null
}
# Добавление компонента в реестр
add_to_registry() {
COMP_ID="$1"
VERSION="$2"
SOURCE="$3"
DESCRIPTION="$4"
INSTALLED_AT=$(date '+%Y-%m-%d %H:%M:%S')
# Проверяем, существует ли уже компонент
EXISTS=$(sqlite3 "$REGISTRY_FILE" "SELECT COUNT(*) FROM components WHERE name = '$COMP_ID';" 2>/dev/null)
if [ "$EXISTS" -gt 0 ] 2>/dev/null; then
# Обновляем существующий компонент
sqlite3 "$REGISTRY_FILE" "UPDATE components SET
version = '$VERSION',
source = '$SOURCE',
description = '$DESCRIPTION',
installed_at = '$INSTALLED_AT'
WHERE name = '$COMP_ID';" 2>/dev/null
log_to_registry "info" "Компонент $COMP_ID обновлен до версии $VERSION"
info "Компонент '$COMP_ID' обновлен в реестре"
else
# Добавляем новый компонент
sqlite3 "$REGISTRY_FILE" "INSERT INTO components (name, version, source, description, installed_at)
VALUES ('$COMP_ID', '$VERSION', '$SOURCE', '$DESCRIPTION', '$INSTALLED_AT');" 2>/dev/null
log_to_registry "info" "Компонент $COMP_ID версии $VERSION установлен"
info "Компонент '$COMP_ID' добавлен в реестр"
fi
}
# Удаление компонента из реестра
remove_from_registry() {
COMP_ID="$1"
sqlite3 "$REGISTRY_FILE" "DELETE FROM components WHERE name = '$COMP_ID';" 2>/dev/null
log_to_registry "info" "Компонент $COMP_ID удален из реестра"
}
# Получение информации о компоненте из gproxy
get_component_info() {
COMP_ID="$1"
VERSION="$2"
# Получаем компонент через gproxy
if [ "$VERSION" = "latest" ]; then
"$GPROXY_SCRIPT" get "$COMP_ID"
else
"$GPROXY_SCRIPT" get "$COMP_ID" "$VERSION"
fi
}
# Установка из Git
install_from_git() {
COMP_ID="$1"
VERSION="$2"
log "Установка компонента '$COMP_ID' версии '$VERSION' из Git"
# Проверяем не установлен ли уже
if is_installed "$COMP_ID"; then
warn "Компонент '$COMP_ID' уже установлен"
# Получаем текущую версию
CURRENT_VERSION=$(sqlite3 "$REGISTRY_FILE" "SELECT version FROM components WHERE name = '$COMP_ID';" 2>/dev/null)
info "Текущая версия: $CURRENT_VERSION"
echo "Переустановить? (y/N): "
read -r answer
if [ "$answer" != "y" ] && [ "$answer" != "Y" ]; then
echo "Установка отменена"
return 1
fi
fi
# Получаем компонент через gproxy
info "Загрузка компонента через gproxy..."
gproxy set-repo ssh://git@gitlab.svsptech.ru:5598/svsptech/calista-components.git
OUTPUT=$(get_component_info "$COMP_ID" "$VERSION")
if echo "$OUTPUT" | grep -q "склонирован в:"; then
# Извлекаем путь из вывода gproxy
REPO_PATH="$GPROXY_CACHE$COMP_ID"
if [ -d "$REPO_PATH" ]; then
log "Компонент загружен в: $REPO_PATH"
# Ищем файл build
if [ -x "$REPO_PATH/build" ]; then
info "Запуск скрипта сборки..."
cd "$REPO_PATH"
if ./build; then
log "Сборка завершена успешно"
# Получаем описание компонента
DESC="Компонент $COMP_ID"
if [ -f "README.md" ]; then
DESC=$(head -1 "README.md" 2>/dev/null | cut -c -100)
elif [ -f "description.txt" ]; then
DESC=$(head -1 "description.txt" 2>/dev/null | cut -c -100)
fi
# Экранируем кавычки для SQL
DESC=$(echo "$DESC" | sed "s/'/''/g")
# Добавляем в реестр
add_to_registry "$COMP_ID" "$VERSION" "git" "$DESC"
# Очищаем кэш gproxy
info "Очистка кэша gproxy..."
"$GPROXY_SCRIPT" clean
log "Компонент '$COMP_ID' успешно установлен"
else
error "Ошибка сборки компонента"
log_to_registry "error" "Ошибка сборки компонента $COMP_ID"
cd - >/dev/null
return 1
fi
cd - >/dev/null
else
warn "Файл build не найден или не исполняемый"
info "Попытка найти альтернативные скрипты..."
# Проверяем другие возможные скрипты
INSTALLED=false
for script in install.sh setup.sh configure.sh; do
if [ -x "$REPO_PATH/$script" ]; then
info "Найден скрипт: $script"
cd "$REPO_PATH"
if ./"$script"; then
log "Установка завершена успешно"
# Получаем описание
DESC="Компонент $COMP_ID"
if [ -f "README.md" ]; then
DESC=$(head -1 "README.md" 2>/dev/null | cut -c -100)
fi
# Экранируем кавычки для SQL
DESC=$(echo "$DESC" | sed "s/'/''/g")
add_to_registry "$COMP_ID" "$VERSION" "git" "$DESC"
"$GPROXY_SCRIPT" clean
log "Компонент '$COMP_ID' успешно установлен"
INSTALLED=true
cd - >/dev/null
break
fi
cd - >/dev/null
fi
done
if [ "$INSTALLED" = false ]; then
error "Не найден скрипт установки"
return 1
fi
fi
else
error "Не удалось определить путь к загруженному компоненту"
log_to_registry "error" "Не удалось определить путь к компоненту $COMP_ID"
return 1
fi
else
error "Не удалось загрузить компонент через gproxy"
echo "Вывод gproxy: $OUTPUT"
log_to_registry "error" "Не удалось загрузить компонент $COMP_ID через gproxy"
return 1
fi
}
# Установка локального компонента (заглушка)
install_local() {
COMP_ID="$1"
VERSION="$2"
warn "Локальная установка компонентов пока не реализована"
echo "Идентификатор: $COMP_ID"
echo "Версия: $VERSION"
echo "Функционал в разработке..."
return 1
}
# Команда установки
cmd_install() {
if [ -z "$1" ]; then
echo "Использование: $0 install <component-id> [version] [source]" >&2
echo " source: git (по умолчанию) или local" >&2
echo " version: номер версии или 'latest' (по умолчанию)" >&2
exit 1
fi
check_init
COMP_ID="$1"
VERSION="${2:-latest}"
SOURCE="${3:-git}"
case "$SOURCE" in
git)
install_from_git "$COMP_ID" "$VERSION"
;;
local)
install_local "$COMP_ID" "$VERSION"
;;
*)
error "Неизвестный источник: $SOURCE"
echo "Допустимые значения: git, local" >&2
exit 1
;;
esac
}
# Команда списка установленных компонентов
cmd_list() {
check_init
# Проверяем количество компонентов
COUNT=$(sqlite3 "$REGISTRY_FILE" "SELECT COUNT(*) FROM components;" 2>/dev/null)
if [ "$COUNT" -eq 0 ] 2>/dev/null; then
echo "Нет установленных компонентов"
return 0
fi
echo "Установленные компоненты:"
echo "========================="
echo ""
# Получаем и выводим список компонентов
sqlite3 "$REGISTRY_FILE" "SELECT name, version, source, description, installed_at FROM components ORDER BY name;" 2>/dev/null | while IFS='|' read -r id version source desc installed; do
if [ -n "$id" ]; then
echo "Компонент: $id"
echo " Версия: ${version:-не указана}"
echo " Описание: ${desc:-нет описания}"
echo " Источник: ${source:-не указан}"
echo " Установлен: ${installed:-неизвестно}"
echo ""
fi
done
echo "Всего компонентов: $COUNT"
}
# Команда информации о компоненте
cmd_info() {
if [ -z "$1" ]; then
echo "Использование: $0 info <component-id>" >&2
exit 1
fi
check_init
COMP_ID="$1"
if is_installed "$COMP_ID"; then
echo "Информация о компоненте: $COMP_ID"
echo "================================"
# Получаем информацию из реестра
sqlite3 "$REGISTRY_FILE" "SELECT name, version, source, description, installed_at FROM components WHERE name = '$COMP_ID';" 2>/dev/null | while IFS='|' read -r id version source desc installed; do
echo "Идентификатор: $id"
echo "Версия: ${version:-не указана}"
echo "Описание: ${desc:-нет описания}"
echo "Источник: ${source:-не указан}"
echo "Дата установки: ${installed:-неизвестно}"
done
else
echo "Компонент '$COMP_ID' не установлен"
# Предлагаем установить
echo ""
info "Для установки компонента используйте:"
echo " $0 install $COMP_ID"
fi
}
# Команда обновления списка компонентов
cmd_update() {
check_init
log "Обновление списка компонентов через gproxy..."
"$GPROXY_SCRIPT" update
log_to_registry "info" "Список компонентов обновлен через gproxy"
}
# Команда показа версий компонента из репозитория
cmd_versions() {
if [ -z "$1" ]; then
echo "Использование: $0 versions <component-id>" >&2
exit 1
fi
check_init
COMP_ID="$1"
# Проверяем, установлен ли компонент
if is_installed "$COMP_ID"; then
CURRENT_VERSION=$(sqlite3 "$REGISTRY_FILE" "SELECT version FROM components WHERE name = '$COMP_ID';" 2>/dev/null)
info "Текущая установленная версия: $CURRENT_VERSION"
fi
echo ""
warn "Получение доступных версий для $COMP_ID..."
info "Для просмотра доступных версий используйте gproxy напрямую:"
echo " $GPROXY_SCRIPT list"
echo ""
info "Или установите последнюю версию:"
echo " $0 install $COMP_ID latest"
}
# Команда удаления компонента
cmd_remove() {
if [ -z "$1" ]; then
echo "Использование: $0 remove <component-id>" >&2
exit 1
fi
check_init
COMP_ID="$1"
if is_installed "$COMP_ID"; then
# Получаем информацию о компоненте
info "Информация о компоненте:"
cmd_info "$COMP_ID"
echo ""
warn "Вы уверены, что хотите удалить компонент '$COMP_ID'?"
echo "Это действие удалит запись из реестра (файлы компонента останутся)"
echo "Продолжить? (y/N): "
read -r answer
if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
remove_from_registry "$COMP_ID"
log "Компонент '$COMP_ID' удален из реестра"
warn "Файлы компонента не были удалены"
else
echo "Удаление отменено"
fi
else
echo "Компонент '$COMP_ID' не установлен"
fi
}
# Команда очистки логов
cmd_clean_logs() {
check_init
DAYS="${1:-30}"
info "Очистка логов старше $DAYS дней..."
sqlite3 "$REGISTRY_FILE" "DELETE FROM calista_log WHERE timestamp < datetime('now', '-$DAYS days');" 2>/dev/null
DELETED=$(sqlite3 "$REGISTRY_FILE" "SELECT changes();" 2>/dev/null)
log "Удалено $DELETED записей из лога"
log_to_registry "info" "Очищены логи старше $DAYS дней"
}
# Команда просмотра логов
cmd_logs() {
check_init
LIMIT="${1:-20}"
echo "Последние $LIMIT записей лога:"
echo "==============================="
echo ""
sqlite3 "$REGISTRY_FILE" "SELECT timestamp, type, user, details FROM calista_log ORDER BY timestamp DESC LIMIT $LIMIT;" 2>/dev/null | while IFS='|' read -r timestamp type user details; do
case "$type" in
"error")
echo -e "${RED}[$timestamp]${NC} [$type] $user: $details"
;;
"info")
echo -e "${GREEN}[$timestamp]${NC} [$type] $user: $details"
;;
*)
echo "[$timestamp] [$type] $user: $details"
;;
esac
done
}
# Команда помощи
cmd_help() {
echo "Calista Component Manager"
echo "========================="
echo "Команды:"
echo " install <id> [version] [source] - Установить компонент"
echo " (source: git или local, по умолчанию git)"
echo " list - Показать установленные компоненты"
echo " info <id> - Информация об установленном компоненте"
echo " remove <id> - Удалить компонент из реестра"
echo " update - Обновить список компонентов из репозитория"
echo " versions <id> - Показать доступные версии компонента"
echo " logs [limit] - Показать последние записи лога (по умолчанию 20)"
echo " clean-logs [days] - Очистить старые логи (по умолчанию старше 30 дней)"
echo " help - Показать эту справку"
echo ""
echo "Примеры:"
echo " $0 install cpm v1.0.0 git"
echo " $0 install calista-graphics-legacy latest"
echo " $0 list"
echo " $0 info cpm"
echo " $0 remove cpm"
echo " $0 logs 50"
echo " $0 clean-logs 60"
echo ""
echo "Путь к реестру: $REGISTRY_FILE"
echo ""
echo "Для работы с репозиторием компонентов сначала настройте gproxy:"
echo " $GPROXY_SCRIPT set-repo <ваш-git-репозиторий>"
echo " $0 update"
}
# Главная функция
main() {
case "$1" in
install)
cmd_install "$2" "$3" "$4"
;;
list)
cmd_list
;;
info)
cmd_info "$2"
;;
remove)
cmd_remove "$2"
;;
update)
cmd_update
;;
versions)
cmd_versions "$2"
;;
logs)
cmd_logs "$2"
;;
clean-logs)
cmd_clean_logs "$2"
;;
help|--help|-h)
cmd_help
;;
*)
if [ -z "$1" ]; then
cmd_help
else
error "Неизвестная команда: $1"
echo "Используйте: $0 help" >&2
exit 1
fi
;;
esac
}
# Проверка root прав для установки
if [ "$(id -u)" -ne 0 ] && [ "$1" = "install" ]; then
warn "Для установки компонентов рекомендуется запускать от root"
echo "Продолжить? (y/N): "
read -r answer
if [ "$answer" != "y" ] && [ "$answer" != "Y" ]; then
exit 1
fi
fi
# Запуск
main "$@"