【问题标题】:Vagrant - how to have host platform specific provisioning stepsVagrant - 如何拥有特定于主机平台的配置步骤
【发布时间】:2015-01-04 19:49:22
【问题描述】:

我们拥有一支多元化的开发团队,一个在 Windows 上,另一个在 Ubuntu 上,另一个在 OSX 上。作为 Windows 男孩,我设置了 vagrant 设置脚本的第一个版本,它运行得非常好;)

但是,在 Ubuntu 主机上运行它时,它第一次进入调用 bash 脚本的配置步骤时,由于权限问题而失败。

在 Windows 上,这无关紧要,因为 samba 共享自动具有足够的权限来运行 bash 脚本(它位于项目层次结构中,因此存在于 VM 上的 /vagrant 共享中),但使用 ubuntu 我需要在我调用它之前在配置脚本中设置这个文件的权限。

这不是问题,老实说,我怀疑即使使用额外的“chmod”步骤,它在 Windows 下仍然可以正常工作,但是,在 vagrant 文件中是否有办法将某些配置步骤标记为“仅限 Windows” '、“仅限 Linux”还是“仅限 Mac”?

即在伪代码中,类似。

.
.
if (host == windows) then
  config.vm.provision : shell, : inline => "/vagrant/provisioning/only_run_this_on_windows.sh"
else if (host == linux) then
  config.vm.provision : shell, : inline => "/vagrant/provisioning/only_run_this_on_linux.sh"
else if (host == osx) then
  config.vm.provision : shell, : inline => "/vagrant/provisioning/only_run_this_on_osx.sh"
end if
.
.

提前致谢。

【问题讨论】:

  • 某人只是不高兴(可能他的问题/答案被否决了)并进入了“投反对票狂欢”——这是我最近的 3 个答案之一。

标签: ruby vagrant


【解决方案1】:

请注意,the Vagrant::Util::Platform class 中的 Vagrant 本身已经在 the answer 中由BernardoSilva 实现了更高级版本的平台检查逻辑。

所以在 Vagrantfile 中,您可以简单地使用以下内容:

if Vagrant::Util::Platform.windows? then
    myHomeDir = ENV["USERPROFILE"]
else
    myHomeDir = "~"
end

【讨论】:

  • 这更像是“如果平台是windows,请在此处应用monkeypatch”。喜欢它。
  • 注意你也可以使用Vagrant::Util::Platform::mac?,我认为then不应该在那里。
  • then is optional in Ruby,这是编写 Vagrantfile 的语言。
  • 检查你的机器是不是Mac,code其实是Vagrant::Util::Platform::darwin?
【解决方案2】:

找出 Vagrantfile 中的当前操作系统。

将此添加到您的 Vagrantfile 中:

