Изменение: улучшение управления мьютексами и правами доступа

This commit is contained in:
2025-11-06 20:03:26 +03:00
parent 4260e09b62
commit b8e35570f8
2 changed files with 64 additions and 15 deletions

View File

@@ -52,9 +52,23 @@ func updaterModule(cfg *config.Config) *starlarkstruct.Module {
}
}
// repoMtx makes sure two starlark threads can
// never access the repo at the same time
var repoMtx = &sync.Mutex{}
// repoMtxMap provides a mutex for each repository to avoid blocking
// operations on one repo from affecting another
var repoMtxMap = make(map[string]*sync.Mutex)
var repoMtxMapMtx = &sync.Mutex{} // protects the map itself
func getRepoMutex(repoName string) *sync.Mutex {
repoMtxMapMtx.Lock()
defer repoMtxMapMtx.Unlock()
mtx, exists := repoMtxMap[repoName]
if !exists {
mtx = &sync.Mutex{}
repoMtxMap[repoName] = mtx
}
return mtx
}
func updaterPull(cfg *config.Config) *starlark.Builtin {
return starlark.NewBuiltin("updater.pull", func(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@@ -69,8 +83,9 @@ func updaterPull(cfg *config.Config) *starlark.Builtin {
return nil, fmt.Errorf("repository '%s' not found in configuration", repoName)
}
repoMtx.Lock()
defer repoMtx.Unlock()
mtx := getRepoMutex(repoName)
mtx.Lock()
defer mtx.Unlock()
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
repo, err := git.PlainOpen(repoDir)
@@ -113,8 +128,9 @@ func updaterPushChanges(cfg *config.Config) *starlark.Builtin {
return nil, fmt.Errorf("repository '%s' not found in configuration", repoName)
}
repoMtx.Lock()
defer repoMtx.Unlock()
mtx := getRepoMutex(repoName)
mtx.Lock()
defer mtx.Unlock()
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
repo, err := git.PlainOpen(repoDir)
@@ -192,8 +208,12 @@ func getPackageFile(cfg *config.Config) *starlark.Builtin {
return nil, fmt.Errorf("repository '%s' not found in configuration", repoName)
}
repoMtx.Lock()
defer repoMtx.Unlock()
// Для этой функции мы не обязательно нуждаемся в мьютексе Git,
// так как это только чтение файлов, а не Git операции
// Но для консистентности и безопасности будем использовать мьютекс
mtx := getRepoMutex(repoName)
mtx.Lock()
defer mtx.Unlock()
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
path := filepath.Join(repoDir, pkg, filename)
@@ -220,8 +240,10 @@ func writePackageFile(cfg *config.Config) *starlark.Builtin {
return nil, fmt.Errorf("repository '%s' not found in configuration", repoName)
}
repoMtx.Lock()
defer repoMtx.Unlock()
// Используем мьютекс для согласованности с другими операциями
mtx := getRepoMutex(repoName)
mtx.Lock()
defer mtx.Unlock()
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
path := filepath.Join(repoDir, pkg, filename)
@@ -345,8 +367,9 @@ func updateChecksums(cfg *config.Config) *starlark.Builtin {
updatedContent := updateChecksumsInContent(content, checksumStrings)
// Автоматически сбрасываем release='1' при изменении версии
repoMtx.Lock()
defer repoMtx.Unlock()
mtx := getRepoMutex(repoName)
mtx.Lock()
defer mtx.Unlock()
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
path := filepath.Join(repoDir, pkg, filename)

View File

@@ -103,19 +103,45 @@ func FixRepoPermissions(path string) error {
// Получаем UID и GID для alr-updater:wheel
uid, gid, err := getAlrUpdaterIDs()
if err != nil {
return fmt.Errorf("failed to get alr-updater IDs: %w", err)
}
// Если не можем получить ID (например, в dev-окружении), только устанавливаем права
return filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Изменяем владельца на alr-updater:wheel
if err := os.Chown(filePath, uid, gid); err != nil {
return fmt.Errorf("failed to chown %s: %w", filePath, err)
}
if info.IsDir() {
// Устанавливаем права 2775 для директорий (setgid)
if err := os.Chmod(filePath, 0o2775); err != nil {
return fmt.Errorf("failed to chmod directory %s: %w", filePath, err)
}
} else {
// Устанавливаем права 664 для файлов
if err := os.Chmod(filePath, 0o664); err != nil {
return fmt.Errorf("failed to chmod file %s: %w", filePath, err)
}
}
return nil
})
}
return filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Изменяем владельца на alr-updater:wheel
if err := os.Chown(filePath, uid, gid); err != nil {
// Если не удалось изменить владельца (недостаточно прав), всё равно устанавливаем права
if info.IsDir() {
_ = os.Chmod(filePath, 0o2775)
return fmt.Errorf("failed to chown directory %s: %w", filePath, err)
} else {
_ = os.Chmod(filePath, 0o664)
return fmt.Errorf("failed to chown file %s: %w", filePath, err)
}
}
if info.IsDir() {
// Устанавливаем права 2775 для директорий (setgid)
if err := os.Chmod(filePath, 0o2775); err != nil {