core: provision "once" or "always" [GH-2421]
This commit is contained in:
parent
f6fb9016a1
commit
aad8e7f80d
|
@ -5,6 +5,9 @@ FEATURES:
|
||||||
- Can now specify a `post_up_message` in your Vagrantfile that is shown
|
- Can now specify a `post_up_message` in your Vagrantfile that is shown
|
||||||
after a `vagrant up`. This is useful for putting some instructions of how
|
after a `vagrant up`. This is useful for putting some instructions of how
|
||||||
to use the development environment.
|
to use the development environment.
|
||||||
|
- Can configure provisioners to run "once" or "always" (defaults to "once"),
|
||||||
|
so that subsequent `vagrant up` or `reload` calls will always run a
|
||||||
|
provisioner. [GH-2421]
|
||||||
|
|
||||||
## 1.5.4 (April 21, 2014)
|
## 1.5.4 (April 21, 2014)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Vagrant
|
||||||
# This returns all the instances of the configured provisioners.
|
# This returns all the instances of the configured provisioners.
|
||||||
# This is safe to call multiple times since it will cache the results.
|
# This is safe to call multiple times since it will cache the results.
|
||||||
#
|
#
|
||||||
# @return [Array<Provisioner>]
|
# @return [Array<Provisioner, Hash>]
|
||||||
def provisioner_instances(env)
|
def provisioner_instances(env)
|
||||||
return @_provisioner_instances if @_provisioner_instances
|
return @_provisioner_instances if @_provisioner_instances
|
||||||
|
|
||||||
|
@ -21,8 +21,13 @@ module Vagrant
|
||||||
# Store in the type map so that --provision-with works properly
|
# Store in the type map so that --provision-with works properly
|
||||||
@_provisioner_types[result] = provisioner.name
|
@_provisioner_types[result] = provisioner.name
|
||||||
|
|
||||||
|
# Build up the options
|
||||||
|
options = {
|
||||||
|
run: provisioner.run,
|
||||||
|
}
|
||||||
|
|
||||||
# Return the result
|
# Return the result
|
||||||
result
|
[result, options]
|
||||||
end
|
end
|
||||||
|
|
||||||
return @_provisioner_instances
|
return @_provisioner_instances
|
||||||
|
|
|
@ -22,8 +22,12 @@ module Vagrant
|
||||||
def call(env)
|
def call(env)
|
||||||
@env = env
|
@env = env
|
||||||
|
|
||||||
|
# Tracks whether we were configured to provision
|
||||||
|
config_enabled = true
|
||||||
|
config_enabled = env[:provision_enabled] if env.has_key?(:provision_enabled)
|
||||||
|
|
||||||
# Check if we already provisioned, and if so, disable the rest
|
# Check if we already provisioned, and if so, disable the rest
|
||||||
enabled = true
|
sentinel_enabled = true
|
||||||
|
|
||||||
ignore_sentinel = true
|
ignore_sentinel = true
|
||||||
if env.has_key?(:provision_ignore_sentinel)
|
if env.has_key?(:provision_ignore_sentinel)
|
||||||
|
@ -52,11 +56,11 @@ module Vagrant
|
||||||
|
|
||||||
if parts.length == 1
|
if parts.length == 1
|
||||||
@logger.info("Old-style sentinel found! Not provisioning.")
|
@logger.info("Old-style sentinel found! Not provisioning.")
|
||||||
enabled = false
|
sentinel_enabled = false
|
||||||
update_sentinel = true
|
update_sentinel = true
|
||||||
elsif parts[0] == "1.5" && parts[1] == env[:machine].id.to_s
|
elsif parts[0] == "1.5" && parts[1] == env[:machine].id.to_s
|
||||||
@logger.info("Sentinel found! Not provisioning.")
|
@logger.info("Sentinel found! Not provisioning.")
|
||||||
enabled = false
|
sentinel_enabled = false
|
||||||
else
|
else
|
||||||
@logger.info("Sentinel found with another machine ID. Removing.")
|
@logger.info("Sentinel found with another machine ID. Removing.")
|
||||||
sentinel_path.unlink
|
sentinel_path.unlink
|
||||||
|
@ -65,10 +69,10 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
# Store the value so that other actions can use it
|
# Store the value so that other actions can use it
|
||||||
env[:provision_enabled] = enabled if !env.has_key?(:provision_enabled)
|
env[:provision_enabled] = sentinel_enabled if !env.has_key?(:provision_enabled)
|
||||||
|
|
||||||
# Ask the provisioners to modify the configuration if needed
|
# Ask the provisioners to modify the configuration if needed
|
||||||
provisioner_instances(env).each do |p|
|
provisioner_instances(env).each do |p, _|
|
||||||
p.configure(env[:machine].config)
|
p.configure(env[:machine].config)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -85,27 +89,37 @@ module Vagrant
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Actually provision if we enabled it
|
# If we're configured to not provision, notify the user and stop
|
||||||
if env[:provision_enabled]
|
if !config_enabled
|
||||||
type_map = provisioner_type_map(env)
|
env[:ui].info(I18n.t("vagrant.actions.vm.provision.disabled_by_config"))
|
||||||
provisioner_instances(env).each do |p|
|
return
|
||||||
type_name = type_map[p]
|
end
|
||||||
next if env[:provision_types] && \
|
|
||||||
!env[:provision_types].include?(type_name)
|
|
||||||
|
|
||||||
env[:ui].info(I18n.t(
|
# If we're not provisioning because of the sentinel, tell the user
|
||||||
"vagrant.actions.vm.provision.beginning",
|
# but continue trying for the "always" provisioners
|
||||||
provisioner: type_name))
|
if !sentinel_enabled
|
||||||
|
|
||||||
env[:hook].call(:provisioner_run, env.merge(
|
|
||||||
callable: method(:run_provisioner),
|
|
||||||
provisioner: p,
|
|
||||||
provisioner_name: type_name,
|
|
||||||
))
|
|
||||||
end
|
|
||||||
elsif !enabled
|
|
||||||
env[:ui].info(I18n.t("vagrant.actions.vm.provision.disabled_by_sentinel"))
|
env[:ui].info(I18n.t("vagrant.actions.vm.provision.disabled_by_sentinel"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
type_map = provisioner_type_map(env)
|
||||||
|
provisioner_instances(env).each do |p, options|
|
||||||
|
type_name = type_map[p]
|
||||||
|
next if env[:provision_types] && \
|
||||||
|
!env[:provision_types].include?(type_name)
|
||||||
|
|
||||||
|
# Don't run if sentinel is around and we're not always running
|
||||||
|
next if !sentinel_enabled && options[:run] != :always
|
||||||
|
|
||||||
|
env[:ui].info(I18n.t(
|
||||||
|
"vagrant.actions.vm.provision.beginning",
|
||||||
|
provisioner: type_name))
|
||||||
|
|
||||||
|
env[:hook].call(:provisioner_run, env.merge(
|
||||||
|
callable: method(:run_provisioner),
|
||||||
|
provisioner: p,
|
||||||
|
provisioner_name: type_name,
|
||||||
|
))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is pulled out into a seperate method so that users can
|
# This is pulled out into a seperate method so that users can
|
||||||
|
|
|
@ -30,7 +30,7 @@ module Vagrant
|
||||||
type_map = provisioner_type_map(env)
|
type_map = provisioner_type_map(env)
|
||||||
|
|
||||||
# Ask the provisioners to modify the configuration if needed
|
# Ask the provisioners to modify the configuration if needed
|
||||||
provisioner_instances(env).each do |p|
|
provisioner_instances(env).each do |p, _|
|
||||||
env[:ui].info(I18n.t(
|
env[:ui].info(I18n.t(
|
||||||
"vagrant.provisioner_cleanup",
|
"vagrant.provisioner_cleanup",
|
||||||
name: type_map[p].to_s))
|
name: type_map[p].to_s))
|
||||||
|
|
|
@ -126,6 +126,7 @@ module VagrantPlugins
|
||||||
if other_p
|
if other_p
|
||||||
# There is an override. Take it.
|
# There is an override. Take it.
|
||||||
other_p.config = p.config.merge(other_p.config)
|
other_p.config = p.config.merge(other_p.config)
|
||||||
|
other_p.run ||= p.run
|
||||||
next if !other_p.preserve_order
|
next if !other_p.preserve_order
|
||||||
|
|
||||||
# We're preserving order, delete from other
|
# We're preserving order, delete from other
|
||||||
|
@ -269,6 +270,7 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
prov.preserve_order = !!options[:preserve_order]
|
prov.preserve_order = !!options[:preserve_order]
|
||||||
|
prov.run = options.delete(:run) if options.has_key?(:run)
|
||||||
prov.add_config(options, &block)
|
prov.add_config(options, &block)
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -395,6 +397,7 @@ module VagrantPlugins
|
||||||
# Finalize all the provisioners
|
# Finalize all the provisioners
|
||||||
@provisioners.each do |p|
|
@provisioners.each do |p|
|
||||||
p.config.finalize! if !p.invalid?
|
p.config.finalize! if !p.invalid?
|
||||||
|
p.run = p.run.to_sym if p.run
|
||||||
end
|
end
|
||||||
|
|
||||||
# If we didn't share our current directory, then do it
|
# If we didn't share our current directory, then do it
|
||||||
|
|
|
@ -20,6 +20,11 @@ module VagrantPlugins
|
||||||
# @return [Object]
|
# @return [Object]
|
||||||
attr_accessor :config
|
attr_accessor :config
|
||||||
|
|
||||||
|
# When to run this provisioner. Either "once" or "always"
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
attr_accessor :run
|
||||||
|
|
||||||
# Whether or not to preserve the order when merging this with a
|
# Whether or not to preserve the order when merging this with a
|
||||||
# parent scope.
|
# parent scope.
|
||||||
#
|
#
|
||||||
|
@ -35,6 +40,7 @@ module VagrantPlugins
|
||||||
@invalid = false
|
@invalid = false
|
||||||
@name = name
|
@name = name
|
||||||
@preserve_order = false
|
@preserve_order = false
|
||||||
|
@run = nil
|
||||||
|
|
||||||
# Attempt to find the provisioner...
|
# Attempt to find the provisioner...
|
||||||
if !Vagrant.plugin("2").manager.provisioners[name]
|
if !Vagrant.plugin("2").manager.provisioners[name]
|
||||||
|
|
|
@ -1490,8 +1490,11 @@ en:
|
||||||
mounting: Mounting NFS shared folders...
|
mounting: Mounting NFS shared folders...
|
||||||
provision:
|
provision:
|
||||||
beginning: "Running provisioner: %{provisioner}..."
|
beginning: "Running provisioner: %{provisioner}..."
|
||||||
|
disabled_by_config: |-
|
||||||
|
Machine not provisioning because `--no-provision` is specified.
|
||||||
disabled_by_sentinel: |-
|
disabled_by_sentinel: |-
|
||||||
VM already provisioned. Run `vagrant provision` or use `--provision` to force it
|
Machine already provisioned. Run `vagrant provision` or use the `--provision`
|
||||||
|
to force provisioning. Provisioners marked to run always will still run.
|
||||||
resume:
|
resume:
|
||||||
resuming: Resuming suspended VM...
|
resuming: Resuming suspended VM...
|
||||||
unpausing: |-
|
unpausing: |-
|
||||||
|
|
|
@ -214,14 +214,16 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
|
||||||
describe "#provision" do
|
describe "#provision" do
|
||||||
it "stores the provisioners" do
|
it "stores the provisioners" do
|
||||||
subject.provision("shell", inline: "foo")
|
subject.provision("shell", inline: "foo")
|
||||||
subject.provision("shell", inline: "bar") { |s| s.path = "baz" }
|
subject.provision("shell", inline: "bar", run: "always") { |s| s.path = "baz" }
|
||||||
subject.finalize!
|
subject.finalize!
|
||||||
|
|
||||||
r = subject.provisioners
|
r = subject.provisioners
|
||||||
expect(r.length).to eql(2)
|
expect(r.length).to eql(2)
|
||||||
|
expect(r[0].run).to be_nil
|
||||||
expect(r[0].config.inline).to eql("foo")
|
expect(r[0].config.inline).to eql("foo")
|
||||||
expect(r[1].config.inline).to eql("bar")
|
expect(r[1].config.inline).to eql("bar")
|
||||||
expect(r[1].config.path).to eql("baz")
|
expect(r[1].config.path).to eql("baz")
|
||||||
|
expect(r[1].run).to eql(:always)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows provisioner settings to be overriden" do
|
it "allows provisioner settings to be overriden" do
|
||||||
|
@ -264,6 +266,20 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "merging" do
|
describe "merging" do
|
||||||
|
it "ignores non-overriding runs" do
|
||||||
|
subject.provision("shell", inline: "foo", run: "once")
|
||||||
|
|
||||||
|
other = described_class.new
|
||||||
|
other.provision("shell", inline: "bar", run: "always")
|
||||||
|
|
||||||
|
merged = subject.merge(other)
|
||||||
|
merged_provs = merged.provisioners
|
||||||
|
|
||||||
|
expect(merged_provs.length).to eql(2)
|
||||||
|
expect(merged_provs[0].run).to eq("once")
|
||||||
|
expect(merged_provs[1].run).to eq("always")
|
||||||
|
end
|
||||||
|
|
||||||
it "copies the configs" do
|
it "copies the configs" do
|
||||||
subject.provision("shell", inline: "foo")
|
subject.provision("shell", inline: "foo")
|
||||||
subject_provs = subject.provisioners
|
subject_provs = subject.provisioners
|
||||||
|
|
Loading…
Reference in New Issue