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
|
#!/bin/sh
#
#set -e
#
# This file understands the following apt configuration variables:
#
# "APT::Periodic::Update-Package-Lists=1"
# - Do "apt-get update" automatically every n-days (0=disable)
#
# "APT::Periodic::Download-Upgradeable-Packages=0",
# - Do "apt-get upgrade --download-only" every n-days (0=disable)
#
# "APT::Periodic::AutocleanInterval"
# - Do "apt-get autoclean" every n-days (0=disable)
#
# "APT::Periodic::Unattended-Upgrade"
# - Run the "unattended-upgrade" security upgrade script
# every n-days (0=disabled)
# Requires the package "unattended-upgrades" and will write
# a log in /var/log/unattended-upgrades
#
# "APT::Archives::MaxAge",
# - Set maximum allowed age of a cache package file. If a cache
# package file is older it is deleted (0=disable)
#
# "APT::Archives::MaxSize",
# - Set maximum size of the cache in MB (0=disable). If the cache
# is bigger, cached package files are deleted until the size
# requirement is met (the biggest packages will be deleted
# first).
#
# "APT::Archives::MinAge"
# - Set minimum age of a package file. If a file is younger it
# will not be deleted (0=disable). Usefull to prevent races
# and to keep backups of the packages for emergency.
#
check_stamp()
{
stamp="$1"
interval="$2"
if [ $interval -eq 0 ]; then
return 1
fi
if [ ! -f $stamp ]; then
return 0
fi
# compare midnight today to midnight the day the stamp was updated
stamp_file="$stamp"
stamp=$(date --date=$(date -r $stamp_file --iso-8601) +%s 2>/dev/null)
if [ "$?" != "0" ]; then
# Due to some timezones returning 'invalid date' for midnight on
# certain dates (eg America/Sao_Paulo), if date returns with error
# remove the stamp file and return 0. See coreutils bug:
# http://lists.gnu.org/archive/html/bug-coreutils/2007-09/msg00176.html
rm -f "$stamp_file"
return 0
fi
now=$(date --date=$(date --iso-8601) +%s 2>/dev/null)
if [ "$?" != "0" ]; then
# As above, due to some timezones returning 'invalid date' for midnight
# on certain dates (eg America/Sao_Paulo), if date returns with error
# return 0.
return 0
fi
delta=$(($now-$stamp))
# intervall is in days,
interval=$(($interval*60*60*24))
#echo "stampfile: $1"
#echo "interval=$interval, now=$now, stamp=$stamp, delta=$delta"
# remove timestamps a day (or more) in the future and force re-check
if [ $stamp -gt $(($now+86400)) ]; then
echo "WARNING: file $stamp_file has a timestamp in the future: $stamp"
rm -f "$stamp_file"
return 0
fi
if [ $delta -ge $interval ]; then
return 0
fi
return 1
}
update_stamp()
{
stamp="$1"
touch $stamp
}
# we check here if autoclean was enough sizewise
check_size_constraints()
{
# min-age in days
MaxAge=0
MinAge=2
MaxSize=0
CacheDir="var/cache/apt"
CacheArchive="archives/"
eval $(apt-config shell MaxAge APT::Archives::MaxAge)
eval $(apt-config shell MinAge APT::Archives::MinAge)
eval $(apt-config shell MaxSize APT::Archives::MaxSize)
eval $(apt-config shell Dir Dir)
eval $(apt-config shell CacheDir Dir::Cache)
eval $(apt-config shell CacheArchive Dir::Cache::archives)
# sanity check
if [ -z "$CacheDir" -o -z "$CacheArchive" ]; then
echo "empty Dir::Cache or Dir::Cache::archives, exiting"
exit
fi
Cache="${Dir%/}/${CacheDir%/}/${CacheArchive%/}/"
# check age
if [ ! $MaxAge -eq 0 ] && [ ! $MinAge -eq 0 ]; then
find $Cache -name "*.deb" \( -mtime +$MaxAge -and -ctime +$MaxAge \) -and -not \( -mtime -$MinAge -or -ctime -$MinAge \) -print0 | xargs -r -0 rm -f
elif [ ! $MaxAge -eq 0 ]; then
find $Cache -name "*.deb" -ctime +$MaxAge -and -mtime +$MaxAge -print0 | xargs -r -0 rm -f
fi
# check size
if [ ! $MaxSize -eq 0 ]; then
# maxSize is in MB
MaxSize=$(($MaxSize*1024))
#get current time
now=$(date --date=$(date --iso-8601) +%s)
MinAge=$(($MinAge*24*60*60))
# reverse-sort by mtime
for file in $(ls -rt $Cache/*.deb 2>/dev/null); do
du=$(du -s $Cache)
size=${du%%/*}
# check if the cache is small enough
if [ $size -lt $MaxSize ]; then
break
fi
# check for MinAge of the file
if [ ! $MinAge -eq 0 ]; then
# check both ctime and mtime
mtime=$(stat -c %Y $file)
ctime=$(stat -c %Z $file)
if [ $mtime -gt $ctime ]; then
delta=$(($now-$mtime))
else
delta=$(($now-$ctime))
fi
#echo "$file ($delta), $MinAge"
if [ $delta -le $MinAge ]; then
#echo "Skiping $file (delta=$delta)"
break
fi
fi
# delete oldest file
rm -f $file
done
fi
}
# sleep for a random interval of time (default 30min)
# (some code taken from cron-apt, thanks)
random_sleep()
{
RandomSleep=1800
eval $(apt-config shell RandomSleep APT::Periodic::RandomSleep)
if [ $RandomSleep -eq 0 ]; then
return
fi
if [ -z "$RANDOM" ] ; then
# A fix for shells that do not have this bash feature.
RANDOM=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -c"1-5")
fi
TIME=$(($RANDOM % $RandomSleep))
sleep $TIME
}
# main
if ! which apt-config >/dev/null; then
exit 0
fi
UpdateInterval=0
DownloadUpgradeableInterval=0
eval $(apt-config shell UpdateInterval APT::Periodic::Update-Package-Lists DownloadUpgradeableInterval APT::Periodic::Download-Upgradeable-Packages)
AutocleanInterval=$DownloadUpgradeableInterval
eval $(apt-config shell AutocleanInterval APT::Periodic::AutocleanInterval)
UnattendedUpgradeInterval=0
eval $(apt-config shell UnattendedUpgradeInterval APT::Periodic::Unattended-Upgrade)
# check if we actually have to do anything
if [ $UpdateInterval -eq 0 ] &&
[ $DownloadUpgradeableInterval -eq 0 ] &&
[ $UnattendedUpgradeInterval -eq 0 ] &&
[ $AutocleanInterval -eq 0 ]; then
exit 0
fi
# laptop check, on_ac_power returns:
# 0 (true) System is on mains power
# 1 (false) System is not on mains power
# 255 (false) Power status could not be determined
# Desktop systems always return 255 it seems
if which on_ac_power >/dev/null; then
on_ac_power
if [ $? -eq 1 ]; then
exit 0
fi
fi
# sleep random amount of time to avoid hitting the
# mirrors at the same time
random_sleep
# check if we can access the cache
if ! apt-get check -q -q 2>/dev/null; then
# wait random amount of time before retrying
random_sleep
# check again
if ! apt-get check -q -q 2>/dev/null; then
echo "$0: could not lock the APT cache while performing daily cron job. "
echo "Is another package manager working?"
exit 1
fi
fi
# set the proxy based on the admin users gconf settings
admin_user=$(getent group admin|cut -d: -f4|cut -d, -f1)
if [ -n "$admin_user" ] && [ -x /usr/bin/sudo ] && [ -z "$http_proxy" ] && [ -x /usr/bin/gconftool ]; then
use=$(sudo -u "$admin_user" gconftool --get /system/http_proxy/use_http_proxy 2>/dev/null)
host=$(sudo -u "$admin_user" gconftool --get /system/http_proxy/host 2>/dev/null)
port=$(sudo -u "$admin_user" gconftool --get /system/http_proxy/port 2>/dev/null)
if [ "$use" = "true" ] && [ -n "$host" ] && [ -n "$port" ]; then
export http_proxy="http://$host:$port/"
fi
fi
UPDATE_STAMP=/var/lib/apt/periodic/update-stamp
if check_stamp $UPDATE_STAMP $UpdateInterval; then
# check for a new archive signing key (against the master keyring)
apt-key net-update
# now run the update
if apt-get -qq update -o APT::Update::Auth-Failure::="cp /usr/share/apt/apt-auth-failure.note /var/lib/update-notifier/user.d/" 2>/dev/null; then
# Could possible test access to '/var/run/dbus/system_bus_socket' has well,
# but I'm not sure how stable the internal pipe location is defined as
# being; so for the moment just 2>/dev/null . --sladen 2007-09-27
if which dbus-send >/dev/null; then
dbus-send --system / app.apt.dbus.updated boolean:true 2>/dev/null || true
fi
# now run apt-xapian-index if it is installed to ensure the index
# is up-to-date
if [ -x /usr/sbin/update-apt-xapian-index ]; then
ionice -c3 update-apt-xapian-index -q
fi
update_stamp $UPDATE_STAMP
fi
fi
DOWNLOAD_UPGRADEABLE_STAMP=/var/lib/apt/periodic/download-upgradeable-stamp
if check_stamp $DOWNLOAD_UPGRADEABLE_STAMP $DownloadUpgradeableInterval; then
apt-get -qq -d dist-upgrade 2>/dev/null
update_stamp $DOWNLOAD_UPGRADEABLE_STAMP
fi
UPGRADE_STAMP=/var/lib/apt/periodic/upgrade-stamp
if check_stamp $UPGRADE_STAMP $UnattendedUpgradeInterval; then
unattended-upgrade
update_stamp $UPGRADE_STAMP
fi
AUTOCLEAN_STAMP=/var/lib/apt/periodic/autoclean-stamp
if check_stamp $AUTOCLEAN_STAMP $AutocleanInterval; then
apt-get -qq autoclean
update_stamp $AUTOCLEAN_STAMP
fi
# check cache size
check_size_constraints
|