vagrantup 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/README.md +2 -2
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/config/default.rb +13 -3
  7. data/lib/vagrant.rb +10 -13
  8. data/lib/vagrant/actions/base.rb +14 -2
  9. data/lib/vagrant/actions/box/download.rb +2 -7
  10. data/lib/vagrant/actions/box/verify.rb +1 -1
  11. data/lib/vagrant/actions/runner.rb +0 -1
  12. data/lib/vagrant/actions/vm/boot.rb +2 -6
  13. data/lib/vagrant/actions/vm/customize.rb +7 -5
  14. data/lib/vagrant/actions/vm/destroy.rb +4 -3
  15. data/lib/vagrant/actions/vm/down.rb +6 -3
  16. data/lib/vagrant/actions/vm/export.rb +2 -4
  17. data/lib/vagrant/actions/vm/forward_ports.rb +77 -16
  18. data/lib/vagrant/actions/vm/halt.rb +10 -2
  19. data/lib/vagrant/actions/vm/import.rb +2 -4
  20. data/lib/vagrant/actions/vm/move_hard_drive.rb +2 -2
  21. data/lib/vagrant/actions/vm/network.rb +120 -0
  22. data/lib/vagrant/actions/vm/package.rb +11 -7
  23. data/lib/vagrant/actions/vm/provision.rb +3 -3
  24. data/lib/vagrant/actions/vm/reload.rb +2 -9
  25. data/lib/vagrant/actions/vm/shared_folders.rb +19 -39
  26. data/lib/vagrant/actions/vm/start.rb +10 -2
  27. data/lib/vagrant/actions/vm/up.rb +5 -6
  28. data/lib/vagrant/active_list.rb +23 -13
  29. data/lib/vagrant/box.rb +2 -2
  30. data/lib/vagrant/busy.rb +3 -3
  31. data/lib/vagrant/command.rb +2 -2
  32. data/lib/vagrant/commands/base.rb +40 -20
  33. data/lib/vagrant/commands/destroy.rb +17 -3
  34. data/lib/vagrant/commands/halt.rb +23 -3
  35. data/lib/vagrant/commands/package.rb +54 -14
  36. data/lib/vagrant/commands/provision.rb +31 -0
  37. data/lib/vagrant/commands/reload.rb +16 -3
  38. data/lib/vagrant/commands/resume.rb +16 -3
  39. data/lib/vagrant/commands/ssh.rb +25 -3
  40. data/lib/vagrant/commands/ssh_config.rb +20 -5
  41. data/lib/vagrant/commands/status.rb +107 -40
  42. data/lib/vagrant/commands/suspend.rb +16 -3
  43. data/lib/vagrant/commands/up.rb +26 -7
  44. data/lib/vagrant/config.rb +82 -12
  45. data/lib/vagrant/downloaders/base.rb +8 -1
  46. data/lib/vagrant/downloaders/http.rb +31 -19
  47. data/lib/vagrant/environment.rb +146 -49
  48. data/lib/vagrant/provisioners/base.rb +19 -5
  49. data/lib/vagrant/provisioners/chef.rb +12 -4
  50. data/lib/vagrant/provisioners/chef_server.rb +13 -6
  51. data/lib/vagrant/provisioners/chef_solo.rb +7 -3
  52. data/lib/vagrant/resource_logger.rb +126 -0
  53. data/lib/vagrant/ssh.rb +109 -8
  54. data/lib/vagrant/systems/base.rb +70 -0
  55. data/lib/vagrant/systems/linux.rb +137 -0
  56. data/lib/vagrant/util.rb +1 -45
  57. data/lib/vagrant/util/error_helper.rb +13 -0
  58. data/lib/vagrant/util/glob_loader.rb +22 -0
  59. data/lib/vagrant/util/output_helper.rb +9 -0
  60. data/lib/vagrant/util/plain_logger.rb +12 -0
  61. data/lib/vagrant/util/platform.rb +7 -2
  62. data/lib/vagrant/util/template_renderer.rb +2 -2
  63. data/lib/vagrant/util/translator.rb +35 -0
  64. data/lib/vagrant/vm.rb +91 -10
  65. data/templates/crontab_entry.erb +1 -0
  66. data/templates/network_entry.erb +8 -0
  67. data/templates/ssh_config.erb +1 -0
  68. data/templates/{errors.yml → strings.yml} +111 -3
  69. data/templates/sync.erb +14 -0
  70. data/test/test_helper.rb +46 -3
  71. data/test/vagrant/actions/box/download_test.rb +0 -17
  72. data/test/vagrant/actions/vm/boot_test.rb +3 -10
  73. data/test/vagrant/actions/vm/customize_test.rb +6 -0
  74. data/test/vagrant/actions/vm/destroy_test.rb +6 -5
  75. data/test/vagrant/actions/vm/down_test.rb +5 -11
  76. data/test/vagrant/actions/vm/export_test.rb +1 -0
  77. data/test/vagrant/actions/vm/forward_ports_test.rb +92 -15
  78. data/test/vagrant/actions/vm/halt_test.rb +36 -4
  79. data/test/vagrant/actions/vm/import_test.rb +2 -0
  80. data/test/vagrant/actions/vm/network_test.rb +237 -0
  81. data/test/vagrant/actions/vm/package_test.rb +35 -5
  82. data/test/vagrant/actions/vm/provision_test.rb +3 -3
  83. data/test/vagrant/actions/vm/reload_test.rb +1 -1
  84. data/test/vagrant/actions/vm/shared_folders_test.rb +41 -74
  85. data/test/vagrant/actions/vm/start_test.rb +41 -3
  86. data/test/vagrant/actions/vm/up_test.rb +10 -21
  87. data/test/vagrant/active_list_test.rb +28 -43
  88. data/test/vagrant/commands/base_test.rb +25 -4
  89. data/test/vagrant/commands/destroy_test.rb +24 -12
  90. data/test/vagrant/commands/halt_test.rb +33 -11
  91. data/test/vagrant/commands/package_test.rb +77 -57
  92. data/test/vagrant/commands/provision_test.rb +50 -0
  93. data/test/vagrant/commands/reload_test.rb +27 -11
  94. data/test/vagrant/commands/resume_test.rb +25 -14
  95. data/test/vagrant/commands/ssh_config_test.rb +40 -17
  96. data/test/vagrant/commands/ssh_test.rb +52 -13
  97. data/test/vagrant/commands/status_test.rb +21 -1
  98. data/test/vagrant/commands/suspend_test.rb +25 -14
  99. data/test/vagrant/commands/up_test.rb +25 -19
  100. data/test/vagrant/config_test.rb +74 -18
  101. data/test/vagrant/downloaders/base_test.rb +2 -1
  102. data/test/vagrant/downloaders/http_test.rb +18 -8
  103. data/test/vagrant/environment_test.rb +245 -77
  104. data/test/vagrant/provisioners/base_test.rb +4 -4
  105. data/test/vagrant/provisioners/chef_server_test.rb +18 -7
  106. data/test/vagrant/provisioners/chef_solo_test.rb +17 -7
  107. data/test/vagrant/provisioners/chef_test.rb +22 -9
  108. data/test/vagrant/resource_logger_test.rb +144 -0
  109. data/test/vagrant/ssh_session_test.rb +46 -0
  110. data/test/vagrant/ssh_test.rb +42 -2
  111. data/test/vagrant/systems/linux_test.rb +174 -0
  112. data/test/vagrant/util/error_helper_test.rb +5 -0
  113. data/test/vagrant/util/output_helper_test.rb +5 -0
  114. data/test/vagrant/util/plain_logger_test.rb +17 -0
  115. data/test/vagrant/util/platform_test.rb +18 -0
  116. data/test/vagrant/util/{errors_test.rb → translator_test.rb} +25 -21
  117. data/test/vagrant/util_test.rb +12 -49
  118. data/test/vagrant/vm_test.rb +133 -11
  119. data/vagrant.gemspec +39 -15
  120. metadata +38 -14
  121. data/lib/vagrant/commands/down.rb +0 -16
  122. data/lib/vagrant/util/errors.rb +0 -36
  123. data/lib/vagrant/util/progress_meter.rb +0 -33
  124. data/test/vagrant/commands/down_test.rb +0 -17
  125. data/test/vagrant/util/progress_meter_test.rb +0 -33
