diff options
| author | Sebastian Heinlein <sebastian.heinlein@web.de> | 2006-04-29 15:53:42 +0200 |
|---|---|---|
| committer | Sebastian Heinlein <sebastian.heinlein@web.de> | 2006-04-29 15:53:42 +0200 |
| commit | 4e093f33b5e9da902a69fc8bdf0fd2109a31c2d5 (patch) | |
| tree | 54cc2932cb71aded4e39a71653dea7b540304049 /DistUpgrade | |
| parent | d19de868ff0230aebfc0920bd31caa64d51ec920 (diff) | |
| parent | dc3dc10c9a2835ffef5708db35dd70344860adab (diff) | |
| download | python-apt-4e093f33b5e9da902a69fc8bdf0fd2109a31c2d5.tar.gz | |
* merged from mvo
Diffstat (limited to 'DistUpgrade')
| -rw-r--r-- | DistUpgrade/Changelog | 17 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgrade.cfg | 2 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeConfigParser.py | 10 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeControler.py | 110 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeView.py | 4 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeViewGtk.py | 37 | ||||
| -rw-r--r-- | DistUpgrade/TODO | 21 | ||||
| -rw-r--r-- | DistUpgrade/mirrors.txt | 278 |
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/ + |
