Is it possible to get inside-out ordering of provisioners in a Vagrant multi-machine setup? - vagrantfile

Is it possible to reverse the order of provisioners from innermost to outermost when using a multi-machine setup? I want a small shell provisioner to create some facts in /etc/facter/facts.d/ before provisioning with puppet, to mimic our current setup as much as possible. (I have inherited a large puppet repo and am trying to create a Vagrant testbed for it before I start doing changes.)
The puppet settings are the same for every box, but requires the shell provisioner to run first. Here's an example Vagrantfile to show what I want to do (some names changed to protect the innocent):
$facts =<<FACTS
set -x
mkdir -p /etc/facter/facts.d
echo role=$1 > /etc/facter/facts.d/role.txt
echo location=$2 > /etc/facter/facts.d/location.txt
echo environment=$3 > /etc/facter/facts.d/environment.txt
FACTS
Vagrant.configure(2) do |config|
config.vm.box = "centos-6.6"
config.vm.synced_folder "hiera", "/etc/puppet/hiera"
config.vm.provision :puppet do |puppet|
puppet.manifest_file = "site.pp"
puppet.module_path = ["modules", "internal"]
puppet.hiera_config_path = "hiera.yaml"
puppet.options = "--test"
end
config.vm.define :foo1 do |c|
c.vm.hostname = "foo-1.vagrant"
c.vm.provision :shell, inline: $facts, args: "foo testing stage"
end
config.vm.define :bar do |c|
c.vm.hostname = "bar-1.vagrant"
c.vm.provision :shell, inline: $facts, args: "bar testing stage"
end
# ... more machines omitted ...
end

Answering my own question as I found an acceptable workaround: I moved the puppet provisioning into the inner block. Here's what my current code looks like:
$facts =<<SET_FACTS
set -x
mkdir -p /etc/facter/facts.d
echo role=$1 > /etc/facter/facts.d/role.txt
echo location=$2 > /etc/facter/facts.d/location.txt
echo environment=$3 > /etc/facter/facts.d/environment.txt
SET_FACTS
module Vagrant
module Config
module V2
class Root
def provision(role, location, environment)
vm.provision "set-facts",
type: :shell,
inline: $facts,
args: [role, location, environment].map { |x| x.to_s }
vm.provision :puppet do |puppet|
puppet.manifest_file = "site.pp"
puppet.module_path = ["modules", "internal"]
puppet.hiera_config_path = "hiera.yaml"
end
end
end
end
end
end
Vagrant.configure(2) do |config|
config.vm.box = "centos-6.6"
config.vm.synced_folder "hiera", "/etc/puppet/hiera"
config.vm.define :foo1 do |c|
c.vm.hostname = "foo-1.vagrant"
c.provision(:foo, :testing, :stage)
end
config.vm.define :bar1 do |c|
c.vm.hostname = "bar-1.vagrant"
c.provision(:bar, :testing, :stage)
end
end

Related

How does vimscript execute functions through multiple threads?

I have a function for generating tags via ctags:
:function! UpdateCtags()
if !has('linux')
echohl ErrorMsg | echo 'This function only supports running under the linux operating system.' | echohl None
return
endif
echo 'Generating labels...'
let output = system('ctags -f ' . g:tags_file . ' -R /usr/include')
if v:shell_error == 0
echo 'Generated labels successfully.'
else
echohl ErrorMsg | echo output | echohl None
endif
:endfunction
I want to simply execute the UpdateCtags function through multiple threads, how can I do this?
My neovim version:
$ nvim -v
NVIM v0.7.2
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by builduser
Features: +acl +iconv +tui
See ":help feature-compile"
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/usr/share/nvim"
Run :checkhealth for more info

Vagrant provision order

I try to install kubernetes with istio. Here is snippet from Vagrantfile(copied from github)
config.vm.define "k8s-master" do |master|
master.vm.box = IMAGE_NAME
master.vm.network "private_network", ip: "192.168.50.10"
master.vm.hostname = "k8s-master"
master.vm.provision "ansible" do |ansible|
ansible.playbook = "kubernetes-setup/master-playbook.yml"
end
end
(1..N).each do |i|
config.vm.define "node-#{i}" do |node|
node.vm.box = IMAGE_NAME
node.vm.network "private_network", ip: "192.168.50.#{i + 10}"
node.vm.hostname = "node-#{i}"
node.vm.provision "ansible" do |ansible|
ansible.playbook = "kubernetes-setup/node-playbook.yml"
end
end
end
If I put installation of istio into k8s-master playbook, it fails. I assume this happens because worker nodes are not installed yet, and istio can't provision its infrastructure. I need to run second playbook on k8s-master after provisioning workers. What is solution?

