pointrelease 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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. if [[ ! -f ${pusuite}.list ]]; then
  114. dak control-suite -l ${pusuite} > ${pusuite}.list &
  115. fi
  116. if [[ ! -f ${suite}.list ]]; then
  117. dak control-suite -l ${suite} > ${suite}.list &
  118. fi
  119. if [[ ! -f ${suite}-debug.list ]]; then
  120. dak control-suite -l ${suite}-debug > ${suite}-debug.list &
  121. fi
  122. if [[ ! -f ${pusuite}-debug.list ]]; then
  123. dak control-suite -l ${pusuite}-debug > ${pusuite}-debug.list &
  124. fi
  125. wait
  126. if [[ -n ${skiplist} ]]; then
  127. for s in ${pusuite} ${pusuite}-debug; do
  128. mv ${s}.list ${s}.list.ori
  129. grep -vFf <(dak ls -f heidi -S -s ${s} ${skiplist}) ${s}.list.ori > ${s}.list
  130. done
  131. fi
  132. log "Creating changelog"
  133. tmpfile=$(mktemp -p "${TMPDIR}" changelog.XXXXXX)
  134. dak make-changelog -s ${pusuite} -b ${suite} | cat - ${ftpdir}/dists/${suite}/ChangeLog > ${tmpfile}
  135. chmod 0644 ${tmpfile}
  136. mv ${tmpfile} ${ftpdir}/dists/${suite}/ChangeLog
  137. if [[ -n ${skiplist} ]]; then
  138. echo "Please edit to remove the changelogs for the skipped packages"
  139. confirm
  140. $EDITOR ${ftpdir}/dists/${suite}/ChangeLog
  141. rm -f ${ftpdir}/dists/${suite}/ChangeLog~
  142. fi
  143. log "Merging ${pusuite} into ${suite}"
  144. while :; do
  145. if dak control-suite --add ${suite} < ${pusuite}.list; then
  146. log "Done"
  147. break
  148. else
  149. log "Please check problem and hit enter when i can retry"
  150. read
  151. fi
  152. done
  153. dak control-suite --add ${suite}-debug < ${pusuite}-debug.list
  154. dak control-suite --remove ${pusuite} < ${pusuite}.list
  155. dak control-suite --remove ${pusuite}-debug < ${pusuite}-debug.list
  156. log "Cleaning changelogs from proposed-updates"
  157. pumorguedir="${base}/morgue/queues/$(date +%Y/%m)"
  158. mkdir -p "${pumorguedir}"
  159. cd ${ftpdir}/dists/${pusuite}
  160. mv -t "${pumorguedir}" -n -- *.changes
  161. if [[ -n ${skiplist} ]]; then
  162. for pack in ${skiplist}; do
  163. mv -t "${ftpdir}/dists/${pusuite}" ${pumorguedir}/${pack}_*.changes
  164. done
  165. fi
  166. log "Checking for r0 additions and propups"
  167. cd ~/${suitename}_${newrev}
  168. propups() {
  169. local target_suite="${1}"
  170. local f="${2:-propups.${target_suite}}"
  171. if ${wget} -O "${f}" "${release_base}/${f}"; then
  172. echo "Please check ${f}"
  173. confirm
  174. dak control-suite --force --add ${target_suite} < ${f}
  175. fi
  176. }
  177. propups ${suitename}-r0 ${suitename}-r0-additions.cs
  178. propups unstable
  179. propups unstable-debug
  180. propups testing
  181. propups testing-debug
  182. log "RM time"
  183. hadrms=0
  184. if ${wget} -O "removallist" "${release_base}/removals.${suitename}"; then
  185. echo "Please check removallist file, I am going to run it as shell script when you confirm"
  186. confirm
  187. $EDITOR removallist
  188. bash removallist
  189. if [ -s removallist ]; then
  190. hadrms=1
  191. fi
  192. fi
  193. echo "Any more removals to be done?"
  194. echo "If nothing - or done, just end with an empty line"
  195. # Blindly ignore errors in dak rm
  196. set +e
  197. while :; do
  198. read -e -p "RM command: " -i "dak rm -s ${suite} -R -p -d ### -m '###' ###" dakrmcmd
  199. if [[ -n ${dakrmcmd} ]]; then
  200. eval "${dakrmcmd}"
  201. hadrms=1
  202. continue
  203. else
  204. break
  205. fi
  206. done
  207. set -e
  208. if [[ ${hadrms} -ne 0 ]]; then
  209. echo "You did some removals, please copy their entries into the changelog"
  210. confirm
  211. $EDITOR ${ftpdir}/dists/${suite}/ChangeLog ${webdir}/removals.txt
  212. rm -f ${ftpdir}/dists/${suite}/ChangeLog~
  213. fi
  214. log "Checking for d-i updates"
  215. echo "Are there d-i updates? Empty version string, if not."
  216. echo "Seperate old version to move to morgue by space."
  217. read -e -p "d-i updates: " diver dioldver
  218. confirm
  219. if [[ -n ${diver} ]]; then
  220. log "Installing new d-i version ${diver}"
  221. dak copy-installer -s ${pusuite} -d ${suite} ${diver}
  222. # Remove new version from proposed-updates
  223. cd $ftpdir/dists/${pusuite}/main
  224. for iarch in $(dak admin s-a list-arch ${suite}); do
  225. rm -rf -- "installer-${iarch}/${diver}"
  226. if [[ -L install-${iarch}/current && "$(readlink install-${iarch}/current)" = "${diver}" ]]; then
  227. rm install-${iarch}/current
  228. fi
  229. done
  230. if [[ -n ${dioldver} ]]; then
  231. log "Moving old d-i version ${dioldver} to morgue"
  232. cd $ftpdir/dists/${suite}/main
  233. for iarch in $(dak admin s-a list-arch ${suite}); do
  234. if [[ -d installer-${iarch}/${dioldver} ]]; then
  235. echo "Moving installer-${iarch}/${dioldver} to morgue"
  236. mkdir -p "${base}/morgue/d-i/installer-${iarch}/"
  237. mv "installer-${iarch}/${dioldver}" "${base}/morgue/d-i/installer-${iarch}/"
  238. fi
  239. done
  240. # Remove old version also from proposed-updates
  241. cd $ftpdir/dists/${pusuite}/main
  242. for iarch in $(dak admin s-a list-arch ${suite}); do
  243. rm -rf -- "installer-${iarch}/${dioldver}"
  244. done
  245. fi
  246. cd $ftpdir/dists/${suite}
  247. fi
  248. log "Checking for win32-loader"
  249. echo "If anything for win32-loader, enter any string, otherwise empty"
  250. read -e -p "win32-loader?" win32loader
  251. if [[ -n ${win32loader} ]]; then
  252. cd ${ftpdir}/tools/win32-loader
  253. if [ -d ${pusuite} ]; then
  254. rm -r ${suite}
  255. mv ${pusuite} ${suite}
  256. fi
  257. cd ${ftpdir}
  258. fi
  259. log "Updating version numbers in readmes, fixing Changelog"
  260. cd ${ftpdir}/dists/${suite}
  261. date_long=$(date "+%A, %-dth %B %Y" | sed 's/1th/1st/; s/2th/2nd/; s/3th/3rd/')
  262. date_iso=$(date "+%Y-%m-%d")
  263. date_short=$(date "+%a, %d %b %Y")
  264. sed -e "1i======================================\n${date_short} - Debian ${newrev} released\n======================================" -i ChangeLog
  265. sed -e "/^${suite}/ s/Debian ${oldrev}/Debian ${newrev}/" -i ../README
  266. sed -e "s/Debian ${oldrev}/Debian ${newrev}/g; /Debian ${newrev}/ s/released .*\\./released ${date_long}./" -i ../../README
  267. 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
  268. echo "Now check if it looks good"
  269. for f in README README.html dists/README dists/${suite}/ChangeLog; do
  270. diff -u ${mirrordir}/ftp-master/${f} ${ftpdir}/${f} || :
  271. done
  272. read -e -p "Does the diff look ok? Enter anything if not, empty if yes" diffcheck
  273. if [[ -n ${diffcheck} ]]; then
  274. cd ${ftpdir}/dists/${suite}
  275. $EDITOR ChangeLog ../README ../../README ../../README.html
  276. rm -f -- ./*~ ../*~ ../../*~
  277. fi
  278. log "Updating the Debianx.y symlink"
  279. cd $ftpdir/dists/
  280. rm -f Debian${oldrev}
  281. ln -s ${suitename} Debian${newrev}
  282. log "Updating suite table in postgres"
  283. mdate=$(date +"%d %B %Y")
  284. psql projectb <<EOF
  285. begin;
  286. update suite set version = '${newrev}' where suite_name = '${suite}' or suite_name = '${suite}-debug';
  287. update suite set description = 'Debian ${newrev} Released ${mdate}' where suite_name = '${suite}';
  288. update suite set description = 'Debian ${newrev} Released ${mdate} - Debug Information' where suite_name = '${suite}-debug';
  289. commit;
  290. EOF
  291. log "Preparing for gps, domination/cruft-report time"
  292. hadremove=0
  293. while :; do
  294. log "dominate"
  295. dak dominate --force -s ${suite}
  296. log "cruft-report"
  297. dak cruft-report -s ${suite}
  298. echo "Anything to remove? If so, copy/paste commands into another window, have fun"
  299. echo "When done, continue here. Enter anything if you got removals, empty if not"
  300. read -e -p "Anything removed?" -i "yes" removedstuff
  301. if [[ -n ${removedstuff} ]]; then
  302. hadremove=1
  303. continue
  304. else
  305. break
  306. fi
  307. done
  308. if [[ ${hadremove} -ne 0 ]]; then
  309. echo "You did some removals, please copy their entries into the changelog"
  310. $EDITOR ${ftpdir}/dists/${suite}/ChangeLog ${webdir}/removals.txt
  311. fi
  312. log "Cleaning up debug suite"
  313. dak manage-debug-suites ${suite}-debug ${pusuite}-debug
  314. log "Time to run gps/contents, RMs can check if all looks ok"
  315. gps_suites=${suite},${pusuite},${suite}-debug,${pusuite}-debug
  316. dak generate-packages-sources2 --force -s ${gps_suites}
  317. ${scriptsdir}/sync-release ${suite} &
  318. log "Contents"
  319. dak contents generate -f -s ${suite} -a ftp-master
  320. wait
  321. ${scriptsdir}/sync-release ${suite}
  322. ${scriptsdir}/sync-release ${suite}-debug
  323. echo "Generate release files?"
  324. confirm
  325. release_suites="${suite} ${pusuite} ${suite}-debug ${pusuite}-debug"
  326. dak generate-releases -f -s ${release_suites}
  327. ${scriptsdir}/sync-release ${suite}
  328. ${scriptsdir}/sync-release ${suite}-debug
  329. log "Release file generated, waiting for RMs checking and (hopefully) signing"
  330. # Remove InRelease: Release can be signed by both ftpmaster & stable release keys
  331. merge-release-signatures() {
  332. local archiveroot="${1}"
  333. local s="${2}"
  334. local releasefile="${3}"
  335. rm -f ${archiveroot}/dists/${s}/InRelease ${archiveroot}/zzz-dists/${s}/InRelease
  336. cd ~/${suitename}_${newrev}
  337. while ! ${wget} -O "${releasefile}" "${release_base}/${releasefile}"; do
  338. sleep 10
  339. done
  340. cd ${archiveroot}/dists/${s}
  341. cat ~/${suitename}_${newrev}/${releasefile} >> Release.gpg
  342. gpg --no-default-keyring --keyring /usr/share/keyrings/debian-archive-keyring.gpg --trust-model=always --verify Release.gpg Release
  343. }
  344. merge-release-signatures $(get_archiveroot ftp-master) ${suite} Release-${newrev}.gpg
  345. merge-release-signatures $(get_archiveroot debian-debug) ${suite}-debug Release-${newrev}-debug.gpg
  346. echo "Done. Is a mirrorpush needed? Or just one to the cd-builder?"
  347. read -e -p "Mirrorpush? no/cd/yes " -i "cd" mirrorpush
  348. case ${mirrorpush} in
  349. no)
  350. :
  351. ;;
  352. yes)
  353. $configdir/cronscript mirror
  354. ;;
  355. cd)
  356. mirror
  357. mirrorpush-release
  358. ;;
  359. *)
  360. echo "Sod off"
  361. ;;
  362. esac