Browse code

Add implementation

Robert Cranston authored on 08/05/2026 23:30:11
Showing 2 changed files

... ...
@@ -6,6 +6,23 @@ Print and check availability of latest versions of [Linux][] [distro][] images.
6 6
 [Linux]: https://en.wikipedia.org/wiki/Linux
7 7
 [distro]: https://en.wikipedia.org/wiki/Linux_distribution
8 8
 
9
+## Usage
10
+
11
+```
12
+distro-url [test] [<distro> [<variant> [<arch> [<mirror>]]]]
13
+```
14
+
15
+-   `test`: Optional verbatim prefix to check that the server responds with a
16
+    non-error code for the [URL][].
17
+-   `<distro>`, `<variant>`, `<arch>`: Optional [glob][]s to match against the
18
+    combinations `distro-url` knows about. All default to `*`, which matches
19
+    everything.
20
+-   `<mirror>`: Optional override of the default server. Probably only useful
21
+    when the above globs only match a single distro.
22
+
23
+[URL]: https://en.wikipedia.org/wiki/URL
24
+[glob]: https://en.wikipedia.org/wiki/Glob_(programming)
25
+
9 26
 ## License
10 27
 
11 28
 Licensed under the [ISC License][] unless otherwise noted, see the
12 29
new file mode 100755
... ...
@@ -0,0 +1,166 @@
1
+#!/bin/sh
2
+set -euC
3
+
4
+# usage: distro-url [test] [<distro> [<variant> [<arch> [<mirror>]]]]
5
+
6
+[ "${1-}" = 'test' ] && shift && test=y || test=
7
+distro="${1-*}"
8
+variant="${2-*}"
9
+arch="${3-*}"
10
+mirror="${4-}"
11
+
12
+case "$distro/$variant" in
13
+  *raspi*) : ${arch:='arm64'}; ext='img.xz'; ;;
14
+  *)       : ${arch:='amd64'}; ext='iso';    ;;
15
+esac
16
+
17
+filter()
18
+{
19
+  for d in $1; do case "$d" in $distro)
20
+  for v in $2; do case "$v" in $variant)
21
+  for a in $3; do case "$a" in $arch)
22
+    echo "$d" "$v" "$a"
23
+  esac; done
24
+  esac; done
25
+  esac; done
26
+}
27
+
28
+main()
29
+{
30
+  {
31
+    filter 'debian'         'netinst inst                                   ' 'amd64 arm64 armhf ppc64el riscv64 s390x'
32
+    filter 'debian'         'standard gnome kde lxqt xfce cinnamon mate lxde' 'amd64                                  '
33
+    filter 'debian'         'raspi                                          ' '      arm64                            '
34
+    filter 'raspios'        'default full lite                              ' '      arm64                            '
35
+    filter 'ubuntu'         'desktop       server                           ' 'amd64                                  '
36
+    filter 'ubuntu'         'desktop-raspi server-raspi                     ' '      arm64                            '
37
+    filter 'edubuntu'       'desktop                                        ' 'amd64                                  '
38
+    filter 'edubuntu'       'desktop-raspi                                  ' '      arm64                            '
39
+    filter 'kubuntu'        'desktop                                        ' 'amd64                                  '
40
+    filter 'lubuntu'        'desktop                                        ' 'amd64                                  '
41
+    filter 'xubuntu'        'desktop                                        ' 'amd64                                  '
42
+    filter 'ubuntucinnamon' 'desktop                                        ' 'amd64                                  '
43
+    filter 'ubuntu-mate'    'desktop                                        ' 'amd64                                  '
44
+    filter 'ubuntu-budgie'  'desktop                                        ' 'amd64                                  '
45
+    filter 'ubuntu-unity'   'desktop                                        ' 'amd64                                  '
46
+    filter 'ubuntustudio'   'desktop                                        ' 'amd64                                  '
47
+    filter 'ubuntukylin'    'desktop                                        ' 'amd64                                  '
48
+    filter 'linuxmint'      'cinnamon mate xfce                             ' 'amd64                                  '
49
+    filter 'opensuse'       'netinst inst                                   ' 'amd64                                  '
50
+    filter 'opensuse'       'gnome kde xfce                                 ' 'amd64                                  '
51
+  } |
52
+  while read d v a
53
+  do
54
+    url="$(url "$d" "$v" "$a")"
55
+    printf '%s %s %s %s' "$d" "$v" "$a" "$url"
56
+    [ "$test" ] && printf ' %s' "$(curl -sfI "$url" > '/dev/null' \
57
+      && echo 'OK' \
58
+      || echo 'Failed'
59
+    )"
60
+    printf '\n'
61
+  done |
62
+  {
63
+    [ "$test" ] && cat || column -t
64
+  }
65
+}
66
+
67
+url()
68
+(
69
+  distro="$1"
70
+  variant="$2"
71
+  arch="$3"
72
+  case "$distro" in
73
+    debian)
74
+      codename='trixie'
75
+      version='13.4.0'
76
+      : ${variant:='gnome'}
77
+      case "$variant" in
78
+        netinst|inst|\
79
+        standard|gnome|kde|lxqt|xfce|cinnamon|mate|lxde)
80
+          # : ${mirror:="https://get.debian.org/images/release"}
81
+          # : ${mirror:="https://cdimage.debian.org/images/release"}
82
+          # : ${mirror:="https://cloud.debian.org/images/release"}
83
+          : ${mirror:="https://cdimage.debian.org/debian-cd"}
84
+          case "$variant" in
85
+            netinst) media='iso-cd';     suffix='';                       ;;
86
+            inst)    media='iso-dvd';    suffix='';      variant='DVD-1'; ;;
87
+            *)       media='iso-hybrid'; suffix='-live';                  ;;
88
+          esac
89
+          dir="$version$suffix/$arch/$media"
90
+          echo "$mirror/$dir/$distro$suffix-$version-$arch-$variant.$ext"
91
+          ;;
92
+        raspi)
93
+          # : ${mirror:="https://get.debian.org/images/cloud"}
94
+          # : ${mirror:="https://cdimage.debian.org/images/cloud"}
95
+          : ${mirror:="https://cloud.debian.org/images/cloud"}
96
+          major="${version%%.*}"
97
+          ext='tar.xz'
98
+          # dir="$codename/latest"
99
+          # echo "$mirror/$dir/$distro-$major-$variant-$arch.$ext"
100
+          dir="$codename/daily/latest"
101
+          echo "$mirror/$dir/$distro-$major-$variant-$arch-daily.$ext"
102
+          ;;
103
+      esac
104
+      ;;
105
+    raspios)
106
+      codename='trixie'
107
+      version='2026-04-21'
108
+      : ${variant:='default'}
109
+      : ${mirror:="https://downloads.raspberrypi.com"}
110
+      case "$variant" in
111
+        default)   name="${distro}_${arch}";            suffix='';          ;;
112
+        full|lite) name="${distro}_${variant}_${arch}"; suffix="-$variant"; ;;
113
+      esac
114
+      dir="$name/images/$name-$version"
115
+      echo "$mirror/$dir/$version-$distro-$codename-$arch$suffix.$ext"
116
+      ;;
117
+    ubuntu|\
118
+    edubuntu|\
119
+    kubuntu|lubuntu|xubuntu|\
120
+    ubuntucinnamon|ubuntu-mate|ubuntu-budgie|ubuntu-unity|\
121
+    ubuntustudio|ubuntukylin)
122
+      codename='resolute'
123
+      version='26.04'
124
+      : ${variant:='desktop'}
125
+      if [ "$distro/$arch" = 'ubuntu/amd64' ]
126
+      then : ${mirror:="https://releases.ubuntu.com"};                 dir="$codename";
127
+      else : ${mirror:="https://cdimage.ubuntu.com/$distro/releases"}; dir="$codename/release";
128
+      fi
129
+      case "$variant" in
130
+        desktop) suffix=''; ;;
131
+        server)  suffix='-live'; ;;
132
+        *-raspi) suffix='-preinstalled'; variant="${variant%%-raspi}"; arch="$arch+raspi"; ;;
133
+      esac
134
+      echo "$mirror/$dir/$distro-$version$suffix-$variant-$arch.$ext"
135
+      ;;
136
+    linuxmint)
137
+      codename='zena'
138
+      version='22.3'
139
+      : ${variant:='cinnamon'}
140
+      : ${mirror:='https://pub.linuxmint.io'}
141
+      case "$arch" in
142
+        amd64) arch='64bit' ;;
143
+      esac
144
+      dir="stable/$version"
145
+      echo "$mirror/$dir/$distro-$version-$variant-$arch.$ext"
146
+      ;;
147
+    opensuse)
148
+      distro='openSUSE'
149
+      codename='Tumbleweed'
150
+      : ${variant:='gnome'}
151
+      : ${mirror:='https://download.opensuse.org'}
152
+      case "$variant" in
153
+        inst)    suffix='';      variant='DVD';                                 ;;
154
+        netinst) suffix='';      variant='NET';                                 ;;
155
+        *)       suffix='-Live'; variant="$(echo "$variant" | tr 'a-z' 'A-Z')"; ;;
156
+      esac
157
+      case "$arch" in
158
+        amd64) arch='x86_64'
159
+      esac
160
+      dir="$codename/iso"; dir="$(echo "$dir" | tr 'A-Z' 'a-z')"
161
+      echo "$mirror/$dir/$distro-$codename-$variant$suffix-$arch-Current.$ext"
162
+      ;;
163
+  esac
164
+)
165
+
166
+main