You need to sign in or sign up before continuing.
epm-install 16 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-requires
26
load_helper epm-check_updated_repo
27
load_helper epm-sh-warmup
28

29

30 31 32
# for zypper before SUSE/11.0
__use_zypper_no_gpg_checks()
{
Vitaly Lipatov's avatar
Vitaly Lipatov committed
33
    a='' zypper install --help 2>&1 | grep -q -- "--no-gpg-checks" && echo "--no-gpg-checks"
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 59
# 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
60
        sudocmd $cmd_re $pkg_noninstalled || return
61 62
    fi
    if [ -n "$pkg_installed" ] ; then
63
        sudocmd $cmd_in $pkg_installed || return
64 65 66 67
    fi
    return 0
}

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

    warmup_hibase

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

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

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

91
    if [ -n "$force_overwrite" ] ; then
92
        APTOPTIONS="$APTOPTIONS -o Dpkg::Options::=--force-overwrite"
93 94
    fi

95 96
    case $PMTYPE in
        apt-rpm|apt-dpkg)
97
            APTOPTIONS="$APTOPTIONS -o APT::Sandbox::User=root $(subst_option verbose "-o Debug::pkgMarkInstall=1 -o Debug::pkgProblemResolver=1")"
98
            # https://bugzilla.altlinux.org/44670
99 100 101 102
            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 $@
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
            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
122 123 124
        redox-pkg)
            sudocmd pkg install $@
            return ;;
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 177 178 179 180 181
        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 ;;
182 183 184
        termux-pkg)
            sudocmd pkg install $@
            return ;;
185 186 187 188 189 190 191 192 193
        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 ;;
194 195 196 197
        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 ;;
198 199 200 201
        appget|winget)
            sudocmd $PMTYPE install $@
            return ;;
        *)
202
            fatal 'Have no suitable install command for $PMTYPE'
203 204
            ;;
    esac
205 206
}

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

298 299
__epm_check_if_rpm_already_installed()
{
300
    # Not: we can make optimize if just check version?
301
    LC_ALL=C sudorun rpm -Uvh --test "$@" 2>&1 | grep -q "is already installed"
302 303
}

304 305
__handle_direct_install()
{
306 307
    case "$BASEDISTRNAME" in
        "alt")
308 309 310 311 312 313 314 315 316 317 318 319 320
            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
}
321

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

331 332
__epm_if_command_path()
{
333
    is_dirpath "$1" && rhas "$1" "bin/" && ! rhas "$1" "/home"
334 335
}

336 337 338 339 340 341
__epm_get_replacepkgs()
{
    [ -n "$2" ] && echo '--replacepkgs' && return
    # don't use --replacepkgs when install only one file
}

342
epm_install_files()
Vitaly Lipatov's avatar
Vitaly Lipatov committed
343
{
344
    local files="$*"
345
    [ -z "$files" ] && return
346

347
    # TODO: enable support only for systems with support for it
348
    # on some systems install target can be a real path
349
    # use hi-level for install by command path (f.i. epm install /usr/bin/git)
350 351 352
    if __epm_if_command_path $files ; then
        epm_install_names $files
        return
353 354
    elif is_dirpath "$1" && [ ! -f "$1" ] ; then
        fatal "Can't install non-existent file '$1'"
355 356
    fi

Vitaly Lipatov's avatar
Vitaly Lipatov committed
357 358 359
    # TODO: check read permissions
    # sudo test -r FILE
    # do not fallback to install_names if we have no permissions
360 361
    case "$BASEDISTRNAME" in
        "alt")
362 363
            load_helper epm-install-alt
            epm_install_files_alt $files
364
            return
365
            ;;
366
    esac
367

368
    case $PMTYPE in
Vitaly Lipatov's avatar
Vitaly Lipatov committed
369
        apt-dpkg|aptitude-dpkg)
370 371
            load_helper epm-install-apt-dpkg
            epm_install_files_apt_dpkg $files
Vitaly Lipatov's avatar
Vitaly Lipatov committed
372
            return
373
            ;;
374

375
       *-rpm)
376 377
            load_helper epm-install-rpm
            epm_install_files_rpm $files
378
            return
379
            ;;
380 381 382
    esac


