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
            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 ;;
Vitaly Lipatov's avatar
Vitaly Lipatov committed
117 118 119
        redox-pkg)
            sudocmd pkg install $@
            return ;;
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 174 175 176
        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 ;;
177 178 179
        termux-pkg)
            sudocmd pkg install $@
            return ;;
180 181 182 183 184 185 186 187 188
        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 ;;
189 190 191 192
        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 ;;
193 194 195 196
        appget|winget)
            sudocmd $PMTYPE install $@
            return ;;
        *)
197
            fatal 'Have no suitable install command for $PMTYPE'
198 199
            ;;
    esac
200 201
}

202
# Non interactive install
203 204
epm_ni_install_names()
{
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 249 250 251
    [ -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 ;;
252 253
        choco)
            docmd choco install $@
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
            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 ;;
280 281 282
        termux-pkg)
            sudocmd pkg install $@
            return ;;
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 ;;
        *)
288
            fatal 'Have no suitable appropriate install command for $PMTYPE'
289 290
            ;;
    esac
Vitaly Lipatov's avatar
Vitaly Lipatov committed
291 292
}

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

299 300
__handle_direct_install()
{
301 302
    case "$BASEDISTRNAME" in
        "alt")
303 304 305 306 307 308 309 310 311 312 313 314 315
            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
}
316

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

326 327
__epm_if_command_path()
{
328
    is_dirpath "$1" && rhas "$1" "bin/" && ! rhas "$1" "/home"
329 330
}

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

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

342 343 344 345 346 347 348
    # 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
349 350 351
    # TODO: check read permissions
    # sudo test -r FILE
    # do not fallback to install_names if we have no permissions
352 353
    case "$BASEDISTRNAME" in
        "alt")
354 355
            load_helper epm-install-alt
            epm_install_files_alt $files
356
            return
357
            ;;
358
    esac
359

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

367
       *-rpm)
368 369
            load_helper epm-install-rpm
            epm_install_files_rpm $files
370
            return
371
            ;;
372 373 374
    esac


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

382 383 384 385 386 387
    if [ -n "$put_to_repo" ] ; then
        load_helper epm-repopkg
        epm_put_to_repo $files
        return
    fi

388

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

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

431
    # other systems can install file package via ordinary command
432
    epm_install_names $files
433 434
}

435

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

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

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

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

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

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

475 476 477
    # to be filter happy
    warmup_lowbase

478
    # Note: filter_out_installed_packages depends on skip_installed flag
479 480
    local names="$(echo $pkg_names | filter_out_installed_packages)"
    #local names="$(echo $pkg_names | exp_with_arch_suffix | filter_out_installed_packages)"
481
    local files="$(echo $pkg_files | filter_out_installed_packages)"
482

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

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

496 497 498 499 500 501 502 503 504 505 506
    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

507
    [ -z "$files" ] && debug "Skip empty install files list" && return 0
508

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

516
    if [ -n "$repack" ] ; then
517
        # repack binary files if asked
518 519
        __epm_repack $files || return
        files="$repacked_pkgs"
520 521
    fi

522
    epm_install_files $files
Vitaly Lipatov's avatar
Vitaly Lipatov committed
523
}