pointrelease 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. #!/bin/bash
  2. # No way I try to deal with a crippled sh just for POSIX foo.
  3. # Copyright (C) 2009-2016 Joerg Jaspert <joerg@debian.org>
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License as
  7. # published by the Free Software Foundation; version 2.
  8. #
  9. # This program is distributed in the hope that it will be useful, but
  10. # WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. # exit on errors
  18. set -e
  19. # A pipeline's return status is the value of the last (rightmost)
  20. # command to exit with a non-zero status, or zero if all commands exit
  21. # successfully.
  22. set -o pipefail
  23. # make sure to only use defined variables
  24. set -u
  25. # ERR traps should be inherited from functions too. (And command
  26. # substitutions and subshells and whatnot, but for us the functions is
  27. # the important part here)
  28. set -E
  29. # If the extglob shell option is enabled using the shopt builtin,
  30. # several extended pattern matching operators are recognized. We use
  31. # it for the POSSIBLEARGS and the first case ${ARGS} matching.
  32. shopt -s extglob
  33. # And use one locale, no matter what the caller has set
  34. export LANG=C.UTF-8
  35. export LC_ALL=C.UTF-8
  36. # If run from crontab, CONFIGDIR will point to the correct dir
  37. # where we find the vars file
  38. configdir=${configdir:-"/srv/ftp-master.debian.org/dak/config/debian"}
  39. # import the general variable set. (This will overwrite configdir, but
  40. # it is expected to have the same value)
  41. export SCRIPTVARS=${configdir}/vars
  42. . "${SCRIPTVARS}"
  43. . "${configdir}/common"
  44. . "${configdir}/dinstall.functions"
  45. umask 022
  46. # Get rid of tempfiles at the end
  47. cleanup() {
  48. echo "You have to clean up your mess on your own. Sorry." >&2
  49. exit 1
  50. }
  51. trap cleanup EXIT TERM HUP INT QUIT
  52. suitename_default=$(psql -qAtc "SELECT codename FROM suite WHERE suite_name='stable'")
  53. function usage() {
  54. echo "Fun with a pointrelease"
  55. echo "Takes two args, suite and version"
  56. echo "Default for suite is ${suitename_default}, version defaults to last plus one"
  57. }
  58. confirm() {
  59. local y=N
  60. while [ "${y}" != "y" ]; do
  61. read -p "Continue [y/N]?" y
  62. done
  63. }
  64. # Arguments, we like
  65. while getopts ":hs:v:" OPTION; do
  66. case ${OPTION} in
  67. s) # suite
  68. suitename="${OPTARG}"
  69. ;;
  70. v) # version
  71. newrev="${OPTARG}"
  72. ;;
  73. h) # help
  74. usage
  75. exit 0
  76. ;;
  77. ?)
  78. echo "Unknown option ${OPTION} given, try -h"
  79. exit 42
  80. ;;
  81. esac
  82. done
  83. # Set some variables
  84. suitename=${suitename:-${suitename_default}}
  85. suite=$(psql -qAtc "SELECT suite_name FROM suite WHERE codename='${suitename}'")
  86. oldrev=$(psql -qAtc "SELECT version FROM suite WHERE codename='${suitename}'")
  87. newrev=${newrev:-${oldrev%.*}.$(( ${oldrev##*.} + 1 ))}
  88. release_base=https://release.debian.org/proposed-updates/${newrev%%.*}/${newrev}
  89. PROGRAM="pointrelease_${suitename}"
  90. # Set some variables
  91. case "${suite}" in
  92. stable) pusuite=proposed-updates ;;
  93. oldstable) pusuite=oldstable-proposed-updates ;;
  94. *) pusuite=INVALID ;;
  95. esac
  96. wget="wget --ca-directory=/etc/ssl/ca-debian"
  97. # set DEBUG if you want to see a little more logs
  98. DEBUG=${DEBUG:-0}
  99. # common functions are "outsourced"
  100. . "${configdir}/common"
  101. # Timestamp when we started
  102. NOW=$(date "+%Y.%m.%d-%H:%M:%S")
  103. log "Point release for ${suite} (${suitename}); old version: ${oldrev}, new: ${newrev}"
  104. log "Updates come from ${pusuite}"
  105. cd ~
  106. mkdir -p ${suitename}_${newrev}
  107. cd ${suitename}_${newrev}
  108. echo "Is there anything to skip in this release? If so, please enter source package names, whitespace separated, if not just hit enter"
  109. read -e -p "Source packages: " skiplist
  110. confirm
  111. log "Preparing"
  112. pg_timestamp pre_${suite}_${newrev}
  113. control-suite-list() {
  114. local s="${1:?}"
  115. if [[ ! -f ${s}.list ]]; then
  116. dak control-suite -l ${s} > ${s}.list &
  117. fi
  118. }
  119. control-suite-list ${pusuite}
  120. control-suite-list ${suite}
  121. control-suite-list ${pusuite}-debug
  122. control-suite-list ${suite}-debug
  123. wait
  124. if [[ -n ${skiplist} ]]; then
  125. for s in ${pusuite} ${pusuite}-debug; do
  126. mv ${s}.list ${s}.list.ori
  127. grep -vFf <(dak ls -f heidi -S -s ${s} ${skiplist}) ${s}.list.ori > ${s}.list
  128. done
  129. fi
  130. edit-changelog() {
  131. local prompt="${1:?}"
  132. shift
  133. if [ -n "${prompt}" ]; then
  134. echo "${prompt}"
  135. confirm
  136. fi
  137. $EDITOR "${ftpdir}/dists/${suite}/ChangeLog" "${@}"
  138. rm -f -- "${ftpdir}/dists/${suite}/ChangeLog~" "${ftpdir}/dists/${suite}/#ChangeLog#"
  139. }
  140. log "Creating changelog"
  141. tmpfile=$(mktemp -p "${TMPDIR}" changelog.XXXXXX)
  142. dak make-changelog -s ${pusuite} -b ${suite} | cat - ${ftpdir}/dists/${suite}/ChangeLog > ${tmpfile}
  143. chmod 0644 ${tmpfile}
  144. mv ${tmpfile} ${ftpdir}/dists/${suite}/ChangeLog
  145. if [[ -n ${skiplist} ]]; then
  146. edit-changelog "Please edit to remove the changelogs for the skipped packages"
  147. fi
  148. merge-suite() {
  149. local source="${1:?}"
  150. local target="${2:?}"
  151. log "Merging ${source} into ${target}"
  152. while :; do
  153. if dak control-suite --add ${target} < ${source}.list; then
  154. log "Done"
  155. break
  156. else
  157. log "Please check problem and hit enter when i can retry"
  158. read
  159. fi
  160. done
  161. }
  162. merge-suite ${pusuite} ${suite}
  163. merge-suite ${pusuite}-debug ${suite}-debug
  164. log "Cleaning ${pusuite} and ${pusuite}-debug"
  165. dak control-suite --remove ${pusuite} < ${pusuite}.list
  166. dak control-suite --remove ${pusuite}-debug < ${pusuite}-debug.list
  167. log "Cleaning changelogs from ${pusuite}"
  168. pumorguedir="${base}/morgue/queues/$(date +%Y/%m)"
  169. mkdir -p "${pumorguedir}"
  170. cd ${ftpdir}/dists/${pusuite}
  171. mv -t "${pumorguedir}" -n -- *.changes
  172. if [[ -n ${skiplist} ]]; then
  173. for pack in ${skiplist}; do
  174. # In corner cases, we may not have the changes file to move back - don't crash
  175. if compgen -G ${pumorguedir}/${pack}_*.changes >/dev/null; then
  176. mv -t "${ftpdir}/dists/${pusuite}" ${pumorguedir}/${pack}_*.changes
  177. else
  178. echo 'W: No changes files for ${pumorguedir}/${pack}_*.changes - check this is expected'
  179. fi
  180. done
  181. fi
  182. log "Checking for r0 additions and propups"
  183. cd ~/${suitename}_${newrev}
  184. propups() {
  185. local target_suite="${1}"
  186. local f="${2:-propups.${target_suite}}"
  187. if ${wget} -O "${f}" "${release_base}/${f}"; then
  188. echo "Please check ${f} (will open an editor for you)"
  189. confirm
  190. $EDITOR ${f}
  191. dak control-suite --force --add ${target_suite} < ${f}
  192. fi
  193. }
  194. propups ${suitename}-r0 ${suitename}-r0-additions.cs
  195. propups unstable
  196. propups unstable-debug
  197. propups testing
  198. propups testing-debug
  199. log "Override changes"
  200. echo "Any override changes? If so, process them in another window."
  201. confirm
  202. log "RM time"
  203. hadrms=0
  204. if ${wget} -O "removallist" "${release_base}/removals.${suitename}"; then
  205. echo "Please check removallist file, I am going to run it as shell script when you confirm (will open an editor for you)"
  206. confirm
  207. $EDITOR removallist
  208. bash removallist
  209. if [ -s removallist ]; then
  210. hadrms=1
  211. fi
  212. fi
  213. echo "Any more removals to be done?"
  214. echo "If nothing - or done, just end with an empty line"
  215. # Blindly ignore errors in dak rm
  216. set +e
  217. while :; do
  218. read -e -p "RM command: " -i "dak rm -s ${suite} -R -p -d ### -m '###' ###" dakrmcmd
  219. if [[ -n ${dakrmcmd} ]]; then
  220. eval "${dakrmcmd}"
  221. hadrms=1
  222. continue
  223. else
  224. break
  225. fi
  226. done
  227. set -e
  228. if [[ ${hadrms} -ne 0 ]]; then
  229. edit-changelog "You did some removals, please copy their entries into the changelog (will open an editor for you)" ${webdir}/removals.txt
  230. fi
  231. log "Checking for d-i updates"
  232. echo "Are there d-i updates? Empty version string, if not."
  233. echo "Seperate old version to move to morgue by space."
  234. read -e -p "d-i updates: " diver dioldver
  235. confirm
  236. if [[ -n ${diver} ]]; then
  237. log "Installing new d-i version ${diver}"
  238. dak copy-installer -s ${pusuite} -d ${suite} ${diver}
  239. # Remove new version from proposed-updates
  240. cd $ftpdir/dists/${pusuite}/main
  241. for iarch in $(dak admin s-a list-arch ${suite}); do
  242. rm -rf -- "installer-${iarch}/${diver}"
  243. if [[ -L install-${iarch}/current && "$(readlink install-${iarch}/current)" = "${diver}" ]]; then
  244. rm install-${iarch}/current
  245. fi
  246. done
  247. if [[ -n ${dioldver} ]]; then
  248. log "Moving old d-i version ${dioldver} to morgue"
  249. cd $ftpdir/dists/${suite}/main
  250. for iarch in $(dak admin s-a list-arch ${suite}); do
  251. if [[ -d installer-${iarch}/${dioldver} ]]; then
  252. echo "Moving installer-${iarch}/${dioldver} to morgue"
  253. mkdir -p "${base}/morgue/d-i/installer-${iarch}/"
  254. mv "installer-${iarch}/${dioldver}" "${base}/morgue/d-i/installer-${iarch}/"
  255. fi
  256. done
  257. # Remove old version also from proposed-updates
  258. cd $ftpdir/dists/${pusuite}/main
  259. for iarch in $(dak admin s-a list-arch ${suite}); do
  260. rm -rf -- "installer-${iarch}/${dioldver}"
  261. done
  262. fi
  263. cd $ftpdir/dists/${suite}
  264. fi
  265. log "Checking for win32-loader"
  266. echo "If anything for win32-loader, enter any string, otherwise empty"
  267. read -e -p "win32-loader?" win32loader
  268. if [[ -n ${win32loader} ]]; then
  269. cd ${ftpdir}/tools/win32-loader
  270. if [ -d ${pusuite} ]; then
  271. rm -r ${suite}
  272. mv ${pusuite} ${suite}
  273. fi
  274. cd ${ftpdir}
  275. fi
  276. log "Updating version numbers in readmes, fixing Changelog"
  277. cd ${ftpdir}/dists/${suite}
  278. date_long=$(date "+%A, %-dth %B %Y" | sed 's/1th/1st/; s/2th/2nd/; s/3th/3rd/')
  279. date_iso=$(date "+%Y-%m-%d")
  280. date_short=$(date "+%a, %d %b %Y")
  281. sed -e "1i======================================\n${date_short} - Debian ${newrev} released\n======================================" -i ChangeLog
  282. sed -e "/^${suite}/ s/Debian ${oldrev}/Debian ${newrev}/" -i ../README
  283. sed -e "s/Debian ${oldrev}/Debian ${newrev}/g; /Debian ${newrev}/ s/released .*\\./released ${date_long}./" -i ../../README
  284. 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
  285. echo "Now check if it looks good"
  286. for f in README README.html dists/README dists/${suite}/ChangeLog; do
  287. diff -u ${mirrordir}/ftp-master/${f} ${ftpdir}/${f} || :
  288. done
  289. 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
  290. if [[ -n ${diffcheck} ]]; then
  291. cd ${ftpdir}/dists/${suite}
  292. edit-changelog "Opening changelog" ../README ../../README ../../README.html
  293. rm -f -- ./*~ ../*~ ../../*~ ./"#"*"#" ../"#"*"#" ../../"#"*"#"
  294. fi
  295. log "Updating the Debianx.y symlink"
  296. cd $ftpdir/dists/
  297. rm -f Debian${oldrev}
  298. ln -s ${suitename} Debian${newrev}
  299. log "Updating suite table in postgres"
  300. mdate=$(date +"%d %B %Y")
  301. psql projectb <<EOF
  302. begin;
  303. update suite set version = '${newrev}' where suite_name = '${suite}' or suite_name = '${suite}-debug';
  304. update suite set description = 'Debian ${newrev} Released ${mdate}' where suite_name = '${suite}';
  305. update suite set description = 'Debian ${newrev} Released ${mdate} - Debug Information' where suite_name = '${suite}-debug';
  306. commit;
  307. EOF
  308. log "Preparing for gps, domination/cruft-report time"
  309. hadremove=0
  310. while :; do
  311. log "dominate"
  312. dak dominate --force -s ${suite}
  313. log "cruft-report"
  314. dak cruft-report -s ${suite}
  315. echo "Remember to keep the linux ABI included in the last release."
  316. echo "Anything to remove? If so, copy/paste commands into another window, have fun"
  317. echo "When done, continue here. Enter anything if you got removals, empty if not (will rerun dominate/cruft-report then)"
  318. read -e -p "Anything removed?" -i "yes" removedstuff
  319. if [[ -n ${removedstuff} ]]; then
  320. hadremove=1
  321. continue
  322. else
  323. break
  324. fi
  325. done
  326. if [[ ${hadremove} -ne 0 ]]; then
  327. edit-changelog "You did some removals, please copy their entries into the changelog (will open an editor for you)" ${webdir}/removals.txt
  328. fi
  329. log "Cleaning up debug suite"
  330. dak manage-debug-suites ${suite}-debug ${pusuite}-debug
  331. log "Time to run gps/contents, RMs can check if all looks ok"
  332. gps_suites=${suite},${pusuite},${suite}-debug,${pusuite}-debug
  333. dak generate-packages-sources2 --force -s ${gps_suites}
  334. ${scriptsdir}/sync-release ${suitename} &
  335. log "Contents"
  336. dak contents generate -f -s ${suite} -a ftp-master
  337. wait
  338. ${scriptsdir}/sync-release ${suitename}
  339. ${scriptsdir}/sync-release ${suitename}-debug
  340. echo "Generate release files?"
  341. confirm
  342. release_suites="${suite} ${pusuite} ${suite}-debug ${pusuite}-debug"
  343. dak generate-releases -f -s ${release_suites}
  344. ${scriptsdir}/sync-release ${suitename}
  345. ${scriptsdir}/sync-release ${suitename}-debug
  346. log "Release file generated, waiting for RMs checking and (hopefully) signing"
  347. # Remove InRelease: Release can be signed by both ftpmaster & stable release keys
  348. merge-release-signatures() {(
  349. set -e
  350. local archiveroot="${1:?}"
  351. local s="${2:?}"
  352. local oursignature="${3:?}"
  353. local ourmessage="${4}"
  354. local releasefile="${5:?}"
  355. local url="${6:-${release_base}/${releasefile}}"
  356. echo "==== Processing ${s}/${oursignature}..."
  357. mkdir -p ~/${suitename:?}_${newrev:?}/${s}
  358. # backup ${oursignature} before we modify it...
  359. # make a .orig copy which we don't overwrite below
  360. cp --no-clobber ${archiveroot}/zzz-dists/${s}/${oursignature} ~/${suitename}_${newrev}/${s}/${oursignature}
  361. cp --no-clobber ${archiveroot}/zzz-dists/${s}/${oursignature} ~/${suitename}_${newrev}/${s}/${oursignature}.orig
  362. cd ~/${suitename}_${newrev}/${s}
  363. while ! ${wget:?} -O "${releasefile}" "${url}"; do
  364. sleep 10
  365. done
  366. ${scriptsdir}/gpg-merge-signatures "${oursignature}" "${releasefile}" > ${oursignature}.combined
  367. mv ${oursignature}.combined ${oursignature}
  368. # If detached, copy the text for checking
  369. if [ ! -z ${ourmessage} ]; then
  370. cp ${archiveroot}/dists/${s}/${ourmessage} ${ourmessage}
  371. fi
  372. gpg --no-default-keyring --keyring /usr/share/keyrings/debian-archive-keyring.gpg --trust-model=always --verify ${oursignature} ${ourmessage}
  373. cp ${oursignature} ${archiveroot}/dists/${s}/${oursignature}
  374. )}
  375. merge-release-signatures $(get_archiveroot ftp-master) ${suitename} Release.gpg Release Release-${newrev}.gpg
  376. merge-release-signatures $(get_archiveroot debian-debug) ${suitename}-debug Release.gpg Release Release-${newrev}-debug.gpg
  377. if [ "${suitename}" = stretch ]; then
  378. rm -f $(get_archiveroot ftp-master)/dists/${suitename}/InRelease $(get_archiveroot ftp-master)/zzz-dists/${suite}/InRelease
  379. rm -f $(get_archiveroot debian-debug)/dists/${suitename}-debug/InRelease $(get_archiveroot debian-debug)/zzz-dists/${suite}-debug/InRelease
  380. else
  381. merge-release-signatures $(get_archiveroot ftp-master) ${suitename} InRelease "" InRelease-${newrev}.gpg
  382. merge-release-signatures $(get_archiveroot debian-debug) ${suitename}-debug InRelease "" InRelease-${newrev}-debug.gpg
  383. fi
  384. echo "Done. Is a mirrorpush needed? Or just one to the cd-builder?"
  385. read -e -p "Mirrorpush? no/cd/yes " -i "cd" mirrorpush
  386. case ${mirrorpush} in
  387. no)
  388. :
  389. ;;
  390. yes)
  391. $configdir/cronscript mirror
  392. ;;
  393. cd)
  394. mirror
  395. mirrorpush-release
  396. ;;
  397. *)
  398. echo "Sod off"
  399. ;;
  400. esac