Merge branch 'chef-solo and shell-provisioning'

This commit is contained in:
Ramakrishnan 2014-04-11 14:27:48 +05:30
Родитель ec0b6d0a83 6e2692a6ab
Коммит 11c79fd994
10 изменённых файлов: 359 добавлений и 5 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -4,6 +4,7 @@ Gemfile.lock
azure.box
Vagrantfile
!example_box/Vagrantfile
!example_box/README.md
babu
example_box/
*.rdp
@ -11,3 +12,4 @@ pkg/
gem/
manifests/
modules/
.vagrant/

Просмотреть файл

@ -110,3 +110,15 @@ The vagrant-azure provide exposes a few Azure specific configration options:
* `winrm_https_port` To map the internal WinRM https port 5986 to a different public port.
* `winrm_http_port` To map the internal WinRM http port 5985 to a different public port.
* `tcp_endpoints` - To open any additional ports. E.g., `80` opens port `80` and `80,3389:53389` opens port `80` and `3389`. Also maps the interal port `3389` to public port `53389`
*
## New Commands for `azure` provider
The `azure` provider introduces the following new `vagrant` commands.
* `rdp` - To connect to a Windows VM using RDP. E.g.,
```
C:\> vagrant up --provider=azure
...
C:\> vagrant rdp
```

15
example_box/README.md Normal file
Просмотреть файл

@ -0,0 +1,15 @@
# Vagrant Azure Example Box
This directory contains the sample contents of a box for `azure` provider. Build this into a box using:
On Windows:
```
C:\> bsdtar -cvzf azure.box metadata.json Vagrantfile
```
On *Nix:
```
$ tar cvzf azure.box ./metadata.json ./Vagrantfile
```
You can add any defaults supported by the ```azure``` provider to the `Vagrantfile` in your box and Vagrant's built-in merging system will set them as defaults. Users can override these defaults in their own Vagrantfiles.

Просмотреть файл

@ -13,6 +13,8 @@ module VagrantPlugins
autoload :Driver, lib_path.join('driver')
require lib_path.join('provisioner/puppet')
require lib_path.join('provisioner/chef-solo')
require lib_path.join('provisioner/shell')
# This returns the path to the source of this plugin.
#

Просмотреть файл

@ -215,13 +215,14 @@ module VagrantPlugins
next
end
b2.use RestartVM
b2.use Call, WaitForState, :ReadyRole do |env2, b3|
b2.use action_halt
b2.use Call, WaitForState, :StoppedDeallocated do |env2, b3|
if env2[:result]
env2[:machine].id =~ /@/
b3.use Message, I18n.t(
'vagrant_azure.vm_started', :name => $`
)
b3.use Message, I18n.t('vagrant_azure.vm_stopped', name: $`)
b3.use action_up
else
b3.use Message, 'Not able to stop the machine. Please retry.'
end
end
end

Просмотреть файл

@ -2,6 +2,7 @@
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#---------------------------------------------------------------------------
module VagrantPlugins
module WinAzure
module Action
@ -24,10 +25,18 @@ module VagrantPlugins
# TODO: Add Shell, Chef-solo and other provisioners
case env[:provisioner].class.to_s
when "VagrantPlugins::Shell::Provisioner"
VagrantPlugins::WinAzure::Provisioner::Shell.new(
env
).provision_for_windows
when "VagrantPlugins::Puppet::Provisioner::Puppet"
VagrantPlugins::WinAzure::Provisioner::Puppet.new(
env
).provision_for_windows
when "VagrantPlugins::Chef::Provisioner::ChefSolo"
VagrantPlugins::WinAzure::Provisioner::ChefSolo.new(
env
).provision_for_windows
end
else
env[:ui].info "Provisioning using SSH"

Просмотреть файл

