Codebase list metche / 3c208f1
Added (alpha) stable state support. intrigeri 18 years ago
5 changed file(s) with 206 addition(s) and 52 deletion(s). Raw diff Collapse all Expand all
66 doc: manpage
77
88 clean:
9 test ! -f metche.8 || rm metche.8
109 test ! -f metche-manpage.xml || rm -f metche-manpage.xml
+181
-41
metche less more
1818 #
1919
2020 set -e
21 shopt -s nullglob
2122
2223 ###
2324 ### Auxiliary functions
2425 ###
2526
2627 function display_usage {
27 ( echo "Usage: $0 [-h HOST] list"
28 echo " $0 [-h HOST] report [milestone]"
29 echo " $0 [-h HOST] cron"
28 ( echo "Usage: `basename $0` [-h HOST] list"
29 echo " `basename $0` [-h HOST] report [{stable|testing|unstable}-YYYYMMDDHHMM]"
30 echo " `basename $0` [-h HOST] cron"
31 echo " `basename $0` [-h HOST] stabilize [testing-YYYYMMDDHHMM]"
3032 echo "If -h is specified, /etc/metche/HOST.conf is used instead of /etc/metche.conf."
3133 echo ""
3234 ) >&2
3739 exit 2
3840 }
3941
42 function debug() {
43 [ $DEBUG -eq 0 ] || echo -e "debug: $@" >&2
44 }
45
46 function email() {
47 debug "email $@"
48 SUBJECT="$_MAIL_SUBJECT : $1"
49 if [ $ENCRYPT_EMAIL == "yes" ]; then
50 cat |
51 (LC_ALL="$LOCALE" gpg --batch --armor --encrypt --recipient "$EMAIL_ADDRESS") |
52 (LC_ALL="$LOCALE" mutt -s "$SUBJECT" "$EMAIL_ADDRESS")
53 else
54 cat |
55 (LC_ALL="$LOCALE" mutt -s "$SUBJECT" "$EMAIL_ADDRESS")
56 fi
57 }
4058
4159 ###
4260 ### Configuration
4361 ###
4462
63 DEBUG=1
4564 WATCHED_DIR="/etc"
4665 BACKUP_DIR="/var/lib/metche"
4766 CHANGELOG_DIR="/root/changelogs"
4867 DO_PACKAGES="yes"
4968 TESTING_TIME="60"
69 STABLE_TIME="3"
5070 EMAIL_ADDRESS="root@`hostname -f`"
5171 ENCRYPT_EMAIL="no"
5272 TAR_OPTS="--exclude *.swp --exclude #* --exclude *~ --exclude=*.key --exclude=ifstate"
91111
92112 "
93113
94 if [ "x$1" == "x-h" ]; then
114 if [ "$1" == "-h" ]; then
95115 if [ -f /etc/metche/$2.conf ]; then
96116 . /etc/metche/$2.conf
97117 CMD="$3"
148168 ###
149169 ### A few functions to do the real work
150170 ###
171 # NB: we often use 'echo' instead of return values because of 'set -e'.
172
173 # Echoes "true" if specified milestone exists, else "false".
174 milestone_exists() {
175 MILESTONE="$1"
176 if [ -f "${BACKUP_DIR}/${MILESTONE}.tar.bz2" -o -L "${BACKUP_DIR}/${MILESTONE}.tar.bz2" ]; then
177 echo "true"
178 else
179 echo "false"
180 fi
181 }
182
183 # Echoes the given milestone's version (i.e. "stable", "testing", "unstable")
184 # if it has a valid version, else "none".
185 # The given milestone can be inexistant.
186 milestone_version() {
187 MILESTONE="$1"
188 VERSION="`echo $MILESTONE | sed 's/-.*$//'`"
189 case $VERSION in
190 stable|testing|unstable)
191 echo $VERSION;;
192 *)
193 echo "none";;
194 esac
195 }
196
197 # Echoes given milestone's date.
198 # Symlinks (e.g.: *-latest) are dereferenced if needed.
199 # The given milestone can be inexistant.
200 milestone_date() {
201 MILESTONE="$1"
202 [ ! -L "${BACKUP_DIR}/${MILESTONE}.tar.bz2" ] || MILESTONE="`readlink ${BACKUP_DIR}/${MILESTONE}.tar.bz2`"
203 echo `basename $MILESTONE` | sed 's/.*-//' | sed 's/\..*$//'
204 }
205
206 # Echoes "true" if the given milestone ($1) is the latest one of its type,
207 # looking at the date in the filename ; else "false".
208 # The given milestone can be inexistant.
209 is_latest() {
210 REF_MILESTONE="$1"
211 REF_DATE="`milestone_date $REF_MILESTONE`"
212 REF_VERSION="`milestone_version $REF_MILESTONE`"
213 for FILE in "${BACKUP_DIR}/${REF_VERSION}-"*.tar.bz2; do
214 MILESTONE=`basename $FILE | sed 's/\.tar\.bz2$//'`
215 if [ `milestone_date $MILESTONE` -gt $REF_DATE ]; then
216 debug "false"
217 echo "false"
218 return
219 fi
220 done
221 echo "true"
222 }
151223
152224 # This will save an archive of the watched directory with the given prefix
153225 save_files() {
226 debug "save_files $@"
154227 tar jcf "$BACKUP_DIR/$1-$DATE".tar.bz2 \
155228 -C "$WATCHED_PARENT" $TAR_OPTS `basename "$WATCHED_DIR"`
156229 ln -sf "$1-$DATE".tar.bz2 "$BACKUP_DIR/$1"-latest.tar.bz2
158231
159232 # This will save packages list with the given prefix
160233 save_packages() {
234 debug "save_packages $@"
161235 $VSERVER_EXEC_PREFIX apt-show-versions -i
162236 $VSERVER_EXEC_PREFIX apt-show-versions | sort > "$BACKUP_DIR/$1-$DATE".packages
163237 ln -sf "$1-$DATE".packages "$BACKUP_DIR/$1"-latest.packages
165239
166240 # This will save Changelogs with the given prefix
167241 save_changelogs() {
242 debug "save_changelogs $@"
168243 for file in "$CHANGELOG_DIR"/*/Changelog; do
169244 CHANGELOG="${file##$CHANGELOG_DIR/}"
170245 DOMAIN="${CHANGELOG%%/Changelog}"
176251
177252 # Save whatever reflect the current state with the given prefix
178253 save_state() {
254 debug "save_state $@"
179255 save_files "$1"
180256 [ $DO_PACKAGES == "no" ] || save_packages "$1"
181257 [ $DO_CHANGELOGS == "no" ] || save_changelogs "$1"
183259
184260 # Report changes against given version to standard output
185261 report_changes() {
262 debug "report_changes $@"
186263 # Just for fancy graphics
187264 RULER=`echo "$WATCHED_DIR" | tr '[:print:]' '='`
188265
269346 rm -rf "$TMP" "$TMPDIR"
270347 }
271348
349 # Turns into stable the given testing.
350 # NB: argument validity is supposed to have been already checked.
351 stabilize_state() {
352 debug "stabilize_state $@"
353 TESTING="$1"
354 # follow symlink if needed
355 if [ -L "${BACKUP_DIR}/$TESTING".tar.bz2 ]; then
356 TESTING="`readlink ${BACKUP_DIR}/${TESTING}.tar.bz2`"
357 TESTING="`basename $TESTING | sed 's/\..*//'`"
358 fi
359 STABLE="`echo $TESTING | sed 's/^testing/stable/'`"
360 IS_LATEST="false"; [ `is_latest $STABLE` == "false" ] || IS_LATEST="true"
361 for FILE in "${BACKUP_DIR}/${TESTING}"*; do
362 DST="`echo $FILE | sed 's/\/testing-/\/stable-/'`"
363 cp "$FILE" "$DST"
364 # create/change stable-latest* links if, and only if, it's really the latest
365 if [ "$IS_LATEST" == "true" ]; then
366 ln -sf "`basename $DST`" "${BACKUP_DIR}/`basename $DST | sed 's/-[0-9]*\./-latest\./'`"
367 fi
368 done
369 }
272370
273371 ###
274372 ### Main
275373 ###
276374
277 # Hey, have I been ever launched before ?!
278 if [ ! -L "$BACKUP_DIR"/testing-latest.tar.bz2 ]; then
279 save_state "testing"
280 fi
375 # make sure we've got at least one testing and one stable
376 [ `milestone_exists testing-latest` == "true" ] || save_state "testing"
377 [ `milestone_exists stable-latest` == "true" ] || stabilize_state "testing-latest"
281378
282379 case "$CMD" in
380
283381 report)
284 if [ "x$MILESTONE" == "x" ]; then
382 if [ "$MILESTONE" == "" ]; then
285383 report_changes "testing-latest"
384 elif [ `milestone_exists "$MILESTONE"` == "true" ]; then
385 report_changes "$MILESTONE"
286386 else
287 report_changes "testing-$MILESTONE"
387 display_usage
388 fatal "The specified state does not exist."
288389 fi
289390 exit 0
290391 ;;
392
291393 list)
292394 for file in "$BACKUP_DIR"/*.tar.bz2; do
293395 echo `basename ${file%%.tar.bz2}`
294396 done
295397 exit 0
296398 ;;
399
297400 cron)
298 # Anyway, backup unstable if there was a change since last unstable
299 if [ -f "$BACKUP_DIR"/unstable-latest.tar.bz2 ]; then
300 if [ "" != "`find "$WATCHED_DIR" -newer \
301 "$BACKUP_DIR"/unstable-latest.tar.bz2 |
302 head -1`" ]; then
303 save_state "unstable"
304 fi
305 else
306 save_state "unstable"
307 fi
308
309 # Is there any modification since "time to testing"
310 # that is more recent than latest testing ?
311 if [ "`find "$WATCHED_DIR" -cmin "-$TESTING_TIME" | head -1`" = "" \
312 -a "`find "$WATCHED_DIR" -newer \
313 "$BACKUP_DIR"/testing-latest.tar.bz2 | head -1`" != "" ]; then
314 # Email report
315 if [ $ENCRYPT_EMAIL == "yes" ]; then
316 report_changes "testing-latest" |
317 (LC_ALL="$LOCALE" gpg --batch --armor --encrypt --recipient "$EMAIL_ADDRESS") |
318 (LC_ALL="$LOCALE" mutt -s "$_MAIL_SUBJECT" "$EMAIL_ADDRESS")
319 else
320 report_changes "testing-latest" |
321 (LC_ALL="$LOCALE" mutt -s "$_MAIL_SUBJECT" "$EMAIL_ADDRESS")
401 ### Algorithm
402 #
403 # if (no change happened for TESTING_TIME) then
404 # if (something has changed since the last testing) then
405 # send a report against last testing
406 # save a new testing state
407 # delete all saved unstable states
408 # elif (no change happened for STABLE_TIME) then
409 # if (something has changed since the last stable) then
410 # save a new stable state and notify EMAIL_ADDRESS
411 # delete all saved testing states older than STABLE_TIME
412 # fi
413 # fi
414 # elif (last unstable exists) then
415 # if (something has changed since the last unstable) then
416 # save a new unstable state
417 # fi
418 # else
419 # save a new unstable state
420 # fi
421 if [ "`find "$WATCHED_DIR" -cmin "-$TESTING_TIME" | head -1`" = "" ]; then
422 if [ "`find "$WATCHED_DIR" -newer "$BACKUP_DIR"/testing-latest.tar.bz2 | head -1`" != "" ]; then
423 report_changes "testing-latest" | email "testing-$DATE"
424 save_state "testing"
425 debug "removing all saved unstable states."
426 find "$BACKUP_DIR" -name 'unstable-*' -exec rm "{}" \;
427 elif [ "`find "$WATCHED_DIR" -ctime "-$STABLE_TIME" | head -1`" = "" ]; then
428 if [ "`find "$WATCHED_DIR" -newer "$BACKUP_DIR"/stable-latest.tar.bz2 | head -1`" != "" ]; then
429 save_state "stable"
430 echo "metche saved a new stable state : stable-${DATE}." | email "stable-$DATE"
431 debug "removing all saved testing states older that STABLE_TIME ($STABLE_TIME)."
432 find "$BACKUP_DIR" -name 'testing-*' -ctime +"$STABLE_TIME" -exec rm "{}" \;
433 fi
322434 fi
323
324 # Create new testing
325 save_state "testing"
326
327 # Remove unstable
328 find "$BACKUP_DIR" -name 'unstable-*' -print0 | xargs -0 rm
329 fi
435 elif [ `milestone_exists unstable-latest` == "true" ]; then
436 if [ "" != "`find "$WATCHED_DIR" -newer "$BACKUP_DIR"/unstable-latest.tar.bz2 | head -1`" ]; then
437 save_state "unstable"
438 fi
439 else
440 save_state "unstable"
441 fi
330442 ;;
443
444 stabilize)
445 if [ "$MILESTONE" == "" ]; then
446 stabilize_state "testing-latest"
447 elif [ "`milestone_version $MILESTONE`" == "testing" -a `milestone_exists $MILESTONE` == "true" ]; then
448 stabilize_state "$MILESTONE"
449 else
450 display_usage
451 fatal "The specified state is not an existing testing state."
452 fi
453 exit 0
454 ;;
455
456 test)
457 milestone_version "stable-200507040202"
458 milestone_version "testing-latest"
459 milestone_version "testing-200507030047"
460 milestone_version "testing-200507030047qsfd"
461 milestone_date "stable-200507040202"
462 milestone_date "testing-latest"
463 milestone_date "testing-200507030047"
464 milestone_date "testing-200507030047qsfd"
465 is_latest testing-latest
466 is_latest testing-200507031821
467 is_latest stable-200507031831
468 is_latest stable-200507040202
469 ;;
470
331471 *)
332472 display_usage
333473 exit 1
108108 send a report against last testing
109109 save a new testing state
110110 delete all saved unstable states
111 elseif (no change happened for STABLE_TIME) then
111 elif (no change happened for STABLE_TIME) then
112112 if (something has changed since the last stable) then
113 save a new stable state, and notify EMAIL_ADDRESS
113 save a new stable state and notify EMAIL_ADDRESS
114114 delete all saved testing states older than STABLE_TIME
115 endif
116 endif
117 endif
115 fi
116 fi
117 elif (last unstable exists) then
118 if (something has changed since the last unstable) then
119 save a new unstable state
120 fi
121 else
122 save a new unstable state
123 fi
118124 </screen>
119125 </Para>
120126 </ListItem>
8383 send a report against last testing
8484 save a new testing state
8585 delete all saved unstable states
86 elseif (no change happened for STABLE_TIME) then
86 elif (no change happened for STABLE_TIME) then
8787 if (something has changed since the last stable) then
88 save a new stable state, and notify EMAIL_ADDRESS
88 save a new stable state and notify EMAIL_ADDRESS
8989 delete all saved testing states older than STABLE_TIME
90 endif
91 endif
92 endif
90 fi
91 fi
92 elif (last unstable exists) then
93 if (something has changed since the last unstable) then
94 save a new unstable state
95 fi
96 else
97 save a new unstable state
98 fi
9399
94100
95101 .SH "FILES"
1616
1717 # Minutes until unstable goes to testing
1818 TESTING_TIME="60"
19
20 # Days until testing goes to stable
21 STABLE_TIME="3"
1922
2023 # Address receiving testing changes report
2124 EMAIL_ADDRESS="root@localhost"