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 Globals 
 22  import sys 
 23  import os 
 24  import os.path 
 25  import ConfigParser 
 26   
 27  from ZenBackupBase import * 
 28   
 29   
30 -class ZenRestore(ZenBackupBase):
31 32
33 - def buildOptions(self):
34 """basic options setup sub classes can add more options here""" 35 ZenBackupBase.buildOptions(self) 36 37 self.parser.add_option('--dbname', 38 dest='dbname', 39 default=None, 40 help='MySQL events database name. Defaults' 41 ' to value saved with backup or "events"') 42 self.parser.add_option('--dbuser', 43 dest='dbuser', 44 default=None, 45 help='MySQL username. Defaults' 46 ' to value saved with backup or "zenoss"') 47 self.parser.add_option('--dbpass', 48 dest='dbpass', 49 default=None, 50 help='MySQL password. Defaults' 51 ' to value saved with backup') 52 self.parser.add_option('--file', 53 dest="file", 54 default=None, 55 help='File from which to restore.') 56 self.parser.add_option('--dir', 57 dest="dir", 58 default=None, 59 help='Path to an untarred backup file' 60 ' from which to restore.') 61 self.parser.add_option('--no-eventsdb', 62 dest="noEventsDb", 63 default=False, 64 action='store_true', 65 help='Do not restore the events database.')
66 67
68 - def getSettings(self, tempDir):
69 ''' Retrieve some options from settings file 70 ''' 71 try: 72 f = open(os.path.join(tempDir, CONFIG_FILE), 'r') 73 except: 74 return 75 try: 76 config = ConfigParser.SafeConfigParser() 77 config.readfp(f) 78 finally: 79 f.close() 80 for key, default, zemAttr in CONFIG_FIELDS: 81 if getattr(self.options, key, None) == None: 82 if config.has_option(CONFIG_SECTION, key): 83 setattr(self.options, key, config.get(CONFIG_SECTION, key)) 84 else: 85 setattr(self.options, key, default)
86 87
88 - def createMySqlDb(self):
89 ''' Create the mysql db if it does not exist 90 ''' 91 # The original dbname is stored in the backup within dbname.txt 92 # For now we ignore it and use the database specified on the command 93 # line. 94 # 95 sql = 'create database if not exists %s' % self.options.dbname 96 cmd = 'echo "%s" | mysql -u"%s" %s' % ( 97 sql, 98 self.options.dbuser, 99 self.getPassArg()) 100 result = os.system(cmd) 101 self.msg('db check returned %s' % result) 102 if result not in [0, 256]: 103 return -1 104 return 0
105 106
107 - def doRestore(self):
108 ''' Restore from a previous backup 109 ''' 110 111 if self.options.file and self.options.dir: 112 sys.stderr.write('You cannot specify both --file and --dir.\n') 113 sys.exit(-1) 114 elif not self.options.file and not self.options.dir: 115 sys.stderr.write('You must specify either --file or --dir.\n') 116 sys.exit(-1) 117 118 # Maybe check to see if zeo is up and tell user to quit zenoss first 119 120 rootTempDir = '' 121 if self.options.file: 122 if not os.path.isfile(self.options.file): 123 sys.stderr('The specified backup file does not exist: %s\n' % 124 self.options.file) 125 sys.exit(-1) 126 # Create temp dir and untar backup into it 127 self.msg('Unpacking backup file') 128 rootTempDir = self.getTempDir() 129 cmd = 'tar xzfC %s %s' % (self.options.file, rootTempDir) 130 if os.system(cmd): return -1 131 tempDir = os.path.join(rootTempDir, BACKUP_DIR) 132 else: 133 self.msg('Using %s as source of restore' % self.options.dir) 134 if not os.path.isdir(self.options.dir): 135 sys.stderr('The specified backup directory does not exist:' 136 ' %s\n' % self.options.dir) 137 sys.exit(-1) 138 tempDir = self.options.dir 139 140 # Maybe use values from backup file as defaults for self.options. 141 self.getSettings(tempDir) 142 if not self.options.dbname: 143 self.options.dbname = 'events' 144 if not self.options.dbuser: 145 self.options.dbuser = 'zenoss' 146 147 # If there is not a Data.fs then create an empty one 148 # Maybe should read file location/name from zeo.conf 149 # but we're going to assume the standard location for now. 150 if not os.path.isfile(os.path.join(self.zenhome, 'var', 'Data.fs')): 151 self.msg('There does not appear to be a zeo database.' 152 ' Starting zeo to create one.') 153 os.system(os.path.join(self.zenhome, 'bin', 'zeoctl start > /dev/null')) 154 os.system(os.path.join(self.zenhome, 'bin', 'zeoctl stop > /dev/null')) 155 156 # Restore zopedb 157 self.msg('Restoring the zeo database.') 158 repozoDir = os.path.join(tempDir, 'repozo') 159 cmd ='%s --recover --repository %s --output %s' % ( 160 self.getRepozoPath(), 161 repozoDir, 162 os.path.join(self.zenhome, 'var', 'Data.fs')) 163 if os.system(cmd): return -1 164 165 # Copy etc files 166 self.msg('Restoring config files.') 167 cmd = 'rm -rf %s' % os.path.join(self.zenhome, 'etc') 168 if os.system(cmd): return -1 169 cmd = 'tar Cxf %s %s' % ( 170 self.zenhome, 171 os.path.join(tempDir, 'etc.tar')) 172 if os.system(cmd): return -1 173 174 # Copy perf files 175 self.msg('Restoring performance data.') 176 cmd = 'rm -rf %s' % os.path.join(self.zenhome, 'perf') 177 if os.system(cmd): return -1 178 cmd = 'tar Cxf %s %s' % ( 179 self.zenhome, 180 os.path.join(tempDir, 'perf.tar')) 181 if os.system(cmd): return -1 182 183 if self.options.noEventsDb: 184 self.msg('Skipping the events database.') 185 else: 186 eventsSql = os.path.join(tempDir, 'events.sql') 187 if os.path.isfile(eventsSql): 188 # Create the mysql db if it doesn't exist already 189 self.msg('Checking that events database exists.') 190 if self.createMySqlDb(): return -1 191 192 # Restore the mysql tables 193 self.msg('Restoring events database.') 194 cmd='mysql -u"%s" %s %s < %s' % ( 195 self.options.dbuser, 196 self.getPassArg(), 197 self.options.dbname, 198 os.path.join(tempDir, 'events.sql')) 199 if os.system(cmd): return -1 200 else: 201 self.msg('This backup does not contain an events database.') 202 203 # clean up 204 if self.options.file: 205 self.msg('Cleaning up temporary files.') 206 cmd = 'rm -r %s' % rootTempDir 207 if os.system(cmd): return -1 208 209 self.msg('Restore complete.') 210 return 0
211 212 213 if __name__ == '__main__': 214 zb = ZenRestore() 215 if zb.doRestore(): 216 sys.exit(-1) 217