Revision 46118ed2

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

  
647 646
nodist_sbin_SCRIPTS = \
648 647
	$(PYTHON_BOOTSTRAP_SBIN) \
649
	daemons/ganeti-cleaner \
650
	daemons/ganeti-master-cleaner
648
	daemons/ganeti-cleaner
651 649

  
652 650
if ENABLE_CONFD
653 651
htools/ganeti-confd: htools/hconfd
......
717 715
	$(RUN_IN_TEMPDIR) \
718 716
	daemons/daemon-util.in \
719 717
	daemons/ganeti-cleaner.in \
720
	daemons/ganeti-master-cleaner.in \
721 718
	$(pkglib_python_scripts) \
722 719
	devel/upload.in \
723 720
	tools/kvm-ifup.in \
......
754 751
	man/ganeti-cleaner.8 \
755 752
	man/ganeti-confd.8 \
756 753
	man/ganeti-listrunner.8 \
757
	man/ganeti-master-cleaner.8 \
758 754
	man/ganeti-masterd.8 \
759 755
	man/ganeti-noded.8 \
760 756
	man/ganeti-os-interface.7 \
......
1045 1041

  
1046 1042
test/daemon-util_unittest.bash: daemons/daemon-util
1047 1043

  
1048
test/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner \
1049
  daemons/ganeti-master-cleaner
1044
test/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner
1050 1045

  
1051 1046
test/bash_completion.bash: doc/examples/bash_completion-debug
1052 1047

  
......
1075 1070
doc/examples/bash_completion doc/examples/bash_completion-debug: \
1076 1071
	$(BUILD_BASH_COMPLETION) $(RUN_IN_TEMPDIR) \
1077 1072
	lib/cli.py $(gnt_scripts) $(client_PYTHON) tools/burnin \
1073
	daemons/ganeti-cleaner \
1078 1074
	$(GENERATED_FILES) $(HTOOLS_GENERATED_FILES)
1079 1075
	PYTHONPATH=. $(RUN_IN_TEMPDIR) \
1080 1076
	  $(CURDIR)/$(BUILD_BASH_COMPLETION) $(BC_ARGS) > $@
b/autotools/build-bash-completion
668 668

  
669 669
#: serialised kind to arg type
670 670
_ARG_MAP = {
671
  "choices": cli.ArgChoice,
671 672
  "command": cli.ArgCommand,
672 673
  "file": cli.ArgFile,
673 674
  "host": cli.ArgHost,
......
677 678
  "onenode": cli.ArgNode,
678 679
  "oneos": cli.ArgOs,
679 680
  "string": cli.ArgUnknown,
681
  "suggests": cli.ArgSuggest,
680 682
  }
681 683

  
682 684

  
......
724 726
    env = {}
725 727
    script_name = os.path.basename(script)
726 728
    func_name = script_name
729
  func_name = func_name.replace("-", "_")
727 730
  output = utils.RunCmd([cmd, "--help-completion"], env=env, cwd=".").output
728 731
  cli_opts = []
729 732
  args = []
......
781 784
                  not options.compact,
782 785
                  opts=burnin.OPTIONS, args=burnin.ARGUMENTS)
783 786

  
787
  # ganeti-cleaner
788
  WriteHaskellCompletion(sw, "daemons/ganeti-cleaner", htools=False,
789
                         debug=not options.compact)
790

  
784 791
  # htools, if enabled
785 792
  if _autoconf.HTOOLS:
786 793
    for script in _autoconf.HTOOLS_PROGS:
b/daemons/ganeti-cleaner.in
25 25
# Overridden by unittest
26 26
: ${CHECK_CERT_EXPIRED:=$PKGLIBDIR/check-cert-expired}
27 27

  
28
readonly CLEANER_LOG_DIR=$LOG_DIR/cleaner
28
usage() {
29
    echo "Usage: $0 node|master" 2>&1
30
    exit $1
31
}
32

  
33
if [[ "$#" -ne 1 ]]; then
34
  usage 1
