136 lines
3.3 KiB
Python
136 lines
3.3 KiB
Python
"""
|
|
Execute patch files.
|
|
|
|
Patch files must be in the "patches" module specified by "modules_path"
|
|
To run directly
|
|
|
|
python lib/wnf.py patch patch1, patch2 etc
|
|
python lib/wnf.py patch -f patch1, patch2 etc
|
|
|
|
where patch1, patch2 is module name
|
|
"""
|
|
|
|
|
|
def run(patch_list, overwrite = 0, log_exception=1, conn = '', db_name = '', db_password = ''):
|
|
import webnotes, webnotes.defs
|
|
|
|
print patch_list
|
|
|
|
# db connection
|
|
if not conn:
|
|
dbn = db_name or webnotes.defs.default_db_name
|
|
pwd = db_password or (hasattr(webnotes.defs, 'get_db_password') and webnotes.defs.get_db_password(dbn)) or (hasattr(webnotes.defs, 'db_password') and webnotes.defs.db_password)
|
|
connect_db(dbn, pwd)
|
|
else:
|
|
webnotes.conn = conn
|
|
|
|
# session
|
|
if not (webnotes.session and webnotes.session['user']):
|
|
webnotes.session = {'user':'Administrator'}
|
|
|
|
# no patches on accounts
|
|
if webnotes.conn.cur_db_name=='accounts':
|
|
return
|
|
|
|
# check if already applied
|
|
if not overwrite:
|
|
patch_list = check_already_applied_patch(patch_list)
|
|
|
|
block_user("Patches are being executed, please try again in a few minutes")
|
|
|
|
try:
|
|
for p in patch_list:
|
|
# execute patch
|
|
execute_patch(p, log_exception)
|
|
|
|
except Exception, e:
|
|
webnotes.conn.rollback()
|
|
if log_exception:
|
|
write_log()
|
|
else:
|
|
print webnotes.getTraceback()
|
|
finally:
|
|
# unblock
|
|
block_user()
|
|
|
|
def block_user(msg=None):
|
|
"""stop further executions till patch is run"""
|
|
import webnotes
|
|
webnotes.conn.begin()
|
|
webnotes.conn.set_global('__session_status', msg and 'stop' or None)
|
|
webnotes.conn.set_global('__session_status_message', msg or None)
|
|
webnotes.conn.commit()
|
|
|
|
|
|
def execute_patch(p, log_exception):
|
|
import webnotes
|
|
|
|
webnotes.conn.begin()
|
|
|
|
exec('import ' + p)
|
|
eval(p).execute()
|
|
|
|
# update patch log table
|
|
webnotes.conn.sql("insert into `__PatchLog` (patch, applied_on) values (%s, now())", p)
|
|
|
|
webnotes.conn.commit()
|
|
|
|
print "Patch: %s applied successfully..." % p
|
|
|
|
def check_already_applied_patch(patch_list):
|
|
"""
|
|
Remove if patch already applied
|
|
"""
|
|
import webnotes
|
|
|
|
try:
|
|
already_patched = [d[0] for d in webnotes.conn.sql("select distinct patch from `__PatchLog`")]
|
|
except Exception, e:
|
|
if e.args[0]==1146:
|
|
webnotes.conn.sql("create table if not exists `__PatchLog` (patch TEXT, applied_on DATETIME)")
|
|
check_already_applied_patch(patch_list)
|
|
return
|
|
else:
|
|
raise e
|
|
|
|
pending_patch = []
|
|
|
|
for p in patch_list:
|
|
if p not in already_patched:
|
|
pending_patch.append(p)
|
|
|
|
return pending_patch
|
|
|
|
def connect_db(db_name, pwd):
|
|
"""
|
|
Connect database
|
|
"""
|
|
import webnotes
|
|
import webnotes.db
|
|
webnotes.conn = webnotes.db.Database(user=db_name, password=pwd)
|
|
webnotes.conn.use(db_name)
|
|
|
|
|
|
def write_log():
|
|
import os
|
|
import webnotes.defs
|
|
import webnotes
|
|
|
|
patch_log = open(os.path.join(webnotes.defs.modules_path, 'patches', 'patch.log'), 'a')
|
|
patch_log.write(('\n\nError in %s:\n' % webnotes.conn.cur_db_name) + webnotes.getTraceback())
|
|
patch_log.close()
|
|
|
|
if getattr(webnotes.defs,'admin_email_notification',0):
|
|
from webnotes.utils import sendmail
|
|
subj = 'Patch Error. <br>Account: %s' % webnotes.conn.cur_db_name
|
|
msg = subj + '<br><br>' + webnotes.getTraceback()
|
|
print msg
|
|
#sendmail(['nabin@erpnext.com'], sender='automail@erpnext.com', subject= subj, parts=[['text/plain', msg]])
|
|
|
|
if __name__=='__main__':
|
|
import sys, os
|
|
|
|
# webnotes path
|
|
sys.path.append('lib/py')
|
|
|
|
run(sys.argv[1:])
|