383 384
    # check save_only before commands without repack supporting
    if [ -n "$save_only" ] ; then
385
        echo
386
        cp -v $files "$EPMCURDIR"
387 388 389
        return
    fi

390 391 392 393 394 395
    if [ -n "$put_to_repo" ] ; then
        load_helper epm-repopkg
        epm_put_to_repo $files
        return
    fi

396

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

            [ -n "$nodeps" ] && return $RES
430
            sudocmd pacman -U $files
431
            return ;;
432
        slackpkg)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
433
            # FIXME: check for full package name
Vitaly Lipatov's avatar
Vitaly Lipatov committed
434
            # FIXME: broken status when use batch and default answer
435
            __separate_sudocmd_foreach "/sbin/installpkg" "/sbin/upgradepkg" $files
436
            return ;;
437 438
    esac

439
    # other systems can install file package via ordinary command
440
    epm_install_names $files
441 442
}

443

444 445
epm_install()
{
446
    if [ "$BASEDISTRNAME" = "alt" ] ; then
447
        if tasknumber "$pkg_names" >/dev/null ; then
448
            load_helper epm-install-alt
449 450 451
            if [ -n "$interactive" ] ; then
                confirm_info "You are about to install $pkg_names task(s) from https://git.altlinux.org."
            fi
452 453
            epm_install_alt_tasks "$pkg_names"
            return
454
        fi
455 456
    fi

457 458 459 460
    if [ -n "$manual_requires" ] ; then
        local pkg_names="$pkg_names $(short=1 epm_requires $pkg_names)"
    fi

461
    if [ -n "$show_command_only" ] ; then
462
        # TODO: handle pkg_urls too
463 464
        load_helper epm-install-print-command
        epm_print_install_files_command $pkg_files
465
        epm_print_install_names_command $pkg_names
466 467 468
        return
    fi

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

474
    if [ -n "$direct" ] && [ -z "$repack" ] ; then
475
        # it will put pkg_urls into pkg_files and reconstruct pkg_filenames
476 477 478
        __handle_direct_install
    fi

479 480
    if [ -n "$pkg_urls" ] ; then
        load_helper epm-download
481
        # it will put downloaded by pkg_urls packages to pkg_files and reconstruct pkg_filenames
482 483
        __handle_pkg_urls_to_install
    fi
484

Vitaly Lipatov's avatar
Vitaly Lipatov committed
485
    [ -z "$pkg_files$pkg_names" ] && info "Empty install list was skipped" && return 22
486

487 488 489
    # to be filter happy
    warmup_lowbase

490
    # Note: filter_out_installed_packages depends on skip_installed flag
491 492
    local names="$(echo $pkg_names | filter_out_installed_packages)"
    #local names="$(echo $pkg_names | exp_with_arch_suffix | filter_out_installed_packages)"
493
    local files="$(echo $pkg_files | filter_out_installed_packages)"
494

495
    # can be empty only after all installed packages were skipped
496 497
    if [ -z "$files$names" ] ; then
        # TODO: assert $skip_installed
Vitaly Lipatov's avatar
Vitaly Lipatov committed
498
        [ -n "$verbose" ] && info "Empty install list was skipped (filtered out, all requested packages is already installed)"
Vitaly Lipatov's avatar
Vitaly Lipatov committed
499
        # FIXME: see to_remove below
500
        return 0
501
    fi
502

503
    if [ -n "$names" ] && [ -z "$direct" ] ; then
504 505 506
        # it is useful for first time running
        update_repo_if_needed
    fi
507

508 509 510 511 512 513 514 515 516 517 518
    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

Vitaly Lipatov's avatar
Vitaly Lipatov committed
519
    [ -z "$files" ] && debug "Empty install files list was skipped" && return 0
520

521 522
    if [ -n "$download_only" ] ; then
        # save files to the current dir before install and repack
523
        echo
524
        cp -v $files "$EPMCURDIR"
525 526 527
        return
    fi

528
    if [ -n "$repack" ] ; then
529
        # repack binary files if asked
530 531
        __epm_repack $files || return
        files="$repacked_pkgs"
532 533
    fi

534
    epm_install_files $files
Vitaly Lipatov's avatar
Vitaly Lipatov committed
535
}