The ISOs for releases are available when navigating the site starting at
However, for some reason, a peak under “ubuntu-server” shows no link to “releases”, the way others do. We have only daily builds offered.
Is that an oversight?
The ISOs for releases are available when navigating the site starting at
However, for some reason, a peak under “ubuntu-server” shows no link to “releases”, the way others do. We have only daily builds offered.
Is that an oversight?
No, not an oversight. That’s not where main releases are officially found. This is:
E.g. for 26.04, click https://releases.ubuntu.com/26.04/
The server image is linked on the page.
cdimage is and always has been an internal project resource, and not intended to be the main public facing place where users get the most popular ISOs. However, people will often grub around there looking for them, especially just prior to final release day.
What you will find on cdimage is ISOs for other supported architectures, like 64-bit ARM, RISC-V and more, here:
Thank you, Alan.
Darn! That’s unfortunate, because I was hoping to continue using my custom script that simplifies things for me (for both Daily Builds and Releases). Unfortunately, the ubuntu-server hierarchy did not fall under the same “distribution” model for mirroring of those ISO images. I like things clean and regimented. ![]()
Script: UTIL__Distro_GetRelatedDownloads.sh
#!/bin/sh
###
### Version 4.0 - Limited checksum to specific ISO file that was downloaded
###
### Version 3.0 - Updated to incorporate checksum of the ISO file
###
### Version 2.0 - Updated to allow for selection of
### either Daily Build or Production Release
### as well as limited selection of Versions
###
doRelease=0
doTorrent=0
getAll=0
dbg=0
sep="<><><><><><><><><><><><><><><><><><><><>"
mode=""
resume="--continue"
# addSuffix="--adjust-extension"
allSources="--span-hosts"
# makeLocal="--convert-links"
# getParts="--page-requisites"
# getParts="--no-parent -mpEk --user-agent='Mozilla/5.0'" ### This does not work because it downloads too much using -m
while [ $# -gt 0 ]
do
case $1 in
"--release" )
doRelease=1
shift
;;
"--daily" )
doRelease=0
shift
;;
"--torrent" )
doTorrent=1
shift
;;
"--download" )
getAll=1
shift
;;
"--showfiles" )
getAll=2
shift
;;
"--verbose" )
mode="$1"
dbg=1
shift
;;
"--debug" )
mode="$1"
dbg=2
shift
;;
* )
echo "\n\t Invalid option used. Only valid options: [ --download ] | [ --showfiles ] \n" ; exit 1
;;
esac
done
reportCommandComponents()
{
echo "
mode = ${mode}
resume = ${resume}
addSuffic = ${addSuffix}
allSources = ${allSources}
makeLocal = ${makeLocal}
getParts = ${getParts}
localFile = ${localFile}
url_DIR = ${url_DIR}\n"
}
chooseBuild()
{
buildList=$(basename "$0" ".sh" ).buildslist
rm -f buildslist
# ubuntu-base/
# ubuntu-core-desktop/
# ubuntu-core-installer/
# ubuntu-core/
# ubuntu-unity/
# ubuntu-wsl/
# ubuntukylin/
echo "\n NOTES:
Download of Daily Builds is the default setting (--daily flag).
To download production releases, run with '--release' flag.
if the '--torrent' flag is set on the command line,
downloading of the *.iso file will be suppressed.
Choose which ${scope} BUILD you wish to download ...
[1] ubuntu-mate
[2] ubuntu (Gnome)
[3] edubuntu
[4] kubuntu
[5] lubuntu
[6] xubuntu
[7] ubuntu-budgie
[8] ubuntucinnamon
[9] ubuntustudio"
if [ ${doRelease} -eq 0 ]
then
echo "
[10] ubuntu-mini-iso
[11] ubuntu-server"
fi
echo "
[Q] Quit
Enter selection [${choiceRange}|Q] => \c" ; read ans
if [ -z "${ans}" ] ; then ans="Q" ; fi
case "${ans}" in
1 ) isoBuild="ubuntu-mate" ;;
2 ) isoBuild="ubuntu" ;;
3 ) isoBuild="edubuntu" ;;
4 ) isoBuild="kubuntu" ;;
5 ) isoBuild="lubuntu" ;;
6 ) isoBuild="xubuntu" ;;
7 ) isoBuild="ubuntu-budgie" ;;
8 ) isoBuild="ubuntucinnamon" ;;
9 ) isoBuild="ubuntustudio" ;;
10 ) isoBuild="ubuntu-mini-iso" ;;
11 ) isoBuild="ubuntu-server" ;;
q* | Q* ) echo "" ; exit ;;
esac
} #chooseBuild_Daily()
getBuildsVersion()
{
#https://cdimage.ubuntu.com/xubuntu/releases/26.04/release/
#https://cdimages.ubuntu.com/xubuntu/releases/26.04/release/
url_DIR="https://cdimages.ubuntu.com/${isoBuild}/releases/"
localFile="-O ${localVers}"
#rm -f ${localName}
if [ -s "${localVers}" ]
then
echo "\n Using existing file '${localVers}' ..."
else
echo "\n${sep}${sep}${sep}\n Downloading information page for ${scope} ISO build '${isoBuild}' ...\n"
test ${dbg} -eq 2 && \
echo " COMMAND: wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} ${localFile} '${url_DIR}'"
wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} ${localFile} "${url_DIR}"
if [ $? -gt 0 ]
then
echo "\n\t Unable to proceed because a list of versions is not available for that ISO build.\n" ; exit 1
fi
fi
#more "${localVers}"
thisYear=$(date '+%y' )
thisMth=$(date '+%m' )
rm -f ${jobList}
rm -f ${jobList}.full
#echo $thisYear $thisMth
awk 'BEGIN{
pr=0 ;
}{
if( pr == 1 ){
print $0 ;
if( $0 ~ /<[/]ul>/ ){
exit ;
} ;
}else{
if( $0 ~ /<ul>/ ){
pr=1 ;
print $0 ;
} ;
} ;
}' <${localVers} | grep '[1-9]' |
awk '{
pos=index( $0, "<li><a href=\"" ) ;
if( pos > 0 ){
rem=substr( $0 , pos+13 ) ;
#print rem ;
posE=index( rem, "\">" ) ;
printf("%s\n", substr( rem , 1, posE-2 ) ) ;
} ;
}' | sort -r > ${jobList}.full
if [ -s ${jobList}.full ]
then
test ${dbg} -eq 2 && {
echo " == DEBUG == RAW LIST OF VERSIONS AVAILABLE ===" ;
awk '{ printf("\t | %s\n", $0 ) ; }' <${jobList}.full ;
echo "" ; }
else
echo "\n ABORT ... Could not identify the associated versions for the ${scope} ISO builds."
echo " Process Abandonned!\n"
exit 1
fi
awk -v yr="${thisYear}" -v mth="${thisMth}" '{
ref=0.0+sprintf("%02d.%02d", yr, mth ) ;
lst=ref-2.5 ;
if( $1 < ref && $1 >= lst ){
print $0 ;
} ;
}' <${jobList}.full >${jobList}
if [ -s ${jobList} ]
then
test ${dbg} -eq 2 && {
echo " == DEBUG == REDUCED SET OF VERSIONS AVAILABLE ===" ;
awk '{ printf("\t | %s\n", $0 ) ; }' <${jobList} ;
echo "" ; }
else
echo "\n ABORT ... Could not identify the associated versions for the ${scope} ISO builds."
echo " Process Abandonned!\n"
exit 1
fi
echo "\n The following are the available ${scope} ISO build versions available:\n"
awk '{ printf("\t %s\n", $0 ) ; }' <${jobList}
echo "\n Please enter your choice of ${scope} version => \c" ; read buildVers
if [ -z "${buildVers}" ]
then
echo "\n ABORT ... No selection entered!\n"
echo " Process Abandonned!\n"
exit 2
fi
testor=$(grep '^'${buildVers}'$' ${jobList} )
if [ -n "${testor}" ]
then
test ${dbg} -eq 2 && echo "\n DEBUG ... version = ${testor} "
else
echo "\n ABORT ... Version '${buildVers}' entered is not available."
echo " Process Abandonned!\n"
exit 2
fi
} #getBuildsVersion()
getBuildsInfo()
{
echo "\n${sep}${sep}${sep}\n Downloading checksum files for ISO build '${isoBuild}' ...\n"
wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} "${url_DIR}/SHA256SUMS"
echo "\n${sep}${sep}${sep}\n"
wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} "${url_DIR}/SHA256SUMS.gpg"
echo ""
buildLabel=$(head -1 SHA256SUMS | awk '{ print $2 ; exit }' | sed 's+^[*]++' | sed 's+[.]iso$++' )
echo "\n Shared identifier string for ISO build files: '${buildLabel}' ..."
} #getBuildsInfo()
getBuildsList()
{
rm -f ${jobList}
if [ -s "${localName}" ]
then
echo "\n Using existing file '${localName}' ..."
else
reportCommandComponents
echo "\n${sep}${sep}${sep}\n Downloading information page for ISO build '${isoBuild}' ...\n"
test ${dbg} -eq 2 && \
echo " COMMAND: wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} ${localFile} '${url_DIR}'"
wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} ${localFile} "${url_DIR}"
fi
pageTitle=$(awk 'BEGIN{
capt=0 ;
strng="" ;
}{
if( capt == 1 ){
posE=index( $0, "</title>" ) ;
if( posE > 0 ){
pends=substr( $0, 1, posE-1 ) ;
printf("%s%s\n", strng, pends ) ;
exit ;
}else{
strng=sprintf("%s%s", strng, $0 ) ;
} ;
}else{
posS=index( $0, "<title>" ) ;
if( posS > 0 ){
capt=1 ;
strng=substr( $0, posS+7 ) ;
} ;
posE=index( strng, "</title>" ) ;
if( posE > 0 ){
strng=substr( strng, 1, posE-1 ) ;
printf("%s\n", strng ) ;
exit ;
} ;
} ;
}' <"${localName}" )
echo "\n\n\n${sep}${sep}${sep}\n${sep}${sep}${sep}\n\n BANNER: ${pageTitle}\n"
awk 'BEGIN{
pr=0 ;
}{
if( pr == 1 ){
print $0 ;
if( $0 ~ /<[/]table>/ ){
exit ;
} ;
}else{
if( $0 ~ /<table>/ ){
pr=1 ;
print $0 ;
} ;
} ;
}' <${localName} | grep '/cdicons/' |
awk -v prefix="${url_DIR}" '{
pos=index( $0, "<td><a href=\"" ) ;
if( pos > 0 ){
rem=substr( $0 , pos+13 ) ;
#print rem ;
posE=index( rem, "\">" ) ;
printf("%s%s\n", prefix, substr( rem , 1, posE-1 ) ) ;
} ;
}' >${jobList}
grep '/SHA256SUMS' ${jobList} >${jobList}.reduced
grep -v '/SHA256SUMS' ${jobList} | grep "${buildLabel}" >>${jobList}.reduced
mv ${jobList}.reduced ${jobList}
} #getBuildsList()
reviewContinue()
{
echo "\n ISO build '${isoBuild}' lists the following associated files:"
awk '{ printf("\t | %s\n", $0 ) ; }' <${jobList}
case ${getAll} in
0 ) echo "\n Proceed with download of all files identified? [y|N] => \c" ; read ans
if [ -z "${ans}" ] ; then ans="N" ; fi
;;
1 ) ans="y" ;;
2 ) ans="N" ;;
esac
} #reviewContinue()
getBuildsComp()
{
case "${ans}" in
y* | Y* )
for suf in iso iso.zsync list manifest
do
if [ ${suf} = "iso" -a ${doTorrent} -eq 1 ]
then
suf="torrent"
fi
item="${buildLabel}.${suf}"
testor=$(grep "${item}" ${jobList} )
if [ -n "${testor}" ]
then
echo "\n${sep}${sep}${sep}\n Downloading build file '${buildLabel}.${suf}' ..."
test ${dbg} -eq 2 && \
echo " COMMAND: wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} '${url_DIR}/${buildLabel}.${suf}'\n"
wget ${mode} ${resume} ${addSuffix} ${allSources} ${makeLocal} ${getParts} "${url_DIR}/${buildLabel}.${suf}"
if [ $? -ne 0 ]
then
echo " File '${buildLabel}.${suf}' was missing ... or failed to download ..."
if [ "${suf}" = "iso" ]
then
test -s "${buildLabel}.${suf}" && echo "\t Retaining partial download for later re-attempt ..."
ls -l "${buildLabel}.${suf}" | awk '{ printf("\t %s\n", $0 ) ; }'
else
rm -i "${buildLabel}.${suf}"
fi
fi
else
echo " NOTE: File '${buildLabel}.${suf}' is not listed as an ISO build related item ..."
fi
done
;;
* ) echo "\n That list of files has been saved in '${jobList}'.\n" ; exit ;;
esac
} #getBuildsComponent()
verifyISO()
{
#set -x
# resolute-live-server-amd64.iso: OK
isoFile=$(ls -dtr *.iso | head -1 )
grep "${isoFile}" SHA256SUMS >SHA256SUMS_this
chkMsgs="${buildLabel}.checksums"
if [ $(sha256sum -c SHA256SUMS_this 2>"${chkMsgs}" | grep "${buildLabel}.${suf}" |
awk '{ if( $2 == "OK" ){ print $2 ; } ; }' ) = "OK" ]
then
echo "\n Download of image '${buildLabel}.${suf}' was successful."
if [ -s "${chkMsgs}" ]
then
echo "\n Other messages generated by 'sha256sum':"
awk '{ printf("\t | %s\n", $0 ) ; }' <"${chkMsgs}"
fi
echo ""
exit 0
else
echo "\n Checksum for '${buildLabel}.${suf}' image FAILED!\n"
exit 1
fi
#set +x
}
####################################################
### This section not tested or integrated
####################################################
getArchBits()
{
thisArch=$( inxi -C 2>&1 |
awk -v dbg="${dbg}" '{
if( $1 == "Info:" ){
posA=index( $0, "model:" ) ;
posB=index( $0, "bits:" ) ;
remA=substr( $0, posA, posB-(posA) ) ;
remB=substr( $0, posB ) ;
if( dbg == 1 ){ print remA | "cat 1>&2" } ;
if( dbg == 1 ){ print remB | "cat 1>&2" } ;
n=split( remA, vals ) ;
arch=tolower(vals[2]) ;
n=split( remB, vals ) ;
bits=vals[2] ;
printf("%s%s\n", arch, bits ) ;
exit ;
} ;
}' )
}
################################################
jobList=$(basename "$0" ".sh" ).joblist
rm -f jobList
if [ ${doRelease} -eq 1 ]
then
scope="Release"
choiceRange="1-9"
chooseBuild
localVers="${isoBuild}_versions.html"
localFile="-O ${localName}"
getBuildsVersion
#url_DIR="https://cdimage.ubuntu.com/${isoBuild}/releases/${buildVers}/release/"
url_DIR="https://cdimages.ubuntu.com/${isoBuild}/releases/${buildVers}/release/"
test ${dbg} -eq 2 && { echo "\t DEBUG ... url_DIR = ${url_DIR}" ; }
else
scope="Daily"
choiceRange="1-11"
chooseBuild
url_DIR="https://cdimages.ubuntu.com/${isoBuild}/daily-live/current/"
test ${dbg} -eq 2 && { echo "\t DEBUG ... url_DIR = ${url_DIR}" ; }
fi
localName="${isoBuild}_details.html"
localFile="-O ${localName}"
getBuildsInfo
getBuildsList
reviewContinue
getBuildsComp
verifyISO
exit 0
exit 0
exit 0
P.S. I even thought about incorporating the “arch” option, but haven’t done that, although I did already discuss it over under UbuntuMATE. ![]()
Oh, if it’s just a script for personal use, or for the community of contributors, it’s probably fine, and you could patch it to get the server ISOs from the releases site, I guess.
There’s always been a reluctance to promote the use of cdimage because it’s not mirrored, and doesn’t have the same resources as other servers. Also, good one using zsync ![]()
This topic was automatically closed 18 hours after the last reply. New replies are no longer allowed.