Revision 2958c56e

b/.gitignore
40 40
# daemons
41 41
/daemons/daemon-util
42 42
/daemons/ganeti-cleaner
43
/daemons/ganeti-master-cleaner
43 44
/daemons/ganeti-confd
44 45
/daemons/ganeti-masterd
45 46
/daemons/ganeti-noded
b/Makefile.am
154 154
	$(SHELL_ENV_INIT) \
155 155
	daemons/daemon-util \
156 156
	daemons/ganeti-cleaner \
157
	daemons/ganeti-master-cleaner \
157 158
	devel/upload \
158 159
	$(BUILT_EXAMPLES) \
159 160
	doc/examples/bash_completion \
......
652 653

  
653 654
nodist_sbin_SCRIPTS = \
654 655
	$(PYTHON_BOOTSTRAP_SBIN) \
655
	daemons/ganeti-cleaner
656
	daemons/ganeti-cleaner \
657
	daemons/ganeti-master-cleaner
656 658

  
657 659
if HS_CONFD
658 660
nodist_sbin_SCRIPTS += htools/hconfd
......
719 721
	$(RUN_IN_TEMPDIR) \
720 722
	daemons/daemon-util.in \
721 723
	daemons/ganeti-cleaner.in \
724
	daemons/ganeti-master-cleaner.in \
722 725
	$(pkglib_python_scripts) \
723 726
	devel/upload.in \
724 727
	tools/kvm-ifup.in \
......
754 757
man_MANS = \
755 758
	man/ganeti.7 \
756 759
	man/ganeti-cleaner.8 \
760
	man/ganeti-master-cleaner.8 \
757 761
	man/ganeti-confd.8 \
758 762
	man/ganeti-listrunner.8 \
759 763
	man/ganeti-masterd.8 \
......
1047 1051

  
1048 1052
test/daemon-util_unittest.bash: daemons/daemon-util
1049 1053

  
1050
test/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner
1054
test/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner \
1055
  daemons/ganeti-master-cleaner
1051 1056

  
1052 1057
test/bash_completion.bash: doc/examples/bash_completion-debug
1053 1058

  
b/daemons/ganeti-cleaner.in
26 26
: ${CHECK_CERT_EXPIRED:=$PKGLIBDIR/check-cert-expired}
27 27

  
28 28
readonly CLEANER_LOG_DIR=$LOG_DIR/cleaner
29
readonly QUEUE_ARCHIVE_DIR=$DATA_DIR/queue/archive
30 29
readonly CRYPTO_DIR=$RUN_DIR/crypto
31 30

  
32 31
in_cluster() {
33 32
  [[ -e $DATA_DIR/ssconf_master_node ]]
34 33
}
35 34

  
36
cleanup_master() {
37
  # Return if machine is not part of a cluster
38
  in_cluster || return 0
39

  
40
  # Return if queue archive directory doesn't exist
41
  [[ -d $QUEUE_ARCHIVE_DIR ]] || return 0
42

  
43
  # Remove old jobs
44
  find $QUEUE_ARCHIVE_DIR -mindepth 2 -type f -mtime +$REMOVE_AFTER -print0 | \
45
  xargs -r0 rm -vf
46
}
47

  
48 35
cleanup_node() {
49 36
  # Return if directory for crypto keys doesn't exist
50 37
  [[ -d $CRYPTO_DIR ]] || return 0
......
90 77
find $CLEANER_LOG_DIR -maxdepth 1 -type f | sort | head -n -$KEEP_LOGS | \
91 78
xargs -r rm -vf
92 79

  
93
cleanup_master
94 80
cleanup_node
95 81
cleanup_watcher
96 82

  
b/daemons/ganeti-master-cleaner.in
1
#!/bin/bash
2
#
3

  
4
# Copyright (C) 2009, 2010, 2011, 2012 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

  
21
set -e -u
22

  
23
@SHELL_ENV_INIT@
24

  
25
readonly CLEANER_LOG_DIR=$LOG_DIR/master-cleaner
26
readonly QUEUE_ARCHIVE_DIR=$DATA_DIR/queue/archive
27

  
28
in_cluster() {
29
  [[ -e $DATA_DIR/ssconf_master_node ]]
30
}
31

  
32
cleanup_master() {
33
  # Return if machine is not part of a cluster
34
  in_cluster || return 0
35

  
36
  # Return if queue archive directory doesn't exist
37
  [[ -d $QUEUE_ARCHIVE_DIR ]] || return 0
38

  
39
  # Remove old jobs
40
  find $QUEUE_ARCHIVE_DIR -mindepth 2 -type f -mtime +$REMOVE_AFTER -print0 | \
41
  xargs -r0 rm -vf
42
}
43

  
44
# Define how many days archived jobs should be left alone
45
REMOVE_AFTER=21
46

  
47
# Define how many log files to keep around (usually one per day)
48
KEEP_LOGS=50
49

  
50
# Log file for this run
51
LOG_FILE=$CLEANER_LOG_DIR/cleaner-$(date +'%Y-%m-%dT%H_%M').$$.log
52

  
53
# Create log directory
54
mkdir -p $CLEANER_LOG_DIR
55

  
56
# Redirect all output to log file
57
exec >>$LOG_FILE 2>&1
58

  
59
echo "Cleaner started at $(date)"
60

  
61
# Remove old cleaner log files
62
find $CLEANER_LOG_DIR -maxdepth 1 -type f | sort | head -n -$KEEP_LOGS | \
63
xargs -r rm -vf
64

  
65
cleanup_master
66

  
67
exit 0
b/doc/examples/ganeti.cron.in
4 4
*/5 * * * * root [ -x @SBINDIR@/ganeti-watcher ] && @SBINDIR@/ganeti-watcher
5 5

  
6 6
# Clean job archive (at 01:45 AM)
7
45 1 * * * root [ -x @SBINDIR@/ganeti-cleaner ] && @SBINDIR@/ganeti-cleaner
7
45 1 * * * @GNTMASTERUSER@ [ -x @SBINDIR@/ganeti-master-cleaner ] && @SBINDIR@/ganeti-master-cleaner
8

  
9
# Clean job archive (at 02:45 AM)
10
45 2 * * * @GNTNODEDUSER@ [ -x @SBINDIR@/ganeti-cleaner ] && @SBINDIR@/ganeti-cleaner
b/lib/tools/ensure_dirs.py
124 124
  rapi_log = constants.DAEMONS_LOGFILES[constants.RAPI]
125 125

  
126 126
  rapi_dir = os.path.join(pathutils.DATA_DIR, "rapi")
127
  cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "cleaner")