Capistrano 3: Relative symlink instead of absolute for current, linked_dirs and linked_files

I need to have relative symlink​ instead of absolute symlink​ when deploying.
I think the tree tasks than need to be overwritten are.
Rake::Task["deploy:symlink:linked_dirs"]
Rake::Task["deploy:symlink:linked_files"]
Rake::Task["deploy:symlink:release"] ​ ​
What I would like is some DSL I can drop in my deploy.rb so when I'm deploying created links are all relative.
You can juste use this in your deploy.rb to overwrite the default behaviour
## Use relative path instead of absolute
Rake::Task["deploy:symlink:linked_dirs"].clear
Rake::Task["deploy:symlink:linked_files"].clear
Rake::Task["deploy:symlink:release"].clear
namespace :deploy do
namespace :symlink do
desc 'Symlink release to current'
task :release do
on release_roles :all do
tmp_current_path = release_path.parent.join(current_path.basename)
execute :ln, '-s', release_path.relative_path_from(current_path.dirname), tmp_current_path
execute :mv, tmp_current_path, current_path.parent
end
end
desc 'Symlink files and directories from shared to release'
task :shared do
invoke 'deploy:symlink:linked_files'
invoke 'deploy:symlink:linked_dirs'
end
desc 'Symlink linked directories'
task :linked_dirs do
next unless any? :linked_dirs
on release_roles :all do
execute :mkdir, '-p', linked_dir_parents(release_path)
fetch(:linked_dirs).each do |dir|
target = release_path.join(dir)
source = shared_path.join(dir)
unless test "[ -L #{target} ]"
if test "[ -d #{target} ]"
execute :rm, '-rf', target
end
execute :ln, '-s', source.relative_path_from(target.dirname), target
end
end
end
end
desc 'Symlink linked files'
task :linked_files do
next unless any? :linked_files
on release_roles :all do
execute :mkdir, '-p', linked_file_dirs(release_path)
fetch(:linked_files).each do |file|
target = release_path.join(file)
source = shared_path.join(file)
unless test "[ -L #{target} ]"
if test "[ -f #{target} ]"
execute :rm, target
end
execute :ln, '-s', source.relative_path_from(target.dirname), target
end
end
end
end
end
end

Vagrant machine disappears after reboot the host machine