@@ -1,10 +1,13 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'open-uri'
4
+ require 'uri'
5
+
1
6
  module Vagrant
2
7
  module Downloaders
3
8
  # Downloads a file from an HTTP URL to a temporary file. This
4
9
  # downloader reports its progress to stdout while downloading.
5
10
  class HTTP < Base
6
- include Util::ProgressMeter
7
-
8
11
  def self.match?(uri)
9
12
  # URI.parse barfs on '<drive letter>:\\files \on\ windows'
10
13
  # TODO temprorary
@@ -13,29 +16,38 @@ module Vagrant
13
16
  end
14
17
 
15
18
  def download!(source_url, destination_file)
16
- Net::HTTP.get_response(URI.parse(source_url)) do |response|
17
- total = response.content_length
18
- progress = 0
19
- segment_count = 0
19
+ uri = URI.parse(source_url)
20
+ http = Net::HTTP.new(uri.host, uri.port)
21
+ if uri.scheme == "https"
22
+ http.use_ssl = true
23
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
24
+ end
20
25
 
21
- response.read_body do |segment|
22
- # Report the progress out
23
- progress += segment.length
24
- segment_count += 1
26
+ http.start do |h|
27
+ h.request_get(uri.request_uri) do |response|
28
+ total = response.content_length
29
+ progress = 0
30
+ segment_count = 0
25
31
 
