简体   繁体   English

在厨师运行期间如何重新加载环境变量?

[英]How to reload environment variables during a chef run?

I am automating some provisioning on windows using chef-solo. 我正在使用Chef-solo在Windows上自动进行一些配置。 I have an issue with a recipe that needs an environment setup indirectly by a previous recipe (concretely, I am installing visual studio in recipe 1, and recipe 2 needs to start in a new environment to access the variables set up by recipe1). 我遇到一个配方问题,该配方需要以前的配方间接设置环境(具体而言,我在配方1中安装了Visual Studio,配方2需要在新的环境中启动才能访问配方1设置的变量)。

As far as I know, there is no way to tell chef to 'reload an environment' ? 据我所知,有没有办法告诉厨师“重新加载环境”? What would be the best way to achieve this ? 实现此目标的最佳方法是什么? At worse, if that makes it easier, I don't mind rebooting either, as long as the reboot and chef continuning the provisioning is entirely automated. 更糟糕的是,如果这样做更容易,那么我也不介意重新启动,只要重新启动和继续进行配置的厨师是完全自动化的即可。

You could possibly run a ruby block and add the new environment variables to the current environment variables: 您可以运行ruby块并将新的环境变量添加到当前的环境变量中:

ruby_block "get new env variables" do
  block do
    new_env = `cmd.exe /C set`
    #do some parsing magic, then set the new_env
    ENV = parsed_env
  end
 end

I haven't tested this, but it may get you on the right track. 我尚未对此进行测试,但这可能会让您步入正轨。

Chocolatey uses Refreshenv script for the very same task, reloading environment variables from Registry. Chocolatey将Refreshenv脚本用于同一任务,从Registry中重新加载环境变量。

I've ported this script to Ruby (licensed under Apache 2.0 license): 我已将此脚本移植到Ruby(获得Apache 2.0许可的许可):

require 'win32/registry'

def get_reg_env(hkey, subkey, &block)
  Win32::Registry.open(hkey, subkey) do |reg|
    reg.each_value do |name|
      value = reg.read_s_expand(name)
      if block && ENV.key?(name)
        ENV[name] = block.call(name, ENV[name], value)
      else
        ENV[name] = value
      end
    end
  end
end

def refresh_env
  get_reg_env(Win32::Registry::HKEY_LOCAL_MACHINE, 'System\CurrentControlSet\Control\Session Manager\Environment')
  get_reg_env(Win32::Registry::HKEY_CURRENT_USER, 'Environment') do |name, old_value, new_value|
    if name.upcase == 'PATH'
      old_value || File::PATH_SEPARATOR || new_value
    else
      new_value
    end
  end
end

You put it in libraries dir and use it in a recipe like this: 您将其放在libraries目录中,并在如下配方中使用它:

ruby_block 'refreshenv' do
  block do
    refresh_env
  end
  action :nothing
end

chocolatey_package 'visualstudio2017buildtools' do
  notifies :run, 'ruby_block[refreshenv]', :immediately
end

Maybe somebody could wrap it in a cookbook. 也许有人可以将其包装在食谱中。

For more cross-platform way you could also take a look at dotenv gem . 对于更多的跨平台方式,您还可以查看dotenv gem

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM