vagrant-dsc 1.0.9 → 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4b6efc99d9b93981b271840132718d939117be3
4
- data.tar.gz: 3696ac715f5a013f3b8b4ffba17a2974423ca0ab
3
+ metadata.gz: f7a7b684574c26b5bcf147def321de8149691c22
4
+ data.tar.gz: 74830fc81b58b8b334a6023d6354580f29b995eb
5
5
  SHA512:
6
- metadata.gz: b49654d807da8cfa54dc7c4f727f3cc6d1fd2bc2b9b5f9e4e3cc006581a8df57214486e459f9207a75b97e9ff71b031dd19d5e4356fc2863bb7134cc62c68352
7
- data.tar.gz: b481a266b8541979cf98275a07bb7be67cc16e8b205f89af7d984b29250330bc7d0d22b245cfc492aea3dd1be7cf629f74f357f76f2be416420105e4cdb5ec13
6
+ metadata.gz: b13745414a9573bcb4d18f2175a17fecd952d4e8359d0b370d2b1e0c6af580a6697cb3c5a54692d109123954e8f1119b2aa46f7ea7ff5a3dcd258df4edc73172
7
+ data.tar.gz: 7eb8afd365a96f8932ef9d00979a264972eeb22124a60cf01a98da23cab8725d6848cf9b4077f63e8ead2706abc4e5e6e97de4f1475e48b83fe86537b16b16a8
data/README.md CHANGED
@@ -85,8 +85,9 @@ Vagrant DSC will create and manage it for you automatically.
85
85
 
86
86
  ## Example
87
87
 
