Package ZenUtils :: Module ZenRestore
[hide private]
[frames] | no frames]

Source Code for Module ZenUtils.ZenRestore

  1  #! /usr/bin/env python  
  2  ########################################################################### 
  3  # 
  4  # This program is part of Zenoss Core, an open source monitoring platform. 
  5  # Copyright (C) 2007, Zenoss Inc. 
  6  # 
  7  # This program is free software; you can redistribute it and/or modify it 
  8  # under the terms of the GNU General Public License version 2 as published by 
  9  # the Free Software Foundation. 
 10  # 
 11  # For complete information please visit: http://www.zenoss.com/oss/ 
 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   
32 -class ZenRestore(ZenBackupBase):
33 34
35 - def buildOptions(self):
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
74 - def getSettings(self, tempDir):
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
94 - def createMySqlDb(self):
95 ''' Create the mysql db if it does not exist 96 ''' 97 # The original dbname is stored in the backup within dbname.txt 98 # For now we ignore it and use the database specified on the command 99 # line. 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
113 - def doRestore(self):
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 # Maybe check to see if zeo is up and tell user to quit zenoss first 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 # Create temp dir and untar backup into it 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 # Maybe use values from backup file as defaults for self.options. 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 # If there is not a Data.fs then create an empty one 154 # Maybe should read file location/name from zeo.conf 155 # but we're going to assume the standard location for now. 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 # Restore zopedb 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 # Copy etc files 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 # Copy ZenPack files if requested 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 # Copy perf files 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 # Create the mysql db if it doesn't exist already 214 self.msg('Checking that events database exists.') 215 if self.createMySqlDb(): return -1 216 217 # Restore the mysql tables 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 # clean up 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