some fixes #67
| @@ -31,10 +31,21 @@ func TestE2EIssue32Interactive(t *testing.T) { | |||||||
| 		"issue-32-interactive", | 		"issue-32-interactive", | ||||||
| 		COMMON_SYSTEMS, | 		COMMON_SYSTEMS, | ||||||
| 		func(t *testing.T, r e2e.Runnable) { | 		func(t *testing.T, r e2e.Runnable) { | ||||||
| 			err := r.Exec(e2e.NewCommand( | 			assert.NoError(t, r.Exec(e2e.NewCommand( | ||||||
| 				"sudo", "alr", "--interactive=false", "remove", "ca-certificates", | 				"sudo", "alr", "--interactive=false", "remove", "ca-certificates", | ||||||
| 			)) | 			))) | ||||||
| 			assert.NoError(t, err) |  | ||||||
|  | 			assert.NoError(t, r.Exec(e2e.NewCommand( | ||||||
|  | 				"sudo", "alr", "--interactive=false", "remove", "openssl", | ||||||
|  | 			))) | ||||||
|  |  | ||||||
|  | 			assert.NoError(t, r.Exec(e2e.NewCommand( | ||||||
|  | 				"alr", "fix", | ||||||
|  | 			))) | ||||||
|  |  | ||||||
|  | 			assert.NoError(t, r.Exec(e2e.NewCommand( | ||||||
|  | 				"sudo", "alr", "--interactive=false", "install", "ca-certificates", | ||||||
|  | 			))) | ||||||
| 		}, | 		}, | ||||||
| 	) | 	) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -46,6 +46,9 @@ func HandleExitCoder(err error) { | |||||||
| 		cli.OsExiter(exitErr.ExitCode()) | 		cli.OsExiter(exitErr.ExitCode()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	slog.Error(err.Error()) | ||||||
|  | 	cli.OsExiter(1) | ||||||
| } | } | ||||||
|  |  | ||||||
| func FormatCliExit(msg string, err error) cli.ExitCoder { | func FormatCliExit(msg string, err error) cli.ExitCoder { | ||||||
|   | |||||||
| @@ -347,19 +347,19 @@ msgstr "" | |||||||
| msgid "Error while running app" | msgid "Error while running app" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:394 | #: pkg/build/build.go:395 | ||||||
| msgid "Building package" | msgid "Building package" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:423 | #: pkg/build/build.go:424 | ||||||
| msgid "The checksums array must be the same length as sources" | msgid "The checksums array must be the same length as sources" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:454 | #: pkg/build/build.go:455 | ||||||
| msgid "Downloading sources" | msgid "Downloading sources" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:543 | #: pkg/build/build.go:549 | ||||||
| msgid "Installing dependencies" | msgid "Installing dependencies" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -363,19 +363,19 @@ msgstr "Показать справку" | |||||||
| msgid "Error while running app" | msgid "Error while running app" | ||||||
| msgstr "Ошибка при запуске приложения" | msgstr "Ошибка при запуске приложения" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:394 | #: pkg/build/build.go:395 | ||||||
| msgid "Building package" | msgid "Building package" | ||||||
| msgstr "Сборка пакета" | msgstr "Сборка пакета" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:423 | #: pkg/build/build.go:424 | ||||||
| msgid "The checksums array must be the same length as sources" | msgid "The checksums array must be the same length as sources" | ||||||
| msgstr "Массив контрольных сумм должен быть той же длины, что и источники" | msgstr "Массив контрольных сумм должен быть той же длины, что и источники" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:454 | #: pkg/build/build.go:455 | ||||||
| msgid "Downloading sources" | msgid "Downloading sources" | ||||||
| msgstr "Скачивание источников" | msgstr "Скачивание источников" | ||||||
|  |  | ||||||
| #: pkg/build/build.go:543 | #: pkg/build/build.go:549 | ||||||
| msgid "Installing dependencies" | msgid "Installing dependencies" | ||||||
| msgstr "Установка зависимостей" | msgstr "Установка зависимостей" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ import ( | |||||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" | 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" | ||||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/types" | ||||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" | 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/distro" | ||||||
|  | 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type BuildInput struct { | type BuildInput struct { | ||||||
| @@ -233,8 +234,8 @@ type CheckerExecutor interface { | |||||||
| } | } | ||||||
|  |  | ||||||
| type InstallerExecutor interface { | type InstallerExecutor interface { | ||||||
| 	InstallLocal(paths []string) error | 	InstallLocal(paths []string, opts *manager.Opts) error | ||||||
| 	Install(pkgs []string) error | 	Install(pkgs []string, opts *manager.Opts) error | ||||||
| 	RemoveAlreadyInstalled(pkgs []string) ([]string, error) | 	RemoveAlreadyInstalled(pkgs []string) ([]string, error) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -521,7 +522,12 @@ func (b *Builder) InstallALRPackages( | |||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		err = b.installerExecutor.InstallLocal(res.PackagePaths) | 		err = b.installerExecutor.InstallLocal( | ||||||
|  | 			res.PackagePaths, | ||||||
|  | 			&manager.Opts{ | ||||||
|  | 				NoConfirm: !input.BuildOpts().Interactive, | ||||||
|  | 			}, | ||||||
|  | 		) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -681,14 +687,18 @@ func (i *Builder) InstallPkgs( | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(builtPaths) > 0 { | 	if len(builtPaths) > 0 { | ||||||
| 		err = i.installerExecutor.InstallLocal(builtPaths) | 		err = i.installerExecutor.InstallLocal(builtPaths, &manager.Opts{ | ||||||
|  | 			NoConfirm: !input.BuildOpts().Interactive, | ||||||
|  | 		}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(repoDeps) > 0 { | 	if len(repoDeps) > 0 { | ||||||
| 		err = i.installerExecutor.Install(repoDeps) | 		err = i.installerExecutor.Install(repoDeps, &manager.Opts{ | ||||||
|  | 			NoConfirm: !input.BuildOpts().Interactive, | ||||||
|  | 		}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -28,12 +28,12 @@ func NewInstaller(mgr manager.Manager) *Installer { | |||||||
|  |  | ||||||
| type Installer struct{ mgr manager.Manager } | type Installer struct{ mgr manager.Manager } | ||||||
|  |  | ||||||
| func (i *Installer) InstallLocal(paths []string) error { | func (i *Installer) InstallLocal(paths []string, opts *manager.Opts) error { | ||||||
| 	return i.mgr.InstallLocal(nil, paths...) | 	return i.mgr.InstallLocal(opts, paths...) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (i *Installer) Install(pkgs []string) error { | func (i *Installer) Install(pkgs []string, opts *manager.Opts) error { | ||||||
| 	return i.mgr.Install(nil, pkgs...) | 	return i.mgr.Install(opts, pkgs...) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (i *Installer) RemoveAlreadyInstalled(pkgs []string) ([]string, error) { | func (i *Installer) RemoveAlreadyInstalled(pkgs []string) ([]string, error) { | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								pkg/build/safe_common.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								pkg/build/safe_common.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | // ALR - Any Linux Repository | ||||||
|  | // Copyright (C) 2025 Евгений Храмов | ||||||
|  | // | ||||||
|  | // 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 <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | package build | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 	"os/exec" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func setCommonCmdEnv(cmd *exec.Cmd) { | ||||||
|  | 	cmd.Env = []string{ | ||||||
|  | 		"HOME=/var/cache/alr", | ||||||
|  | 		"LOGNAME=alr", | ||||||
|  | 		"USER=alr", | ||||||
|  | 		"PATH=/usr/bin:/bin:/usr/local/bin", | ||||||
|  | 	} | ||||||
|  | 	for _, env := range os.Environ() { | ||||||
|  | 		if strings.HasPrefix(env, "LANG=") || | ||||||
|  | 			strings.HasPrefix(env, "LANGUAGE=") || | ||||||
|  | 			strings.HasPrefix(env, "LC_") || | ||||||
|  | 			strings.HasPrefix(env, "ALR_LOG_LEVEL=") { | ||||||
|  | 			cmd.Env = append(cmd.Env, env) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -28,6 +28,7 @@ import ( | |||||||
| 	"github.com/hashicorp/go-plugin" | 	"github.com/hashicorp/go-plugin" | ||||||
|  |  | ||||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger" | 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger" | ||||||
|  | 	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type InstallerPlugin struct { | type InstallerPlugin struct { | ||||||
| @@ -42,21 +43,31 @@ type InstallerRPCServer struct { | |||||||
| 	Impl InstallerExecutor | 	Impl InstallerExecutor | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *InstallerRPC) InstallLocal(paths []string) error { | type InstallArgs struct { | ||||||
| 	return r.client.Call("Plugin.InstallLocal", paths, nil) | 	PackagesOrPaths []string | ||||||
|  | 	Opts            *manager.Opts | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *InstallerRPCServer) InstallLocal(paths []string, reply *struct{}) error { | func (r *InstallerRPC) InstallLocal(paths []string, opts *manager.Opts) error { | ||||||
| 	return s.Impl.InstallLocal(paths) | 	return r.client.Call("Plugin.InstallLocal", &InstallArgs{ | ||||||
|  | 		PackagesOrPaths: paths, | ||||||
|  | 		Opts:            opts, | ||||||
|  | 	}, nil) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *InstallerRPC) Install(pkgs []string) error { | func (s *InstallerRPCServer) InstallLocal(args *InstallArgs, reply *struct{}) error { | ||||||
| 	return r.client.Call("Plugin.Install", pkgs, nil) | 	return s.Impl.InstallLocal(args.PackagesOrPaths, args.Opts) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *InstallerRPCServer) Install(pkgs []string, reply *struct{}) error { | func (r *InstallerRPC) Install(pkgs []string, opts *manager.Opts) error { | ||||||
| 	slog.Debug("install", "pkgs", pkgs) | 	return r.client.Call("Plugin.Install", &InstallArgs{ | ||||||
| 	return s.Impl.Install(pkgs) | 		PackagesOrPaths: pkgs, | ||||||
|  | 		Opts:            opts, | ||||||
|  | 	}, nil) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *InstallerRPCServer) Install(args *InstallArgs, reply *struct{}) error { | ||||||
|  | 	return s.Impl.Install(args.PackagesOrPaths, args.Opts) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *InstallerRPC) RemoveAlreadyInstalled(paths []string) ([]string, error) { | func (r *InstallerRPC) RemoveAlreadyInstalled(paths []string) ([]string, error) { | ||||||
| @@ -90,28 +101,7 @@ func GetSafeInstaller() (InstallerExecutor, func(), error) { | |||||||
| 		return nil, nil, err | 		return nil, nil, err | ||||||
| 	} | 	} | ||||||
| 	cmd := exec.Command(executable, "_internal-installer") | 	cmd := exec.Command(executable, "_internal-installer") | ||||||
| 	cmd.Env = []string{ | 	setCommonCmdEnv(cmd) | ||||||
| 		"HOME=/var/cache/alr", |  | ||||||
| 		"LOGNAME=alr", |  | ||||||
| 		"USER=alr", |  | ||||||
| 		"PATH=/usr/bin:/bin:/usr/local/bin", |  | ||||||
| 		"ALR_LOG_LEVEL=DEBUG", |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 		uid, gid, err := utils.GetUidGidAlrUser() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 			cmd.SysProcAttr = &syscall.SysProcAttr{ |  | ||||||
| 				Credential: &syscall.Credential{ |  | ||||||
| 					Uid: uint32(uid), |  | ||||||
| 					Gid: uint32(gid), |  | ||||||
| 				}, |  | ||||||
| 			} |  | ||||||
| 	*/ |  | ||||||
|  |  | ||||||
| 	slog.Debug("safe installer setup", "uid", syscall.Getuid(), "gid", syscall.Getgid()) | 	slog.Debug("safe installer setup", "uid", syscall.Getuid(), "gid", syscall.Getgid()) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -226,26 +226,7 @@ func GetSafeScriptExecutor() (ScriptExecutor, func(), error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd := exec.Command(executable, "_internal-safe-script-executor") | 	cmd := exec.Command(executable, "_internal-safe-script-executor") | ||||||
| 	cmd.Env = []string{ | 	setCommonCmdEnv(cmd) | ||||||
| 		"HOME=/var/cache/alr", |  | ||||||
| 		"LOGNAME=alr", |  | ||||||
| 		"USER=alr", |  | ||||||
| 		"PATH=/usr/bin:/bin:/usr/local/bin", |  | ||||||
| 		"ALR_LOG_LEVEL=DEBUG", |  | ||||||
| 	} |  | ||||||
| 	/* |  | ||||||
| 		uid, gid, err := utils.GetUidGidAlrUser() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 			cmd.SysProcAttr = &syscall.SysProcAttr{ |  | ||||||
| 				Credential: &syscall.Credential{ |  | ||||||
| 					Uid: uint32(uid), |  | ||||||
| 					Gid: uint32(gid), |  | ||||||
| 				}, |  | ||||||
| 			} |  | ||||||
| 	*/ |  | ||||||
|  |  | ||||||
| 	client := plugin.NewClient(&plugin.ClientConfig{ | 	client := plugin.NewClient(&plugin.ClientConfig{ | ||||||
| 		HandshakeConfig: HandshakeConfig, | 		HandshakeConfig: HandshakeConfig, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user