Are there alternative repositories to ports.ubuntu.com for ARM?

I'm using on a Samsung chromebook (with an ARM chip). ports.ubuntu.com is a fairly slow mirror for me. Are there other mirrors that carry the ARM packages?

https://wiki.ubuntu.com/UbuntuDevelopment/PackageArchive#Ports seems to suggest there are none, or at least very few - are there any?


Solution 1:

Yes, there are. Though not many.

I wrote the following script which will parse all the mirrors from the Launchpad mirror list, and check whether they contain the path /dists/$DIST/$REPO/binary-$ARCH/ where

  • $DIST is your Ubuntu distribution, e.g., precise, saucy, trusty, ...
  • $REPO is the repository you're looking for, i.e., main, restricted, universe or multiverse.
  • $ARCH is the architecture you're looking for, e.g., armhf.

For the sake of example let me assume you have Ubuntu 13.10 (Saucy). Then you may want to search the mirrors for the path /dists/saucy/main/binary-armhf/ so as to discover mirrors that offer the main repository for the armhf architecture. If a mirror contains this path, it means that it should have the binary packages for the armhf architecture for the main repository for Saucy Salamander, and the script will output FOUND: along with the mirror's URL.

Please note: the presence of this path on a mirror is not actually a guarantee, but only an indication that it contains the required packages; however if a mirror does contain that path but not the packages, at least we can say that there is something fishy with that mirror.

Also note that the script requires curl. Install it if you do not have it (sudo apt-get install curl).

Thus, using this script, you can quickly find out which mirrors from the Launchpad mirror list offer what you need. Note that the script may run for quite some time since it contacts each and every server on that list. These servers are distributed around the globe and some of them may be slow or unreachable (such that curl may stall until the connection attempt times out). It may easily be improved to scan only certain mirrors (e.g., only in your country), but it's a good starting point.

Edit: Updated for parallel processing, should take about a minute now.

#!/bin/bash

# URL of the Launchpad mirror list
MIRROR_LIST=https://launchpad.net/ubuntu/+archivemirrors

# Set to the architecture you're looking for (e.g., amd64, i386, arm64, armhf, armel, powerpc, ...).
# See https://wiki.ubuntu.com/UbuntuDevelopment/PackageArchive#Architectures
ARCH=$1
# Set to the Ubuntu distribution you need (e.g., precise, saucy, trusty, ...)
# See https://wiki.ubuntu.com/DevelopmentCodeNames
DIST=$2
# Set to the repository you're looking for (main, restricted, universe, multiverse)
# See https://help.ubuntu.com/community/Repositories/Ubuntu
REPO=$3

mirrorList=()
# First, we retrieve the Launchpad mirror list, and massage it to obtain a newline-separated list of HTTP mirrors
for url in $(curl -s $MIRROR_LIST | grep -Po 'http://.*(?=">http</a>)'); do
  mirrorList+=( "$url" )
done

for url in "${mirrorList[@]}"; do
  (
    # If you like some output while the script is running (feel free to comment out the following line)
    echo "Processing $url..."
    # retrieve the header for the URL $url/dists/$DIST/$REPO/binary-$ARCH/; check if status code is of the form 2.. or 3..
    if curl --connect-timeout 1 -m 1 -s --head "$url/dists/$DIST/$REPO/binary-$ARCH/" | head -n 1 | grep -q "HTTP/1.[01] [23]..";
    then
        echo "FOUND: $url"
    fi
  ) &
done

wait

echo "All done!"

I saved the script as find_mirrors, made it executable (chmod 755 find_mirrors), and executed it as follows:

$ ./find_mirrors armhf saucy main | grep FOUND
FOUND: http://ftp.tu-chemnitz.de/pub/linux/ubuntu-ports/

It took around 10-15 minutes for me. I was surprised to find only one mirror for the armhf architecture for Saucy in the Launchpad mirror list, namely the one at TU Chemnitz (this is based in Germany; it may still be faster for you than ports.ubuntu.com which seems to be based in Great Britain.) So it would seem the answer to your question is more like "Yes, there is one alternative mirror for you..." ;-)

The good news is that I did manually check this mirror and it is indeed a complete mirror of ports.ubuntu.com, with all the packages for all alive Ubuntu releases. So, do try it!

Note also that you may have more luck with another release than Saucy.

Alternative (not recommended)

I mention this for the purpose of completeness, but I do not advise this. Instead of looking on the Launchpad mirror list, you can of course also simply google for mirrors.

