epm-install 15.5 KB
Newer Older
Vitaly Lipatov's avatar
Vitaly Lipatov committed
1 2
#!/bin/sh
#
3 4
# Copyright (C) 2012-2020  Etersoft
# Copyright (C) 2012-2020  Vitaly Lipatov <lav@etersoft.ru>
Vitaly Lipatov's avatar
Vitaly Lipatov committed
5
#
6 7 8
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
Vitaly Lipatov's avatar
Vitaly Lipatov committed
9 10 11 12 13
# (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
14
# GNU Affero General Public License for more details.
Vitaly Lipatov's avatar
Vitaly Lipatov committed
15
#
16 17
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
Vitaly Lipatov's avatar
Vitaly Lipatov committed
18 19
#

20
load_helper epm-sh-altlinux
21
load_helper epm-sh-install
22
load_helper epm-query
23
load_helper epm-assure
24
load_helper epm-repack
25
load_helper epm-check_updated_repo
26
load_helper epm-sh-warmup
27

28

29 30 31
# for zypper before SUSE/11.0
__use_zypper_no_gpg_checks()
{
Vitaly Lipatov's avatar
Vitaly Lipatov committed
32
    a='' zypper install --help 2>&1 | grep -q -- "--no-gpg-checks" && echo "--no-gpg-checks"
33
}
34

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
# args: cmd_reinstall, cmd_install, packages
__separate_sudocmd_foreach()
{
    local cmd_re=$1
    local cmd_in=$2
    shift 2
    separate_installed $@
    if [ -n "$pkg_noninstalled" ] ; then
        sudocmd_foreach "$cmd_re" $pkg_noninstalled || return
    fi
    if [ -n "$pkg_installed" ] ; then
        sudocmd_foreach "$cmd_in" $pkg_installed || return
    fi
    return 0
}

# args: cmd_reinstall, cmd_install, packages
__separate_sudocmd()
{
    local cmd_re=$1
    local cmd_in=$2
    shift 2
    separate_installed $@
    if [ -n "$pkg_noninstalled" ] ; then
59
        sudocmd $cmd_re $pkg_noninstalled || return
60 61
    fi
    if [ -n "$pkg_installed" ] ; then
62
        sudocmd $cmd_in $pkg_installed || return
63 64 65 66
    fi
    return 0
}

Vitaly Lipatov's avatar
Vitaly Lipatov committed
67
# copied from etersoft-build-utils/share/eterbuild/functions/rpmpkg
68
epm_install_names()
Vitaly Lipatov's avatar
Vitaly Lipatov committed
69
{
70 71 72 73 74 75 76 77 78
    [ -z "$1" ] && return

    warmup_hibase

    if [ -n "$download_only" ] ; then
        epm download "$@"
        return
    fi

79 80 81 82 83 84
    if [ -n "$dryrun" ] ; then
        load_helper epm-simulate
        epm simulate "$@"
        return
    fi

85 86 87 88 89 90 91 92
    if [ -n "$non_interactive" ] ; then
        epm_ni_install_names "$@"
        return
    fi

    case $PMTYPE in
        apt-rpm|apt-dpkg)
            APTOPTIONS="$APTOPTIONS $(subst_option verbose "-o Debug::pkgMarkInstall=1 -o Debug::pkgProblemResolver=1")"
93
            # https://bugzilla.altlinux.org/44670
