diff --git a/internal/builtins/updater.go b/internal/builtins/updater.go index e4ec824..8b354d7 100644 --- a/internal/builtins/updater.go +++ b/internal/builtins/updater.go @@ -33,6 +33,7 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport/http" "go.elara.ws/logger/log" "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/permissions" "go.starlark.net/starlark" "go.starlark.net/starlarkstruct" ) @@ -88,7 +89,7 @@ func updaterPull(cfg *config.Config) *starlark.Builtin { } // Исправляем права доступа после git pull - err = fixRepoPermissions(repoDir) + err = permissions.FixRepoPermissions(repoDir) if err != nil { log.Warn("Failed to fix repository permissions after pull").Str("repo", repoName).Err(err).Send() } @@ -98,28 +99,6 @@ func updaterPull(cfg *config.Config) *starlark.Builtin { }) } -// fixRepoPermissions рекурсивно устанавливает права 775 для директорий и 664 для файлов -func fixRepoPermissions(path string) error { - return filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - // Пропускаем директорию .git и её содержимое - // Git управляет правами самостоятельно, не нужно их трогать - if info.IsDir() && info.Name() == ".git" { - return filepath.SkipDir - } - - if info.IsDir() { - // Устанавливаем права 2775 для директорий (setgid) - return os.Chmod(filePath, 0o2775) - } else { - // Устанавливаем права 664 для файлов - return os.Chmod(filePath, 0o664) - } - }) -} func updaterPushChanges(cfg *config.Config) *starlark.Builtin { return starlark.NewBuiltin("updater.push_changes", func(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { @@ -267,6 +246,11 @@ func writePackageFile(cfg *config.Config) *starlark.Builtin { return nil, err } + // Восстанавливаем права на файл + if err := permissions.FixFilePermissions(path); err != nil { + log.Warn("Failed to fix file permissions").Str("path", path).Err(err).Send() + } + log.Debug("Wrote package file").Str("repo", repoName).Str("package", pkg).Str("filename", filename).Stringer("pos", thread.CallFrame(1).Pos).Send() return starlark.None, nil }) @@ -388,13 +372,18 @@ func updateChecksums(cfg *config.Config) *starlark.Builtin { return nil, err } + // Восстанавливаем права на файл + if err := permissions.FixFilePermissions(path); err != nil { + log.Warn("Failed to fix file permissions").Str("path", path).Err(err).Send() + } + log.Debug("Updated package file with checksums"). Str("repo", repoName). Str("package", pkg). Str("filename", filename). Int("checksums_count", len(checksumStrings)). Stringer("pos", thread.CallFrame(1).Pos).Send() - + return starlark.None, nil }) } diff --git a/internal/generator/plugin_generator.go b/internal/generator/plugin_generator.go index 94ad290..f073d31 100644 --- a/internal/generator/plugin_generator.go +++ b/internal/generator/plugin_generator.go @@ -9,6 +9,8 @@ import ( "text/template" "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/permissions" + "go.elara.ws/logger/log" ) // PluginTemplate представляет шаблон плагина @@ -383,6 +385,11 @@ func (pg *PluginGenerator) GeneratePlugin(detected DetectedPackage, repoName str return fmt.Errorf("failed to execute template: %w", err) } + // Восстанавливаем права на файл плагина + if err := permissions.FixFilePermissions(pluginFile); err != nil { + log.Warn("Failed to fix plugin file permissions").Str("path", pluginFile).Err(err).Send() + } + fmt.Printf("✅ Generated plugin: %s\n", pluginFile) return nil } diff --git a/internal/logger/file_logger.go b/internal/logger/file_logger.go index 4accee5..06b34c7 100644 --- a/internal/logger/file_logger.go +++ b/internal/logger/file_logger.go @@ -25,6 +25,8 @@ import ( "path/filepath" "sync" "time" + + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/permissions" ) type RotatingFileWriter struct { @@ -37,10 +39,16 @@ type RotatingFileWriter struct { func NewRotatingFileWriter(filename string, maxSize int64) (*RotatingFileWriter, error) { dir := filepath.Dir(filename) - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.MkdirAll(dir, 0o2775); err != nil { return nil, fmt.Errorf("failed to create log directory: %w", err) } + // Восстанавливаем права на директорию логов + if err := permissions.FixDirectoryPermissions(dir); err != nil { + // Не критичная ошибка, продолжаем работу + fmt.Fprintf(os.Stderr, "Warning: failed to fix log directory permissions: %v\n", err) + } + rfw := &RotatingFileWriter{ filename: filename, maxSize: maxSize, @@ -54,11 +62,17 @@ func NewRotatingFileWriter(filename string, maxSize int64) (*RotatingFileWriter, } func (rfw *RotatingFileWriter) openFile() error { - file, err := os.OpenFile(rfw.filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) + file, err := os.OpenFile(rfw.filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o664) if err != nil { return fmt.Errorf("failed to open log file: %w", err) } + // Восстанавливаем права на файл лога + if err := permissions.FixFilePermissions(rfw.filename); err != nil { + // Не критичная ошибка, продолжаем работу + fmt.Fprintf(os.Stderr, "Warning: failed to fix log file permissions: %v\n", err) + } + info, err := file.Stat() if err != nil { file.Close() diff --git a/internal/permissions/permissions.go b/internal/permissions/permissions.go new file mode 100644 index 0000000..43025d5 --- /dev/null +++ b/internal/permissions/permissions.go @@ -0,0 +1,61 @@ +/* + * ALR Updater - Automated updater bot for ALR packages + * Copyright (C) 2025 The ALR Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package permissions + +import ( + "os" + "path/filepath" +) + +// FixFilePermissions устанавливает права 664 для файла +// Используется для всех файлов, создаваемых программой, чтобы они были доступны +// для чтения и записи группе (wheel), даже если файл создан от пользователя alr-updater +func FixFilePermissions(filePath string) error { + return os.Chmod(filePath, 0o664) +} + +// FixDirectoryPermissions устанавливает права 2775 для директории (с setgid битом) +// Бит setgid (2000) гарантирует, что все новые файлы в директории будут принадлежать группе директории +func FixDirectoryPermissions(dirPath string) error { + return os.Chmod(dirPath, 0o2775) +} + +// FixRepoPermissions рекурсивно устанавливает права 775 для директорий и 664 для файлов +// Пропускает директорию .git, так как Git управляет правами самостоятельно +func FixRepoPermissions(path string) error { + return filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + // Пропускаем директорию .git и её содержимое + // Git управляет правами самостоятельно, не нужно их трогать + if info.IsDir() && info.Name() == ".git" { + return filepath.SkipDir + } + + if info.IsDir() { + // Устанавливаем права 2775 для директорий (setgid) + return os.Chmod(filePath, 0o2775) + } else { + // Устанавливаем права 664 для файлов + return os.Chmod(filePath, 0o664) + } + }) +} \ No newline at end of file diff --git a/main.go b/main.go index 0de52e8..720885d 100644 --- a/main.go +++ b/main.go @@ -38,6 +38,7 @@ import ( "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config" "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/generator" filelogger "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/logger" + "gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/permissions" "go.etcd.io/bbolt" "go.starlark.net/starlark" "golang.org/x/crypto/bcrypt" @@ -80,22 +81,6 @@ func parseRepositoryFromPlugin(filePath string) (string, error) { return "", scanner.Err() } -// fixRepoPermissions рекурсивно устанавливает права 775 для директорий и 664 для файлов -func fixRepoPermissions(path string) error { - return filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if info.IsDir() { - // Устанавливаем права 2775 для директорий (setgid) - return os.Chmod(filePath, 0o2775) - } else { - // Устанавливаем права 664 для файлов - return os.Chmod(filePath, 0o664) - } - }) -} func main() { configPath := pflag.StringP("config", "c", "/etc/alr-updater/config.toml", "Path to config file") @@ -262,7 +247,7 @@ func main() { } // Исправляем права доступа после клонирования - if err := fixRepoPermissions(repoDir); err != nil { + if err := permissions.FixRepoPermissions(repoDir); err != nil { log.Error("Error fixing repository permissions").Str("repo", repoName).Err(err).Send() }