pointrelease 15.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#!/bin/bash
# No way I try to deal with a crippled sh just for POSIX foo.

# Copyright (C) 2009-2016 Joerg Jaspert <joerg@debian.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# exit on errors
set -e
# A pipeline's return status is the value of the last (rightmost)
# command to exit with a non-zero status, or zero if all commands exit
# successfully.
set -o pipefail
# make sure to only use defined variables
set -u
# ERR traps should be inherited from functions too. (And command
# substitutions and subshells and whatnot, but for us the functions is
# the important part here)
set -E

# If the extglob shell option is enabled using the shopt builtin,
# several extended pattern matching operators are recognized. We use
# it for the POSSIBLEARGS and the first case ${ARGS} matching.
shopt -s extglob

# And use one locale, no matter what the caller has set
export LANG=C.UTF-8
export LC_ALL=C.UTF-8

# If run from crontab, CONFIGDIR will point to the correct dir
# where we find the vars file
configdir=${configdir:-"/srv/ftp-master.debian.org/dak/config/debian"}
# import the general variable set. (This will overwrite configdir, but
# it is expected to have the same value)
export SCRIPTVARS=${configdir}/vars
. "${SCRIPTVARS}"
48
. "${configdir}/common"
49 50 51 52
. "${configdir}/dinstall.functions"
umask 022

# Get rid of tempfiles at the end
53 54 55 56
cleanup() {
    echo "You have to clean up your mess on your own. Sorry." >&2
    exit 1
}
57 58
trap cleanup EXIT TERM HUP INT QUIT

59 60
suitename_default=$(psql -qAtc "SELECT codename FROM suite WHERE suite_name='stable'")

61 62 63
function usage() {
    echo "Fun with a pointrelease"
    echo "Takes two args, suite and version"
64
    echo "Default for suite is ${suitename_default}, version defaults to last plus one"
65 66
}

67 68 69 70 71 72 73
confirm() {
    local y=N
    while [ "${y}" != "y" ]; do
        read -p "Continue [y/N]?" y
    done
}

74 75 76 77 78 79
# Arguments, we like
while getopts ":hs:v:" OPTION; do
    case ${OPTION} in
        s) # suite
            suitename="${OPTARG}"
            ;;
A
Ansgar Burchardt 已提交
80
        v) # version
81
            newrev="${OPTARG}"
82 83 84 85 86 87 88 89 90 91 92 93 94
            ;;
        h) # help
            usage
            exit 0
            ;;
        ?)
            echo "Unknown option ${OPTION} given, try -h"
            exit 42
            ;;
    esac
done

