2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
26 """ Check_MK comes with a simple backup and restore of the current
27 configuration and cache files (cmk --backup and cmk --restore). This
28 is implemented here. """
34 import cStringIO
as StringIO
36 import cmk
.utils
.paths
37 import cmk
.utils
.render
as render
38 from cmk
.utils
.exceptions
import MKGeneralException
40 import cmk_base
.console
as console
44 # TODO: Refactor to named tuples
47 # tarname path canonical name description is_dir
48 ('check_mk_configfile', cmk
.utils
.paths
.main_config_file
, "main.mk", "Main configuration file", False, ),
49 ('final_mk', cmk
.utils
.paths
.final_config_file
, "final.mk", "Final configuration file final.mk", False, ),
50 ('check_mk_configdir', cmk
.utils
.paths
.check_mk_config_dir
, "", "Configuration sub files", True, ),
51 ('autochecksdir', cmk
.utils
.paths
.autochecks_dir
, "", "Automatically inventorized checks", True, ),
52 ('counters_directory', cmk
.utils
.paths
.counters_dir
, "", "Performance counters", True, ),
53 ('tcp_cache_dir', cmk
.utils
.paths
.tcp_cache_dir
, "", "Agent cache", True, ),
54 ('logwatch_dir', cmk
.utils
.paths
.logwatch_dir
, "", "Logwatch", True, ),
59 def do_backup(tarname
):
60 console
.verbose("Creating backup file '%s'...\n", tarname
)
61 tar
= tarfile
.open(tarname
, "w:gz")
63 for name
, path
, canonical_name
, descr
, is_dir
, in backup_paths():
65 absdir
= os
.path
.abspath(path
)
66 if os
.path
.exists(path
):
68 subtarname
= name
+ ".tar"
69 subfile
= StringIO
.StringIO()
70 subtar
= tarfile
.open(mode
="w", fileobj
=subfile
, dereference
=True)
71 subtar
.add(path
, arcname
=".")
72 subdata
= subfile
.getvalue()
74 subtarname
= canonical_name
75 subdata
= file(absdir
).read()
77 info
= tarfile
.TarInfo(subtarname
)
78 info
.mtime
= time
.time()
81 info
.size
= len(subdata
)
83 info
.type = tarfile
.REGTYPE
84 info
.name
= subtarname
85 console
.verbose(" Added %s (%s) with a size of %s\n", descr
, absdir
,
86 render
.fmt_bytes(info
.size
))
87 tar
.addfile(info
, StringIO
.StringIO(subdata
))
90 console
.verbose("Successfully created backup.\n")
93 def do_restore(tarname
):
94 console
.verbose("Restoring from '%s'...\n", tarname
)
96 if not os
.path
.exists(tarname
):
97 raise MKGeneralException("Unable to restore: File does not exist")
99 for name
, path
, canonical_name
, descr
, is_dir
in backup_paths():
100 absdir
= os
.path
.abspath(path
)
104 if os
.path
.exists(absdir
):
105 console
.verbose(" Deleting old contents of '%s'\n", absdir
)
106 # The path might point to a symbalic link. So it is no option
107 # to call shutil.rmtree(). We must delete just the contents
108 for f
in os
.listdir(absdir
):
109 if f
not in ['.', '..']:
116 except Exception as e
:
117 console
.warning(" Cannot delete %s: %s", p
, e
)
119 basedir
= os
.path
.dirname(absdir
)
120 filename
= os
.path
.basename(absdir
)
121 canonical_path
= basedir
+ "/" + canonical_name
122 if os
.path
.exists(canonical_path
):
123 console
.verbose(" Deleting old version of '%s'\n", canonical_path
)
124 os
.remove(canonical_path
)
126 if not os
.path
.exists(basedir
):
127 console
.verbose(" Creating directory %s\n", basedir
)
130 console
.verbose(" Extracting %s (%s)\n", descr
, absdir
)
131 tar
= tarfile
.open(tarname
, "r:gz")
133 subtar
= tarfile
.open(fileobj
=tar
.extractfile(name
+ ".tar"))
135 subtar
.extractall(basedir
)
136 elif filename
in subtar
.getnames():
137 subtar
.extract(filename
, basedir
)
139 elif filename
in tar
.getnames():
140 tar
.extract(filename
, basedir
)
143 console
.verbose("Successfully restored backup.\n")