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 69
70 - def getSettings(self, tempDir):
71 ''' Retrieve some options from settings file 72 ''' 73 try: 74 f = open(os.path.join(tempDir, CONFIG_FILE), 'r') 75 except: 76 return 77 try: 78 config = ConfigParser.SafeConfigParser() 79 config.readfp(f) 80 finally: 81 f.close() 82 for key, default, zemAttr in CONFIG_FIELDS: 83 if getattr(self.options, key, None) == None: 84 if config.has_option(CONFIG_SECTION, key): 85 setattr(self.options, key, config.get(CONFIG_SECTION, key)) 86 else: 87 setattr(self.options, key, default)
88 89
90 - def createMySqlDb(self):
91 ''' Create the mysql db if it does not exist 92 ''' 93 # The original dbname is stored in the backup within dbname.txt 94 # For now we ignore it and use the database specified on the command 95 # line. 96 # 97 sql = 'create database if not exists %s' % self.options.dbname 98 cmd = 'echo "%s" | mysql -u"%s" %s' % ( 99 sql, 100 self.options.dbuser, 101 self.getPassArg()) 102 result = os.system(cmd) 103 self.msg('db check returned %s' % result) 104 if result not in [0, 256]: 105 return -1 106 return 0
107 108
109 - def doRestore(self):
110 ''' Restore from a previous backup 111 ''' 112 113 if self.options.file and self.options.dir: 114 sys.stderr.write('You cannot specify both --file and --dir.\n') 115 sys.exit(-1) 116 elif not self.options.file and not self.options.dir: 117 sys.stderr.write('You must specify either --file or --dir.\n') 118 sys.exit(-1) 119 120 # Maybe check to see if zeo is up and tell user to quit zenoss first 121 122 rootTempDir = '' 123 if self.options.file: 124 if not os.path.isfile(self.options.file): 125 sys.stderr.write('The specified backup file does not exist: %s\n' % 126 self.options.file) 127 sys.exit(-1) 128 # Create temp dir and untar backup into it 129 self.msg('Unpacking backup file') 130 rootTempDir = self.getTempDir() 131 cmd = 'tar xzfC %s %s' % (self.options.file, rootTempDir) 132 if os.system(cmd): return -1 133 tempDir = os.path.join(rootTempDir, BACKUP_DIR) 134 else: 135 self.msg('Using %s as source of restore' % self.options.dir) 136 if not os.path.isdir(self.options.dir): 137 sys.stderr.write('The specified backup directory does not exist:' 138 ' %s\n' % self.options.dir) 139 sys.exit(-1) 140 tempDir = self.options.dir 141 142 # Maybe use values from backup file as defaults for self.options. 143 self.getSettings(tempDir) 144 if not self.options.dbname: 145 self.options.dbname = 'events' 146 if not self.options.dbuser: 147 self.options.dbuser = 'zenoss' 148 149 # If there is not a Data.fs then create an empty one 150 # Maybe should read file location/name from zeo.conf 151 # but we're going to assume the standard location for now. 152 if not os.path.isfile(zenPath('var', 'Data.fs')): 153 self.msg('There does not appear to be a zeo database.' 154 ' Starting zeo to create one.') 155 os.system(binPath('zeoctl') + 'start > /dev/null') 156 os.system(binPath('zeoctl') + 'stop > /dev/null') 157 158 # Restore zopedb 159 self.msg('Restoring the zeo database.') 160 repozoDir = os.path.join(tempDir, 'repozo') 161 cmd ='%s %s --recover --repository %s --output %s' % ( 162 binPath('python'), 163 binPath('repozo.py'), 164 repozoDir, 165 zenPath('var', 'Data.fs')) 166 if os.system(cmd): return -1 167 168 # Copy etc files 169 self.msg('Restoring config files.') 170 cmd = 'rm -rf %s' % zenPath('etc') 171 if os.system(cmd): return -1 172 cmd = 'tar Cxf %s %s' % ( 173 zenPath(), 174 os.path.join(tempDir, 'etc.tar')) 175 if os.system(cmd): return -1 176 177 # Copy perf files 178 cmd = 'rm -rf %s' % os.path.join(zenPath(), 'perf') 179 if os.system(cmd): return -1 180 tempPerf = os.path.join(tempDir, 'perf.tar') 181 if os.path.isfile(tempPerf): 182 self.msg('Restoring performance data.') 183 cmd = 'tar Cxf %s %s' % ( 184 zenPath(), 185 os.path.join(tempDir, 'perf.tar')) 186 if os.system(cmd): return -1 187 else: 188 self.msg('Backup contains no perf data.') 189 190 if self.options.noEventsDb: 191 self.msg('Skipping the events database.') 192 else: 193 eventsSql = os.path.join(tempDir, 'events.sql') 194 if os.path.isfile(eventsSql): 195 # Create the mysql db if it doesn't exist already 196 self.msg('Checking that events database exists.') 197 if self.createMySqlDb(): return -1 198 199 # Restore the mysql tables 200 self.msg('Restoring events database.') 201 cmd='mysql -u"%s" %s %s < %s' % ( 202 self.options.dbuser, 203 self.getPassArg(), 204 self.options.dbname, 205 os.path.join(tempDir, 'events.sql')) 206 if os.system(cmd): return -1 207 else: 208 self.msg('This backup does not contain an events database.') 209 210 # clean up 211 if self.options.file: 212 self.msg('Cleaning up temporary files.') 213 cmd = 'rm -r %s' % rootTempDir 214 if os.system(cmd): return -1 215 216 self.msg('Restore complete.') 217 return 0
218 219 220 if __name__ == '__main__': 221 zb = ZenRestore() 222 if zb.doRestore(): 223 sys.exit(-1) 224