Внесение логики для запуска из под root
This commit is contained in:
		| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								fix.go
									
									
									
									
									
								
							| @@ -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) | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -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...) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	// Для остальных каталогов обычное создание | 	// Для остальных каталогов обычное создание | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user