1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 __doc__='''zenrestore
17
18 Restores a zenoss backup created by zenbackup.
19 '''
20
21 import sys
22 import os
23 import os.path
24 import ConfigParser
25
26 import Globals
27 from Products.ZenUtils.Utils import zenPath, binPath
28
29 from ZenBackupBase import *
30
31
33
34
36 """basic options setup sub classes can add more options here"""
37 ZenBackupBase.buildOptions(self)
38
39 self.parser.add_option('--dbname',
40 dest='dbname',
41 default=None,
42 help='MySQL events database name. Defaults'
43 ' to value saved with backup or "events"')
44 self.parser.add_option('--dbuser',
45 dest='dbuser',
46 default=None,
47 help='MySQL username. Defaults'
48 ' to value saved with backup or "zenoss"')
49 self.parser.add_option('--dbpass',
50 dest='dbpass',
51 default=None,
52 help='MySQL password. Defaults'
53 ' to value saved with backup')
54 self.parser.add_option('--file',
55 dest="file",
56 default=None,
57 help='File from which to restore.')
58 self.parser.add_option('--dir',
59 dest="dir",
60 default=None,
61 help='Path to an untarred backup file'
62 ' from which to restore.')
63 self.parser.add_option('--no-eventsdb',
64 dest="noEventsDb",
65 default=False,
66 action='store_true',
67 help='Do not restore the events database.')
68 self.parser.add_option('--zenpacks',
69 dest='zenpacks',
70 default=False,
71 action='store_true',
72 help='Restore any ZenPacks in the backup.')
73
75 ''' Retrieve some options from settings file
76 '''
77 try:
78 f = open(os.path.join(tempDir, CONFIG_FILE), 'r')
79 except:
80 return
81 try:
82 config = ConfigParser.SafeConfigParser()
83 config.readfp(f)
84 finally:
85 f.close()
86 for key, default, zemAttr in CONFIG_FIELDS:
87 if getattr(self.options, key, None) == None:
88 if config.has_option(CONFIG_SECTION, key):
89 setattr(self.options, key, config.get(CONFIG_SECTION, key))
90 else:
91 setattr(self.options, key, default)
92
93
95 ''' Create the mysql db if it does not exist
96 '''
97
98
99
100
101 sql = 'create database if not exists %s' % self.options.dbname
102 cmd = 'echo "%s" | mysql -u"%s" %s' % (
103 sql,
104 self.options.dbuser,
105 self.getPassArg())
106 result = os.system(cmd)
107 self.msg('db check returned %s' % result)
108 if result not in [0, 256]:
109 return -1
110 return 0
111
112
114 ''' Restore from a previous backup
115 '''
116
117 if self.options.file and self.options.dir:
118 sys.stderr.write('You cannot specify both --file and --dir.\n')
119 sys.exit(-1)
120 elif not self.options.file and not self.options.dir:
121 sys.stderr.write('You must specify either --file or --dir.\n')
122 sys.exit(-1)
123
124
125
126 rootTempDir = ''
127 if self.options.file:
128 if not os.path.isfile(self.options.file):
129 sys.stderr.write('The specified backup file does not exist: %s\n' %
130 self.options.file)
131 sys.exit(-1)
132
133 self.msg('Unpacking backup file')
134 rootTempDir = self.getTempDir()
135 cmd = 'tar xzfC %s %s' % (self.options.file, rootTempDir)
136 if os.system(cmd): return -1
137 tempDir = os.path.join(rootTempDir, BACKUP_DIR)
138 else:
139 self.msg('Using %s as source of restore' % self.options.dir)
140 if not os.path.isdir(self.options.dir):
141 sys.stderr.write('The specified backup directory does not exist:'
142 ' %s\n' % self.options.dir)
143 sys.exit(-1)
144 tempDir = self.options.dir
145
146
147 self.getSettings(tempDir)
148 if not self.options.dbname:
149 self.options.dbname = 'events'
150 if not self.options.dbuser:
151 self.options.dbuser = 'zenoss'
152
153
154
155
156 if not os.path.isfile(zenPath('var', 'Data.fs')):
157 self.msg('There does not appear to be a zeo database.'
158 ' Starting zeo to create one.')
159 os.system(binPath('zeoctl') + 'start > /dev/null')
160 os.system(binPath('zeoctl') + 'stop > /dev/null')
161
162
163 self.msg('Restoring the zeo database.')
164 repozoDir = os.path.join(tempDir, 'repozo')
165 cmd ='%s %s --recover --repository %s --output %s' % (
166 binPath('python'),
167 binPath('repozo.py'),
168 repozoDir,
169 zenPath('var', 'Data.fs'))
170 if os.system(cmd): return -1
171
172
173 self.msg('Restoring config files.')
174 cmd = 'rm -rf %s' % zenPath('etc')
175 if os.system(cmd): return -1
176 cmd = 'tar Cxf %s %s' % (
177 zenPath(),
178 os.path.join(tempDir, 'etc.tar'))
179 if os.system(cmd): return -1
180
181
182 if self.options.zenpacks:
183 tempPacks = os.path.join(tempDir, 'ZenPacks.tar')
184 if os.path.isfile(tempPacks):
185 self.msg('Restoring ZenPacks.')
186 cmd = 'rm -rf %s' % zenPath('ZenPacks')
187 if os.system(cmd): return -1
188 cmd = 'tar Cxf %s %s' % (
189 zenPath(),
190 os.path.join(tempDir, 'ZenPacks.tar'))
191 if os.system(cmd): return -1
192 else:
193 self.msg('Backup contains no ZenPacks.')
194
195
196 cmd = 'rm -rf %s' % os.path.join(zenPath(), 'perf')
197 if os.system(cmd): return -1
198 tempPerf = os.path.join(tempDir, 'perf.tar')
199 if os.path.isfile(tempPerf):
200 self.msg('Restoring performance data.')
201 cmd = 'tar Cxf %s %s' % (
202 zenPath(),
203 os.path.join(tempDir, 'perf.tar'))
204 if os.system(cmd): return -1
205 else:
206 self.msg('Backup contains no perf data.')
207
208 if self.options.noEventsDb:
209 self.msg('Skipping the events database.')
210 else:
211 eventsSql = os.path.join(tempDir, 'events.sql')
212 if os.path.isfile(eventsSql):
213
214 self.msg('Checking that events database exists.')
215 if self.createMySqlDb(): return -1
216
217
218 self.msg('Restoring events database.')
219 cmd='mysql -u"%s" %s %s < %s' % (
220 self.options.dbuser,
221 self.getPassArg(),
222 self.options.dbname,
223 os.path.join(tempDir, 'events.sql'))
224 if os.system(cmd): return -1
225 else:
226 self.msg('This backup does not contain an events database.')
227
228
229 if self.options.file:
230 self.msg('Cleaning up temporary files.')
231 cmd = 'rm -r %s' % rootTempDir
232 if os.system(cmd): return -1
233
234 self.msg('Restore complete.')
235 return 0
236
237
238 if __name__ == '__main__':
239 zb = ZenRestore()
240 if zb.doRestore():
241 sys.exit(-1)
242