26
- # Progress reporting is limited to every 25 segments just so
27
- # we're not constantly updating
28
- if segment_count % 25 == 0
29
- update_progress(progress, total)
30
- segment_count = 0
31
- end
32
+ response.read_body do |segment|
33
+ # Report the progress out
34
+ progress += segment.length
35
+ segment_count += 1
36
+
37
+ # Progress reporting is limited to every 25 segments just so
38
+ # we're not constantly updating
39
+ if segment_count % 25 == 0
40
+ env.logger.report_progress(progress, total)
41
+ segment_count = 0
42
+ end
32
43
 
33
- # Store the segment
34
- destination_file.write(segment)
44
+ # Store the segment
45
+ destination_file.write(segment)
46
+ end
35
47
  end
36
48
  end
37
49
 
38
- complete_progress
50
+ env.logger.clear_progress
39
51
  end
40
52
  end
41
53
  end
@@ -5,27 +5,32 @@ module Vagrant
5
5
  class Environment
6
6
  ROOTFILE_NAME = "Vagrantfile"
7
7
  HOME_SUBDIRS = ["tmp", "boxes"]
8
+ DEFAULT_VM = :default
8
9
 
9
10
  include Util
10
11
 
12
+ attr_reader :parent # Parent environment (in the case of multi-VMs)
13
+ attr_reader :vm_name # The name of the VM (internal name) which this environment represents
14
+
11
15
  attr_accessor :cwd
12
16
  attr_reader :root_path
13
17
  attr_reader :config
14
18
  attr_reader :box
15
19
  attr_accessor :vm
16
- attr_reader :ssh
20
+ attr_reader :vms
17
21
  attr_reader :active_list
18
22
  attr_reader :commands
23
+ attr_reader :logger
19
24
 
20
25
  #---------------------------------------------------------------
21
26
  # Class Methods
22
27
  #---------------------------------------------------------------
23
- class <<self
28
+ class << self
24
29
  # Loads and returns an environment given a specific working
25
30
  # directory. If a working directory is not given, it will default
26
31
  # to the pwd.
27
32
  def load!(cwd=nil)
28
- Environment.new(cwd).load!
33
+ Environment.new(:cwd => cwd).load!
29
34
  end
30
35
 
31
36
  # Verifies that VirtualBox is installed and that the version of
@@ -43,12 +48,23 @@ module Vagrant
43
48
  end
44
49
  end
45
50
 
46
- def initialize(cwd=nil)
47
- @cwd = cwd
51
+ def initialize(opts=nil)
52
+ defaults = {
53
+ :parent => nil,
54
+ :vm_name => nil,
55
+ :vm => nil,
56
+ :cwd => nil
57
+ }
58
+
59
+ opts = defaults.merge(opts || {})
60
+
61
+ defaults.each do |key, value|
62
+ instance_variable_set("@#{key}".to_sym, opts[key])
63
+ end
48
64
  end
49
65
 
50
66
  #---------------------------------------------------------------
