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.

1037 lines
33 KiB

  1. #-*- coding: utf-8 -*-
  2. # Copyright 2008-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 os
  16. import sys
  17. import re
  18. from os import path
  19. from calculate.lib.datavars import (Variable, VariableError,
  20. ReadonlyVariable, ReadonlyTableVariable, TableVariable, FieldValue,
  21. SimpleDataVars, DataVarsError)
  22. from calculate.lib.utils.portage import searchProfile
  23. from calculate.lib.utils.files import readLinesFile, readFile, makeDirectory, \
  24. listDirectory, process
  25. from calculate.lib.cl_lang import setLocalTranslate
  26. from calculate.lib.utils.text import simplify_profiles
  27. from calculate.update.package_tools import Git, GitError, Layman
  28. from calculate.update.profile import RepositoryStorageSet, DEFAULT_BRANCH
  29. from calculate.lib.variables.linux import VariableOsLinuxName, \
  30. VariableOsLinuxSubname, VariableOsLinuxVer, VariableOsLinuxShortname
  31. from calculate.lib.variables.env import VariableClTemplateLocation
  32. setLocalTranslate('cl_update3', sys.modules[__name__])
  33. class VariableAcUpdateSync(ReadonlyVariable):
  34. """
  35. Action variable which has value "up" for package install and
  36. install this package
  37. """
  38. def get(self):
  39. action = self.Get("cl_action")
  40. if action in ("sync",):
  41. if self.Get('cl_update_world'):
  42. return self.Get('cl_update_world')
  43. return ""
  44. class VariableClUpdateWorld(Variable):
  45. type = "choice"
  46. value = "update"
  47. opt = ["--world"]
  48. syntax = "--{choice}-world"
  49. metavalue = "MODE"
  50. def init(self):
  51. self.help = ("'rebuild' - " + _("rebuild system packages list") +
  52. ",\n'merge' - " + _("append profile system packages list") +
  53. ",\n'update' - " + _("update system packages list"))
  54. self.label = _("System packages list")
  55. def choice(self):
  56. return [("rebuild", _("Rebuild")),
  57. ("merge", _("Merge")),
  58. ("update", _("Update"))]
  59. class VariableClRebuildWorldSet(Variable):
  60. """
  61. List of action update world, rebuild world,
  62. """
  63. type = "bool"
  64. opt = ["--rebuild-world"]
  65. untrusted = True
  66. value = "off"
  67. def init(self):
  68. self.help = _("Rebuild world")
  69. self.label = _("Rebuild world")
  70. class VariableClUpdateRevSet(Variable):
  71. """
  72. List of action update world, rebuild world,
  73. """
  74. type = "bool"
  75. opt = ["--update-rev"]
  76. untrusted = True
  77. value = "on"
  78. check_after = ["cl_update_sync_rep",
  79. "cl_update_metadata_force",
  80. "cl_update_other_set",
  81. "cl_update_eixupdate_force"]
  82. def init(self):
  83. self.help = _("make a revision update")
  84. self.label = _("Make a revision update")
  85. class VariableClUpdateRep(Variable):
  86. """
  87. Обновлять репозитории до конкретной ревизии или до последней
  88. """
  89. type = "choice"
  90. value = "rev"
  91. def choice(self):
  92. return ["last","rev"]
  93. class VariableClUpdateRepData(ReadonlyTableVariable):
  94. """
  95. Информация о репозиториях
  96. """
  97. source = ['cl_update_rep_name',
  98. 'cl_update_rep_url',
  99. 'cl_update_rep_path',
  100. 'cl_update_rep_rev',
  101. 'cl_update_branch_name']
  102. class VariableClUpdateRepName(Variable):
  103. """
  104. Список имен используемых репозиториев
  105. """
  106. type = "list"
  107. value = []
  108. class VariableClUpdateRepUrl(Variable):
  109. """
  110. Список путей до репозиториев
  111. """
  112. type = "list"
  113. value = []
  114. class VariableClUpdateLaymanStorage(ReadonlyVariable):
  115. """
  116. Путь к репозиториям layman
  117. """
  118. def get(self):
  119. laymanConf = "/etc/layman/layman.cfg"
  120. reStorage = re.compile("^storage\s*:\s*(\S+)")
  121. if path.exists(laymanConf):
  122. for line in readLinesFile(laymanConf):
  123. match = reStorage.search(line)
  124. if match:
  125. return match.group(1)
  126. return "/var/lib/layman"
  127. class VariableClUpdateRepPath(ReadonlyVariable):
  128. """
  129. Пути до репозиториев
  130. """
  131. type = "list"
  132. mapPath = {'portage':'/usr/portage'}
  133. def get(self):
  134. repPath = self.Get('cl_update_layman_storage')
  135. def generatePaths(names):
  136. for name in names:
  137. if name in self.mapPath:
  138. yield self.mapPath[name]
  139. else:
  140. yield path.join(repPath,name)
  141. return list(generatePaths(self.Get('cl_update_rep_name')))
  142. class VariableClUpdateRepRev(Variable):
  143. """
  144. Ревизии до которых необходимо обновить репозитории
  145. """
  146. type = "list"
  147. def get(self):
  148. if self.Get('cl_update_rep') == 'rev':
  149. revPaths = searchProfile(self.Get('cl_profile_system'),
  150. "rev")
  151. if revPaths:
  152. revPath = revPaths[-1]
  153. dictNamesRevs = dict(map(lambda x:x.strip().partition('=')[::2],
  154. readLinesFile(revPath)))
  155. return map(lambda x:dictNamesRevs.get(x,"last"),
  156. self.Get('cl_update_rep_name'))
  157. return ["last"]*len(self.Get('cl_update_rep_name'))
  158. class VariableClUpdateBranch(TableVariable):
  159. """
  160. Выбор веток репозиториев до которых необходимо обновиться
  161. """
  162. opt = ["--branch"]
  163. metavalue = 'BRANCHES'
  164. untrusted = True
  165. source = ["cl_update_branch_rep",
  166. "cl_update_branch_name"]
  167. def init(self):
  168. self.help = _("set branches for repository (REPOSITORY:BRANCH)")
  169. self.label = _("Repositories branches")
  170. def raiseReadonlyIndexError(self,fieldname="",variablename="",
  171. value=""):
  172. """
  173. Неизвестный оврелей
  174. """
  175. raise VariableError(_("Repository %s not found")%value)
  176. class VariableClUpdateBranchRep(ReadonlyVariable):
  177. """
  178. Список доступных репозиторием
  179. """
  180. type = "list"
  181. def init(self):
  182. self.label = _("Repositories")
  183. def get(self):
  184. return self.Get('cl_update_rep_name')
  185. class VariableClUpdateBranchName(Variable):
  186. """
  187. Список доступных репозиторием
  188. """
  189. type = "choiceedit-list"
  190. def init(self):
  191. self.label = _("Branches")
  192. def choice(self):
  193. return ["master", "develop", "update"]
  194. def get(self):
  195. def generateBranch():
  196. for reppath in self.Get('cl_update_rep_path'):
  197. headPath = path.join(reppath, ".git/HEAD")
  198. yield readFile(headPath).rpartition('/')[2].strip() or "master"
  199. return list(generateBranch())
  200. class VariableClUpdateSyncRep(Variable):
  201. """
  202. Обновляемый репозиторий
  203. """
  204. type = "choice-list"
  205. element = "selecttable"
  206. opt = ["-r", "--repositories"]
  207. metavalue = "REPOSITORIES"
  208. untrusted = True
  209. def init(self):
  210. self.help = _("synchronized repositories (all by default)")
  211. self.label = _("Synchronized repositories")
  212. def set(self,value):
  213. orderList = self.Get('cl_update_rep_name')
  214. return sorted(value,key=lambda x:
  215. (orderList.index(x) if x in orderList else -1),reverse=True)
  216. def get(self):
  217. return list(reversed(self.Get('cl_update_rep_name')))
  218. def choice(self):
  219. return self.Get('cl_update_rep_name')
  220. class VariableClUpdateSyncOverlayRep(ReadonlyVariable):
  221. """
  222. Обновляемые репозитории (исключая portage)
  223. """
  224. type = "list"
  225. def get(self):
  226. return filter(lambda x:x!="portage",self.Get('cl_update_sync_rep'))
  227. class VariableClUpdateOutdateSet(ReadonlyVariable):
  228. """
  229. Флаг устанавливаемый в ходе обновления репозиториев,
  230. сообщающий что хотя бы один из запланированных репозиториев
  231. обновлен и следует обновляет различные метаданные
  232. Если обновляются прочие оверлеи - данные считаются что устарели
  233. """
  234. type = "bool"
  235. value = "off"
  236. def get(self):
  237. return self.Get('cl_update_other_set')
  238. class VariableClUpdateMetadataForce(Variable):
  239. """
  240. Принудительное действие с метаданными
  241. """
  242. type = "choice"
  243. value = "auto"
  244. opt = ["--update-metadata"]
  245. syntax = "--{choice}-update-metadata"
  246. metavalue = "MODE"
  247. #untrusted = True
  248. def init(self):
  249. self.help = ("'force' - " + _("force the update ebuilds metadata") +
  250. ",\n'skip' - " + _("skip the ebuild metadata update") +
  251. ",\n'auto' - " + _("update metadata if it is outdated"))
  252. self.label = _("Update metadata")
  253. def choice(self):
  254. return [("force", _("Force")),
  255. ("skip", _("Skip")),
  256. ("auto", _("If needed"))]
  257. class VariableClUpdateEgencacheForce(Variable):
  258. """
  259. Принудительное выполнение egencache
  260. """
  261. type = "choice"
  262. value = "auto"
  263. opt = ["--egencache"]
  264. syntax = "--{choice}-egencache"
  265. metavalue = "MODE"
  266. #untrusted = True
  267. def init(self):
  268. self.help = ("'force' - " + _("force the update overlays cache") +
  269. ",\n'skip' - " + _("skip the overlays cache update") +
  270. ",\n'auto' - " + _("update overlays cache if it is outdated"))
  271. self.label = _("Update overlays cache")
  272. def choice(self):
  273. return [("force", _("Force")),
  274. ("skip", _("Skip")),
  275. ("auto", _("If needed"))]
  276. class VariableClUpdateEixupdateForce(Variable):
  277. """
  278. Принудительное действие с eix-update
  279. """
  280. type = "choice"
  281. value = "auto"
  282. opt = ["--eix-update"]
  283. syntax = "--{choice}-eix-update"
  284. metavalue = "MODE"
  285. #untrusted = True
  286. def init(self):
  287. self.help = ("'force' - " + _("force the eix cache update") +
  288. ",\n'skip' - " + _("skip the eix cache update") +
  289. ",\n'auto' - " + _("update the eix cache if it "
  290. "is outdated"))
  291. self.label = _("Update the eix cache")
  292. def choice(self):
  293. return [("force", _("Force")),
  294. ("skip", _("Skip")),
  295. ("auto", _("If needed"))]
  296. class VariableClUpdateOtherSet(Variable):
  297. """
  298. Обновить остальные оверлеи
  299. """
  300. type = "bool"
  301. value = "off"
  302. opt = ["-o", "--update-other"]
  303. def init(self):
  304. self.help = _("update other overlays")
  305. self.label = _("Update other overlays")
  306. class VariableClUpdateOtherRepData(ReadonlyTableVariable):
  307. """
  308. Информация о прочих репозиториях
  309. """
  310. source = ['cl_update_other_rep_name',
  311. 'cl_update_other_rep_path']
  312. def generator(self):
  313. repNames = self.Get('cl_update_rep_name')
  314. layman = Layman(self.Get('cl_update_layman_installed'),
  315. self.Get('cl_update_layman_make'))
  316. layman_overlays = layman.get_installed()
  317. for rpath in self.Get('cl_portdir_overlay'):
  318. repo_file = path.join(rpath, "profiles/repo_name")
  319. rname = readFile(repo_file).strip() or path.basename(rpath)
  320. if rname in layman_overlays and not rname in repNames:
  321. yield (rname, rpath)
  322. def get(self):
  323. return list(self.generator())
  324. class VariableClUpdateOtherRepName(FieldValue,ReadonlyVariable):
  325. """
  326. Список имен прочих репозиториев
  327. """
  328. type = "list"
  329. source_variable = "cl_update_other_rep_data"
  330. column = 0
  331. class VariableClUpdateOtherRepPath(FieldValue,ReadonlyVariable):
  332. """
  333. Список путей до прочих репозиториев
  334. """
  335. type = "list"
  336. source_variable = "cl_update_other_rep_data"
  337. column = 1
  338. class VariableClUpdateLaymanInstalled(Variable):
  339. """
  340. Путь до файла layman installed.xml
  341. """
  342. # TODO: извлечь из layman.cfg
  343. value = "/var/lib/layman/installed.xml"
  344. class VariableClUpdateLaymanMake(Variable):
  345. """
  346. Путь до файла make.conf изменяемого layman`ом
  347. """
  348. # TODO: извлечь из layman.cfg
  349. value = "/var/lib/layman/make.conf"
  350. class VariableClUpdatePretendSet(Variable):
  351. """
  352. Запустить предварительную проверку на обновления
  353. """
  354. type = "bool"
  355. value = "off"
  356. opt = ["-p", "--pretend"]
  357. def init(self):
  358. self.label = _("Pretend a package update")
  359. self.help = _("instead of actually performing the update, "
  360. "simply display the list of packages that "
  361. "will be installed")
  362. class VariableClUpdateSyncOnlySet(Variable):
  363. """
  364. Не выполнять установку/обновление пакетов при обновлении
  365. """
  366. type = "bool"
  367. value = "off"
  368. opt = ["-s", "--sync-only"]
  369. def init(self):
  370. self.label = _("Only synchronize repositories")
  371. self.help = _("do not update packages")
  372. def check(self, value):
  373. if (value == "on" and self.Get('cl_rebuild_world_set') != 'on' and
  374. not self.Get('cl_update_sync_rep') and
  375. self.Get('cl_update_other_set') == 'off' and
  376. self.Get('cl_update_rev_set') == 'off' and
  377. self.Get('cl_update_metadata_force') != "force" and
  378. self.Get('cl_update_eixupdate_force') != "force"):
  379. raise VariableError(_("Select at least one sync repository"))
  380. class VariableClUpdateWaitAnotherSet(Variable):
  381. """
  382. Ждать завершения другого процесса обновления
  383. """
  384. type = "bool"
  385. value = "on"
  386. opt = ["--wait-another-update"]
  387. def init(self):
  388. self.label = _("Wait for another update to be complete")
  389. self.help = _("wait until the running update is finished")
  390. class VariableClUpdateProfileStorage(ReadonlyVariable):
  391. type = "object"
  392. def get(self):
  393. return RepositoryStorageSet()
  394. class VariableClUpdateRepHost(Variable):
  395. type = "list"
  396. value = ['calculate']
  397. class VariableClUpdateRepHostUrl(Variable):
  398. type = "list"
  399. value = ['git://git.calculate.ru/calculate/%s.git']
  400. class VariableClUpdateProfileDatavars(ReadonlyVariable):
  401. type = "object"
  402. def get(self):
  403. profile = self.Get('cl_update_profile_system')
  404. path_profile = self.Select('cl_profile_path',
  405. where='cl_profile_shortname',
  406. eq=profile, limit=1)
  407. if path_profile:
  408. return DataVarsUpdateProfile(path_profile)
  409. return ""
  410. class VariableClUpdateProfileLinuxFullname(ReadonlyVariable):
  411. """
  412. Имя системы в профиле
  413. """
  414. def init(self):
  415. self.label = _("Distribution name")
  416. def get(self):
  417. dv = self.Get('cl_update_profile_datavars')
  418. if dv:
  419. try:
  420. subname = dv.Get('os_linux_subname')
  421. linuxname = dv.Get('os_linux_name')
  422. linuxver = dv.Get('os_linux_ver')
  423. if subname:
  424. return "%s %s %s" % (linuxname, linuxver, subname)
  425. return "%s %s" %(linuxname,linuxver)
  426. except DataVarsError:
  427. raise VariableError("Wrong Calculate Linux profile")
  428. return ""
  429. class VariableClUpdateProfileDependData(ReadonlyTableVariable):
  430. """
  431. Зависимые репозитории
  432. """
  433. source = ['cl_update_profile_depend_name',
  434. 'cl_update_profile_depend_url']
  435. def init(self):
  436. self.label = _("Used repositories")
  437. @staticmethod
  438. def url_like(url1, url2):
  439. match1 = VariableClUpdateProfileRep.re_url.search(url1)
  440. match2 = VariableClUpdateProfileRep.re_url.search(url2)
  441. if match1 and match2:
  442. return match1.group(2).lower() == match2.group(2).lower()
  443. return False
  444. def get(self, hr=False):
  445. dv = self.Get('cl_update_profile_datavars')
  446. url = self.Get('cl_update_profile_rep').lower()
  447. if dv:
  448. return reversed(zip(dv.Get('cl_update_rep_name'),
  449. dv.Get('cl_update_rep_url')))
  450. return ""
  451. setValue = Variable.setValue
  452. class VariableClUpdateTemplatesLocate(Variable):
  453. """
  454. Выбранные типы хранилищ шаблонов
  455. """
  456. type = "choice-list"
  457. element = "selecttable"
  458. opt = ["-T","--templates"]
  459. metavalue = "TEMPLATES"
  460. untrusted = True
  461. check_after = ['cl_update_profile_system']
  462. descriptionMap = {'overlay': _('Overlay templates'),
  463. 'local': _('Local templates'),
  464. 'calculate': _("Calculate overlay templates"),
  465. 'distros': _('Distribution templates'),
  466. 'distro': _('Distribution templates'),
  467. 'remote': _('Remote templates'),
  468. 'clt': _('clt templates')}
  469. def init(self):
  470. self.label = _("Templates location")
  471. self.help = _("select location for templates %s") \
  472. %",".join(self.get())
  473. def get(self):
  474. dv = self.Get('update.cl_update_profile_datavars')
  475. if dv:
  476. return dv.Get('cl_template_location') + ['clt']
  477. else:
  478. return self.Get('cl_templates_locate')
  479. def choice(self):
  480. return map(lambda x:(x,self.descriptionMap.get(x,_("%s overlay templates")%x)),
  481. self.get())
  482. class VariableClUpdateProfileDependName(FieldValue, ReadonlyVariable):
  483. type = "list"
  484. source_variable = "cl_update_profile_depend_data"
  485. column = 0
  486. def init(self):
  487. self.label = _("Name")
  488. class VariableClUpdateProfileDependUrl(FieldValue, ReadonlyVariable):
  489. type = "list"
  490. source_variable = "cl_update_profile_depend_data"
  491. column = 1
  492. def init(self):
  493. self.label = _("URL")
  494. class VariableClUpdateProfileRepName(ReadonlyVariable):
  495. type = "list"
  496. def get(self):
  497. dv = self.Get('cl_update_profile_datavars')
  498. if dv:
  499. return dv.Get('cl_update_rep_name')
  500. return []
  501. class VariableClUpdateProfileSyncRep(ReadonlyVariable):
  502. type = "list"
  503. def get(self):
  504. return list(reversed(self.Get('cl_update_profile_rep_name')))
  505. class VariableClUpdateProfileRepUrl(ReadonlyVariable):
  506. type = "list"
  507. def get(self):
  508. dv = self.Get('cl_update_profile_datavars')
  509. if dv:
  510. return dv.Get('cl_update_rep_url')
  511. return []
  512. class VariableClUpdateProfileLinuxVer(ReadonlyVariable):
  513. """
  514. Имя системы в профиле
  515. """
  516. def init(self):
  517. self.label = _("System profile version")
  518. def get(self):
  519. dv = self.Get('cl_update_profile_datavars')
  520. if dv:
  521. return dv.Get('os_linux_ver')
  522. return ""
  523. class VariableClUpdateProfileLinuxName(ReadonlyVariable):
  524. """
  525. Имя системы в профиле
  526. """
  527. def get(self):
  528. dv = self.Get('cl_update_profile_datavars')
  529. if dv:
  530. dv.Get('os_linux_name')
  531. return ""
  532. class VariableClUpdateProfileRep(Variable):
  533. """
  534. Текущий репозиторий
  535. """
  536. untrusted = True
  537. check_after = ["cl_update_profile_branch"]
  538. opt = ["--url"]
  539. def init(self):
  540. self.label = _("Profile repository")
  541. self.help = _("set the profile repository")
  542. re_url = re.compile(
  543. r"^(?:(%s)://)?(\w[\w\./:-]+?\w)(\.git)?$" % "|".join(
  544. ["http", "https", "git"]))
  545. re_shortname = re.compile('^(?:([\w\.-]+):)?([\w\.-]+)$')
  546. @classmethod
  547. def normalize_url(cls, url):
  548. match = cls.re_url.match(url)
  549. if not match:
  550. raise VariableError(_("Wrong repository URL"))
  551. url = match.group(2)
  552. url = "%s://%s" % (match.group(1) or "git", url)
  553. url = "%s.git" % url
  554. return url
  555. def url_by_shortname(self, value):
  556. match = self.re_shortname.match(value)
  557. if not match.group(1):
  558. template = self.Get('cl_update_rep_host_url')
  559. if template:
  560. template = template[0]
  561. else:
  562. template = self.Select('cl_update_rep_host_url',
  563. where='cl_update_rep_host',
  564. eq=match.group(1), limit=1)
  565. if not template:
  566. raise VariableError(_("Failed to determine the repository host"))
  567. try:
  568. return template % match.group(2)
  569. except TypeError:
  570. raise VariableError(_("Failed to determine the repository host"))
  571. def set(self, value):
  572. if self.re_shortname.match(value):
  573. value = self.url_by_shortname(value)
  574. return self.normalize_url(value)
  575. def check(self, value):
  576. if not value:
  577. raise VariableError("Need to specify profile repository")
  578. try:
  579. branch = self.Get('cl_update_profile_branch')
  580. self.Get('cl_update_profile_storage').get_profiles(value, branch)
  581. except GitError as e:
  582. raise VariableError(str(e))
  583. if not self.Get('cl_profile_shortname'):
  584. raise VariableError(_("Repository %s has no profiles")%value)
  585. def get(self):
  586. try:
  587. profile = self.Get('cl_profile_system')
  588. while profile != '/' and ".git" not in listDirectory(profile):
  589. profile = path.dirname(profile)
  590. if profile == '/':
  591. return ""
  592. git = Git()
  593. return git.get_url(profile, "origin") or ""
  594. except:
  595. return "git://git.calculate.ru/calculate/distros.git"
  596. class VariableClUpdateProfileRepoName(ReadonlyVariable):
  597. def init(self):
  598. self.label = _("Repository name")
  599. def get(self):
  600. rep_set = self.Get('cl_update_profile_storage')
  601. url = self.Get('cl_update_profile_rep')
  602. rep = rep_set.get_repository(url)
  603. if rep:
  604. return rep.repo_name
  605. return ""
  606. class VariableClUpdateProfileBranch(Variable):
  607. """
  608. Текущий репозиторий
  609. """
  610. untrusted = True
  611. type = "edit"
  612. opt = ["--branch"]
  613. def init(self):
  614. self.label = _("Repository branch")
  615. self.help = _("set the repository branch")
  616. def check(self, value):
  617. pass
  618. ## TODO: проверка ветки
  619. #try:
  620. # url = self.Get('cl_update_profile_rep')
  621. # self.Get('cl_update_profile_storage').get_profiles(url, value)
  622. #except GitError as e:
  623. # raise VariableError(str(e))
  624. def get(self):
  625. rep_set = self.Get('cl_update_profile_storage')
  626. url = self.Get('cl_update_profile_rep')
  627. #print url, rep_set.is_local(url, branch=None)
  628. if rep_set.is_local(url, branch=None):
  629. rep = rep_set.get_repository(url, branch=None)
  630. git = Git()
  631. return git.getBranch(rep.directory)
  632. return DEFAULT_BRANCH
  633. class VariableClProfileSystem(ReadonlyVariable):
  634. """
  635. Профиль системы (симлинк /etc/make.profile')
  636. """
  637. def get(self):
  638. try:
  639. make_profile = self.Get('cl_make_profile')
  640. return path.normpath(
  641. path.join(path.dirname(make_profile),
  642. os.readlink(make_profile)))
  643. except:
  644. raise VariableError(_("Failed to determine the system profile"))
  645. class VariableClProfileData(ReadonlyTableVariable):
  646. source = ["cl_profile_fullname",
  647. "cl_profile_shortname",
  648. "cl_profile_path",
  649. "cl_profile_arch"]
  650. def get(self, hr=False):
  651. url = self.Get('cl_update_profile_rep')
  652. if not url:
  653. return [[]]
  654. try:
  655. rep_set = self.Get('cl_update_profile_storage')
  656. branch = self.Get('cl_update_profile_branch')
  657. rep = rep_set.get_repository(url, branch)
  658. if rep and self.Get('cl_update_profile_sync_set') == 'on':
  659. rep.sync()
  660. profiles = rep_set.get_profiles(url, branch)
  661. except GitError:
  662. return [[]]
  663. arch = self.Get('os_arch_machine_gentoo')
  664. if profiles:
  665. repo_name = profiles[0].repository.repo_name
  666. arch_profiles = [x for x in profiles if x.arch == arch]
  667. full_name = [x.profile for x in arch_profiles]
  668. profile_path = [x.path for x in arch_profiles]
  669. profile_arch = [x.arch for x in arch_profiles]
  670. short_name = simplify_profiles(full_name)
  671. full_name = ["%s:%s"%(repo_name,x) for x in full_name]
  672. return zip(full_name,
  673. short_name,
  674. profile_path,
  675. profile_arch)
  676. return [[]]
  677. setValue = Variable.setValue
  678. class VariableClProfileFullname(FieldValue, ReadonlyVariable):
  679. """
  680. Полное название профиля
  681. """
  682. type = "list"
  683. source_variable = "cl_profile_data"
  684. column = 0
  685. class VariableClProfileShortname(FieldValue, ReadonlyVariable):
  686. """
  687. Упрощенное название профиля
  688. """
  689. type = "list"
  690. source_variable = "cl_profile_data"
  691. column = 1
  692. class VariableClProfilePath(FieldValue, ReadonlyVariable):
  693. """
  694. Путь от корня до профиля
  695. """
  696. type = "list"
  697. source_variable = "cl_profile_data"
  698. column = 2
  699. class VariableClProfileArch(FieldValue, ReadonlyVariable):
  700. """
  701. Архитектура профиля
  702. """
  703. type = "list"
  704. source_variable = "cl_profile_data"
  705. column = 3
  706. class VariableClUpdateProfileSystem(Variable):
  707. """
  708. Профиль системы (симлинк /etc/make.profile')
  709. """
  710. type = "choice"
  711. opt = ["cl_update_profile_system"]
  712. untrusted = True
  713. metavalue = "PROFILE"
  714. def init(self):
  715. self.label = _("System profile")
  716. self.help = _("set the system profile")
  717. def check(self, profile):
  718. if not profile:
  719. raise VariableError(_("You must specify the profile"))
  720. path_profile = self.Select('cl_profile_path',
  721. where='cl_profile_shortname',
  722. eq=profile, limit=1)
  723. if path_profile:
  724. dv = DataVarsUpdateProfile(path_profile)
  725. try:
  726. if (not dv.Get('cl_update_rep_name') or
  727. not dv.Get('cl_update_rep_url')):
  728. raise VariableError(_("Repository variables "
  729. "were not configured for the profile"))
  730. if not dv.Get('os_linux_name'):
  731. raise VariableError()
  732. except (DataVarsError, VariableError) as e:
  733. raise VariableError(_("The selected profile is not Calculate"))
  734. else:
  735. raise VariableError(_("Wrong Calculate profile"))
  736. def get(self):
  737. try:
  738. profile_system = self.Get('cl_profile_system')
  739. profile = self.Select('cl_profile_shortname',
  740. where='cl_profile_path',
  741. eq=profile_system, limit=1)
  742. if profile:
  743. return profile
  744. except VariableError:
  745. pass
  746. shortname = self.Get('cl_profile_shortname')
  747. if len(shortname) == 1:
  748. return shortname[0]
  749. return ""
  750. def choice(self):
  751. url = self.Get('cl_update_profile_rep')
  752. if not url:
  753. return []
  754. arch = self.Get('os_arch_machine_gentoo')
  755. profiles = zip(*self.Select(['cl_profile_shortname',
  756. 'cl_profile_fullname'],
  757. where='cl_profile_arch', eq=arch))
  758. if profiles:
  759. short_name, full_name = profiles
  760. return zip(short_name, full_name)
  761. return []
  762. class DataVarsUpdateProfile(SimpleDataVars):
  763. """
  764. Упрощенная модель переменных для получения данных с удаленного профиля
  765. """
  766. source = ['cl_update_rep_name',
  767. 'cl_update_rep_url',
  768. 'cl_update_rep_path',
  769. 'cl_update_rep_rev',
  770. 'cl_update_branch_name']
  771. def __init__(self, profile):
  772. SimpleDataVars.__init__(self,
  773. VariableOsLinuxName(),
  774. VariableOsLinuxShortname(),
  775. VariableOsLinuxSubname(),
  776. VariableOsLinuxVer(),
  777. VariableClTemplateLocation(),
  778. VariableClUpdateRepData(section="update"),
  779. VariableClUpdateRepPath(section="update"),
  780. VariableClUpdateRepRev(section="update"),
  781. VariableClUpdateBranchName(section="update"),
  782. VariableClProfileSystem(section="update"),
  783. VariableClUpdateLaymanStorage(section="update"),
  784. VariableClUpdateRepName(section="update"),
  785. VariableClUpdateRep(section="update"),
  786. VariableClUpdateRepUrl(section="update"))
  787. self.cache['cl_profile_system'] = profile
  788. self.flIniFileFrom(profile)
  789. def __repr__(self):
  790. return "Profile variables"
  791. class VariableClUpdateProfileSyncSet(Variable):
  792. """
  793. Синхронизировать репозиторий перед сменой профиля
  794. """
  795. type = "bool"
  796. value = "off"
  797. opt = ["-u", "--update-cache"]
  798. def init(self):
  799. self.label = _("Update the cache")
  800. self.help = _("Update the cache")
  801. class VariableClUpdateAutocheckSet(Variable):
  802. """
  803. Выполнять/невыполнять автопроверку обновлений
  804. """
  805. type = "bool"
  806. value = "on"
  807. opt = ["-a", "--autocheck"]
  808. def init(self):
  809. self.label = _("Automatically check updates")
  810. self.help = _("automatically check updates")
  811. class VariableClUpdateAutocheckInterval(Variable):
  812. """
  813. Интервал выполнения проверки
  814. """
  815. type = "choiceedit"
  816. opt = ["-I", "--autocheck-interval"]
  817. metavalue = "INTERVAL"
  818. def init(self):
  819. self.label = _("Interval for the updates checking")
  820. self.help = _("set interval for the updates checking")
  821. def choice(self):
  822. return [["6h",_("every six hours")],
  823. ["12h",_("every twenty hours")],
  824. ["1d",_("daily")]]
  825. class VariableClUpdateAutocheckScheduleSet(Variable):
  826. """
  827. Запустить проверку только если со времени последнего запуска прошло
  828. необходимое время
  829. """
  830. type = "bool"
  831. value = "off"
  832. opt = ["--schedule"]
  833. def init(self):
  834. self.label = _("Consider the autocheck schedule")
  835. self.help = _("consider the autocheck schedule")
  836. class VariableClUpdateEmergelistSet(Variable):
  837. """
  838. Вывести список пакетов в формате emerge
  839. """
  840. type = "bool"
  841. value = "off"
  842. opt = ["-e","--emergelist"]
  843. def init(self):
  844. self.label = _("Emerge like packages list")
  845. self.help = _("display packages list in emerge format")
  846. class VariableClUpdateKernelVersion(ReadonlyVariable):
  847. """
  848. Текущая версия ядра
  849. """
  850. def get(self):
  851. return process('/bin/uname','-r').read().strip()
  852. class VariableClUpdateKernelSrcPath(ReadonlyVariable):
  853. """
  854. Каталог содержащий исходный код текущего ядра
  855. """
  856. def get(self):
  857. module_build_path = (
  858. "/lib/modules/%s/build" % self.Get('cl_update_kernel_version'))
  859. if path.exists(module_build_path):
  860. return os.readlink(module_build_path)
  861. class VariableClUpdateKernelPkg(ReadonlyVariable):
  862. """
  863. Пакет текущего ядра
  864. """
  865. def get(self):
  866. qfile = process('/usr/bin/qfile', '-vC',
  867. self.Get('cl_update_kernel_src_path'))
  868. if qfile.success():
  869. return qfile.read().partition(" ")[0]
  870. else:
  871. return ""