Compare commits

...

2 Commits

9 changed files with 106 additions and 71 deletions

@ -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

@ -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,