diff --git a/install.go b/install.go index 9df3010..4ab493d 100644 --- a/install.go +++ b/install.go @@ -46,11 +46,7 @@ func InstallCmd() *cli.Command { Usage: gotext.Get("Build package from scratch even if there's an already built package available"), }, }, - Action: func(c *cli.Context) error { - if err := utils.ExitIfNotRoot(); err != nil { - return err - } - + Action: utils.RootNeededAction(func(c *cli.Context) error { args := c.Args() if args.Len() < 1 { return cliutils.FormatCliExit(gotext.Get("Command install expected at least 1 argument, got %d", args.Len()), nil) @@ -119,7 +115,7 @@ func InstallCmd() *cli.Command { } return nil - }, + }), BashComplete: cliutils.BashCompleteWithError(func(c *cli.Context) error { if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil { return err @@ -213,11 +209,7 @@ func RemoveCmd() *cli.Command { return nil }), - Action: func(c *cli.Context) error { - if err := utils.ExitIfNotRoot(); err != nil { - return err - } - + Action: utils.RootNeededAction(func(c *cli.Context) error { args := c.Args() if args.Len() < 1 { return cliutils.FormatCliExit(gotext.Get("Command remove expected at least 1 argument, got %d", args.Len()), nil) @@ -239,6 +231,6 @@ func RemoveCmd() *cli.Command { } return nil - }, + }), } } diff --git a/internal/config/config.go b/internal/config/config.go index 6eccc91..64d2ce1 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -39,6 +39,7 @@ type ALRConfig struct { var defaultConfig = &types.Config{ RootCmd: "sudo", + UseRootCmd: true, PagerStyle: "native", IgnorePkgUpdates: []string{}, AutoPull: true, @@ -142,6 +143,10 @@ func (c *ALRConfig) LogLevel() string { return c.cfg.LogLevel } +func (c *ALRConfig) UseRootCmd() bool { + return c.cfg.UseRootCmd +} + func (c *ALRConfig) GetPaths() *Paths { return c.paths } diff --git a/internal/translations/default.pot b/internal/translations/default.pot index a4ff189..bc63d5b 100644 --- a/internal/translations/default.pot +++ b/internal/translations/default.pot @@ -154,27 +154,27 @@ msgstr "" msgid "Install a new package" msgstr "" -#: install.go:56 +#: install.go:52 msgid "Command install expected at least 1 argument, got %d" msgstr "" -#: install.go:118 +#: install.go:114 msgid "Error when installing the package" msgstr "" -#: install.go:163 +#: install.go:159 msgid "Remove an installed package" msgstr "" -#: install.go:182 +#: install.go:178 msgid "Error listing installed packages" msgstr "" -#: install.go:223 +#: install.go:215 msgid "Command remove expected at least 1 argument, got %d" msgstr "" -#: install.go:238 +#: install.go:230 msgid "Error removing packages" msgstr "" @@ -315,16 +315,16 @@ msgstr "" msgid "ERROR" msgstr "" -#: internal/utils/cmd.go:95 +#: internal/utils/cmd.go:97 msgid "Error on dropping capabilities" msgstr "" -#: internal/utils/cmd.go:123 -msgid "You need to be root to perform this action" +#: internal/utils/cmd.go:164 +msgid "You need to be a %s member to perform this action" msgstr "" -#: internal/utils/cmd.go:165 -msgid "You need to be a %s member to perform this action" +#: internal/utils/cmd.go:200 +msgid "You need to be root to perform this action" msgstr "" #: list.go:41 @@ -443,35 +443,35 @@ msgstr "" msgid "URL of the new repo" msgstr "" -#: repo.go:79 +#: repo.go:75 msgid "Repo \"%s\" already exists" msgstr "" -#: repo.go:90 repo.go:167 +#: repo.go:86 repo.go:159 msgid "Error saving config" msgstr "" -#: repo.go:116 +#: repo.go:112 msgid "Remove an existing repository" msgstr "" -#: repo.go:123 +#: repo.go:119 msgid "Name of the repo to be deleted" msgstr "" -#: repo.go:156 +#: repo.go:148 msgid "Repo \"%s\" does not exist" msgstr "" -#: repo.go:163 +#: repo.go:155 msgid "Error removing repo directory" msgstr "" -#: repo.go:186 +#: repo.go:178 msgid "Error removing packages from database" msgstr "" -#: repo.go:197 +#: repo.go:189 msgid "Pull all repositories that have changed" msgstr "" @@ -515,10 +515,10 @@ msgstr "" msgid "Upgrade all installed packages" msgstr "" -#: upgrade.go:109 upgrade.go:126 +#: upgrade.go:105 upgrade.go:122 msgid "Error checking for updates" msgstr "" -#: upgrade.go:129 +#: upgrade.go:125 msgid "There is nothing to do." msgstr "" diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po index 380164c..5afa67b 100644 --- a/internal/translations/po/ru/default.po +++ b/internal/translations/po/ru/default.po @@ -12,8 +12,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Gtranslator 48.0\n" #: build.go:42 @@ -161,27 +161,27 @@ msgstr "Ошибка кодирования переменных скрита" msgid "Install a new package" msgstr "Установить новый пакет" -#: install.go:56 +#: install.go:52 msgid "Command install expected at least 1 argument, got %d" msgstr "Для команды install ожидался хотя бы 1 аргумент, получено %d" -#: install.go:118 +#: install.go:114 msgid "Error when installing the package" msgstr "Ошибка при установке пакета" -#: install.go:163 +#: install.go:159 msgid "Remove an installed package" msgstr "Удалить установленный пакет" -#: install.go:182 +#: install.go:178 msgid "Error listing installed packages" msgstr "Ошибка при составлении списка установленных пакетов" -#: install.go:223 +#: install.go:215 msgid "Command remove expected at least 1 argument, got %d" msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d" -#: install.go:238 +#: install.go:230 msgid "Error removing packages" msgstr "Ошибка при удалении пакетов" @@ -323,18 +323,18 @@ msgstr "%s %s загружается — %s/с\n" msgid "ERROR" msgstr "ОШИБКА" -#: internal/utils/cmd.go:95 +#: internal/utils/cmd.go:97 msgid "Error on dropping capabilities" msgstr "Ошибка при понижении привилегий" -#: internal/utils/cmd.go:123 -msgid "You need to be root to perform this action" -msgstr "Вы должны быть root чтобы выполнить это" - -#: internal/utils/cmd.go:165 +#: internal/utils/cmd.go:164 msgid "You need to be a %s member to perform this action" msgstr "Вы должны быть членом %s чтобы выполнить это" +#: internal/utils/cmd.go:200 +msgid "You need to be root to perform this action" +msgstr "Вы должны быть root чтобы выполнить это" + #: list.go:41 msgid "List ALR repo packages" msgstr "Список пакетов репозитория ALR" @@ -457,35 +457,35 @@ msgstr "Название нового репозитория" msgid "URL of the new repo" msgstr "URL-адрес нового репозитория" -#: repo.go:79 +#: repo.go:75 msgid "Repo \"%s\" already exists" msgstr "Репозиторий \"%s\" уже существует" -#: repo.go:90 repo.go:167 +#: repo.go:86 repo.go:159 msgid "Error saving config" msgstr "Ошибка при сохранении конфигурации" -#: repo.go:116 +#: repo.go:112 msgid "Remove an existing repository" msgstr "Удалить существующий репозиторий" -#: repo.go:123 +#: repo.go:119 msgid "Name of the repo to be deleted" msgstr "Название репозитория удалён" -#: repo.go:156 +#: repo.go:148 msgid "Repo \"%s\" does not exist" msgstr "Репозитория \"%s\" не существует" -#: repo.go:163 +#: repo.go:155 msgid "Error removing repo directory" msgstr "Ошибка при удалении каталога репозитория" -#: repo.go:186 +#: repo.go:178 msgid "Error removing packages from database" msgstr "Ошибка при удалении пакетов из базы данных" -#: repo.go:197 +#: repo.go:189 msgid "Pull all repositories that have changed" msgstr "Скачать все изменённые репозитории" @@ -529,11 +529,11 @@ msgstr "Ошибка при выполнении шаблона" msgid "Upgrade all installed packages" msgstr "Обновить все установленные пакеты" -#: upgrade.go:109 upgrade.go:126 +#: upgrade.go:105 upgrade.go:122 msgid "Error checking for updates" msgstr "Ошибка при проверке обновлений" -#: upgrade.go:129 +#: upgrade.go:125 msgid "There is nothing to do." msgstr "Здесь нечего делать." diff --git a/internal/types/config.go b/internal/types/config.go index f2004e8..55480e5 100644 --- a/internal/types/config.go +++ b/internal/types/config.go @@ -22,6 +22,7 @@ package types // Config represents the ALR configuration file type Config struct { RootCmd string `toml:"rootCmd" env:"ALR_ROOT_CMD"` + UseRootCmd bool `toml:"useRootCmd"` PagerStyle string `toml:"pagerStyle" env:"ALR_PAGER_STYLE"` IgnorePkgUpdates []string `toml:"ignorePkgUpdates"` Repos []Repo `toml:"repo"` diff --git a/internal/utils/cmd.go b/internal/utils/cmd.go index 1822b8b..5753f2f 100644 --- a/internal/utils/cmd.go +++ b/internal/utils/cmd.go @@ -19,6 +19,7 @@ package utils import ( "errors" "os" + "os/exec" "os/user" "strconv" "syscall" @@ -27,6 +28,7 @@ import ( "github.com/urfave/cli/v2" "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils" + appbuilder "gitea.plemya-x.ru/Plemya-x/ALR/internal/cliutils/app_builder" "gitea.plemya-x.ru/Plemya-x/ALR/internal/constants" ) @@ -118,11 +120,8 @@ func ExitIfCantDropCapsToAlrUserNoPrivs() cli.ExitCoder { return nil } -func ExitIfNotRoot() error { - if os.Getuid() != 0 { - return cli.Exit(gotext.Get("You need to be root to perform this action"), 1) - } - return nil +func IsNotRoot() bool { + return os.Getuid() != 0 } func EnsureIsAlrUser() error { @@ -184,3 +183,33 @@ func EscalateToRoot() error { } return nil } + +func RootNeededAction(f cli.ActionFunc) cli.ActionFunc { + return func(ctx *cli.Context) error { + deps, err := appbuilder. + New(ctx.Context). + WithConfig(). + Build() + if err != nil { + return err + } + defer deps.Defer() + + if IsNotRoot() { + if !deps.Cfg.UseRootCmd() { + return cli.Exit(gotext.Get("You need to be root to perform this action"), 1) + } + executable, err := os.Executable() + if err != nil { + return cliutils.FormatCliExit("failed to get executable path", err) + } + args := append([]string{executable}, os.Args[1:]...) + cmd := exec.Command(deps.Cfg.RootCmd(), args...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() + } + return f(ctx) + } +} diff --git a/repo.go b/repo.go index 0410833..c679c95 100644 --- a/repo.go +++ b/repo.go @@ -52,11 +52,7 @@ func AddRepoCmd() *cli.Command { Usage: gotext.Get("URL of the new repo"), }, }, - Action: func(c *cli.Context) error { - if err := utils.ExitIfNotRoot(); err != nil { - return err - } - + Action: utils.RootNeededAction(func(c *cli.Context) error { name := c.String("name") repoURL := c.String("url") @@ -106,7 +102,7 @@ func AddRepoCmd() *cli.Command { defer deps.Defer() return nil - }, + }), } } @@ -123,11 +119,7 @@ func RemoveRepoCmd() *cli.Command { Usage: gotext.Get("Name of the repo to be deleted"), }, }, - Action: func(c *cli.Context) error { - if err := utils.ExitIfNotRoot(); err != nil { - return err - } - + Action: utils.RootNeededAction(func(c *cli.Context) error { ctx := c.Context name := c.String("name") @@ -187,7 +179,7 @@ func RemoveRepoCmd() *cli.Command { } return nil - }, + }), } } diff --git a/upgrade.go b/upgrade.go index a08d443..7b148aa 100644 --- a/upgrade.go +++ b/upgrade.go @@ -53,11 +53,7 @@ func UpgradeCmd() *cli.Command { Usage: gotext.Get("Build package from scratch even if there's an already built package available"), }, }, - Action: func(c *cli.Context) error { - if err := utils.ExitIfNotRoot(); err != nil { - return err - } - + Action: utils.RootNeededAction(func(c *cli.Context) error { if err := utils.ExitIfCantDropCapsToAlrUser(); err != nil { return err } @@ -130,7 +126,7 @@ func UpgradeCmd() *cli.Command { } return nil - }, + }), } }