summaryrefslogtreecommitdiff
path: root/DistUpgrade
diff options
context:
space:
mode:
authorSebastian Heinlein <sebastian.heinlein@web.de>2006-04-29 15:53:42 +0200
committerSebastian Heinlein <sebastian.heinlein@web.de>2006-04-29 15:53:42 +0200
commit4e093f33b5e9da902a69fc8bdf0fd2109a31c2d5 (patch)
tree54cc2932cb71aded4e39a71653dea7b540304049 /DistUpgrade
parentd19de868ff0230aebfc0920bd31caa64d51ec920 (diff)
parentdc3dc10c9a2835ffef5708db35dd70344860adab (diff)
downloadpython-apt-4e093f33b5e9da902a69fc8bdf0fd2109a31c2d5.tar.gz
* merged from mvo
Diffstat (limited to 'DistUpgrade')
-rw-r--r--DistUpgrade/Changelog17
-rw-r--r--DistUpgrade/DistUpgrade.cfg2
-rw-r--r--DistUpgrade/DistUpgradeConfigParser.py10
-rw-r--r--DistUpgrade/DistUpgradeControler.py110
-rw-r--r--DistUpgrade/DistUpgradeView.py4
-rw-r--r--DistUpgrade/DistUpgradeViewGtk.py37
-rw-r--r--DistUpgrade/TODO21
-rw-r--r--DistUpgrade/mirrors.txt278
8 files changed, 448 insertions, 31 deletions
diff --git a/DistUpgrade/Changelog b/DistUpgrade/Changelog
index df5bb506..c450d99d 100644
--- a/DistUpgrade/Changelog
+++ b/DistUpgrade/Changelog
@@ -1,3 +1,20 @@
+2006-04-28:
+ - add more sanity checking, if no valid mirror is found in the
+ sources.list ask for "dumb" rewrite
+ - if nothing valid was found after a dumb rewrite, add official
+ sources
+ - don't report install TIMEOUT over and over in the log
+ - report what package caused a install TIMEOUT
+2006-04-27:
+ - add a additonal sanity check after the rewriting of the sources.list
+ (check for BaseMetaPkgs still in the cache)
+ - on abort reopen() the cache to force writing a new
+ /var/cache/apt/pkgcache.bin
+ - use a much more compelte mirror list (based on the information
+ from https://wiki.ubuntu.com/Archive)
+2006-04-25:
+ - make sure that DistUpgradeView.getTerminal().call() actually
+ waits until the command has finished (dpkg --configure -a)
2006-04-18:
- add logging to the sources.list modification code
- general logging improvements (thanks to Xavier Poinsard) \ No newline at end of file
diff --git a/DistUpgrade/DistUpgrade.cfg b/DistUpgrade/DistUpgrade.cfg
index a2720f49..de52098d 100644
--- a/DistUpgrade/DistUpgrade.cfg
+++ b/DistUpgrade/DistUpgrade.cfg
@@ -34,7 +34,7 @@ BackupExt=distUpgrade
From=breezy
To=dapper
ValidOrigin=Ubuntu
-ValidMirrors = http://archive.ubuntu.com/ubuntu, http://security.ubuntu.com/ubuntu
+ValidMirrors = mirrors.txt
[Network]
MaxRetries=3 \ No newline at end of file
diff --git a/DistUpgrade/DistUpgradeConfigParser.py b/DistUpgrade/DistUpgradeConfigParser.py
index c87e2f1b..a4c55080 100644
--- a/DistUpgrade/DistUpgradeConfigParser.py
+++ b/DistUpgrade/DistUpgradeConfigParser.py
@@ -12,9 +12,17 @@ class DistUpgradeConfig(ConfigParser):
return []
items = [x.strip() for x in tmp.split(",")]
return items
+ def getListFromFile(self, section, option):
+ try:
+ filename = self.get(section, option)
+ except NoOptionError:
+ return []
+ items = [x.strip() for x in open(filename)]
+ return filter(lambda s: not s.startswith("#") and not s == "", items)
if __name__ == "__main__":
- c = DistUpgradeConfigParser()
+ c = DistUpgradeConfig()
print c.getlist("Distro","MetaPkgs")
print c.getlist("Distro","ForcedPurges")
+ print c.getListFromFile("Sources","ValidMirrors")
diff --git a/DistUpgrade/DistUpgradeControler.py b/DistUpgrade/DistUpgradeControler.py
index 9a03f288..c89f6a34 100644
--- a/DistUpgrade/DistUpgradeControler.py
+++ b/DistUpgrade/DistUpgradeControler.py
@@ -57,10 +57,9 @@ class DistUpgradeControler(object):
self.cache = MyCache(self._view.getOpCacheProgress())
- def updateSourcesList(self):
+ def rewriteSourcesList(self, mirror_check=True):
+ logging.debug("rewriteSourcesList()")
- logging.debug("updateSourcesList()")
-
# this must map, i.e. second in "from" must be the second in "to"
# (but they can be different, so in theory we could exchange
# component names here)
@@ -76,49 +75,92 @@ class DistUpgradeControler(object):
]
# list of valid mirrors that we can add
- valid_mirrors = self.config.getlist("Sources","ValidMirrors")
+ valid_mirrors = self.config.getListFromFile("Sources","ValidMirrors")
+
+ self.sources_disabled = False
# look over the stuff we have
foundToDist = False
for entry in self.sources:
- # ignore invalid records (but update disabled ones)
- if entry.invalid:
+ # ignore invalid records (but update disabled ones)
+ # or cdrom entries
+ if entry.invalid or entry.uri.startswith("cdrom:"):
continue
logging.debug("examining: '%s'" % entry)
# check if it's a mirror (or offical site)
validMirror = False
for mirror in valid_mirrors:
- if is_mirror(mirror,entry.uri):
+ if not mirror_check or is_mirror(mirror,entry.uri):
validMirror = True
+ # security is a special case
+ res = not entry.uri.startswith("http://security.ubuntu.com") and not entry.disabled
if entry.dist in toDists:
# so the self.sources.list is already set to the new
# distro
logging.debug("entry '%s' is already set to new dist" % entry)
- foundToDist = True
+ foundToDist |= res
elif entry.dist in fromDists:
- foundToDist = True
+ foundToDist |= res
entry.dist = toDists[fromDists.index(entry.dist)]
logging.debug("entry '%s' updated to new dist" % entry)
else:
# disable all entries that are official but don't
- # point to the "from" dist
+ # point to either "to" or "from" dist
entry.disabled = True
+ self.sources_disabled = True
logging.debug("entry '%s' was disabled (unknown dist)" % entry)
# it can only be one valid mirror, so we can break here
break
# disable anything that is not from a official mirror
if not validMirror:
entry.disabled = True
+ self.sources_disabled = True
logging.debug("entry '%s' was disabled (unknown mirror)" % entry)
+ return foundToDist
- if not foundToDist:
- # FIXME: offer to write a new self.sources.list entry
- # DONT'T ERROR, write a line with mirror here
- logging.error("No valid entry found")
- return self._view.error(_("No valid entry found"),
- _("While scaning your repository "
- "information no valid entry for "
- "the upgrade was found.\n"))
+ def updateSourcesList(self):
+ logging.debug("updateSourcesList()")
+ self.sources = SourcesList()
+ if not self.rewriteSourcesList(mirror_check=True):
+ logging.error("No valid mirror found")
+ res = self._view.askYesNoQuestion(_("No valid mirror found"),
+ _("While scaning your repository "
+ "information no mirror entry for "
+ "the upgrade was found."
+ "This cam happen if you run a internal "
+ "mirror or if the mirror information is "
+ "out of date.\n\n"
+ "Do you want to rewrite your "
+ "'sources.list' file anyway? If you choose "
+ "'Yes' here it will update all '%s' to '%s' "
+ "entries.\n"
+ "If you select 'no' the update will cancel."
+ ) % (self.fromDist, self.toDist))
+ if res:
+ # re-init the sources and try again
+ self.sources = SourcesList()
+ if not self.rewriteSourcesList(mirror_check=False):
+ #hm, still nothing useful ...
+ prim = _("Generate default sources?")
+ secon = _("After scanning your 'sources.list' no "
+ "valid entry for '%s' was found.\n\n"
+ "Should default entries for '%s' be "
+ "added? If you select 'No' the update "
+ "will cancel.") % (self.fromDist, self.toDist)
+ if not self._view.askYesNoQuestion(prim, secon):
+ self.abort()
+
+ # add some defaults here
+ # FIXME: find mirror here
+ uri = "http://archive.ubuntu.com/ubuntu"
+ comps = ["main","restricted"]
+ self.sources.add("deb", uri, self.toDist, comps)
+ self.sources.add("deb", uri, self.toDist+"-updates", comps)
+ self.sources.add("deb",
+ "http://security.ubuntu.com/ubuntu/",
+ self.toDist+"-security", comps)
+ else:
+ self.abort()
# write (well, backup first ;) !
self.sources.backup(self.sources_backup_ext)
@@ -139,6 +181,14 @@ class DistUpgradeControler(object):
"resulted in a invalid file. Please "
"report this as a bug."))
return False
+
+ if self.sources_disabled:
+ self._view.information(_("Third party sources disabled"),
+ _("Some third party entries in your souces.list "
+ "where disabled. You can re-enable them "
+ "after the upgrade with the "
+ "'software-properties' tool or with synaptic."
+ ))
return True
def _logChanges(self):
@@ -223,12 +273,12 @@ class DistUpgradeControler(object):
res = self.cache.commit(fprogress,iprogress)
except SystemError, e:
# installing the packages failed, can't be retried
+ self._view.getTerminal().call(["dpkg","--configure","-a"])
self._view.error(_("Could not install the upgrades"),
_("The upgrade aborts now. Your system "
"can be in an unusable state. A recovery "
- "is now run (dpkg --configure -a)."),
+ "was run (dpkg --configure -a)."),
"%s" % e)
- self._view.getTerminal().call(["dpkg","--configure","-a"])
return False
except IOError, e:
# fetch failed, will be retried
@@ -303,6 +353,8 @@ class DistUpgradeControler(object):
def abort(self):
""" abort the upgrade, cleanup (as much as possible) """
self.sources.restoreBackup(self.sources_backup_ext)
+ # generate a new cache
+ self.openCache()
sys.exit(1)
@@ -313,8 +365,6 @@ class DistUpgradeControler(object):
self._view.setStep(1)
self.openCache()
- self.sources = SourcesList()
-
if not self.cache.sanityCheck(self._view):
abort(1)
@@ -337,6 +387,22 @@ class DistUpgradeControler(object):
# then open the cache (again)
self._view.updateStatus(_("Checking package manager"))
self.openCache()
+ # now check if we still have some key packages after the update
+ # if not something went seriously wrong
+ for pkg in self.config.getlist("Distro","BaseMetaPkgs"):
+ if not self.cache.has_key(pkg):
+ # FIXME: we could offer to add default source entries here,
+ # but we need to be careful to not duplicate them
+ # (i.e. the error here could be something else than
+ # missing sources entires but network errors etc)
+ logging.error("No '%s' after sources.list rewrite+update")
+ self._view.error(_("Inavlid package information"),
+ _("After your package information was "
+ "updated the essential package '%s' can "
+ "not be found anymore.\n"
+ "This indicates a serious error, please "
+ "report this as a bug.") % pkg)
+ self.abort()
# calc the dist-upgrade and see if the removals are ok/expected
# do the dist-upgrade
diff --git a/DistUpgrade/DistUpgradeView.py b/DistUpgrade/DistUpgradeView.py
index 57b94636..99dedc6f 100644
--- a/DistUpgrade/DistUpgradeView.py
+++ b/DistUpgrade/DistUpgradeView.py
@@ -81,4 +81,6 @@ class DistUpgradeView(object):
def error(self, summary, msg, extended_msg=None):
" display a error "
pass
-
+ def information(self, summary, msg):
+ " display a information msg"
+ pass
diff --git a/DistUpgrade/DistUpgradeViewGtk.py b/DistUpgrade/DistUpgradeViewGtk.py
index dba8014f..f3ab2983 100644
--- a/DistUpgrade/DistUpgradeViewGtk.py
+++ b/DistUpgrade/DistUpgradeViewGtk.py
@@ -212,6 +212,7 @@ class GtkInstallProgressAdapter(InstallProgress):
# start showing when we gathered some data
if percent > 1.0:
self.last_activity = time.time()
+ self.activity_timeout_reported = False
delta = self.last_activity - self.start_time
time_per_percent = (float(delta)/percent)
eta = (100.0 - self.percent) * time_per_percent
@@ -242,7 +243,9 @@ class GtkInstallProgressAdapter(InstallProgress):
# check about terminal activity
if self.last_activity > 0 and \
(self.last_activity + self.TIMEOUT_TERMINAL_ACTIVITY) < time.time():
- logging.warning("no activity on terminal for %s seconds" % self.TIMEOUT_TERMINAL_ACTIVITY)
+ if not self.activity_timeout_reported:
+ logging.warning("no activity on terminal for %s seconds (%s)" % (self.TIMEOUT_TERMINAL_ACTIVITY, self.label_status.get_text()))
+ self.activity_timeout_reported = True
self.parent.expander_terminal.set_expanded(True)
while gtk.events_pending():
gtk.main_iteration()
@@ -253,9 +256,19 @@ class DistUpgradeVteTerminal(object):
self.term = term
self.parent = parent
def call(self, cmd):
+ def wait_for_child(widget):
+ #print "wait for child finished"
+ self.finished=True
self.term.show()
+ self.term.connect("child-exited", wait_for_child)
self.parent.expander_terminal.set_expanded(True)
self.term.fork_command(command=cmd[0],argv=cmd)
+ self.finished = False
+ while not self.finished:
+ while gtk.events_pending():
+ gtk.main_iteration()
+ time.sleep(0.1)
+ del self.finished
class DistUpgradeViewGtk(DistUpgradeView,SimpleGladeApp):
" gtk frontend of the distUpgrade tool "
@@ -299,9 +312,11 @@ class DistUpgradeViewGtk(DistUpgradeView,SimpleGladeApp):
logging.error("not handled expection:\n%s" % "\n".join(lines))
self.error(_("A fatal error occured"),
_("Please report this as a bug and include the "
- "files '/var/log/dist-upgrade.log' and "
- "'/var/log/dist-upgrade-apt.log' "
- "in your report. The upgrade aborts now. "),
+ "files /var/log/dist-upgrade.log and "
+ "/var/log/dist-upgrade-apt.log "
+ "in your report. The upgrade aborts now.\n"
+ "Your original sources.list was saved in "
+ "/etc/apt/sources.list.distUpgrade."),
"\n".join(lines))
sys.exit(1)
@@ -361,6 +376,16 @@ class DistUpgradeViewGtk(DistUpgradeView,SimpleGladeApp):
attrlist.insert(attr)
label.set_property("attributes",attrlist)
+ def information(self, summary, msg):
+ msg = "<big><b>%s</b></big>\n\n%s" % (summary,msg)
+ dialog = gtk.MessageDialog(parent=self.window_main,
+ flags=gtk.DIALOG_MODAL,
+ type=gtk.MESSAGE_INFO,
+ buttons=gtk.BUTTONS_CLOSE)
+ dialog.set_markup(msg)
+ dialog.run()
+ dialog.destroy()
+
def error(self, summary, msg, extended_msg=None):
self.dialog_error.set_transient_for(self.window_main)
#self.expander_terminal.set_expanded(True)
@@ -498,10 +523,10 @@ if __name__ == "__main__":
cache[pkg].markInstall()
cache.commit(fp,ip)
- sys.exit(0)
+ #sys.exit(0)
ip.conffile("TODO","TODO~")
view.getTerminal().call(["dpkg","--configure","-a"])
- view.getTerminal().call(["ls"])
+ view.getTerminal().call(["ls","-R","/usr"])
view.error("short","long",
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
diff --git a/DistUpgrade/TODO b/DistUpgrade/TODO
index 217eb6cb..9c4f503c 100644
--- a/DistUpgrade/TODO
+++ b/DistUpgrade/TODO
@@ -7,6 +7,27 @@ MUSTFIX:
happen)
[done in current dialog]
+* sources.list edit needs to add valid sources if all other sources
+ are commented out
+ (or for sources that can't be identified and rewrite ask the user
+ what to do by just s/breezy/dapper/g?)
+ [Done]
+* inform about commented out sources
+ [Done]
+* fix "no activity for 120s warning" being repeated every sec in the logs
+ [Done]
+* use the dialog frontend (for debconf) and detect the ansi sequence that
+ clear the screen and expand the terminal then
+* [fabbio]: we probably don't want to remove stuff that moved from main
+ to universe (if the user has only main enabled this is considered
+ obsolete). It would also be nice inform about packages that went from
+ main->universe. We could ship a list of demotions.
+* [kamion]: we could use debconf-frontend=dialog and then detect the ansi
+ seqence that clear the screen and open the terminal then
+ -> trouble: vte does not give me the raw codes but only the
+ text (as \n\n\n\n\n... for cls)
+* add "add cdrom" to the "Do upgrade?" screen? And recalc the download
+ size again then :) ?
breezy->dapper
--------------
diff --git a/DistUpgrade/mirrors.txt b/DistUpgrade/mirrors.txt
new file mode 100644
index 00000000..e18f3616
--- /dev/null
+++ b/DistUpgrade/mirrors.txt
@@ -0,0 +1,278 @@
+#ubuntu
+http://archive.ubuntu.com/ubuntu
+http://security.ubuntu.com/ubuntu
+
+##===Australia===
+http://ftp.iinet.net.au/pub/ubuntu/
+http://mirror.optus.net/ubuntu/
+http://mirror.isp.net.au/ftp/pub/ubuntu/
+http://www.planetmirror.com/pub/ubuntu/
+http://ftp.filearena.net/pub/ubuntu/
+http://mirror.pacific.net.au/linux/ubuntu/
+ftp://mirror.isp.net.au/pub/ubuntu/
+ftp://ftp.planetmirror.com/pub/ubuntu/
+ftp://ftp.filearena.net/pub/ubuntu/
+ftp://mirror.internode.on.net/pub/ubuntu/ubuntu(InternodeCustomersonly)
+ftp://ftp.iinet.net.au/pub/ubuntu/
+ftp://mirror.pacific.net.au/linux/ubuntu/
+rsync://ftp.iinet.net.au/ubuntu/
+rsync://mirror.isp.net.au/ubuntu
+rsync://rsync.filearena.net/ubuntu/
+
+##===Austria===
+http://ubuntu.inode.at/ubuntu/
+http://ubuntu.uni-klu.ac.at/ubuntu/
+http://gd.tuwien.ac.at/opsys/linux/ubuntu/archive/
+ftp://ubuntu.inode.at/ubuntu/
+ftp://ftp.uni-klu.ac.at/linux/ubuntu/
+ftp://gd.tuwien.ac.at/opsys/linux/ubuntu/archive/
+rsync://ubuntu.inode.at/ubuntu/ubuntu/
+rsync://gd.tuwien.ac.at/ubuntu/archive/
+
+#===Belgium===
+http://ftp.belnet.be/pub/mirror/ubuntu.com/
+http://ubuntu.mirrors.skynet.be/pub/ubuntu.com/
+http://mirror.freax.be/ubuntu/archive.ubuntu.com/
+ftp://ftp.belnet.be/pub/mirror/ubuntu.com/
+ftp://ubuntu.mirrors.skynet.be/pub/ubuntu.com/
+
+#===Brazil===
+http://espelhos.edugraf.ufsc.br/ubuntu/
+http://ubuntu.interlegis.gov.br/archive/
+http://ubuntu.c3sl.ufpr.br/ubuntu/
+
+#===Canada===
+ftp://ftp.cs.mun.ca/pub/mirror/ubuntu/
+rsync://rsync.cs.mun.ca/ubuntu/
+http://mirror.cpsc.ucalgary.ca/mirror/ubuntu.com/
+ftp://mirror.cpsc.ucalgary.ca/mirror/ubuntu.com/
+http://mirror.arcticnetwork.ca/pub/ubuntu/packages/
+ftp://mirror.arcticnetwork.ca/pub/ubuntu/packages/
+rsync://rsync.arcticnetwork.ca/ubuntu-packages
+
+#===China===
+http://archive.ubuntu.org.cn/ubuntu/
+http://debian.cn99.com/ubuntu/
+http://mirror.lupaworld.com/ubuntu/
+
+#===CostaRica===
+http://ftp.ucr.ac.cr/ubuntu/
+ftp://ftp.ucr.ac.cr/pub/ubuntu/
+
+#===CzechRepublic===
+http://archive.ubuntu.cz/ubuntu/
+ftp://archive.ubuntu.cz/ubuntu/
+http://ubuntu.supp.name/ubuntu/
+
+#===Denmark===
+http://mirrors.dk.telia.net/ubuntu/
+http://mirrors.dotsrc.org/ubuntu/
+http://klid.dk/homeftp/ubuntu/
+ftp://mirrors.dk.telia.net/ubuntu/
+ftp://mirrors.dotsrc.org/ubuntu/
+ftp://klid.dk/ubuntu/
+
+#===Estonia===
+http://ftp.estpak.ee/pub/ubuntu/
+ftp://ftp.estpak.ee/pub/ubuntu/
+
+#===Finland===
+http://www.nic.funet.fi/pub/mirrors/archive.ubuntu.com/
+ftp://ftp.funet.fi/pub/mirrors/archive.ubuntu.com/
+
+#===France===
+http://mir1.ovh.net/ubuntu/ubuntu/
+http://fr.archive.ubuntu.com/ubuntu/
+http://ftp.u-picardie.fr/pub/ubuntu/ubuntu/
+http://ftp.oleane.net/pub/ubuntu/
+ftp://mir1.ovh.net/ubuntu/ubuntu/
+ftp://fr.archive.ubuntu.com/ubuntu/
+ftp://ftp.u-picardie.fr/pub/ubuntu/ubuntu/
+ftp://ftp.proxad.net/mirrors/ftp.ubuntu.com/ubuntu/(slow)
+ftp://ftp.oleane.net/pub/ubuntu/
+rsync://mir1.ovh.net/ubuntu/ubuntu/
+
+#===Germany===
+http://debian.charite.de/ubuntu/
+http://ftp.inf.tu-dresden.de/os/linux/dists/ubuntu
+http://www.artfiles.org/ubuntu.com
+http://ftp.rz.tu-bs.de/pub/mirror/ubuntu-packages/
+http://ftp.join.uni-muenster.de/pub/mirrors/ftp.ubuntu.com/ubuntu/
+http://www.ftp.uni-erlangen.de/pub/mirrors/ubuntu/
+http://debian.tu-bs.de/ubuntu
+ftp://debian.charite.de/ubuntu/
+ftp://ftp.fu-berlin.de/linux/ubuntu/
+ftp://ftp.rz.tu-bs.de/pub/mirror/ubuntu-packages/
+ftp://ftp.join.uni-muenster.de/pub/mirrors/ftp.ubuntu.com/ubuntu/
+ftp://ftp.uni-erlangen.de/pub/mirrors/ubuntu/
+ftp://debian.tu-bs.de/ubuntu
+rsync://ftp.inf.tu-dresden.de/ubuntu
+rsync://ftp.rz.tu-bs.de/pub/mirror/ubuntu-packages/
+rsync://ftp.join.uni-muenster.de/pub/mirrors/ftp.ubuntu.com/ubuntu/
+rsync://debian.tu-bs.de/ubuntu
+
+#===Greece===
+http://ftp.ntua.gr/pub/linux/ubuntu/
+ftp://ftp.ntua.gr/pub/linux/ubuntu/
+
+#===Hungary===
+http://ftp.kfki.hu/linux/ubuntu/
+ftp://ftp.kfki.hu/pub/linux/ubuntu/
+ftp://ftp.fsn.hu/pub/linux/distributions/ubuntu/
+
+#===Indonesia===
+http://komo.vlsm.org/ubuntu/
+http://kambing.vlsm.org/ubuntu/
+rsync://komo.vlsm.org/ubuntu/
+rsync://kambing.vlsm.org/ubuntu/
+
+#===Iceland===
+http://ubuntu.odg.cc/
+http://ubuntu.lhi.is/
+
+#===Ireland===
+http://ftp.esat.net/mirrors/archive.ubuntu.com/
+http://ftp.heanet.ie/pub/ubuntu/
+ftp://ftp.esat.net/mirrors/archive.ubuntu.com/
+ftp://ftp.heanet.ie/pub/ubuntu/
+rsync://ftp.esat.net/mirrors/archive.ubuntu.com/
+rsync://ftp.heanet.ie/pub/ubuntu/
+
+#===Italy===
+http://ftp.linux.it/ubuntu/
+http://na.mirror.garr.it/mirrors/ubuntu-archive/
+ftp://ftp.linux.it/ubuntu/
+ftp://na.mirror.garr.it/mirrors/ubuntu-archive/
+rsync://na.mirror.garr.it/ubuntu-archive/
+
+#===Japan===
+http://ubuntu.mithril-linux.org/archives/
+
+#===Korea===
+http://mirror.letsopen.com/os/ubuntu/
+ftp://mirror.letsopen.com/os/ubuntu/
+http://ftp.kaist.ac.kr/pub/ubuntu/
+ftp://ftp.kaist.ac.kr/pub/ubuntu/
+rsync://ftp.kaist.ac.kr/ubuntu/
+
+#===Latvia===
+http://ubuntu-arch.linux.edu.lv/ubuntu/
+
+#===Lithuania===
+http://ftp.litnet.lt/pub/ubuntu/
+ftp://ftp.litnet.lt/pub/ubuntu/
+
+#===Namibia===
+ftp://ftp.polytechnic.edu.na/pub/ubuntulinux/
+
+#===Netherlands===
+http://ftp.bit.nl/ubuntu/(Movedtohttp://nl.archive.ubuntu.com/ubuntu/)
+http://ubuntu.synssans.nl
+ftp://ftp.bit.nl/ubuntu/(Movedtoftp://nl.archive.ubuntu.com/ubuntu/)
+rsync://ftp.bit.nl/ubuntu/(Movedtorsync://nl.archive.ubuntu.com/ubuntu/)
+
+#===NewZealand===
+ftp://ftp.citylink.co.nz/ubuntu/(maynotbeaccessibleoutsideof.nz)
+
+#===Nicaragua===
+http://www.computacion.uni.edu.ni/iso/ubuntu/
+
+#===Norway===
+http://mirror.trivini.no/ubuntu(Movedtohttp://no.archive.ubuntu.com/ubuntu/)
+ftp://mirror.trivini.no/ubuntu(Movedtoftp://no.archive.ubuntu.com/ubuntu/)
+ftp://ftp.uninett.no/linux/ubuntu
+rsync://ftp.uninett.no/ubuntu
+
+#===Poland===
+http://ubuntulinux.mainseek.com/ubuntu/
+http://ubuntu.task.gda.pl/ubuntu/
+ftp://ubuntu.task.gda.pl/ubuntu/
+rsync://ubuntu.task.gda.pl/ubuntu/
+
+#===Portugal===
+ftp://ftp.rnl.ist.utl.pt/ubuntu/
+http://darkstar.ist.utl.pt/ubuntu/archive/
+http://ubuntu.dcc.fc.up.pt/
+
+#===Romania===
+http://ftp.iasi.roedu.net/mirrors/ubuntulinux.org/ubuntu/(fullmirror)
+ftp://ftp.iasi.roedu.net/mirrors/ubuntulinux.org/ubuntu/(fullmirror)
+rsync://ftp.iasi.roedu.net/ubuntu/(fullmirror)
+http://ftp.lug.ro/ubuntu/(i386andamd64)
+ftp://ftp.lug.ro/ubuntu/(i386andamd64)
+
+#===Russia===
+http://debian.nsu.ru/ubuntu/(i386andamd64)
+ftp://debian.nsu.ru/ubuntu/(i386andamd64)
+
+#===SouthAfrica===
+ftp://ftp.is.co.za/ubuntu
+ftp://ftp.leg.uct.ac.za/pub/linux/ubuntu
+ftp://ftp.sun.ac.za/ftp/ubuntu/
+
+#===Spain===
+ftp://ftp.um.es/mirror/ubuntu/
+ftp://ftp.ubuntu-es.org/ubuntu/
+
+#===Sweden===
+http://ftp.acc.umu.se/mirror/ubuntu/
+ftp://ftp.se.linux.org/pub/Linux/distributions/ubuntu/
+
+#===Switzerland===
+http://mirror.switch.ch/ftp/mirror/ubuntu/
+ftp://mirror.switch.ch/mirror/ubuntu/
+
+#===Taiwan===
+http://apt.ubuntu.org.tw/ubuntu/
+ftp://apt.ubuntu.org.tw/ubuntu/
+http://apt.nc.hcc.edu.tw/pub/ubuntu/
+http://ubuntu.csie.ntu.edu.tw/ubuntu/
+ftp://apt.nc.hcc.edu.tw/pub/ubuntu/
+ftp://os.nchc.org.tw/ubuntu/
+ftp://ftp.ee.ncku.edu.tw/pub/ubuntu/
+rsync://ftp.ee.ncku.edu.tw/ubuntu/
+http://ftp.cse.yzu.edu.tw/ftp/Linux/Ubuntu/ubuntu/
+ftp://ftp.cse.yzu.edu.tw/Linux/Ubuntu/ubuntu/
+
+#===Turkey===
+http://godel.cs.bilgi.edu.tr/mirror/ubuntu/(i386)
+ftp://godel.cs.bilgi.edu.tr/ubuntu/(i386)
+
+#===UnitedKingdom===
+http://www.mirrorservice.org/sites/archive.ubuntu.com/ubuntu/
+ftp://ftp.mirrorservice.org/sites/archive.ubuntu.com/ubuntu/
+http://www.mirror.ac.uk/mirror/archive.ubuntu.com/ubuntu/
+ftp://ftp.mirror.ac.uk/mirror/archive.ubuntu.com/ubuntu/
+rsync://rsync.mirrorservice.org/archive.ubuntu.com/ubuntu/
+http://ubuntu.blueyonder.co.uk/archive/
+ftp://ftp.blueyonder.co.uk/sites/ubuntu/archive/
+
+#===UnitedStates===
+http://mirror.cs.umn.edu/ubuntu/
+http://lug.mtu.edu/ubuntu/
+http://mirror.clarkson.edu/pub/distributions/ubuntu/
+http://ubuntu.mirrors.tds.net/ubuntu/
+http://www.opensourcemirrors.org/ubuntu/
+http://ftp.ale.org/pub/mirrors/ubuntu/
+http://ubuntu.secs.oakland.edu/
+http://mirror.mcs.anl.gov/pub/ubuntu/
+http://mirrors.cat.pdx.edu/ubuntu/
+http://ubuntu.cs.utah.edu/ubuntu/
+http://ftp.ussg.iu.edu/linux/ubuntu/
+http://mirrors.xmission.com/ubuntu/
+http://ftp.osuosl.org/pub/ubuntu/
+http://mirrors.cs.wmich.edu/ubuntu/
+ftp://ftp.osuosl.org/pub/ubuntu/
+ftp://mirrors.xmission.com/ubuntu/
+ftp://ftp.ussg.iu.edu/linux/ubuntu/
+ftp://mirror.clarkson.edu/pub/distributions/ubuntu/
+ftp://ubuntu.mirrors.tds.net/ubuntu/
+ftp://mirror.mcs.anl.gov/pub/ubuntu/
+ftp://mirrors.cat.pdx.edu/ubuntu/
+ftp://ubuntu.cs.utah.edu/pub/ubuntu/ubuntu/
+rsync://ubuntu.cs.utah.edu/ubuntu/
+rsync://mirrors.cat.pdx.edu/ubuntu/
+rsync://mirror.mcs.anl.gov/ubuntu/
+rsync://ubuntu.mirrors.tds.net/ubuntu/
+rsync://mirror.cs.umn.edu/ubuntu/
+