diff --git a/pym/update/update.py b/pym/update/update.py index 207b3e0..5e24a45 100644 --- a/pym/update/update.py +++ b/pym/update/update.py @@ -29,6 +29,8 @@ from calculate.lib.datavars import DataVarsError, VariableError, Variable from calculate.lib.utils.tools import AddonError from calculate.lib.utils.colortext.palette import TextState from calculate.lib.utils.colortext import get_color_print + +from calculate.core.server.core_interfaces import RerunTrigger from .emerge_parser import RevdepPercentBlock from .datavars import DataVarsUpdate from .update_info import UpdateInfo @@ -1501,9 +1503,9 @@ class Update(MethodsInterface): class Reason(): Success = 0 - BadSign = 1 - Outdated = 2 - LevelWrong = 3 + LevelWrong = 1 + BadSign = 2 + Outdated = 3 Skip = 4 Updating = 5 WrongBinhost = 6 @@ -1525,7 +1527,6 @@ class Update(MethodsInterface): Update.Reason.Skip: "SKIP", Update.Reason.SkipSlower: "", Update.Reason.Success: "", - #TODO formulate better Update.Reason.LevelWrong: "FAILED (binhost level is low)" }.get(reason,reason) @@ -1614,7 +1615,6 @@ class Update(MethodsInterface): reason=Update.Reason.humanReadable(reason))) if not retval: if actual_reason is self.Reason.LevelWrong: - #TODO translate raise UpdateError(_("Failed to find trusted server with current level")) elif actual_reason is self.Reason.BadSign: raise UpdateError(_("Failed to find the reliable server with appropriate updates")) @@ -1638,16 +1638,23 @@ class Update(MethodsInterface): return None return level - int(self.clVars.Get("update.cl_update_level")) - def check_if_no_branch_is_set(self): + def is_branch_set(self): #basically, if any of the branches are specified, we won't use migration return any(x != "tag" for x in self.clVars.Get("cl_update_branch_name")) - def turn_off_migration_if_needed(self): - check = self.check_if_no_branch_is_set() - if check: - self.clVars.Set("cl_check_update_level", Variable.Off) - return True + def is_level_forced(self): + flvl = self.clVars.Get("cl_update_force_level") + return flvl.isdigit() and int(flvl) > 0 + def perform_migration_system_pre_check(self): + branch_is_set_check = self.is_branch_set() + if branch_is_set_check: + self.clVars.Set("cl_update_ignore_level", Variable.On) + else: + if self.is_level_forced(): + self.clVars.Set("cl_update_level", int(self.clVars.Get("cl_update_force_level")) - 1) + self.set_migration_mode(True) + return True def check_current_binhost(self, binhost_url): """ @@ -1656,8 +1663,8 @@ class Update(MethodsInterface): if not binhost_url in self.binhosts_data.binhost_list: raise UpdateError(_("Current binhost is absent in list of update servers")) binhost = self.binhosts_data.get_binhost(binhost_url) - ignore_level = self.clVars.Get("cl_check_update_level") == Variable.Off - cur_level_valid = self.check_current_level() if not ignore_level else None + ignore_level = self.clVars.Get("cl_update_ignore_level") == Variable.On + cur_level_valid = self.is_current_level_a_digit() if not ignore_level else None if binhost.valid and not binhost.outdated and not binhost.downgraded \ and (ignore_level or not cur_level_valid or self.is_binhost_level_valid(binhost)): if binhost.status == self.binhosts_data.BinhostStatus.Success: @@ -1667,7 +1674,7 @@ class Update(MethodsInterface): str(binhost.duration), str(binhost.level)]], force=True) - if not ignore_level and not cur_level_valid: + if not ignore_level and not cur_level_valid and not self.is_level_forced(): self.pull_level_from_binhost(binhost) self.endTask() else: @@ -1685,7 +1692,6 @@ class Update(MethodsInterface): # self.stash_binhost(binhost_url) if self.compare_update_level(binhost.level) > 0: self.set_migration_mode(True) - #TODO translate raise UpdateError(( _("Current binhost {} has wrong update level. Current level: {} Binhost level: {}").\ format(binhost_url, self.clVars.Get("update.cl_update_level"), binhost.level))) @@ -1720,7 +1726,7 @@ class Update(MethodsInterface): return f"{host}level{level_required}" @variable_module("update") - def detect_best_binhost(self, cl_check_update_level): + def detect_best_binhost(self, ignore_level): # выполняется переход с серверов unstable обновлении на stable # в этом случае не важно, что бинари могут старее текущих if (self.clVars.GetBool('cl_update_binhost_stable_opt_set') and @@ -1729,17 +1735,17 @@ class Update(MethodsInterface): else: stabilization = False #had to extract ignore level logic to cl_update because of variable module - ignore_level = not cl_check_update_level - # ignore_level = self.clVars.Get('cl_check_update_level') == Variable.Off - current_level_is_valid = self.check_current_level() if not ignore_level else False + current_level_is_valid = self.is_current_level_a_digit() if not ignore_level else False self.startTask(_("Searching new binhost")) + + #add try catch + retval = self._search_best_binhost(self.binhosts_data, stabilization, ignore_level or not current_level_is_valid) self.clVars.Set('update.cl_update_binhost_data', retval or Variable.EmptyTable, force=True) - if not ignore_level: best_binhost_level = int(self.clVars.Get("update.cl_update_binhost_level")[0]) #int(sorted(self.clVars.Get("update.cl_update_binhost_level"), key=int)[-1]) @@ -1751,21 +1757,18 @@ class Update(MethodsInterface): cmpr = self.compare_update_level(best_binhost_level) if cmpr > 0: self.set_migration_mode(True) - #TODO reformulate, add translation raise UpdateError(_("Current level: {} Binhost level: {}").\ format(self.clVars.Get("update.cl_update_level"), best_binhost_level)) if cmpr < 0: - # self.clVars.Delete('update.cl_update_binhost_host', location="system") - #self.clVars.Get("update.cl_update_binhost_host") self.delete_binhost() - # raise UpdateError(_("Failed to find binhost with level equal or higher than local level")) - return False + raise UpdateError(_("Failed to find binhost with level equal or higher than local level")) self.endTask() return True #нужен так как detect_best_binhost не essential, ошибка не останавливает def interrupt_on_no_leveled_binhost(self): - raise UpdateError(_("Failed to find binhost with level equal to or higher than local level")) + # raise UpdateError(_("Failed to find binhost with level equal to or higher than local level")) + return False def set_migration_mode(self, val=True): val_to_write = Variable.On if val else Variable.Off @@ -1774,8 +1777,19 @@ class Update(MethodsInterface): return True + def cmp_rep_tag_to_current_calc_rep_tag(self): + #TODO value to Var + repname = 'calculate' + git = self.getGit() + rpath, revision = ( + self.clVars.Select(["cl_update_rep_path", + "cl_update_rep_rev"], + where="cl_update_rep_name", + eq=repname, limit=1)) + #try ValueError? + return int(revision) - int(git.getCurrentTag(rpath)) + def set_migration_host(self): - #TODO translate self.startTask(_("Setting up migration host")) dv = self.clVars last_ts = dv.Get('cl_update_last_timestamp') @@ -1799,8 +1813,14 @@ class Update(MethodsInterface): self.clVars.Set('update.cl_update_binhost_data', migr_binhost_data or Variable.EmptyTable, force=True) if not (migr_binhost_data): - #TODO translate raise UpdateError(_("Failed to find working migration host with current level")) + if not self.is_level_forced(): + tag_cmp = self.cmp_rep_tag_to_current_calc_rep_tag() + if tag_cmp <= 0: + self._update_increment_current_level() + self.set_migration_mode(False) + self.delete_binhost() + raise RerunTrigger(_("Raising level due to migration host being outdated")) self.endTask() return True @@ -1903,7 +1923,6 @@ class Update(MethodsInterface): return True def update_increment_current_level(self): - #TODO add translation self.startTask(_("Using higher update level")) self._update_increment_current_level() self.set_migration_mode(False) @@ -1917,9 +1936,9 @@ class Update(MethodsInterface): self.clVars.Write('cl_update_level', str(current_level + 1), location="system") - def check_current_level(self): + def is_current_level_a_digit(self): """ - Возвращает True если есть значение в calculate.env + Возвращает True если значение update_level это цифра >=0 """ # isdigit - True if it can be interp-ed as a number >=0 return self.clVars.Get('cl_update_level').isdigit() @@ -1929,12 +1948,9 @@ class Update(MethodsInterface): return True def _set_update_level(self, level): - if level: - self.clVars.Write('cl_update_level', + level = level if level else 0 + self.clVars.Write('cl_update_level', str(level), location="system") - else: - self.clVars.Write('cl_update_level', - str(0), location="system") # def stash_binhost(self, binhost_url): # """ diff --git a/pym/update/utils/cl_update.py b/pym/update/utils/cl_update.py index 35b1681..4372c57 100644 --- a/pym/update/utils/cl_update.py +++ b/pym/update/utils/cl_update.py @@ -48,9 +48,9 @@ def get_synchronization_tasks(object_name): 'method': Object('create_binhost_data()') }, { - 'name': 'check_if_update_by_branch', - 'method': Object('turn_off_migration_if_needed()'), - 'condition': lambda Get, GetBool: (Get('cl_check_update_level') == 'on') + 'name': 'perform_migration_system_pre_check', + 'method': Object('perform_migration_system_pre_check()'), + 'condition': lambda Get, GetBool: (Get('cl_update_ignore_level') == 'off') }, # проверить валиден ли текущий хост {'name': 'check_current_binhost', @@ -60,7 +60,8 @@ def get_synchronization_tasks(object_name): 'condition': lambda GetBool, Get: ( not GetBool('update.cl_update_binhost_recheck_set') and Get('update.cl_update_sync_rep') and - Get('update.cl_update_binhost')) + Get('update.cl_update_binhost') and + Get('update.cl_update_use_migration_host') == 'off') }, {'name': 'not_use_search:failed_base_binhost', 'error': __("Failed to use base binhost"), @@ -78,7 +79,7 @@ def get_synchronization_tasks(object_name): 'tasks': [ # найти лучший сервер обновлений {'name': 'detect_best_binhost', - 'method': Object(f'detect_best_binhost({object_name.lower()}.cl_check_update_level)'), + 'method': Object(f'detect_best_binhost({object_name.lower()}.cl_update_ignore_level)'), 'essential': False, 'depend': (Tasks.success() & ~AllTasks.has_any("not_use_search") & (~AllTasks.success_one_of("check_current_binhost") | diff --git a/pym/update/variables/update.py b/pym/update/variables/update.py index 40aea50..2e8a208 100644 --- a/pym/update/variables/update.py +++ b/pym/update/variables/update.py @@ -1888,10 +1888,35 @@ class VariableClBinhostStash(Variable): """ value = "" -class VariableClCheckUpdateLevel(Variable): +class VariableClUpdateIgnoreLevel(Variable): """ Проверять уровень обновления при соединении с binhost """ type = "bool" - value = "on" \ No newline at end of file + opt = ["--ignore-level"] + value = "off" + + def init(self): + self.label = _("Forcefully ignore update level and migration system") + self.help = _("forcefully ignore update level and migration system") + +class VariableClUpdateForceLevel(Variable): + """ + Принудительное обновление до определенного уровня + """ + type = "int" + opt = ["--force-level"] + metavalue = "LEVEL" + + + def init(self): + self.label = _("Force update to particular level") + self.help = _("force update to particular level") + +class VariableClUpdateForceLevelMode(Variable): + """ + Режим принудительного обновления до определенного уровня + """ + type = "bool" + value = "off" diff --git a/pym/update/wsdl_update.py b/pym/update/wsdl_update.py index 6a91e2a..7d61579 100644 --- a/pym/update/wsdl_update.py +++ b/pym/update/wsdl_update.py @@ -71,25 +71,27 @@ class Wsdl(WsdlBase): 'cl_update_with_bdeps_opt_set' ), expert=( - 'cl_update_sync_only_set', - 'cl_update_other_set', - 'cl_update_pretend_set', - 'cl_update_sync_rep', - 'cl_update_emergelist_set', - 'cl_update_check_rep_set', - 'cl_update_force_fix_set', - 'cl_update_world', - 'cl_update_gpg_force', - 'cl_update_egencache_force', - 'cl_update_eixupdate_force', - 'cl_update_revdep_rebuild_set', - 'cl_update_wait_another_set', - 'cl_update_autocheck_schedule_set', - 'cl_update_onedepth_set', - 'cl_update_cleanpkg_set', - 'cl_update_branch_data', - 'cl_templates_locate', - 'cl_verbose_set', 'cl_dispatch_conf'), + 'cl_update_sync_only_set', + 'cl_update_other_set', + 'cl_update_pretend_set', + 'cl_update_sync_rep', + 'cl_update_emergelist_set', + 'cl_update_check_rep_set', + 'cl_update_force_fix_set', + 'cl_update_ignore_level', + 'cl_update_force_level', + 'cl_update_world', + 'cl_update_gpg_force', + 'cl_update_egencache_force', + 'cl_update_eixupdate_force', + 'cl_update_revdep_rebuild_set', + 'cl_update_wait_another_set', + 'cl_update_autocheck_schedule_set', + 'cl_update_onedepth_set', + 'cl_update_cleanpkg_set', + 'cl_update_branch_data', + 'cl_templates_locate', + 'cl_verbose_set', 'cl_dispatch_conf'), next_label=_("Run"))]}, # # Сменить профиль