You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

136 rivejä
4.4 KiB

  1. # Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. #
  3. # MIT License (MIT)
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the "Software"),
  7. # to deal in the Software without restriction, including without limitation
  8. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. # and/or sell copies of the Software, and to permit persons to whom the
  10. # Software is furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #
  22. from __future__ import unicode_literals
  23. """
  24. Execute Patch Files
  25. To run directly
  26. python lib/wnf.py patch patch1, patch2 etc
  27. python lib/wnf.py patch -f patch1, patch2 etc
  28. where patch1, patch2 is module name
  29. """
  30. import webnotes
  31. def run_all(patch_list=None):
  32. """run all pending patches"""
  33. if webnotes.conn.table_exists("__PatchLog"):
  34. executed = [p[0] for p in webnotes.conn.sql("""select patch from `__PatchLog`""")]
  35. else:
  36. executed = [p[0] for p in webnotes.conn.sql("""select patch from `tabPatch Log`""")]
  37. import patches.patch_list
  38. for patch in (patch_list or patches.patch_list.patch_list):
  39. if patch not in executed:
  40. if not run_single(patchmodule = patch):
  41. return log(patch + ': failed: STOPPED')
  42. def reload_doc(args):
  43. import webnotes.modules
  44. run_single(method = webnotes.modules.reload_doc, methodargs = args)
  45. def run_single(patchmodule=None, method=None, methodargs=None, force=False):
  46. import conf
  47. # don't write txt files
  48. conf.developer_mode = 0
  49. if force or method or not executed(patchmodule):
  50. return execute_patch(patchmodule, method, methodargs)
  51. else:
  52. return True
  53. def execute_patch(patchmodule, method=None, methodargs=None):
  54. """execute the patch"""
  55. success = False
  56. block_user(True)
  57. webnotes.conn.begin()
  58. try:
  59. log('Executing %s in %s' % (patchmodule or str(methodargs), webnotes.conn.cur_db_name))
  60. if patchmodule:
  61. if patchmodule.startswith("execute:"):
  62. exec patchmodule.split("execute:")[1] in globals()
  63. else:
  64. webnotes.get_method(patchmodule + ".execute")()
  65. update_patch_log(patchmodule)
  66. elif method:
  67. method(**methodargs)
  68. webnotes.conn.commit()
  69. success = True
  70. except Exception, e:
  71. webnotes.conn.rollback()
  72. global has_errors
  73. has_errors = True
  74. tb = webnotes.getTraceback()
  75. log(tb)
  76. import os
  77. if os.environ.get('HTTP_HOST'):
  78. add_to_patch_log(tb)
  79. block_user(False)
  80. if success:
  81. log('Success')
  82. return success
  83. def add_to_patch_log(tb):
  84. """add error log to patches/patch.log"""
  85. import conf, os
  86. with open(os.path.join(os.path.dirname(conf.__file__), 'app', 'patches','patch.log'),'a') as patchlog:
  87. patchlog.write('\n\n' + tb)
  88. def update_patch_log(patchmodule):
  89. """update patch_file in patch log"""
  90. if webnotes.conn.table_exists("__PatchLog"):
  91. webnotes.conn.sql("""INSERT INTO `__PatchLog` VALUES (%s, now())""", \
  92. patchmodule)
  93. else:
  94. webnotes.doc({"doctype": "Patch Log", "patch": patchmodule}).insert()
  95. def executed(patchmodule):
  96. """return True if is executed"""
  97. if webnotes.conn.table_exists("__PatchLog"):
  98. done = webnotes.conn.sql("""select patch from __PatchLog where patch=%s""", patchmodule)
  99. else:
  100. done = webnotes.conn.get_value("Patch Log", {"patch": patchmodule})
  101. if done:
  102. print "Patch %s executed in %s" % (patchmodule, webnotes.conn.cur_db_name)
  103. return done
  104. def block_user(block):
  105. """stop/start execution till patch is run"""
  106. webnotes.conn.begin()
  107. msg = "Patches are being executed in the system. Please try again in a few moments."
  108. webnotes.conn.set_global('__session_status', block and 'stop' or None)
  109. webnotes.conn.set_global('__session_status_message', block and msg or None)
  110. webnotes.conn.commit()
  111. def setup():
  112. webnotes.conn.sql("""CREATE TABLE IF NOT EXISTS `__PatchLog` (
  113. patch TEXT, applied_on DATETIME) engine=InnoDB""")
  114. log_list = []
  115. has_errors = False
  116. def log(msg):
  117. log_list.append(msg)