зеркало из https://github.com/Azure/vagrant-azure.git
Merge branch 'chef-solo and shell-provisioning'
This commit is contained in:
Коммит
11c79fd994
|
@ -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/
|
||||
|
|
12
README.md
12
README.md
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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 -%>
|
Загрузка…
Ссылка в новой задаче