128
  master_cleaner_log_dir = os.path.join(pathutils.LOG_DIR, "master-cleaner")
127 129

  
128 130
  paths = [
129 131
    (pathutils.DATA_DIR, DIR, 0755, getent.masterd_uid,
......
192 194
    (rapi_log, FILE, 0600, getent.rapi_uid, getent.masterd_gid, False),
193 195
    (pathutils.LOG_OS_DIR, DIR, 0750, getent.masterd_uid,
194 196
     getent.daemons_gid),
197
    (cleaner_log_dir, DIR, 0750, getent.noded_uid, getent.noded_gid),
198
    (master_cleaner_log_dir, DIR, 0750, getent.masterd_uid, getent.masterd_gid),
195 199
    ])
196 200

  
197 201
  return paths
b/man/ganeti-cleaner.rst
14 14
DESCRIPTION
15 15
-----------
16 16

  
17
The **ganeti-cleaner** is a periodically run script to clean old job
18
files from the job queue archive and to remove expired X509
19
certificates and keys.
17
The **ganeti-cleaner** is a periodically run script to remove expired
18
X509 certificates and keys, as well as outdated **ganeti-watcher**
19
information.
20 20

  
21
**ganeti-cleaner** automatically removes all files older than 21 days
22
from ``@LOCALSTATEDIR@/lib/ganeti/queue/archive`` and all expired
23
certificates and keys from ``@LOCALSTATEDIR@/run/ganeti/crypto``.
21
**ganeti-cleaner** automatically removes  all expired certificates and
22
keys from ``@LOCALSTATEDIR@/run/ganeti/crypto``.
24 23

  
25 24
.. vim: set textwidth=72 :
26 25
.. Local Variables:
b/man/ganeti-master-cleaner.rst
1
ganeti-master-cleaner(8) Ganeti | Version @GANETI_VERSION@
2
==========================================================
3

  
4
Name
5
----
6

  
7
ganeti-master-cleaner - Ganeti job queue cleaner
8

  
9
Synopsis
10
--------
11

  
12
**ganeti-master-cleaner**
13

  
14
DESCRIPTION
15
-----------
16

  
17
The **ganeti-master-cleaner** is a periodically run script to clean old
18
job files from the job queue archive.
19

  
20
**ganeti-master-cleaner** automatically removes all files older than 21
21
days from ``@LOCALSTATEDIR@/lib/ganeti/queue/archive``.
22

  
23
.. vim: set textwidth=72 :
24
.. Local Variables:
25
.. mode: rst
26
.. fill-column: 72
27
.. End:
b/test/ganeti-cleaner_unittest.bash
24 24
export PYTHON=${PYTHON:=python}
25 25

  
26 26
GNTC=daemons/ganeti-cleaner
27
GNTMC=daemons/ganeti-master-cleaner
27 28
CCE=tools/check-cert-expired
28 29

  
29 30
err() {
......
44 45
}
45 46

  
46 47
check_logfiles() {
47
  local n=$1
48
  [[ "$(find $tmpls/log/ganeti/cleaner -mindepth 1 | wc -l)" -le "$n" ]] || \
48
  local n=$1 p=$2 path
49
  if [[ "$p2" = master ]]; then
50
    path=$tmpls/log/ganeti/mastercleaner
51
  else
52
    path=$tmpls/log/ganeti/cleaner
53
  fi
54
  [[ "$(find $path -mindepth 1 | wc -l)" -le "$n" ]] || \
49 55
    err "Found more than $n logfiles"
50 56
}
51 57

  
......
77 83
}
78 84

  
79 85
run_cleaner() {
80
  CHECK_CERT_EXPIRED=$CCE LOCALSTATEDIR=$tmpls $GNTC
86
  local cmd
87

  
88
  if [[ "$1" = master ]]; then
89
    cmd=$GNTMC
90
  else
91
    cmd=$GNTC
92
  fi
93

  
94
  CHECK_CERT_EXPIRED=$CCE LOCALSTATEDIR=$tmpls $cmd
81 95
}
82 96

  
83 97
create_archived_jobs() {
......
162 176
test -d $tmpls/log/ganeti/cleaner || err 'log/ganeti/cleaner should exist'
163 177
check_logfiles 1
164 178

  
165
upto 'Checking number of retained log files'
179
test -d $tmpls/log/ganeti/master-cleaner && \
180
  err 'log/ganeti/master-cleaner should not exist yet'
181
run_cleaner master
182
test -d $tmpls/log/ganeti/master-cleaner || \
183
  err 'log/ganeti/master-cleaner should exist'
184
check_logfiles 1 master
185

  
186
upto 'Checking number of retained log files (master)'
187
for (( i=0; i < (maxlog + 10); ++i )); do
188
  run_cleaner master
189
  check_logfiles 1
190
  check_logfiles $(( (i + 2) > $maxlog?$maxlog:(i + 2) )) master
191
done
192

  
193
upto 'Checking number of retained log files (node)'
166 194
for (( i=0; i < (maxlog + 10); ++i )); do
167 195
  run_cleaner
168 196
  check_logfiles $(( (i + 2) > $maxlog?$maxlog:(i + 2) ))
197
  check_logfiles $maxlog master
169 198
done
170 199

  
171 200
upto 'Removal of archived jobs (non-master)'
......
175 204
  err 'ssconf_master_node should not exist'
176 205
run_cleaner
177 206
count_jobs 55
207
run_cleaner master
208
count_jobs 55
178 209

  
179 210
upto 'Removal of archived jobs (master node)'
180 211
create_archived_jobs
181 212
count_jobs 55
182 213
echo $HOSTNAME > $tmpls/lib/ganeti/ssconf_master_node
183 214
run_cleaner
215
count_jobs 55
216
run_cleaner master
184 217
count_jobs 31
185 218

  
186 219
upto 'Certificate expiration'
......
191 224
create_certdirs $tmpdir/expcert bar{x,y,z}999 fx0ljoImWr em3RBC0U8c
192 225
create_certdirs '' empty{1,2,3} gd2HCvRc iFG55Z0a PP28v5kg
193 226
count_and_check_certs 10
227
run_cleaner master
228
count_and_check_certs 10
194 229
run_cleaner
195 230
count_and_check_certs 5
196 231

  
197 232
check_logfiles $maxlog
233
check_logfiles $maxlog master
198 234
count_jobs 31
199 235

  
200 236
upto 'Watcher status files'
201 237
create_watcher_state
202 238
count_watcher data 10
203 239
count_watcher instance-status 10
240
run_cleaner master
241
count_watcher data 10
242
count_watcher instance-status 10
204 243
run_cleaner
205 244
count_watcher data 5
206 245
count_watcher instance-status 5

Also available in: Unified diff