51
- # Path Helpers
67
+ # Helpers
52
68
  #---------------------------------------------------------------
53
69
 
54
70
  # Specifies the "current working directory" for this environment.
@@ -62,7 +78,7 @@ module Vagrant
62
78
  # The path to the `dotfile`, which contains the persisted UUID of
63
79
  # the VM if it exists.
64
80
  def dotfile_path
65
- File.join(root_path, config.vagrant.dotfile_name)
81
+ root_path ? File.join(root_path, config.vagrant.dotfile_name) : nil
66
82
  end
67
83
 
68
84
  # The path to the home directory, which is usually in `~/.vagrant/~
@@ -80,6 +96,34 @@ module Vagrant
80
96
  File.join(home_path, "boxes")
81
97
  end
82
98
 
99
+ # Returns the VMs associated with this environment.
100
+ def vms
101
+ @vms ||= {}
102
+ end
103
+
104
+ # Returns the primray VM associated with this environment
105
+ def primary_vm
106
+ return vms.values.first if !multivm?
107
+ return parent.primary_vm if parent
108
+
109
+ config.vm.defined_vms.each do |name, subvm|
110
+ return vms[name] if subvm.options[:primary]
111
+ end
112
+
113
+ nil
114
+ end
115
+
116
+ # Returns a boolean whether this environment represents a multi-VM
117
+ # environment or not. This will work even when called on child
118
+ # environments.
119
+ def multivm?
120
+ if parent
121
+ parent.multivm?
122
+ else
123
+ vms.length > 1
124
+ end
125
+ end
126
+
83
127
  #---------------------------------------------------------------
84
128
  # Load Methods
85
129
  #---------------------------------------------------------------
@@ -88,6 +132,7 @@ module Vagrant
88
132
  # such as `vm`, `config`, etc. on this environment. The order this
89
133
  # method calls its other methods is very particular.
90
134
  def load!
135
+ load_logger!
91
136
  load_root_path!
92
137
  load_config!
93
138
  load_home_directory!
@@ -95,7 +140,6 @@ module Vagrant
95
140
  load_config!
96
141
  self.class.check_virtualbox!
97
142
  load_vm!
98
- load_ssh!
99
143
  load_active_list!
100
144
  load_commands!
101
145
  self
@@ -125,25 +169,54 @@ module Vagrant
125
169
  # this environment, meaning that it will use the given root directory
126
170
  # to load the Vagrantfile into that context.
127
171
  def load_config!
128
- # Prepare load paths for config files
129
- load_paths = [File.join(PROJECT_ROOT, "config", "default.rb")]
130
- load_paths << File.join(box.directory, ROOTFILE_NAME) if box
131
- load_paths << File.join(home_path, ROOTFILE_NAME) if home_path
132
- load_paths << File.join(root_path, ROOTFILE_NAME) if root_path
172
+ # Prepare load paths for config files and append to config queue
173
+ config_queue = [File.join(PROJECT_ROOT, "config", "default.rb")]
174
+ config_queue << File.join(box.directory, ROOTFILE_NAME) if box
175
+ config_queue << File.join(home_path, ROOTFILE_NAME) if home_path
176
+ config_queue << File.join(root_path, ROOTFILE_NAME) if root_path
177
+
178
+ # If this environment represents some VM in a multi-VM environment,
179
+ # we push that VM's configuration onto the config_queue.
180
+ if vm_name
181
+ subvm = parent.config.vm.defined_vms[vm_name]
182
+ config_queue << subvm.proc_stack if subvm
183
+ end
184
+
185
+ # Flatten the config queue so any nested procs are flattened
186
+ config_queue.flatten!
133
187
 
134
188
  # Clear out the old data
135
189
  Config.reset!(self)
136
190
 
137
191
  # Load each of the config files in order
138
- load_paths.each do |path|
139
- if File.exist?(path)
140
- logger.info "Loading config from #{path}..."
141
- load path
192
+ config_queue.each do |item|
193
+ if item.is_a?(String) && File.exist?(item)
194
+ load item
195
+ next
196
+ end
197
+
198
+ if item.is_a?(Proc)
199
+ # Just push the proc straight onto the config runnable stack
200
+ Config.run(&item)
142
201
  end
143
202
  end
