为什么这个 Vagrant / Ansible Ruby 循环执行了两次并且不考虑变量更改?
Why is this Vagrant / Ansible Ruby loop executed twice and variable changes not respected?
我是 Vagrant / Ansible / Ruby 的新手,我不知道为什么内部循环似乎被执行了两次以及为什么外部循环不考虑对变量所做的更改内循环。
我想要一个动态清单文件,我想将一些配置值放入由 Vagrant 加载的配置文件中,它将为我创建它。我想定义一些具有相似结构的组,这些组将定义每个组中有多少主机由 Vagrant 创建。
---
# vagrant.yml
general:
base_ip: "192.168.2"
vm_box: "ubuntu/trusty64"
virtualbox:
vb_gui: true
vb_memory: 2048
vb_cpus: 1
groupA:
num_nodes: 1
instance_name_prefix: "groupA"
base_ip_offset: 50
groupB:
num_nodes: 0
instance_name_prefix: "groupB"
base_ip_offset: 60
我想遍历每个组并使用 Vagrant 在该组中创建 num_nodes
个实例。这是我的 Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
require 'yaml'
settings = YAML.load_file 'vagrant.yml'
Vagrant.configure(2) do |config|
config.vm.box = settings['general']['vm_box']
ansible_groups = [
"groupA",
"groupB"
]
# this counter should just represent which machine we are configuring out of the total
# population of all machines across all groups
# i.e. it should be monotonically increasing from 0..totalNumberOfNodes
machine_counter = 0
ansible_groups.each do |group|
num_nodes = settings[group]['num_nodes'].to_i
(1..num_nodes).each do |i|
config.vm.define vm_name = "%s-%02d" % [settings[group]['instance_name_prefix'], i]
config.vm.hostname = vm_name
config.vm.provider :virtualbox do |vb|
vb.gui = settings['virtualbox']['vb_gui']
vb.memory = settings['virtualbox']['vb_memory']
vb.cpus = settings['virtualbox']['vb_cpus']
end
ip = "#{settings['general']['base_ip']}.#{settings[group]['base_ip_offset'].to_i + i}"
config.vm.network :private_network, ip: ip
config.vm.network :forwarded_port, guest: 2001, host: 10000 + 2001 + machine_counter
machine_counter = machine_counter + 1
config.vm.provision :ansible do |ansible|
ansible.playbook = "playbook.yml"
# ansible.verbose = "vvvv"
end
end
end
end
此时groupB为空(num_nodes为0),一切正常。这是 vagrant up --no-provision
:
的输出
$ vagrant up --no-provision
Bringing machine 'groupA-01' up with 'virtualbox' provider...
==> groupA-01: Importing base box 'ubuntu/trusty64'...
==> groupA-01: Matching MAC address for NAT networking...
==> groupA-01: Checking if box 'ubuntu/trusty64' is up to date...
==> groupA-01: Setting the name of the VM: demo_groupA-01_1442511426046_79038
==> groupA-01: Clearing any previously set forwarded ports...
==> groupA-01: Clearing any previously set network interfaces...
==> groupA-01: Preparing network interfaces based on configuration...
groupA-01: Adapter 1: nat
groupA-01: Adapter 2: hostonly
==> groupA-01: Forwarding ports...
groupA-01: 2001 => 12001 (adapter 1)
groupA-01: 22 => 2222 (adapter 1)
==> groupA-01: Running 'pre-boot' VM customizations...
==> groupA-01: Booting VM...
==> groupA-01: Waiting for machine to boot. This may take a few minutes...
groupA-01: SSH address: 127.0.0.1:2222
groupA-01: SSH username: vagrant
groupA-01: SSH auth method: private key
groupA-01: Warning: Connection timeout. Retrying...
groupA-01:
groupA-01: Vagrant insecure key detected. Vagrant will automatically replace
groupA-01: this with a newly generated keypair for better security.
groupA-01:
groupA-01: Inserting generated public key within guest...
groupA-01: Removing insecure key from the guest if it's present...
groupA-01: Key inserted! Disconnecting and reconnecting using new SSH key...
==> groupA-01: Machine booted and ready!
==> groupA-01: Checking for guest additions in VM...
==> groupA-01: Setting hostname...
==> groupA-01: Configuring and enabling network interfaces...
==> groupA-01: Mounting shared folders...
groupA-01: /vagrant => /Users/me/demo
==> groupA-01: Machine not provisioned because `--no-provision` is specified.
现在,当我将另一台机器添加到配置时(groupA
中的 num_nodes
为 2),我将端口转发两次,并且端口转发到第二台机器的相同值,导致失败:
$ vagrant up --no-provision
Bringing machine 'groupA-01' up with 'virtualbox' provider...
Bringing machine 'groupA-02' up with 'virtualbox' provider...
==> groupA-01: Importing base box 'ubuntu/trusty64'...
==> groupA-01: Matching MAC address for NAT networking...
==> groupA-01: Checking if box 'ubuntu/trusty64' is up to date...
==> groupA-01: Setting the name of the VM: demo_ groupA-01_1442512392590_86418
==> groupA-01: Clearing any previously set forwarded ports...
==> groupA-01: Clearing any previously set network interfaces...
==> groupA-01: Preparing network interfaces based on configuration...
groupA-01: Adapter 1: nat
groupA-01: Adapter 2: hostonly
groupA-01: Adapter 3: hostonly
==> groupA-01: Forwarding ports...
groupA-01: 2001 => 12001 (adapter 1)
groupA-01: 2001 => 12002 (adapter 1)
groupA-01: 22 => 2222 (adapter 1)
==> groupA-01: Running 'pre-boot' VM customizations...
==> groupA-01: Booting VM...
==> groupA-01: Waiting for machine to boot. This may take a few minutes...
groupA-01: SSH address: 127.0.0.1:2222
groupA-01: SSH username: vagrant
groupA-01: SSH auth method: private key
groupA-01: Warning: Connection timeout. Retrying...
groupA-01:
groupA-01: Vagrant insecure key detected. Vagrant will automatically replace
groupA-01: this with a newly generated keypair for better security.
groupA-01:
groupA-01: Inserting generated public key within guest...
groupA-01: Removing insecure key from the guest if it's present...
groupA-01: Key inserted! Disconnecting and reconnecting using new SSH key...
==> groupA-01: Machine booted and ready!
==> groupA-01: Checking for guest additions in VM...
==> groupA-01: Setting hostname...
==> groupA-01: Configuring and enabling network interfaces...
==> groupA-01: Mounting shared folders...
groupA-01: /vagrant => /Users/john/travelnet/kafka-samza2
==> groupA-01: Machine not provisioned because `--no-provision` is specified.
==> groupA-02: Importing base box 'ubuntu/trusty64'...
==> groupA-02: Matching MAC address for NAT networking...
==> groupA-02: Checking if box 'ubuntu/trusty64' is up to date...
==> groupA-02: Setting the name of the VM: demo_ groupA-02_1442512426303_57538
==> groupA-02: Clearing any previously set forwarded ports...
Vagrant cannot forward the specified ports on this VM, since they
would collide with some other application that is already listening
on these ports. The forwarded port to 12001 is already in use
on the host machine.
To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:
config.vm.network :forwarded_port, guest: 2001, host: 1234
Sometimes, Vagrant will attempt to auto-correct this for you. In this
case, Vagrant was unable to. This is usually because the guest machine
is in a state which doesn't allow modifying port forwarding.
端口转发部分被执行了两次(如果我不使用 --no-provision
,配置部分也是如此)。
我不明白为什么它被执行了两次,也不明白为什么第二个虚拟机试图转发到 12001(我认为应该是到 12002,这应该没问题,因为第一个虚拟机应该只能转发到 12001)。
此处有关于使用 Vagrant 循环进行延迟加载的警告:https://docs.vagrantup.com/v2/vagrantfile/tips.html,但我是 Ruby 的新手,我看不到 how/why 适用于此处。
我要实现的循环是:
For each group within groups:
For each node in 1..num_nodes within group:
Configure node
请问这是怎么回事?
我的猜测是 ruby 没有任何问题。
问题是您只使用一台机器。如果你想在 Vagrant 中使用多台机器,你需要遵循:https://docs.vagrantup.com/v2/multi-machine/
你想做的未经测试的方法(注意 this_vm 而不是配置):
(1..num_nodes).each do |i|
vm_name = "%s-%02d" % [settings[group]['instance_name_prefix'], i]
config.vm.define vm_name do |this_vm|
this_vm.vm.hostname = vm_name
this_vm.vm.provider :virtualbox do |vb|
vb.gui = settings['virtualbox']['vb_gui']
vb.memory = settings['virtualbox']['vb_memory']
vb.cpus = settings['virtualbox']['vb_cpus']
end
end
我是 Vagrant / Ansible / Ruby 的新手,我不知道为什么内部循环似乎被执行了两次以及为什么外部循环不考虑对变量所做的更改内循环。
我想要一个动态清单文件,我想将一些配置值放入由 Vagrant 加载的配置文件中,它将为我创建它。我想定义一些具有相似结构的组,这些组将定义每个组中有多少主机由 Vagrant 创建。
---
# vagrant.yml
general:
base_ip: "192.168.2"
vm_box: "ubuntu/trusty64"
virtualbox:
vb_gui: true
vb_memory: 2048
vb_cpus: 1
groupA:
num_nodes: 1
instance_name_prefix: "groupA"
base_ip_offset: 50
groupB:
num_nodes: 0
instance_name_prefix: "groupB"
base_ip_offset: 60
我想遍历每个组并使用 Vagrant 在该组中创建 num_nodes
个实例。这是我的 Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
require 'yaml'
settings = YAML.load_file 'vagrant.yml'
Vagrant.configure(2) do |config|
config.vm.box = settings['general']['vm_box']
ansible_groups = [
"groupA",
"groupB"
]
# this counter should just represent which machine we are configuring out of the total
# population of all machines across all groups
# i.e. it should be monotonically increasing from 0..totalNumberOfNodes
machine_counter = 0
ansible_groups.each do |group|
num_nodes = settings[group]['num_nodes'].to_i
(1..num_nodes).each do |i|
config.vm.define vm_name = "%s-%02d" % [settings[group]['instance_name_prefix'], i]
config.vm.hostname = vm_name
config.vm.provider :virtualbox do |vb|
vb.gui = settings['virtualbox']['vb_gui']
vb.memory = settings['virtualbox']['vb_memory']
vb.cpus = settings['virtualbox']['vb_cpus']
end
ip = "#{settings['general']['base_ip']}.#{settings[group]['base_ip_offset'].to_i + i}"
config.vm.network :private_network, ip: ip
config.vm.network :forwarded_port, guest: 2001, host: 10000 + 2001 + machine_counter
machine_counter = machine_counter + 1
config.vm.provision :ansible do |ansible|
ansible.playbook = "playbook.yml"
# ansible.verbose = "vvvv"
end
end
end
end
此时groupB为空(num_nodes为0),一切正常。这是 vagrant up --no-provision
:
$ vagrant up --no-provision
Bringing machine 'groupA-01' up with 'virtualbox' provider...
==> groupA-01: Importing base box 'ubuntu/trusty64'...
==> groupA-01: Matching MAC address for NAT networking...
==> groupA-01: Checking if box 'ubuntu/trusty64' is up to date...
==> groupA-01: Setting the name of the VM: demo_groupA-01_1442511426046_79038
==> groupA-01: Clearing any previously set forwarded ports...
==> groupA-01: Clearing any previously set network interfaces...
==> groupA-01: Preparing network interfaces based on configuration...
groupA-01: Adapter 1: nat
groupA-01: Adapter 2: hostonly
==> groupA-01: Forwarding ports...
groupA-01: 2001 => 12001 (adapter 1)
groupA-01: 22 => 2222 (adapter 1)
==> groupA-01: Running 'pre-boot' VM customizations...
==> groupA-01: Booting VM...
==> groupA-01: Waiting for machine to boot. This may take a few minutes...
groupA-01: SSH address: 127.0.0.1:2222
groupA-01: SSH username: vagrant
groupA-01: SSH auth method: private key
groupA-01: Warning: Connection timeout. Retrying...
groupA-01:
groupA-01: Vagrant insecure key detected. Vagrant will automatically replace
groupA-01: this with a newly generated keypair for better security.
groupA-01:
groupA-01: Inserting generated public key within guest...
groupA-01: Removing insecure key from the guest if it's present...
groupA-01: Key inserted! Disconnecting and reconnecting using new SSH key...
==> groupA-01: Machine booted and ready!
==> groupA-01: Checking for guest additions in VM...
==> groupA-01: Setting hostname...
==> groupA-01: Configuring and enabling network interfaces...
==> groupA-01: Mounting shared folders...
groupA-01: /vagrant => /Users/me/demo
==> groupA-01: Machine not provisioned because `--no-provision` is specified.
现在,当我将另一台机器添加到配置时(groupA
中的 num_nodes
为 2),我将端口转发两次,并且端口转发到第二台机器的相同值,导致失败:
$ vagrant up --no-provision
Bringing machine 'groupA-01' up with 'virtualbox' provider...
Bringing machine 'groupA-02' up with 'virtualbox' provider...
==> groupA-01: Importing base box 'ubuntu/trusty64'...
==> groupA-01: Matching MAC address for NAT networking...
==> groupA-01: Checking if box 'ubuntu/trusty64' is up to date...
==> groupA-01: Setting the name of the VM: demo_ groupA-01_1442512392590_86418
==> groupA-01: Clearing any previously set forwarded ports...
==> groupA-01: Clearing any previously set network interfaces...
==> groupA-01: Preparing network interfaces based on configuration...
groupA-01: Adapter 1: nat
groupA-01: Adapter 2: hostonly
groupA-01: Adapter 3: hostonly
==> groupA-01: Forwarding ports...
groupA-01: 2001 => 12001 (adapter 1)
groupA-01: 2001 => 12002 (adapter 1)
groupA-01: 22 => 2222 (adapter 1)
==> groupA-01: Running 'pre-boot' VM customizations...
==> groupA-01: Booting VM...
==> groupA-01: Waiting for machine to boot. This may take a few minutes...
groupA-01: SSH address: 127.0.0.1:2222
groupA-01: SSH username: vagrant
groupA-01: SSH auth method: private key
groupA-01: Warning: Connection timeout. Retrying...
groupA-01:
groupA-01: Vagrant insecure key detected. Vagrant will automatically replace
groupA-01: this with a newly generated keypair for better security.
groupA-01:
groupA-01: Inserting generated public key within guest...
groupA-01: Removing insecure key from the guest if it's present...
groupA-01: Key inserted! Disconnecting and reconnecting using new SSH key...
==> groupA-01: Machine booted and ready!
==> groupA-01: Checking for guest additions in VM...
==> groupA-01: Setting hostname...
==> groupA-01: Configuring and enabling network interfaces...
==> groupA-01: Mounting shared folders...
groupA-01: /vagrant => /Users/john/travelnet/kafka-samza2
==> groupA-01: Machine not provisioned because `--no-provision` is specified.
==> groupA-02: Importing base box 'ubuntu/trusty64'...
==> groupA-02: Matching MAC address for NAT networking...
==> groupA-02: Checking if box 'ubuntu/trusty64' is up to date...
==> groupA-02: Setting the name of the VM: demo_ groupA-02_1442512426303_57538
==> groupA-02: Clearing any previously set forwarded ports...
Vagrant cannot forward the specified ports on this VM, since they
would collide with some other application that is already listening
on these ports. The forwarded port to 12001 is already in use
on the host machine.
To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:
config.vm.network :forwarded_port, guest: 2001, host: 1234
Sometimes, Vagrant will attempt to auto-correct this for you. In this
case, Vagrant was unable to. This is usually because the guest machine
is in a state which doesn't allow modifying port forwarding.
端口转发部分被执行了两次(如果我不使用 --no-provision
,配置部分也是如此)。
我不明白为什么它被执行了两次,也不明白为什么第二个虚拟机试图转发到 12001(我认为应该是到 12002,这应该没问题,因为第一个虚拟机应该只能转发到 12001)。
此处有关于使用 Vagrant 循环进行延迟加载的警告:https://docs.vagrantup.com/v2/vagrantfile/tips.html,但我是 Ruby 的新手,我看不到 how/why 适用于此处。
我要实现的循环是:
For each group within groups:
For each node in 1..num_nodes within group:
Configure node
请问这是怎么回事?
我的猜测是 ruby 没有任何问题。
问题是您只使用一台机器。如果你想在 Vagrant 中使用多台机器,你需要遵循:https://docs.vagrantup.com/v2/multi-machine/
你想做的未经测试的方法(注意 this_vm 而不是配置):
(1..num_nodes).each do |i|
vm_name = "%s-%02d" % [settings[group]['instance_name_prefix'], i]
config.vm.define vm_name do |this_vm|
this_vm.vm.hostname = vm_name
this_vm.vm.provider :virtualbox do |vb|
vb.gui = settings['virtualbox']['vb_gui']
vb.memory = settings['virtualbox']['vb_memory']
vb.cpus = settings['virtualbox']['vb_cpus']
end
end