bosh-director 1.5.0.pre.1113

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 (180) hide show
  1. data/CHANGELOG +34 -0
  2. data/bin/bosh-director +36 -0
  3. data/bin/bosh-director-console +84 -0
  4. data/bin/bosh-director-drain-workers +42 -0
  5. data/bin/bosh-director-migrate +58 -0
  6. data/bin/bosh-director-scheduler +27 -0
  7. data/bin/bosh-director-worker +76 -0
  8. data/db/migrations/README +1 -0
  9. data/db/migrations/director/20110209010747_initial.rb +118 -0
  10. data/db/migrations/director/20110406055800_add_task_user.rb +9 -0
  11. data/db/migrations/director/20110518225809_remove_cid_constrain.rb +13 -0
  12. data/db/migrations/director/20110617211923_add_deployments_release_versions.rb +32 -0
  13. data/db/migrations/director/20110622212607_add_task_checkpoint_timestamp.rb +9 -0
  14. data/db/migrations/director/20110628023039_add_state_to_instances.rb +21 -0
  15. data/db/migrations/director/20110709012332_add_disk_size_to_instances.rb +9 -0
  16. data/db/migrations/director/20110906183441_add_log_bundles.rb +11 -0
  17. data/db/migrations/director/20110907194830_add_logs_json_to_templates.rb +9 -0
  18. data/db/migrations/director/20110915205610_add_persistent_disks.rb +51 -0
  19. data/db/migrations/director/20111005180929_add_properties.rb +14 -0
  20. data/db/migrations/director/20111110024617_add_deployment_problems.rb +24 -0
  21. data/db/migrations/director/20111216214145_recreate_support_for_vms.rb +9 -0
  22. data/db/migrations/director/20120102084027_add_credentials_to_vms.rb +7 -0
  23. data/db/migrations/director/20120427235217_allow_multiple_releases_per_deployment.rb +36 -0
  24. data/db/migrations/director/20120524175805_add_task_type.rb +44 -0
  25. data/db/migrations/director/20120614001930_delete_redundant_deployment_release_relation.rb +34 -0
  26. data/db/migrations/director/20120822004528_add_fingerprint_to_templates_and_packages.rb +17 -0
  27. data/db/migrations/director/20120830191244_add_properties_to_templates.rb +9 -0
  28. data/db/migrations/director/20121106190739_persist_vm_env.rb +9 -0
  29. data/db/migrations/director/20130222232131_add_sha1_to_stemcells.rb +9 -0
  30. data/db/migrations/director/20130312211407_add_commit_hash_to_release_versions.rb +19 -0
  31. data/db/migrations/director/20130409235338_snapshot.rb +15 -0
  32. data/db/migrations/director/20130530164918_add_paused_flag_to_instance.rb +14 -0
  33. data/db/migrations/director/20130531172604_add_director_attributes.rb +13 -0
  34. data/db/migrations/dns/20120123234908_initial.rb +27 -0
  35. data/lib/bosh/director.rb +133 -0
  36. data/lib/bosh/director/agent_client.rb +78 -0
  37. data/lib/bosh/director/api.rb +29 -0
  38. data/lib/bosh/director/api/api_helper.rb +81 -0
  39. data/lib/bosh/director/api/backup_manager.rb +15 -0
  40. data/lib/bosh/director/api/controller.rb +639 -0
  41. data/lib/bosh/director/api/controller_helpers.rb +34 -0
  42. data/lib/bosh/director/api/deployment_lookup.rb +13 -0
  43. data/lib/bosh/director/api/deployment_manager.rb +60 -0
  44. data/lib/bosh/director/api/http_constants.rb +16 -0
  45. data/lib/bosh/director/api/instance_lookup.rb +44 -0
  46. data/lib/bosh/director/api/instance_manager.rb +63 -0
  47. data/lib/bosh/director/api/problem_manager.rb +40 -0
  48. data/lib/bosh/director/api/property_manager.rb +69 -0
  49. data/lib/bosh/director/api/release_manager.rb +59 -0
  50. data/lib/bosh/director/api/resource_manager.rb +69 -0
  51. data/lib/bosh/director/api/resurrector_manager.rb +15 -0
  52. data/lib/bosh/director/api/snapshot_manager.rb +94 -0
  53. data/lib/bosh/director/api/stemcell_manager.rb +50 -0
  54. data/lib/bosh/director/api/task_helper.rb +46 -0
  55. data/lib/bosh/director/api/task_manager.rb +64 -0
  56. data/lib/bosh/director/api/user_manager.rb +72 -0
  57. data/lib/bosh/director/api/vm_state_manager.rb +11 -0
  58. data/lib/bosh/director/app.rb +35 -0
  59. data/lib/bosh/director/blob_util.rb +87 -0
  60. data/lib/bosh/director/blobstores.rb +29 -0
  61. data/lib/bosh/director/client.rb +156 -0
  62. data/lib/bosh/director/cloudcheck_helper.rb +204 -0
  63. data/lib/bosh/director/compile_task.rb +157 -0
  64. data/lib/bosh/director/config.rb +370 -0
  65. data/lib/bosh/director/configuration_hasher.rb +114 -0
  66. data/lib/bosh/director/cycle_helper.rb +36 -0
  67. data/lib/bosh/director/db_backup.rb +22 -0
  68. data/lib/bosh/director/db_backup/adapter.rb +3 -0
  69. data/lib/bosh/director/db_backup/adapter/mysql2.rb +27 -0
  70. data/lib/bosh/director/db_backup/adapter/postgres.rb +36 -0
  71. data/lib/bosh/director/db_backup/adapter/sqlite.rb +17 -0
  72. data/lib/bosh/director/db_backup/error.rb +10 -0
  73. data/lib/bosh/director/deployment_plan.rb +26 -0
  74. data/lib/bosh/director/deployment_plan/assembler.rb +430 -0
  75. data/lib/bosh/director/deployment_plan/compilation_config.rb +54 -0
  76. data/lib/bosh/director/deployment_plan/compiled_package.rb +35 -0
  77. data/lib/bosh/director/deployment_plan/dynamic_network.rb +91 -0
  78. data/lib/bosh/director/deployment_plan/idle_vm.rb +109 -0
  79. data/lib/bosh/director/deployment_plan/instance.rb +413 -0
  80. data/lib/bosh/director/deployment_plan/job.rb +470 -0
  81. data/lib/bosh/director/deployment_plan/manual_network.rb +137 -0
  82. data/lib/bosh/director/deployment_plan/network.rb +74 -0
  83. data/lib/bosh/director/deployment_plan/network_subnet.rb +167 -0
  84. data/lib/bosh/director/deployment_plan/planner.rb +288 -0
  85. data/lib/bosh/director/deployment_plan/preparer.rb +52 -0
  86. data/lib/bosh/director/deployment_plan/release.rb +126 -0
  87. data/lib/bosh/director/deployment_plan/resource_pool.rb +143 -0
  88. data/lib/bosh/director/deployment_plan/resource_pools.rb +68 -0
  89. data/lib/bosh/director/deployment_plan/stemcell.rb +56 -0
  90. data/lib/bosh/director/deployment_plan/template.rb +94 -0
  91. data/lib/bosh/director/deployment_plan/update_config.rb +80 -0
  92. data/lib/bosh/director/deployment_plan/updater.rb +55 -0
  93. data/lib/bosh/director/deployment_plan/vip_network.rb +79 -0
  94. data/lib/bosh/director/dns_helper.rb +204 -0
  95. data/lib/bosh/director/download_helper.rb +44 -0
  96. data/lib/bosh/director/duration.rb +36 -0
  97. data/lib/bosh/director/encryption_helper.rb +10 -0
  98. data/lib/bosh/director/errors.rb +198 -0
  99. data/lib/bosh/director/event_log.rb +136 -0
  100. data/lib/bosh/director/ext.rb +64 -0
  101. data/lib/bosh/director/hash_string_vals.rb +13 -0
  102. data/lib/bosh/director/instance_deleter.rb +109 -0
  103. data/lib/bosh/director/instance_updater.rb +506 -0
  104. data/lib/bosh/director/ip_util.rb +67 -0
  105. data/lib/bosh/director/job_queue.rb +16 -0
  106. data/lib/bosh/director/job_runner.rb +162 -0
  107. data/lib/bosh/director/job_updater.rb +121 -0
  108. data/lib/bosh/director/jobs/backup.rb +86 -0
  109. data/lib/bosh/director/jobs/base_job.rb +66 -0
  110. data/lib/bosh/director/jobs/cloud_check/apply_resolutions.rb +46 -0
  111. data/lib/bosh/director/jobs/cloud_check/scan.rb +38 -0
  112. data/lib/bosh/director/jobs/cloud_check/scan_and_fix.rb +73 -0
  113. data/lib/bosh/director/jobs/create_snapshot.rb +23 -0
  114. data/lib/bosh/director/jobs/delete_deployment.rb +183 -0
  115. data/lib/bosh/director/jobs/delete_deployment_snapshots.rb +34 -0
  116. data/lib/bosh/director/jobs/delete_release.rb +219 -0
  117. data/lib/bosh/director/jobs/delete_snapshots.rb +23 -0
  118. data/lib/bosh/director/jobs/delete_stemcell.rb +102 -0
  119. data/lib/bosh/director/jobs/fetch_logs.rb +99 -0
  120. data/lib/bosh/director/jobs/scheduled_backup.rb +38 -0
  121. data/lib/bosh/director/jobs/snapshot_deployment.rb +61 -0
  122. data/lib/bosh/director/jobs/snapshot_deployments.rb +23 -0
  123. data/lib/bosh/director/jobs/snapshot_self.rb +43 -0
  124. data/lib/bosh/director/jobs/ssh.rb +59 -0
  125. data/lib/bosh/director/jobs/update_deployment.rb +110 -0
  126. data/lib/bosh/director/jobs/update_release.rb +672 -0
  127. data/lib/bosh/director/jobs/update_stemcell.rb +109 -0
  128. data/lib/bosh/director/jobs/vm_state.rb +89 -0
  129. data/lib/bosh/director/lock.rb +133 -0
  130. data/lib/bosh/director/lock_helper.rb +92 -0
  131. data/lib/bosh/director/models.rb +29 -0
  132. data/lib/bosh/director/models/compiled_package.rb +33 -0
  133. data/lib/bosh/director/models/deployment.rb +22 -0
  134. data/lib/bosh/director/models/deployment_problem.rb +49 -0
  135. data/lib/bosh/director/models/deployment_property.rb +21 -0
  136. data/lib/bosh/director/models/director_attribute.rb +9 -0
  137. data/lib/bosh/director/models/dns.rb +9 -0
  138. data/lib/bosh/director/models/dns/domain.rb +9 -0
  139. data/lib/bosh/director/models/dns/record.rb +7 -0
  140. data/lib/bosh/director/models/helpers/model_helper.rb +7 -0
  141. data/lib/bosh/director/models/instance.rb +28 -0
  142. data/lib/bosh/director/models/log_bundle.rb +10 -0
  143. data/lib/bosh/director/models/package.rb +30 -0
  144. data/lib/bosh/director/models/persistent_disk.rb +13 -0
  145. data/lib/bosh/director/models/release.rb +17 -0
  146. data/lib/bosh/director/models/release_version.rb +16 -0
  147. data/lib/bosh/director/models/snapshot.rb +13 -0
  148. data/lib/bosh/director/models/stemcell.rb +18 -0
  149. data/lib/bosh/director/models/task.rb +10 -0
  150. data/lib/bosh/director/models/template.rb +44 -0
  151. data/lib/bosh/director/models/user.rb +11 -0
  152. data/lib/bosh/director/models/vm.rb +42 -0
  153. data/lib/bosh/director/nats_rpc.rb +54 -0
  154. data/lib/bosh/director/network_reservation.rb +121 -0
  155. data/lib/bosh/director/next_rebase_version.rb +20 -0
  156. data/lib/bosh/director/package_compiler.rb +423 -0
  157. data/lib/bosh/director/problem_handlers/base.rb +153 -0
  158. data/lib/bosh/director/problem_handlers/inactive_disk.rb +112 -0
  159. data/lib/bosh/director/problem_handlers/invalid_problem.rb +28 -0
  160. data/lib/bosh/director/problem_handlers/missing_vm.rb +34 -0
  161. data/lib/bosh/director/problem_handlers/mount_info_mismatch.rb +62 -0
  162. data/lib/bosh/director/problem_handlers/out_of_sync_vm.rb +64 -0
  163. data/lib/bosh/director/problem_handlers/unbound_instance_vm.rb +85 -0
  164. data/lib/bosh/director/problem_handlers/unresponsive_agent.rb +78 -0
  165. data/lib/bosh/director/problem_resolver.rb +103 -0
  166. data/lib/bosh/director/problem_scanner.rb +268 -0
  167. data/lib/bosh/director/resource_pool_updater.rb +216 -0
  168. data/lib/bosh/director/scheduler.rb +57 -0
  169. data/lib/bosh/director/sequel.rb +13 -0
  170. data/lib/bosh/director/tar_gzipper.rb +47 -0
  171. data/lib/bosh/director/task_result_file.rb +19 -0
  172. data/lib/bosh/director/thread_pool.rb +8 -0
  173. data/lib/bosh/director/validation_helper.rb +55 -0
  174. data/lib/bosh/director/version.rb +7 -0
  175. data/lib/bosh/director/vm_creator.rb +80 -0
  176. data/lib/bosh/director/vm_data.rb +63 -0
  177. data/lib/bosh/director/vm_metadata_updater.rb +29 -0
  178. data/lib/bosh/director/vm_reuser.rb +63 -0
  179. data/lib/cloud/dummy.rb +149 -0
  180. metadata +664 -0
