Изменение: улучшение управления мьютексами и правами доступа
This commit is contained in:
@@ -52,9 +52,23 @@ func updaterModule(cfg *config.Config) *starlarkstruct.Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// repoMtx makes sure two starlark threads can
|
// repoMtxMap provides a mutex for each repository to avoid blocking
|
||||||
// never access the repo at the same time
|
// operations on one repo from affecting another
|
||||||
var repoMtx = &sync.Mutex{}
|
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 {
|
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) {
|
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)
|
return nil, fmt.Errorf("repository '%s' not found in configuration", repoName)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoMtx.Lock()
|
mtx := getRepoMutex(repoName)
|
||||||
defer repoMtx.Unlock()
|
mtx.Lock()
|
||||||
|
defer mtx.Unlock()
|
||||||
|
|
||||||
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
||||||
repo, err := git.PlainOpen(repoDir)
|
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)
|
return nil, fmt.Errorf("repository '%s' not found in configuration", repoName)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoMtx.Lock()
|
mtx := getRepoMutex(repoName)
|
||||||
defer repoMtx.Unlock()
|
mtx.Lock()
|
||||||
|
defer mtx.Unlock()
|
||||||
|
|
||||||
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
||||||
repo, err := git.PlainOpen(repoDir)
|
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)
|
return nil, fmt.Errorf("repository '%s' not found in configuration", repoName)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoMtx.Lock()
|
// Для этой функции мы не обязательно нуждаемся в мьютексе Git,
|
||||||
defer repoMtx.Unlock()
|
// так как это только чтение файлов, а не Git операции
|
||||||
|
// Но для консистентности и безопасности будем использовать мьютекс
|
||||||
|
mtx := getRepoMutex(repoName)
|
||||||
|
mtx.Lock()
|
||||||
|
defer mtx.Unlock()
|
||||||
|
|
||||||
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
||||||
path := filepath.Join(repoDir, pkg, filename)
|
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)
|
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)
|
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
||||||
path := filepath.Join(repoDir, pkg, filename)
|
path := filepath.Join(repoDir, pkg, filename)
|
||||||
@@ -345,8 +367,9 @@ func updateChecksums(cfg *config.Config) *starlark.Builtin {
|
|||||||
updatedContent := updateChecksumsInContent(content, checksumStrings)
|
updatedContent := updateChecksumsInContent(content, checksumStrings)
|
||||||
|
|
||||||
// Автоматически сбрасываем release='1' при изменении версии
|
// Автоматически сбрасываем release='1' при изменении версии
|
||||||
repoMtx.Lock()
|
mtx := getRepoMutex(repoName)
|
||||||
defer repoMtx.Unlock()
|
mtx.Lock()
|
||||||
|
defer mtx.Unlock()
|
||||||
|
|
||||||
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
repoDir := filepath.Join(cfg.ReposBaseDir, repoName)
|
||||||
path := filepath.Join(repoDir, pkg, filename)
|
path := filepath.Join(repoDir, pkg, filename)
|
||||||
|
|||||||
@@ -103,19 +103,45 @@ func FixRepoPermissions(path string) error {
|
|||||||
// Получаем UID и GID для alr-updater:wheel
|
// Получаем UID и GID для alr-updater:wheel
|
||||||
uid, gid, err := getAlrUpdaterIDs()
|
uid, gid, err := getAlrUpdaterIDs()
|
||||||
if err != nil {
|
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 {
|
return filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Изменяем владельца на alr-updater:wheel
|
if info.IsDir() {
|
||||||
if err := os.Chown(filePath, uid, gid); err != nil {
|
// Устанавливаем права 2775 для директорий (setgid)
|
||||||
return fmt.Errorf("failed to chown %s: %w", filePath, err)
|
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() {
|
if info.IsDir() {
|
||||||
// Устанавливаем права 2775 для директорий (setgid)
|
// Устанавливаем права 2775 для директорий (setgid)
|
||||||
if err := os.Chmod(filePath, 0o2775); err != nil {
|
if err := os.Chmod(filePath, 0o2775); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user