88
- There is a [sample](https://github.com/mefellows/vagrant-dsc/tree/master/development) Vagrant setup used for development of this plugin.
89
- This is a great real-life example to get you on your way.
88
+ There is a [sample](https://github.com/mefellows/vagrant-dsc/tree/master/development/web)
89
+ Vagrant setup used for development of this plugin. This is a great real-life example
90
+ to get you on your way.
90
91
 
91
92
  ## Creating Windows Vagrant boxes
92
93
 
@@ -120,7 +121,7 @@ We may consider automatically installing and configuring DSC in a future release
120
121
 
121
122
  ## Development
122
123
 
123
- Before getting started, read the Vagrant plugin [development basics](https://docs.vagrantup.com/v2/plugins/development-basics.html) and [packaging](https://docs.vagrantup.com/v2/plugins/packaging.html] documentation.
124
+ Before getting started, read the Vagrant plugin [development basics](https://docs.vagrantup.com/v2/plugins/development-basics.html) and [packaging](https://docs.vagrantup.com/v2/plugins/packaging.html) documentation.
124
125
 
125
126
  You will need Ruby 1.9.3+ and Bundler installed before proceeding.
126
127
 
data/appveyor.yml ADDED
@@ -0,0 +1,13 @@
1
+ install:
2
+ - set PATH=C:\Ruby22\bin;%PATH%
3
+ - bundle install
4
+
5
+ build: off
6
+
7
+ before_test:
8
+ - ruby -v
9
+ - gem -v
10
+ - bundle -v
11
+
12
+ test_script:
13
+ - bundle exec rake spec
@@ -0,0 +1,35 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ $shell_script = <<SCRIPT
5
+ # config desired state
6
+ . C:\\vagrant\\manifests\\LCMConfig.ps1
7
+ LCMConfig
8
+ Set-DscLocalConfigurationManager -Path ".\\LCMConfig"
9
+ SCRIPT
10
+
11
+ VAGRANTFILE_API_VERSION = "2"
12
+
13
+ # linked clone feature requires 1.8
14
+ Vagrant.require_version ">= 1.8"
15
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
16
+ config.vm.box = "mwrock/Windows2016"
17
+ config.vm.guest = :windows
18
+ config.vm.communicator = "winrm"
19
+
20
+ # we do not need, the following config, but gives some convenience
21
+ config.vm.provider "virtualbox" do |v|
22
+ # Link clone, get a faster up after destroy
23
+ v.linked_clone = true
24
+ # Get the clipboard to interact with host
25
+ v.customize ["modifyvm", :id, "--clipboard", "bidirectional"]
26
+ end
27
+
28
+ config.vm.provision "shell", inline: $shell_script
29
+
30
+ config.vm.provision "dsc" do |dsc|
31
+ dsc.configuration_file = "Reboot.ps1"
32
+ dsc.configuration_name = "Reboot"
33
+ dsc.manifests_path = "manifests"
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ [DSCLocalConfigurationManager()]
2
+ configuration LCMConfig
3
+ {
4
+ Node localhost
5
+ {
6
+ Settings
7
+ {
8
+ RebootNodeIfNeeded = $true
9
+ ActionAfterReboot = "ContinueConfiguration"
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,30 @@
1
+ Configuration Reboot
2
+ {
3
+ Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
4
+
5
+ Script Reboot
6
+ {
7
+ TestScript = {
8
+ return (Test-Path HKLM:\SOFTWARE\MyMainKey\RebootKey)
9
+ }
10
+ SetScript = {
11
+ New-Item -Path HKLM:\SOFTWARE\MyMainKey\RebootKey -Force
12
+ $global:DSCMachineStatus = 1
13
+
14
+ }
15
+ GetScript = { return @{result = 'result'}}
16
+ }
17
+
18
+ Script Error
19
+ {
20
+ TestScript = {
21
+ throw "This did not work"
22
+ return $true
23
+ }
24
+ SetScript = {
25
+
26
+ }
27
+ GetScript = { return @{result = 'result'}}
28
+ DependsOn = "[Script]Reboot"
29
+ }
30
+ }
File without changes
File without changes
@@ -38,3 +38,5 @@ en:
38
38
  "Operation unsupported / not-yet implemented: %{operation}"
39
39
  absolute_module_path: |-
40
40
  "Absolute 'module_path' not allowed. Please provide a path relative to your Vagrantfile."
41
+ failure_status: |-
42
+ "DSC Status is \"Failure\"."
@@ -1,5 +1,6 @@
1
1
  require "log4r"
2
2
  require 'erb'
3
+ require "vagrant/util/powershell"
3
4
 
4
5
  module VagrantPlugins
5
6
  module DSC
@@ -99,6 +100,51 @@ module VagrantPlugins
99
100
  write_dsc_runner_script(generate_dsc_runner_script)
100
101
 
101
102
  run_dsc_apply
103
+
104
+ wait_for_dsc_completion
105
+ end
106
+
107
+ # Waits for the completion of the dsc configuration if dsc needs reboots. This currntly only works for WMF5 and needs wait_for_reboot
108
+ def wait_for_dsc_completion
109
+ return if Vagrant::Util::PowerShell.version.to_i < 5 || !@machine.guest.capability?(:wait_for_reboot)
110
+
111
+ dsc_running = true
112
+
113
+ while dsc_running
114
+ case get_lcm_state
115
+ when "PendingReboot"
116
+ @machine.ui.info("DSC needs reboot. Wait for the completion of DSC.")
117
+ @machine.guest.capability(:wait_for_reboot)
118
+
119
+ # Do not Know a way to reattch to dsc job, therefore check periodically the state
120
+ when "Busy"
121
+ sleep 10
122
+ else
123
+ dsc_running = false
124
+ end
125
+ end
126
+
127
+ if (get_configuration_status == "Failure")
128
+ @machine.ui.error(I18n.t("failure_status"))
129
+ show_dsc_failure_message
130
+ end
131
+ end
132
+
133
+ def get_lcm_state
134
+ state = @machine.communicate.shell.powershell("(Get-DscLocalConfigurationManager).LCMState")
135
+ return state[:data][0][:stdout]
136
+ end
137
+
138
+ def get_configuration_status
139
+ status = @machine.communicate.shell.powershell("(Get-DscConfigurationStatus).Status")
140
+ return status[:data][0][:stdout]
141
+ end
142
+
143
+ def show_dsc_failure_message
144
+ dsc_error_ps = "Get-WinEvent \"Microsoft-Windows-Dsc/Operational\" | Where-Object {$_.LevelDisplayName -eq \"Error\" -and $_.Message.StartsWith(\"Job $((Get-DscConfigurationStatus).JobId)\" )} | foreach { $_.Message }"
145
+ @machine.communicate.shell.powershell(dsc_error_ps) do |type,data|
146
+ @machine.ui.error(data, prefix: false)
147
+ end
102
148
  end
103
149
 
104
150
  # Cleanup after a destroy action.
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
2
  module Dsc
3
- VERSION = "1.0.9"
3
+ VERSION = "1.0.10"
4
4
  end
5
5
  end
data/spec/base.rb CHANGED
@@ -40,7 +40,7 @@ shared_context "unit" do
40
40
  # Asserts that the current (config) validation should fail with a specific message.
41
41
  def assert_error(error)
42
42
  errors = subject.validate(machine)
43
- raise "Error #{error} was not raised" if !errors["dsc provisioner"].include? error
43
+ raise "Error #{error} was not raised" if !errors["dsc provisioner"].any? { |val| error =~ val }
44
44
  end
45
45
 
46
46
  # Asserts that no failures should occur in the current (config) validation run.
@@ -73,7 +73,7 @@ describe VagrantPlugins::DSC::Config do
73
73
  subject.finalize!
74
74
  subject.validate(machine)
75
75
 
76
- expect(subject.expanded_configuration_file.to_s).to eq("#{subject.temp_dir}/manifests/MyWebsite.ps1")
76
+ expect(subject.expanded_configuration_file.to_s).to match(/(C:)?#{subject.temp_dir}\/manifests\/MyWebsite.ps1$/)
77
77
  end
78
78
  end
79
79
 
@@ -98,37 +98,41 @@ describe VagrantPlugins::DSC::Config do
98
98
 
99
99
  it "should generate a module path on the host machine relative to the Vagrantfile" do
100
100
  subject.module_path = "foo/modules"
101
- expect(subject.expanded_module_paths('/path/to/vagrant/')).to eq(["/path/to/vagrant/foo/modules"])
101
+ expect(subject.expanded_module_paths('/path/to/vagrant/').length).to eq(1)
102
+ expect(subject.expanded_module_paths('/path/to/vagrant/')[0]).to match(/([Cc]:)?\/path\/to\/vagrant\/foo\/modules/)
102
103
  end
103
104
 
104
105
  it "should generate a module path on the host machine relative to the Vagrantfile with relative paths" do
105
106
  subject.module_path = "../modules"
106
- expect(subject.expanded_module_paths('/path/to/vagrant/')).to eq(["/path/to/modules"])
107
+ expect(subject.expanded_module_paths('/path/to/vagrant/').length).to eq(1)
108
+ expect(subject.expanded_module_paths('/path/to/vagrant/')[0]).to match(/([Cc]:)?\/path\/to\/modules/)
107
109
  end
108
110
 
109
111
  it "should generate module paths on the host machine relative to the Vagrantfile" do
110
112
  subject.module_path = ["dont/exist", "also/dont/exist"]
111
- expect(subject.expanded_module_paths('/path/to/vagrant/')).to eq(["/path/to/vagrant/dont/exist", "/path/to/vagrant/also/dont/exist"])
113
+ expect(subject.expanded_module_paths('/path/to/vagrant/').length).to eq(2)
114
+ expect(subject.expanded_module_paths('/path/to/vagrant/')[0]).to match(/([Cc]:)?\/path\/to\/vagrant\/dont\/exist/)
115
+ expect(subject.expanded_module_paths('/path/to/vagrant/')[1]).to match(/([Cc]:)?\/path\/to\/vagrant\/also\/dont\/exist/)
112
116
  end
113
117
 
114
118
  it "should be invalid if 'manifests_path' is not a real directory" do
115
119
  subject.manifests_path = "/i/do/not/exist"
116
120
  assert_invalid
117
- assert_error("\"Path to DSC Manifest folder does not exist: /i/do/not/exist\"")
121
+ assert_error(/\"Path to DSC Manifest folder does not exist: ([Cc]:)?\/i\/do\/not\/exist\"/)
118
122
  end
119
123
 
120
124
  it "should be invalid if 'configuration_file' is not a real file" do
121
125
  subject.manifests_path = "/"
122
126
  subject.configuration_file = "notexist.ps1"
123
127
  assert_invalid
124
- assert_error("\"Path to DSC Manifest does not exist: /notexist.ps1\"")
128
+ assert_error(/\"Path to DSC Manifest does not exist: ([Cc]:)?\/notexist.ps1\"/)
125
129
  end
126
130
 
127
131
  it "should be invalid if 'configuration_data_file' is not a real file" do
128
132
  subject.manifests_path = "/"
129
133
  subject.configuration_data_file = "/oeu/aoeu/notexist.psd1"
130
134
  assert_invalid
131
- assert_error("\"Path to DSC Configuration Data file does not exist: /oeu/aoeu/notexist.psd1\"")
135
+ assert_error(/\"Path to DSC Configuration Data file does not exist: ([Cc]:)?\/oeu\/aoeu\/notexist.psd1\"/)
132
136
  end
133
137
 
134
138
  it "should detect the fully qualified path to the configuration data file automatically" do
@@ -142,13 +146,13 @@ describe VagrantPlugins::DSC::Config do
142
146
  subject.finalize!
143
147
  subject.validate(machine)
144
148
 
145
- expect(subject.expanded_configuration_data_file.to_s).to eq("#{subject.temp_dir}/manifests/foo.psd1")
149
+ expect(subject.expanded_configuration_data_file.to_s).to match(/([Cc]:)?#{subject.temp_dir}\/manifests\/foo.psd1/)
146
150
  end
147
151
 
148
152
  it "should be invalid if 'module_path' is not a real directory" do
149
153
  subject.module_path = "/i/dont/exist"
150
154
  assert_invalid
151
- assert_error("\"Path to DSC Modules does not exist: /i/dont/exist\"")
155
+ assert_error(/\"Path to DSC Modules does not exist: ([Cc]:)?\/i\/dont\/exist\"/)
152
156
  end
153
157
 
154
158
  it "should be invalid if 'configuration_file' and 'mof_path' provided" do
@@ -133,6 +133,7 @@ describe VagrantPlugins::DSC::Provisioner do
133
133
  allow(subject).to receive(:verify_shared_folders).and_return(true)
134
134
  allow(subject).to receive(:verify_dsc).and_return(true)
135
135
  allow(subject).to receive(:run_dsc_apply).and_return(true)
136
+ allow(subject).to receive(:wait_for_dsc_completion)
136
137
  allow(guest).to receive(:capability?).with(:wait_for_reboot).and_return(true)
137
138
  expect(guest).to receive(:capability).with(:wait_for_reboot)
138
139
 
@@ -146,6 +147,7 @@ describe VagrantPlugins::DSC::Provisioner do
146
147
  allow(subject).to receive(:verify_shared_folders).and_return(true)
147
148
  allow(subject).to receive(:verify_dsc).and_return(true)
148
149
  allow(subject).to receive(:run_dsc_apply).and_return(true)
150
+ allow(subject).to receive(:wait_for_dsc_completion)
149
151
  allow(guest).to receive(:capability?).with(:wait_for_reboot).and_return(false)
150
152
  expect(guest).to_not receive(:capability).with(:wait_for_reboot)
151
153
 
@@ -158,6 +160,7 @@ describe VagrantPlugins::DSC::Provisioner do
158
160
  allow(subject).to receive(:verify_shared_folders).and_return(true)
159
161
  allow(subject).to receive(:verify_dsc).and_return(true)
160
162
  allow(subject).to receive(:run_dsc_apply).and_return(true)
163
+ allow(subject).to receive(:wait_for_dsc_completion)
161
164
  allow(guest).to receive(:capability?)
162
165
  allow(guest).to receive(:capability)
163
166
 
@@ -173,6 +176,7 @@ describe VagrantPlugins::DSC::Provisioner do
173
176
  allow(subject).to receive(:verify_shared_folders).and_return(true)
174
177
  allow(subject).to receive(:verify_dsc).and_return(true)
175
178
  allow(subject).to receive(:run_dsc_apply).and_return(true)
179
+ allow(subject).to receive(:wait_for_dsc_completion)
176
180
  allow(guest).to receive(:capability?)
177
181
  allow(guest).to receive(:capability)
178
182
 
@@ -191,6 +195,7 @@ describe VagrantPlugins::DSC::Provisioner do
191
195
  allow(communicator).to receive(:upload)
192
196
  allow(subject).to receive(:verify_dsc).and_return(true)
193
197
  allow(subject).to receive(:run_dsc_apply).and_return(true)
198
+ allow(subject).to receive(:wait_for_dsc_completion)
194
199
  allow(guest).to receive(:capability?)
195
200
  allow(guest).to receive(:capability)
196
201
 
@@ -200,6 +205,84 @@ describe VagrantPlugins::DSC::Provisioner do
200
205
  subject.provision
201
206
  end
202
207
 
208
+ it "should provision wait for dsc" do
209
+ allow(communicator).to receive(:sudo)
210
+ allow(communicator).to receive(:test)
211
+ allow(communicator).to receive(:upload)
212
+ allow(subject).to receive(:verify_shared_folders).and_return(true)
213
+ allow(subject).to receive(:verify_dsc).and_return(true)
214
+ allow(subject).to receive(:run_dsc_apply).and_return(true)
215
+ allow(guest).to receive(:capability?).with(:wait_for_reboot).and_return(true)
216
+ allow(guest).to receive(:capability).with(:wait_for_reboot)
217
+ expect(subject).to receive(:wait_for_dsc_completion)
218
+
219
+ subject.provision
220
+ end
221
+
222
+ it "should wait for pending reboot" do
223
+ allow_any_instance_of(Object).to receive(:sleep)
224
+ allow(guest).to receive(:capability?).with(:wait_for_reboot).and_return(true)
225
+ allow(communicator).to receive(:shell).and_return(shell)
226
+ allow(subject).to receive(:get_lcm_state).and_return("PendingReboot", "Busy", "Sucess")
227
+ allow(subject).to receive(:get_configuration_status).and_return("Sucess")
228
+ allow(Vagrant::Util::PowerShell).to receive(:version).and_return("5")
229
+ expect(guest).to receive(:capability).with(:wait_for_reboot)
230
+
231
+ subject.wait_for_dsc_completion
232
+ end
233
+
234
+ it "should wait for multi pending reboots" do
235
+ allow_any_instance_of(Object).to receive(:sleep)
236
+ allow(guest).to receive(:capability?).with(:wait_for_reboot).and_return(true)
237
+ allow(communicator).to receive(:shell).and_return(shell)
238
+ allow(subject).to receive(:get_lcm_state).and_return("PendingReboot", "Busy", "PendingReboot", "Busy", "Idle")
239
+ allow(subject).to receive(:get_configuration_status).and_return("Success")
240
+ allow(Vagrant::Util::PowerShell).to receive(:version).and_return("5")
241
+ expect(guest).to receive(:capability).twice.with(:wait_for_reboot)
242
+
243
+ subject.wait_for_dsc_completion
244
+ end
245
+
246
+ it "should show error message on failure" do
247
+ allow_any_instance_of(Object).to receive(:sleep)
248
+ allow(guest).to receive(:capability?).with(:wait_for_reboot).and_return(true)
249
+ allow(communicator).to receive(:shell).and_return(shell)
250
+ allow(guest).to receive(:capability).with(:wait_for_reboot)
251
+ allow(subject).to receive(:get_lcm_state).and_return("PendingReboot", "Busy", "PendingConfiguration")
252
+ allow(subject).to receive(:get_configuration_status).and_return("Failure")
253
+ allow(Vagrant::Util::PowerShell).to receive(:version).and_return("5")
254
+ expect(subject).to receive(:show_dsc_failure_message)
255
+
256
+ subject.wait_for_dsc_completion
257
+ end
258
+
259
+ it "should get the lcm state" do
260
+ allow(communicator).to receive(:shell).and_return(shell)
261
+ expect(shell).to receive(:powershell).with("(Get-DscLocalConfigurationManager).LCMState").and_return({:data => [{:stdout => "LCMState"}]})
262
+
263
+ expect(subject.get_lcm_state).to eq("LCMState")
264
+ end
265
+
266
+ it "should get the configuration status" do
267
+ allow(communicator).to receive(:shell).and_return(shell)
268
+ expect(shell).to receive(:powershell).with("(Get-DscConfigurationStatus).Status").and_return({:data => [{:stdout => "Status"}]})
269
+
270
+ expect(subject.get_configuration_status).to eq("Status")
271
+ end
272
+
273
+ it "should get the dsc error message" do
274
+ allow(communicator).to receive(:shell).and_return(shell)
275
+ expect(shell).to receive(:powershell)
276
+ .with("Get-WinEvent \"Microsoft-Windows-Dsc/Operational\" | Where-Object {$_.LevelDisplayName -eq \"Error\" -and $_.Message.StartsWith(\"Job $((Get-DscConfigurationStatus).JobId)\" )} | foreach { $_.Message }")
277
+ .and_yield(:stdout, "\r\n")
278
+ .and_yield(:stdout, "\r\n")
279
+ .and_yield(:stdout, "Job AE9233FD-8491-11E6-9810-080027F3ADE1} : \r\n MIResult: 1\r\n")
280
+ expect(ui).to receive(:error).with("\r\n", :prefix=>false).twice
281
+ expect(ui).to receive(:error).with("Job AE9233FD-8491-11E6-9810-080027F3ADE1} : \r\n MIResult: 1\r\n", :prefix=>false)
282
+
283
+ subject.show_dsc_failure_message
284
+ end
285
+
203
286
  it "should verify DSC binary exists" do
204
287
  expect(communicator).to receive(:sudo).with("which Start-DscConfiguration", {:error_class=>VagrantPlugins::DSC::DSCError, :error_key=>:dsc_not_detected, :binary=>"Start-DscConfiguration"})
205
288
  subject.verify_binary("Start-DscConfiguration")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-dsc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.9
4
+ version: 1.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Fellows
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-30 00:00:00.000000000 Z
11
+ date: 2016-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -108,13 +108,17 @@ files:
108
108
  - LICENSE.txt
109
109
  - README.md
110
110
  - Rakefile
111
- - development/Vagrantfile
112
- - development/manifests/MyConfig.psd1
113
- - development/manifests/MyWebsite.ps1
114
- - development/modules/MyWebapp/DSCResources/SimpleWebsite/SimpleWebsite.psd1
115
- - development/modules/MyWebapp/DSCResources/SimpleWebsite/SimpleWebsite.schema.psm1
116
- - development/modules/MyWebapp/MyWebapp.psd1
117
- - development/website/index.html
111
+ - appveyor.yml
112
+ - development/reboot/Vagrantfile
113
+ - development/reboot/manifests/LCMConfig.ps1
114
+ - development/reboot/manifests/Reboot.ps1
115
+ - development/web/Vagrantfile
116
+ - development/web/manifests/MyConfig.psd1
117
+ - development/web/manifests/MyWebsite.ps1
118
+ - development/web/modules/MyWebapp/DSCResources/SimpleWebsite/SimpleWebsite.psd1
119
+ - development/web/modules/MyWebapp/DSCResources/SimpleWebsite/SimpleWebsite.schema.psm1
120
+ - development/web/modules/MyWebapp/MyWebapp.psd1
121
+ - development/web/website/index.html
118
122
  - lib/vagrant-dsc.rb
119
123
  - lib/vagrant-dsc/config.rb
120
124
  - lib/vagrant-dsc/locales/en.yml
@@ -148,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
152
  version: '0'
149
153
  requirements: []
150
154
  rubyforge_project:
151
- rubygems_version: 2.4.8
155
+ rubygems_version: 2.4.6
152
156
  signing_key:
153
157
  specification_version: 4
154
158
  summary: DSC Provisioner for Vagrant