Package Products :: Package ZenModel :: Module zenbuild
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.zenbuild

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 or (at your 
  8  # option) any later version as published by the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  __doc__="""zenbuild 
 15   
 16  Build the zentinel portal object and the dmd database 
 17   
 18  $Id: DmdBuilder.py,v 1.11 2004/04/06 22:33:07 edahl Exp $""" 
 19   
 20  __version__ = "$Revision: 1.11 $"[11:-2] 
 21   
 22  import os 
 23  import Globals 
 24  import transaction 
 25  import subprocess 
 26   
 27  from Products.ZenUtils.Utils import zenPath 
 28   
 29  from Products.ZenUtils import Security 
 30  from Products.ZenUtils.CmdBase import CmdBase 
 31  from Products.PluggableAuthService import plugins 
 32  from MySQLdb import OperationalError 
 33   
34 -class zenbuild(CmdBase):
35 36 sitename = "zport" 37
38 - def connect(self):
39 zopeconf = zenPath("etc/zope.conf") 40 import Zope2 41 Zope2.configure(zopeconf) 42 self.app = Zope2.app()
43
44 - def buildOptions(self):
45 CmdBase.buildOptions(self) 46 self.parser.add_option('--xml', dest="fromXml", 47 action='store_true', default=False, 48 help="Load data from XML files instead of SQL") 49 self.parser.add_option('-s','--evthost', dest="evthost", 50 default="127.0.0.1", help="events database hostname") 51 self.parser.add_option('-u','--evtuser', dest="evtuser", default="root", 52 help="username used to connect to the events database") 53 self.parser.add_option('-p','--evtpass', dest="evtpass", default="", 54 help="password used to connect to the events database") 55 self.parser.add_option('-d','--evtdb', dest="evtdb", default="events", 56 help="name of events database") 57 self.parser.add_option('-t','--evtport', dest="evtport", 58 type='int', default=3306, 59 help="port used to connect to the events database") 60 self.parser.add_option('--smtphost', dest="smtphost", default="localhost", 61 help="smtp host") 62 self.parser.add_option('--smtpport', dest="smtpport", default=25, 63 help="smtp port") 64 self.parser.add_option('--cachesize', 65 dest="cachesize",default=1000, type='int', 66 help="in memory cachesize default: 1000") 67 self.parser.add_option('--host', 68 dest="host",default="localhost", 69 help="hostname of MySQL object store") 70 self.parser.add_option('--port', 71 dest="port", type="int", default=3306, 72 help="port of MySQL object store") 73 self.parser.add_option('--mysqluser', dest='mysqluser', default='zenoss', 74 help='username for MySQL object store') 75 self.parser.add_option('--mysqlpasswd', dest='mysqlpasswd', default='zenoss', 76 help='passwd for MySQL object store') 77 self.parser.add_option('--mysqldb', dest='mysqldb', default='zodb', 78 help='Name of database for MySQL object store') 79 self.parser.add_option('--mysqlsocket', dest='mysqlsocket', default=None, 80 help='Name of socket file for MySQL server connection') 81 self.parser.add_option('--cacheservers', dest='cacheservers', 82 default="127.0.0.1:11211", 83 help='memcached servers to use for object cache (eg. 127.0.0.1:11211)') 84 self.parser.add_option('--pagecommand', dest="pagecommand", default="$ZENHOME/bin/zensnpp localhost 444 $RECIPIENT", 85 help="page command") 86 # amqp stuff 87 self.parser.add_option('--amqphost', dest="amqphost", default="localhost", 88 help="AMQP Host Location") 89 self.parser.add_option('--amqpport', dest="amqpport", default=5672, 90 help="AMQP Server Port") 91 self.parser.add_option('--amqpvhost', dest="amqpvhost", default="/zenoss", 92 help="Default Virtual Host") 93 self.parser.add_option('--amqpuser', dest="amqpuser", default="zenoss", 94 help="AMQP User Name") 95 self.parser.add_option('--amqppassword', dest="amqppassword", default="zenoss", 96 help="AMQP Password")
97
98 - def zodbConnect(self):
99 """ 100 Used to connect to ZODB (without going through the entire ZOPE 101 initialization process. This allows us to get a lightweight 102 connection to the database to test to see if the database is already 103 initialized. 104 """ 105 self.options.port = self.options.port or 3306 106 from relstorage.storage import RelStorage 107 from relstorage.adapters.mysql import MySQLAdapter 108 connectionParams = { 109 'host' : self.options.host, 110 'port' : self.options.port, 111 'user' : self.options.mysqluser, 112 'passwd' : self.options.mysqlpasswd, 113 'db' : self.options.mysqldb, 114 } 115 if getattr(self.options, 'mysqlsocket', None) and self.options.mysqlsocket != 'None': 116 connectionParams['unix_socket'] = self.options.mysqlsocket 117 118 kwargs = { 119 'keep_history': False, 120 } 121 from relstorage.options import Options 122 adapter = MySQLAdapter(options=Options(**kwargs),**connectionParams) 123 self.storage = RelStorage(adapter, **kwargs) 124 from ZODB import DB 125 self.db = DB(self.storage, cache_size=self.options.cachesize)
126
127 - def build(self):
128 mysqlcmd = ['mysql', '-u', self.options.mysqluser] 129 if self.options.mysqlpasswd: 130 mysqlcmd.append('-p%s' % self.options.mysqlpasswd) 131 mysqlcmd.extend([ 132 '-h', self.options.host, 133 '--port', str(self.options.port) 134 ]) 135 136 mysqlcmd = subprocess.list2cmdline(mysqlcmd) 137 138 conn = None 139 try: 140 self.zodbConnect() 141 conn = self.db.open() 142 root = conn.root() 143 app = root.get('Application') 144 if app and getattr(app, self.sitename, None) is not None: 145 print "zport portal object exists; exiting." 146 return 147 except OperationalError, e: 148 if 'Unknown database' in e[1]: 149 queries = ( 150 'CREATE DATABASE %s;' % self.options.mysqldb, 151 "GRANT ALL ON %s.* TO %s@'%s' IDENTIFIED BY '%s';" % ( 152 self.options.mysqldb, self.options.mysqluser, 153 self.options.host, self.options.mysqlpasswd), 154 "GRANT ALL ON %s.* TO %s@'%%' IDENTIFIED BY '%s';" % ( 155 self.options.mysqldb, self.options.mysqluser, 156 self.options.mysqlpasswd), 157 "FLUSH PRIVILEGES;" 158 ) 159 160 for query in queries: 161 cmd = mysqlcmd + ' -e "%s"' % query 162 os.system(cmd) 163 else: 164 raise 165 finally: 166 if conn: 167 conn.close() 168 if self.db: 169 self.db.close() 170 self.db = None 171 if self.storage: 172 self.storage.close() 173 self.storage = None 174 175 if self.options.fromXml: 176 self.connect() 177 from Products.ZenModel.ZentinelPortal import manage_addZentinelPortal 178 manage_addZentinelPortal(self.app, self.sitename) 179 site = self.app._getOb(self.sitename) 180 181 # build index_html 182 if self.app.hasObject('index_html'): 183 self.app._delObject('index_html') 184 from Products.PythonScripts.PythonScript import manage_addPythonScript 185 manage_addPythonScript(self.app, 'index_html') 186 newIndexHtml = self.app._getOb('index_html') 187 text = 'container.REQUEST.RESPONSE.redirect("/zport/dmd/")\n' 188 newIndexHtml.ZPythonScript_edit('', text) 189 190 # build standard_error_message 191 if self.app.hasObject('standard_error_message'): 192 self.app._delObject('standard_error_message') 193 file = open(zenPath('Products/ZenModel/dtml/standard_error_message.dtml')) 194 try: 195 text = file.read() 196 finally: 197 file.close() 198 import OFS.DTMLMethod 199 OFS.DTMLMethod.addDTMLMethod(self.app, id='standard_error_message', 200 file=text) 201 202 # Convert the acl_users folder at the root to a PAS folder and update 203 # the login form to use the Zenoss login form 204 Security.replaceACLWithPAS(self.app, deleteBackup=True) 205 206 # Add groupManager to zport.acl 207 acl = site.acl_users 208 if not hasattr(acl, 'groupManager'): 209 plugins.ZODBGroupManager.addZODBGroupManager(acl, 'groupManager') 210 acl.groupManager.manage_activateInterfaces(['IGroupsPlugin',]) 211 212 trans = transaction.get() 213 trans.note("Initial ZentinelPortal load by zenbuild.py") 214 trans.commit() 215 print "ZentinelPortal loaded at %s" % self.sitename 216 217 # build dmd 218 from Products.ZenModel.DmdBuilder import DmdBuilder 219 dmdBuilder = DmdBuilder(site, 220 self.options.evthost, 221 self.options.evtuser, 222 self.options.evtpass, 223 self.options.evtdb, 224 self.options.evtport, 225 self.options.smtphost, 226 self.options.smtpport, 227 self.options.pagecommand) 228 dmdBuilder.build() 229 transaction.commit() 230 231 # Load XML Data 232 from Products.ZenModel.XmlDataLoader import XmlDataLoader 233 dl = XmlDataLoader(noopts=True, app=self.app) 234 dl.loadDatabase() 235 236 else: 237 238 mysqlcmd += ' %s' % self.options.mysqldb 239 240 cmd = 'cat $ZENHOME/Products/ZenModel/data/zodb.sql.gz | gzip -c -d | %s' % mysqlcmd 241 os.system(cmd) 242 243 # Relstorage may have already loaded items into the cache in the 244 # initial connection to the database. We have to expire everything 245 # in the cache in order to prevent errors with overlapping 246 # transactions from the model which was just imported above. 247 if self.options.cacheservers: 248 self.flush_memcached(self.options.cacheservers.split()) 249 250 self.connect() 251 252 # Set all the attributes 253 site = getattr(self.app, self.sitename, None) 254 site.dmd.smtpHost = self.options.smtphost 255 site.dmd.smtpPort = self.options.smtpport 256 site.dmd.pageCommand = self.options.pagecommand 257 site.dmd.uuid = None 258 site.dmd._rq = False 259 for evmgr in (site.dmd.ZenEventManager, site.dmd.ZenEventHistory): 260 evmgr.username = self.options.evtuser 261 evmgr.password = self.options.evtpass 262 evmgr.database = self.options.evtdb 263 evmgr.host = self.options.evthost 264 evmgr.port = self.options.evtport 265 transaction.commit() 266 267 # Update the global conf 268 print "Updating global.conf" 269 zenglobalconf = zenPath('bin', 'zenglobalconf') 270 cmd = [zenglobalconf, '-u'] 271 for opt in ('host', 'port', 'mysqldb', 'mysqluser', 'mysqlpasswd', 272 'amqphost', 'amqpport', 'amqpvhost', 'amqpuser', 273 'amqppassword', 'cacheservers'): 274 cmd.append('%s=%s' % (opt, getattr(self.options, opt))) 275 subprocess.call(cmd) 276 277 # Load reports 278 from Products.ZenReports.ReportLoader import ReportLoader 279 rl = ReportLoader(noopts=True, app=self.app) 280 rl.loadDatabase()
281
282 - def flush_memcached(self, cacheservers):
283 import memcache 284 mc = memcache.Client(cacheservers, debug=0) 285 mc.flush_all() 286 mc.disconnect_all()
287 288 if __name__ == "__main__": 289 zb = zenbuild() 290 zb.build() 291