35
fi
36

  
37
case "$1" in
38
  node)
39
    readonly CLEANER_LOG_DIR=$LOG_DIR/cleaner
40
    ;;
41
  master)
42
    readonly CLEANER_LOG_DIR=$LOG_DIR/master-cleaner
43
    ;;
44
  --help-completion)
45
    echo "choices=node,master 1 1"
46
    exit 0
47
    ;;
48
  --help)
49
    usage 0
50
    ;;
51
  *)
52
    usage 1
53
    ;;
54
esac
55

  
29 56
readonly CRYPTO_DIR=$RUN_DIR/crypto
57
readonly QUEUE_ARCHIVE_DIR=$DATA_DIR/queue/archive
30 58

  
31 59
in_cluster() {
32 60
  [[ -e $DATA_DIR/ssconf_master_node ]]
......
56 84
  xargs -r0 rm -vf
57 85
}
58 86

  
87
cleanup_master() {
88
  # Return if machine is not part of a cluster
89
  in_cluster || return 0
90

  
91
  # Return if queue archive directory doesn't exist
92
  [[ -d $QUEUE_ARCHIVE_DIR ]] || return 0
93

  
94
  # Remove old jobs
95
  find $QUEUE_ARCHIVE_DIR -mindepth 2 -type f -mtime +$REMOVE_AFTER -print0 | \
96
  xargs -r0 rm -vf
97
}
98

  
59 99
# Define how many days archived jobs should be left alone
60 100
REMOVE_AFTER=21
61 101

  
......
77 117
find $CLEANER_LOG_DIR -maxdepth 1 -type f | sort | head -n -$KEEP_LOGS | \
78 118
xargs -r rm -vf
79 119

  
80
cleanup_node
81
cleanup_watcher
120
case "$1" in
121
  node)
122
    cleanup_node
123
    cleanup_watcher
124
    ;;
125
  master)
126
    cleanup_master
127
    ;;