144
203
 
145
204
  # Execute the configuration stack and store the result
146
205
  @config = Config.execute!
206
+
207
+ # (re)load the logger
208
+ load_logger!
209
+ end
210
+
211
+ # Loads the logger for this environment. This is called by
212
+ # {#load_config!} so that the logger is only loaded after
213
+ # configuration information is available. The logger is also
214
+ # loaded early on in the load chain process so that the various
215
+ # references to logger won't throw nil exceptions, but by default
216
+ # the logger will just send the log data to a black hole.
217
+ def load_logger!
218
+ resource = vm_name || "vagrant"
219
+ @logger = ResourceLogger.new(resource, self)
147
220
  end
148
221
 
149
222
  # Loads the home directory path and creates the necessary subdirectories
@@ -171,19 +244,49 @@ module Vagrant
171
244
 
172
245
  # Loads the persisted VM (if it exists) for this environment.
173
246
  def load_vm!
174
- return if !root_path || !File.file?(dotfile_path)
247
+ # This environment represents a single sub VM. The VM is then
248
+ # probably (read: should be) set on the VM attribute, so we do
249
+ # nothing.
250
+ return if vm_name
251
+
252
+ # First load the defaults (blank, noncreated VMs)
253
+ load_blank_vms!
175
254
 
255
+ # If we have no dotfile, then return
256
+ return if !dotfile_path || !File.file?(dotfile_path)
257
+
258
+ # Open and parse the dotfile
176
259
  File.open(dotfile_path) do |f|
177
- @vm = Vagrant::VM.find(f.read)
178
- @vm.env = self if @vm
260
+ data = { DEFAULT_VM => f.read }
261
+
262
+ begin
263
+ data = JSON.parse(data[DEFAULT_VM])
264
+ rescue JSON::ParserError
265
+ # Most likely an older (<= 0.3.x) dotfile. Try to load it
266
+ # as the :__vagrant VM.
267
+ end
268
+
269
+ data.each do |key, value|
270
+ key = key.to_sym
271
+ vms[key] = Vagrant::VM.find(value, self, key)
272
+ end
179
273
  end
180
274
  rescue Errno::ENOENT
181
- @vm = nil
275
+ # Just rescue it.
182
276
  end
183
277
 
184
- # Loads/initializes the SSH object
185
- def load_ssh!
186
- @ssh = SSH.new(self)
278
+ # Loads blank VMs into the `vms` attribute.
279
+ def load_blank_vms!
280
+ # Clear existing vms
281
+ vms.clear
282
+
283
+ # Load up the blank VMs
284
+ defined_vms = config.vm.defined_vms.keys
285
+ defined_vms = [DEFAULT_VM] if defined_vms.empty?
286
+
287
+ defined_vms.each do |name|
288
+ vms[name] = Vagrant::VM.new(:vm_name => name, :env => self)
289
+ end
187
290
  end
188
291
 
189
292
  # Loads the activelist for this environment
@@ -202,34 +305,28 @@ module Vagrant
202
305
  # Methods to manage VM
203
306
  #---------------------------------------------------------------
204
307
 
205
- # Sets the VM to a new VM. This is not too useful but is used
206
- # in {Command.up}. This will very likely be refactored at a later
207
- # time.
208
- def create_vm
209
- @vm = VM.new
210
- @vm.env = self
211
- @vm
212
- end
213
-
214
308
  # Persists this environment's VM to the dotfile so it can be
215
309
  # re-loaded at a later time.
216
- def persist_vm
217
- # Save to the dotfile for this project
218
- File.open(dotfile_path, 'w+') do |f|
219
- f.write(vm.uuid)
310
+ def update_dotfile
311
+ return parent.update_dotfile if parent
312
+
313
+ # Generate and save the persisted VM info
314
+ data = vms.inject({}) do |acc, data|
315
+ key, value = data
316
+ acc[key] = value.uuid if value.created?
317
+ acc
220
318
  end
221
319
 
222
- # Also add to the global store
223
- active_list.add(vm)
224
- end
225
-
226
- # Removes this environment's VM from the dotfile.
227
- def depersist_vm
228
- # Delete the dotfile if it exists
229
- File.delete(dotfile_path) if File.exist?(dotfile_path)
320
+ if data.empty?
321
+ File.delete(dotfile_path)
322
+ else
323
+ File.open(dotfile_path, 'w+') do |f|
324
+ f.write(data.to_json)
325
+ end
326
+ end
230
327
 