@ -0,0 +1,177 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#--------------------------------------------------------------------------
require "fileutils"
require "tempfile"
module VagrantPlugins
module WinAzure
module Provisioner
class ChefSolo
attr_reader :provisioner
def initialize(env)
@env = env
@provisioner = env[:provisioner]
end
def provision_for_windows
# Copy the chef cookbooks roles data bags and environment folders to Guest
copy_folder_to_guest(provisioner.cookbook_folders)
copy_folder_to_guest(provisioner.role_folders)
copy_folder_to_guest(provisioner.data_bags_folders)
copy_folder_to_guest(provisioner.environments_folders)
# Upload Encrypted data bag
upload_encrypted_data_bag_secret if config.encrypted_data_bag_secret_key_path
setup_json
setup_solo_config
run_chef_solo
# TODO
# delete_encrypted_data_bag_secret
end
def setup_json
@env[:machine].env.ui.info I18n.t("vagrant.provisioners.chef.json")
# Get the JSON that we're going to expose to Chef
json = config.json
json[:run_list] = config.run_list if !config.run_list.empty?
json = JSON.pretty_generate(json)
# Create a temporary file to store the data so we
# can upload it
temp = Tempfile.new("vagrant")
temp.write(json)
temp.close
remote_file = File.join(config.provisioning_path, "dna.json")
@env[:machine].provider.driver.upload(temp.path, remote_file)
end
def setup_solo_config
cookbooks_path = guest_paths(provisioner.cookbook_folders)
roles_path = guest_paths(provisioner.role_folders)
data_bags_path = guest_paths(provisioner.data_bags_folders).first
environments_path = guest_paths(provisioner.environments_folders).first
source_path = "#{VagrantPlugins::WinAzure.source_root}"
template_path = source_path + "/templates/provisioners/chef-solo/solo"
setup_config(template_path, "solo.rb", {
:cookbooks_path => cookbooks_path,
:recipe_url => config.recipe_url,
:roles_path => roles_path,
:data_bags_path => data_bags_path,
:environments_path => environments_path
})
end
def setup_config(template, filename, template_vars)
# If we have custom configuration, upload it
remote_custom_config_path = nil
if config.custom_config_path
expanded = File.expand_path(
config.custom_config_path, @machine.env.root_path)
remote_custom_config_path = File.join(
config.provisioning_path, "custom-config.rb")
@env[:machine].provider.driver.upload(expanded, remote_custom_config_path)
end
config_file = Vagrant::Util::TemplateRenderer.render(template, {
:custom_configuration => remote_custom_config_path,
:file_cache_path => config.file_cache_path,
:file_backup_path => config.file_backup_path,
:log_level => config.log_level.to_sym,
:verbose_logging => config.verbose_logging,
:http_proxy => config.http_proxy,
:http_proxy_user => config.http_proxy_user,
:http_proxy_pass => config.http_proxy_pass,
:https_proxy => config.https_proxy,
:https_proxy_user => config.https_proxy_user,
:https_proxy_pass => config.https_proxy_pass,
:no_proxy => config.no_proxy,
:formatter => config.formatter
}.merge(template_vars))
# Create a temporary file to store the data so we can upload it
temp = Tempfile.new("vagrant")
temp.write(config_file)
temp.close
remote_file = File.join(config.provisioning_path, filename)
@env[:machine].provider.driver.upload(temp.path, remote_file)
end
def run_chef_solo
if config.run_list && config.run_list.empty?
@env[:machine].ui.warn(I18n.t("vagrant.chef_run_list_empty"))
end
options = [
"-c #{config.provisioning_path}/solo.rb",
"-j #{config.provisioning_path}/dna.json"
]
command_env = config.binary_env ? "#{config.binary_env} " : ""
command_args = config.arguments ? " #{config.arguments}" : ""
command = "#{command_env}#{chef_binary_path("chef-solo")} " +
"#{options.join(" ")} #{command_args}"
config.attempts.times do |attempt|
if attempt == 0
@env[:machine].env.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
else
@env[:machine].env.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again")
end
command
@env[:machine].provider.driver.run_remote_ps(command) do |type, data|
# Output the data with the proper color based on the stream.
if (type == :stdout || type == :stderr)
@env[:ui].detail data
end
end
end
end
def upload_encrypted_data_bag_secret
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.upload_encrypted_data_bag_secret_key")
@env[:machine].provider.driver.upload(encrypted_data_bag_secret_key_path,
config.encrypted_data_bag_secret)
end
def encrypted_data_bag_secret_key_path
File.expand_path(config.encrypted_data_bag_secret_key_path, @env[:machine].env.root_path)
end
def config
provisioner.config
end
def guest_paths(folders)
folders.map { |parts| parts[2] }
end
# Returns the path to the Chef binary, taking into account the
# `binary_path` configuration option.
def chef_binary_path(binary)
return binary if !config.binary_path
return File.join(config.binary_path, binary)
end
def copy_folder_to_guest(folders)
folders.each do |type, local_path, remote_path|
if type == :host
@env[:machine].provider.driver.upload(local_path, remote_path)
end
end
end
end
end
end
end