@@ -0,0 +1,216 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ class ResourcePoolUpdater
5
+
6
+ def initialize(resource_pool)
7
+ @resource_pool = resource_pool
8
+ @cloud = Config.cloud
9
+ @logger = Config.logger
10
+ @event_log = Config.event_log
11
+ end
12
+
13
+ ##
14
+ # Creates VMs that are considered missing from the deployment
15
+ #
16
+ # @param [ThreadPool] thread_pool Thread pool that will be used to
17
+ # parallelize the operation
18
+ # @yield [idle_vm] filter for which missing VMs to create
19
+ def create_missing_vms(thread_pool)
20
+ counter = 0
21
+ vms_to_process = []
22
+
23
+ each_idle_vm do |idle_vm|
24
+ next if idle_vm.vm
25
+ if !block_given? || yield(idle_vm)
26
+ counter += 1
27
+ vms_to_process << idle_vm
28
+ end
29
+ end
30
+
31
+ @logger.info("Creating #{counter} missing VMs")
32
+ vms_to_process.each_with_index do |idle_vm, index|
33
+ thread_pool.process do
34
+ @event_log.track("#{@resource_pool.name}/#{index}") do
35
+ with_thread_name("create_missing_vm(#{@resource_pool.name}, #{index}/#{counter})") do
36
+ @logger.info("Creating missing VM")
37
+ create_missing_vm(idle_vm)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ # Creates missing VMs that have bound instances
45
+ # (as opposed to missing resource pool VMs)
46
+ def create_bound_missing_vms(thread_pool)
47
+ create_missing_vms(thread_pool) { |idle_vm| !idle_vm.bound_instance.nil? }
48
+ end
49
+
50
+ def create_missing_vm(idle_vm)
51
+ deployment = @resource_pool.deployment_plan.model
52
+ stemcell = @resource_pool.stemcell.model
53
+
54
+ vm = VmCreator.new.create(deployment, stemcell, @resource_pool.cloud_properties,
55
+ idle_vm.network_settings, nil, @resource_pool.env)
56
+
57
+ agent = AgentClient.new(vm.agent_id)
58
+ agent.wait_until_ready
59
+
60
+ update_state(agent, vm, idle_vm)
61
+
62
+ idle_vm.vm = vm
63
+ idle_vm.current_state = agent.get_state
64
+ rescue Exception => e
65
+ @logger.info("Cleaning up the created VM due to an error: #{e}")
66
+ begin
67
+ @cloud.delete_vm(vm.cid) if vm && vm.cid
68
+ vm.destroy if vm && vm.id
69
+ rescue Exception
70
+ @logger.info("Could not cleanup VM: #{vm.cid}") if vm
71
+ end
72
+ raise e
73
+ end
74
+
75
+ def update_state(agent, vm, idle_vm)
76
+ state = {
77
+ "deployment" => @resource_pool.deployment_plan.name,
78
+ "resource_pool" => @resource_pool.spec,
79
+ "networks" => idle_vm.network_settings
80
+ }
81
+
82
+ vm.update(:apply_spec => state)
83
+ agent.apply(state)
84
+ end
85
+
86
+ # Deletes extra VMs in a resource pool
87
+ # @param thread_pool Thread pool used to parallelize delete operations
88
+ def delete_extra_vms(thread_pool)
89
+ count = extra_vm_count
90
+ @logger.info("Deleting #{count} extra VMs")
91
+
92
+ count.times do
93
+ idle_vm = @resource_pool.idle_vms.shift
94
+ vm_cid = idle_vm.vm.cid
95
+
96
+ thread_pool.process do
97
+ @event_log.track("#{@resource_pool.name}/#{vm_cid}") do
98
+ @logger.info("Deleting extra VM: #{vm_cid}")
99
+ @cloud.delete_vm(vm_cid)
100
+ idle_vm.vm.destroy
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ def delete_outdated_idle_vms(thread_pool)
107
+ count = outdated_idle_vm_count
108
+ index = 0
109
+ index_lock = Mutex.new
110
+
111
+ @logger.info("Deleting #{count} outdated idle VMs")
112
+
113
+ @resource_pool.idle_vms.each do |idle_vm|
114
+ next unless idle_vm.vm && idle_vm.changed?
115
+ vm_cid = idle_vm.vm.cid
116
+
117
+ thread_pool.process do
118
+ @event_log.track("#{@resource_pool.name}/#{vm_cid}") do
119
+ index_lock.synchronize { index += 1 }
120
+
121
+ with_thread_name("delete_outdated_vm(#{@resource_pool.name}, #{index - 1}/#{count})") do
122
+ @logger.info("Deleting outdated VM: #{vm_cid}")
123
+ @cloud.delete_vm(vm_cid)
124
+ vm = idle_vm.vm
125
+ idle_vm.vm = nil
126
+ idle_vm.current_state = nil
127
+ vm.destroy
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ # Attempts to allocate a dynamic IP address for all idle VMs
135
+ # (unless they already have one). This allows us to fail earlier
136
+ # in case any of resource pools is not big enough to accommodate
137
+ # those VMs.
138
+ def reserve_networks
139
+ network = @resource_pool.network
140
+
141
+ each_idle_vm do |idle_vm|
142
+ unless idle_vm.network_reservation
143
+ reservation = NetworkReservation.new(
144
+ :type => NetworkReservation::DYNAMIC)
145
+ network.reserve(reservation)
146
+
147
+ unless reservation.reserved?
148
+ case reservation.error
149
+ when NetworkReservation::CAPACITY
150
+ raise NetworkReservationNotEnoughCapacity,
151
+ "`#{name}/#{index}' asked for a dynamic IP " +
152
+ "but there were no more available"
153
+ else
154
+ raise NetworkReservationError,
155
+ "`#{name}/#{index}' failed to reserve " +
156
+ "dynamic IP: #{reservation.error}"
157
+ end
158
+ end
159
+
160
+ idle_vm.network_reservation = reservation
161
+ end
162
+ end
163
+ end
164
+
165
+ def generate_agent_id
166
+ SecureRandom.uuid
167
+ end
168
+
169
+ def each_idle_vm
170
+ @resource_pool.allocated_vms.each { |idle_vm| yield idle_vm }
171
+ @resource_pool.idle_vms.each { |idle_vm| yield idle_vm }
172
+ end
173
+
174
+ def each_idle_vm_with_index
175
+ index = 0
176
+ each_idle_vm do |idle_vm|
177
+ yield(idle_vm, index)
178
+ index += 1
179
+ end
180
+ end
181
+
182
+ def extra_vm_count
183
+ @resource_pool.active_vm_count +
184
+ @resource_pool.idle_vms.size +
185
+ @resource_pool.allocated_vms.size -
186
+ @resource_pool.size
187
+ end
188
+
189
+ def outdated_idle_vm_count
190
+ counter = 0
191
+ @resource_pool.idle_vms.each do |idle_vm|
192
+ counter += 1 if idle_vm.vm && idle_vm.changed?
193
+ end
194
+ counter
195
+ end
196
+
197
+ def missing_vm_count
198
+ counter = 0
199
+ each_idle_vm do |idle_vm|
200
+ next if idle_vm.vm
201
+ counter += 1
202
+ end
203
+ counter
204
+ end
205
+
206
+ def bound_missing_vm_count
207
+ counter = 0
208
+ each_idle_vm do |idle_vm|
209
+ next if idle_vm.vm
210
+ next if idle_vm.bound_instance.nil?
211
+ counter += 1
212
+ end
213
+ counter
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,57 @@
1
+ require 'rufus/scheduler'
2
+
3
+ module Bosh::Director
4
+ class Scheduler
5
+ def initialize(scheduled_jobs=[], options={})
6
+ if scheduled_jobs.nil? || scheduled_jobs.is_a?(Array)
7
+ @scheduled_jobs = scheduled_jobs
8
+ @scheduler = options.fetch(:scheduler) { Rufus::Scheduler::PlainScheduler.new }
9
+ @queue = options.fetch(:queue) { JobQueue.new }
10
+ else
11
+ raise 'scheduled_jobs must be an array'
12
+ end
13
+ end
14
+
15
+ def start!
16
+ logger.info('starting scheduler')
17
+ add_jobs unless @added_already
18
+ @scheduler.start
19
+ @scheduler.join
20
+ end
21
+
22
+ def stop!
23
+ logger.info('stopping scheduler')
24
+ @scheduler.stop
25
+ end
26
+
27
+ def logger
28
+ @logger ||= Config.logger
29
+ end
30
+
31
+ private
32
+
33
+ def add_jobs
34
+ return if @scheduled_jobs.nil?
35
+ @added_already = true
36
+
37
+ @scheduled_jobs.each do |scheduled_job|
38
+ begin
39
+ director_job_class = Bosh::Director::Jobs.const_get(scheduled_job['command'].to_s)
40
+ rescue NameError
41
+ raise "unknown job `Bosh::Director::Jobs::#{scheduled_job['command']}'"
42
+ end
43
+
44
+ @scheduler.cron(scheduled_job['schedule']) do |_|
45
+ logger.info("enqueueing `#{scheduled_job['command']}'")
46
+
47
+ @queue.enqueue('scheduler',
48
+ director_job_class,
49
+ "scheduled #{scheduled_job['command']}",
50
+ scheduled_job['params'])
51
+ end
52
+
53
+ logger.info("added scheduled job `#{director_job_class}' with interval '#{scheduled_job['schedule']}'")
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ Sequel.extension :blank
4
+
5
+ Sequel::Model.plugin :validation_helpers
6
+ Sequel::Model.raise_on_typecast_failure = false
7
+
8
+ [:exact_length, :format, :includes, :integer, :length_range, :max_length,
9
+ :min_length, :not_string, :numeric, :type, :presence, :unique].each do |validation|
10
+ Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS[validation][:message] = validation
11
+ end
12
+
13
+ Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS[:max_length][:nil_message] = :max_length
@@ -0,0 +1,47 @@
1
+ require 'tmpdir'
2
+ require 'open3'
3
+
4
+ module Bosh::Director
5
+ class TarGzipper
6
+ include Bosh::RunsCommands
7
+
8
+ # @param [String] base_dir the directory from which the tar command is run
9
+ # @param [String, Array] sources the relative paths to include
10
+ # @param [String] dest the destination filename for the tgz output
11
+ # @param [Hash] options the options for compress
12
+ # @option options [Boolean] :copy_first copy the source to a temp dir before archiving
13
+ def compress(base_dir, sources, dest, options={})
14
+ sources = [*sources]
15
+
16
+ sources.each do |source|
17
+ raise "Sources must have a path depth of 1 and contain no '#{File::SEPARATOR}'" if source.include?(File::SEPARATOR)
18
+ end
19
+
20
+ base_dir_path = Pathname.new(base_dir)
21
+
22
+ unless base_dir_path.exist?
23
+ raise "The base directory #{base_dir} could not be found."
24
+ end
25
+
26
+ unless base_dir_path.absolute?
27
+ raise "The base directory #{base_dir} is not an absolute path."
28
+ end
29
+
30
+ if options[:copy_first]
31
+ Dir.mktmpdir do |tmpdir|
32
+ FileUtils.cp_r(sources.map { |s| File.join(base_dir, s) }, "#{tmpdir}/")
33
+ tar(tmpdir, dest, sources)
34
+ end
35
+ else
36
+ tar(base_dir, dest, sources)
37
+ end
38
+ end
39
+
40
+ private
41
+ def tar(base_dir, dest, sources)
42
+ out, err, status = Open3.capture3('tar', '-C', base_dir, '-czf', dest, *sources)
43
+ raise("tar exited #{status.exitstatus}, output: '#{out}', error: '#{err}'") unless status.success?
44
+ out
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+
5
+ class TaskResultFile
6
+ def initialize(file_name)
7
+ @file = File.open(file_name, "w")
8
+ @lock = Mutex.new
9
+ end
10
+
11
+ def write(result)
12
+ @lock.synchronize do
13
+ @file.write(result)
14
+ @file.flush
15
+ end
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,8 @@
1
+ module Bosh::Director
2
+ class ThreadPool < Bosh::ThreadPool
3
+ def initialize(options)
4
+ options[:logger] ||= Config.logger
5
+ super(options)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,55 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module ValidationHelper
5
+
6
+ def safe_property(hash, property, options = {})
7
+ result = nil
8
+
9
+ if hash && hash.has_key?(property)
10
+ result = hash[property]
11
+
12
+ if options[:class]
13
+
14
+ if options[:class] == :boolean
15
+ unless result.kind_of?(TrueClass) || result.kind_of?(FalseClass)
16
+ invalid_type(property, options[:class], result)
17
+ end
18
+
19
+ elsif !result.kind_of?(options[:class])
20
+ if options[:class] == String && result.kind_of?(Numeric)
21
+ result = result.to_s
22
+ else
23
+ invalid_type(property, options[:class], result)
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ if options[:min] && result < options[:min]
30
+ raise ValidationViolatedMin,
31
+ "`#{property}' value (#{result}) should be greater than #{options[:min]}"
32
+ end
33
+
34
+ if options[:max] && result > options[:max]
35
+ raise ValidationViolatedMax,
36
+ "`#{property}' value (#{result}) should be less than #{options[:max]}"
37
+ end
38
+
39
+ elsif options[:default]
40
+ result = options[:default]
41
+
42
+ elsif !options[:optional]
43
+ raise ValidationMissingField,
44
+ "Required property `#{property}' was not specified in #{self.class.name}"
45
+ end
46
+ result
47
+ end
48
+
49
+ def invalid_type(property, klass, value)
50
+ raise ValidationInvalidType,
51
+ "Property `#{property}' (value #{value.inspect}) did not match the required type `#{klass}'"
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh
4
+ module Director
5
+ VERSION = '1.5.0.pre.1113'
6
+ end
7
+ end
@@ -0,0 +1,80 @@
1
+ require 'common/deep_copy'
2
+
3
+ module Bosh::Director
4
+ # Creates VM model and call out to CPI to create VM in IaaS
5
+ class VmCreator
6
+ include EncryptionHelper
7
+
8
+ # this is used to retry VM creation on clouds that are unreliable (e.g. AWS)
9
+ MAX_CREATE_VM_TRIES = 5
10
+
11
+ def self.create(*args)
12
+ new.create(*args)
13
+ end
14
+
15
+ def initialize
16
+ @cloud = Config.cloud
17
+ @logger = Config.logger
18
+ end
19
+
20
+ def create(deployment, stemcell, cloud_properties, network_settings,
21
+ disks=nil, env={})
22
+ vm = nil
23
+ vm_cid = nil
24
+
25
+ env = Bosh::Common::DeepCopy.copy(env)
26
+
27
+ agent_id = self.class.generate_agent_id
28
+
29
+ options = {
30
+ :deployment => deployment,
31
+ :agent_id => agent_id,
32
+ :env => env
33
+ }
34
+
35
+ if Config.encryption?
36
+ credentials = generate_agent_credentials
37
+ env["bosh"] ||= {}
38
+ env["bosh"]["credentials"] = credentials
39
+ options[:credentials] = credentials
40
+ end
41
+
42
+ count = 0
43
+ begin
44
+ vm_cid = @cloud.create_vm(agent_id, stemcell.cid, cloud_properties, network_settings, disks, env)
45
+ rescue Bosh::Clouds::VMCreationFailed => e
46
+ count += 1
47
+ logger.error("failed to create VM, retrying (#{count})")
48
+ retry if e.ok_to_retry && count < MAX_CREATE_VM_TRIES
49
+ raise e
50
+ end
51
+
52
+ options[:cid] = vm_cid
53
+ vm = Models::Vm.new(options)
54
+
55
+ vm.save
56
+ VmMetadataUpdater.build.update(vm, {})
57
+ vm
58
+ rescue => e
59
+ logger.error("error creating vm: #{e.message}")
60
+ delete_vm(vm_cid) if vm_cid
61
+ vm.destroy if vm
62
+ raise e
63
+ end
64
+
65
+ def delete_vm(vm_cid)
66
+ @cloud.delete_vm(vm_cid)
67
+ rescue => e
68
+ logger.error("error cleaning up #{vm_cid}: #{e.message}\n#{e.backtrace.join("\n")}")
69
+ end
70
+
71
+ def self.generate_agent_id
72
+ SecureRandom.uuid
73
+ end
74
+
75
+ def logger
76
+ Config.logger
77
+ end
78
+
79
+ end
80
+ end