231
- # Remove from the global store
232
- active_list.remove(vm)
328
+ # Also add to the global store
329
+ # active_list.add(vm)
233
330
  end
234
331
 
235
332
  #---------------------------------------------------------------
@@ -244,10 +341,10 @@ module Vagrant
244
341
  require_root_path
245
342
 
246
343
  if !box
247
- if !Vagrant.config.vm.box
344
+ if !config.vm.box
248
345
  error_and_exit(:box_not_specified)
249
346
  else
250
- error_and_exit(:box_specified_doesnt_exist, :box_name => Vagrant.config.vm.box)
347
+ error_and_exit(:box_specified_doesnt_exist, :box_name => config.vm.box)
251
348
  end
252
349
  end
253
350
  end
@@ -7,11 +7,25 @@ module Vagrant
7
7
  class Base
8
8
  include Vagrant::Util
9
9
 
10
- # The environment which this is being provisioned in
11
- attr_reader :env
10
+ # The VM which this is being provisioned for
11
+ attr_reader :vm
12
12
 
13
- def initialize(env)
14
- @env = env
13
+ def initialize(vm)
14
+ @vm = vm
15
+ end
16
+
17
+ # This method returns the environment which the provisioner is working
18
+ # on. This is also the environment of the VM. This method is provided
19
+ # as a simple helper since the environment is often used throughout the
20
+ # provisioner.
21
+ def env
22
+ @vm.env
23
+ end
24
+
25
+ # This method returns the environment's logger as a convenience
26
+ # method.
27
+ def logger
28
+ env.logger
15
29
  end
16
30
 
17
31
  # This is the method called to "prepare" the provisioner. This is called
@@ -26,4 +40,4 @@ module Vagrant
26
40
  def provision!; end
27
41
  end
28
42
  end
29
- end
43
+ end
@@ -75,9 +75,17 @@ module Vagrant
75
75
  raise Actions::ActionException.new(:chef_base_invalid_provisioner)
76
76
  end
77
77
 
78
+ def verify_binary(binary)
79
+ vm.ssh.execute do |ssh|
80
+ # Checks for the existence of chef binary and error if it
81
+ # doesn't exist.
82
+ ssh.exec!("which #{binary}", :error_key => :chef_not_detected, :error_data => {:binary => binary})
83
+ end
84
+ end
85
+
78
86
  def chown_provisioning_folder
79
87
  logger.info "Setting permissions on chef provisioning folder..."
80
- env.ssh.execute do |ssh|
88
+ vm.ssh.execute do |ssh|
81
89
  ssh.exec!("sudo mkdir -p #{env.config.chef.provisioning_path}")
82
90
  ssh.exec!("sudo chown #{env.config.ssh.username} #{env.config.chef.provisioning_path}")
83
91
  end
@@ -89,7 +97,7 @@ module Vagrant
89
97
  }.merge(template_vars))
90
98
 
91
99
  logger.info "Uploading chef configuration script..."
92
- env.ssh.upload!(StringIO.new(config_file), File.join(env.config.chef.provisioning_path, filename))
100
+ vm.ssh.upload!(StringIO.new(config_file), File.join(env.config.chef.provisioning_path, filename))
93
101
  end
94
102
 
95
103
  def setup_json
@@ -98,7 +106,7 @@ module Vagrant
98
106
  # Set up initial configuration
99
107
  data = {
100
108
  :config => env.config,
101
- :directory => env.config.vm.project_directory,
109
+ :directory => env.config.vm.shared_folders["v-root"][:guestpath],
102
110
  }
103
111
 
104
112
  # And wrap it under the "vagrant" namespace
@@ -110,7 +118,7 @@ module Vagrant
110
118
 
111
119
  json = data.to_json
112
120
 
113
- env.ssh.upload!(StringIO.new(json), File.join(env.config.chef.provisioning_path, "dna.json"))
121
+ vm.ssh.upload!(StringIO.new(json), File.join(env.config.chef.provisioning_path, "dna.json"))
114
122
  end
115
123
  end
116
124
  end