94 95 96 97
            VIRTAPTOPTIONS="-o APT::Install::VirtualVersion=true -o APT::Install::Virtual=true"
            # not for kernel packages
            echo "$*" | grep -q "^kernel-"  && VIRTAPTOPTIONS=''
            sudocmd apt-get $VIRTAPTOPTIONS $APTOPTIONS $noremove install $@ && save_installed_packages $@
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
            return ;;
        aptitude-dpkg)
            sudocmd aptitude install $@
            return ;;
        deepsolver-rpm)
            sudocmd ds-install $@
            return ;;
        urpm-rpm)
            sudocmd urpmi $URPMOPTIONS $@
            return ;;
        packagekit)
            docmd pkcon install $@
            return ;;
        pkgsrc)
            sudocmd pkg_add -r $@
            return ;;
        pkgng)
            sudocmd pkg install $@
            return ;;
        emerge)
            sudocmd emerge -uD $@
            return ;;
        pacman)
            sudocmd pacman -S $nodeps $@
            return ;;
        aura)
            sudocmd aura -A $force $nodeps $@
            return ;;
        yum-rpm)
            sudocmd yum $YUMOPTIONS install $(echo "$*" | exp_with_arch_suffix)
            return ;;
        dnf-rpm)
            sudocmd dnf install $(echo "$*" | exp_with_arch_suffix)
            return ;;
        snappy)
            sudocmd snappy install $@
            return ;;
        zypper-rpm)
            sudocmd zypper install $ZYPPEROPTIONS $@
            return ;;
        mpkg)
            sudocmd mpkg install $@
            return ;;
        eopkg)
            sudocmd eopkg $(subst_option nodeps --ignore-dependency) install $@
            return ;;
        conary)
            sudocmd conary update $@
            return ;;
        npackd)
            # FIXME: correct arg
            __separate_sudocmd_foreach "npackdcl add --package=" "npackdcl update --package=" $@
            return ;;
        slackpkg)
            __separate_sudocmd_foreach "/usr/sbin/slackpkg install" "/usr/sbin/slackpkg upgrade" $@
            return ;;
        homebrew)
            # FIXME: sudo and quote
            SUDO='' __separate_sudocmd "brew install" "brew upgrade" "$@"
            return ;;
        opkg)
            [ -n "$force" ] && force=-force-depends
            sudocmd opkg $force install $@
            return ;;
        nix)
            __separate_sudocmd "nix-env --install" "nix-env --upgrade" "$@"
            return ;;
        apk)
            sudocmd apk add $@
            return ;;
        tce)
            sudocmd tce-load -wi $@
            return ;;
        guix)
            __separate_sudocmd "guix package -i" "guix package -i" $@
            return ;;
174 175 176
        termux-pkg)
            sudocmd pkg install $@
            return ;;
177 178 179 180 181 182 183 184 185
        android)
            fatal "We still have no idea how to use package repository, ever if it is F-Droid."
            return ;;
        aptcyg)
            sudocmd apt-cyg install $@
            return ;;
        xbps)
            sudocmd xbps-install $@
            return ;;
186 187 188 189
        nix)
            info "When you ask Nix to install a package, it will first try to get it in pre-compiled form from a binary cache. By default, Nix will use the binary cache https://cache.nixos.org; it contains binaries for most packages in Nixpkgs. Only if no binary is available in the binary cache, Nix will build the package from source."
            sudocmd nix-env -iA $@
            return ;;
190 191 192 193 194 195 196
        appget|winget)
            sudocmd $PMTYPE install $@
            return ;;
        *)
            fatal "Have no suitable install command for $PMTYPE"
            ;;
    esac
197 198
}

199
# Non interactive install
200 201
epm_ni_install_names()
{
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
    [ -z "$1" ] && return

    case $PMTYPE in
        apt-rpm)
            sudocmd apt-get -y $noremove --force-yes -o APT::Install::VirtualVersion=true -o APT::Install::Virtual=true -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" $APTOPTIONS install $@
            return ;;
        apt-dpkg)
            sudocmd env ACCEPT_EULA=y DEBIAN_FRONTEND=noninteractive apt-get -y $noremove --force-yes -o APT::Install::VirtualVersion=true -o APT::Install::Virtual=true -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" $APTOPTIONS install $@
            return ;;
        aptitude-dpkg)
            sudocmd env ACCEPT_EULA=y DEBIAN_FRONTEND=noninteractive aptitude -y install $@
            return ;;
        yum-rpm)
            sudocmd yum -y $YUMOPTIONS install $(echo "$*" | exp_with_arch_suffix)
            return ;;
        dnf-rpm)
            sudocmd dnf -y --allowerasing $YUMOPTIONS install $(echo "$*" | exp_with_arch_suffix)
            return ;;
        urpm-rpm)
            sudocmd urpmi --auto $URPMOPTIONS $@
            return ;;
        zypper-rpm)
            # FIXME: returns true ever no package found, need check for "no found", "Nothing to do."
            yes | sudocmd zypper --non-interactive $ZYPPEROPTIONS install $@
            return ;;
        packagekit)
            docmd pkcon install --noninteractive $@
            return ;;
        pkgsrc)
            sudocmd pkg_add -r $@
            return ;;
        pkgng)
            sudocmd pkg install -y $@
            return ;;
        emerge)
            sudocmd emerge -uD $@
            return ;;
        pacman)
            sudocmd pacman -S --noconfirm $nodeps $@
            return ;;
        aura)
            sudocmd aura -A $force $nodeps $@
            return ;;
        npackd)
            #  npackdcl update --package=<package> (remove old and install new)
            sudocmd npackdcl add --package="$*"
            return ;;
