我有以下多机Vagrant设置:
Vagrant.configure(2) do |config|
config.vm.define "xfcevm" do |xfcevm|
xfcevm.vm.box = "generic/ubuntu1904"
xfcevm.vm.hostname = "xfcevm"
config.vm.provider "virtualbox" do |vb|
vb.name = "ubuntu-xfce"
end
end
config.vm.define "kdevm" do |kdevm|
kdevm.vm.box = "generic/arch"
kdevm.vm.hostname = "kdevm"
config.vm.provider "virtualbox" do |vb|
vb.name = "arch-kde"
end
end
## only Arch doesn't ship with Python installed
config.vm.provision "shell", inline: "which python || sudo pacman --noconfirm -S python"
config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.memory = "2048"
vb.cpus = 1
vb.customize ["modifyvm", :id, "--vram", "32"]
end
config.vm.provision "ansible" do |ansible|
ansible.verbose = "v"
ansible.compatibility_mode = "2.0"
ansible.playbook = "setup.yml"
ansible.inventory_path = "hosts"
end
end由于Arch vagrant box不包含Python,因此我创建了一个内联外壳配置命令,该命令应该测试Python的存在(由which python执行),如果结果为false,则应随后进行Python的pacman安装。对于回显输出,不应该计算第二部分,这是通过在终端中运行命令来实现的。
但是,不管||是否存在,shell provisioner都会在Python后对该部分进行评估。在Ubuntu的情况下,它引发了一个明显的错误,因为pacman没有被安装:
$ vagrant up --provision
Bringing machine 'xfcevm' up with 'virtualbox' provider...
Bringing machine 'kdevm' up with 'virtualbox' provider...
==> xfcevm: Checking if box 'generic/ubuntu1904' version '1.9.34' is up to date...
==> xfcevm: Running provisioner: shell...
xfcevm: Running: inline script
xfcevm: sudo
xfcevm: :
xfcevm: pacman: command not found
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.同样的道理也适用于简单的if语句,而不是||
config.vm.provision "shell", inline: "if [ ! `which python` ]; then sudo pacman --noconfirm -S python; fi"发布于 2019-10-10 00:04:57
实际的问题是两件事的结合:在Arch中使用python作为Python3的别名(与Ubuntu相反,在Ubuntu中python是Python2的别名),以及Ubuntu不随Python2一起提供的事实(我们不需要它用于任何目的,我们使用Python3)。
因此,解决方案是同时检查python和python3
config.vm.provision "shell", inline: "if [ ! `which python`] && [ ! `which python3` ]; then sudo pacman --noconfirm -S python; fi"发布于 2019-10-10 00:08:14
在我的机器上使用以下Vagranfile进行测试后:
Vagrant.configure(2) do |config|
config.vm.box = "generic/ubuntu1904"
config.vm.hostname = "test"
config.vm.network "private_network", type: "dhcp"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider "virtualbox" do |v|
v.memory = 2048
v.cpus = 2
end
config.vm.provision "default", type: "shell", inline: "which python", run: "always"
end这是vagrant up的结果(仅最后一行)
==> default: Running provisioner: default (shell)...
default: Running: inline script
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.交互检查:
$ vagrant ssh
Last login: Wed Oct 9 15:33:22 2019 from 10.0.2.2
vagrant@test:~$ which python
vagrant@test:~$ echo $?
1
vagrant@test:~$ which python3
/usr/bin/python3
vagrant@test:~$ echo $?
0
vagrant@test:~$结论:你得到的是完全连贯的。python不存在于您的ubuntu镜像中,因此您的命令的其余部分将被运行。你的方案有一个缺陷,你需要找到另一种方法。
在您的上下文中,我会尝试在ansible中运行所有内容。这里有一个我没有测试的例子,它肯定可以得到很大的改进
- name: Make sure machine can run ansible
hosts: all
gather_facts: false
tasks:
- block:
- name: Try to ansible-ping the host. Consider python is not installed otherwise
ping:
rescue:
- name: No python available, install with low-level and dirty command
become: true
become_method: sudo
raw: pacman --noconfirm -S pythonhttps://stackoverflow.com/questions/58301725
复制相似问题