This is a workaround to the US pacman mirror unavailability. It does refresh all enabled repos while skipping the ones that are down after a timeout (3 seconds by default). It also replaces unreachable URLS with the next available one, allowing the use of multiple URLs for repos and finally restores the default URL (the first one defined in the alias) when it is back. You can add other repos by setting a variable with the same name as their alias. This example includes only packman. This script might need some testing (meaning you’re using it at your own risk.)
#! /bin/bash
#
#: Title : updaterepos
#: Date Created: Fri May 13 10:51:42 PDT 2011
#: Last Edit : Fri May 13 12:52:04 PDT 2011
#: Author : please_try_again
#: Version : 1.0
#: Description : Refreshes all enabled repos, while skipping repos that are down after a defined timeout
# Replaces repos that are down by the next available repo defined for their alias - if any
# Replaces repos that are up by the first repo defined for their alias if it is back online
# You can define the timeout
TimeOut=3
# check if we are root
[ $UID -eq 0 ] || exec echo "You have to run this script as root or sudo"
# use lsb_release to get openSUSE version
which lsb_release >/dev/null 2>&1 || zypper -n in lsb-release
suseRel=$(lsb_release -rs)
# You can define multiples urls for each repo's alias, as in the packman example below.
packman="http://packman.unixheads.com/suse/openSUSE_$suseRel/ \
http://ftp.uni-erlangen.de/pub/mirrors/packman/suse/openSUSE_$suseRel/ \
http://ftp.gwdg.de/pub/linux/misc/packman/suse/openSUSE_$suseRel/ \
http://ftp.halifax.rwth-aachen.de/packman/suse/openSUSE_$suseRel/ \
http://mirror.geht-schon.de/packman.links2linux.de/suse/openSUSE_$suseRel/ \
http://packman.jacobs-university.de/suse/openSUSE_$suseRel/ \
http://packman.inode.at/suse/openSUSE_$suseRel/"
eval $(zypper lr -u | tr -d " " | awk -F "|" '/^[1-9]/{ E=tolower($4) ; printf "ralias[%s]=%s;rurl[%s]=%s;enable[%s]=%s;", $1, $2, $1, $6, $1, E}')
i=0
while [ $i -le ${#ralias[li]} ] ; do[/li] let i++
uri=${rurl[$i]} ; alias=${ralias[$i]}
[ "${uri#http*}" != "$uri" -o "${uri#ftp*}" != "$uri" ] || continue
[ "${enable[$i]}" == "yes" ] || continue
rfile=/etc/zypp/repos.d/$alias.repo
[ -f $rfile ] || continue
curl --connect-timeout $TimeOut $uri > /dev/null 2>&1 && {
if [ "${!alias}" ] ; then
for mirror in ${!alias} ; do
if [ "$uri" != "$mirror" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && sed -i "s|$uri|$mirror|" $rfile
fi
break
done
fi
} || {
for mirror in ${!alias} ; do
if [ "$uri" != "$mirror" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && {
sed -i "s|$uri|$mirror|" $rfile
break
}
fi
done
}
zypper refresh -r "$alias"
done
Where $rfile is the file /etc/zypp/repos.d/$alias.repo. I do it by “sediting” the repo file because I wanted to change only the URL and not any other property of the repo, like ‘autorefresh’, ‘enabled’ (although the script skips disabled repos earlier) or ‘keeppackages’. Finally zypper refreshes the repo with the new URL. For me it’s a simple workaround, as I didn’t want to worry about the packman US mirror being available or not.
IMHO “they” would just need to replace an URL with an array of URLs.
On 2011-05-14 16:06, please try again wrote:
>
> Comment_pasted_from_that_thread:‘Packman_broken?’
> (http://tinyurl.com/5rgy669)_
>
> robin_listas;2339581 Wrote:
>>
>> What I don’t see is how you change the URL for zypper :-?
>>
>> I mean, zypper must think it is using packman with the same URL as
>> always,
>> but in fact you change it somehow. At least, I think you do, but I
>> didn’t
>> see how.
>>
>
> This is how I change the URL:
>
> Code:
> --------------------
> sed -i “s|$uri|$mirror|” $rfile
> --------------------
>
> Where $rfile is the file /etc/zypp/repos.d/$alias.repo. I do it by
> “sediting” the repo file because I wanted to change only the URL and not
> any other property of the repo, like ‘autorefresh’, ‘enabled’ (although
> the script skips disabled repos earlier) or ‘keeppackages’.
Yes, that’s was the trick I knew you must be doing somehow.
Mmm… weird. That directory is not named after the ‘alias’ zypper uses,
but after the name. When you list the output of “zypper lr --details”, each
repo has both a name and an alias. The alias is used for the directories
names in “/var/cache/zypp/packages/”. But looking at “/etc/zypp/repos.d/”
it is using instead the names.
So zypper is not consistent. For some filenames it uses “alias”, for other
it uses “names”. Interesting!
> Finally
> zypper refreshes the repo with the new URL. For me it’s a simple
> workaround, as I didn’t want to worry about the packman US mirror being
> available or not.
It is a good solution.
> robin_listas;2339581 Wrote:
>>
>> If this works, you have a good idea to propose “them”
>>
>
> IMHO “they” would just need to replace an URL with an array of URLs.
They went another route.
They use a redirector, that when you ask for a package it can give back a
metalink info file, which includes a list of mirrors for that package. The
downloader can use that metalink file to download from several mirrors at
once, and to bypass bad mirrors.
That’s the theory. And packman is not included in the redirector.
–
Cheers / Saludos,
Carlos E. R.
(from 11.2 x86_64 “Emerald” at Telcontar)
The alias seems to be used in both cases for the download directory and repo file names. However if you edit the repo file afterwards as I do, I can not tell since packman’s alias and names are the same (at least the way I originally added the repo). Look at ‘repo-oss’ in the example below.
On 2011-05-15 13:36, please try again wrote:
>
> robin_listas;2339750 Wrote:
>> So zypper is not consistent. For some filenames it uses “alias”, for
>> other it uses “names”. Interesting!
>>
>
> The alias seems to be used in both cases for the download directory and
> repo file names. However if you edit the repo file afterwards as I do, I
> can not tell since packman’s alias and names are the same (at least the
> way I originally added the repo). Look at ‘repo-oss’ in the example
> below.
Ah, yes, you don’t notice the difference because you have both name and
alias the same. I alter the alias, so I noticed.
The packages dirs in my case are symlinks, because I export them via NFS
and share the download on two computers. But the names are put by zypper,
so you can see that it is using “alias” for the package dirs, and “name”
for the repo metadata you use.
The case of your repo-oss is curious, though. Maybe it can use either of
alias or name. Intriguing.
–
Cheers / Saludos,
Carlos E. R.
(from 11.2 x86_64 “Emerald” at Telcontar)
This is weird. In my case the packages dirs are not symlinks but the parent directory /var/cache/zypp/packages is a symlink to a directory on my file server. I didn’t install any of the openSUSE-11.4xxx (name) or repo-xxx (alias) myself. Those are installed by default. I installed all the other repos from my own installation script, using the syntax:
zypper ar repo_url alias
meaning I always explicitely specify the alias. The fact that I chose the alias ‘packman’ while the repo was also named ‘packman’ is actually a coincidence.
On 2011-05-15 17:36, please try again wrote:
>
> This is weird. In my case the packages dirs are not symlinks but the
> parent directory /var/cache/zypp/packages is a symlink to a directory on
> my file server.
I let zypper create the real directory, then I move it to the nfs mount and
symlink it. This way it works even if in another install it is named
differently.
> I didn’t install any of the openSUSE-11.4xxx (name) or
> repo-xxx (alias) myself. Those are installed by default. I installed all
> the other repos from my own installation script, using the syntax:
>
> Code:
> --------------------
> zypper ar repo_url alias
> --------------------
>
> meaning I always explicitely specify the alias.
I change both name and alias after the creation, which I typically create
from YaST (with yast you can define the name, not the alias). Only in YaST
I can see which repos have the keep packages option enabled (and not at a
glance).
–
Cheers / Saludos,
Carlos E. R.
(from 11.2 x86_64 “Emerald” at Telcontar)
packman.unixheads.com now responds to curl but the repo is still unavailable. I had to modify the script, so that it will switch back to the former mirror if zypper refresh fails. Don’t worry about the error message while trying to refresh packman. This is normal.
#! /bin/bash
#
#: Title : updaterepos
#: Date Created: Fri May 13 10:51:42 PDT 2011
#: Last Edit : Fri May 13 12:52:04 PDT 2011
#: Author : please_try_again
#: Version : 1.0
#: Description : Refreshes all enabled repos, while skipping repos that are down after a defined timeout
# Replaces repos that are down by the next available repo defined for their alias - if any
# Replaces repos that are up by the first repo defined for their alias if it is back online
# You can define the timeout
TimeOut=3
# check if we are root
[ $UID -eq 0 ] || exec echo "You have to run this script as root or sudo"
# use lsb_release to get openSUSE version
which lsb_release >/dev/null 2>&1 || zypper -n in lsb-release
suseRel=$(lsb_release -rs)
# You can define multiples urls for each repo's alias, as in the packman example below.
packman="http://packman.unixheads.com/suse/openSUSE_$suseRel/ \
http://ftp.uni-erlangen.de/pub/mirrors/packman/suse/openSUSE_$suseRel/ \
http://ftp.gwdg.de/pub/linux/misc/packman/suse/openSUSE_$suseRel/ \
http://ftp.halifax.rwth-aachen.de/packman/suse/openSUSE_$suseRel/ \
http://mirror.geht-schon.de/packman.links2linux.de/suse/openSUSE_$suseRel/ \
http://packman.jacobs-university.de/suse/openSUSE_$suseRel/ \
http://packman.inode.at/suse/openSUSE_$suseRel/"
eval $(zypper lr -u | tr -d " " | awk -F "|" '/^[1-9]/{ E=tolower($4) ; printf "ralias[%s]=%s;rurl[%s]=%s;enable[%s]=%s;", $1, $2, $1, $6, $1, E}')
i=0
while [ $i -le ${#ralias[li]} ] ; do
[/li] let i++
uri=${rurl[$i]} ; alias=${ralias[$i]}
[ "${uri#http*}" != "$uri" -o "${uri#ftp*}" != "$uri" ] || continue
[ "${enable[$i]}" == "yes" ] || continue
rfile=/etc/zypp/repos.d/$alias.repo
[ -f $rfile ] || continue
curl --connect-timeout $TimeOut $uri > /dev/null 2>&1 && {
if [ "${!alias}" ] ; then
for mirror in ${!alias} ; do
if [ "$uri" != "$mirror" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && sed -i "s|$uri|$mirror|" $rfile
fi
break
done
fi
} || {
for mirror in ${!alias} ; do
if [ "$uri" != "$mirror" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && {
sed -i "s|$uri|$mirror|" $rfile
break
}
fi
done
}
zypper -n refresh -r "$alias" || {
for mirror in ${!alias} ; do
if [ "$uri" != "$mirror" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && sed -i "s|$uri|$mirror|" $rfile
break
fi
done
zypper -n refresh -r "$alias"
}
done
Done. I made it optional too in case it is desired to use static mirrors.
#! /bin/bash
#
#: Title : updaterepos
#: Date Created: Fri May 13 10:51:42 PDT 2011
#: Last Edit : Tue May 17 21:37:56 PDT 2011
#: Author : please_try_again
#: Version : 1.0
#: Description : Refreshes all enabled repos, while skipping repos that are down after a defined timeout
# Replaces repos that are down by the next available repo defined for their alias - if any
# Replaces repos that are up by the first repo defined for their alias if it is back online
# You can define the timeout
TimeOut=3
# use dynamic mirror list (1 or 0 )
DynamicMirrors=1
# check if we are root
[ $UID -eq 0 ] || exec echo "You have to run this script as root or sudo"
# use lsb_release to get openSUSE version
which lsb_release >/dev/null 2>&1 || zypper -n in lsb-release
suseRel=$(lsb_release -rs)
# You can define multiples urls for each repo's alias, as in the packman example below.
# preferred mirror
packman_default="http://packman.unixheads.com/suse/openSUSE_$suseRel/"
# static mirror list
packman="$packman_default \
http://ftp.uni-erlangen.de/pub/mirrors/packman/suse/openSUSE_$suseRel/ \
http://ftp.gwdg.de/pub/linux/misc/packman/suse/openSUSE_$suseRel/ \
http://ftp.halifax.rwth-aachen.de/packman/suse/openSUSE_$suseRel/ \
http://mirror.geht-schon.de/packman.links2linux.de/suse/openSUSE_$suseRel/ \
http://packman.jacobs-university.de/suse/openSUSE_$suseRel/ \
http://packman.inode.at/suse/openSUSE_$suseRel/"
# dynamic mirror list
packman_list=ftp://packman.links2linux.de/pub/packman/MIRRORS
eval $(zypper lr -u | tr -d " " | awk -F "|" '/^[1-9]/{ E=tolower($4) ; printf "ralias[%s]=%s;rurl[%s]=%s;enable[%s]=%s;", $1, $2, $1, $6, $1, E}')
i=0
while [ $i -le ${#ralias[li]} ] ; do
[/li] let i++
uri=${rurl[$i]} ; alias=${ralias[$i]}
[ "${uri#http*}" != "$uri" -o "${uri#ftp*}" != "$uri" ] || continue
[ "${enable[$i]}" == "yes" ] || continue
rfile=/etc/zypp/repos.d/$alias.repo
[ -f $rfile ] || continue
if [ "$DynamicMirrors" == "1" ] ; then
list=${alias}_list
pref=${alias}_default
if [ "x${!list}" != "x" ] ; then
curl --connect-timeout $TimeOut ${!list} > /dev/null 2>&1 && \
mirrors=$(curl --connect-timeout $TimeOut ${!list} 2>/dev/null | tr -d "|" | awk 'BEGIN { REL="'"$suseRel"'" } ; /^http:|^ftp:/ { printf "%ssuse/openSUSE_%s/ ", $1, REL }')
eval $alias='"'${!pref} $mirrors'"'
fi
fi
curl --connect-timeout $TimeOut $uri > /dev/null 2>&1 && {
if [ "${!alias}" ] ; then
for mirror in ${!alias} ; do
if [ "$uri" != "$mirror" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && sed -i "s|$uri|$mirror|" $rfile
fi
break
done
fi
} || {
for mirror in ${!alias} ; do
if [ "$uri" != "$mirror" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && {
sed -i "s|$uri|$mirror|" $rfile
break
}
fi
done
}
zypper -n refresh -r "$alias" || {
uri=$(awk -F "=" '/baseurl/{ print $2 }' $rfile)
if [ "${!alias}" ] ; then
for mirror in ${!alias} ; do
if [ "$mirror" != "$uri" ] ; then
curl --connect-timeout $TimeOut $mirror > /dev/null 2>&1 && sed -i "s|$uri|$mirror|" $rfile
break
fi
done
fi
zypper -n refresh -r "$alias"
}
done