diff --git a/TODO b/TODO index f753199cd21ee70fe594be34cc7127c7da014d77..32329a49b6eefb44c857deedd63e2e401acc38c6 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,9 @@ +TODO: yaourt (pacman frontend), need we? +https://archlinux.fr/man/yaourt.8.html + /etc/eepm.conf конфиг -FIXME: epm-install need realpath, missed on some systems +implement distr_info as inside tool and do access via epm command [18:21:12] <danil> Вот так можно: RED='\033[0;31m' ; NC='\033[0m' b="b" ; echo -e "aba" | sed -e "s|${b}|\\${RED}${b}\\${NC}|g" | xargs -0 printf diff --git a/bin/distr_info b/bin/distr_info index fbe29174ea28cc96ef8d57addd390cf937880e01..e0d173d3d9229451f674b016e41f8ad5487488bd 100755 --- a/bin/distr_info +++ b/bin/distr_info @@ -61,7 +61,7 @@ pkgtype() debian|ubuntu|mint|runtu|mcst|astra) echo "deb" ;; alt|asplinux|suse|mandriva|rosa|mandrake|pclinux|sled|sles) echo "rpm" ;; - fedora|redhat|scientific|centos|rhel) + fedora|redhat|scientific|centos|rhel|goslinux) echo "rpm" ;; *) echo "rpm" ;; esac @@ -69,8 +69,8 @@ pkgtype() get_var() { - grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" - + # get first variable and print it out, drop quotes if exists + grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" | sed -e "s/^[\'\"]\(.*\)[\'\"]/\1/" } # 2010.1 -> 2010 @@ -97,6 +97,7 @@ if distro altlinux-release ; then if has Sisyphus ; then DISTRIB_RELEASE="Sisyphus" elif has "ALT Linux 7." ; then DISTRIB_RELEASE="p7" elif has "ALT Linux 8." ; then DISTRIB_RELEASE="p8" + elif has "ALT .*8.[0-9]" ; then DISTRIB_RELEASE="p8" elif has "Simply Linux 6." ; then DISTRIB_RELEASE="p6" elif has "Simply Linux 7." ; then DISTRIB_RELEASE="p7" elif has "Simply Linux 8." ; then DISTRIB_RELEASE="p8" @@ -241,6 +242,8 @@ elif distro redhat-release ; then DISTRIB_ID="CentOS" elif has Scientific ; then DISTRIB_ID="Scientific" + elif has GosLinux ; then + DISTRIB_ID="GosLinux" fi if has Beryllium ; then DISTRIB_ID="Scientific" @@ -298,7 +301,13 @@ elif [ `uname -o 2>/dev/null` = "Cygwin" ] ; then # try use standart LSB info by default elif distro lsb-release && [ -n "$DISTRIB_RELEASE" ]; then # use LSB - true + + # fix distro name + case "$DISTRIB_ID" in + "openSUSE Tumbleweed") + DISTRIB_ID="Tumbleweed" + ;; + esac fi case $1 in @@ -340,7 +349,7 @@ case $1 in exit 0 ;; -V) - echo "20160822" + echo "20161212" exit 0 ;; *) diff --git a/bin/epm b/bin/epm index 6b1d0930e5a63b67e31cf5839b5b2d4856514d82..df1451483d0cbcbe601dac6961023431ecee9c8d 100755 --- a/bin/epm +++ b/bin/epm @@ -65,7 +65,7 @@ print_version() { echo "EPM package manager version @VERSION@" echo "Running on $($DISTRVENDOR) ('$PMTYPE' package manager uses '$PKGFORMAT' package format)" - echo "Copyright (c) Etersoft 2012-2016" + echo "Copyright (c) Etersoft 2012-2017" echo "This program may be freely redistributed under the terms of the GNU AGPLv3." } @@ -80,6 +80,7 @@ nodeps= noremove= force= short= +direct= sort= non_interactive= skip_installed= @@ -157,7 +158,7 @@ check_command() -i|install|add|i) # HELPCMD: install package(s) from remote repositories or from local file epm_cmd=install ;; - -e|-P|remove|delete|uninstall|erase|e) # HELPCMD: remove (delete) package(s) from the database and the system + -e|-P|rm|del|remove|delete|uninstall|erase|e) # HELPCMD: remove (delete) package(s) from the database and the system epm_cmd=remove ;; -s|search|s) # HELPCMD: search in remote package repositories @@ -189,7 +190,7 @@ check_command() check|fix|verify) # HELPCMD: check local package base integrity and fix it epm_cmd=check ;; - changelog|cl|-cl) # HELPCMD: show changelog for package + -cl|cl|changelog) # HELPCMD: show changelog for package epm_cmd=changelog ;; -qi|qi|info|show) # HELPCMD: print package detail info @@ -210,13 +211,13 @@ check_command() conflicts) # HELPCMD: print package conflicts epm_cmd=conflicts ;; - -qa|list|packages|-l|qa) # HELPCMD: print list of installed package(s) + -qa|qa|-l|list|packages) # HELPCMD: print list of installed package(s) epm_cmd=packages ;; - programs) # HELPCMD: print list of installed GUI program(s) + programs) # HELPCMD: print list of installed GUI program(s) (they have .desktop files) epm_cmd=programs ;; - assure) # HELPCMD: <command> [package]: install package if command does not exists + assure) # HELPCMD: <command> [package]: install package if command does not exist epm_cmd=assure ;; policy) # HELPCMD: print detailed information about the priority selection of package @@ -283,7 +284,7 @@ check_command() site|url) # HELPCMD: open package's site in a browser (use -p for open packages.altlinux.org site) epm_cmd=site ;; - ei|epminstall|epm-install|selfinstall) # HELPCMD: install or update eepm from all in one script + ei|epminstall|epm-install|selfinstall) # HELPCMD: install or update eepm package from all in one script epm_cmd=epm_install ;; print) # HELPCMD: print various info, run epm print help for details @@ -335,6 +336,9 @@ check_option() --short) # HELPOPT: short output (just 'package' instead 'package-version-release') short="--short" ;; + --direct) # HELPOPT: direct install package file from ftp (not via hilevel repository manager) + direct="--direct" + ;; --sort) # HELPOPT: sort output, f.i. --sort=size (supported only for packages command) # TODO: how to read arg? sort="$1" @@ -402,7 +406,9 @@ pkg_filenames=$(strip_spaces "$pkg_files $pkg_names") if [ -z "$epm_cmd" ] ; then print_version echo - fatal "Unknown command $@. Run $ $PROGNAME --help for get help" + fatstr="Unknown command in $@ arg(s)" + [ -n "$*" ] || fatstr="That program needs be running with some command" + fatal "$fatstr. Run $ $PROGNAME --help to get help." fi # Use eatmydata for write specific operations diff --git a/bin/epm-addrepo b/bin/epm-addrepo index e8df16fb0eaf3ff7f0a660de6514398e5106d547..8bdba4ec1f7cd18e822e29b969665081b8ac47b0 100644 --- a/bin/epm-addrepo +++ b/bin/epm-addrepo @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (C) 2012, 2016 Etersoft -# Copyright (C) 2012, 2016 Vitaly Lipatov <lav@etersoft.ru> +# Copyright (C) 2012, 2017 Etersoft +# Copyright (C) 2012, 2017 Vitaly Lipatov <lav@etersoft.ru> # # 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 @@ -19,12 +19,49 @@ epm_addrepo() { -local repo="$(eval echo $quoted_args)" -case $PMTYPE in - apt-rpm) +local repo="$(eval echo "$quoted_args")" + +case $DISTRNAME in + ALTLinux) + case "$repo" in + etersoft) + info "add etersoft repo" + load_helper epm-query + epm install --skip-installed apt-conf-etersoft-common apt-conf-etersoft-hold || fatal + local branch="$DISTRVERSION/branch" + [ "$DISTRVERSION" = "Sisyphus" ] && branch="$DISTRVERSION" + # FIXME + [ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION" + local arch=$(uname -m) + [ "$arch" = "i686" ] && arch="i586" + echo "" | sudocmd tee -a /etc/apt/sources.list + echo "# added with eepm addrepo etersoft" | sudocmd tee -a /etc/apt/sources.list + echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch addon" | sudocmd tee -a /etc/apt/sources.list + if [ "$arch" = "x86_64" ] ; then + echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch-i586 addon" | sudocmd tee -a /etc/apt/sources.list + fi + echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/noarch addon" | sudocmd tee -a /etc/apt/sources.list + repo="$DISTRVERSION" + return 0 + ;; + autoimports) + [ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION" + repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")" + esac + assure_exists apt-repo + if [ -z "$repo" ] ; then + docmd apt-repo add branch + echo "etersoft" + return + fi sudocmd apt-repo add "$repo" + return ;; +esac + + +case $PMTYPE in apt-dpkg|aptitude-dpkg) info "You need manually add repo to /etc/apt/sources.list" ;; diff --git a/bin/epm-autoremove b/bin/epm-autoremove index f94b3061217375bf8ee1a526bc2869e7a0cbe35e..c421cbfbae8fdd30427daa4244abcf82c31a8eed 100644 --- a/bin/epm-autoremove +++ b/bin/epm-autoremove @@ -17,45 +17,76 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -__epm_autoremove_altrpm() +__epm_autoremove_altrpm_pp() { - local pkg - load_helper epm-packages - assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts + local pkgs + + info "Removing unused python/perl modules..." + #[ -n "$force" ] || info "You can run with --force for more deep removing" + local force=force + + local flag= + [ -n "$force" ] || libexclude=$libexclude'[^-]*$' + + libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)' + [ -n "$force" ] || libexclude=$libexclude'[^-]*$' + showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\"" + pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" ) + [ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1 + + if [ -n "$flag" ] ; then + info "" + info "call again for next cycle until all modules will be removed" + __epm_autoremove_altrpm_pp + fi + + return 0 +} + +__epm_autoremove_altrpm_lib() +{ + local pkgs + info info "Removing all non -devel/-debuginfo libs packages not need by anything..." #[ -n "$force" ] || info "You can run with --force for more deep removing" local force=force local flag= - local libexclude='^lib' + local libexclude='^(lib|i586-lib)' [ -n "$force" ] || libexclude=$libexclude'[^-]*$' # https://www.altlinux.org/APT_в_ALT_Linux/Советы_по_использованию#apt-cache_list-nodeps showcmd "apt-cache list-nodeps | grep -- \"$libexclude\"" - pkgs=$(apt-cache list-nodeps | grep -- "$libexclude" \ - | grep -E -v -- "-(devel|debuginfo)$" \ + pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" \ + | sed -e "s/[-\.]32bit$//g" \ + | grep -E -v -- "-(devel|devel-static|debuginfo)$" \ | grep -E -v -- "-(util|utils|tool|tools|plugin|daemon|help)$" \ - | sed -e "s/\.32bit$//g" \ - | grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|eepm)" ) - [ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1 - - info "Removing unused python/perl modules..." - libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)' - [ -n "$force" ] || libexclude=$libexclude'[^-]*$' - showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\"" - pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" ) + | grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|libsasl2-plugin|eepm)" ) [ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1 if [ -n "$flag" ] ; then info "" info "call again for next cycle until all libs will be removed" - __epm_autoremove_altrpm + __epm_autoremove_altrpm_lib fi return 0 } + +__epm_autoremove_altrpm() +{ + local pkg + load_helper epm-packages + assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts + + __epm_autoremove_altrpm_pp + __epm_autoremove_altrpm_lib + + return 0 +} + # TODO: keep our eepm package epm_autoremove() { diff --git a/bin/epm-check_updated_repo b/bin/epm-check_updated_repo index 7bdd23f8c8a176f50cf281aabe6fa7edab92f474..f4e453f99b292797a46454520ec9b98085157dfc 100644 --- a/bin/epm-check_updated_repo +++ b/bin/epm-check_updated_repo @@ -34,15 +34,15 @@ __is_repo_info_downloaded() __is_repo_info_uptodate() { case $PMTYPE in - apt-rpm) + apt-*) # apt-deb do not update lock file date - if $SUDO test -r /var/lib/apt/lists ; then - local LOCKFILE=/var/lib/apt/lists/lock + #if $SUDO test -r /var/lib/apt/lists ; then + local LOCKFILE=/var/lib/apt/lists $SUDO test -r $LOCKFILE || return # if repo older than 1 day, return false # find print string if file is obsoleted - test -z "$($SUDO find $LOCKFILE -mtime +1)" || return - fi + test -z "$(find $LOCKFILE -maxdepth 0 -mtime +1)" || return + #fi ;; *) ;; diff --git a/bin/epm-download b/bin/epm-download index 7ab4d2305c101feffd04d8d2359455e490554eb7..e223dcfd5aa3fec930dcb8cba3c608fe7cc266df 100644 --- a/bin/epm-download +++ b/bin/epm-download @@ -19,11 +19,19 @@ __use_url_install() { - case $PMTYPE in - apt-rpm) - # ALT Linux really? + case $DISTRNAME in + "ALTLinux") + # not for https + echo "$pkg_urls" | grep -q "https://" && return 1 pkg_names="$pkg_names $pkg_urls" + return 0 ;; + esac + + case $PMTYPE in + #apt-rpm) + # pkg_names="$pkg_names $pkg_urls" + # ;; #deepsolver-rpm) # pkg_names="$pkg_names $pkg_urls" # ;; @@ -54,13 +62,15 @@ __download_pkg_urls() for url in $pkg_urls ; do # TODO: use some individual tmp dir local new_file=/tmp/$(basename "$url") - if eget -O $new_file $url && [ -s "$new_file" ] ; then + if docmd eget -O $new_file $url && [ -s "$new_file" ] ; then pkg_files="$pkg_files $new_file" to_remove_pkg_files="$to_remove_pkg_files $new_file" else warning "Failed to download $url, ignoring" fi done + # restore + pkg_filenames=$(strip_spaces "$pkg_files $pkg_names") } # NOTE: call __clean_downloaded_pkg_files after @@ -70,8 +80,8 @@ __handle_pkg_urls_to_install() # TODO: do it correctly to_remove_pkg_files= - - if [ "$(get_package_type "$pkg")" != $PKGFORMAT ] || ! __use_url_install ; then + # FIXME: check type of pkg_urls separately? + if [ "$(get_package_type "$pkg_urls")" != $PKGFORMAT ] || ! __use_url_install ; then # use workaround with eget: download and put in pkg_files __download_pkg_urls fi @@ -98,11 +108,38 @@ __handle_pkg_urls_to_checking() # rm -fv $to_remove_pkg_files #} +__epm_get_altpkg_url() +{ + info "TODO: https://packages.altlinux.org/api/branches" + load_helper epm-site + local arch=$(paoapi packages/$1 | get_pao_var arch) + # FIXME: arch can be list + [ "$arch" = "noarch" ] || arch=$(arch) + # HACK: filename can be list + local filename=$(paoapi packages/$1 | get_pao_var filename | grep $arch) + [ -n "$filename" ] || fatal "Can't get filename" + # fixme: get from /branches + local dv=$DISTRNAME/$DISTRVERSION/branch + [ "$DISTRVERSION" = "Sisyphus" ] && dv=$DISTRNAME/$DISTRVERSION + echo "http://ftp.basealt.ru/pub/distributions/$dv/$arch/RPMS.classic/$filename" +} epm_download() { local CMD + case $DISTRNAME in + ALTLinux) + local pkg + for pkg in $pkg_filenames ; do + local url=$(__epm_get_altpkg_url $pkg) + [ -n "$url" ] || warning "Can't get url for $pkg" + docmd eget $url + done + return + ;; + esac + case $PMTYPE in dnf-rpm) sudocmd dnf download $pkg_filenames @@ -118,6 +155,9 @@ epm_download() dnf-rpm) sudocmd dnf download $pkg_filenames ;; + urpm-rpm) + sudocmd urpmi --no-install $URPMOPTIONS $@ + ;; tce) sudocmd tce-load -w $pkg_filenames ;; diff --git a/bin/epm-filelist b/bin/epm-filelist index 81751fd6d3f0919b2e20ac5414fe5a225d686486..0cffa8a328a11210bab50d53b98990b575c70389 100644 --- a/bin/epm-filelist +++ b/bin/epm-filelist @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (C) 2012-2016 Etersoft -# Copyright (C) 2012-2016 Vitaly Lipatov <lav@etersoft.ru> +# Copyright (C) 2012-2017 Etersoft +# Copyright (C) 2012-2017 Vitaly Lipatov <lav@etersoft.ru> # # 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 @@ -37,7 +37,7 @@ __alt_local_content_filelist() { [ -n "$USETTY" ] && info "Search in $CI for $1..." - grep -h -- ".*$1$" $CI | sed -e "s|\(.*\)\t\(.*\)|\1|g" + __local_ercat $CI | grep -h -- ".*$1$" | sed -e "s|\(.*\)\t\(.*\)|\1|g" } | $OUTCMD } @@ -64,7 +64,7 @@ __epm_filelist_remote() docmd_foreach __deb_local_content_filelist $@ ;; *) - fatal "Query filelist for non installed packages does not realized" + fatal "Query filelist for non installed packages is not implemented yet." ;; esac } @@ -134,7 +134,7 @@ __epm_filelist_name() return ;; slackpkg) - is_installed $@ || fatal "Query filelist for non installed packages does not realized" + is_installed $@ || fatal "Query filelist for non installed packages is not implemented yet" docmd awk 'BEGIN{desk=1}{if(/^FILE LIST:$/){desk=0} else if (desk==0) {print}}' /var/log/packages/${pkg_filenames}* | less return ;; diff --git a/bin/epm-info b/bin/epm-info index 1e6c61bd2b5e6027254903f810a613e1e3e261e8..4f7f5c47762454d1b8b7521d725487399ca4f5dd 100644 --- a/bin/epm-info +++ b/bin/epm-info @@ -29,10 +29,16 @@ __epm_info_rpm_low() } # TODO: separate to _files and _names parts -# realize _files part per package, not by PMTYPE (see filelist) +# implement _files part per package, not by PMTYPE (see filelist) epm_info() { +# if possible, it will put pkg_urls into pkg_files or pkg_names +if [ -n "$pkg_urls" ] ; then + load_helper epm-download + __handle_pkg_urls_to_checking +fi + [ -n "$pkg_filenames" ] || fatal "Info: missing package(s) name" case $PMTYPE in @@ -117,4 +123,10 @@ case $PMTYPE in ;; esac +local RETVAL=$? + +# TODO: reinvent +[ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files + +return $RETVAL } diff --git a/bin/epm-install b/bin/epm-install index e3e62e97d204e2494d9ffe6b7410d52454e93f9a..c339bd6d9fb0d24f7fd496bd137c17952c25fdc4 100644 --- a/bin/epm-install +++ b/bin/epm-install @@ -312,7 +312,6 @@ __epm_check_if_try_install_rpm() cd $TDIR for pkg in $rpmpkgs ; do showcmd_store_output fakeroot alien -d -k --scripts "$pkg" - clean_store_output local DEBCONVERTED=$(grep "deb generated" $RC_STDOUT | sed -e "s| generated||g") clean_store_output epm install $DEBCONVERTED @@ -323,6 +322,23 @@ __epm_check_if_try_install_rpm() return 0 } +__handle_direct_install() +{ + case "$DISTRNAME" in + "ALTLinux") + 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 +} epm_install_files() { @@ -514,6 +530,10 @@ epm_install() return fi + if [ -n "$direct" ] ; then + __handle_direct_install + fi + # if possible, it will put pkg_urls into pkg_files or pkg_names if [ -n "$pkg_urls" ] ; then load_helper epm-download @@ -527,7 +547,7 @@ epm_install() [ -z "$files$names" ] && info "Skip empty install list" && return 22 - if [ -z "$files" ] ; then + if [ -z "$files" ] && [ -z "$direct" ] ; then # it is useful for first time running update_repo_if_needed fi diff --git a/bin/epm-packages b/bin/epm-packages index e48a448b0ffb63bc921c0323e5241fabb63d977f..af3fc7abae50eae434318390ea523f082cf9156d 100644 --- a/bin/epm-packages +++ b/bin/epm-packages @@ -23,13 +23,13 @@ __epm_packages_sort() case $PMTYPE in apt-rpm|yum-rpm|urpm-rpm|zypper-rpm|dnf-rpm) # FIXME: space with quotes problems, use point instead - docmd rpm -qa --queryformat "%{size}.%{name}-%{version}-%{release}\n" $pkg_filenames | sort -n + docmd rpm -qa --queryformat "%{size}@%{name}-%{version}-%{release}\n" $pkg_filenames | sed -e "s|@| |g" | sort -n -k1 ;; apt-dpkg) - docmd dpkg-query -W --showformat="\${Size}.\${Package}-\${Version}\n" $pkg_filenames | sort -n + docmd dpkg-query -W --showformat="\${Installed-Size}@\${Package}-\${Version}\n" $pkg_filenames | sed -e "s|@| |g" | sort -n -k1 ;; *) - fatal "Sorted package list are not realized for $PMTYPE" + fatal "Sorted package list function is not implemented for $PMTYPE" ;; esac } diff --git a/bin/epm-policy b/bin/epm-policy index 987af2771b44b10c68e82299cbfe83ac3f3e1649..74926b7b490315e2623ac16c74d9970411b4ef20 100644 --- a/bin/epm-policy +++ b/bin/epm-policy @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (C) 2015 Etersoft -# Copyright (C) 2015 Vitaly Lipatov <lav@etersoft.ru> +# Copyright (C) 2015, 2017 Etersoft +# Copyright (C) 2015, 2017 Vitaly Lipatov <lav@etersoft.ru> # # 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 @@ -17,11 +17,16 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +load_helper epm-query + epm_policy() { [ -n "$pkg_names" ] || fatal "Info: missing package(s) name" +# get package name for hi level package management command (with version if supported and if possible) +pkg_names=$(__epm_get_hilevel_name $pkg_names) + case $PMTYPE in apt-rpm) docmd apt-cache policy $pkg_names diff --git a/bin/epm-query b/bin/epm-query index ec4c8db8aad9ff27ec9aa98ff50d9ac599711a48..b95d307015b4ffbbd5fff421e31e374829697651 100644 --- a/bin/epm-query +++ b/bin/epm-query @@ -98,11 +98,11 @@ __epm_get_hilevel_nameform() echo $pkg return ;; - yum-rpm) + yum-rpm|dnf-rpm) # just use strict version with Epoch and Serial local pkg - pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}%{VERSION}-%{RELEASE}.${ARCH}\n" $1) - echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.${ARCH}\n" $1) + pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1) + echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1) echo $pkg return ;; diff --git a/bin/epm-query_file b/bin/epm-query_file index e20853644567d55665f5cc32f6eef847df77f627..ee3d68a1a9457976b64cdf80a35d12c86b4f9911 100644 --- a/bin/epm-query_file +++ b/bin/epm-query_file @@ -19,13 +19,27 @@ # copied from etersoft-build-utils/bin/rpmqf +# TODO: check for lib64/name situations +__abs_filename() +{ + if echo "$1" | grep -q "/" ; then + echo "$1" + return + fi + if [ -e "$1" ] ; then + echo "$(pwd)/$1" + return + fi + echo "$1" +} + __do_query_real_file() { local TOFILE # get canonical path if [ -e "$1" ] ; then - TOFILE=$(realpath "$1") + TOFILE="$(__abs_filename "$1")" else TOFILE=$(which "$1" 2>/dev/null || echo "$1") if [ "$TOFILE" != "$1" ] ; then @@ -104,7 +118,7 @@ __do_query() ;; aptcyg) #CMD="apt-cyg packageof" - # do not realized locally + # is not implemented locally return 1 ;; *) diff --git a/bin/epm-release_upgrade b/bin/epm-release_upgrade index 49c18888c222ced8d475c3c79655a4e76eadcbed..b577d7ff00a3c7b074b0b21660fe8e5e16383cda 100644 --- a/bin/epm-release_upgrade +++ b/bin/epm-release_upgrade @@ -117,7 +117,7 @@ __update_to_the_distro() ;; Sisyphus) docmd epm update || fatal - docmd epm install apt rpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again" + docmd epm install apt rpm librpm7 librpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again" docmd epm upgrade || fatal "Check an error and run epm release-upgrade again" ;; *) @@ -232,9 +232,11 @@ epm_release_upgrade() assure_exists dnf-plugin-system-upgrade sudocmd dnf system-upgrade local RELEASEVER="$pkg_filenames" - [ -n "$RELEASEVER" ] || fatal "Run me with new version" + [ -n "$RELEASEVER" ] || RELEASEVER=$(($DISTRVERSION + 1)) + #[ -n "$RELEASEVER" ] || fatal "Run me with new version" + info "Upgrate to $DISTRNAME/$RELEASEVER" sudocmd dnf system-upgrade download --refresh --releasever=$RELEASEVER - sudocmd dnf system-upgrade + sudocmd dnf distro-sync --releasever=$RELEASEVER info "Run epm autoorphans to remove orphaned packages" ;; urpm-rpm) diff --git a/bin/epm-removerepo b/bin/epm-removerepo index b90715df8671485aceeabc27bae18e6a06e6583b..ac03b071609bc68cf5d177ee579a4d66aad2d68c 100644 --- a/bin/epm-removerepo +++ b/bin/epm-removerepo @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (C) 2012, 2016 Etersoft -# Copyright (C) 2012, 2016 Vitaly Lipatov <lav@etersoft.ru> +# Copyright (C) 2012, 2017 Etersoft +# Copyright (C) 2012, 2017 Vitaly Lipatov <lav@etersoft.ru> # # 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 @@ -20,11 +20,24 @@ epm_removerepo() { local repo="$(eval echo $quoted_args)" -case $PMTYPE in - apt-rpm) + +case $DISTRNAME in + ALTLinux) + case "$repo" in + autoimports) + info "remove autoimports repo" + [ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION" + repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")" + ;; + esac + assure_exists apt-repo sudocmd apt-repo rm "$repo" + return ;; +esac; + +case $PMTYPE in apt-dpkg|aptitude-dpkg) info "You need remove repo from /etc/apt/sources.list" ;; diff --git a/bin/epm-repofix b/bin/epm-repofix index 0e998fd90148e98e9e04f3de449f64a3f14e48a0..4cd993abf6754c39bb289e3efabed41165432372 100644 --- a/bin/epm-repofix +++ b/bin/epm-repofix @@ -29,8 +29,26 @@ __repofix_check_vendor() return 1 } +# source-list vendor path +# example: /etc/apt/source.list p7 ALTLinux\/Sisyphus +__try_fix_apt_source_list() +{ + local list="$1" + local br="$2" + local path="$3" + if grep -q -e "^[^#].*$path" $list ; then + if __repofix_check_vendor $br ; then + regexp_subst "/$path/s/^rpm[[:space:]]*([fhr])/rpm [$br] \1/" $list + else + warning "Skip set $br vendor key (it misssed) for $list" + regexp_subst "/$path/s/^rpm[[:space:]]*\[$br\][[:space:]]*([fhr])/rpm \1/" $list + fi + fi +} + __fix_apt_sources_list() { + # for beauty spaces local SUBST_ALT_RULE='s!^(.*)[/ ](ALTLinux|LINUX\@Etersoft)[/ ](Sisyphus|p8[/ ]branch|p7[/ ]branch|p6[/ ]branch)[/ ](x86_64|i586|x86_64-i586|noarch) !\1 \2/\3/\4 !gi' local i assure_root @@ -42,33 +60,14 @@ __fix_apt_sources_list() regexp_subst "/^ *#/! $SUBST_ALT_RULE" $i # Sisyphus uses 'alt' vendor key - if __repofix_check_vendor alt ; then - regexp_subst "/ALTLinux\/Sisyphus\//s/^rpm *([fhr])/rpm [alt] \1/" $i - else - warning "Skip set alt vendor key (it misssed)" - fi + __try_fix_apt_source_list $i alt "ALTLinux\/Sisyphus" # skip branch replacement for ALT Linux Sisyphus [ "$DISTRVERSION" = "Sisyphus" ] && continue # add signs for branches - local br - for br in $DISTRVERSION ; do - if ! __repofix_check_vendor $br ; then - warning "Skip set $br vendor key (it misssed)" - continue - fi - regexp_subst "/ALTLinux\/$br\/branch/s/^rpm *([fhr])/rpm [$br] \1/" $i - done - - for br in $DISTRVERSION ; do - #if is_installed apt-conf-etersoft-common ; then - if ! __repofix_check_vendor etersoft ; then - warning "Skip set etersoft vendor key (it misssed)" - continue - fi - regexp_subst "/Etersoft\/$br\/branch/s/^rpm *([fhr])/rpm [etersoft] \1/" $i - done + __try_fix_apt_source_list $i $DISTRVERSION "ALTLinux\/$DISTRVERSION\/branch" + __try_fix_apt_source_list $i etersoft "Etersoft\/$DISTRVERSION\/branch" done } diff --git a/bin/epm-search_file b/bin/epm-search_file index ddffa4ec058827edd14dfeede0b6007621b8b6c9..567dafd9d5167a8fb66f6bffeb021dc06c7e4c83 100644 --- a/bin/epm-search_file +++ b/bin/epm-search_file @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (C) 2012, 2016 Etersoft -# Copyright (C) 2012, 2016 Vitaly Lipatov <lav@etersoft.ru> +# Copyright (C) 2012, 2016, 2017 Etersoft +# Copyright (C) 2012, 2016, 2017 Vitaly Lipatov <lav@etersoft.ru> # # 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 @@ -17,21 +17,34 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +# TODO: see epm-search (colorify for all distro) + +# args: index_lists word grep_string +__alt_search_file_output() +{ + # grep only on left part (filename), then revert order and grep with color + __local_ercat $1 | grep -h -- ".*$2.*[[:space:]]" | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g" $3 +} + __alt_local_content_search() { load_helper epm-sh-altlinux + load_helper epm-search + info "Locate contents index file(s) ..." local CI="$(get_local_alt_contents_index)" + # TODO use something like [ -n "$CI" ] || fatal "Have no local contents index" - #local OUTCMD="less" - #[ -n "$USETTY" ] || OUTCMD="cat" - OUTCMD="cat" - { - [ -n "$USETTY" ] && info "Search in $CI for $1..." - # note! tabulation below! - grep -h -- ".*$1.* " $CI | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g" - } | $OUTCMD + info "Searching in" + echo "$CI" + echo "for $1... " + + # FIXME: do it better + local MGS + MGS=$(eval __epm_search_make_grep $quoted_args) + showcmd "$ cat contents_index $MGS" + eval "__alt_search_file_output \"$CI\" \"$(eval get_firstarg $quoted_args)\" $MGS" } epm_search_file() @@ -50,12 +63,12 @@ case $PMTYPE in return ;; yum-rpm) # TODO - info "Search by full packages list does not realized" + info "Search by full packages list is not implemented yet" CMD="yum provides" ;; dnf-rpm) # TODO - info "Search by full packages list does not realized" + info "Search by full packages list is not implemented yet" CMD="dnf provides" ;; urpm-rpm) diff --git a/bin/epm-sh-altlinux b/bin/epm-sh-altlinux index a74db9885f9396f268ea00b60e0cf5bee612688b..f9e563e093f5812605212b7974cbc6fe5317ba74 100644 --- a/bin/epm-sh-altlinux +++ b/bin/epm-sh-altlinux @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (C) 2014 Etersoft -# Copyright (C) 2014 Vitaly Lipatov <lav@etersoft.ru> +# Copyright (C) 2014, 2017 Etersoft +# Copyright (C) 2014, 2017 Vitaly Lipatov <lav@etersoft.ru> # # 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 @@ -17,19 +17,98 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -# TODO: port or rewrite apt-file +# apt-file like. See also # https://bugzilla.altlinux.org/show_bug.cgi?id=14449 + +# convert "http://download.etersoft.ru/pub/ALTLinux/p8/branch x86_64" to /tmp/epm/ALTLinux/p8/branch/x86_64 +get_local_alt_mirror_path() +{ + local DN1=$(dirname "$1") + local DN2=$(dirname $DN1) + local DN3=$(dirname $DN2) + + local BN0=$(basename "$1") # arch + local BN1=$(basename $DN1) # branch/Sisyphus + local BN2=$(basename $DN2) # p8/ALTLinux + local BN3=$(basename $DN3) # ALTLinux/ + + [ "$BN1" = "branch" ] && echo "/tmp/eepm/$BN3/$BN2/$BN1/$BN0" || echo "/tmp/eepm/$BN2/$BN1/$BN0" +} + +__local_ercat() +{ + local i + for i in $* ; do + case "$i" in + *.xz) + a= xzcat $i + ;; + *.lz4) + a= lz4cat $i + ;; + *.failed) + # just ignore + ;; + *) + cat $i + ;; + esac + done +} + +# something like gzip +compress_file_inplace() +{ + local OFILE="$1" + if epm assure lz4 </dev/null ; then + #docmd lz4 --rm "$OFILE" "$OFILE.lz4" || return + # due old lz4 + docmd lz4 "$OFILE" "$OFILE.lz4" || return + rm -fv "$OFILE" + else + epm assure xz </dev/null || return + docmd xz "$OFILE" || return + fi + return 0 +} + +# args: url/path target_file +# result: will set FILE +download_alt_contents_index() +{ + local URL="$1" + local TD="$2" + local OFILE="$TD/$(basename "$URL")" + + local DONE=$(echo $OFILE*) + # TODO: check if too old + if [ -r "$DONE" ] ; then + return + fi + + mkdir -p "$TD" + + if echo "$URL" | grep -q "^file:/" ; then + URL=$(echo "$URL" | sed -e "s|^file:||") + [ -s "$URL" ] || { touch $OFILE.failed ; return 1; } + ln -s "$URL" "$OFILE" || { touch $OFILE.failed ; return 1; } + else + docmd eget -O "$OFILE" "$URL" || { rm -fv $OFILE ; touch $OFILE.failed ; return 1; } + fi + + compress_file_inplace "$OFILE" +} + get_local_alt_contents_index() { load_helper epm-repolist - epm_repolist | grep "rpm.*file:/" | sed -e "s|^rpm.*file:||g" | while read URL ARCH other ; do - test -d "$URL/$ARCH" || continue # fatal "Local mirror is not accessible via $URL/$ARCH" - FILE="$URL/$ARCH/base/contents_index" - if [ -r "$FILE" ] ; then - echo "$FILE" - else - info "TODO for girar server: There is no $(basename $FILE) file in $(dirname $FILE)" - fi + local LOCALPATH + + epm_repolist | grep -E "rpm.*(ftp://|http://|https://|file:/)" | sed -e "s@^rpm.*\(ftp://\|http://\|https://\|file:\)@\1@g" | while read URL ARCH other ; do + LOCALPATH=$(get_local_alt_mirror_path "$URL/$ARCH") + download_alt_contents_index $URL/$ARCH/base/contents_index $LOCALPATH >&2 || continue + echo "$LOCALPATH/contents_index*" done + } diff --git a/bin/epm-sh-functions b/bin/epm-sh-functions index 3bdbf001358c5d29df2e5a7dba64045a189fe834..93c9c27fb5dd6997740d8999c4940e5bcc215352 100644 --- a/bin/epm-sh-functions +++ b/bin/epm-sh-functions @@ -154,6 +154,14 @@ sudocmd_foreach() done } +# add realpath if missed +if ! which realpath 2>/dev/null >/dev/null ; then +realpath() +{ + readlink -f "$@" +} +fi + get_firstarg() { echon "$1" @@ -459,14 +467,14 @@ case $DISTRNAME in ArchLinux) CMD="pacman" ;; - Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific) + Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux) CMD="yum-rpm" which dnf 2>/dev/null >/dev/null && test -d /var/lib/dnf/yumdb && CMD=dnf-rpm ;; Slackware) CMD="slackpkg" ;; - SUSE|SLED|SLES) + SUSE|SLED|SLES|Tumbleweed) CMD="zypper-rpm" ;; ForesightLinux|rPathLinux) @@ -515,6 +523,7 @@ is_active_systemd() [ -x "$SYSTEMCTL" ] || return [ -d "$SYSTEMD_CGROUP_DIR" ] || return a= mountpoint -q "$SYSTEMD_CGROUP_DIR" || return + readlink /sbin/init | grep -q 'systemd' || return # some hack - ps ax | grep -q '[s]ystemd' | grep -v 'systemd-udev' >/dev/null + ps ax | grep '[s]ystemd' | grep -q -v 'systemd-udev' } diff --git a/bin/epm-site b/bin/epm-site index c48ccb48b59b4ea6bb2bd72f69282e30938e4fc3..0789ec86c552cbbefd7a8296491aff3592f29847 100644 --- a/bin/epm-site +++ b/bin/epm-site @@ -22,6 +22,24 @@ load_helper epm-print PAOURL="https://packages.altlinux.org" +paoapi() +{ + # http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs + epm assure curl || return 1 + showcmd curl "$PAOURL/api/$1" + a= curl -s --header "Accept: application/json" "$PAOURL/api/$1" +} + +# TODO: use /home/lav/Projects/git/JSON.sh +get_pao_var() +{ + local FIELD="$1" + #grep '"$FIELD"' | sed -e 's|.*"$FIELD":"||g' | sed -e 's|".*||g' + $SHAREDIR/tools_json -b | egrep "\[.*\"$FIELD\"\]" | sed -e 's|.*[[:space:]]"\(.*\)"|\1|g' + return 0 +} + + run_command_if_exists() { local CMD="$1" @@ -43,14 +61,9 @@ open_browser() __query_package_hl_url() { - local PAOAPI="$PAOURL/api" case $DISTRNAME in ALTLinux) - # http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs - epm assure curl || return 1 - showcmd curl "$PAOAPI/srpms/$1" - a= curl -s --header "Accept: application/json" "$PAOAPI/srpms/$1" | grep '"url"' | sed -e 's|.*"url":"||g' | sed -e 's|".*||g' - return 0 + paoapi srpms/$1 | get_pao_var url ;; esac return 1 diff --git a/bin/epm-upgrade b/bin/epm-upgrade index 0943699cbfb4aa57873eb9f35d046f7fcd7fa965..8ac13cfb05f850bb10084cc37efc9d0970c11bed 100644 --- a/bin/epm-upgrade +++ b/bin/epm-upgrade @@ -23,7 +23,7 @@ epm_upgrade() { local CMD - [ -z "$pkg_filenames" ] || fatal "No arguments are allowed here" + #[ -z "$pkg_filenames" ] || fatal "No arguments are allowed here" # it is useful for first time running update_repo_if_needed @@ -42,18 +42,18 @@ epm_upgrade() yum-rpm) local OPTIONS="$(subst_option non_interactive -y)" # can do update repobase automagically - CMD="yum $OPTIONS update" + CMD="yum $OPTIONS update $pkg_filenames" ;; dnf-rpm) local OPTIONS="$(subst_option non_interactive -y)" - CMD="dnf $OPTIONS distro-sync" + CMD="dnf $OPTIONS distro-sync $pkg_filenames" ;; snappy) CMD="snappy update" ;; urpm-rpm) # or --auto-select --replace-files - CMD="urpmi --update --auto-select" + CMD="urpmi --update --auto-select $pkg_filenames" ;; zypper-rpm) CMD="zypper dist-upgrade" diff --git a/bin/epm-whatdepends b/bin/epm-whatdepends index f4ef16876916cdf66e053ce347bfa7fb3e403858..770fd0390c899018fadd9a57c08765272170486c 100644 --- a/bin/epm-whatdepends +++ b/bin/epm-whatdepends @@ -17,6 +17,8 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +# TODO: will it has local only mode? + load_helper epm-print epm_whatdepends() @@ -44,6 +46,7 @@ case $PMTYPE in CMD="urpmq --whatrequires" ;; dnf-rpm) + # check command: dnf repoquery --whatrequires CMD="repoquery --whatrequires" ;; emerge) diff --git a/bin/serv b/bin/serv index 7a5610791a211a47c833e44cc64f4cf62c41d8fd..5e8062ad67acb551e37a344ddd0bac1f852145da 100755 --- a/bin/serv +++ b/bin/serv @@ -58,7 +58,7 @@ case $DISTRNAME in ALTLinux) CMD="service-chkconfig" ;; - Ubuntu|Debian|Mint) + Ubuntu|Debian|Mint|AstraLinux) CMD="service-update" ;; Mandriva|ROSA) @@ -73,7 +73,7 @@ case $DISTRNAME in # ArchLinux) # CMD="pacman" # ;; - Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific) + Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux) CMD="service-chkconfig" ;; VoidLinux) @@ -82,7 +82,7 @@ case $DISTRNAME in Slackware) CMD="service-initd" ;; - SUSE|SLED|SLES) + SUSE|SLED|SLES|Tumbleweed) CMD="service-chkconfig" ;; # Windows) diff --git a/bin/tools_json b/bin/tools_json new file mode 100755 index 0000000000000000000000000000000000000000..c4452f9bf97f2fb2eed33f58685f412b11bca622 --- /dev/null +++ b/bin/tools_json @@ -0,0 +1,211 @@ +#!/bin/sh + +# License: MIT or Apache +# Homepage: http://github.com/dominictarr/JSON.sh + +throw() { + echo "$*" >&2 + exit 1 +} + +BRIEF=0 +LEAFONLY=0 +PRUNE=0 +NO_HEAD=0 +NORMALIZE_SOLIDUS=0 + +usage() { + echo + echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]" + echo + echo "-p - Prune empty. Exclude fields with empty values." + echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." + echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." + echo "-n - No-head. Do not show nodes that have no path (lines that start with [])." + echo "-s - Remove escaping of the solidus symbol (straight slash)." + echo "-h - This help text." + echo +} + +parse_options() { + set -- "$@" + local ARGN=$# + while [ "$ARGN" -ne 0 ] + do + case $1 in + -h) usage + exit 0 + ;; + -b) BRIEF=1 + LEAFONLY=1 + PRUNE=1 + ;; + -l) LEAFONLY=1 + ;; + -p) PRUNE=1 + ;; + -n) NO_HEAD=1 + ;; + -s) NORMALIZE_SOLIDUS=1 + ;; + ?*) echo "ERROR: Unknown option." + usage + exit 0 + ;; + esac + shift 1 + ARGN=$((ARGN-1)) + done +} + +awk_egrep () { + local pattern_string=$1 + + gawk '{ + while ($0) { + start=match($0, pattern); + token=substr($0, start, RLENGTH); + print token; + $0=substr($0, start+RLENGTH); + } + }' pattern="$pattern_string" +} + +tokenize () { + local GREP + local ESCAPE + local CHAR + + if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 + then + GREP='egrep -ao --color=never' + else + GREP='egrep -ao' + fi + + if echo "test string" | egrep -o "test" >/dev/null 2>&1 + then + ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\]' + else + GREP=awk_egrep + ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\\\]' + fi + + local STRING="\"$CHAR*($ESCAPE$CHAR*)*\"" + local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?' + local KEYWORD='null|false|true' + local SPACE='[[:space:]]+' + + # Force zsh to expand $A into multiple words + local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') + if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi + $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" + if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi +} + +parse_array () { + local index=0 + local ary='' + read -r token + case "$token" in + ']') ;; + *) + while : + do + parse_value "$1" "$index" + index=$((index+1)) + ary="$ary""$value" + read -r token + case "$token" in + ']') break ;; + ',') ary="$ary," ;; + *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value= + : +} + +parse_object () { + local key + local obj='' + read -r token + case "$token" in + '}') ;; + *) + while : + do + case "$token" in + '"'*'"') key=$token ;; + *) throw "EXPECTED string GOT ${token:-EOF}" ;; + esac + read -r token + case "$token" in + ':') ;; + *) throw "EXPECTED : GOT ${token:-EOF}" ;; + esac + read -r token + parse_value "$1" "$key" + obj="$obj$key:$value" + read -r token + case "$token" in + '}') break ;; + ',') obj="$obj," ;; + *) throw "EXPECTED , or } GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value= + : +} + +parse_value () { + local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 + case "$token" in + '{') parse_object "$jpath" ;; + '[') parse_array "$jpath" ;; + # At this point, the only valid single-character tokens are digits. + ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; + *) value=$token + # if asked, replace solidus ("\/") in json strings with normalized value: "/" + [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g') + isleaf=1 + [ "$value" = '""' ] && isempty=1 + ;; + esac + [ "$value" = '' ] && return + [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return + + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ + [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 + [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" + : +} + +parse () { + read -r token + parse_value + read -r token + case "$token" in + '') ;; + *) throw "EXPECTED EOF GOT $token" ;; + esac +} + +if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); +then + parse_options "$@" + tokenize | parse +fi + +# vi: expandtab sw=2 ts=2 diff --git a/eepm.spec b/eepm.spec index 0ffb7a949223458186812b7e2c95ad074cebd469..02c95d8b134646ba07e3f2d5847dfbbfd8f5711e 100644 --- a/eepm.spec +++ b/eepm.spec @@ -1,7 +1,7 @@ # This spec is backported to ALTLinux p7 automatically by rpmbph script from etersoft-build-utils. # Name: eepm -Version: 1.9.8 +Version: 2.0.6 Release: alt0.M70P.1 Summary: Etersoft EPM package manager @@ -68,9 +68,58 @@ chmod a+x %buildroot%_datadir/%name/tools_* %_sysconfdir/bash_completion.d/cerv %changelog -* Fri Dec 02 2016 Vitaly Lipatov <lav@altlinux.ru> 1.9.8-alt0.M70P.1 +* Thu Mar 23 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.6-alt0.M70P.1 - backport to ALTLinux p7 (by rpmbph script) +* Mon Mar 13 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.6-alt1 +- epm-packages: improve sort output +- hack to support old lz4 + +* Fri Mar 10 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.5-alt1 +- epm sf: make compressed cache for local file too +- rewrite epm sf, colorify it +- more correct message when empty run + +* Thu Mar 09 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.4-alt1 +- epm-policy: move to hilevel package name +- implement local cache for contents index for ALT repos + +* Tue Mar 07 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.3-alt1 +- fix query hilevel name for yum/dnf +- epm install: fix install rpm on deb +- add missed in some cases AstraLinux and GosLinux + +* Thu Mar 02 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.2-alt1 +- distr_info: fix version detection for all ALT p8 distros +- add workaround for ALT rpm missed https support +- install librpm7 during upgrade to Sisyphus +- improve systemd checking + +* Tue Feb 07 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.1-alt1 +- autoremove: skip -32bit suffix + +* Mon Jan 16 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.0-alt1 +- distr_info: fix get lsb-release file with quoted fields +- epm-download: add filename empty checking +- epm info: add URL support +- epm upgrade: allow extra args +- release_upgrade: improve for Fedora +- epm-download: add support for urpm +- check_update_repo: check for /var/lib/apt/lists date +- query_file: improve check for relative path +- epm-automove: fix i586-lib issue +- fix systemd detection +- epm: add/remove autoimports + +* Wed Dec 07 2016 Vitaly Lipatov <lav@altlinux.ru> 1.9.9-alt1 +- add own realpath implementation if missed +- add openSUSE Tumbleweed support +- autoremove: do separate removing cycles for python/perl and libs +- epm-site: fix json parsing +- epm-download: realize download via info from packages.altlinux.org +- epm-install: add direct install (not via apt) support for ALT Linux +- addrepo: implement support for epm addrepo etersoft + * Thu Dec 01 2016 Vitaly Lipatov <lav@altlinux.ru> 1.9.8-alt1 - epm-install: move download code to epm-download - epm-checkpkg: add support for checking package by url diff --git a/pack_in_onefile.sh b/pack_in_onefile.sh index 68182e243753a3dda93c39bacc6a90c556f48c8c..ec5a51b6dfa7e594a8c7c0f47450d56e4ce7f03c 100755 --- a/pack_in_onefile.sh +++ b/pack_in_onefile.sh @@ -44,6 +44,7 @@ filter_out() { grep -v "^[ ]*load_helper " | \ sed -e 's|$SHAREDIR/tools_eget|internal_tools_eget|g' | \ + sed -e 's|$SHAREDIR/tools_json|internal_tools_json|g' | \ sed -e 's|DISTRVENDOR=$PROGDIR/distr_info|DISTRVENDOR=internal_distr_info|g' | \ sed -e "s|@VERSION@|$(get_version)|g" @@ -64,6 +65,7 @@ done | filter_out >>$OUTPUT incorporate_subfile distr_info incorporate_subfile tools_eget +incorporate_subfile tools_json awk 'BEGIN{desk=0}{if(desk>0) {print} ; if(/^load_helper epm-sh-functions/){desk++}}' <bin/$PACKCOMMAND | filter_out >>$OUTPUT chmod 0755 $OUTPUT diff --git a/packed/epm.sh b/packed/epm.sh index 9269d79bcf097dfb5203cb14c7196ed9bb0ba94b..4e97ab2756a6883b9f42557067fabaabb2966980 100755 --- a/packed/epm.sh +++ b/packed/epm.sh @@ -166,6 +166,13 @@ sudocmd_foreach() done } +if ! which realpath 2>/dev/null >/dev/null ; then +realpath() +{ + readlink -f "$@" +} +fi + get_firstarg() { echon "$1" @@ -451,14 +458,14 @@ case $DISTRNAME in ArchLinux) CMD="pacman" ;; - Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific) + Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux) CMD="yum-rpm" which dnf 2>/dev/null >/dev/null && test -d /var/lib/dnf/yumdb && CMD=dnf-rpm ;; Slackware) CMD="slackpkg" ;; - SUSE|SLED|SLES) + SUSE|SLED|SLES|Tumbleweed) CMD="zypper-rpm" ;; ForesightLinux|rPathLinux) @@ -507,20 +514,57 @@ is_active_systemd() [ -x "$SYSTEMCTL" ] || return [ -d "$SYSTEMD_CGROUP_DIR" ] || return a= mountpoint -q "$SYSTEMD_CGROUP_DIR" || return + readlink /sbin/init | grep -q 'systemd' || return # some hack - ps ax | grep -q '[s]ystemd' >/dev/null + ps ax | grep '[s]ystemd' | grep -q -v 'systemd-udev' } # File bin/epm-addrepo: epm_addrepo() { -local repo="$(eval echo $quoted_args)" -case $PMTYPE in - apt-rpm) +local repo="$(eval echo "$quoted_args")" + +case $DISTRNAME in + ALTLinux) + case "$repo" in + etersoft) + info "add etersoft repo" + epm install --skip-installed apt-conf-etersoft-common apt-conf-etersoft-hold || fatal + local branch="$DISTRVERSION/branch" + [ "$DISTRVERSION" = "Sisyphus" ] && branch="$DISTRVERSION" + # FIXME + [ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION" + local arch=$(uname -m) + [ "$arch" = "i686" ] && arch="i586" + echo "" | sudocmd tee -a /etc/apt/sources.list + echo "# added with eepm addrepo etersoft" | sudocmd tee -a /etc/apt/sources.list + echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch addon" | sudocmd tee -a /etc/apt/sources.list + if [ "$arch" = "x86_64" ] ; then + echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch-i586 addon" | sudocmd tee -a /etc/apt/sources.list + fi + echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/noarch addon" | sudocmd tee -a /etc/apt/sources.list + repo="$DISTRVERSION" + return 0 + ;; + autoimports) + [ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION" + repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")" + esac + assure_exists apt-repo + if [ -z "$repo" ] ; then + docmd apt-repo add branch + echo "etersoft" + return + fi sudocmd apt-repo add "$repo" + return ;; +esac + + +case $PMTYPE in apt-dpkg|aptitude-dpkg) info "You need manually add repo to /etc/apt/sources.list" ;; @@ -708,13 +752,14 @@ case $PMTYPE in # ;; yum-rpm) showcmd package-cleanup --orphans - local PKGLIST=$(package-cleanup --orphans | grep -v "^eepm$") + local PKGLIST=$(package-cleanup -q --orphans | grep -v "^eepm-") docmd epm remove $PKGLIST ;; dnf-rpm) # TODO: dnf list extras + # TODO: Yum-utils package has been deprecated, use dnf instead. showcmd package-cleanup --orphans - local PKGLIST=$(package-cleanup --orphans | grep -v "^eepm$") + local PKGLIST=$(package-cleanup -q --orphans | grep -v "^eepm-") docmd epm remove $PKGLIST ;; urpm-rpm) @@ -760,44 +805,75 @@ esac # File bin/epm-autoremove: -__epm_autoremove_altrpm() +__epm_autoremove_altrpm_pp() { - local pkg - assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts + local pkgs + + info "Removing unused python/perl modules..." + #[ -n "$force" ] || info "You can run with --force for more deep removing" + local force=force + + local flag= + [ -n "$force" ] || libexclude=$libexclude'[^-]*$' + + libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)' + [ -n "$force" ] || libexclude=$libexclude'[^-]*$' + showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\"" + pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" ) + [ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1 + + if [ -n "$flag" ] ; then + info "" + info "call again for next cycle until all modules will be removed" + __epm_autoremove_altrpm_pp + fi + + return 0 +} + +__epm_autoremove_altrpm_lib() +{ + local pkgs + info info "Removing all non -devel/-debuginfo libs packages not need by anything..." #[ -n "$force" ] || info "You can run with --force for more deep removing" local force=force local flag= - local libexclude='^lib' + local libexclude='^(lib|i586-lib)' [ -n "$force" ] || libexclude=$libexclude'[^-]*$' # https://www.altlinux.org/APT_в_ALT_Linux/Советы_по_использованию#apt-cache_list-nodeps showcmd "apt-cache list-nodeps | grep -- \"$libexclude\"" - pkgs=$(apt-cache list-nodeps | grep -- "$libexclude" \ - | grep -E -v -- "-(devel|debuginfo)$" \ + pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" \ + | sed -e "s/[-\.]32bit$//g" \ + | grep -E -v -- "-(devel|devel-static|debuginfo)$" \ | grep -E -v -- "-(util|utils|tool|tools|plugin|daemon|help)$" \ - | sed -e "s/\.32bit$//g" \ - | grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|eepm)" ) - [ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1 - - info "Removing unused python/perl modules..." - libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)' - [ -n "$force" ] || libexclude=$libexclude'[^-]*$' - showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\"" - pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" ) + | grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|libsasl2-plugin|eepm)" ) [ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1 if [ -n "$flag" ] ; then info "" info "call again for next cycle until all libs will be removed" - __epm_autoremove_altrpm + __epm_autoremove_altrpm_lib fi return 0 } + +__epm_autoremove_altrpm() +{ + local pkg + assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts + + __epm_autoremove_altrpm_pp + __epm_autoremove_altrpm_lib + + return 0 +} + epm_autoremove() { @@ -830,7 +906,7 @@ case $PMTYPE in while true ; do docmd package-cleanup --leaves $(subst_option non_interactive --assumeyes) # FIXME: package-cleanup have to use stderr for errors - local PKGLIST=$(package-cleanup --leaves | grep -v "Loaded plugins" | grep -v "Unable to" | grep -v "^eepm$") + local PKGLIST=$(package-cleanup -q --leaves | grep -v "^eepm-") [ -n "$PKGLIST" ] || break sudocmd yum remove $PKGLIST done @@ -1093,16 +1169,31 @@ esac epm_checkpkg() { if [ -n "$pkg_names" ] ; then + # TODO: если есть / или расширение, это отсутствующий файл info "Suggest $pkg_names are name(s) of installed packages" __epm_check_installed_pkg $pkg_names return fi + # if possible, it will put pkg_urls into pkg_files or pkg_names + if [ -n "$pkg_urls" ] ; then + __handle_pkg_urls_to_checking + fi + [ -n "$pkg_files" ] || fatal "Checkpkg: missing file or package name(s)" + + local RETVAL=0 + local pkg for pkg in $pkg_files ; do - check_pkg_integrity $pkg || fatal "Broken package $pkg" + check_pkg_integrity $pkg || RETVAL=1 done + + # TODO: reinvent + [ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files + + #fatal "Broken package $pkg" + return $RETVAL } # File bin/epm-checksystem: @@ -1166,15 +1257,15 @@ __is_repo_info_downloaded() __is_repo_info_uptodate() { case $PMTYPE in - apt-rpm) + apt-*) # apt-deb do not update lock file date - if $SUDO test -r /var/lib/apt/lists ; then - local LOCKFILE=/var/lib/apt/lists/lock + #if $SUDO test -r /var/lib/apt/lists ; then + local LOCKFILE=/var/lib/apt/lists $SUDO test -r $LOCKFILE || return # if repo older than 1 day, return false # find print string if file is obsoleted - test -z "$($SUDO find $LOCKFILE -mtime +1)" || return - fi + test -z "$(find $LOCKFILE -maxdepth 0 -mtime +1)" || return + #fi ;; *) ;; @@ -1429,10 +1520,18 @@ epm_downgrade() ;; yum-rpm) # can do update repobase automagically - sudocmd yum downgrade $pkg_filenames + if [ -n "$pkg_filenames" ] ; then + sudocmd yum downgrade $pkg_filenames + else + sudocmd yum distro-sync + fi ;; dnf-rpm) - sudocmd dnf downgrade $pkg_filenames + if [ -n "$pkg_filenames" ] ; then + sudocmd dnf downgrade $pkg_filenames + else + sudocmd dnf distro-sync + fi ;; urpm-rpm) assure_exists urpm-reposync urpm-tools @@ -1446,10 +1545,121 @@ epm_downgrade() # File bin/epm-download: +__use_url_install() +{ + case $DISTRNAME in + "ALTLinux") + # not for https + echo "$pkg_urls" | grep -q "https://" && return 1 + pkg_names="$pkg_names $pkg_urls" + return 0 + ;; + esac + + case $PMTYPE in + #apt-rpm) + # pkg_names="$pkg_names $pkg_urls" + # ;; + #deepsolver-rpm) + # pkg_names="$pkg_names $pkg_urls" + # ;; + #urpm-rpm) + # pkg_names="$pkg_names $pkg_urls" + # ;; + pacman) + pkg_names="$pkg_names $pkg_urls" + ;; + yum-rpm|dnf-rpm) + pkg_names="$pkg_names $pkg_urls" + ;; + #zypper-rpm) + # pkg_names="$pkg_names $pkg_urls" + # ;; + *) + return 1 + ;; + esac + return 0 +} + +__download_pkg_urls() +{ + local url + [ -z "$pkg_urls" ] && return + for url in $pkg_urls ; do + # TODO: use some individual tmp dir + local new_file=/tmp/$(basename "$url") + if docmd eget -O $new_file $url && [ -s "$new_file" ] ; then + pkg_files="$pkg_files $new_file" + to_remove_pkg_files="$to_remove_pkg_files $new_file" + else + warning "Failed to download $url, ignoring" + fi + done + # restore + pkg_filenames=$(strip_spaces "$pkg_files $pkg_names") +} + +__handle_pkg_urls_to_install() +{ + #[ -n "$pkg_urls" ] || return + + # TODO: do it correctly + to_remove_pkg_files= + # FIXME: check type of pkg_urls separately? + if [ "$(get_package_type "$pkg_urls")" != $PKGFORMAT ] || ! __use_url_install ; then + # use workaround with eget: download and put in pkg_files + __download_pkg_urls + fi + + pkg_urls= +} + +__handle_pkg_urls_to_checking() +{ + #[ -n "$pkg_urls" ] || return + + # TODO: do it correctly + to_remove_pkg_files= + + # use workaround with eget: download and put in pkg_files + __download_pkg_urls + + pkg_urls= +} + + +__epm_get_altpkg_url() +{ + info "TODO: https://packages.altlinux.org/api/branches" + local arch=$(paoapi packages/$1 | get_pao_var arch) + # FIXME: arch can be list + [ "$arch" = "noarch" ] || arch=$(arch) + # HACK: filename can be list + local filename=$(paoapi packages/$1 | get_pao_var filename | grep $arch) + [ -n "$filename" ] || fatal "Can't get filename" + # fixme: get from /branches + local dv=$DISTRNAME/$DISTRVERSION/branch + [ "$DISTRVERSION" = "Sisyphus" ] && dv=$DISTRNAME/$DISTRVERSION + echo "http://ftp.basealt.ru/pub/distributions/$dv/$arch/RPMS.classic/$filename" +} + epm_download() { local CMD + case $DISTRNAME in + ALTLinux) + local pkg + for pkg in $pkg_filenames ; do + local url=$(__epm_get_altpkg_url $pkg) + [ -n "$url" ] || warning "Can't get url for $pkg" + docmd eget $url + done + return + ;; + esac + case $PMTYPE in dnf-rpm) sudocmd dnf download $pkg_filenames @@ -1465,6 +1675,9 @@ epm_download() dnf-rpm) sudocmd dnf download $pkg_filenames ;; + urpm-rpm) + sudocmd urpmi --no-install $URPMOPTIONS $@ + ;; tce) sudocmd tce-load -w $pkg_filenames ;; @@ -1503,7 +1716,7 @@ __alt_local_content_filelist() { [ -n "$USETTY" ] && info "Search in $CI for $1..." - grep -h -- ".*$1$" $CI | sed -e "s|\(.*\)\t\(.*\)|\1|g" + __local_ercat $CI | grep -h -- ".*$1$" | sed -e "s|\(.*\)\t\(.*\)|\1|g" } | $OUTCMD } @@ -1530,7 +1743,7 @@ __epm_filelist_remote() docmd_foreach __deb_local_content_filelist $@ ;; *) - fatal "Query filelist for non installed packages does not realized" + fatal "Query filelist for non installed packages is not implemented yet." ;; esac } @@ -1600,7 +1813,7 @@ __epm_filelist_name() return ;; slackpkg) - is_installed $@ || fatal "Query filelist for non installed packages does not realized" + is_installed $@ || fatal "Query filelist for non installed packages is not implemented yet" docmd awk 'BEGIN{desk=1}{if(/^FILE LIST:$/){desk=0} else if (desk==0) {print}}' /var/log/packages/${pkg_filenames}* | less return ;; @@ -1641,6 +1854,10 @@ __epm_info_rpm_low() epm_info() { +if [ -n "$pkg_urls" ] ; then + __handle_pkg_urls_to_checking +fi + [ -n "$pkg_filenames" ] || fatal "Info: missing package(s) name" case $PMTYPE in @@ -1725,6 +1942,11 @@ case $PMTYPE in ;; esac +local RETVAL=$? + +[ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files + +return $RETVAL } # File bin/epm-install: @@ -2013,7 +2235,6 @@ __epm_check_if_try_install_rpm() cd $TDIR for pkg in $rpmpkgs ; do showcmd_store_output fakeroot alien -d -k --scripts "$pkg" - clean_store_output local DEBCONVERTED=$(grep "deb generated" $RC_STDOUT | sed -e "s| generated||g") clean_store_output epm install $DEBCONVERTED @@ -2024,6 +2245,22 @@ __epm_check_if_try_install_rpm() return 0 } +__handle_direct_install() +{ + case "$DISTRNAME" in + "ALTLinux") + 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 +} epm_install_files() { @@ -2206,64 +2443,6 @@ epm_print_install_command() esac } -download_pkg_urls() -{ - local url - [ -z "$pkg_urls" ] && return - for url in $pkg_urls ; do - # TODO: use some individual tmp dir - local new_file=/tmp/$(basename "$url") - if eget -O $new_file $url && [ -s "$new_file" ] ; then - pkg_files="$pkg_files $new_file" - to_remove_pkg_files="$to_remove_pkg_files $new_file" - else - warning "Failed to download $url, ignoring" - fi - done -} - -__use_url_install() -{ - case $PMTYPE in - apt-rpm) - # ALT Linux really? - pkg_names="$pkg_names $pkg_urls" - ;; - #deepsolver-rpm) - # pkg_names="$pkg_names $pkg_urls" - # ;; - #urpm-rpm) - # pkg_names="$pkg_names $pkg_urls" - # ;; - pacman) - pkg_names="$pkg_names $pkg_urls" - ;; - yum-rpm|dnf-rpm) - pkg_names="$pkg_names $pkg_urls" - ;; - #zypper-rpm) - # pkg_names="$pkg_names $pkg_urls" - # ;; - *) - return 1 - ;; - esac - return 0 -} - -__handle_pkg_urls() -{ - [ -n "$pkg_urls" ] || return - - # TODO: do it correctly - to_remove_pkg_files= - - if [ "$(get_package_type "$pkg")" != $PKGFORMAT ] || ! __use_url_install ; then - # use workaround with eget: download and put in pkg_files - download_pkg_urls - fi - pkg_urls= -} epm_install() { @@ -2272,8 +2451,14 @@ epm_install() return fi - # in any case it will put pkg_urls into pkg_files or pkg_names - __handle_pkg_urls + if [ -n "$direct" ] ; then + __handle_direct_install + fi + + # if possible, it will put pkg_urls into pkg_files or pkg_names + if [ -n "$pkg_urls" ] ; then + __handle_pkg_urls_to_install + fi [ -z "$pkg_files$pkg_names" ] && info "Skip empty install list" && return 22 @@ -2282,17 +2467,18 @@ epm_install() [ -z "$files$names" ] && info "Skip empty install list" && return 22 - if [ -z "$files" ] ; then + if [ -z "$files" ] && [ -z "$direct" ] ; then # it is useful for first time running update_repo_if_needed fi epm_install_names $names || return epm_install_files $files + local RETVAL=$? # TODO: reinvent - local RETVAL=$? [ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files + return $RETVAL } @@ -2465,7 +2651,7 @@ case $PMTYPE in docmd dpkg-query -W --showformat="\${Size}.\${Package}-\${Version}\n" $pkg_filenames | sort -n ;; *) - fatal "Sorted package list are not realized for $PMTYPE" + fatal "Sorted package list function is not implemented for $PMTYPE" ;; esac } @@ -2620,6 +2806,8 @@ epm_policy() [ -n "$pkg_names" ] || fatal "Info: missing package(s) name" +pkg_names=$(__epm_get_hilevel_name $pkg_names) + case $PMTYPE in apt-rpm) docmd apt-cache policy $pkg_names @@ -3023,11 +3211,11 @@ __epm_get_hilevel_nameform() echo $pkg return ;; - yum-rpm) + yum-rpm|dnf-rpm) # just use strict version with Epoch and Serial local pkg - pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}%{VERSION}-%{RELEASE}.${ARCH}\n" $1) - echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.${ARCH}\n" $1) + pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1) + echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1) echo $pkg return ;; @@ -3200,13 +3388,26 @@ epm_query() # File bin/epm-query_file: +__abs_filename() +{ + if echo "$1" | grep -q "/" ; then + echo "$1" + return + fi + if [ -e "$1" ] ; then + echo "$(pwd)/$1" + return + fi + echo "$1" +} + __do_query_real_file() { local TOFILE # get canonical path if [ -e "$1" ] ; then - TOFILE="$1" + TOFILE="$(__abs_filename "$1")" else TOFILE=$(which "$1" 2>/dev/null || echo "$1") if [ "$TOFILE" != "$1" ] ; then @@ -3285,7 +3486,7 @@ __do_query() ;; aptcyg) #CMD="apt-cyg packageof" - # do not realized locally + # is not implemented locally return 1 ;; *) @@ -3386,6 +3587,9 @@ epm_reinstall_names() aptitude-dpkg) sudocmd aptitude reinstall $@ return ;; + yum-rpm) + sudocmd yum reinstall $@ + return ;; dnf-rpm) sudocmd dnf reinstall $@ return ;; @@ -3535,7 +3739,7 @@ __update_to_the_distro() ;; Sisyphus) docmd epm update || fatal - docmd epm install apt rpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again" + docmd epm install apt rpm librpm7 librpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again" docmd epm upgrade || fatal "Check an error and run epm release-upgrade again" ;; *) @@ -3650,9 +3854,11 @@ epm_release_upgrade() assure_exists dnf-plugin-system-upgrade sudocmd dnf system-upgrade local RELEASEVER="$pkg_filenames" - [ -n "$RELEASEVER" ] || fatal "Run me with new version" + [ -n "$RELEASEVER" ] || RELEASEVER=$(($DISTRVERSION + 1)) + #[ -n "$RELEASEVER" ] || fatal "Run me with new version" + info "Upgrate to $DISTRNAME/$RELEASEVER" sudocmd dnf system-upgrade download --refresh --releasever=$RELEASEVER - sudocmd dnf system-upgrade + sudocmd dnf distro-sync --releasever=$RELEASEVER info "Run epm autoorphans to remove orphaned packages" ;; urpm-rpm) @@ -3972,11 +4178,24 @@ epm_remove_old_kernels() epm_removerepo() { local repo="$(eval echo $quoted_args)" -case $PMTYPE in - apt-rpm) + +case $DISTRNAME in + ALTLinux) + case "$repo" in + autoimports) + info "remove autoimports repo" + [ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION" + repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")" + ;; + esac + assure_exists apt-repo sudocmd apt-repo rm "$repo" + return ;; +esac; + +case $PMTYPE in apt-dpkg|aptitude-dpkg) info "You need remove repo from /etc/apt/sources.list" ;; @@ -4022,8 +4241,24 @@ __repofix_check_vendor() return 1 } +__try_fix_apt_source_list() +{ + local list="$1" + local br="$2" + local path="$3" + if grep -q -e "^[^#].*$path" $list ; then + if __repofix_check_vendor $br ; then + regexp_subst "/$path/s/^rpm[[:space:]]*([fhr])/rpm [$br] \1/" $list + else + warning "Skip set $br vendor key (it misssed) for $list" + regexp_subst "/$path/s/^rpm[[:space:]]*\[$br\][[:space:]]*([fhr])/rpm \1/" $list + fi + fi +} + __fix_apt_sources_list() { + # for beauty spaces local SUBST_ALT_RULE='s!^(.*)[/ ](ALTLinux|LINUX\@Etersoft)[/ ](Sisyphus|p8[/ ]branch|p7[/ ]branch|p6[/ ]branch)[/ ](x86_64|i586|x86_64-i586|noarch) !\1 \2/\3/\4 !gi' local i assure_root @@ -4035,33 +4270,14 @@ __fix_apt_sources_list() regexp_subst "/^ *#/! $SUBST_ALT_RULE" $i # Sisyphus uses 'alt' vendor key - if __repofix_check_vendor alt ; then - regexp_subst "/ALTLinux\/Sisyphus\//s/^rpm *([fhr])/rpm [alt] \1/" $i - else - warning "Skip set alt vendor key (it misssed)" - fi + __try_fix_apt_source_list $i alt "ALTLinux\/Sisyphus" # skip branch replacement for ALT Linux Sisyphus [ "$DISTRVERSION" = "Sisyphus" ] && continue # add signs for branches - local br - for br in $DISTRVERSION ; do - if ! __repofix_check_vendor $br ; then - warning "Skip set $br vendor key (it misssed)" - continue - fi - regexp_subst "/ALTLinux\/$br\/branch/s/^rpm *([fhr])/rpm [$br] \1/" $i - done - - for br in $DISTRVERSION ; do - #if is_installed apt-conf-etersoft-common ; then - if ! __repofix_check_vendor etersoft ; then - warning "Skip set etersoft vendor key (it misssed)" - continue - fi - regexp_subst "/Etersoft\/$br\/branch/s/^rpm *([fhr])/rpm [etersoft] \1/" $i - done + __try_fix_apt_source_list $i $DISTRVERSION "ALTLinux\/$DISTRVERSION\/branch" + __try_fix_apt_source_list $i etersoft "Etersoft\/$DISTRVERSION\/branch" done } @@ -4125,7 +4341,7 @@ case $PMTYPE in print_apt_sources_list /etc/apt/sources.list /etc/apt/sources.list.d/*.list ;; yum-rpm) - docmd yum repolist + docmd yum repolist -v ;; dnf-rpm) docmd dnf repolist -v @@ -4435,20 +4651,30 @@ epm_search() # File bin/epm-search_file: + +__alt_search_file_output() +{ + # grep only on left part (filename), then revert order and grep with color + __local_ercat $1 | grep -h -- ".*$2.*[[:space:]]" | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g" $3 +} + __alt_local_content_search() { + info "Locate contents index file(s) ..." local CI="$(get_local_alt_contents_index)" + # TODO use something like [ -n "$CI" ] || fatal "Have no local contents index" - #local OUTCMD="less" - #[ -n "$USETTY" ] || OUTCMD="cat" - OUTCMD="cat" - { - [ -n "$USETTY" ] && info "Search in $CI for $1..." - # note! tabulation below! - grep -h -- ".*$1.* " $CI | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g" - } | $OUTCMD + info "Searching in" + echo "$CI" + echo "for $1... " + + # FIXME: do it better + local MGS + MGS=$(eval __epm_search_make_grep $quoted_args) + showcmd "$ cat contents_index $MGS" + eval "__alt_search_file_output \"$CI\" \"$(eval get_firstarg $quoted_args)\" $MGS" } epm_search_file() @@ -4467,12 +4693,12 @@ case $PMTYPE in return ;; yum-rpm) # TODO - info "Search by full packages list does not realized" + info "Search by full packages list is not implemented yet" CMD="yum provides" ;; dnf-rpm) # TODO - info "Search by full packages list does not realized" + info "Search by full packages list is not implemented yet" CMD="dnf provides" ;; urpm-rpm) @@ -4508,18 +4734,90 @@ docmd $CMD $pkg_filenames # File bin/epm-sh-altlinux: + +get_local_alt_mirror_path() +{ + local DN1=$(dirname "$1") + local DN2=$(dirname $DN1) + local DN3=$(dirname $DN2) + + local BN0=$(basename "$1") # arch + local BN1=$(basename $DN1) # branch/Sisyphus + local BN2=$(basename $DN2) # p8/ALTLinux + local BN3=$(basename $DN3) # ALTLinux/ + + [ "$BN1" = "branch" ] && echo "/tmp/eepm/$BN3/$BN2/$BN1/$BN0" || echo "/tmp/eepm/$BN2/$BN1/$BN0" +} + +__local_ercat() +{ + local i + for i in $* ; do + case "$i" in + *.xz) + a= xzcat $i + ;; + *.lz4) + a= lz4cat $i + ;; + *.failed) + # just ignore + ;; + *) + cat $i + ;; + esac + done +} + +compress_file_inplace() +{ + local OFILE="$1" + if epm assure lz4 </dev/null ; then + docmd lz4 --rm "$OFILE" "$OFILE.lz4" || return + else + epm assure xz </dev/null || return + docmd xz "$OFILE" || return + fi + return 0 +} + +download_alt_contents_index() +{ + local URL="$1" + local TD="$2" + local OFILE="$TD/$(basename "$URL")" + + local DONE=$(echo $OFILE*) + # TODO: check if too old + if [ -r "$DONE" ] ; then + return + fi + + mkdir -p "$TD" + + if echo "$URL" | grep -q "^file:/" ; then + URL=$(echo "$URL" | sed -e "s|^file:||") + [ -s "$URL" ] || { touch $OFILE.failed ; return 1; } + ln -s "$URL" "$OFILE" || { touch $OFILE.failed ; return 1; } + else + docmd eget -O "$OFILE" "$URL" || { rm -fv $OFILE ; touch $OFILE.failed ; return 1; } + fi + + compress_file_inplace "$OFILE" +} + get_local_alt_contents_index() { - epm_repolist | grep "rpm.*file:/" | sed -e "s|^rpm.*file:||g" | while read URL ARCH other ; do - test -d "$URL/$ARCH" || continue # fatal "Local mirror is not accessible via $URL/$ARCH" - FILE="$URL/$ARCH/base/contents_index" - if [ -r "$FILE" ] ; then - echo "$FILE" - else - info "TODO for girar server: There is no $(basename $FILE) file in $(dirname $FILE)" - fi + local LOCALPATH + + epm_repolist | grep -E "rpm.*(ftp://|http://|https://|file:/)" | sed -e "s@^rpm.*\(ftp://\|http://\|https://\|file:\)@\1@g" | while read URL ARCH other ; do + LOCALPATH=$(get_local_alt_mirror_path "$URL/$ARCH") + download_alt_contents_index $URL/$ARCH/base/contents_index $LOCALPATH || continue + echo "$LOCALPATH/contents_index*" done + } # File bin/epm-simulate: @@ -4660,6 +4958,23 @@ epm_simulate() PAOURL="https://packages.altlinux.org" +paoapi() +{ + # http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs + epm assure curl || return 1 + showcmd curl "$PAOURL/api/$1" + a= curl -s --header "Accept: application/json" "$PAOURL/api/$1" +} + +get_pao_var() +{ + local FIELD="$1" + #grep '"$FIELD"' | sed -e 's|.*"$FIELD":"||g' | sed -e 's|".*||g' + internal_tools_json -b | egrep "\[.*\"$FIELD\"\]" | sed -e 's|.*[[:space:]]"\(.*\)"|\1|g' + return 0 +} + + run_command_if_exists() { local CMD="$1" @@ -4681,14 +4996,9 @@ open_browser() __query_package_hl_url() { - local PAOAPI="$PAOURL/api" case $DISTRNAME in ALTLinux) - # http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs - epm assure curl || return 1 - showcmd curl "$PAOAPI/srpms/$1" - a= curl -s --header "Accept: application/json" "$PAOAPI/srpms/$1" | grep '"url"' | sed -e 's|.*"url":"||g' | sed -e 's|".*||g' - return 0 + paoapi srpms/$1 | get_pao_var url ;; esac return 1 @@ -4857,7 +5167,7 @@ epm_upgrade() { local CMD - [ -z "$pkg_filenames" ] || fatal "No arguments are allowed here" + #[ -z "$pkg_filenames" ] || fatal "No arguments are allowed here" # it is useful for first time running update_repo_if_needed @@ -4876,18 +5186,18 @@ epm_upgrade() yum-rpm) local OPTIONS="$(subst_option non_interactive -y)" # can do update repobase automagically - CMD="yum $OPTIONS update" + CMD="yum $OPTIONS update $pkg_filenames" ;; dnf-rpm) local OPTIONS="$(subst_option non_interactive -y)" - CMD="dnf $OPTIONS distro-sync" + CMD="dnf $OPTIONS distro-sync $pkg_filenames" ;; snappy) CMD="snappy update" ;; urpm-rpm) # or --auto-select --replace-files - CMD="urpmi --update --auto-select" + CMD="urpmi --update --auto-select $pkg_filenames" ;; zypper-rpm) CMD="zypper dist-upgrade" @@ -4961,6 +5271,7 @@ epm_Upgrade() # File bin/epm-whatdepends: + epm_whatdepends() { local CMD @@ -4985,6 +5296,7 @@ case $PMTYPE in CMD="urpmq --whatrequires" ;; dnf-rpm) + # check command: dnf repoquery --whatrequires CMD="repoquery --whatrequires" ;; emerge) @@ -5112,7 +5424,7 @@ pkgtype() debian|ubuntu|mint|runtu|mcst|astra) echo "deb" ;; alt|asplinux|suse|mandriva|rosa|mandrake|pclinux|sled|sles) echo "rpm" ;; - fedora|redhat|scientific|centos|rhel) + fedora|redhat|scientific|centos|rhel|goslinux) echo "rpm" ;; *) echo "rpm" ;; esac @@ -5120,8 +5432,8 @@ pkgtype() get_var() { - grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" - + # get first variable and print it out, drop quotes if exists + grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" | sed -e "s/^[\'\"]\(.*\)[\'\"]/\1/" } # 2010.1 -> 2010 @@ -5148,6 +5460,7 @@ if distro altlinux-release ; then if has Sisyphus ; then DISTRIB_RELEASE="Sisyphus" elif has "ALT Linux 7." ; then DISTRIB_RELEASE="p7" elif has "ALT Linux 8." ; then DISTRIB_RELEASE="p8" + elif has "ALT .*8.[0-9]" ; then DISTRIB_RELEASE="p8" elif has "Simply Linux 6." ; then DISTRIB_RELEASE="p6" elif has "Simply Linux 7." ; then DISTRIB_RELEASE="p7" elif has "Simply Linux 8." ; then DISTRIB_RELEASE="p8" @@ -5292,6 +5605,8 @@ elif distro redhat-release ; then DISTRIB_ID="CentOS" elif has Scientific ; then DISTRIB_ID="Scientific" + elif has GosLinux ; then + DISTRIB_ID="GosLinux" fi if has Beryllium ; then DISTRIB_ID="Scientific" @@ -5349,7 +5664,13 @@ elif [ `uname -o 2>/dev/null` = "Cygwin" ] ; then # try use standart LSB info by default elif distro lsb-release && [ -n "$DISTRIB_RELEASE" ]; then # use LSB - true + + # fix distro name + case "$DISTRIB_ID" in + "openSUSE Tumbleweed") + DISTRIB_ID="Tumbleweed" + ;; + esac fi case $1 in @@ -5391,7 +5712,7 @@ case $1 in exit 0 ;; -V) - echo "20160822" + echo "20161212" exit 0 ;; *) @@ -5447,7 +5768,7 @@ fi # If ftp protocol or have no asterisk, just download # TODO: use has() -if echo "$1" | grep -q "\(^ftp://\|[^*]$\)" ; then +if echo "$1" | grep -q "\(^ftp://\|[^*]\)" ; then $WGET $WGET_OPTION_TARGET "$1" return fi @@ -5495,6 +5816,220 @@ download_files || echo "There was some download errors" >&2 rm -rf "$MYTMPDIR" } +internal_tools_json() +{ + +# License: MIT or Apache +# Homepage: http://github.com/dominictarr/JSON.sh + +throw() { + echo "$*" >&2 + exit 1 +} + +BRIEF=0 +LEAFONLY=0 +PRUNE=0 +NO_HEAD=0 +NORMALIZE_SOLIDUS=0 + +usage() { + echo + echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]" + echo + echo "-p - Prune empty. Exclude fields with empty values." + echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." + echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." + echo "-n - No-head. Do not show nodes that have no path (lines that start with [])." + echo "-s - Remove escaping of the solidus symbol (straight slash)." + echo "-h - This help text." + echo +} + +parse_options() { + set -- "$@" + local ARGN=$# + while [ "$ARGN" -ne 0 ] + do + case $1 in + -h) usage + exit 0 + ;; + -b) BRIEF=1 + LEAFONLY=1 + PRUNE=1 + ;; + -l) LEAFONLY=1 + ;; + -p) PRUNE=1 + ;; + -n) NO_HEAD=1 + ;; + -s) NORMALIZE_SOLIDUS=1 + ;; + ?*) echo "ERROR: Unknown option." + usage + exit 0 + ;; + esac + shift 1 + ARGN=$((ARGN-1)) + done +} + +awk_egrep () { + local pattern_string=$1 + + gawk '{ + while ($0) { + start=match($0, pattern); + token=substr($0, start, RLENGTH); + print token; + $0=substr($0, start+RLENGTH); + } + }' pattern="$pattern_string" +} + +tokenize () { + local GREP + local ESCAPE + local CHAR + + if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 + then + GREP='egrep -ao --color=never' + else + GREP='egrep -ao' + fi + + if echo "test string" | egrep -o "test" >/dev/null 2>&1 + then + ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\]' + else + GREP=awk_egrep + ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\\\]' + fi + + local STRING="\"$CHAR*($ESCAPE$CHAR*)*\"" + local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?' + local KEYWORD='null|false|true' + local SPACE='[[:space:]]+' + + # Force zsh to expand $A into multiple words + local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') + if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi + $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" + if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi +} + +parse_array () { + local index=0 + local ary='' + read -r token + case "$token" in + ']') ;; + *) + while : + do + parse_value "$1" "$index" + index=$((index+1)) + ary="$ary""$value" + read -r token + case "$token" in + ']') break ;; + ',') ary="$ary," ;; + *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value= + : +} + +parse_object () { + local key + local obj='' + read -r token + case "$token" in + '}') ;; + *) + while : + do + case "$token" in + '"'*'"') key=$token ;; + *) throw "EXPECTED string GOT ${token:-EOF}" ;; + esac + read -r token + case "$token" in + ':') ;; + *) throw "EXPECTED : GOT ${token:-EOF}" ;; + esac + read -r token + parse_value "$1" "$key" + obj="$obj$key:$value" + read -r token + case "$token" in + '}') break ;; + ',') obj="$obj," ;; + *) throw "EXPECTED , or } GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value= + : +} + +parse_value () { + local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 + case "$token" in + '{') parse_object "$jpath" ;; + '[') parse_array "$jpath" ;; + # At this point, the only valid single-character tokens are digits. + ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; + *) value=$token + # if asked, replace solidus ("\/") in json strings with normalized value: "/" + [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g') + isleaf=1 + [ "$value" = '""' ] && isempty=1 + ;; + esac + [ "$value" = '' ] && return + [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return + + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ + [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 + [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" + : +} + +parse () { + read -r token + parse_value + read -r token + case "$token" in + '') ;; + *) throw "EXPECTED EOF GOT $token" ;; + esac +} + +if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); +then + parse_options "$@" + tokenize | parse +fi + +# vi: expandtab sw=2 ts=2 +} + #PATH=$PATH:/sbin:/usr/sbin set_pm_type @@ -5519,9 +6054,9 @@ $(get_help HELPOPT) print_version() { - echo "EPM package manager version 1.9.6" + echo "EPM package manager version 2.0.5" echo "Running on $($DISTRVENDOR) ('$PMTYPE' package manager uses '$PKGFORMAT' package format)" - echo "Copyright (c) Etersoft 2012-2016" + echo "Copyright (c) Etersoft 2012-2017" echo "This program may be freely redistributed under the terms of the GNU AGPLv3." } @@ -5536,6 +6071,7 @@ nodeps= noremove= force= short= +direct= sort= non_interactive= skip_installed= @@ -5791,6 +6327,9 @@ check_option() --short) # HELPOPT: short output (just 'package' instead 'package-version-release') short="--short" ;; + --direct) # HELPOPT: direct install package file from ftp (not via hilevel repository manager) + direct="--direct" + ;; --sort) # HELPOPT: sort output, f.i. --sort=size (supported only for packages command) # TODO: how to read arg? sort="$1" @@ -5858,7 +6397,9 @@ pkg_filenames=$(strip_spaces "$pkg_files $pkg_names") if [ -z "$epm_cmd" ] ; then print_version echo - fatal "Unknown command $@. Run $ $PROGNAME --help for get help" + fatstr="Unknown command in $@ arg(s)" + [ -n "$*" ] || fatstr="That program needs be running with some command" + fatal "$fatstr. Run $ $PROGNAME --help to get help." fi # Use eatmydata for write specific operations diff --git a/packed/serv.sh b/packed/serv.sh index f0f4d963ab9a1624cacfe9f524ba1216d0bb3639..e03901b34831b941f287c325de312677a311b6ab 100755 --- a/packed/serv.sh +++ b/packed/serv.sh @@ -159,6 +159,13 @@ sudocmd_foreach() done } +if ! which realpath 2>/dev/null >/dev/null ; then +realpath() +{ + readlink -f "$@" +} +fi + get_firstarg() { echon "$1" @@ -444,14 +451,14 @@ case $DISTRNAME in ArchLinux) CMD="pacman" ;; - Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific) + Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux) CMD="yum-rpm" which dnf 2>/dev/null >/dev/null && test -d /var/lib/dnf/yumdb && CMD=dnf-rpm ;; Slackware) CMD="slackpkg" ;; - SUSE|SLED|SLES) + SUSE|SLED|SLES|Tumbleweed) CMD="zypper-rpm" ;; ForesightLinux|rPathLinux) @@ -500,8 +507,9 @@ is_active_systemd() [ -x "$SYSTEMCTL" ] || return [ -d "$SYSTEMD_CGROUP_DIR" ] || return a= mountpoint -q "$SYSTEMD_CGROUP_DIR" || return + readlink /sbin/init | grep -q 'systemd' || return # some hack - ps ax | grep -q '[s]ystemd' >/dev/null + ps ax | grep '[s]ystemd' | grep -q -v 'systemd-udev' } # File bin/serv-common: @@ -1056,7 +1064,7 @@ pkgtype() debian|ubuntu|mint|runtu|mcst|astra) echo "deb" ;; alt|asplinux|suse|mandriva|rosa|mandrake|pclinux|sled|sles) echo "rpm" ;; - fedora|redhat|scientific|centos|rhel) + fedora|redhat|scientific|centos|rhel|goslinux) echo "rpm" ;; *) echo "rpm" ;; esac @@ -1064,8 +1072,8 @@ pkgtype() get_var() { - grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" - + # get first variable and print it out, drop quotes if exists + grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" | sed -e "s/^[\'\"]\(.*\)[\'\"]/\1/" } # 2010.1 -> 2010 @@ -1092,6 +1100,7 @@ if distro altlinux-release ; then if has Sisyphus ; then DISTRIB_RELEASE="Sisyphus" elif has "ALT Linux 7." ; then DISTRIB_RELEASE="p7" elif has "ALT Linux 8." ; then DISTRIB_RELEASE="p8" + elif has "ALT .*8.[0-9]" ; then DISTRIB_RELEASE="p8" elif has "Simply Linux 6." ; then DISTRIB_RELEASE="p6" elif has "Simply Linux 7." ; then DISTRIB_RELEASE="p7" elif has "Simply Linux 8." ; then DISTRIB_RELEASE="p8" @@ -1236,6 +1245,8 @@ elif distro redhat-release ; then DISTRIB_ID="CentOS" elif has Scientific ; then DISTRIB_ID="Scientific" + elif has GosLinux ; then + DISTRIB_ID="GosLinux" fi if has Beryllium ; then DISTRIB_ID="Scientific" @@ -1293,7 +1304,13 @@ elif [ `uname -o 2>/dev/null` = "Cygwin" ] ; then # try use standart LSB info by default elif distro lsb-release && [ -n "$DISTRIB_RELEASE" ]; then # use LSB - true + + # fix distro name + case "$DISTRIB_ID" in + "openSUSE Tumbleweed") + DISTRIB_ID="Tumbleweed" + ;; + esac fi case $1 in @@ -1335,7 +1352,7 @@ case $1 in exit 0 ;; -V) - echo "20160822" + echo "20161212" exit 0 ;; *) @@ -1391,7 +1408,7 @@ fi # If ftp protocol or have no asterisk, just download # TODO: use has() -if echo "$1" | grep -q "\(^ftp://\|[^*]$\)" ; then +if echo "$1" | grep -q "\(^ftp://\|[^*]\)" ; then $WGET $WGET_OPTION_TARGET "$1" return fi @@ -1439,6 +1456,220 @@ download_files || echo "There was some download errors" >&2 rm -rf "$MYTMPDIR" } +internal_tools_json() +{ + +# License: MIT or Apache +# Homepage: http://github.com/dominictarr/JSON.sh + +throw() { + echo "$*" >&2 + exit 1 +} + +BRIEF=0 +LEAFONLY=0 +PRUNE=0 +NO_HEAD=0 +NORMALIZE_SOLIDUS=0 + +usage() { + echo + echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]" + echo + echo "-p - Prune empty. Exclude fields with empty values." + echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." + echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." + echo "-n - No-head. Do not show nodes that have no path (lines that start with [])." + echo "-s - Remove escaping of the solidus symbol (straight slash)." + echo "-h - This help text." + echo +} + +parse_options() { + set -- "$@" + local ARGN=$# + while [ "$ARGN" -ne 0 ] + do + case $1 in + -h) usage + exit 0 + ;; + -b) BRIEF=1 + LEAFONLY=1 + PRUNE=1 + ;; + -l) LEAFONLY=1 + ;; + -p) PRUNE=1 + ;; + -n) NO_HEAD=1 + ;; + -s) NORMALIZE_SOLIDUS=1 + ;; + ?*) echo "ERROR: Unknown option." + usage + exit 0 + ;; + esac + shift 1 + ARGN=$((ARGN-1)) + done +} + +awk_egrep () { + local pattern_string=$1 + + gawk '{ + while ($0) { + start=match($0, pattern); + token=substr($0, start, RLENGTH); + print token; + $0=substr($0, start+RLENGTH); + } + }' pattern="$pattern_string" +} + +tokenize () { + local GREP + local ESCAPE + local CHAR + + if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1 + then + GREP='egrep -ao --color=never' + else + GREP='egrep -ao' + fi + + if echo "test string" | egrep -o "test" >/dev/null 2>&1 + then + ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\]' + else + GREP=awk_egrep + ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' + CHAR='[^[:cntrl:]"\\\\]' + fi + + local STRING="\"$CHAR*($ESCAPE$CHAR*)*\"" + local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?' + local KEYWORD='null|false|true' + local SPACE='[[:space:]]+' + + # Force zsh to expand $A into multiple words + local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$') + if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi + $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" + if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi +} + +parse_array () { + local index=0 + local ary='' + read -r token + case "$token" in + ']') ;; + *) + while : + do + parse_value "$1" "$index" + index=$((index+1)) + ary="$ary""$value" + read -r token + case "$token" in + ']') break ;; + ',') ary="$ary," ;; + *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value= + : +} + +parse_object () { + local key + local obj='' + read -r token + case "$token" in + '}') ;; + *) + while : + do + case "$token" in + '"'*'"') key=$token ;; + *) throw "EXPECTED string GOT ${token:-EOF}" ;; + esac + read -r token + case "$token" in + ':') ;; + *) throw "EXPECTED : GOT ${token:-EOF}" ;; + esac + read -r token + parse_value "$1" "$key" + obj="$obj$key:$value" + read -r token + case "$token" in + '}') break ;; + ',') obj="$obj," ;; + *) throw "EXPECTED , or } GOT ${token:-EOF}" ;; + esac + read -r token + done + ;; + esac + [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value= + : +} + +parse_value () { + local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 + case "$token" in + '{') parse_object "$jpath" ;; + '[') parse_array "$jpath" ;; + # At this point, the only valid single-character tokens are digits. + ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; + *) value=$token + # if asked, replace solidus ("\/") in json strings with normalized value: "/" + [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g') + isleaf=1 + [ "$value" = '""' ] && isempty=1 + ;; + esac + [ "$value" = '' ] && return + [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return + + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 + [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ + [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 + [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" + : +} + +parse () { + read -r token + parse_value + read -r token + case "$token" in + '') ;; + *) throw "EXPECTED EOF GOT $token" ;; + esac +} + +if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); +then + parse_options "$@" + tokenize | parse +fi + +# vi: expandtab sw=2 ts=2 +} + INITDIR=/etc/init.d PATH=$PATH:/sbin:/usr/sbin @@ -1465,7 +1696,7 @@ case $DISTRNAME in ALTLinux) CMD="service-chkconfig" ;; - Ubuntu|Debian|Mint) + Ubuntu|Debian|Mint|AstraLinux) CMD="service-update" ;; Mandriva|ROSA) @@ -1480,7 +1711,7 @@ case $DISTRNAME in # ArchLinux) # CMD="pacman" # ;; - Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific) + Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux) CMD="service-chkconfig" ;; VoidLinux) @@ -1489,7 +1720,7 @@ case $DISTRNAME in Slackware) CMD="service-initd" ;; - SUSE|SLED|SLES) + SUSE|SLED|SLES|Tumbleweed) CMD="service-chkconfig" ;; # Windows) @@ -1536,7 +1767,7 @@ $(get_help HELPOPT) print_version() { - echo "Service manager version 1.9.6" + echo "Service manager version 2.0.5" echo "Running on $($DISTRVENDOR) with $SERVICETYPE" echo "Copyright (c) Etersoft 2012, 2013, 2016" echo "This program may be freely redistributed under the terms of the GNU AGPLv3." diff --git a/tests/etc/lsb-release b/tests/etc/lsb-release new file mode 100644 index 0000000000000000000000000000000000000000..64d8b14880e362f8c5c6f39f41af9ee0a2508d06 --- /dev/null +++ b/tests/etc/lsb-release @@ -0,0 +1,5 @@ +LSB_VERSION="core-2.0-noarch:core-3.2-noarch:core-4.0-noarch:core-2.0-x86_64:core-3.2-x86_64:core-4.0-x86_64" +DISTRIB_ID="openSUSE Tumbleweed" +DISTRIB_RELEASE="20161014" +DISTRIB_CODENAME="" +DISTRIB_DESCRIPTION="openSUSE Tumbleweed"