module OS
    def OS.windows?
        (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
    end

    def OS.mac?
        (/darwin/ =~ RUBY_PLATFORM) != nil
    end

    def OS.unix?
        !OS.windows?
    end

    def OS.linux?
        OS.unix? and not OS.mac?
    end
end

那么你就可以随意使用了。

if OS.windows? [then]
    code...
end

编辑:缺少 ?在 if 条件下。

用于测试的示例:

is_windows_host = "#{OS.windows?}"
puts "is_windows_host: #{OS.windows?}"
if OS.windows?
    puts "Vagrant launched from windows."
elsif OS.mac?
    puts "Vagrant launched from mac."
elsif OS.unix?
    puts "Vagrant launched from unix."
elsif OS.linux?
    puts "Vagrant launched from linux."
else
    puts "Vagrant launched from unknown platform."
end

执行:

# Ran provision to call Vagrantfile.
$ vagrant provision
is_windows_host: false
Vagrant launched from mac.

【讨论】:

  • 感谢您的回复,但我现在遇到了一个错误,我的 Ruby 技能一点也不好 :( "Vagrantfile:145:in block in <top (required)>': undefined method unix' for OS:Module (NoMethodError )" Vagrant File: VAGRANTFILE_API_VERSION = "2" 我把模块代码放在 'VAGRANTFILE_API_VERSION = "2"' 的正下方,然后在文件底部的 'end' 之前放置 if。如果 OS.unix config.vm.provision :shell, :inline => "sudo chmod 755 /vagrant/provision/*.sh"; 结束(对不起裤子格式...)
  • 我修复了它,我从给定的代码中删除了“?”,它工作正常。 :) 如果你能修改你的答案,我会接受。
  • 这是我能找到的最有用的 vagrant 条件/平台/环境教程!
  • 把 linux 检查放在 unix 之前,否则 linux 永远不会被视为这样。
【解决方案3】:

这是一个使用 Vagrant 工具来检查 mac 和 windows 的版本:

    if Vagrant::Util::Platform.windows?
        # is windows
    elsif Vagrant::Util::Platform.darwin?
        # is mac
    else
        # is linux or some other OS
    end

【讨论】:

  • 不知道为什么不这样做,但这对我来说在 mac 上失败了,Vagrant::Util::Platform.mac?Vagrant::Util::Platform::darwin? 都失败了。贝尔纳多席尔瓦的回答效果很好。
  • 上面有错字。将elseif 替换为elsif,一切正常
【解决方案4】:

根据我的说法,当我阅读原始问题时,不是如何找出它在哪个操作系统上自行运行,而是要配置的虚拟机具有哪个操作系统。这就是为什么您要根据新 VM 的不同操作系统运行不同的配置脚本的原因,例如:“/vagrant/provisioning/only_run_this_on_${OS_OF_NEW_VM}.sh”。

不幸的是,Vagrant 还没有这个功能,所以这是我的解决方案:我在我的 vagrant 文件之上定义我的虚拟机:

   cluster = {
  "control.ansible.RHEL76" => { :ip => "192.168.1.31", :type => 0, :cpus => 1, :mem => 1024, :box_image => "centos/7" },
  "app01.ansible.RHEL76"   => { :ip => "192.168.1.32", :type => 1, :cpus => 1, :mem => 1024, :box_image => "centos/7" },
  "app02.ansible.RHEL76"   => { :ip => "192.168.1.33", :type => 1, :cpus => 1, :mem => 1024, :box_image => "centos/7" },
  "winserver"          => { :ip => "192.168.1.34", :type => 2, :cpus => 1, :mem => 1024, :box_image => "mwrock/Windows2016" },
}

然后我的代码中的这些条件可以根据 VM 的操作系统提供不同的方式:

if "#{info[:box_image]}" == "mwrock/Windows2016" then
  puts "is_windows_host: #{info[:box_image]}"
  config.vm.provision : shell, inline => "/vagrant/provisioning/only_run_this_on_windows.psl"
end
if "#{info[:box_image]}" == "centos/7" then
  puts "is_linux_host: #{info[:box_image]}"
  config.vm.provision : shell, inline => "/vagrant/provisioning/only_run_this_on_linux.sh"
end

顺便说一句,只有 ansible 控制器应该安装 ansible,因为在现实生活中(是的办公室)我不使用 vagrant 而是一个 ansible 控制器,我也想要在我的实验室中(在我的两个 Windows 上都可以使用 Virtual Box 10 台式机以及我的 Ubuntu 笔记本电脑)。我使用条件来测试“type = 0”(我将其用于 ansible“控制器”)。只有 ansible 控制器启动 ansible_local 以使用 ansible 配置 VM 集群。

   if info[:type]  == 0 then
     cfg.vm.provision "shell", inline: "if [ `which ansible` ] ; then echo \"ansible available\"; else sudo  yum -y update; sudo yum -y install epel-release; sudo yum -y install ansible; fi"
     cfg.vm.provision "ansible_local" do |ansible|
        ansible.extra_vars = { ansible_ssh_user: 'vagrant' }
        ansible.inventory_path = "./production"
        ansible.playbook = "rhelhosts.yml"
        ansible.limit = "local"
     end # ansible_local

这是在流浪者提供期间显示的:

PS D:\Documents\vagrant\top> vagrant 提供 control.top.RHEL76 is_linux_host: centos/7 is_linux_host: centos/7 is_linux_host: centos/7 is_windows_host: mwrock/Windows2016

这是在流浪者提供期间显示的:

PS D:\Documents\vagrant\ansible> vagrant provision control.ansible.RHEL76

is_linux_host: centos/7

is_linux_host: centos/7

is_linux_host: centos/7

is_windows_host: mwrock/Windows2016

--- many more lines, not relevant ---

尽情体验和部署您的多机/多操作系统实验室!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多