Files
calista_main/ccomp/ccomp
T

531 lines
19 KiB
Bash
Executable File

#!/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 "$@"