pointrelease 13.6 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 59 60 61 62 63 64
trap cleanup EXIT TERM HUP INT QUIT

function usage() {
    echo "Fun with a pointrelease"
    echo "Takes two args, suite and version"
    echo "Default for suite is jessie, version defaults to last plus one"
}

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

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

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

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

107 108
wget="wget --ca-directory=/etc/ssl/ca-debian"

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
# 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}
124

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

log "Preparing"
pg_timestamp pre_${suite}_${newrev}
131 132 133 134 135 136
if [[ ! -f ${pusuite}.list ]]; then
    dak control-suite -l ${pusuite} > ${pusuite}.list &
fi
if [[ ! -f ${suite}.list ]]; then
    dak control-suite -l ${suite} > ${suite}.list &
fi
137
if [[ ${suitename} != jessie ]]; then
138 139 140 141 142 143
    if [[ ! -f ${suite}-debug.list ]]; then
        dak control-suite -l ${suite}-debug > ${suite}-debug.list &
    fi
    if [[ ! -f ${pusuite}-debug.list ]]; then
        dak control-suite -l ${pusuite}-debug > ${pusuite}-debug.list &
    fi
144
fi
145
wait
146 147

if [[ -n ${skiplist} ]]; then
148 149 150 151 152
  for s in ${pusuite} ${pusuite}-debug; do
    if [[ ${s} = ${pusuite}-debug && ${suitename} = jessie ]]; then
      continue
    fi
    mv ${s}.list ${s}.list.ori
153
    grep -vFf <(dak ls -f heidi -S -s ${s} ${skiplist}) ${s}.list.ori > ${s}.list
154
  done
155 156 157 158 159 160 161 162 163
fi

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
    echo "Please edit to remove the changelogs for the skipped packages"
164
    confirm
165 166 167 168
    $EDITOR ${ftpdir}/dists/${suite}/ChangeLog
    rm -f ${ftpdir}/dists/${suite}/ChangeLog~
fi

169
log "Merging ${pusuite} into ${suite}"
J
Joerg Jaspert 已提交
170 171 172 173 174 175 176 177 178 179
while :; do
    if dak control-suite --add ${suite} < ${pusuite}.list; then
        log "Done"
        break
    else
        log "Please check problem and hit enter when i can retry"
        read
    fi
done

180 181 182
if [[ ${suitename} != jessie ]]; then
    dak control-suite --add ${suite}-debug < ${pusuite}-debug.list
fi
183
dak control-suite --remove ${pusuite} < ${pusuite}.list
184 185 186
if [[ ${suitename} != jessie ]]; then
    dak control-suite --remove ${pusuite}-debug < ${pusuite}-debug.list
fi
187 188 189 190 191 192 193 194

log "Cleaning changelogs from proposed-updates"
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
195
        mv -t "${ftpdir}/dists/${pusuite}" ${pumorguedir}/${pack}_*.changes
196 197 198 199 200
    done
fi

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

202 203
propups() {
    local target_suite="${1}"
204
    local f="${2:-propups.${target_suite}}"
205 206 207
    if ${wget} -O "${f}" "${release_base}/${f}"; then
        echo "Please check ${f}"
        confirm
208
        dak control-suite --force --add ${target_suite} < ${f}
209 210
    fi
}
211

212
propups ${suitename}-r0 ${suitename}-r0-additions.cs
213 214 215 216 217 218 219
propups unstable
if [[ ${suitename} != jessie ]]; then
    propups unstable-debug
fi
propups testing
if [[ ${suitename} != jessie ]]; then
    propups testing-debug
220 221 222
fi

log "RM time"
223 224 225 226 227 228 229 230
if ${wget} -O "removallist" "${release_base}/removals.${target_suite}"; then
    echo "Please check removallist file, I am going to run it as shell script when you confirm"
    confirm
    $EDITOR removallist
    bash removallist
fi

echo "Any more removals to be done?"
231 232
echo "If nothing - or done, just end with an empty line"
hadrms=0
233

J
Joerg Jaspert 已提交
234 235
# Blindly ignore errors in dak rm
set +e
236 237 238
while :; do
    read -e -p "RM command: " -i "dak rm -s ${suite} -R -p -d ### -m '###' ###" dakrmcmd
    if [[ -n ${dakrmcmd} ]]; then
239
        eval "${dakrmcmd}"
240 241 242 243 244 245
        hadrms=1
        continue
    else
        break
    fi
done
J
Joerg Jaspert 已提交
246
set -e
247 248 249

if [[ ${hadrms} -ne 0 ]]; then
    echo "You did some removals, please copy their entries into the changelog"