One way to do this would be to simply google for the string */dists/saucy/main/binary-armhf/* (suit distribution, repository and architecture to your needs as before). This will find many alternative mirrors, but most are not officially registered on Launchpad. Hence there are no quality checks by the Ubuntu mirror team; they may be slow, not regularly updated, or contain only a subset of the packages required by a full Ubuntu system, or even some modified packages. When you think about it, if someone wanted to make their mirror publicly available, they would probably have registered it on Launchpad, and then the above script would have found it. So google for mirrors at your own risk. If you ask me, don't do it.

Solution 2:

Using the script in another answer to find mirrors to use with Ubuntu Touch (xenial armhf), here are my findings:

phablet@ubuntu-phablet:~$ ./find_mirrors.sh armhf xenial main | grep FOUND
FOUND: http://mirror.kumi.systems/ubuntu-ports/
FOUND: http://mirror.exid.us/ubuntu-archive/
FOUND: http://mirror.telcotech.com.kh/Linux/ubuntu-releases/
FOUND: http://mirrors.layeronline.com/ubuntu/
FOUND: http://mirror.rcg.sfu.ca/mirror/ubuntu/
FOUND: http://linux.xjtuns.cn/ubuntu/
FOUND: http://klid.dk/ftp/ubuntu/
FOUND: http://ftp.tu-chemnitz.de/pub/linux/ubuntu-ports/
FOUND: http://www.ubuntu.org.tw/
FOUND: http://kebo.vlsm.org/ubuntu/
FOUND: http://mirror.unej.ac.id/ubuntu/
FOUND: http://ir.ubuntu.sindad.cloud/ubuntu/
FOUND: http://twitchdarkbot.com/ubuntu-ports/
FOUND: http://ftp.daum.net/ubuntu/
FOUND: http://ntc.net.np/ubuntu/
FOUND: http://mirror.chmuri.net/ubuntu/
FOUND: http://cesium.di.uminho.pt/pub/ubuntu-archive/
FOUND: http://ubuntu.mirror.ac.za/ubuntu-archive/
FOUND: http://dafi.inf.um.es/ubuntu/
FOUND: http://mirrors.c0urier.net/linux/ubuntu/
FOUND: http://ubuntu.vargonen.com/ubuntu/
FOUND: http://mirrors.coreix.net/ubuntu/
FOUND: http://mirrors.us.kernel.org/ubuntu/
FOUND: http://lug.mtu.edu/ubuntu/
FOUND: http://mirrors.avalonhosting.services/ubuntu-archive/
FOUND: http://mirror.vcu.edu/pub/gnu+linux/ubuntu/

phablet@ubuntu-phablet:~$ ./find_mirrors.sh armhf xenial universe | grep FOUND
FOUND: http://mirror.kumi.systems/ubuntu-ports/
FOUND: http://mirror.exid.us/ubuntu-archive/
FOUND: http://mirror.telcotech.com.kh/Linux/ubuntu-releases/
FOUND: http://mirrors.layeronline.com/ubuntu/
FOUND: http://mirror.rcg.sfu.ca/mirror/ubuntu/
FOUND: http://klid.dk/ftp/ubuntu/
FOUND: http://ftp.tu-chemnitz.de/pub/linux/ubuntu-ports/
FOUND: http://www.ubuntu.org.tw/
FOUND: http://kebo.vlsm.org/ubuntu/
FOUND: http://mirror.unej.ac.id/ubuntu/
FOUND: http://ir.ubuntu.sindad.cloud/ubuntu/
FOUND: http://twitchdarkbot.com/ubuntu-ports/
FOUND: http://ftp.daum.net/ubuntu/
FOUND: http://ntc.net.np/ubuntu/
FOUND: http://mirror.chmuri.net/ubuntu/
FOUND: http://cesium.di.uminho.pt/pub/ubuntu-archive/
FOUND: http://ubuntu.mirror.ac.za/ubuntu-archive/
FOUND: http://dafi.inf.um.es/ubuntu/
FOUND: http://mirrors.c0urier.net/linux/ubuntu/
FOUND: http://mirrors.coreix.net/ubuntu/
FOUND: http://mirrors.us.kernel.org/ubuntu/
FOUND: http://lug.mtu.edu/ubuntu/
FOUND: http://mirrors.avalonhosting.services/ubuntu-archive/
FOUND: http://mirror.vcu.edu/pub/gnu+linux/ubuntu/

phablet@ubuntu-phablet:~$ ./find_mirrors.sh armhf xenial multiverse | grep FOUND
FOUND: http://mirror.kumi.systems/ubuntu-ports/
FOUND: http://mirror.exid.us/ubuntu-archive/
FOUND: http://mirror.telcotech.com.kh/Linux/ubuntu-releases/
FOUND: http://mirrors.layeronline.com/ubuntu/
FOUND: http://mirror.rcg.sfu.ca/mirror/ubuntu/
FOUND: http://klid.dk/ftp/ubuntu/
FOUND: http://ftp.tu-chemnitz.de/pub/linux/ubuntu-ports/
FOUND: http://kebo.vlsm.org/ubuntu/
FOUND: http://mirror.unej.ac.id/ubuntu/
FOUND: http://ir.ubuntu.sindad.cloud/ubuntu/
FOUND: http://twitchdarkbot.com/ubuntu-ports/
FOUND: http://ftp.daum.net/ubuntu/
FOUND: http://ntc.net.np/ubuntu/
FOUND: http://mirror.chmuri.net/ubuntu/
FOUND: http://cesium.di.uminho.pt/pub/ubuntu-archive/
FOUND: http://ubuntu.mirror.ac.za/ubuntu-archive/
FOUND: http://dafi.inf.um.es/ubuntu/
FOUND: http://mirrors.c0urier.net/linux/ubuntu/
FOUND: http://mirrors.coreix.net/ubuntu/
FOUND: http://mirrors.us.kernel.org/ubuntu/
FOUND: http://lug.mtu.edu/ubuntu/
FOUND: http://mirrors.avalonhosting.services/ubuntu-archive/
FOUND: http://mirror.vcu.edu/pub/gnu+linux/ubuntu/

Solution 3:

The above script by Malte Skoruppa and Can Özokur works well, however it will create 566+ new Bash processes when you run it, while also making 566+ simultaneous network connections, which can overwhelm low-powered machines and poor connections.

You can rate limit the number of concurrent jobs and network connections with GNU parallel, like in the example below.

Here's a script that checks Ubuntu repositories and implements rate limiting:

#!/usr/bin/env bash
# Requires: Bash, GNU grep and parallel, htmlq, and httpie or xh.
# Usage: 
#        ./find-mirrors.sh ARCH DISTRO REPOSITORY PROTOCOL JOBS
# Example: 
#        ./find-mirrors.sh armhf focal main https 6
#
# Copyright 2022 Alex DeLorenzo. Licensed under the GPLv3.
#
export ARCH="${1:-amd64}"
export DISTRO="${2:-focal}"
export REPOSITORY="${3:-main}"
export PROTOCOL="${4:-http}"
export JOBS="${5:-4}"

export URL_PATH="dists/$DISTRO/$REPOSITORY/binary-$ARCH/"
export LIST_URL="https://launchpad.net/ubuntu/+archivemirrors/"
export SELECTOR="#mirrors_list > tbody > tr > td:nth-child(2) > a"
export TIMEOUT=10

export RC_MISSING_DEPS=1
export NO_PARALLEL="GNU parallel is missing, installing with apt...\n"
export NO_HTMLQ="You need to install htmlq: https://github.com/mgdm/htmlq\n"


quiet() {
  $@ &> /dev/null
}
export -f quiet


exists() {
  quiet which $@
}


getDependencies() {
  exists parallel || {
    printf "%s" "$NO_PARALLEL"
    sudo apt install parallel
  }

  exists xh || exists http ||
    python3 -m pip install --upgrade httpie &&
    export http=http ||
      return $RC_MISSING_DEPS

  exists xh &&
    export http=xh

  exists htmlq || {
    printf "%s" "$NO_HTMLQ"
    return $RC_MISSING_DEPS
  }
}


getMirrors() {
  $http --body --follow "$LIST_URL" \
    | htmlq "$SELECTOR" --attribute href \
    | grep -i "$PROTOCOL:"
}


checkRepo() {
  local url="$1"

  quiet $http "$url" \
    --quiet --quiet \
    --timeout $TIMEOUT \
    --verify=no \
    --ignore-stdin \
    --follow \
    --headers \
    --check-status
}
export -f checkRepo


testMirror() {
  local url="$1"
  local repoUrl="$url/$URL_PATH"

  checkRepo "$repoUrl" &&
    printf "Valid: %s\n" "$url"
}
export -f testMirror


testMirrors() {
  parallel --will-cite --jobs "$JOBS" testMirror
}


main() {
  getDependencies &&
    getMirrors | testMirrors
}


main

See: https://gist.github.com/alexdelorenzo/8cdb21718c2d2d3f5f8beaad0bf6c843

It requires the following packages: bash, parallel, htmlq, and httpie

Here's the syntax:

./find-mirrors.sh ARCH DISTRO REPOSITORY PROTO JOBS

If you want to find alternatives for armhf architectures, you can do this:

./find-mirrors.sh armhf jammy main http 6