-
Notifications
You must be signed in to change notification settings - Fork 12
/
deb-mirror
executable file
·612 lines (529 loc) · 25 KB
/
deb-mirror
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
#!/bin/bash
# Source separate config file if given
CONFIG_FILE="$1"
[[ -r "$CONFIG_FILE" ]] && . "$CONFIG_FILE"
# Sync source
UPSTREAM=${UPSTREAM:-""}
UPSTREAM_DIR=${UPSTREAM_DIR:-""}
# Sync destination
LOCAL_DIR=${LOCAL_DIR:-""}
# Local fqdn
LOCAL_FQDN=${LOCAL_FQDN:-"`hostname -f`"}
#declare -A DIST_COMPONENTs
# Optional fetch configuration
FETCH_I18N=${FETCH_I18N:-"yes"} # Fetch translations
FETCH_SOURCES=${FETCH_SOURCES:-"no"} # Fetch packages sources
FETCH_CONTENTS=${FETCH_CONTENTS:-"no"} # Fetch 'Contents' file for distro
FETCH_INSTALLER=${FETCH_INSTALLER:="no"} # Fetch separate 'debian-installer'
FETCH_DIFF=${FETCH_DIFF:-"no"} # Fetch diffs of 'Packages'
# (speedsup client update... NOT)
# Misc
ARCH_ALL_IS_MANDATORY=${ARCH_ALL_IS_MANDATORY:-"no"}
#------------------------------------------------------------------------------#
POSSIBLE_COMPRESSIONS=( gz bz2 xz lzma )
BINROOT=$(dirname `readlink -f "$0"`)
VERSION="0.1"
. $BINROOT/util/msgs.sh
. $BINROOT/util/rsync.sh
. $BINROOT/util/dpkg.sh
. $BINROOT/util/checksum.sh
[[ -n "$UPSTREAM" ]] || fatal "UPSTREAM is not defined in config"
[[ -n "$UPSTREAM_DIR" ]] || fatal "UPSTREAM_DIR is not defined in config"
[[ -n "$LOCAL_DIR" ]] || fatal "LOCAL_DIR is not defined in config"
[[ -n "${ARCHs[@]}" ]] || fatal "ARCHs is not defined in config"
[[ -n "${DISTs[@]}" ]] || fatal "DISTs is not defined in config"
#------------------------------------------------------------------------------#
# Checks if 'value' contained within 'array'
# USAGE: contains 'what' 'where'
# $1 -- value to find in array
# $2 -- array to search
contains()
{
local e
for e in "${@:2}"; do [[ "$e" = "$1" ]] && return 0; done
return 1
}
on_SIGINT()
{
fatal "Got user interrupt, aborting"
exit 1
}
#------------------------------------------------------------------------------#
# MAIN()
#------------------------------------------------------------------------------#
# Trap user abort
trap "on_SIGINT" INT
info "Started $0 $*"
debug "Upstream source is: $UPSTREAM::$UPSTREAM_DIR"
debug "Local dir is: $LOCAL_DIR"
debug "Architectures to sync: ${ARCHs[@]}"
debug "Dists to sync: ${DISTs[@]}"
debug "FETCH_I18N: $FETCH_I18N "
debug "FETCH_SOURCES: $FETCH_SOURCES "
debug "FETCH_CONTENTS: $FETCH_CONTENTS "
debug "FETCH_INSTALLER: $FETCH_INSTALLER "
debug "FETCH_DIFF: $FETCH_DIFF "
debug "ARCH_ALL_IS_MANDATORY: $ARCH_ALL_IS_MANDATORY"
debug "POSSIBLE_COMPRESSIONS: ${POSSIBLE_COMPRESSIONS[@]}"
debug "BINROOT: $BINROOT "
# Create dist dir
mkdir -p $LOCAL_DIR/dists
# Array of Packages files, that contains package descriptions
packages_pool_files=()
sources_pool_files=()
debug_job_start "Checking if upstream mirror update is in progress..."
if rsync_file_exists "Archive-Update-in-Progress*"; then
fatal "'Archive-Update-in-Progress' file found on upstream mirror. Aborting"
fi; debug_job_ok
################################################################################
# Stage 1
# Download metainformation files
################################################################################
for dist in "${DISTs[@]}"; do
info "Fetching dist '$dist' lists"
############################################################################
# Phase 1: Check if we have aliased distro and create necessary symlinks
# aliases is specified after '@'-sign in dist name, separated by commas
# For example: 'wheezy@testing,somealias' means dist 'wheezy' with symlinks
# 'testing' and 'somealias' pointing to it
############################################################################
# TODO: get aliases from Release suite
if [ -n ${dist#*@} ]; then
normal_dist="${dist%%@*}"
for dist_alias in `echo ${dist#*@} | tr ',' ' '`; do
if [[ "$dist_alias" == "$normal_dist" ]]; then
continue
fi
if [ ! -L $LOCAL_DIR/dists/$dist_alias ]; then
debug "Creating dist alias '$dist_alias' -> '$normal_dist'"
ln -s "$normal_dist" "$LOCAL_DIR/dists/$dist_alias" || \
error "Error creating alias for $normal_dist ($dist_alias)"
fi
done
dist="$normal_dist"
unset normal_dist
fi
############################################################################
# Phase 2: Create distribution dir
############################################################################
mkdir -p $LOCAL_DIR/dists/$dist/
############################################################################
# Phase 3: Fetch Release files
# InRelease uses new scheme of inline Release signing
# Old scheme implies separate 'Release' and 'Release.gpg' files
############################################################################
debug "Fetching Release files"
for rel_file in InRelease Release Release.gpg; do
fetch "/dists/$dist/$rel_file" "$LOCAL_DIR/dists/$dist/"
done
release_file="$LOCAL_DIR/dists/$dist/InRelease"
# Check InRelease file
if [ -f "$release_file" ]; then
inrl_valid=$(date -d "$(grep Valid-Until "$release_file" | awk '{$1=""; print $0}')" +%s)
now=$(date +%s)
if [[ $(( $now - $inrl_valid )) -gt -86400 ]]; then
info "InRelease file will expire before the next update, removing it..."
rm -f "$release_file"
release_file="$LOCAL_DIR/dists/$dist/Release"
fi
else
release_file="$LOCAL_DIR/dists/$dist/Release"
fi
[ -f "$release_file" ] || fatal "Unable to find release file for dist $dist"
debug "Got Release file '$release_file'"
############################################################################
# Phase 4: check release signature
############################################################################
if [[ "$release_file" =~ ".*InRelease$" ]]; then
gpg --verify "$release_file" || \
fatal "Failed to check signature for $release_file"
elif [[ "$release_file" =~ ".*Release" ]]; then
gpg --verify "${release_file}.gpg" "${release_file}" || \
fatal "Failed to check signature for $release_file"
fi
############################################################################
# Phase 5: Determine which components and arches to download
# Case A: If we have user specified component list, and hasn't found any
# in distro description, then blindly use user given values
# Case B: If we have no user specified component list, try to get them from
# repository Release file, if it fails - bail out
# Case C: If we have both, calculate intersection of them
############################################################################
debug "Calculating arches/components to fetch from dist"
components=`get_dist_components $release_file "${DIST_COMPONENTs[$dist]}"`
arches=`get_dist_architectures $release_file ${ARCHs[@]}`
# Phase 6: Fork components into binary_components
# That allows us to add special sub-components specific to binary components
# such as 'debian-installer'
binary_components="$components"
############################################################################
# Phase 7: Check if we must fetch 'debian-installer' sub-components and add
# them to the binary_components list if needed
############################################################################
if [[ "$FETCH_INSTALLER" = "yes" ]]; then
for component in $components; do
if rsync_file_exists "dists/$dist/$component/debian-installer"; then
debug "Adding debian-installer '$component/debian-installer'"
binary_components="$binary_components $component/debian-installer"
else
error "Not found debian-installer at '$component/debian-installer'"
fi
done
fi
############################################################################
# Phase 8: Fetch binary components 'Packages' indexes and diffs
############################################################################
debug "Will fetch binary components: $binary_components"
for component in $binary_components; do
info "Fetching component '$component' binary package lists"
# Component path
comp_path="dists/$dist/$component"
# Create component dir
mkdir -p "$LOCAL_DIR/$comp_path"
# First, fetch binary packages lists
for arch in $arches; do
arch_path="$comp_path/binary-$arch"
# Check if remote the dir exists
if ! rsync_file_exists "$arch_path"; then
# Missing 'all' architecture in a non critical error
if [[ "$arch" = "all" ]] && [[ "$ARCH_ALL_IS_MANDATORY" != "yes" ]]; then
debug "Missing 'all' architecture in $dist/$component"
continue
fi
fatal "Arch '$arch' in '$dist/$component' doesn't exist"
fi
# Prepare component dir
mkdir -p "$LOCAL_DIR/$arch_path"
to_fetch=()
# List of files that we want to dl
to_fetch+=( "$arch_path/Release" )
to_fetch+=( "$arch_path/Packages" )
for ext in ${POSSIBLE_COMPRESSIONS[@]}; do
to_fetch+=( "$arch_path/Packages.$ext" )
done
# Clean up before fetch
for oldfile in ${to_fetch[@]}; do
debug "Removing old file '${LOCAL_DIR}/${oldfile}'"
rm -f "${LOCAL_DIR}/${oldfile}"
done
# Check if we want a Packages.diff files Index too
if [[ "$FETCH_DIFF" = "yes" ]] && \
rsync_file_exists "$arch_path/Packages.diff/Index"; then
to_fetch+=( `rsync_ls "$arch_path/Packages.diff/*"` )
fi
# Download files in our wishlist and get names of actually
# downloaded files
fetched_files=`fetch_all "$LOCAL_DIR" ${to_fetch[@]}`
# Verify all fetched files
for file in ${fetched_files[@]}; do
# Skip checking of diffs, they are mentioned in Index file
# Validate only Index file
if [[ "`dirname $file`" = "$LOCAL_DIR/$arch_path/Packages.diff" ]]; then
[[ "`basename $file`" != "Index" ]] && continue
fi
# Check file by Release file's checksum
pkg_file_valid "$release_file" "${file#$LOCAL_DIR/dists/$dist/}" &> /dev/null || \
fatal "Checksum check failed for $file"
# Validate that theese friggin file have valid content
algo="${file##*.}"
if [[ " ${POSSIBLE_COMPRESSIONS[@]} " =~ " $algo " ]]; then
if [[ "bz2" == "$algo" ]]; then
decompressor="bunzip2 -c"
elif [[ "gz" == "$algo" ]]; then
decompressor="gunzip -c"
else
decompressor="un${algo} -c"
fi
debug "$file is an '$algo' archive, we should check for it contents (using: $decompressor)"
cat "$file" | ${decompressor} > "${file%.*}"
pkg_path="${file#$LOCAL_DIR/dists/$dist/}"
if pkg_file_valid "$release_file" "${pkg_path%.*}"; then
info "$file is valid archive of ${file%.*}"
else
error "$file is NOT valid archive of ${file%.*}, removing..."
rm -f "${file}"
fi
rm -f "${file%.*}"
else
debug "File $file is not archive, skipping content check..."
fi
done
# Make sure that we have at least one valid packages list
packages_file=`guess_filename "$LOCAL_DIR/$arch_path/Packages"`
if [[ -z "$packages_file" ]]; then
fatal "Failed to find Packages file at $arch_path"
fi
# Check integrity of .diffs if we got them
diff_index=`guess_filename "$LOCAL_DIR/$arch_path/Packages.diff/Index"`
if [[ "$FETCH_DIFF" = "yes" ]] && [[ -n "$diff_index" ]]; then
diffs=`cat $diff_index | awk '/SHA1-Patches:/,0' | tail -n +2 | awk '{print $3}'`
for diff in $diffs; do
debug_job_start "Checking file $LOCAL_DIR/$arch_path/Packages.diff/$diff"
diff_exp_sha1=`cat $diff_index | awk '/SHA1-Patches:/,0' | grep "$diff" | awk '{print $1}'`
diff_real_sha1=`read_file "$LOCAL_DIR/$arch_path/Packages.diff/$diff" | sha1sum | awk '{print $1}'`
if [[ "$diff_exp_sha1" != "$diff_real_sha1" ]]; then
debug_job_err
error "Checksum failed on file $arch_path/Packages.diff/$diff, removing all diffs"
rm -rf "$LOCAL_DIR/$arch_path/Packages.diff"
break
fi
debug_job_ok
done
fi
# Parse package file and add packages from it to dl list
packages_pool_files+=( "$packages_file" )
done
done
############################################################################
# Phase 9: Fetch additional stuff for components, i18n, sources, 'Contents'
############################################################################
for component in $components; do
comp_path="dists/$dist/$component"
mkdir -p "$LOCAL_DIR/$comp_path"
# Second, the i18n packages
info "Fetching section '$component' i18n"
if [[ "$FETCH_I18N" = "yes" ]]; then
mkdir -p "$LOCAL_DIR/$comp_path/i18n/"
to_fetch=()
to_fetch+=( "$comp_path/i18n/Index" )
for i18n in ${I18Ns[@]}; do
to_fetch+=( "$comp_path/i18n/Translation-$i18n" )
# Translation files may have diffs too
to_fetch+=( "$comp_path/i18n/Translation-$i18n.diff/*" )
for ext in ${POSSIBLE_COMPRESSIONS[@]}; do
to_fetch+=( "$comp_path/i18n/Translation-$i18n.$ext" )
done
# Download files in our wishlist and get names of actually
# downloaded files
fetched_files=`fetch_all "$LOCAL_DIR" ${to_fetch[@]}`
# Verify
for file in ${fetched_files[@]}; do
# Skip checking of diffs, except it's Index file
if [[ "`dirname $file`" = "$LOCAL_DIR/$comp_path/i18n/Translation-$i18n.diff" ]]; then
[[ "`basename $file`" != "Index" ]] && continue
fi
debug_job_start "Checking file $file"
pkg_file_valid "$release_file" "${file#$LOCAL_DIR/dists/$dist/}" || \
fatal "Checksum check failed for $file"
debug_job_ok
done
# Check integrity of .diffs if we got them
diff_index=`guess_filename "$LOCAL_DIR/$comp_path/i18n/Translation-$i18n.diff/Index"`
if [[ -n "$diff_index" ]]; then
diffs=`cat $diff_index | awk '/SHA1-Patches:/,0' | tail -n +2 | awk '{print $3}'`
for diff in $diffs; do
debug_job_start "Checking file $LOCAL_DIR/$comp_path/i18n/Translation-$i18n.diff/$diff"
diff_exp_sha1=`cat $diff_index | awk '/SHA1-Patches:/,0' | grep "$diff" | awk '{print $1}'`
diff_real_sha1=`read_file "$LOCAL_DIR/$comp_path/i18n/Translation-$i18n.diff/$diff" | sha1sum | awk '{print $1}'`
if [[ "$diff_exp_sha1" != "$diff_real_sha1" ]]; then
debug_job_err
fatal "Checksum failed on file $comp_path/i18n/Translation-$i18n.diff/$diff"
fi
debug_job_ok
done
fi
done
fi
# Third is the Sources
if [[ "$FETCH_SOURCES" = "yes" ]]; then
info "Fetching component '$component' source package lists"
mkdir -p "$LOCAL_DIR/$comp_path/source/"
to_fetch=()
to_fetch+=( "$comp_path/source/Release" )
to_fetch+=( "$comp_path/source/Sources" )
for ext in ${POSSIBLE_COMPRESSIONS[@]}; do
to_fetch+=( "$comp_path/source/Sources.$ext" )
done
# Clean up before fetch
for oldfile in ${to_fetch[@]}; do
debug "Removing old file '${LOCAL_DIR}/${oldfile}'"
rm -f "${LOCAL_DIR}/${oldfile}"
done
# Download files in our wishlist and get names of actually
# downloaded files
fetched_files=`fetch_all "$LOCAL_DIR" ${to_fetch[@]}`
# Verify
for file in ${fetched_files[@]}; do
pkg_file_valid "$release_file" "${file#$LOCAL_DIR/dists/$dist/}" || \
fatal "Checksum check failed for $file"
# Validate that theese friggin file have valid content
algo="${file##*.}"
if [[ " ${POSSIBLE_COMPRESSIONS[@]} " =~ " $algo " ]]; then
if [[ "bz2" == "$algo" ]]; then
decompressor="bunzip2 -c"
elif [[ "gz" == "$algo" ]]; then
decompressor="gunzip -c"
else
decompressor="un${algo} -c"
fi
debug "$file is an '$algo' archive, we should check for it contents (using: $decompressor)"
cat "$file" | ${decompressor} > "${file%.*}"
pkg_path="${file#$LOCAL_DIR/dists/$dist/}"
if pkg_file_valid "$release_file" "${pkg_path%.*}"; then
info "$file is valid archive of ${file%.*}"
else
error "$file is NOT valid archive of ${file%.*}, removing..."
rm -f "${file}"
fi
rm -f "${file%.*}"
else
debug "File $file is not archive, skipping content check..."
fi
done
sources_file=`guess_filename "$LOCAL_DIR/$comp_path/source/Sources"`
if [[ -z "$sources_file" ]]; then
fatal "Failed to find Sources file at $LOCAL_DIR/$comp_path/source"
fi
# Parse sources file and add packages from it to dl list
sources_pool_files+=( "$sources_file" )
fi
# Fetch the component contents packs
if [[ "$FETCH_CONTENTS" = "yes" ]]; then
info "Fetching component '$component' content lists"
to_fetch=()
for arch in $arches; do
to_fetch+=( "$comp_path/Contents-$arch" )
for ext in ${POSSIBLE_COMPRESSIONS[@]}; do
to_fetch+=( "$comp_path/Contents-$arch.$ext" )
done
done
# Download files in our wishlist and get names of actually
# downloaded files
fetched_files=`fetch_all "$LOCAL_DIR" ${to_fetch[@]}`
# Verify
for file in ${fetched_files[@]}; do
pkg_file_valid "$release_file" "${file#$LOCAL_DIR/dists/$dist/}" || \
fatal "Checksum check failed for $file"
done
# If our component is "main", make link in the root of distribution
if [[ "$component" = "main" ]]; then
for arch in $arches; do
if [[ -e "$LOCAL_DIR/dists/$dist/$component/Contents-$arch.gz" ]]; then
debug "Creating link to main/Contents-$arch.gz at $LOCAL_DIR/dists/$dist"
ln -sf main/Contents-$arch.gz $LOCAL_DIR/dists/$dist/Contents-$arch.gz
else
debug "Deleting link to main/Contents-$arch.gz at $LOCAL_DIR/dists/$dist"
rm -f "$LOCAL_DIR/dists/$dist/Contents-$arch.gz"
fi
done
fi
fi
done
done
################################################################################
# Stage 2
# Download pool of packages
################################################################################
info "Parsing package and sources files files:"
info "${packages_pool_files[@]}"
info "${sources_pool_files[@]}"
files_to_dl_list=`mktemp --suffix="-deb-mirror"`
# File that contains md5sums of deb pkgs
deb_md5=`mktemp --suffix="-deb-mirror-md5"`
rsync_log=`mktemp --suffix="-deb-mirror-rslog"`
$BINROOT/util/parse_packages.py ${packages_pool_files[@]} > "$files_to_dl_list" \
2> "$deb_md5" && \
$BINROOT/util/parse_sources.py ${sources_pool_files[@]} >> "$files_to_dl_list" || \
fatal "Unable to create list of packages to fetch"
# Subroutine to check md5 sum for the file
#check_md5_file()
#{
# debug_job_start "Checking md5sum of file '$LOCAL_DIR/$1'"
# expected_md5=`grep "$1" "$deb_md5" | awk '{print $1}' | head -n 1`
# [[ -z "$expected_md5" ]] && echo -n "ms5sum not found..." \
# && debug_job_skip && return 0
#
# actual_md5=`md5sum "$LOCAL_DIR/$1" | head -c 32`
# [[ "$expected_md5" == "$actual_md5" ]] && debug_job_ok && return 0
# debug_job_err
# return 1
#}
info "Downloading pool files"
rsync --verbose --out-format="%i %n" --stats \
--recursive --perms --links --times --hard-links --sparse --safe-links \
--exclude=".tmp/" --exclude=".temp/" --exclude=".~tmp~/" \
--files-from="$files_to_dl_list" \
--bwlimit=5192 \
"${UPSTREAM}::${UPSTREAM_DIR}/" "$LOCAL_DIR" | tee "$rsync_log"
# --files-from="$files_to_dl_list" \--block-size=8192
#--max-delete=40000 --delay-updates --delete --delete-after \
# Check if rsync was ok
if [[ $? != 0 ]]; then
rm "$files_to_dl_list"
fatal "Failed to sync all package files, see log for details"
#error "Failed to sync all package files, see log for details"
else
info "Primary sync successfully completed"
fi
# Let's check new file MD5sums
fresh_files=`egrep "^>f......... .*" "$rsync_log" | awk '{print $2}'`
for fresh_file in $fresh_files; do
check_file "$deb_md5" "$LOCAL_DIR" "$fresh_file"
if [[ $? != 0 ]]; then
rm "$deb_md5"
rm "$rsync_log"
fatal "MD5sum check failed for file $LOCAL_DIR/$fresh_file"
fi
done
rm "$deb_md5"
rm "$rsync_log"
# Now iterate through all downloaded files and check if any of them are symlink
# download neccessary files if needed
# Yeah, some times section can contain a metainfo for symlink to file in
# diffirent section that is no longer exists in there, so it will be wiped as
# unused
wayback="`pwd`"
cd "$LOCAL_DIR/"
info "Checking for treacherous cross-section symlinks"
info "Total files `cat $files_to_dl_list | grep "^pool" | wc -l`"
for file_to_dl in `cat $files_to_dl_list | grep "^pool"`; do
if [[ -L "$LOCAL_DIR/$file_to_dl" ]]; then
realfile=`readlink -m $file_to_dl`
info "File $LOCAL_DIR/$file_to_dl is a link to $realfile, adding..."
echo "${realfile#$LOCAL_DIR/*}" >> $files_to_dl_list
if [[ ! -f "$realfile" ]]; then
error "File $realfile not found, attempting to redownload..."
fetch "${realfile#${LOCAL_DIR}*}" "$realfile"
fi
fi
done
pool_current_files=`mktemp --suffix d-m_got`
pool_required_files=`mktemp --suffix d-m_req`
# Create lists of files that we got and that we need
find pool -type f -or -type l | sort -u > $pool_current_files
cat $files_to_dl_list | grep "^pool" | sort -u > $pool_required_files
cd "$wayback"
info "Cleaning up pool files"
# Clean obsolete files
obsolete_files=`comm -3 -2 "$pool_current_files" "$pool_required_files"`
for file in $obsolete_files; do
debug_job_start "Deleting '$LOCAL_DIR/$file'"
rm "$LOCAL_DIR/$file" && debug_job_ok || debug_job_err
done
info "Doublechecking that required pool files exists"
missing_files=`comm -3 -1 "$pool_current_files" "$pool_required_files"`
if [[ -n "$missing_files" ]]; then
error "Some files are missing after sync!!!:"
error "$missing_files"
fatal "Aborting due to missing files"
fi
rm "$files_to_dl_list"
rm "$pool_required_files"
rm "$pool_current_files"
# Create trace if exists
if rsync_file_exists "project/trace"; then
info "Setting up trace file"
rm -rf "$LOCAL_DIR/project/trace/"
mkdir -p "$LOCAL_DIR/project/trace/"
fetch "/project/trace/*" "$LOCAL_DIR/project/trace/"
trace_file="$LOCAL_DIR/project/trace/$LOCAL_FQDN"
LC_ALL=POSIX LANG=POSIX date -u > "$trace_file"
echo "Used '`basename $0`' version: ${VERSION}" >> "$trace_file"
echo "Running on host: ${LOCAL_FQDN}" >> "$trace_file"
echo "Architectures: ${ARCHs[@]}" >> "$trace_file"
echo "Upstream-mirror: ${UPSTREAM}" >> "$trace_file"
else
info "No trace found upstream, skipping..."
fi
# Timestamp
echo "Updated at: `date`" > $LOCAL_DIR/.lastupdate