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.

351 lines
16 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2010-2016 Mir Calculate. 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.cl_template import TemplatesError
  19. from calculate.lib.utils.binhosts import BinhostError
  20. from calculate.lib.utils.files import FilesError, readFile
  21. from calculate.update.update import UpdateError
  22. from calculate.update.emerge_parser import EmergeError
  23. from calculate.lib.utils.git import GitError
  24. from calculate.lib.utils.portage import (EmergeLog,
  25. EmergeLogNamedTask, PackageList)
  26. from calculate.update.update_tasks import EmergeMark
  27. _ = lambda x: x
  28. setLocalTranslate('cl_update3', sys.modules[__name__])
  29. __ = getLazyLocalTranslate(_)
  30. class UpdateConditions(object):
  31. @staticmethod
  32. def was_installed(pkg, task_name):
  33. def func():
  34. task = EmergeLog(EmergeLogNamedTask(task_name))
  35. return bool(PackageList(task.list)[pkg])
  36. return func
  37. @staticmethod
  38. def need_depclean(pkg, task_name):
  39. def func(Get):
  40. task = EmergeLog(EmergeLogNamedTask(task_name))
  41. return (bool(PackageList(task.list)[pkg])
  42. or Get('cl_update_force_depclean_set') == 'on'
  43. or Get('cl_update_outdated_kernel_set') == 'on')
  44. return func
  45. @staticmethod
  46. def force_preserved(Get):
  47. pfile = "/var/lib/portage/preserved_libs_registry"
  48. content = readFile(pfile).strip()
  49. if not content or content[1:-1].strip() == '':
  50. return False
  51. else:
  52. return True
  53. class ClUpdateAction(Action):
  54. """
  55. Действие обновление конфигурационных файлов
  56. """
  57. # ошибки, которые отображаются без подробностей
  58. native_error = (FilesError, UpdateError,
  59. TemplatesError, BinhostError,
  60. GitError, EmergeError)
  61. successMessage = None
  62. failedMessage = None
  63. interruptMessage = __("Update manually interrupted")
  64. emerge_tasks = [
  65. {'name': 'save_bdeps_val',
  66. 'method': 'Update.save_with_bdeps()',
  67. 'essential': False
  68. },
  69. {'name': 'premerge_group',
  70. 'group': __("Checking for updates"),
  71. 'tasks': [
  72. {'name': 'premerge',
  73. 'message': __("Calculating dependencies"),
  74. 'method': 'Update.premerge("-uDN","@world")',
  75. 'condition': lambda Get: (
  76. Get('cl_update_sync_only_set') == 'off' and
  77. Get('cl_update_pretend_set') == 'on')
  78. }],
  79. },
  80. {'name': 'update',
  81. 'condition': lambda Get:Get('cl_update_pretend_set') == 'off',
  82. },
  83. {'name': 'update_other',
  84. 'condition': lambda Get: ( Get('cl_update_pretend_set') == 'off' and
  85. Get('cl_update_sync_only_set') == 'off')
  86. },
  87. {'name': 'update:update_world',
  88. 'group': __("Updating packages"),
  89. 'tasks': [
  90. {'name': 'update_world',
  91. 'message': __("Calculating dependencies"),
  92. 'method': 'Update.emerge_ask(cl_update_pretend_set,'
  93. '"-uDN","@world")',
  94. }
  95. ],
  96. 'condition': lambda Get: Get('cl_update_sync_only_set') == 'off'
  97. },
  98. {'name': 'update_other:update_perl',
  99. 'group': __("Updating Perl"),
  100. 'tasks': [
  101. {'name': 'update_other:perl_cleaner',
  102. 'message': __('Find & rebuild packages and Perl header files '
  103. 'broken due to a perl upgrade'),
  104. 'method': 'Update.emergelike("perl-cleaner", "all")',
  105. 'condition': UpdateConditions.was_installed(
  106. 'dev-lang/perl$', EmergeMark.PerlCleaner),
  107. 'decoration': 'Update.update_task("%s")' % EmergeMark.PerlCleaner
  108. },
  109. ]
  110. },
  111. {'name': 'update_other:depclean',
  112. 'group': __("Cleaning the system from needless packages"),
  113. 'tasks': [
  114. {'name': 'update_other:update_depclean',
  115. 'message': __("Calculating dependencies"),
  116. 'method': 'Update.depclean()',
  117. 'condition': UpdateConditions.need_depclean(
  118. '.*', EmergeMark.Depclean),
  119. 'decoration': 'Update.update_task("%s")' % EmergeMark.Depclean
  120. },
  121. ]
  122. },
  123. {'name': 'update_other:update_modules',
  124. 'group': __("Rebuilding dependent modules"),
  125. 'tasks': [
  126. {'name': 'update_other:module_rebuild',
  127. 'message': __('Updating Kernel modules'),
  128. 'method': 'Update.emerge("","@module-rebuild")',
  129. 'condition': UpdateConditions.was_installed(
  130. 'sys-kernel/.*source', EmergeMark.KernelModules),
  131. 'decoration': 'Update.update_task("%s")' %
  132. EmergeMark.KernelModules
  133. },
  134. {'name': 'update_other:x11_module_rebuild',
  135. 'message': __('Updating X.Org server modules'),
  136. 'method': 'Update.emerge("","@x11-module-rebuild")',
  137. 'condition': UpdateConditions.was_installed(
  138. 'x11-base/xorg-server', EmergeMark.XorgModules),
  139. 'decoration': 'Update.update_task("%s")' %
  140. EmergeMark.XorgModules
  141. },
  142. {'name': 'update_other:preserved_rebuild',
  143. 'message': __('Updating preserved libraries'),
  144. 'method': 'Update.emerge("","@preserved-rebuild")',
  145. 'condition': lambda Get: (UpdateConditions.was_installed(
  146. '.*', EmergeMark.PreservedLibs)() or
  147. UpdateConditions.force_preserved(Get)),
  148. 'decoration': 'Update.update_task("%s")' %
  149. EmergeMark.PreservedLibs
  150. },
  151. {'name': 'update_other:revdev_rebuild',
  152. 'message': __('Checking reverse dependencies'),
  153. 'method': 'Update.revdep_rebuild("revdep-rebuild")',
  154. 'condition': lambda Get: (Get(
  155. 'cl_update_skip_rb_set') == 'off' and
  156. UpdateConditions.was_installed(
  157. '.*', EmergeMark.RevdepRebuild)()),
  158. 'decoration': 'Update.update_task("%s")' %
  159. EmergeMark.RevdepRebuild
  160. },
  161. {'name': 'update_other:dispatch_conf_end',
  162. 'message': __("Updating configuration files"),
  163. 'method': 'Update.dispatchConf()',
  164. 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and
  165. Get('cl_update_pretend_set') == 'off')
  166. },
  167. ]
  168. },
  169. {'name': 'update:set_upto_date_cache',
  170. 'method': 'Update.setUpToDateCache()'
  171. }
  172. ]
  173. # список задач для действия
  174. tasks = [
  175. {'name': 'check_schedule',
  176. 'method': 'Update.checkSchedule(cl_update_autocheck_interval,'
  177. 'cl_update_autocheck_set)',
  178. 'condition': lambda Get: (
  179. Get('cl_update_autocheck_schedule_set') == 'on'),
  180. },
  181. {'name': 'check_run',
  182. 'method': 'Update.checkRun(cl_update_wait_another_set)'
  183. },
  184. {'name': 'reps_synchronization',
  185. 'group': __("Repositories synchronization"),
  186. 'tasks': [
  187. # запасная синхронизация, в ходе которой ветки обновляются до
  188. # master
  189. {'name': 'sync_reps_fallback',
  190. 'foreach': 'cl_update_sync_rep',
  191. 'message':
  192. __("Fallback syncing the {eachvar:capitalize} repository"),
  193. 'method': 'Update.syncRepositories(eachvar,True)',
  194. 'condition': lambda Get: ("getbinpkg" in Get('cl_features') and
  195. not Get('cl_update_binhost_data')[0])
  196. },
  197. # обновление переменных информации из binhost
  198. {'name': 'update_binhost_list',
  199. 'method': 'Update.update_binhost_list()',
  200. 'condition': lambda Get: ("getbinpkg" in Get('cl_features') and
  201. not Get('cl_update_binhost_data')[0])
  202. },
  203. {'name': 'sync_reps',
  204. 'foreach': 'cl_update_sync_rep',
  205. 'message': __("Checking {eachvar:capitalize} updates"),
  206. 'method': 'Update.syncRepositories(eachvar)',
  207. 'condition': lambda Get: Get('cl_update_sync_rep')
  208. },
  209. {'name': 'check_binhost',
  210. 'method': 'Update.check_binhost()',
  211. 'condition': lambda Get: "getbinpkg" in Get('cl_features')
  212. },
  213. {'name': 'sync_other_reps',
  214. 'foreach': 'cl_update_other_rep_name',
  215. 'message': __("Syncing the {eachvar:capitalize} repository"),
  216. 'method': 'Update.syncLaymanRepository(eachvar)',
  217. 'condition': lambda Get: Get('cl_update_other_set') == 'on'
  218. },
  219. {'name': 'trim_reps',
  220. 'foreach': 'cl_update_sync_rep',
  221. 'message': __("Cleaning the history of the "
  222. "{eachvar:capitalize} repository"),
  223. 'method': 'Update.trimRepositories(eachvar)',
  224. 'condition': lambda Get: (Get('cl_update_sync_rep') and
  225. Get('cl_update_onedepth_set') == 'on')
  226. },
  227. {'name': 'sync_reps:regen_cache',
  228. 'foreach': 'cl_update_sync_overlay_rep',
  229. 'essential': False,
  230. 'method': 'Update.regenCache(eachvar)',
  231. 'condition': (
  232. lambda Get: (Get('cl_update_outdate_set') == 'on' and
  233. Get('cl_update_egencache_force') != 'skip' or
  234. Get('cl_update_egencache_force') == 'force'))
  235. },
  236. {'name': 'sync_other_reps:regen_other_cache',
  237. 'foreach': 'cl_update_other_rep_name',
  238. 'method': 'Update.regenCache(eachvar)',
  239. 'essential': False,
  240. },
  241. {'name': 'emerge_metadata',
  242. 'message': __("Metadata transfer"),
  243. 'method': 'Update.emergeMetadata()',
  244. 'condition': (
  245. lambda Get: (Get('cl_update_outdate_set') == 'on' and
  246. Get('cl_update_metadata_force') != 'skip' or
  247. Get('cl_update_metadata_force') == 'force'))
  248. },
  249. {'name': 'eix_update',
  250. 'message': __("Updating the eix cache for "
  251. "{cl_update_eix_repositories}"),
  252. 'method': 'Update.eixUpdate(cl_repository_name)',
  253. 'condition': (
  254. lambda Get: (Get('cl_update_outdate_set') == 'on' and
  255. Get('cl_update_eixupdate_force') != 'skip' or
  256. Get('cl_update_eixupdate_force') == 'force'))
  257. },
  258. {'name': 'update_setup_cache',
  259. 'message': __("Updating the cache of configurable packages"),
  260. 'method': 'Update.updateSetupCache()',
  261. 'essential': False,
  262. 'condition': lambda Get: Get('cl_update_outdate_set') == 'on'
  263. },
  264. {'name': 'sync_reps:cleanpkg',
  265. 'message': __("Removing obsolete distfiles and binary packages"),
  266. 'method': 'Update.cleanpkg()',
  267. 'condition': (
  268. lambda Get: Get('cl_update_cleanpkg_set') == 'on' and
  269. Get('cl_update_outdate_set') == 'on'),
  270. 'essential': False
  271. },
  272. {'name': 'update_packages_cache',
  273. 'message': __("Update packages index"),
  274. 'method': 'Update.download_packages(cl_update_portage_binhost,'
  275. 'cl_update_package_cache)',
  276. 'essential': False,
  277. 'condition': lambda Get: (
  278. "getbinpkg" in Get('cl_features') and
  279. Get('cl_update_package_cache') and (
  280. Get('cl_update_outdate_set') == 'on' or
  281. Get('cl_update_package_cache_set') == 'on'))
  282. },
  283. # сообщение удачного завершения при обновлении репозиториев
  284. {'name': 'success_syncrep',
  285. 'message': __("Synchronization finished"),
  286. 'depend': (Tasks.success() & Tasks.has_any("sync_reps",
  287. "sync_other_reps",
  288. "emerge_metadata",
  289. "eix_update")),
  290. }
  291. ]
  292. },
  293. {'name': 'reps_synchronization',
  294. 'group': __("System configuration"),
  295. 'tasks': [
  296. {'name': 'revision',
  297. 'message': __("Fixing the settings"),
  298. 'method': 'Update.applyTemplates(install.cl_source,'
  299. 'cl_template_clt_set,True,None,False)',
  300. 'condition': lambda Get: (Get('cl_templates_locate') and
  301. (Get('cl_update_world') != "update" or
  302. Get('cl_update_outdate_set') == 'on' or
  303. Get('cl_update_force_fix_set') == 'on'))
  304. },
  305. {'name': 'dispatch_conf',
  306. 'message': __("Updating configuration files"),
  307. 'method': 'Update.dispatchConf()',
  308. 'condition': lambda Get: (Get('cl_dispatch_conf') != 'skip' and
  309. Get('cl_update_pretend_set') == 'off' and
  310. (Get('cl_update_outdate_set') == 'on' or
  311. Get('cl_update_force_fix_set') == 'on'))
  312. },
  313. {'name': 'binhost_changed',
  314. 'method': 'Update.message_binhost_changed()'
  315. },
  316. ]
  317. }
  318. ] + emerge_tasks + [
  319. {'name': 'failed',
  320. 'error': __("Update failed"),
  321. 'depend': (Tasks.failed() & Tasks.hasnot("interrupt") &
  322. (Tasks.hasnot("check_schedule") |
  323. Tasks.success_all("check_schedule")))},
  324. {'name': 'failed',
  325. 'depend': Tasks.failed_all("check_schedule")
  326. },
  327. # сообщение удачного завершения при обновлении ревизии
  328. {'name': 'success_rev',
  329. 'message': __("System update finished!"),
  330. 'condition': lambda Get: (Get('cl_update_rev_set') == 'on' and
  331. Get('cl_update_pretend_set') == 'off')
  332. },
  333. # сообщение удачного завершения при пересоздании world
  334. {'name': 'success_world',
  335. 'message': __("World rebuild finished!"),
  336. 'condition': lambda Get: Get('cl_rebuild_world_set') == 'on'
  337. },
  338. ]