Внесение логики для запуска из под root
Some checks failed
Pre-commit / pre-commit (push) Successful in 5m40s
Create Release / changelog (push) Failing after 2m27s

This commit is contained in:
2025-08-27 01:45:54 +03:00
parent 75ece6dfcc
commit 59cc41e94c
5 changed files with 93 additions and 21 deletions

View File

@@ -85,11 +85,18 @@ jobs:
sed -i "s/release='[0-9]\+'/release='1'/g" alr-default/alr-bin/alr.sh sed -i "s/release='[0-9]\+'/release='1'/g" alr-default/alr-bin/alr.sh
- name: Install alr - name: Install alr
env:
CREATE_SYSTEM_RESOURCES: 0
run: | run: |
groupadd wheel
usermod -aG wheel root
make install make install
- name: Prepare directories for ALR
run: |
# Создаём необходимые директории для работы alr build
mkdir -p /tmp/alr/dl /tmp/alr/pkgs /var/cache/alr
chmod -R 777 /tmp/alr
chmod -R 755 /var/cache/alr
- name: Build packages - name: Build packages
run: | run: |
SCRIPT_PATH=alr-default/alr-bin/alr.sh SCRIPT_PATH=alr-default/alr-bin/alr.sh

29
fix.go
View File

@@ -34,6 +34,21 @@ import (
"gitea.plemya-x.ru/Plemya-x/ALR/internal/utils" "gitea.plemya-x.ru/Plemya-x/ALR/internal/utils"
) )
// execWithPrivileges выполняет команду напрямую если root или CI, иначе через sudo
func execWithPrivileges(name string, args ...string) *exec.Cmd {
isRoot := os.Geteuid() == 0
isCI := os.Getenv("CI") == "true"
if !isRoot && !isCI {
// Если не root и не в CI, используем sudo
allArgs := append([]string{name}, args...)
return exec.Command("sudo", allArgs...)
} else {
// Если root или в CI, запускаем напрямую
return exec.Command(name, args...)
}
}
func FixCmd() *cli.Command { func FixCmd() *cli.Command {
return &cli.Command{ return &cli.Command{
Name: "fix", Name: "fix",
@@ -90,7 +105,7 @@ func FixCmd() *cli.Command {
// Если не получилось удалить, пробуем через sudo // Если не получилось удалить, пробуем через sudo
slog.Warn(gotext.Get("Unable to remove cache item (%s) as current user, trying with sudo", entry)) slog.Warn(gotext.Get("Unable to remove cache item (%s) as current user, trying with sudo", entry))
sudoCmd := exec.Command("sudo", "rm", "-rf", fullPath) sudoCmd := execWithPrivileges("rm", "-rf", fullPath)
if sudoErr := sudoCmd.Run(); sudoErr != nil { if sudoErr := sudoCmd.Run(); sudoErr != nil {
// Если и через sudo не получилось, пропускаем с предупреждением // Если и через sudo не получилось, пропускаем с предупреждением
slog.Error(gotext.Get("Unable to remove cache item (%s)", entry), "error", err) slog.Error(gotext.Get("Unable to remove cache item (%s)", entry), "error", err)
@@ -109,7 +124,7 @@ func FixCmd() *cli.Command {
if err != nil { if err != nil {
// Если не получилось удалить, пробуем через sudo // Если не получилось удалить, пробуем через sudo
slog.Warn(gotext.Get("Unable to remove temporary directory as current user, trying with sudo")) slog.Warn(gotext.Get("Unable to remove temporary directory as current user, trying with sudo"))
sudoCmd := exec.Command("sudo", "rm", "-rf", tmpDir) sudoCmd := execWithPrivileges("rm", "-rf", tmpDir)
if sudoErr := sudoCmd.Run(); sudoErr != nil { if sudoErr := sudoCmd.Run(); sudoErr != nil {
slog.Error(gotext.Get("Unable to remove temporary directory"), "error", err) slog.Error(gotext.Get("Unable to remove temporary directory"), "error", err)
} }
@@ -143,12 +158,12 @@ func FixCmd() *cli.Command {
// Проверяем, есть ли файлы в директории // Проверяем, есть ли файлы в директории
entries, err := os.ReadDir(tmpDir) entries, err := os.ReadDir(tmpDir)
if err == nil && len(entries) > 0 { if err == nil && len(entries) > 0 {
fixCmd := exec.Command("sudo", "chown", "-R", "root:wheel", tmpDir) fixCmd := execWithPrivileges("chown", "-R", "root:wheel", tmpDir)
if fixErr := fixCmd.Run(); fixErr != nil { if fixErr := fixCmd.Run(); fixErr != nil {
slog.Warn(gotext.Get("Unable to fix file ownership"), "error", fixErr) slog.Warn(gotext.Get("Unable to fix file ownership"), "error", fixErr)
} }
fixCmd = exec.Command("sudo", "chmod", "-R", "2775", tmpDir) fixCmd = execWithPrivileges("chmod", "-R", "2775", tmpDir)
if fixErr := fixCmd.Run(); fixErr != nil { if fixErr := fixCmd.Run(); fixErr != nil {
slog.Warn(gotext.Get("Unable to fix file permissions"), "error", fixErr) slog.Warn(gotext.Get("Unable to fix file permissions"), "error", fixErr)
} }
@@ -162,18 +177,18 @@ func FixCmd() *cli.Command {
if err != nil { if err != nil {
// Если не получилось, пробуем через sudo с правильными правами для группы wheel // Если не получилось, пробуем через sudo с правильными правами для группы wheel
slog.Info(gotext.Get("Creating cache directory with sudo")) slog.Info(gotext.Get("Creating cache directory with sudo"))
sudoCmd := exec.Command("sudo", "mkdir", "-p", paths.CacheDir) sudoCmd := execWithPrivileges("mkdir", "-p", paths.CacheDir)
if sudoErr := sudoCmd.Run(); sudoErr != nil { if sudoErr := sudoCmd.Run(); sudoErr != nil {
return cliutils.FormatCliExit(gotext.Get("Unable to create new cache directory"), err) return cliutils.FormatCliExit(gotext.Get("Unable to create new cache directory"), err)
} }
// Устанавливаем права 775 и группу wheel // Устанавливаем права 775 и группу wheel
chmodCmd := exec.Command("sudo", "chmod", "775", paths.CacheDir) chmodCmd := execWithPrivileges("chmod", "775", paths.CacheDir)
if chmodErr := chmodCmd.Run(); chmodErr != nil { if chmodErr := chmodCmd.Run(); chmodErr != nil {
return cliutils.FormatCliExit(gotext.Get("Unable to set cache directory permissions"), chmodErr) return cliutils.FormatCliExit(gotext.Get("Unable to set cache directory permissions"), chmodErr)
} }
chgrpCmd := exec.Command("sudo", "chgrp", "wheel", paths.CacheDir) chgrpCmd := execWithPrivileges("chgrp", "wheel", paths.CacheDir)
if chgrpErr := chgrpCmd.Run(); chgrpErr != nil { if chgrpErr := chgrpCmd.Run(); chgrpErr != nil {
return cliutils.FormatCliExit(gotext.Get("Unable to set cache directory group"), chgrpErr) return cliutils.FormatCliExit(gotext.Get("Unable to set cache directory group"), chgrpErr)
} }

View File

@@ -16,14 +16,30 @@
package manager package manager
import "os/exec" import (
"os"
"os/exec"
)
type CommonPackageManager struct { type CommonPackageManager struct {
noConfirmArg string noConfirmArg string
} }
func (m *CommonPackageManager) getCmd(opts *Opts, mgrCmd string, args ...string) *exec.Cmd { func (m *CommonPackageManager) getCmd(opts *Opts, mgrCmd string, args ...string) *exec.Cmd {
cmd := exec.Command(mgrCmd) var cmd *exec.Cmd
// Проверяем, нужно ли повышение привилегий
isRoot := os.Geteuid() == 0
isCI := os.Getenv("CI") == "true"
if !isRoot && !isCI {
// Если не root и не в CI, используем sudo
cmd = exec.Command("sudo", mgrCmd)
} else {
// Если root или в CI, запускаем напрямую
cmd = exec.Command(mgrCmd)
}
cmd.Args = append(cmd.Args, opts.Args...) cmd.Args = append(cmd.Args, opts.Args...)
cmd.Args = append(cmd.Args, args...) cmd.Args = append(cmd.Args, args...)

View File

@@ -39,19 +39,45 @@ func EnsureTempDirWithRootOwner(path string, mode os.FileMode) error {
return err return err
} }
// Все каталоги в /tmp/alr доступны для группы wheel // В CI или если мы уже root, не нужно использовать sudo
// Устанавливаем setgid бит (2775), чтобы новые файлы наследовали группу isRoot := os.Geteuid() == 0
isCI := os.Getenv("CI") == "true"
// Если мы в CI или root, выполняем команды напрямую
// В противном случае используем sudo
permissions := "2775" permissions := "2775"
group := "wheel" group := "wheel"
var chmodCmd, chownCmd *exec.Cmd
if isRoot || isCI {
// Выполняем команды напрямую без sudo
chmodCmd = exec.Command("chmod", permissions, path)
chownCmd = exec.Command("chown", "root:"+group, path)
} else {
// Используем sudo для обычных пользователей
chmodCmd = exec.Command("sudo", "chmod", permissions, path)
chownCmd = exec.Command("sudo", "chown", "root:"+group, path)
}
// Устанавливаем права с setgid битом // Устанавливаем права с setgid битом
err = exec.Command("sudo", "chmod", permissions, path).Run() err = chmodCmd.Run()
if err != nil { if err != nil {
return err // В CI или для root игнорируем ошибки, если группа wheel не существует
if !isRoot && !isCI {
return err
}
} }
// Устанавливаем владельца root:wheel // Устанавливаем владельца root:wheel
return exec.Command("sudo", "chown", "root:"+group, path).Run() err = chownCmd.Run()
if err != nil {
// В CI или для root игнорируем ошибки, если группа wheel не существует
if !isRoot && !isCI {
return err
}
}
return nil
} }
// Для остальных каталогов обычное создание // Для остальных каталогов обычное создание

View File

@@ -32,12 +32,20 @@ error() {
installPkg() { installPkg() {
rootCmd="" rootCmd=""
if command -v doas &>/dev/null; then
rootCmd="doas" # Проверяем, запущен ли скрипт от root
elif command -v sudo &>/dev/null; then if [ "$(id -u)" = "0" ]; then
rootCmd="sudo" # Если root, не используем sudo/doas
rootCmd=""
else else
warn "Не обнаружена команда повышения привилегий (например, sudo, doas)" # Если не root, ищем команду повышения привилегий
if command -v doas &>/dev/null; then
rootCmd="doas"
elif command -v sudo &>/dev/null; then
rootCmd="sudo"
else
warn "Не обнаружена команда повышения привилегий (например, sudo, doas)"
fi
fi fi
case $1 in case $1 in