首页 / 资讯中心 / 文章详情

Salt progress 输出器深度解析:用 `--progress` 实时跟踪大规模 minion 返回进度

Salt progress 输出器深度解析:用 `--progress` 实时跟踪大规模 minion 返回进度 ★ FEATURED ARTICLE
运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载本篇文章围绕 Salt 的progress输出模块salt/output/progress.py展开讲解它如何将批量命令执行过程中的 minion 返回情况渲染为实时进度条涵盖依赖加载、事件数据结构、进度条初始化与更新、输出器调度层的衔接以及state_events、异步 runner 等相关配置。读完本文你将掌握salt * --progress的完整工作链路并能基于源码定位 Syndic 场景下的进度统计偏差等边界问题。模块定位把零散返回变成实时进度在管理大量 minion 时salt命令默认会等每个 minion 逐个返回结果返回顺序随机且不直观。progress输出器解决的是结果还没齐、但我想知道进度的诉求它以进度条的形式展示当前已有多少 minion 返回、总共目标多少 minion让运维人员在大规模并行执行如salt * state.apply、salt * pkg.upgrade时能直观感知任务推进情况。该模块的源码定位在 salt/output/progress.py模块 docstring 只有一句话Display return data as a progress bar。它属于 Salt 输出器outputter体系由 salt/output/init.py 统一调度。依赖与加载没有 progressbar 就静默退出progress输出器依赖第三方 Python 包progressbar模块加载时做了显式探测try: import progressbar HAS_PROGRESSBAR True except ImportError: HAS_PROGRESSBAR False随后通过__virtual__()控制是否允许该输出器被加载salt/output/progress.py L13-L14def __virtual__(): return True if HAS_PROGRESSBAR else False这意味着未安装progressbar时输出器不会出现在 loader 的结果集中。此时如果在 CLI 上强制使用进度模式会由 salt/cli/salt.py 的_progress_ret捕获异常并抛出LoaderError提示WARNING: Install the progressbar python package. Requested job was still run but output cannot be displayed.注意这里的语义任务仍然会执行只是终端无法展示进度输出。因此对生产环境而言若计划使用--progress应预先pip install progressbar或progressbar2兼容版本。触发入口-p/--progress命令行开关progress输出器由salt命令行客户端的-p/--progress开关触发。该选项定义在 salt/utils/parsers.py L2088-L2094self.add_option( -p, --progress, defaultFalse, actionstore_true, helpDisplay a progress graph. Requires progressbar python package., )典型用法salt -p * test.ping salt --progress * pkg.upgrade salt --progress -t 300 web* state.apply当开关开启后salt/cli/salt.py 的run()进入专门的分支L191-L204if self.options.progress: kwargs[progress] True self.config[progress] True ret {} for progress in cmd_func(**kwargs): out progress try: self._progress_ret(progress, out) except LoaderError as exc: raise SaltSystemExit(exc) if return_count not in progress: ret.update(progress) self._progress_end(out) self._print_returns_summary(ret)关键逻辑向本地客户端传入progressTrue要求其逐条产出进度事件输出器固定为progress即使在get_printout中也会被强制覆盖见下文每个不含return_count的返回被累积进ret最终通过_print_returns_summary打印目标 minion 数 / 已返回数 / 未返回数的汇总见 salt/cli/salt.py L464-L497结束后调用_progress_end停止进度条。数据来源cmd_cli 如何产生进度事件进度事件并不是 CLI 凭空捏造的而是由 salt/client/init.py 的cmd_cli在迭代返回时实时生成。在 L1835-L1861 可以看到计数器与进度字典的构造return_count 0 for ret in self.get_iter_returns(...): log.debug(return event: %s, ret) return_count return_count 1 if progress: for id_, min_ret in ret.items(): if not min_ret.get(failed) is True: yield { minion_count: len(minions), return_count: return_count, }每次从事件总线收到一个 minion 的返回return_count自增 1并产出一条形如{minion_count: 目标总数, return_count: 当前已返回数}的进度字典。失败的返回failed为真不计入进度。这也解释了progress输出器output()的输入结构它只关心minion_count与return_count两个键。进度条初始化progress_iterprogress_iter负责构建并启动进度条salt/output/progress.py L33-L49def progress_iter(progress): widgets [ progressbar.Percentage(), , progressbar.Bar(), , progressbar.Timer(), Returns: [, progressbar.Counter(), /{}].format(progress[minion_count]), ] bar progressbar.ProgressBar(widgetswidgets, maxvalprogress[minion_count]) bar.start() return bar它根据传入的进度字典中的minion_count目标 minion 总数设置进度条最大值maxval并按顺序组合了以下部件widget部件含义Percentage()当前完成的百分比Bar()可视化进度条本体Timer()从启动开始计时的运行耗时Counter()//总数形如Returns: [12/50]的已返回计数progress_iter会在 CLI 收到第一条进度事件时被调用一次此后进度条复用同一个实例持续更新。进度条更新outputoutput是progress输出器真正面向输出器调度层暴露的接口salt/output/progress.py L17-L30def output(ret, bar, **kwargs): if return_count in ret: val ret[return_count] # Avoid to fail if targets are behind a syndic. In this case actual return count will be # higher than targeted by MoM itself. # TODO: implement a way to get the proper target minions count and remove this workaround. # Details are in #44239. if val bar.maxval: bar.maxval val bar.update(val) return 每次收到进度事件都执行从ret中取出return_count动态扩容若实际返回数超过初始maxval则将maxval抬高到val。这是针对 Syndic 拓扑的兼容性处理——当目标 minion 位于 Syndic 之下时实际返回数可能高于 MoMMaster of Masters预设的目标数若不扩容进度条会直接越界报错。该问题在源码注释与 doc/topics/releases/2017.7.3.rstissue #44239中均有记录调用bar.update(val)刷新进度条返回空字符串表示本输出器不产生普通文本输出终端内容全部由 progressbar 库绘制。调度层get_progress / update_progress / progress_endprogress输出器与普通输出器如nested、json的用法不同它需要初始化一次、反复更新、最后停止。这一生命周期由 salt/output/init.py 的三个辅助函数管理初始化L53-L59def get_progress(opts, out, progress): return salt.loader.raw_mod(opts, out, rawmodule, modoutput) f{out}.progress_iter通过 loader 的raw_mod机制加载{out}.progress_iter即progress.progress_iter并立即调用返回已启动的进度条对象。更新L62-L72def update_progress(opts, progress, progress_iter, out): try: progress_outputter salt.loader.outputters(opts)[out] except KeyError: # Outputter is not loaded log.warning(Progress outputter not available.) return False progress_outputter(progress, progress_iter)加载输出器模块并调用其output(ret, bar)。若输出器未加载例如缺少progressbar导致__virtual__返回 False则记录 warning 并返回 False。收尾L75-L80def progress_end(progress_iter): try: progress_iter.stop() except Exception: # pylint: disablebroad-except pass return None安全停止进度条异常一律吞掉避免收尾阶段的错误影响最终汇总输出。此外salt/output/init.py 的get_printout中还有一处强制覆盖逻辑L157-L158if opts.get(progress, False): out progress即只要--progress被启用无论用户是否同时指定了其他--out输出器都会优先切到progress保证进度模式与输出模式的互斥关系清晰。对应到 CLI 侧salt/cli/salt.py 的_progress_retL521-L536负责懒加载进度条只有收到第一条进度事件时才调用get_progress初始化避免空跑时白开一个进度条而_progress_endL516-L519则在全部返回收齐后调用progress_end停止进度条。关联配置与使用边界master 端state_eventsprogress输出器消费的是cmd_cli事件流中的返回事件而针对 state 运行master 还提供state_events配置来控制是否逐个函数地发送进度事件。该配置定义在 doc/ref/configuration/master.rststate_events条目默认值False作用设为True后state 运行中每个函数执行完成都会发送进度事件事件格式为salt/job/JID/prog/MID/RUN NUM。配置示例state_events: True从源码结构看state_events产生的是 master 事件总线上面向 state 执行细节的prog事件与--progress输出器消费的return_count进度字典分属两条路径但两者组合使用可以在大规模state.apply时同时获得函数级进度事件与minion 级返回进度条。异步 runner 的进度限制--progress与 runner 的异步模式存在边界限制。doc/ref/runners/index.rst 明确指出以异步方式运行 runner 时--progress标志不会在salt-runCLI 上产出输出但进度事件仍会照常发布到事件总线salt/run/JID/progress等可通过事件监听手段另行消费。关于输出叠加进度模式结束后CLI 会打印一次汇总行# of minions targeted/# of minions returned/# of minions that did not return见 salt/cli/salt.py L492-L496并在所有 minion 均以非零退出码返回时报错退出salt.defaults.exitcodes.EX_GENERIC可继续与脚本的退出码判断配合使用。实践小结与故障排查一个典型的大规模升级场景可以这样使用# 预装依赖 pip install progressbar # 带进度条执行批量操作 salt --progress -t 600 * pkg.upgrade可能遇到的典型问题与排查路径现象原因与排查报错提示安装progressbar__virtual__检测失败输出器未加载安装依赖后重试进度条停在某个值不再增长剩余 minion 未返回等待-t超时阈值超时后输出no_return汇总进度条计数超过目标总数目标 minion 经 Syndic 路由时返回数可能高于预设output()通过动态扩容maxval规避issue #44239 的 workaroundsalt-run异步模式无进度输出符合预期进度事件仅发往事件总线不进入 CLI 终端总体而言progress输出器是 Salt 输出体系中最轻的一个模块——它不产生任何结构化结果文本只负责把cmd_cli产生的return_count流渲染成终端进度条而其真实价值在于与-p/--progress、cmd_cli事件生成、loader 动态加载以及 Syndic 兼容处理共同构成一条完整的大规模执行可观测性链路。深入阅读 salt/output/progress.py 与 salt/output/init.py 的源码即可完全掌握这条链路的每一环。赞分享运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载相关推荐终极进度监控神器使用progress实时跟踪tar/gzip压缩解压进度想要实时监控Linux系统中tar、gzip等压缩解压命令的进度吗progress工具就是你的最佳选择这个轻量级的进度监控神器能够显示文件操作的完成百分比、开发工具CANN/ops-nn矩阵乘法算子aclnnAddmmWeightNz 产品支持情况 | 产品 | 是否支持 | | : | : : | | term Ascend 950PR/Ascend人工智能算子库深度学习CANNAscend异步进度跟踪Async Progress Tracking与 Continuous Processing 性能优化实战指南异步进度跟踪Async Progress Tracking与 Continuous Processing 性能优化实战指南 导读 本篇指南围绕 Spark大数据数据分析批处理流处理机器学习图计算上一篇ESP-Mail-Client 库完全指南在 ESP32/ESP8266 与 Tasmota 中收发邮件SMTP 与 IMAP 全 API 解析下一篇MongoDB mongobridge 网络故障注入框架实战指南在副本集与分片集群测试中模拟网络分区、延迟与丢包创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站