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.

280 lines
12 KiB

  1. #-*- coding: utf-8 -*-
  2. # Copyright 2010-2013 Calculate Ltd. http://www.calculate-linux.org
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import sys
  16. from calculate.core.server.func import Action, Tasks
  17. from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
  18. from calculate.lib.utils.colortext import get_color_print, Colors
  19. from calculate.lib.utils.files import FilesError
  20. from calculate.update.update import UpdateError
  21. from calculate.update.emerge_parser import EmergeError
  22. from calculate.update.package_tools import GitError, Eix, EmergeLog, \
  23. EmergeLogNamedTask, PackageList
  24. setLocalTranslate('cl_update3', sys.modules[__name__])
  25. __ = getLazyLocalTranslate(_)
  26. class ClUpdateAction(Action):
  27. """
  28. Действие обновление конфигурационных файлов
  29. """
  30. # ошибки, которые отображаются без подробностей
  31. native_error = (FilesError, UpdateError, GitError, EmergeError)
  32. successMessage = None
  33. failedMessage = None
  34. interruptMessage = __("Update manually interrupted")
  35. def was_installed(pkg, task_name):
  36. def func():
  37. task = EmergeLog(EmergeLogNamedTask(task_name))
  38. return bool(PackageList(task.list)[pkg])
  39. return func
  40. def need_upgrade(pkg):
  41. def func():
  42. return bool(Eix(pkg, Eix.Option.Upgrade).get_packages())
  43. return func
  44. def pkg_color(text):
  45. return text
  46. log_names = {'schedule': "schedule",
  47. 'premerge': "check updates",
  48. 'python_updater': "update python modules",
  49. 'perl_cleaner': "update perl modules",
  50. 'kernel_modules': "update kernel modules",
  51. 'depclean': "depclean",
  52. 'xorg_modules': "update xorg modules",
  53. 'preserved_libs': "update preserved libs",
  54. 'revdep': "revdep rebuild"}
  55. emerge_tasks = [
  56. {'name': 'premerge_group',
  57. 'group': __("Checking for updates"),
  58. 'tasks': [
  59. {'name': 'premerge',
  60. 'message': __("Calculating dependencies"),
  61. 'method': 'Update.premerge("-uDN","--with-bdeps=y","@world")',
  62. 'condition': lambda Get:Get('cl_update_sync_only_set') == 'off'
  63. }],
  64. },
  65. {'name': 'premerge:update',
  66. 'condition': lambda Get:Get('cl_update_pretend_set') == 'off',
  67. 'depend': Tasks.result("premerge", eq='yes')
  68. },
  69. {'name': 'update_other',
  70. 'condition': lambda Get: ( Get('cl_update_pretend_set') == 'off' and
  71. Get('cl_update_sync_only_set') == 'off')
  72. },
  73. {'name': 'update:update_world',
  74. 'group': __("Updating packages"),
  75. 'tasks': [
  76. {'name': 'update:update_world',
  77. 'message': __("Calculating dependencies"),
  78. 'method': 'Update.emerge("-uDN","--with-bdeps=y","@world")',
  79. }
  80. ]
  81. },
  82. {'name': 'update:update_python',
  83. 'group': __("Updating Python"),
  84. 'tasks': [
  85. {'name': 'update:python_updater',
  86. 'message': __('Find & rebuild packages broken due '
  87. 'to a Python upgrade'),
  88. 'method': 'Update.emergelike("python-updater")',
  89. 'condition': was_installed('dev-lang/python$',
  90. log_names['python_updater']),
  91. 'decoration': 'Update.update_task("%s")' % log_names[
  92. 'python_updater']
  93. },
  94. ]
  95. },
  96. {'name': 'update:update_perl',
  97. 'group': __("Updating Perl"),
  98. 'tasks': [
  99. {'name': 'update:perl_cleaner',
  100. 'message': __('Find & rebuild packages and Perl header files '
  101. 'broken due to a perl upgrade'),
  102. 'method': 'Update.emergelike("perl-cleaner", "all")',
  103. 'condition': was_installed('dev-lang/perl$',
  104. log_names['perl_cleaner']),
  105. 'decoration': 'Update.update_task("%s")' % log_names[
  106. 'perl_cleaner']
  107. },
  108. ]
  109. },
  110. {'name': 'update_other:depclean',
  111. 'group': __("Cleaning the system from needless packages"),
  112. 'tasks': [
  113. {'name': 'update_other:update_depclean',
  114. 'message': __("Calculating dependencies"),
  115. 'method': 'Update.depclean()',
  116. 'condition': was_installed('.*', log_names['depclean']),
  117. 'decoration': 'Update.update_task("%s")' % log_names['depclean']
  118. },
  119. ]
  120. },
  121. {'name': 'update_other:update_modules',
  122. 'group': __("Rebuilding dependent modules"),
  123. 'tasks': [
  124. {'name': 'update_other:module_rebuild',
  125. 'message': __('Updating Kernel modules'),
  126. 'method': 'Update.emerge("@module-rebuild")',
  127. 'condition': was_installed('sys-kernel/.*source',
  128. log_names['kernel_modules']),
  129. 'decoration': 'Update.update_task("%s")' % log_names[
  130. 'kernel_modules']
  131. },
  132. {'name': 'update_other:x11_module_rebuild',
  133. 'message': __('Updating X.Org server modules'),
  134. 'method': 'Update.emerge("@x11-module-rebuild")',
  135. 'condition': was_installed('x11-base/xorg-server',
  136. log_names['xorg_modules']),
  137. 'decoration': 'Update.update_task("%s")' % log_names[
  138. 'xorg_modules']
  139. },
  140. {'name': 'update_other:preserved_rebuild',
  141. 'message': __('Updating preserved libraries'),
  142. 'method': 'Update.emerge("@preserved-rebuild")',
  143. 'condition': was_installed('.*', log_names['preserved_libs']),
  144. 'decoration': 'Update.update_task("%s")' % log_names[
  145. 'preserved_libs']
  146. },
  147. {'name': 'update_other:revdev_rebuild',
  148. 'message': __('Checking reverse dependencies'),
  149. 'method': 'Update.revdep_rebuild("revdep-rebuild")',
  150. 'condition': was_installed('.*', log_names['revdep']),
  151. 'decoration': 'Update.update_task("%s")' % log_names['revdep']
  152. },
  153. {'name': 'update_other:dispatch_conf_end',
  154. 'message': __("Updating configuration files"),
  155. 'method':'Update.dispatchConf()',
  156. 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and
  157. Get('cl_update_pretend_set') == 'off')
  158. },
  159. ]
  160. },
  161. {'name': 'update:set_upto_date_cache',
  162. 'method': 'Update.setUpToDateCache()'
  163. }
  164. ]
  165. # список задач для дейсвия
  166. tasks = [
  167. {'name': 'check_schedule',
  168. 'method': 'Update.checkSchedule(cl_update_autocheck_interval,'
  169. 'cl_update_autocheck_set)',
  170. 'condition': lambda Get: (
  171. Get('cl_update_autocheck_schedule_set') == 'on'),
  172. },
  173. {'name': 'check_run',
  174. 'method': 'Update.checkRun(cl_update_wait_another_set)'},
  175. {'name': 'reps_synchronization',
  176. 'group': __("Repositories synchronization"),
  177. 'tasks': [
  178. {'name': 'sync_reps',
  179. 'foreach': 'cl_update_sync_rep',
  180. 'message': __("Syncing the {eachvar:capitalize} repository"),
  181. 'method': 'Update.syncRepositories(eachvar)',
  182. 'condition': lambda Get: Get('cl_update_sync_rep')
  183. },
  184. {'name': 'sync_other_reps',
  185. 'foreach': 'cl_update_other_rep_name',
  186. 'message': __("Syncing the {eachvar:capitalize} repository"),
  187. 'method': 'Update.syncLaymanRepository(eachvar)',
  188. 'condition': lambda Get: Get('cl_update_other_set') == 'on'
  189. },
  190. {'name': 'sync_reps:regen_cache',
  191. 'foreach': 'cl_update_sync_overlay_rep',
  192. 'essential': False,
  193. 'method': 'Update.regenCache(eachvar)',
  194. 'condition': (
  195. lambda Get: (Get('cl_update_outdate_set') == 'on' and
  196. Get('cl_update_egencache_force') != 'skip' or
  197. Get('cl_update_egencache_force') == 'force'))
  198. },
  199. {'name': 'sync_other_reps:regen_other_cache',
  200. 'foreach': 'cl_update_other_rep_name',
  201. 'method': 'Update.regenCache(eachvar)',
  202. 'essential': False,
  203. },
  204. {'name': 'emerge_metadata',
  205. 'message': __("Metadata transfer"),
  206. 'method': 'Update.emergeMetadata()',
  207. 'condition': (
  208. lambda Get: (Get('cl_update_outdate_set') == 'on' and
  209. Get('cl_update_metadata_force') != 'skip' or
  210. Get('cl_update_metadata_force') == 'force'))
  211. },
  212. {'name': 'eix_update',
  213. 'message': __("Updating the eix cache"),
  214. 'method': 'Update.eixUpdate()',
  215. 'condition': (
  216. lambda Get: (Get('cl_update_outdate_set') == 'on' and
  217. Get('cl_update_eixupdate_force') != 'skip' or
  218. Get('cl_update_eixupdate_force') == 'force'))
  219. },
  220. # сообщение удачного завершения при обновлении репозиториев
  221. {'name': 'success_syncrep',
  222. 'message': __("Synchronization finished"),
  223. 'depend': (Tasks.success() & Tasks.has_any("sync_reps",
  224. "sync_other_reps",
  225. "emerge_metadata",
  226. "eix_update")),
  227. }
  228. ]
  229. },
  230. {'name': 'reps_synchronization',
  231. 'group': __("System configuration"),
  232. 'tasks': [
  233. {'name': 'revision',
  234. 'message': __("Fixing the settings"),
  235. 'method': 'Update.applyTemplates(install.cl_source,'
  236. 'cl_template_clt_set,True,None,False)',
  237. 'condition': lambda Get: Get('cl_templates_locate')
  238. },
  239. {'name': 'dispatch_conf',
  240. 'message': __("Updating configuration files"),
  241. 'method':'Update.dispatchConf()',
  242. 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and
  243. Get('cl_update_pretend_set') == 'off')
  244. },
  245. ]
  246. }
  247. ] + emerge_tasks + [
  248. {'name':'failed',
  249. 'error':__("Update failed"),
  250. 'depend': (Tasks.failed() & Tasks.hasnot("interrupt") &
  251. (Tasks.hasnot("check_schedule") |
  252. Tasks.success_all("check_schedule")))},
  253. {'name': 'failed',
  254. 'depend': Tasks.failed_all("check_schedule")
  255. },
  256. # сообщение удачного завершения при обновлении ревизии
  257. {'name': 'success_rev',
  258. 'message': __("System update finished!"),
  259. 'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and
  260. Get('cl_update_pretend_set') == 'off')
  261. },
  262. # сообщение удачного завершения при пересоздании world
  263. {'name': 'success_world',
  264. 'message': __("World rebuild finished!"),
  265. 'condition': lambda Get: Get('cl_rebuild_world_set') == 'on'
  266. },
  267. ]