如何让Vagrant自定义认证插件在box镜像下载前触发执行
解决方案
你遇到的问题主要是钩子挂载时机错误、动作类定义缺失必要方法、依赖引入不全三个原因导致的,按照以下步骤修改即可:
1. 修正钩子挂载逻辑
你现在遍历了大量无关的动作挂载钩子,且挂载位置在ConfigValidate之后,早于Box下载动作触发的时机,应该直接把钩子插在Vagrant内置的Box添加动作之前,确保认证逻辑在下载前执行。
修改plugin.rb的钩子部分代码:
# 删除原来的批量action挂载逻辑,替换为以下代码 # 仅针对会触发box下载的两个核心动作挂载钩子 [:machine_action_up, :machine_action_box_add].each do |action| action_hook(:authenticate_provision, action) do |hook| # 直接在内置Box添加动作之前插入你的认证流程 hook.before(Vagrant::Action::Builtin::BoxAdd, Action::Base.setup) end end # 同时在plugin.rb头部引入action相关依赖,否则无法识别Action类 require_relative "action/base" require_relative "action/authenticate"
2. 补全Authenticate动作类的必要定义
Vagrant的自定义动作类必须实现初始化方法接收动作链上下文,且执行完自定义逻辑后必须调用@app.call将流程传递给后续动作,你当前的类缺少这部分逻辑导致执行中断。
修改authenticate.rb代码:
module VagrantPlugins module Authenticate module Action class Authenticate < Base # 新增初始化方法,保存动作链上下文和日志实例 def initialize(app, env) @app = app @logger = Log4r::Logger.new("vagrant::authenticate") end def call(env) puts env[:machine].config.authenticate.to_hash[:enabled] # 开关判断,未开启则直接走后续流程 unless env[:machine].config.authenticate.to_hash[:enabled] @logger.info "Authenticate disabled, skipping" return @app.call(env) end # 检查本地是否已存在目标box target_box = env[:machine].config.vm.box target_provider = env[:machine].provider_name target_version = env[:machine].config.vm.box_version || ">= 0" local_box_exists = env[:box_collection].find(target_box, target_provider, target_version) # 本地不存在box时才执行Artifactory认证逻辑 if !local_box_exists @logger.info "Target box not found locally, starting Artifactory authentication" # 此处添加你的认证逻辑,拿到令牌后可以直接修改env[:machine].config.vm.box_url,将凭证拼入地址 # 示例:env[:machine].config.vm.box_url = "https://#{auth_token}@#{original_box_url}" end # 必须调用该方法将动作传递给后续的Box下载流程 @app.call(env) end end end end end
3. 可选优化
如果你需要适配box_check_update开启的场景,还可以在Vagrant::Action::Builtin::BoxCheckOutdated动作之前也插入你的认证钩子,避免更新检查时因无权限报错。
内容的提问来源于stack exchange,提问作者AlperenK
相关产品推荐
相关产品推荐