128
esac
82 129

  
83 130
exit 0
/dev/null
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 * * * @GNTMASTERUSER@ [ -x @SBINDIR@/ganeti-master-cleaner ] && @SBINDIR@/ganeti-master-cleaner
7
45 1 * * * @GNTMASTERUSER@ [ -x @SBINDIR@/ganeti-master-cleaner ] && @SBINDIR@/ganeti-cleaner master
8 8

  
9 9
# Clean job archive (at 02:45 AM)
10
45 2 * * * @GNTNODEDUSER@ [ -x @SBINDIR@/ganeti-cleaner ] && @SBINDIR@/ganeti-cleaner
10
45 2 * * * @GNTNODEDUSER@ [ -x @SBINDIR@/ganeti-cleaner ] && @SBINDIR@/ganeti-cleaner node
b/man/ganeti-cleaner.rst
9 9
Synopsis
10 10
--------
11 11

  
12
**ganeti-cleaner**
12
**ganeti-cleaner** node|master
13 13

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

  
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.
17
The **ganeti-cleaner** is a periodically run script to remove old
18
files. It can clean either node-specific or master-specific files.
20 19

  
21
**ganeti-cleaner** automatically removes  all expired certificates and
22
keys from ``@LOCALSTATEDIR@/run/ganeti/crypto``.
20
When called with ``node`` as argument, it will cleanup expired X509
21
certificates and keys from ``@LOCALSTATEDIR@/run/ganeti/crypto``, as
22
well as outdated **ganeti-watcher** information.
23

  
24
When called with ``master`` as argument, it will instead automatically
25
remove all files older than 21 days from
26
``@LOCALSTATEDIR@/lib/ganeti/queue/archive``.
23 27

  
24 28
.. vim: set textwidth=72 :
25 29
.. Local Variables:
/dev/null
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
1 1
#!/bin/bash
2 2
#
3 3

  
4
# Copyright (C) 2010 Google Inc.
4
# Copyright (C) 2010, 2012 Google Inc.
5 5
#
6 6
# This program is free software; you can redistribute it and/or modify
7 7
# it under the terms of the GNU General Public License as published by
......
18 18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 19
# 02110-1301, USA.
20 20

  
21
set -e
21
set -e -u
22 22
set -o pipefail
23 23

  
24 24
export PYTHON=${PYTHON:=python}
25 25

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

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

  
47 46
check_logfiles() {
48 47
  local n=$1 p=$2 path
49
  if [[ "$p2" = master ]]; then
50
    path=$tmpls/log/ganeti/mastercleaner
48
  if [[ "$p" = master ]]; then
49
    path=$tmpls/log/ganeti/master-cleaner
51 50
  else
52 51
    path=$tmpls/log/ganeti/cleaner
53 52
  fi
53

  
54
  test -d $path || \
55
    err "Log file directory '$path' not created"
56

  
54 57
  [[ "$(find $path -mindepth 1 | wc -l)" -le "$n" ]] || \
55 58
    err "Found more than $n logfiles"
56 59
}
......
83 86
}
84 87

  
85 88
run_cleaner() {
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
89
  CHECK_CERT_EXPIRED=$CCE LOCALSTATEDIR=$tmpls $GNTC $1
95 90
}
96 91

  
97 92
create_archived_jobs() {
......
172 167
test -d $tmpls/log/ganeti || err 'log/ganeti does not exist'
173 168
test -d $tmpls/log/ganeti/cleaner && \
174 169
  err 'log/ganeti/cleaner should not exist yet'
175
run_cleaner
176
test -d $tmpls/log/ganeti/cleaner || err 'log/ganeti/cleaner should exist'
177
check_logfiles 1
170
run_cleaner node
171
check_logfiles 1 node
178 172

  
179 173
test -d $tmpls/log/ganeti/master-cleaner && \
180 174
  err 'log/ganeti/master-cleaner should not exist yet'
181 175
run_cleaner master
182
test -d $tmpls/log/ganeti/master-cleaner || \
183
  err 'log/ganeti/master-cleaner should exist'
184 176
check_logfiles 1 master
185 177

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

  
193 185
upto 'Checking number of retained log files (node)'
194 186
for (( i=0; i < (maxlog + 10); ++i )); do
195
  run_cleaner
196
  check_logfiles $(( (i + 2) > $maxlog?$maxlog:(i + 2) ))
187
  run_cleaner node
188
  check_logfiles $(( (i + 2) > $maxlog?$maxlog:(i + 2) )) node
197 189
  check_logfiles $maxlog master
198 190
done
199 191

  
......
202 194
count_jobs 55
203 195
test -f $tmpls/lib/ganeti/ssconf_master_node && \
204 196
  err 'ssconf_master_node should not exist'
205
run_cleaner
197
run_cleaner node
206 198
count_jobs 55
207 199
run_cleaner master
208 200
count_jobs 55
......
211 203
create_archived_jobs
212 204
count_jobs 55
213 205
echo $HOSTNAME > $tmpls/lib/ganeti/ssconf_master_node
214
run_cleaner
206
run_cleaner node
215 207
count_jobs 55
216 208
run_cleaner master
217 209
count_jobs 31
......
226 218
count_and_check_certs 10
227 219
run_cleaner master
228 220
count_and_check_certs 10
229
run_cleaner
221
run_cleaner node
230 222
count_and_check_certs 5
231 223

  
232
check_logfiles $maxlog
224
check_logfiles $maxlog node
233 225
check_logfiles $maxlog master
234 226
count_jobs 31
235 227

  
......
240 232
run_cleaner master
241 233
count_watcher data 10
242 234
count_watcher instance-status 10
243
run_cleaner
235
run_cleaner node
244 236
count_watcher data 5
245 237
count_watcher instance-status 5
246 238

  

Also available in: Unified diff