Просмотреть файл

@ -0,0 +1,83 @@
#---------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the Apache 2.0 License.
#---------------------------------------------------------------------------
module VagrantPlugins
module WinAzure
module Provisioner
class Shell
attr_reader :provisioner
def initialize(env)
@env = env
@provisioner = env[:provisioner]
end
def provision_for_windows
arguments = ''
arguments = "#{config.args}" if config.args
with_windows_script_file do |path|
guest_path = if File.extname(config.upload_path) == ''
"#{config.upload_path}#{File.extname(path.to_s)}"
else
config.upload_path
end
@env[:ui].detail "Uploading [#{path}] to [#{guest_path}]"
response = @env[:machine].provider.driver.upload(path, guest_path)
command = "powershell.exe #{guest_path} #{arguments}"
@env[:machine].provider.driver.run_remote_ps(
command
) do |type, data|
if type == :stdout || type == :stderr
@env[:ui].detail data
end
end
end
end
protected
def config
provisioner.config
end
def with_windows_script_file
if config.remote?
download_path = @env[:machine].env.tmp_path.join(
"#{env[:mahine].id}-remote-script#{File.extname(config.path)}"
)
download_path.delete if download_path.file?
begin
Vagrant::Util::Downloader.new(
config.path, download_path
).download!
yield download_path
ensure
download_path.delete
end
elsif config.path
yield config.path
else
# We have an inline script. Create a temp file and handle it.
file = Tempfile.new(['vagrant-powershell', '.ps1'])
begin
file.write(config.inline)
file.fsync
file.close
yield file.path
ensure
file.close
end
end
end
end
end
end
end

Просмотреть файл

@ -12,3 +12,5 @@ en:
RDP not ready
vm_started: |-
VM '%{name}' has been started
vm_stopped: |-
VM '%{name}' has been stopped

Просмотреть файл

@ -0,0 +1,51 @@
require 'chef/version_constraint'
<% if node_name %>
node_name "<%= node_name %>"
<% end %>
file_cache_path "<%= file_cache_path %>"
file_backup_path "<%= file_backup_path %>"
cookbook_path <%= cookbooks_path.inspect %>
<% if roles_path %>
if Chef::VersionConstraint.new("< 11.8.0").include?(Chef::VERSION)
role_path <%= roles_path.first.inspect %>
else
role_path <%= roles_path.inspect %>
end
<% end %>
log_level <%= log_level.inspect %>
verbose_logging <%= verbose_logging.inspect %>
encrypted_data_bag_secret <%= encrypted_data_bag_secret.inspect %>
<% if data_bags_path -%>
data_bag_path <%= data_bags_path.inspect %>
<% end %>
<% if recipe_url -%>
recipe_url "<%= recipe_url %>"
<% end -%>
<% if environments_path %>
environment_path <%= environments_path.inspect %>
<% end -%>
<% if environment %>
environment "<%= environment %>"
<% end -%>
http_proxy <%= http_proxy.inspect %>
http_proxy_user <%= http_proxy_user.inspect %>
http_proxy_pass <%= http_proxy_pass.inspect %>
https_proxy <%= https_proxy.inspect %>
https_proxy_user <%= https_proxy_user.inspect %>
https_proxy_pass <%= https_proxy_pass.inspect %>
no_proxy <%= no_proxy.inspect %>
<% if formatter %>
add_formatter "<%= formatter %>"
<% end %>
<% if custom_configuration -%>
Chef::Config.from_file "<%= custom_configuration %>"
<% end -%>