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,109 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module Jobs
5
+ class UpdateStemcell < BaseJob
6
+ include ValidationHelper
7
+ include DownloadHelper
8
+
9
+ UPDATE_STEPS = 5
10
+
11
+ @queue = :normal
12
+
13
+ def self.job_type
14
+ :update_stemcell
15
+ end
16
+
17
+ # @param [String] stemcell_file Stemcell tarball path
18
+ def initialize(stemcell_file, options = {})
19
+ @stemcell_file = stemcell_file
20
+ @cloud = Config.cloud
21
+ @stemcell_manager = Api::StemcellManager.new
22
+ @remote_stemcell = options['remote'] || false
23
+ end
24
+
25
+ def perform
26
+ logger.info("Processing update stemcell")
27
+ event_log.begin_stage("Update stemcell", update_steps)
28
+
29
+ if @remote_stemcell
30
+ downloaded_stemcell_dir = Dir.mktmpdir("downloaded-stemcell")
31
+ download_remote_stemcell(downloaded_stemcell_dir)
32
+ end
33
+
34
+ stemcell_dir = Dir.mktmpdir("stemcell")
35
+
36
+ track_and_log("Extracting stemcell archive") do
37
+ result = Bosh::Exec.sh("tar -C #{stemcell_dir} -xzf #{@stemcell_file} 2>&1", :on_error => :return)
38
+ if result.failed?
39
+ logger.error("Extracting stemcell archive failed in dir #{stemcell_dir}, " +
40
+ "tar returned #{result.exit_status}, " +
41
+ "output: #{result.output}")
42
+ raise StemcellInvalidArchive, "Extracting stemcell archive failed. Check task debug log for details."
43
+ end
44
+ end
45
+
46
+ track_and_log("Verifying stemcell manifest") do
47
+ stemcell_manifest_file = File.join(stemcell_dir, "stemcell.MF")
48
+ stemcell_manifest = Psych.load_file(stemcell_manifest_file)
49
+
50
+ @name = safe_property(stemcell_manifest, "name", :class => String)
51
+ @version = safe_property(stemcell_manifest, "version", :class => String)
52
+ @cloud_properties = safe_property(stemcell_manifest, "cloud_properties", :class => Hash, :optional => true)
53
+ @sha1 = safe_property(stemcell_manifest, "sha1", :class => String)
54
+
55
+ logger.info("Found stemcell image `#{@name}/#{@version}', " +
56
+ "cloud properties are #{@cloud_properties.inspect}")
57
+
58
+ logger.info("Verifying stemcell image")
59
+ @stemcell_image = File.join(stemcell_dir, "image")
60
+ unless File.file?(@stemcell_image)
61
+ raise StemcellImageNotFound, "Stemcell image not found"
62
+ end
63
+ end
64
+
65
+ track_and_log("Checking if this stemcell already exists") do
66
+ if @stemcell_manager.stemcell_exists?(@name, @version)
67
+ raise StemcellAlreadyExists,
68
+ "Stemcell `#{@name}/#{@version}' already exists"
69
+ end
70
+ end
71
+
72
+ stemcell = Models::Stemcell.new
73
+ stemcell.name = @name
74
+ stemcell.version = @version
75
+ stemcell.sha1 = @sha1
76
+
77
+ track_and_log("Uploading stemcell #{@name}/#{@version} to the cloud") do
78
+ stemcell.cid =
79
+ @cloud.create_stemcell(@stemcell_image, @cloud_properties)
80
+ logger.info("Cloud created stemcell: #{stemcell.cid}")
81
+ end
82
+
83
+ track_and_log("Save stemcell #{@name}/#{@version} (#{stemcell.cid})") do
84
+ stemcell.save
85
+ end
86
+
87
+ "/stemcells/#{stemcell.name}/#{stemcell.version}"
88
+ ensure
89
+ FileUtils.rm_rf(stemcell_dir) if stemcell_dir
90
+ FileUtils.rm_rf(downloaded_stemcell_dir) if downloaded_stemcell_dir
91
+ FileUtils.rm_rf(@stemcell_file) if @stemcell_file
92
+ end
93
+
94
+ def download_remote_stemcell(downloaded_stemcell_dir)
95
+ track_and_log("Downloading remote stemcell") do
96
+ downloaded_stemcell_file = File.join(downloaded_stemcell_dir, "stemcell-#{SecureRandom.uuid}")
97
+ download_remote_file('stemcell', @stemcell_file, downloaded_stemcell_file)
98
+ @stemcell_file = downloaded_stemcell_file
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def update_steps
105
+ @remote_stemcell ? UPDATE_STEPS + 1 : UPDATE_STEPS
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,89 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module Jobs
5
+ class VmState < BaseJob
6
+ TIMEOUT = 5
7
+
8
+ @queue = :normal
9
+
10
+ def self.job_type
11
+ :vms
12
+ end
13
+
14
+ # @param [Integer] deployment_id Deployment id
15
+ def initialize(deployment_id, format)
16
+ @deployment_id = deployment_id
17
+ @format = format
18
+ end
19
+
20
+ def perform
21
+ @domain = Models::Dns::Domain.find(name: Config.dns_domain_name, type: "NATIVE") if Config.dns_enabled?
22
+
23
+ vms = Models::Vm.filter(:deployment_id => @deployment_id)
24
+ ThreadPool.new(:max_threads => Config.max_threads).wrap do |pool|
25
+ vms.each do |vm|
26
+ pool.process do
27
+ vm_state = process_vm(vm)
28
+ result_file.write(vm_state.to_json + "\n")
29
+ end
30
+ end
31
+ end
32
+
33
+ # task result
34
+ nil
35
+ end
36
+
37
+ def process_vm(vm)
38
+ ips = []
39
+ dns_records = []
40
+ job_name = nil
41
+ job_state = nil
42
+ resource_pool = nil
43
+ job_vitals = nil
44
+ index = nil
45
+
46
+ begin
47
+ agent = AgentClient.new(vm.agent_id, :timeout => TIMEOUT)
48
+ agent_state = agent.get_state(@format)
49
+ agent_state["networks"].each_value do |network|
50
+ ips << network["ip"]
51
+ end
52
+ index = agent_state["index"]
53
+ job_name = agent_state["job"]["name"] if agent_state["job"]
54
+ job_state = agent_state["job_state"]
55
+ if agent_state["resource_pool"]
56
+ resource_pool = agent_state["resource_pool"]["name"]
57
+ end
58
+ if agent_state["vitals"]
59
+ job_vitals = agent_state["vitals"]
60
+ end
61
+ rescue Bosh::Director::RpcTimeout
62
+ job_state = "unresponsive agent"
63
+ end
64
+
65
+ instance = Models::Instance.find(deployment_id: @deployment_id, job: job_name, index: index)
66
+
67
+ if @domain
68
+ ips.each do |ip|
69
+ records = Models::Dns::Record.filter(domain_id: @domain.id, type: "A", content: ip)
70
+ dns_records << records.collect { |record| record.name } unless records.empty?
71
+ end
72
+ end
73
+
74
+ {
75
+ :vm_cid => vm.cid,
76
+ :ips => ips,
77
+ :dns => dns_records.flatten,
78
+ :agent_id => vm.agent_id,
79
+ :job_name => job_name,
80
+ :index => index,
81
+ :job_state => job_state,
82
+ :resource_pool => resource_pool,
83
+ :vitals => job_vitals,
84
+ :resurrection_paused => instance ? instance.resurrection_paused : nil,
85
+ }
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,133 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+
5
+ # Distributed lock backed by Redis.
6
+ class Lock
7
+
8
+ # Error returned when Lock could not be acquired.
9
+ class TimeoutError < StandardError; end
10
+
11
+ # Creates new lock with the given name.
12
+ #
13
+ # @param name lock name
14
+ # @option opts [Number] timeout how long to wait before giving up
15
+ # @option opts [Number] expiration how long to wait before expiring an old
16
+ # lock
17
+ def initialize(name, opts = {})
18
+ @name = name
19
+ @id = SecureRandom.uuid
20
+ @timeout = opts[:timeout] || 1.0
21
+ @expiration = opts[:expiration] || 10.0
22
+ @logger = Config.logger
23
+ @refresh_thread = nil
24
+ end
25
+
26
+ # Acquire a lock.
27
+ #
28
+ # @yield [void] optional block to do work before automatically releasing
29
+ # the lock.
30
+ # @return [void]
31
+ def lock
32
+ acquire
33
+
34
+ @refresh_thread = Thread.new do
35
+ redis = Config.redis
36
+ sleep_interval = [1.0, @expiration/2].max
37
+ begin
38
+ loop do
39
+ @logger.debug("Renewing lock: #@name")
40
+ redis.watch(@name)
41
+ existing_lock = redis.get(@name)
42
+ lock_id = existing_lock.split(":")[1]
43
+ break if lock_id != @id
44
+ lock_expiration = Time.now.to_f + @expiration + 1
45
+ redis.multi do
46
+ redis.set(@name, "#{lock_expiration}:#@id")
47
+ end
48
+ sleep(sleep_interval)
49
+ end
50
+ ensure
51
+ @logger.debug("Lock renewal thread exiting")
52
+ redis.quit
53
+ end
54
+ end
55
+
56
+ if block_given?
57
+ begin
58
+ yield
59
+ ensure
60
+ release
61
+ end
62
+ end
63
+ end
64
+
65
+ # Release a lock that was not auto released by the lock method.
66
+ #
67
+ # @return [void]
68
+ def release
69
+ @refresh_thread.exit if @refresh_thread
70
+ delete
71
+ end
72
+
73
+ private
74
+
75
+ def acquire
76
+ @logger.debug("Acquiring lock: #@name")
77
+ redis = Config.redis
78
+ started = Time.now
79
+
80
+ lock_expiration = Time.now.to_f + @expiration + 1
81
+ until redis.setnx(@name, "#{lock_expiration}:#@id")
82
+ existing_lock = redis.get(@name)
83
+ @logger.debug("Lock #@name is already locked by someone " +
84
+ "else: #{existing_lock}")
85
+ if lock_expired?(existing_lock)
86
+ @logger.debug("Lock #@name is already expired, " +
87
+ "trying to take it back")
88
+ replaced_lock = redis.getset(@name, "#{lock_expiration}:#@id")
89
+ if replaced_lock == existing_lock
90
+ @logger.debug("Lock #@name was revoked and relocked")
91
+ break
92
+ else
93
+ @logger.debug("Lock #@name was acquired by someone else, " +
94
+ "trying again")
95
+ end
96
+ end
97
+
98
+ raise TimeoutError if Time.now - started > @timeout
99
+
100
+ sleep(0.5)
101
+
102
+ lock_expiration = Time.now.to_f + @expiration + 1
103
+ end
104
+
105
+ @lock_expiration = lock_expiration
106
+ @logger.debug("Acquired lock: #@name")
107
+ end
108
+
109
+ def delete
110
+ @logger.debug("Deleting lock: #@name")
111
+ redis = Config.redis
112
+
113
+ redis.watch(@name)
114
+ existing_lock = redis.get(@name)
115
+ lock_id = existing_lock.split(":")[1]
116
+ if lock_id == @id
117
+ redis.multi do
118
+ redis.del(@name)
119
+ end
120
+ else
121
+ redis.unwatch
122
+ end
123
+ @logger.debug("Deleted lock: #@name")
124
+ end
125
+
126
+ def lock_expired?(lock)
127
+ existing_lock_expiration = lock.split(":")[0].to_f
128
+ lock_time_left = existing_lock_expiration - Time.now.to_f
129
+ @logger.info("Lock: #{lock} expires in #{lock_time_left} seconds")
130
+ lock_time_left < 0
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,92 @@
1
+ module Bosh::Director
2
+ # Helper for managing BOSH locks.
3
+ module LockHelper
4
+
5
+ # Surround with deployment lock.
6
+ #
7
+ # @param [DeploymentPlan|String] deployment plan or name.
8
+ # @option opts [Number] timeout how long to wait before giving up
9
+ # @return [void]
10
+ # @yield [void] block to surround
11
+ def with_deployment_lock(deployment, opts = {})
12
+ if deployment.respond_to?(:name)
13
+ name = deployment.name
14
+ elsif deployment.kind_of?(String)
15
+ name = deployment
16
+ else
17
+ raise ArgumentError, "invalid deployment: #{deployment}"
18
+ end
19
+ timeout = opts[:timeout] || 10
20
+ Config.logger.info("Acquiring deployment lock on #{name}")
21
+ Lock.new("lock:deployment:#{name}", :timeout => timeout).lock { yield }
22
+ end
23
+
24
+ # Surround with stemcell lock.
25
+ #
26
+ # @param [String] name stemcell name.
27
+ # @param [String] version stemcell version.
28
+ # @option opts [Number] timeout how long to wait before giving up
29
+ # @return [void]
30
+ # @yield [void] block to surround
31
+ def with_stemcell_lock(name, version, opts = {})
32
+ timeout = opts[:timeout] || 10
33
+ Config.logger.info("Acquiring deployment lock on #{name}:#{version}")
34
+ Lock.new("lock:stemcells:#{name}:#{version}", :timeout => timeout).
35
+ lock { yield }
36
+ end
37
+
38
+ # Surround with release lock.
39
+ #
40
+ # @param [String] release name.
41
+ # @option opts [Number] timeout how long to wait before giving up
42
+ # @return [void]
43
+ # @yield [void] block to surround
44
+ def with_release_lock(release, opts = {})
45
+ timeout = opts[:timeout] || 10
46
+ Config.logger.info("Acquiring deployment lock on #{release}")
47
+ Lock.new("lock:release:#{release}", :timeout => timeout).lock { yield }
48
+ end
49
+
50
+ # Surround with deployment releases lock.
51
+ #
52
+ # @param [DeploymentPlan] deployment plan.
53
+ # @option opts [Number] timeout how long to wait before giving up
54
+ # @return [void]
55
+ # @yield [void] block to surround
56
+ def with_release_locks(deployment_plan, opts = {})
57
+ timeout = opts[:timeout] || 10
58
+ release_names = deployment_plan.releases.map do |release|
59
+ release.name
60
+ end
61
+
62
+ # Sorting to enforce lock order to avoid deadlocks
63
+ locks = release_names.sort.map do |release_name|
64
+ Config.logger.info("Acquiring release lock: #{release_name}")
65
+ Lock.new("lock:release:#{release_name}", :timeout => timeout)
66
+ end
67
+
68
+ begin
69
+ locks.each { |lock| lock.lock }
70
+ yield
71
+ ensure
72
+ locks.reverse_each { |lock| lock.release }
73
+ end
74
+ end
75
+
76
+ # Surround with compile lock.
77
+ #
78
+ # @param [String|Number] package_id package id.
79
+ # @param [String|Number] stemcell_id stemcell id.
80
+ # @option opts [Number] timeout how long to wait before giving up
81
+ # @return [void]
82
+ # @yield [void] block to surround
83
+ def with_compile_lock(package_id, stemcell_id, opts = {})
84
+ timeout = opts[:timeout] || 15 * 60 # 15 minutes
85
+
86
+ Config.logger.info("Acquiring compile lock on " +
87
+ "#{package_id} #{stemcell_id}")
88
+ Lock.new("lock:compile:#{package_id}:#{stemcell_id}",
89
+ :timeout => timeout).lock { yield }
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+ #
3
+
4
+ require 'bosh/director/models/compiled_package'
5
+ require 'bosh/director/models/deployment'
6
+ require 'bosh/director/models/deployment_problem'
7
+ require 'bosh/director/models/deployment_property'
8
+ require 'bosh/director/models/instance'
9
+ require 'bosh/director/models/log_bundle'
10
+ require 'bosh/director/models/package'
11
+ require 'bosh/director/models/release'
12
+ require 'bosh/director/models/release_version'
13
+ require 'bosh/director/models/stemcell'
14
+ require 'bosh/director/models/snapshot'
15
+ require 'bosh/director/models/task'
16
+ require 'bosh/director/models/template'
17
+ require 'bosh/director/models/user'
18
+ require 'bosh/director/models/vm'
19
+ require 'bosh/director/models/persistent_disk'
20
+ require 'bosh/director/models/director_attribute'
21
+
22
+ module Bosh::Director
23
+ module Models
24
+ VALID_ID = /^[-a-z0-9_.]+$/i
25
+
26
+ autoload :Dns, 'bosh/director/models/dns'
27
+ end
28
+ end
29
+