2024-01-22 10:36:06 +00:00
|
|
|
|
/*
|
2024-05-05 10:32:08 +00:00
|
|
|
|
* ALR - Any Linux Repository
|
2024-11-16 08:32:47 +00:00
|
|
|
|
* ALR - Любой Linux Репозиторий
|
2024-05-05 10:32:08 +00:00
|
|
|
|
* Copyright (C) 2024 Евгений Храмов
|
2024-01-22 10:36:06 +00:00
|
|
|
|
*
|
2024-11-16 08:32:47 +00:00
|
|
|
|
* This program является свободным: вы можете распространять его и/или изменять
|
|
|
|
|
* на условиях GNU General Public License, опубликованной Free Software Foundation,
|
|
|
|
|
* либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
|
2024-01-22 10:36:06 +00:00
|
|
|
|
*
|
2024-11-16 08:32:47 +00:00
|
|
|
|
* Это программное обеспечение распространяется в надежде, что оно будет полезным,
|
|
|
|
|
* но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; без подразумеваемой гарантии
|
|
|
|
|
* КОММЕРЧЕСКОЙ ПРИГОДНОСТИ или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ.
|
|
|
|
|
* Подробности см. в GNU General Public License.
|
2024-01-22 10:36:06 +00:00
|
|
|
|
*
|
2024-11-16 08:32:47 +00:00
|
|
|
|
* Вы должны были получить копию GNU General Public License
|
|
|
|
|
* вместе с этой программой. Если нет, см. <http://www.gnu.org/licenses/>.
|
2024-01-22 10:36:06 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package manager
|
|
|
|
|
|
|
|
|
|
import (
|
2024-11-16 08:32:47 +00:00
|
|
|
|
"bufio"
|
|
|
|
|
"fmt"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"strings"
|
2024-01-22 10:36:06 +00:00
|
|
|
|
)
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// DNF представляет менеджер пакетов DNF
|
2024-01-22 10:36:06 +00:00
|
|
|
|
type DNF struct {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
rootCmd string // rootCmd хранит команду, используемую для выполнения команд с правами root
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// Exists проверяет, доступен ли DNF в системе, возвращает true если да
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (*DNF) Exists() bool {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
_, err := exec.LookPath("dnf")
|
|
|
|
|
return err == nil
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// Name возвращает имя менеджера пакетов, в данном случае "dnf"
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (*DNF) Name() string {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
return "dnf"
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// Format возвращает формат пакетов "rpm", используемый DNF
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (*DNF) Format() string {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
return "rpm"
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// SetRootCmd устанавливает команду, используемую для выполнения операций с правами root
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) SetRootCmd(s string) {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
d.rootCmd = s
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// Sync выполняет upgrade всех установленных пакетов, обновляя их до более новых версий
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) Sync(opts *Opts) error {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
opts = ensureOpts(opts) // Гарантирует, что opts не равен nil и содержит допустимые значения
|
|
|
|
|
cmd := d.getCmd(opts, "dnf", "upgrade")
|
|
|
|
|
setCmdEnv(cmd) // Устанавливает переменные окружения для команды
|
|
|
|
|
err := cmd.Run() // Выполняет команду
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("dnf: sync: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// Install устанавливает указанные пакеты с помощью DNF
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) Install(opts *Opts, pkgs ...string) error {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
opts = ensureOpts(opts)
|
|
|
|
|
cmd := d.getCmd(opts, "dnf", "install", "--allowerasing")
|
|
|
|
|
cmd.Args = append(cmd.Args, pkgs...) // Добавляем названия пакетов к команде
|
|
|
|
|
setCmdEnv(cmd)
|
|
|
|
|
err := cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("dnf: install: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// InstallLocal расширяет метод Install для установки пакетов, расположенных локально
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) InstallLocal(opts *Opts, pkgs ...string) error {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
opts = ensureOpts(opts)
|
|
|
|
|
return d.Install(opts, pkgs...)
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// Remove удаляет указанные пакеты с помощью DNF
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) Remove(opts *Opts, pkgs ...string) error {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
opts = ensureOpts(opts)
|
|
|
|
|
cmd := d.getCmd(opts, "dnf", "remove")
|
|
|
|
|
cmd.Args = append(cmd.Args, pkgs...)
|
|
|
|
|
setCmdEnv(cmd)
|
|
|
|
|
err := cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("dnf: remove: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// Upgrade обновляет указанные пакеты до более новых версий
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) Upgrade(opts *Opts, pkgs ...string) error {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
opts = ensureOpts(opts)
|
|
|
|
|
cmd := d.getCmd(opts, "dnf", "upgrade")
|
|
|
|
|
cmd.Args = append(cmd.Args, pkgs...)
|
|
|
|
|
setCmdEnv(cmd)
|
|
|
|
|
err := cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("dnf: upgrade: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// UpgradeAll обновляет все установленные пакеты
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) UpgradeAll(opts *Opts) error {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
opts = ensureOpts(opts)
|
|
|
|
|
cmd := d.getCmd(opts, "dnf", "upgrade")
|
|
|
|
|
setCmdEnv(cmd)
|
|
|
|
|
err := cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("dnf: upgradeall: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// ListInstalled возвращает список установленных пакетов и их версий
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) ListInstalled(opts *Opts) (map[string]string, error) {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
out := map[string]string{}
|
|
|
|
|
cmd := exec.Command("rpm", "-qa", "--queryformat", "%{NAME}\u200b%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\\n")
|
|
|
|
|
|
|
|
|
|
stdout, err := cmd.StdoutPipe()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = cmd.Start()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scanner := bufio.NewScanner(stdout)
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
|
name, version, ok := strings.Cut(scanner.Text(), "\u200b")
|
|
|
|
|
if !ok {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
version = strings.TrimPrefix(version, "0:")
|
|
|
|
|
out[name] = version
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = scanner.Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return out, nil
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-16 08:32:47 +00:00
|
|
|
|
// getCmd создает и возвращает команду exec.Cmd для менеджера пакетов DNF
|
2024-01-22 10:36:06 +00:00
|
|
|
|
func (d *DNF) getCmd(opts *Opts, mgrCmd string, args ...string) *exec.Cmd {
|
2024-11-16 08:32:47 +00:00
|
|
|
|
var cmd *exec.Cmd
|
|
|
|
|
if opts.AsRoot {
|
|
|
|
|
cmd = exec.Command(getRootCmd(d.rootCmd), mgrCmd)
|
|
|
|
|
cmd.Args = append(cmd.Args, opts.Args...)
|
|
|
|
|
cmd.Args = append(cmd.Args, args...)
|
|
|
|
|
} else {
|
|
|
|
|
cmd = exec.Command(mgrCmd, args...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if opts.NoConfirm {
|
|
|
|
|
cmd.Args = append(cmd.Args, "-y") // Добавляет параметр автоматического подтверждения (-y)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cmd
|
2024-01-22 10:36:06 +00:00
|
|
|
|
}
|