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.

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