def get_summary_str(self): """Return the poll context as a summary string delimited by "|".""" ret = OrderedDict() for key in self.CONTEXT_ATTRIBUTES: value = getattr(self, key) if key == 'job_log_dir' or value is None: continue ret[key] = value return '%s|%s' % (self.job_log_dir, json.dumps(ret))
def upgrade(self): warnings = OrderedDict() for vn, upgs in self.upgrades.items(): for u in upgs: try: exp = self.expand(u) except (KeyError, UpgradeError): continue for upg in exp: try: old = self.get_item(upg['old']) except KeyError: # OK: deprecated item not found pass else: msg = self.show_keys(upg['old']) if upg['new']: msg += ' -> ' + self.show_keys(upg['new']) else: upg['new'] = upg['old'] msg += " - " + upg['cvt'].describe() if not upg['silent']: warnings.setdefault(vn, []) warnings[vn].append(msg) self.del_item(upg['old']) if upg['cvt'].describe() != "DELETED (OBSOLETE)": # check self.cfg does not already contain a # non-deprecated item matching upg['new']: try: self.get_item(upg['new']) except KeyError: self.put_item(upg['new'], upg['cvt'].convert(old)) else: raise UpgradeError( 'ERROR: Cannot upgrade deprecated ' f'item "{msg}" because the upgraded ' 'item already exists' ) if warnings: level = WARNING if self.descr == self.SITE_CONFIG: # Site level configuration, user cannot easily fix. # Only log at debug level. level = DEBUG else: # User level configuration, user should be able to fix. # Log at warning level. level = WARNING LOG.log(level, 'deprecated items were automatically upgraded in ' f'"{self.descr}"') for vn, msgs in warnings.items(): for msg in msgs: LOG.log(level, ' * (%s) %s', vn, msg)
def test_expand_obsolete(self): upg = { 'new': None, 'cvt': None, 'silent': True, 'old': ['section', '__MANY__', 'a'] } self.cfg['__MANY__'] = OrderedDict() self.cfg['__MANY__']['name'] = 'Arthur' self.u.obsolete('entry', ['section', '__MANY__']) self.u.upgrade() expanded = self.u.expand(upg) self.assertEqual(1, len(expanded)) self.assertTrue(expanded[0]['new'] is None)
def setUp(self): self.cfg = OrderedDict() self.cfg['section'] = OrderedDict() self.cfg['section']['a'] = '1' self.cfg['section']['b'] = '2' self.u = upgrader(self.cfg, "1.0 to 2.0")
def __init__(self, cfg, descr): """Store the config dict to be upgraded if necessary.""" self.cfg = cfg self.descr = descr # upgrades must be ordered in case several act on the same item self.upgrades = OrderedDict()
# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ An empty config file should successfully yield an empty sparse config dict. """ import os import sys from cylc.flow.parsec.config import ParsecConfig from cylc.flow.parsec.validate import ParsecValidator as VDR from cylc.flow.parsec.OrderedDict import OrderedDict fpath = os.path.dirname(os.path.abspath(__file__)) # parsec sys.path.append(fpath + '/../../..') SPEC = {'meta': {'title': [VDR.V_STRING]}} cfg = ParsecConfig(SPEC) cfg.loadcfg("empty.rc") if cfg.get(sparse=True) != OrderedDict(): sys.exit(1)
def run(self, options, *args): suite = args[0] if len(args) > 1: try: user_at_host, options.port = args[1].split(":") options.owner, options.host = user_at_host.split("@") except ValueError: print( ("USER_AT_HOST must take the form " '"user@host:port"'), file=sys.stderr, ) sys.exit(1) client_name = os.path.basename(sys.argv[0]) if options.restricted: client_name += " -r" legend = "" for state in TASK_STATUSES_ORDERED: legend += get_status_prop(state, "ascii_ctrl") legend += f"{HELD_SYMBOL}" legend = legend.rstrip() len_header = sum(len(s) for s in TASK_STATUSES_ORDERED) self.reset( suite, options.owner, options.host, options.port, options.comms_timeout, ) is_cont = False while True: if is_cont: if options.once: break else: sleep(float(options.update_interval)) is_cont = True try: glbl, task_summaries = self.pclient("get_suite_state_summary")[ 0:2 ] except ClientError as exc: print("\033[1;37;41mERROR\033[0m", str(exc), file=sys.stderr) self.reset( suite, options.owner, options.host, options.port, options.comms_timeout, ) else: if not glbl: print( ("\033[1;37;41mWARNING\033[0m suite initialising"), file=sys.stderr, ) continue states = [ t["state"] for t in task_summaries.values() if ("state" in t) ] n_tasks_total = len(states) if options.restricted: task_summaries = dict( (i, j) for i, j in task_summaries.items() if (j["state"] in TASK_STATUSES_RESTRICTED) ) if not options.display_runahead: task_summaries = dict( (i, j) for i, j in task_summaries.items() if (j["state"] != TASK_STATUS_RUNAHEAD) ) try: updated_at = get_time_string_from_unix_time( glbl["last_updated"] ) except KeyError: updated_at = time() except (TypeError, ValueError): # Older suite. updated_at = glbl["last_updated"].isoformat() run_mode = glbl["run_mode"] ns_defn_order = glbl["namespace definition order"] status_string = glbl["status_string"] task_info = {} name_list = set() task_ids = list(task_summaries) for task_id in task_ids: name = task_summaries[task_id]["name"] point_string = task_summaries[task_id]["label"] state = task_summaries[task_id]["state"] is_held = task_summaries[task_id]["is_held"] name_list.add(name) if is_held: text = f"{HELD_SYMBOL}{name}" else: text = name if point_string not in task_info: task_info[point_string] = {} task_info[point_string][name] = get_status_prop( state, "ascii_ctrl", subst=text ) # Sort the tasks in each cycle point. if options.sort_order == "alphanumeric": sorted_name_list = sorted(name_list) else: sorted_name_list = ns_defn_order sorted_task_info = {} for point_str, info in task_info.items(): sorted_task_info[point_str] = OrderedDict() for name in sorted_name_list: if name in name_list: # (Defn order includes family names.). sorted_task_info[point_str][name] = info.get(name) # Construct lines to blit to the screen. blit = [] suite_name = suite if run_mode != "live": suite_name += " (%s)" % run_mode prefix = "%s - %d tasks" % (suite_name, int(n_tasks_total)) suffix = "%s" % client_name title_str = " " * len_header title_str = prefix + title_str[len(prefix):] title_str = "\033[1;37;44m%s%s\033[0m" % ( title_str[: -len(suffix)], suffix, ) blit.append(title_str) blit.append(legend) updated_str = "updated: \033[1;38m%s\033[0m" % updated_at blit.append(updated_str) summary = "state summary:" state_totals = glbl["state totals"] for state, tot in state_totals.items(): subst = " %d " % tot summary += get_status_prop(state, "ascii_ctrl", subst) blit.append(summary) # Print a divider line containing the suite status string. try: status1, status2 = ( SUITE_STATUS_SPLIT_REC.match(status_string) ).groups() except AttributeError: status1 = status_string status2 = "" suffix = "_".join(list(status1.replace(" ", "_"))) + status2 divider_str = "_" * len_header divider_str = "\033[1;31m%s%s\033[0m" % ( divider_str[: -len(suffix)], suffix, ) blit.append(divider_str) blitlines = {} for point_str, val in sorted_task_info.items(): indx = point_str line = "\033[1;34m%s\033[0m" % point_str for name, info in val.items(): if info is not None: line += " %s" % info elif options.align_columns: line += " %s" % (" " * len(name)) blitlines[indx] = line if not options.once: os.system("clear") print("\n".join(blit)) indxs = list(blitlines) try: int(indxs[1]) except (ValueError, IndexError): indxs.sort() else: indxs.sort(key=int) for ix in indxs: print(blitlines[ix])