Улучшена логика создания конфига при новом запуске и при появлении новых опций (миграция)
This commit is contained in:
@@ -22,11 +22,13 @@ package config
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/goccy/go-yaml"
|
"github.com/goccy/go-yaml"
|
||||||
"github.com/knadh/koanf/providers/confmap"
|
"github.com/knadh/koanf/providers/confmap"
|
||||||
"github.com/knadh/koanf/v2"
|
"github.com/knadh/koanf/v2"
|
||||||
|
ktoml "github.com/knadh/koanf/parsers/toml/v2"
|
||||||
|
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/internal/constants"
|
"gitea.plemya-x.ru/Plemya-x/ALR/internal/constants"
|
||||||
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
"gitea.plemya-x.ru/Plemya-x/ALR/pkg/types"
|
||||||
@@ -134,26 +136,13 @@ func (c *ALRConfig) ToYAML() (string, error) {
|
|||||||
func (c *ALRConfig) migrateConfig() error {
|
func (c *ALRConfig) migrateConfig() error {
|
||||||
// Проверяем, существует ли конфигурационный файл
|
// Проверяем, существует ли конфигурационный файл
|
||||||
if _, err := os.Stat(constants.SystemConfigPath); os.IsNotExist(err) {
|
if _, err := os.Stat(constants.SystemConfigPath); os.IsNotExist(err) {
|
||||||
// Если файла нет, но конфигурация уже загружена (из defaults или env),
|
// Если файла нет, создаем полный конфигурационный файл с дефолтными значениями
|
||||||
// создаем файл с настройкой по умолчанию
|
if err := c.createDefaultConfig(); err != nil {
|
||||||
needsCreation := false
|
// Если не удается создать конфиг, это не критично - продолжаем работу
|
||||||
|
// но выводим предупреждение
|
||||||
// Проверяем, установлена ли переменная окружения ALR_UPDATESYSTEMONUPGRADE
|
fmt.Fprintf(os.Stderr, "Предупреждение: не удалось создать конфигурационный файл %s: %v\n", constants.SystemConfigPath, err)
|
||||||
if os.Getenv("ALR_UPDATESYSTEMONUPGRADE") == "" {
|
|
||||||
// Если переменная не установлена, проверяем наличие пакетов ALR
|
|
||||||
// чтобы определить, нужно ли включить эту опцию для обновления
|
|
||||||
needsCreation = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if needsCreation {
|
|
||||||
// Устанавливаем значение false по умолчанию для новой опции
|
|
||||||
c.System.SetUpdateSystemOnUpgrade(false)
|
|
||||||
// Сохраняем конфигурацию
|
|
||||||
if err := c.System.Save(); err != nil {
|
|
||||||
// Если не удается сохранить - это не критично, продолжаем работу
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Если файл существует, проверяем, есть ли в нем новая опция
|
// Если файл существует, проверяем, есть ли в нем новая опция
|
||||||
if !c.System.k.Exists("updateSystemOnUpgrade") {
|
if !c.System.k.Exists("updateSystemOnUpgrade") {
|
||||||
@@ -170,6 +159,100 @@ func (c *ALRConfig) migrateConfig() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ALRConfig) createDefaultConfig() error {
|
||||||
|
// Проверяем, запущен ли процесс от root
|
||||||
|
if os.Getuid() != 0 {
|
||||||
|
// Если не root, пытаемся запустить создание конфига с повышением привилегий
|
||||||
|
return c.createDefaultConfigWithPrivileges()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если уже root, создаем конфиг напрямую
|
||||||
|
return c.doCreateDefaultConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ALRConfig) createDefaultConfigWithPrivileges() error {
|
||||||
|
// Если useRootCmd отключен, просто пытаемся создать без повышения привилегий
|
||||||
|
if !c.cfg.UseRootCmd {
|
||||||
|
return c.doCreateDefaultConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Определяем команду для повышения привилегий
|
||||||
|
rootCmd := c.cfg.RootCmd
|
||||||
|
if rootCmd == "" {
|
||||||
|
rootCmd = "sudo" // fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создаем временный файл с дефолтной конфигурацией
|
||||||
|
tmpFile, err := os.CreateTemp("", "alr-config-*.toml")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("не удалось создать временный файл: %w", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(tmpFile.Name())
|
||||||
|
defer tmpFile.Close()
|
||||||
|
|
||||||
|
// Генерируем дефолтную конфигурацию во временный файл
|
||||||
|
defaults := defaultConfigKoanf()
|
||||||
|
tempSystemConfig := &SystemConfig{k: defaults}
|
||||||
|
|
||||||
|
bytes, err := tempSystemConfig.k.Marshal(ktoml.Parser())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("не удалось сериализовать конфигурацию: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := tmpFile.Write(bytes); err != nil {
|
||||||
|
return fmt.Errorf("не удалось записать во временный файл: %w", err)
|
||||||
|
}
|
||||||
|
tmpFile.Close()
|
||||||
|
|
||||||
|
// Используем команду повышения привилегий для создания директории и копирования файла
|
||||||
|
|
||||||
|
// Создаем директорию с правами
|
||||||
|
configDir := filepath.Dir(constants.SystemConfigPath)
|
||||||
|
mkdirCmd := exec.Command(rootCmd, "mkdir", "-p", configDir)
|
||||||
|
if err := mkdirCmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("не удалось создать директорию %s: %w", configDir, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Копируем файл в нужное место
|
||||||
|
cpCmd := exec.Command(rootCmd, "cp", tmpFile.Name(), constants.SystemConfigPath)
|
||||||
|
if err := cpCmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("не удалось скопировать конфигурацию в %s: %w", constants.SystemConfigPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Устанавливаем правильные права доступа
|
||||||
|
chmodCmd := exec.Command(rootCmd, "chmod", "644", constants.SystemConfigPath)
|
||||||
|
if err := chmodCmd.Run(); err != nil {
|
||||||
|
// Не критично, продолжаем
|
||||||
|
fmt.Fprintf(os.Stderr, "Предупреждение: не удалось установить права доступа для %s: %v\n", constants.SystemConfigPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ALRConfig) doCreateDefaultConfig() error {
|
||||||
|
// Проверяем, существует ли директория для конфига
|
||||||
|
configDir := filepath.Dir(constants.SystemConfigPath)
|
||||||
|
if _, err := os.Stat(configDir); os.IsNotExist(err) {
|
||||||
|
// Пытаемся создать директорию
|
||||||
|
if err := os.MkdirAll(configDir, 0755); err != nil {
|
||||||
|
return fmt.Errorf("не удалось создать директорию %s: %w", configDir, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Загружаем дефолтную конфигурацию
|
||||||
|
defaults := defaultConfigKoanf()
|
||||||
|
|
||||||
|
// Копируем все дефолтные значения в системную конфигурацию
|
||||||
|
c.System.k = defaults
|
||||||
|
|
||||||
|
// Сохраняем конфигурацию в файл
|
||||||
|
if err := c.System.Save(); err != nil {
|
||||||
|
return fmt.Errorf("не удалось сохранить конфигурацию в %s: %w", constants.SystemConfigPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *ALRConfig) RootCmd() string { return c.cfg.RootCmd }
|
func (c *ALRConfig) RootCmd() string { return c.cfg.RootCmd }
|
||||||
func (c *ALRConfig) PagerStyle() string { return c.cfg.PagerStyle }
|
func (c *ALRConfig) PagerStyle() string { return c.cfg.PagerStyle }
|
||||||
func (c *ALRConfig) AutoPull() bool { return c.cfg.AutoPull }
|
func (c *ALRConfig) AutoPull() bool { return c.cfg.AutoPull }
|
||||||
|
Reference in New Issue
Block a user