# Set some variables
95
suitename=${suitename:-${suitename_default}}
96 97
suite=$(psql -qAtc "SELECT suite_name FROM suite WHERE codename='${suitename}'")
oldrev=$(psql -qAtc "SELECT version FROM suite WHERE codename='${suitename}'")
98
newrev=${newrev:-${oldrev%.*}.$(( ${oldrev##*.} + 1 ))}
99
release_base=https://release.debian.org/proposed-updates/${newrev%%.*}/${newrev}
100 101 102 103 104 105 106 107 108
PROGRAM="pointrelease_${suitename}"

# Set some variables
case "${suite}" in
  stable)    pusuite=proposed-updates ;;
  oldstable) pusuite=oldstable-proposed-updates ;;
  *)         pusuite=INVALID ;;
esac

109 110
wget="wget --ca-directory=/etc/ssl/ca-debian"

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
# set DEBUG if you want to see a little more logs
DEBUG=${DEBUG:-0}

# common functions are "outsourced"
. "${configdir}/common"

# Timestamp when we started
NOW=$(date "+%Y.%m.%d-%H:%M:%S")

log "Point release for ${suite} (${suitename}); old version: ${oldrev}, new: ${newrev}"
log "Updates come from ${pusuite}"

cd ~
mkdir -p ${suitename}_${newrev}
cd ${suitename}_${newrev}
126

A
Ansgar Burchardt 已提交
127
echo "Is there anything to skip in this release? If so, please enter source package names, whitespace separated, if not just hit enter"
128 129 130 131 132
read -e -p "Source packages: " skiplist
confirm

log "Preparing"
pg_timestamp pre_${suite}_${newrev}
133 134 135 136 137 138 139 140 141 142 143

control-suite-list() {
    local s="${1:?}"
    if [[ ! -f ${s}.list ]]; then
        dak control-suite -l ${s} > ${s}.list &
    fi
}
control-suite-list ${pusuite}
control-suite-list ${suite}
control-suite-list ${pusuite}-debug
control-suite-list ${suite}-debug
144
wait
145 146

if [[ -n ${skiplist} ]]; then
147 148
  for s in ${pusuite} ${pusuite}-debug; do
    mv ${s}.list ${s}.list.ori
149
    grep -vFf <(dak ls -f heidi -S -s ${s} ${skiplist}) ${s}.list.ori > ${s}.list
150
  done
151 152
fi

153 154 155 156 157 158 159 160 161 162 163 164 165
edit-changelog() {
    local prompt="${1:?}"
    shift

    if [ -n "${prompt}" ]; then
        echo "${prompt}"
        confirm
    fi

    $EDITOR "${ftpdir}/dists/${suite}/ChangeLog" "${@}"
    rm -f -- "${ftpdir}/dists/${suite}/ChangeLog~" "${ftpdir}/dists/${suite}/#ChangeLog#"
}

166 167 168 169 170 171
log "Creating changelog"
tmpfile=$(mktemp -p "${TMPDIR}" changelog.XXXXXX)
dak make-changelog -s ${pusuite} -b ${suite} | cat - ${ftpdir}/dists/${suite}/ChangeLog > ${tmpfile}
chmod 0644 ${tmpfile}
mv ${tmpfile} ${ftpdir}/dists/${suite}/ChangeLog
if [[ -n ${skiplist} ]]; then
172
    edit-changelog "Please edit to remove the changelogs for the skipped packages"
173 174
fi

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
merge-suite() {
    local source="${1:?}"
    local target="${2:?}"

    log "Merging ${source} into ${target}"
    while :; do
        if dak control-suite --add ${target} < ${source}.list; then
            log "Done"
            break
        else
            log "Please check problem and hit enter when i can retry"
            read
        fi
    done
}
J
Joerg Jaspert 已提交
190

191 192
merge-suite ${pusuite} ${suite}
merge-suite ${pusuite}-debug ${suite}-debug
M
Mark Hymers 已提交
193

194
log "Cleaning ${pusuite} and ${pusuite}-debug"
195
dak control-suite --remove ${pusuite} < ${pusuite}.list
196
dak control-suite --remove ${pusuite}-debug < ${pusuite}-debug.list
197

198
log "Cleaning changelogs from ${pusuite}"
199 200 201 202 203 204
pumorguedir="${base}/morgue/queues/$(date +%Y/%m)"
mkdir -p "${pumorguedir}"
cd ${ftpdir}/dists/${pusuite}
mv -t "${pumorguedir}" -n -- *.changes
if [[ -n ${skiplist} ]]; then
    for pack in ${skiplist}; do
M
Mark Hymers 已提交
205 206 207 208 209 210
        # In corner cases, we may not have the changes file to move back - don't crash
        if compgen -G ${pumorguedir}/${pack}_*.changes >/dev/null; then
            mv -t "${ftpdir}/dists/${pusuite}" ${pumorguedir}/${pack}_*.changes
        else
            echo 'W: No changes files for ${pumorguedir}/${pack}_*.changes - check this is expected'
        fi
211 212 213 214 215
    done
fi

log "Checking for r0 additions and propups"
cd ~/${suitename}_${newrev}
216

217 218
propups() {
    local target_suite="${1}"
219
    local f="${2:-propups.${target_suite}}"
220
    if ${wget} -O "${f}" "${release_base}/${f}"; then
221
        echo "Please check ${f} (will open an editor for you)"
222
        confirm
223
        $EDITOR ${f}
224
        dak control-suite --force --add ${target_suite} < ${f}
225 226
    fi
}
227

228
propups ${suitename}-r0 ${suitename}-r0-additions.cs
229
propups unstable
230
propups unstable-debug
231
propups testing
232
propups testing-debug
233

234 235 236 237
log "Override changes"
echo "Any override changes? If so, process them in another window."
confirm

238
log "RM time"
239 240
hadrms=0

241
if ${wget} -O "removallist" "${release_base}/removals.${suitename}"; then
242
    echo "Please check removallist file, I am going to run it as shell script when you confirm (will open an editor for you)"
243 244 245
    confirm
    $EDITOR removallist
    bash removallist
246 247 248
    if [ -s removallist ]; then
        hadrms=1
    fi
249 250 251
fi

echo "Any more removals to be done?"
252
echo "If nothing - or done, just end with an empty line"
253

J
Joerg Jaspert 已提交
254 255
# Blindly ignore errors in dak rm
set +e
256 257 258
while :; do
    read -e -p "RM command: " -i "dak rm -s ${suite} -R -p -d ### -m '###' ###" dakrmcmd
    if [[ -n ${dakrmcmd} ]]; then
259
        eval "${dakrmcmd}"
260 261 262 263 264 265
        hadrms=1
        continue
    else
        break
    fi
done
J
Joerg Jaspert 已提交
266
set -e
267 268

if [[ ${hadrms} -ne 0 ]]; then
269
    edit-changelog "You did some removals, please copy their entries into the changelog (will open an editor for you)" ${webdir}/removals.txt
270 271 272 273 274 275
fi

log "Checking for d-i updates"
echo "Are there d-i updates? Empty version string, if not."
echo "Seperate old version to move to morgue by space."
read -e -p "d-i updates: " diver dioldver
276
confirm
277 278 279 280

if [[ -n ${diver} ]]; then
    log "Installing new d-i version ${diver}"
    dak copy-installer -s ${pusuite} -d ${suite} ${diver}
281 282 283 284 285 286 287 288
    # Remove new version from proposed-updates
    cd $ftpdir/dists/${pusuite}/main
    for iarch in $(dak admin s-a list-arch ${suite}); do
        rm -rf -- "installer-${iarch}/${diver}"
        if [[ -L install-${iarch}/current && "$(readlink install-${iarch}/current)" = "${diver}" ]]; then
            rm install-${iarch}/current
        fi
    done
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314

    if [[ -n ${dioldver} ]]; then
        log "Moving old d-i version ${dioldver} to morgue"
        cd $ftpdir/dists/${suite}/main
        for iarch in $(dak admin s-a list-arch ${suite}); do
            if [[ -d installer-${iarch}/${dioldver} ]]; then
                echo "Moving installer-${iarch}/${dioldver} to morgue"
                mkdir -p "${base}/morgue/d-i/installer-${iarch}/"
                mv "installer-${iarch}/${dioldver}" "${base}/morgue/d-i/installer-${iarch}/"
            fi
        done

        # Remove old version also from proposed-updates
        cd $ftpdir/dists/${pusuite}/main
        for iarch in $(dak admin s-a list-arch ${suite}); do
            rm -rf -- "installer-${iarch}/${dioldver}"
        done
    fi
    cd $ftpdir/dists/${suite}
fi

log "Checking for win32-loader"
echo "If anything for win32-loader, enter any string, otherwise empty"
read -e -p "win32-loader?" win32loader
if [[ -n ${win32loader} ]]; then
    cd ${ftpdir}/tools/win32-loader
315
    if [ -d ${pusuite} ]; then
316
        rm -r ${suite}
317
        mv ${pusuite} ${suite}
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
    fi
    cd ${ftpdir}
fi

log "Updating version numbers in readmes, fixing Changelog"
cd ${ftpdir}/dists/${suite}

date_long=$(date "+%A, %-dth %B %Y" | sed 's/1th/1st/; s/2th/2nd/; s/3th/3rd/')
date_iso=$(date "+%Y-%m-%d")
date_short=$(date "+%a, %d %b %Y")
sed -e "1i======================================\n${date_short} - Debian ${newrev} released\n======================================" -i ChangeLog
sed -e "/^${suite}/ s/Debian ${oldrev}/Debian ${newrev}/" -i ../README
sed -e "s/Debian ${oldrev}/Debian ${newrev}/g; /Debian ${newrev}/ s/released .*\\./released ${date_long}./" -i ../../README
sed -e "s/Debian ${oldrev}/Debian ${newrev}/g; /Debian ${newrev}/ s/released .*\\./released ${date_long}./; /meta name=\"Modified\"/ s/content=\".*\"/content=\"${date_iso}\"/" -i ../../README.html

echo "Now check if it looks good"
for f in README README.html dists/README dists/${suite}/ChangeLog; do
335
  diff -u ${mirrordir}/ftp-master/${f} ${ftpdir}/${f} || :
336
done
337
read -e -p "Does the diff look ok? Enter anything if not, empty if yes (if nonempty, I will open an editor for you)" diffcheck
338 339
if [[ -n ${diffcheck} ]]; then
    cd ${ftpdir}/dists/${suite}
M
Mark Hymers 已提交
340
    edit-changelog "Opening changelog" ../README ../../README ../../README.html
A
Ansgar 已提交
341
    rm -f -- ./*~ ../*~ ../../*~ ./"#"*"#" ../"#"*"#" ../../"#"*"#"
342 343 344 345 346 347 348 349 350 351 352
fi

log "Updating the Debianx.y symlink"
cd $ftpdir/dists/
rm -f Debian${oldrev}
ln -s ${suitename} Debian${newrev}

log "Updating suite table in postgres"
mdate=$(date +"%d %B %Y")
psql projectb <<EOF
begin;
353
update suite set version = '${newrev}' where suite_name = '${suite}' or suite_name = '${suite}-debug';
354
update suite set description = 'Debian ${newrev} Released ${mdate}' where suite_name = '${suite}';
355
update suite set description = 'Debian ${newrev} Released ${mdate} - Debug Information' where suite_name = '${suite}-debug';
356 357 358 359 360 361 362 363 364 365
commit;
EOF

log "Preparing for gps, domination/cruft-report time"
hadremove=0
while :; do
    log "dominate"
    dak dominate --force -s ${suite}
    log "cruft-report"
    dak cruft-report -s ${suite}
366
    echo "Remember to keep the linux ABI included in the last release."
367
    echo "Anything to remove? If so, copy/paste commands into another window, have fun"
368
    echo "When done, continue here. Enter anything if you got removals, empty if not (will rerun dominate/cruft-report then)"
369 370 371 372 373 374 375 376 377 378
    read -e -p "Anything removed?" -i "yes" removedstuff
    if [[ -n ${removedstuff} ]]; then
        hadremove=1
        continue
    else
        break
    fi
done

if [[ ${hadremove} -ne 0 ]]; then
379
    edit-changelog "You did some removals, please copy their entries into the changelog (will open an editor for you)" ${webdir}/removals.txt
380 381
fi

382 383
log "Cleaning up debug suite"
dak manage-debug-suites ${suite}-debug ${pusuite}-debug
384

385
log "Time to run gps/contents, RMs can check if all looks ok"
386 387
gps_suites=${suite},${pusuite},${suite}-debug,${pusuite}-debug

388
dak generate-packages-sources2 --force -s ${gps_suites}
389
${scriptsdir}/sync-release ${suite} &
390 391
log "Contents"
dak contents generate -f -s ${suite} -a ftp-master
392
wait
393
${scriptsdir}/sync-release ${suite}
394
${scriptsdir}/sync-release ${suite}-debug
395

396 397
echo "Generate release files?"
confirm
398
release_suites="${suite} ${pusuite} ${suite}-debug ${pusuite}-debug"
399
dak generate-releases -f -s ${release_suites}
400
${scriptsdir}/sync-release ${suite}
401
${scriptsdir}/sync-release ${suite}-debug
402 403 404 405

log "Release file generated, waiting for RMs checking and (hopefully) signing"

# Remove InRelease: Release can be signed by both ftpmaster & stable release keys
406 407 408 409 410
merge-release-signatures() {(
    set -e
    local archiveroot="${1:?}"
    local s="${2:?}"
    local oursignature="${3:?}"
411
    local ourmessage="${4}"
412 413
    local releasefile="${5:?}"
    local url="${6:-${release_base}/${releasefile}}"
414 415 416

    echo "==== Processing ${s}/${oursignature}..."

417
    mkdir -p ~/${suitename:?}_${newrev:?}/${s}
418

419
    # backup ${oursignature} before we modify it...
420 421 422
    # make a .orig copy which we don't overwrite below
    cp --no-clobber ${archiveroot}/zzz-dists/${s}/${oursignature} ~/${suitename}_${newrev}/${s}/${oursignature}
    cp --no-clobber ${archiveroot}/zzz-dists/${s}/${oursignature} ~/${suitename}_${newrev}/${s}/${oursignature}.orig
423

424
    cd ~/${suitename}_${newrev}/${s}
425
    while ! ${wget:?} -O "${releasefile}" "${url}"; do
426 427
        sleep 10
    done
428 429 430 431 432 433 434 435

    ${scriptsdir}/gpg-merge-signatures "${oursignature}" "${releasefile}" > ${oursignature}.combined
    mv ${oursignature}.combined ${oursignature}

    # If detached, copy the text for checking
    if [ ! -z ${ourmessage} ]; then
	    cp ${archiveroot}/dists/${s}/${ourmessage} ${ourmessage}
    fi
436 437

    gpg --no-default-keyring --keyring /usr/share/keyrings/debian-archive-keyring.gpg --trust-model=always --verify ${oursignature} ${ourmessage}
438 439

    cp ${oursignature} ${archiveroot}/dists/${s}/${oursignature}
440
)}
441

442 443 444
merge-release-signatures $(get_archiveroot ftp-master) ${suite} Release.gpg Release Release-${newrev}.gpg
merge-release-signatures $(get_archiveroot debian-debug) ${suite}-debug Release.gpg Release Release-${newrev}-debug.gpg
if [ "${suitename}" = stretch ]; then
M
Mark Hymers 已提交
445 446
    rm -f $(get_archiveroot ftp-master)/dists/${suite}/InRelease $(get_archiveroot ftp-master)/zzz-dists/${suite}/InRelease
    rm -f $(get_archiveroot debian-debug)/dists/${suite}-debug/InRelease $(get_archiveroot debian-debug)/zzz-dists/${suite}-debug/InRelease
447 448 449 450
else
    merge-release-signatures $(get_archiveroot ftp-master) ${suite} InRelease "" InRelease-${newrev}.gpg
    merge-release-signatures $(get_archiveroot debian-debug) ${suite}-debug InRelease "" InRelease-${newrev}-debug.gpg
fi
451

452
echo "Done. Is a mirrorpush needed? Or just one to the cd-builder?"
453
read -e -p "Mirrorpush? no/cd/yes " -i "cd" mirrorpush
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469

case ${mirrorpush} in
    no)
        :
        ;;
    yes)
        $configdir/cronscript mirror
        ;;
    cd)
        mirror
        mirrorpush-release
        ;;
    *)
        echo "Sod off"
        ;;
esac