249 250
        choco)
            docmd choco install $@
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
            return ;;
        opkg)
            sudocmd opkg -force-defaults install $@
            return ;;
        eopkg)
            sudocmd eopkg --yes-all install $@
            return ;;
        nix)
            sudocmd nix-env --install $@
            return ;;
        apk)
            sudocmd apk add $@
            return ;;
        tce)
            sudocmd tce-load -wi $@
            return ;;
        xbps)
            sudocmd xbps-install -y $@
            return ;;
        appget|winget)
            sudocmd $PMTYPE -s install $@
            return ;;
        homebrew)
            # FIXME: sudo and quote
            SUDO='' __separate_sudocmd "brew install" "brew upgrade" $@
            return ;;
277 278 279
        termux-pkg)
            sudocmd pkg install $@
            return ;;
280 281 282 283 284 285 286 287
        slackpkg)
            # FIXME: broken status when use batch and default answer
            __separate_sudocmd_foreach "/usr/sbin/slackpkg -batch=on -default_answer=yes install" "/usr/sbin/slackpkg -batch=on -default_answer=yes upgrade" $@
            return ;;
        *)
            fatal "Have no suitable appropriate install command for $PMTYPE"
            ;;
    esac
Vitaly Lipatov's avatar
Vitaly Lipatov committed
288 289
}

290 291
__epm_check_if_rpm_already_installed()
{
292 293
    # Not: we can make optimize if just check version?
    LANG=C sudorun rpm -Uvh --test "$@" 2>&1 | grep -q "is already installed"
294 295
}

296 297
__handle_direct_install()
{
298 299
    case "$BASEDISTRNAME" in
        "alt")
300 301 302 303 304 305 306 307 308 309 310 311 312
            load_helper epm-download
            local pkg url
            for pkg in $pkg_names ; do
                url=$(__epm_get_altpkg_url $pkg)
                [ -n "$url" ] || continue
                # TODO: use estrlist
                pkg_urls="$pkg_urls $url"
            done
            # FIXME: need remove
            pkg_names=""
            ;;
    esac
}
313

314 315 316 317 318 319 320 321 322
# TODO: forbid src.rpm
__epm_check_if_src_rpm()
{
    local pkg
    for pkg in $@ ; do
        echo "$pkg" | grep -q "\.src.\rpm" && fatal "Installation of a source packages (like '$pkg') is not supported."
    done
}

323 324
__epm_if_command_path()
{
325
    is_dirpath "$1" && rhas "$1" "bin/" && ! rhas "$1" "/home"
326 327
}

328 329 330 331 332 333
__epm_get_replacepkgs()
{
    [ -n "$2" ] && echo '--replacepkgs' && return
    # don't use --replacepkgs when install only one file
}

334
epm_install_files()
Vitaly Lipatov's avatar
Vitaly Lipatov committed
335
{
336
    local files="$*"
337
    [ -z "$files" ] && return
338

339 340 341 342 343 344 345
    # on some systems install target can be a real path
    # use hi-level for install by file path (f.i. epm install /usr/bin/git)
    if __epm_if_command_path $files ; then
        epm_install_names $files
        return
    fi

Vitaly Lipatov's avatar
Vitaly Lipatov committed
346 347 348
    # TODO: check read permissions
    # sudo test -r FILE
    # do not fallback to install_names if we have no permissions
349 350
    case "$BASEDISTRNAME" in
        "alt")
351 352
            load_helper epm-install-alt
            epm_install_files_alt $files
353
            return
354
            ;;
355
    esac
356

357
    case $PMTYPE in
Vitaly Lipatov's avatar
Vitaly Lipatov committed
358
        apt-dpkg|aptitude-dpkg)
359 360
            load_helper epm-install-apt-dpkg
            epm_install_files_apt_dpkg $files
Vitaly Lipatov's avatar
Vitaly Lipatov committed
361
            return
362
            ;;
363

364
       *-rpm)
365 366
            load_helper epm-install-rpm
            epm_install_files_rpm $files
367
            return
368
            ;;
369 370 371
    esac


372 373
    # check save_only before commands without repack supporting
    if [ -n "$save_only" ] ; then
374
        echo
375
        cp -v $files "$EPMCURDIR"
376 377 378
        return
    fi

379 380 381 382 383 384
    if [ -n "$put_to_repo" ] ; then
        load_helper epm-repopkg
        epm_put_to_repo $files
        return
    fi

385

386
    case $PMTYPE in
387
        packagekit)
388
            docmd pkcon install-local $files
389
            return ;;
390
        pkgsrc)
391
            sudocmd pkg_add $files
392
            return ;;
393
        pkgng)
394
            local PKGTYPE="$(get_package_type $files)"
