選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

137 行
3.3 KiB

  1. """
  2. Execute patch files.
  3. Patch files must be in the "patches" module specified by "modules_path"
  4. To run directly
  5. python lib/wnf.py patch patch1, patch2 etc
  6. python lib/wnf.py patch -f patch1, patch2 etc
  7. where patch1, patch2 is module name
  8. """
  9. def run(patch_list, overwrite = 0, log_exception=1, conn = '', db_name = '', db_password = ''):
  10. import webnotes, webnotes.defs
  11. print patch_list
  12. # db connection
  13. if not conn:
  14. dbn = db_name or webnotes.defs.default_db_name
  15. 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)
  16. connect_db(dbn, pwd)
  17. else:
  18. webnotes.conn = conn
  19. # session
  20. if not (webnotes.session and webnotes.session['user']):
  21. webnotes.session = {'user':'Administrator'}
  22. # no patches on accounts
  23. if webnotes.conn.cur_db_name=='accounts':
  24. return
  25. # check if already applied
  26. if not overwrite:
  27. patch_list = check_already_applied_patch(patch_list)
  28. block_user("Patches are being executed, please try again in a few minutes")
  29. try:
  30. for p in patch_list:
  31. # execute patch
  32. execute_patch(p, log_exception)
  33. except Exception, e:
  34. webnotes.conn.rollback()
  35. if log_exception:
  36. write_log()
  37. else:
  38. print webnotes.getTraceback()
  39. finally:
  40. # unblock
  41. block_user()
  42. def block_user(msg=None):
  43. """stop further executions till patch is run"""
  44. import webnotes
  45. webnotes.conn.begin()
  46. webnotes.conn.set_global('__session_status', msg and 'stop' or None)
  47. webnotes.conn.set_global('__session_status_message', msg or None)
  48. webnotes.conn.commit()
  49. def execute_patch(p, log_exception):
  50. import webnotes
  51. webnotes.conn.begin()
  52. exec('import ' + p)
  53. eval(p).execute()
  54. # update patch log table
  55. webnotes.conn.sql("insert into `__PatchLog` (patch, applied_on) values (%s, now())", p)
  56. webnotes.conn.commit()
  57. print "Patch: %s applied successfully..." % p
  58. def check_already_applied_patch(patch_list):
  59. """
  60. Remove if patch already applied
  61. """
  62. import webnotes
  63. try:
  64. already_patched = [d[0] for d in webnotes.conn.sql("select distinct patch from `__PatchLog`")]
  65. except Exception, e:
  66. if e.args[0]==1146:
  67. webnotes.conn.sql("create table if not exists `__PatchLog` (patch TEXT, applied_on DATETIME)")
  68. check_already_applied_patch(patch_list)
  69. return
  70. else:
  71. raise e
  72. pending_patch = []
  73. for p in patch_list:
  74. if p not in already_patched:
  75. pending_patch.append(p)
  76. return pending_patch
  77. def connect_db(db_name, pwd):
  78. """
  79. Connect database
  80. """
  81. import webnotes
  82. import webnotes.db
  83. webnotes.conn = webnotes.db.Database(user=db_name, password=pwd)
  84. webnotes.conn.use(db_name)
  85. def write_log():
  86. import os
  87. import webnotes.defs
  88. import webnotes
  89. patch_log = open(os.path.join(webnotes.defs.modules_path, 'patches', 'patch.log'), 'a')
  90. patch_log.write(('\n\nError in %s:\n' % webnotes.conn.cur_db_name) + webnotes.getTraceback())
  91. patch_log.close()
  92. if getattr(webnotes.defs,'admin_email_notification',0):
  93. from webnotes.utils import sendmail
  94. subj = 'Patch Error. <br>Account: %s' % webnotes.conn.cur_db_name
  95. msg = subj + '<br><br>' + webnotes.getTraceback()
  96. print msg
  97. #sendmail(['nabin@erpnext.com'], sender='automail@erpnext.com', subject= subj, parts=[['text/plain', msg]])
  98. if __name__=='__main__':
  99. import sys, os
  100. # webnotes path
  101. sys.path.append('lib/py')
  102. run(sys.argv[1:])