Well, the title explain the issue very well. I install my vagrant machine through vagrant up from netbeans plugin. I configure it and use it propperly. Then i halt the machine, shut down my host machine, and when i start my host the vagrant machine has disappeared. No config files, no machine itself. Didn't find any documentation on this issue and i need the vagrant machine, so i install a new one every day so i can propperly debug my work project. I dont know what to do nor try, because I´ve only been using vagrant for a few weeks on a new job, but im wasting a lot of time on this daily instalation and i need to solve this. I appreciate any help.
Any ideas?
Vagrantfile:
require 'yaml'
dir = File.dirname(File.expand_path(__FILE__))
configValues = YAML.load_file("#{dir}/puphpet/config.yaml")
data = configValues['vagrantfile-local']
Vagrant.require_version '>= 1.6.0'
Vagrant.configure('2') do |config|
config.vm.box = "#{data['vm']['box']}"
config.vm.box_url = "#{data['vm']['box_url']}"
if data['vm']['hostname'].to_s.strip.length != 0
config.vm.hostname = "#{data['vm']['hostname']}"
end
if data['vm']['network']['private_network'].to_s != ''
config.vm.network 'private_network', ip: "#{data['vm']['network']['private_network']}"
end
data['vm']['network']['forwarded_port'].each do |i, port|
if port['guest'] != '' && port['host'] != ''
config.vm.network :forwarded_port, guest: port['guest'].to_i, host: port['host'].to_i
end
end
if !data['vm']['post_up_message'].nil?
config.vm.post_up_message = "#{data['vm']['post_up_message']}"
end
if Vagrant.has_plugin?('vagrant-hostmanager')
hosts = Array.new()
if !configValues['apache']['install'].nil? &&
configValues['apache']['install'].to_i == 1 &&
configValues['apache']['vhosts'].is_a?(Hash)
configValues['apache']['vhosts'].each do |i, vhost|
hosts.push(vhost['servername'])
if vhost['serveraliases'].is_a?(Array)
vhost['serveraliases'].each do |vhost_alias|
hosts.push(vhost_alias)
end
end
end
elsif !configValues['nginx']['install'].nil? &&
configValues['nginx']['install'].to_i == 1 &&
configValues['nginx']['vhosts'].is_a?(Hash)
configValues['nginx']['vhosts'].each do |i, vhost|
hosts.push(vhost['server_name'])
if vhost['server_aliases'].is_a?(Array)
vhost['server_aliases'].each do |x, vhost_alias|
hosts.push(vhost_alias)
end
end
end
end
if hosts.any?
contents = File.open("#{dir}/puphpet/shell/ascii-art/hostmanager-notice.txt", 'r'){ |file| file.read }
puts "\n\033[32m#{contents}\033[0m\n"
if config.vm.hostname.to_s.strip.length == 0
config.vm.hostname = 'puphpet-dev-machine'
end
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
config.hostmanager.ignore_private_ip = false
config.hostmanager.include_offline = false
config.hostmanager.aliases = hosts
end
end
if Vagrant.has_plugin?('vagrant-cachier')
config.cache.scope = :box
end
data['vm']['synced_folder'].each do |i, folder|
if folder['source'] != '' && folder['target'] != ''
if folder['sync_type'] == 'nfs'
config.vm.synced_folder "#{folder['source']}", "#{folder['target']}", id: "#{i}", type: 'nfs'
config.vm.network "private_network", type: "dhcp"
elsif folder['sync_type'] == 'smb'
config.vm.synced_folder "#{folder['source']}", "#{folder['target']}", id: "#{i}", type: 'smb'
elsif folder['sync_type'] == 'rsync'
rsync_args = !folder['rsync']['args'].nil? ? folder['rsync']['args'] : ['--verbose', '--archive', '-z']
rsync_auto = !folder['rsync']['auto'].nil? ? folder['rsync']['auto'] : true
rsync_exclude = !folder['rsync']['exclude'].nil? ? folder['rsync']['exclude'] : ['.vagrant/']
config.vm.synced_folder "#{folder['source']}", "#{folder['target']}", id: "#{i}",
rsync__args: rsync_args, rsync__exclude: rsync_exclude, rsync__auto: rsync_auto, type: 'rsync'
else
config.vm.synced_folder "#{folder['source']}", "#{folder['target']}", id: "#{i}",
group: 'www-data', owner: 'www-data', mount_options: ['dmode=777', 'fmode=777']
end
end
end
config.vm.usable_port_range = (data['vm']['usable_port_range']['start'].to_i..data['vm']['usable_port_range']['stop'].to_i)
if data['vm']['chosen_provider'].empty? || data['vm']['chosen_provider'] == 'virtualbox'
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'virtualbox'
config.vm.provider :virtualbox do |virtualbox|
data['vm']['provider']['virtualbox']['modifyvm'].each do |key, value|
if key == 'memory'
next
end
if key == 'cpus'
next
end
if key == 'natdnshostresolver1'
value = value ? 'on' : 'off'
end
virtualbox.customize ['modifyvm', :id, "--#{key}", "#{value}"]
end
virtualbox.customize ['modifyvm', :id, '--memory', "#{data['vm']['memory']}"]
virtualbox.customize ['modifyvm', :id, '--cpus', "#{data['vm']['cpus']}"]
if data['vm']['hostname'].to_s.strip.length != 0
virtualbox.customize ['modifyvm', :id, '--name', config.vm.hostname]
end
end
end
if data['vm']['chosen_provider'] == 'vmware_fusion' || data['vm']['chosen_provider'] == 'vmware_workstation'
ENV['VAGRANT_DEFAULT_PROVIDER'] = (data['vm']['chosen_provider'] == 'vmware_fusion') ? 'vmware_fusion' : 'vmware_workstation'
config.vm.provider 'vmware_fusion' do |v|
data['vm']['provider']['vmware'].each do |key, value|
if key == 'memsize'
next
end
if key == 'cpus'
next
end
v.vmx["#{key}"] = "#{value}"
end
v.vmx['memsize'] = "#{data['vm']['memory']}"
v.vmx['numvcpus'] = "#{data['vm']['cpus']}"
if data['vm']['hostname'].to_s.strip.length != 0
v.vmx['displayName'] = config.vm.hostname
end
end
end
if data['vm']['chosen_provider'] == 'parallels'
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'parallels'
config.vm.provider 'parallels' do |v|
data['vm']['provider']['parallels'].each do |key, value|
if key == 'memsize'
next
end
if key == 'cpus'
next
end
v.customize ['set', :id, "--#{key}", "#{value}"]
end
v.memory = "#{data['vm']['memory']}"
v.cpus = "#{data['vm']['cpus']}"
if data['vm']['hostname'].to_s.strip.length != 0
v.name = config.vm.hostname
end
end
end
ssh_username = !data['ssh']['username'].nil? ? data['ssh']['username'] : 'vagrant'
config.vm.provision 'shell' do |s|
s.path = 'puphpet/shell/initial-setup.sh'
s.args = '/vagrant/puphpet'
end
config.vm.provision 'shell' do |kg|
kg.path = 'puphpet/shell/ssh-keygen.sh'
kg.args = "#{ssh_username}"
end
config.vm.provision :shell, :path => 'puphpet/shell/install-ruby.sh'
config.vm.provision :shell, :path => 'puphpet/shell/install-puppet.sh'
config.vm.provision :puppet do |puppet|
puppet.facter = {
'ssh_username' => "#{ssh_username}",
'provisioner_type' => ENV['VAGRANT_DEFAULT_PROVIDER'],
'vm_target_key' => 'vagrantfile-local',
}
puppet.manifests_path = "#{data['vm']['provision']['puppet']['manifests_path']}"
puppet.manifest_file = "#{data['vm']['provision']['puppet']['manifest_file']}"
puppet.module_path = "#{data['vm']['provision']['puppet']['module_path']}"
if !data['vm']['provision']['puppet']['options'].empty?
puppet.options = data['vm']['provision']['puppet']['options']
end
end
config.vm.provision :shell do |s|
s.path = 'puphpet/shell/execute-files.sh'
s.args = ['exec-once', 'exec-always']
end
config.vm.provision :shell, run: 'always' do |s|
s.path = 'puphpet/shell/execute-files.sh'
s.args = ['startup-once', 'startup-always']
end
config.vm.provision :shell, :path => 'puphpet/shell/important-notices.sh'
if File.file?("#{dir}/puphpet/files/dot/ssh/id_rsa")
config.ssh.private_key_path = [
"#{dir}/puphpet/files/dot/ssh/id_rsa",
"#{dir}/puphpet/files/dot/ssh/insecure_private_key"
]
end
if !data['ssh']['host'].nil?
config.ssh.host = "#{data['ssh']['host']}"
end
if !data['ssh']['port'].nil?
config.ssh.port = "#{data['ssh']['port']}"
end
if !data['ssh']['username'].nil?
config.ssh.username = "#{data['ssh']['username']}"
end
if !data['ssh']['guest_port'].nil?
config.ssh.guest_port = data['ssh']['guest_port']
end
if !data['ssh']['shell'].nil?
config.ssh.shell = "#{data['ssh']['shell']}"
end
if !data['ssh']['keep_alive'].nil?
config.ssh.keep_alive = data['ssh']['keep_alive']
end
if !data['ssh']['forward_agent'].nil?
config.ssh.forward_agent = data['ssh']['forward_agent']
end
if !data['ssh']['forward_x11'].nil?
config.ssh.forward_x11 = data['ssh']['forward_x11']
end
if !data['vagrant']['host'].nil?
config.vagrant.host = data['vagrant']['host'].gsub(':', '').intern
end
end
As a provisional solution im saving from now on all the vm files into other folder so i can only restore and dont need to install again, but this is a lame solution and i wish to do this propperly.
This question is of low quality and I'd recommend closing it if we can't fully describe what the issue that you were having and the solution to that issue. Keep in mind, you're able to submit answers to your own question. That way, other people who come across this issue will understand how you fixed the problem. Typically, you can discover a lot by searching "debugging X" (e.g. Google -> "debugging vagrant").
Short of that, something that might be useful to you is looking at the machine console (GUI) while your VM is booting. Since you're using Virtualbox, this is quite easy. In the section of your Vagrantfile that begins with config.vm.provider :virtualbox do |virtualbox| , add the following :
virtualbox.gui = true
This is a common approach, described in the documentation: http://docs.vagrantup.com/v2/virtualbox/configuration.html
To fix this i just stop launching vagrant from netbeans and started using it from cygwin. This way it dont disappear. Still dont know why it removes the machine if i launch it from netbeans, but i need to use it at work so i have to do it this way and move on. Thanks everyone for the answers and the time spent.

How to set conditional variables in capistrano's deploy.rb

Snippet from deploy.rb
task :prod1 do
set :deploy_to, "/home/project/src/prod1"
end
task :prod2 do
set :deploy_to, "/home/project/src/prod2"
end
I have 2 tasks like the above. Now instead of manually running either "cap prod1 deploy" or "cap prod2 deploy", I want to create a task "prod" which sets the required "deploy_to" based on the existence of a file on the server.
something like:
task :prod do
if (A_FILE_IN_SERVER_EXISTS)
set :deploy_to, "/home/project/src/prod2"
else
set :deploy_to, "/home/project/src/prod1"
end
How do I do that?
You can do that like this:
task :set_deploy_to_location do
if capture("[ -f /etc/passwd2 ] && echo '1' || echo '0'").strip == '1'
set :deploy_to, "/home/project/src/prod2"
else
set :deploy_to, "/home/project/src/prod1"
end
logger.info "set deploy_to = #{deploy_to}"
end
This will do what you need. You can hook this method using before and after hooks like this:
before :deploy, :set_deploy_to_location