395 396
            case "$PKGTYPE" in
                tbz)
397
                    sudocmd pkg_add $files
398 399
                    ;;
                *)
400
                    sudocmd pkg add $files
401 402 403
                    ;;
            esac
            return ;;
404
        android)
405
            sudocmd pm install $files
406
            return ;;
407 408 409
        eopkg)
            sudocmd eopkg install $files
            return ;;
410
        emerge)
411
            load_helper epm-install-emerge
412
            sudocmd epm_install_emerge $files
413
            return ;;
414
        pacman)
415
            sudocmd pacman -U --noconfirm $nodeps $files && return
416 417 418
            local RES=$?

            [ -n "$nodeps" ] && return $RES
419
            sudocmd pacman -U $files
420
            return ;;
421
        slackpkg)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
422
            # FIXME: check for full package name
Vitaly Lipatov's avatar
Vitaly Lipatov committed
423
            # FIXME: broken status when use batch and default answer
424
            __separate_sudocmd_foreach "/sbin/installpkg" "/sbin/upgradepkg" $files
425
            return ;;
426 427
    esac

428
    # other systems can install file package via ordinary command
429
    epm_install_names $files
430 431
}

432

433 434
epm_install()
{
435
    if [ "$BASEDISTRNAME" = "alt" ] ; then
436
        if tasknumber "$pkg_names" >/dev/null ; then
437
            load_helper epm-install-alt
438 439 440
            if [ -n "$interactive" ] ; then
                confirm_info "You are about to install $pkg_names task(s) from https://git.altlinux.org."
            fi
441 442
            epm_install_alt_tasks "$pkg_names"
            return
443
        fi
444 445
    fi

446
    if [ -n "$show_command_only" ] ; then
447
        # TODO: handle pkg_urls too
448 449
        load_helper epm-install-print-command
        epm_print_install_files_command $pkg_files
450
        epm_print_install_names_command $pkg_names
451 452 453
        return
    fi

454
    if [ -n "$interactive" ] && [ -n "$pkg_names$pkg_files$pkg_urls" ] ; then
455
        confirm_info "You are about to install $(echo $pkg_names $pkg_files $pkg_urls) package(s)."
456 457 458
        # TODO: for some packages with dependencies apt will ask later again
    fi

459
    if [ -n "$direct" ] && [ -z "$repack" ] ; then
460
        # it will put pkg_urls into pkg_files and reconstruct pkg_filenames
461 462 463
        __handle_direct_install
    fi

464 465
    if [ -n "$pkg_urls" ] ; then
        load_helper epm-download
466
        # it will put downloaded by pkg_urls packages to pkg_files and reconstruct pkg_filenames
467 468
        __handle_pkg_urls_to_install
    fi
469

470
    [ -z "$pkg_files$pkg_names" ] && info "Skip empty install list" && return 22
471

472 473 474
    # to be filter happy
    warmup_lowbase

475
    # Note: filter_out_installed_packages depends on skip_installed flag
476 477
    local names="$(echo $pkg_names | filter_out_installed_packages)"
    #local names="$(echo $pkg_names | exp_with_arch_suffix | filter_out_installed_packages)"
478
    local files="$(echo $pkg_files | filter_out_installed_packages)"
479

480
    # can be empty only after all installed packages were skipped
481 482
    if [ -z "$files$names" ] ; then
        # TODO: assert $skip_installed
483
        [ -n "$verbose" ] && info "Skip empty install list (filtered out, all requested packages is already installed)"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
484
        # FIXME: see to_remove below
485
        return 0
486
    fi
487

488
    if [ -n "$names" ] && [ -z "$direct" ] ; then
489 490 491
        # it is useful for first time running
        update_repo_if_needed
    fi
492

493 494 495 496 497 498 499 500 501 502 503
    case "$BASEDISTRNAME" in
        "alt")
            load_helper epm-install-alt
            epm_install_alt_names $names || return
            ;;
        *)
            # FIXME: see to_remove below
            epm_install_names $names || return
            ;;
    esac

504
    [ -z "$files" ] && debug "Skip empty install files list" && return 0
505

506 507
    if [ -n "$download_only" ] ; then
        # save files to the current dir before install and repack
508
        echo
509
        cp -v $files "$EPMCURDIR"
510 511 512
        return
    fi

513
    if [ -n "$repack" ] ; then
514
        # repack binary files if asked
515 516
        __epm_repack $files || return
        files="$repacked_pkgs"
517 518
    fi

519
    epm_install_files $files
Vitaly Lipatov's avatar
Vitaly Lipatov committed
520
}