-
-
Save awerlang/b792a3f908206a90ad58ba559c5400bb to your computer and use it in GitHub Desktop.
zypper-download | |
=============== | |
Downloads packages using any amount of available openSUSE mirrors. | |
Installation | |
------------ | |
Copy both files to the following locations: | |
$HOME/.config/aria2/aria2.conf | |
$HOME/bin/zypper-download | |
Make sure the program is executable: | |
chmod +x $HOME/bin/zypper-download | |
This tool leverages aria2 to be awesome, so make sure it is installed (use zypper one last time): | |
zypper in aria2 | |
Usage | |
----- | |
It works best with repositories set to an official download redirector e.g. http://download.opensuse.org, since it relies on generated metalinks. So update your repositories URLs as needed. | |
Refer to instructions: | |
$ zypper-download -h | |
Known issues | |
------------ | |
* Only supports HTTP/HTTPS/FTP protocols for repositories | |
* Cannot be passed an individual .rpm URL directly (use aria2c instead) | |
* Minor: Some third-party repositories (e.g. Visual Studio Code) follow a different directory structure which results in those packages being skipped |
check-integrity=true | |
console-log-level=error | |
file-allocation=falloc | |
max-concurrent-downloads=40 |
#!/bin/bash | |
##################################################################################################### | |
## | |
### NAME | |
## zypper-download - Downloads packages using any amount of available openSUSE mirrors. | |
## | |
### SYNOPSIS | |
## Usage: zypper-download [options] command [command-args]... | |
## | |
## Options: | |
## | |
## -d <dir> Package cache directory. It can be an absolute path or relative to the | |
## current directory, or start with the environment variable ${HOME}. | |
## Default: $PKG_CACHE_DIR | |
## -z Run zypper once packages are ready in cache. | |
## -c Display default configuration. | |
## -h Display this message and exit. | |
## -v Display version information and exit. | |
## | |
## Commands: | |
## | |
## dup, dist-upgrade | |
## in, install package-name... | |
## inr, install-new-recommends | |
## | |
### CONFIGURATION | |
## PKG_CACHE_DIR = ${HOME}/.cache/zypp/packages | |
## RUN_ZYPPER = no | |
## | |
### LICENSE | |
## zypper-download v0.3.3 | |
## | |
## Copyright (C) 2020-2022 André Werlang | |
## | |
## License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. | |
## This is free software: you are free to change and redistribute it. | |
## There is NO WARRANTY, to the extent permitted by law. | |
## | |
##################################################################################################### | |
set -o errexit -o nounset -o noclobber -o pipefail | |
shopt -s nullglob | |
export LC_ALL=C | |
main() { | |
parse_opts "$@" | |
set_default_config | |
run | |
} | |
error() { | |
echo "$0: $*" | |
} 1>&2 | |
parse_opts() { | |
local OPTIND OPTARG flag | |
while getopts hvczd: flag | |
do | |
case "$flag" in | |
(h) help; exit 0;; | |
(v) version; exit 0;; | |
(c) configuration | about; exit 0;; | |
(d) readonly PKG_CACHE_DIR="$OPTARG";; | |
(z) readonly RUN_ZYPPER="yes";; | |
(*) usage; exit 1;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
if [ $# -eq 0 ]; then | |
error "expected required argument -- command" | |
usage; | |
exit 1; | |
fi | |
readonly SUB_COMMAND=("$@") | |
} | |
read_default_config() { | |
configuration | awk '/[[:alnum:]_ *= *.*]/{ print "[[ -v " $1 " ]] || readonly " $1 $2 "\x27" $3 "\x27" }' | |
} | |
set_default_config() { | |
local vars | |
vars=$(read_default_config) | |
eval "$vars" | |
} | |
subst_vars() { | |
export PKG_CACHE_DIR | |
envsubst '$HOME $PKG_CACHE_DIR' | |
} | |
about() { | |
set_default_config | |
subst_vars | |
} | |
usage() { | |
sed '/^### SYNOPSIS$/,/^###/!d;//d;s/^## \{0,6\}//' "$0" | about | |
} | |
version() { | |
sed '/^### LICENSE$/,/^###/!d;//d;s/^## \{0,6\}//' "$0" | about | |
} | |
help() { | |
sed '/^##$/,/^####/!d;//d;s/^##.\{0,2\}//' "$0" | about | |
} | |
configuration() { | |
sed '/^### CONFIGURATION$/,/^###/!d;//d;s/^## \{0,6\}//' "$0" | |
} | |
package_dir() { | |
echo "$PKG_CACHE_DIR" | subst_vars | |
} | |
run() { | |
call_zypper "${SUB_COMMAND[@]}" \ | |
| create_download_spec \ | |
| tee ./zypper-download.log \ | |
| download_all | |
check_rpm || { error "Package signature failed"; exit 1; } | |
if [[ "$RUN_ZYPPER" == yes ]]; then | |
local dir | |
dir=$(package_dir) | |
sudo zypper --pkg-cache-dir "$dir" "${SUB_COMMAND[@]}" | |
fi | |
} | |
call_zypper() { | |
local command="$1" | |
local command_args=("${@:2}") | |
sudo zypper --quiet \ | |
--terse \ | |
--non-interactive \ | |
"$command" --details \ | |
--dry-run \ | |
"${command_args[@]}" | |
} | |
create_download_spec() { | |
local repo_arrays | |
repo_arrays=$(zypper repos --uri | awk -F "|" ' | |
function trim(s) { | |
gsub(/^ +| +$/, "", s); | |
return s; | |
} | |
BEGIN { | |
print "BEGIN {"; | |
} | |
/:\/\// { | |
alias=trim($2); | |
name=trim($3); | |
uri=trim($NF); | |
print " uri[\"" name "\"]=\"" uri "\";"; | |
print " alias[\"" name "\"]=\"" alias "\";"; | |
} | |
END { | |
print "}"; | |
} | |
' | |
) | |
awk -v PKG_CACHE_DIR="$PKG_CACHE_DIR" "$repo_arrays"' | |
function trim(s) { | |
gsub(/^ +| +$/, "", s); | |
return s; | |
} | |
NF==0 { | |
pkg=0; | |
next; | |
} | |
/ packages? (is|are) going to (be installed|be reinstalled|be upgraded|be downgraded|change architecture):$/ { | |
pkg=1; | |
next; | |
} | |
pkg==1 { | |
name=$1; getline; | |
version=$NF; getline; | |
arch=$1; getline; | |
repo=trim($0); getline; | |
host=uri[repo]; | |
print host "/" arch "/" name "-" version "." arch ".rpm"; | |
print " dir=" PKG_CACHE_DIR "/" alias[repo] "/" arch; | |
} | |
' - | |
} | |
download_all() { | |
aria2c --input-file=- \ | |
--max-connection-per-server=6 \ | |
--split=16 \ | |
--min-split-size=1M \ | |
--check-integrity=true \ | |
--allow-overwrite=true \ | |
--auto-file-renaming=false \ | |
--continue=true | |
} | |
check_rpm() { | |
local dir output | |
dir=$(package_dir) | |
output=$(find "$dir" -type f -name "*.rpm" -execdir rpm --checksig "{}" +) | |
local result=$? | |
if (( result != 0 )); then | |
grep " NOT OK$" <<< "$output" | |
fi | |
return $result | |
} 1>&2 | |
main "$@" |
@marozsas Took the zypper-download.log you provided and pass it on to aria2. There's a couple different errors, but it's just regular operation. I got about 3080 packages downloaded at the end.
Summary of errors:
- Checksum error detected: aria2 checksums local files even when they don't yet exist. Can be ignored.
- errorCode=3 Resource not found: some packages from packman had new versions published. zypper refresh and repeat.
About the original error you found, I suppose it's related to repo URIs which can be a source of error.
Getting error messages on first run
02/25 14:10:47 [ERROR] Unrecognized URI or unsupported protocol: /noarch/yast2-network-4.4.40-1.1.noarch.rpm
02/25 14:10:47 [ERROR] Unrecognized URI or unsupported protocol: /noarch/yast2-security-4.4.12-1.1.noarch.rpm
02/25 14:10:47 [ERROR] Unrecognized URI or unsupported protocol: /noarch/info-lang-6.7-6.1.noarch.rpm
02/25 14:10:47 [ERROR] Unrecognized URI or unsupported protocol: /noarch/makeinfo-lang-6.7-6.1.noarch.rpm
Hi @marcushallett, this is likely related to your repositories, send me the output of
zypper lr --uri
cat zypper-download.log
Sorry for the delay, @awerlang.
From three weeks ago, this was the output.
Edit: Today it's giving me "No files to download." That's a different issue, I'll investigate that further a bit later. Needed a vendor change. Fixed this, but yields same problem as before, for which you asked for the information.
@marcushallett I published v0.3.2 which addresses when there are more than 9 repositories in the system. Please let me know if you find other issues.
@awerlang I'm seeing a ton of checksum error messages when running zypper-download (zypper-download dist-upgrade --no-recommends
)
@marcushallett at the end, is every package downloaded successfully? you can see that when zypper reports no more packages to download. If they do download, then there's no problem.
@awerlang It seems to fail every time there is a package on the Packman repo on my laptop. It seems to miss the Extra or Multimedia directory which should be in between the openSUSE_Tumbleweed and x86_64. Do I need to add a separate repo file for each part of packman?
@awerlang It seems to fail every time there is a package on the Packman repo on my laptop. It seems to miss the Extra or Multimedia directory which should be in between the openSUSE_Tumbleweed and x86_64. Do I need to add a separate repo file for each part of packman?
@p4p4j0hn I use packman essentials without issues, but per your description the full packman repo uses a different url pattern. As you mention using separate repos might work.
To get it working out of the box there's a few alternatives:
- Hardcode fixes for such repos (full packman, vs code, etc)
- Parse the repositories metadata to find the correct location for each download
- If there's a python lib for that if would be great
@awerlang I ended up adding a separate repo file for each section of Packman that I use. This allowed the script to find the packages.
I originally installed those packages using opi which only added the main repo. Zypper was able to update the applications for some reason, just not this script.
Has there been any updates to this? I pretty much require packman and vscode so this is of limited utility without understanding how to workaround those limitations. I don't understand how to "add a separate repo file for each part of packman"
@TonyApuzzo see https://en.opensuse.org/Additional_package_repositories#Packman how to use separate packman repos. I updated the known issues to mention that it's not a big deal, it just skips packages (e.g. vs code)
I got errors that I hope could help you to debug.
Please, note the errors, this time, are not the same as reported on reddit. Anyway... here, follows:
tinybit:~ # zypper lr --uri
Repository priorities in effect: (See 'zypper lr -P' for details)
90 (raised priority) : 1 repository
99 (default priority) : 6 repositories
| Alias | Name | Enabled | GPG Check | Refresh | URI
--+---------------------+---------------------------------------------+---------+-----------+---------+--------------------------------------------------------------------------------------
1 | google-chrome-beta | google-chrome-beta | Yes | (r ) Yes | Yes | http://dl.google.com/linux/chrome/rpm/stable/x86_64
2 | home_concyclic_java | Java-related packages (openSUSE_Tumbleweed) | Yes | (r ) Yes | No | https://download.opensuse.org/repositories/home:/concyclic:/java/openSUSE_Tumbleweed/
3 | microsoft-edge | microsoft-edge | Yes | (r ) Yes | Yes | https://packages.microsoft.com/yumrepos/edge/
4 | packman | packman | Yes | (r ) Yes | Yes | http://ftp.gwdg.de/pub/linux/misc/packman/suse/openSUSE_Tumbleweed/
5 | repo-non-oss | openSUSE-Tumbleweed-Non-Oss (20220113) | Yes | (r ) Yes | Yes | http://download.opensuse.org/history/20220113/tumbleweed/repo/non-oss/
6 | repo-oss | openSUSE-Tumbleweed-Oss (20220113) | Yes | (r ) Yes | Yes | http://download.opensuse.org/history/20220113/tumbleweed/repo/oss/
7 | repo-update | openSUSE-Tumbleweed-Update | Yes | (r ) Yes | Yes | http://download.opensuse.org/update/tumbleweed/
tinybit:~ #
The zypper-download.log can be found at https://paste.opensuse.org/36157840
thanks for any help,