250
    confirm
251 252 253 254 255 256 257
    $EDITOR ${ftpdir}/dists/${suite}/ChangeLog ${webdir}/removals.txt
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
258
confirm
259 260 261 262

if [[ -n ${diver} ]]; then
    log "Installing new d-i version ${diver}"
    dak copy-installer -s ${pusuite} -d ${suite} ${diver}
263 264 265 266 267 268 269 270
    # 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
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296

    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
297
    if [ -d ${pusuite} ]; then
298
        rm -r ${suite}
299
        mv ${pusuite} ${suite}
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    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
317
  diff -u ${mirrordir}/ftp-master/${f} ${ftpdir}/${f} || :
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
done
read -e -p "Does the diff look ok? Enter anything if not, empty if yes" diffcheck
if [[ -n ${diffcheck} ]]; then
    cd ${ftpdir}/dists/${suite}
    $EDITOR ChangeLog ../README ../../README ../../README.html
    rm -f -- ./*~ ../*~ ../../*~
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;
335
update suite set version = '${newrev}' where suite_name = '${suite}' or suite_name = '${suite}-debug';
336
update suite set description = 'Debian ${newrev} Released ${mdate}' where suite_name = '${suite}';
337
update suite set description = 'Debian ${newrev} Released ${mdate} - Debug Information' where suite_name = '${suite}-debug';
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
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}
    echo "Anything to remove? If so, copy/paste commands into another window, have fun"
    echo "When done, continue here. Enter anything if you got removals, empty if not"
    read -e -p "Anything removed?" -i "yes" removedstuff
    if [[ -n ${removedstuff} ]]; then
        hadremove=1
        continue
    else
        break
    fi
done

if [[ ${hadremove} -ne 0 ]]; then
    echo "You did some removals, please copy their entries into the changelog"
    $EDITOR ${ftpdir}/dists/${suite}/ChangeLog ${webdir}/removals.txt
fi

364 365
if [[ ${suitename} != jessie ]]; then
    log "Cleaning up debug suite"
366
    dak manage-debug-suites ${suite}-debug ${pusuite}-debug
367 368
fi

369
log "Time to run gps/contents, RMs can check if all looks ok"
370 371 372 373 374
gps_suites=${suite},${pusuite}
if [[ ${suitename} != jessie ]]; then
    gps_suites=${gps_suites},${suite}-debug,${pusuite}-debug
fi
dak generate-packages-sources2 --force -s ${gps_suites}
375
${scriptsdir}/sync-release ${suite} &
376 377
log "Contents"
dak contents generate -f -s ${suite} -a ftp-master
378
wait
379
${scriptsdir}/sync-release ${suite}
380 381 382
if [[ ${suitename} != jessie ]]; then
    ${scriptsdir}/sync-release ${suite}-debug
fi
383

384 385
echo "Generate release files?"
confirm
386 387 388 389 390
release_suites="${suite} ${pusuite}"
if [[ ${suitename} != jessie ]]; then
    release_suites="${release_suites} ${suite}-debug ${pusuite}-debug"
fi
dak generate-releases -f -s ${release_suites}
391
${scriptsdir}/sync-release ${suite}
392 393 394
if [[ ${suitename} != jessie ]]; then
    ${scriptsdir}/sync-release ${suite}-debug
fi
395 396 397 398

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

# Remove InRelease: Release can be signed by both ftpmaster & stable release keys
399
merge-release-signatures() {
400 401 402 403
    local archiveroot="${1}"
    local s="${2}"
    local releasefile="${3}"
    rm -f ${archiveroot}/dists/${s}/InRelease ${archiveroot}/zzz-dists/${s}/InRelease
404 405 406 407
    cd ~/${suitename}_${newrev}
    while ! ${wget} -O "${releasefile}" "${release_base}/${releasefile}"; do
        sleep 10
    done
408
    cd ${archiveroot}/dists/${s}
409 410 411 412
    cat ~/${suitename}_${newrev}/${releasefile} >> Release.gpg
    gpg --no-default-keyring --keyring /usr/share/keyrings/debian-archive-keyring.gpg --trust-model=always --verify Release.gpg Release
}

413
merge-release-signatures $(get_archiveroot ftp-master) ${suite} Release-${newrev}.gpg
414
if [[ ${suitename} != jessie ]]; then
415
    merge-release-signatures $(get_archiveroot debian-debug) ${suite}-debug Release-${newrev}-debug.gpg
416 417
fi

418
echo "Done. Is a mirrorpush needed? Or just one to the cd-builder?"
419
read -e -p "Mirrorpush? no/cd/yes " -i "cd" mirrorpush
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435

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