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,153 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module ProblemHandlers
5
+
6
+ class Base
7
+ include CloudcheckHelper
8
+
9
+ attr_reader :data
10
+ attr_accessor :job # so we can checkpoint task
11
+
12
+ def self.create_from_model(model)
13
+ create_by_type(model.type, model.resource_id, model.data)
14
+ end
15
+
16
+ # create_by_type might not be able to initialize
17
+ # problem handler if some part of its state
18
+ # or dependencies is invalid. In this case it
19
+ # just substitutes a generic "invalid_problem"
20
+ # handler that reports the fact that the original
21
+ # problem is invalid and offers closing it as
22
+ # the only solution.
23
+ def self.create_by_type(type, resource_id, data)
24
+ handler_class = Base.handlers[type.to_s]
25
+ if handler_class.nil?
26
+ raise "Cannot find handler for `#{type}' problem"
27
+ end
28
+
29
+ handler_class.new(resource_id, data)
30
+ rescue ProblemHandlerError => e
31
+ create_by_type(:invalid_problem, resource_id,
32
+ {"error" => e, "original_type" => type.to_s})
33
+ end
34
+
35
+ # Problem state is described by constructor parameters.
36
+ # Problem handler can reach out to check if the problem
37
+ # is still present and attempt to fix it by applying
38
+ # a potential resolution tagged with one or more labels.
39
+ def initialize(resource_id, data)
40
+ @logger = Config.logger
41
+ @event_log = Config.event_log
42
+ @job = nil
43
+ end
44
+
45
+ def checkpoint
46
+ @job.task_checkpoint if @job
47
+ end
48
+
49
+ # Talking to cloud should only be possible
50
+ # in the context of Resque job
51
+ def cloud
52
+ if @job.nil?
53
+ handler_error("Cannot talk to cloud outside of job context")
54
+ end
55
+ super
56
+ end
57
+
58
+ # Problem description
59
+ def description; end
60
+
61
+ def resolutions
62
+ self.class.resolutions.map do |name|
63
+ { :name => name.to_s, :plan => resolution_plan(name) }
64
+ end
65
+ end
66
+
67
+ def resolution_plan(resolution)
68
+ plan = self.class.plan_for(resolution)
69
+ return nil if plan.nil?
70
+ instance_eval(&plan)
71
+ end
72
+
73
+ def auto_resolution
74
+ self.class.get_auto_resolution
75
+ end
76
+
77
+ # @param resolution desired resolution
78
+ def apply_resolution(resolution)
79
+ action = self.class.action_for(resolution)
80
+ if action.nil?
81
+ handler_error("Cannot find `#{resolution}' resolution for `#{self.class}'")
82
+ end
83
+ instance_eval(&action)
84
+ end
85
+
86
+ def auto_resolve
87
+ apply_resolution(auto_resolution)
88
+ end
89
+
90
+ # Registration DSL
91
+ class << self
92
+ attr_accessor :handlers
93
+ end
94
+
95
+ def self.register_as(type)
96
+ Base.handlers ||= {}
97
+ Base.handlers[type.to_s] = self
98
+ end
99
+
100
+ # Resolution DSL
101
+ class << self
102
+ attr_reader :resolutions
103
+ end
104
+
105
+ def self.init_dsl_data
106
+ @resolutions = []
107
+ @plans = {}
108
+ @actions = {}
109
+ @auto_resolution = nil
110
+ end
111
+
112
+ init_dsl_data
113
+
114
+ def self.inherited(base)
115
+ base.class_eval { init_dsl_data }
116
+ end
117
+
118
+ def self.plan_for(resolution)
119
+ @plans[resolution.to_s]
120
+ end
121
+
122
+ def self.action_for(resolution)
123
+ @actions[resolution.to_s]
124
+ end
125
+
126
+ def self.plan(&block)
127
+ @plans[@pending_name.to_s] = block
128
+ end
129
+
130
+ def self.action(&block)
131
+ @actions[@pending_name.to_s] = block
132
+ end
133
+
134
+ def self.get_auto_resolution
135
+ @auto_resolution
136
+ end
137
+
138
+ def self.auto_resolution(name)
139
+ @auto_resolution = name
140
+ end
141
+
142
+ def self.resolution(name, &block)
143
+ @resolutions << name
144
+ @pending_name = name
145
+ instance_eval(&block)
146
+ ensure
147
+ @pending_name = nil
148
+ end
149
+
150
+ end
151
+ end
152
+ end
153
+
@@ -0,0 +1,112 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module ProblemHandlers
5
+ class InactiveDisk < Base
6
+
7
+ register_as :inactive_disk
8
+ auto_resolution :ignore
9
+
10
+ def initialize(disk_id, data)
11
+ super
12
+ @disk_id = disk_id
13
+ @data = data
14
+ @disk = Models::PersistentDisk[@disk_id]
15
+
16
+ if @disk.nil?
17
+ handler_error("Disk `#{@disk_id}' is no longer in the database")
18
+ end
19
+
20
+ if @disk.active
21
+ handler_error("Disk `#{@disk.disk_cid}' is no longer inactive")
22
+ end
23
+
24
+ @instance = @disk.instance
25
+ if @instance.nil?
26
+ handler_error("Cannot find instance for disk `#{@disk.disk_cid}'")
27
+ end
28
+
29
+ @vm = @instance.vm
30
+ end
31
+
32
+ def description
33
+ job = @instance.job || "unknown job"
34
+ index = @instance.index || "unknown index"
35
+ disk_label = "`#{@disk.disk_cid}' (#{job}/#{index}, #{@disk.size.to_i}M)"
36
+ "Disk #{disk_label} is inactive"
37
+ end
38
+
39
+ resolution :ignore do
40
+ plan { "Ignore problem" }
41
+ action { }
42
+ end
43
+
44
+ resolution :delete_disk do
45
+ plan { "Delete disk" }
46
+ action { delete_disk }
47
+ end
48
+
49
+ resolution :activate_disk do
50
+ plan { "Activate disk" }
51
+ action { activate_disk }
52
+ end
53
+
54
+ def activate_disk
55
+ unless disk_mounted?
56
+ handler_error("Disk is not mounted")
57
+ end
58
+ # Currently the director allows ONLY one persistent disk per
59
+ # instance. We are about to activate a disk but the instance already
60
+ # has an active disk.
61
+ # For now let's be conservative and return an error.
62
+ if @instance.persistent_disk
63
+ handler_error("Instance already has an active disk")
64
+ end
65
+ @disk.active = true
66
+ @disk.save
67
+ end
68
+
69
+ def delete_disk
70
+ if disk_mounted?
71
+ handler_error("Disk is currently in use")
72
+ end
73
+
74
+ if @vm
75
+ begin
76
+ cloud.detach_disk(@vm.cid, @disk.disk_cid)
77
+ rescue => e
78
+ # We are going to delete this disk anyway
79
+ # and we know it's not in use, so we can ignore
80
+ # detach errors here.
81
+ @logger.warn(e)
82
+ end
83
+ end
84
+
85
+ # FIXME: Currently there is no good way to know if delete_disk
86
+ # failed because of cloud error or because disk doesn't exist
87
+ # in vsphere_disks.
88
+ begin
89
+ cloud.delete_disk(@disk.disk_cid)
90
+ rescue Bosh::Clouds::DiskNotFound, RuntimeError => e # FIXME
91
+ @logger.warn(e)
92
+ end
93
+
94
+ @disk.destroy
95
+ end
96
+
97
+ def disk_mounted?
98
+ return false if @vm.nil?
99
+
100
+ begin
101
+ agent_timeout_guard(@vm) do |agent|
102
+ agent.list_disk.include?(@disk.disk_cid)
103
+ end
104
+ rescue RuntimeError
105
+ # old stemcells without 'list_disk' support. We need to play
106
+ # conservative and assume that the disk is mounted.
107
+ true
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module ProblemHandlers
5
+ class InvalidProblem < Base
6
+
7
+ register_as :invalid_problem
8
+ auto_resolution :close
9
+
10
+ def initialize(resource_id, data)
11
+ super
12
+ @resource_id = resource_id
13
+ @error = data["error"] || "unknown error"
14
+ @original_type = data["original_type"] || "unknown_type"
15
+ end
16
+
17
+ def description
18
+ "Problem (#{@original_type} #{@resource_id}) is no longer valid: #{@error}"
19
+ end
20
+
21
+ resolution :close do
22
+ plan { "Close problem" }
23
+ action { }
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module ProblemHandlers
5
+ class MissingVM < Base
6
+
7
+ register_as :missing_vm
8
+
9
+ def initialize(vm_id, data)
10
+ super
11
+ @vm = Models::Vm[vm_id]
12
+ end
13
+
14
+ resolution :ignore do
15
+ plan { "Ignore problem" }
16
+ action { }
17
+ end
18
+
19
+ resolution :recreate_vm do
20
+ plan { "Recreate VM using last known apply spec" }
21
+ action { recreate_vm(@vm) }
22
+ end
23
+
24
+ resolution :delete_vm_reference do
25
+ plan { "Delete VM reference (DANGEROUS!)" }
26
+ action { delete_vm_reference(@vm, skip_cid_check: true) }
27
+ end
28
+
29
+ def description
30
+ "VM with cloud ID `#{@vm.cid}' missing."
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,62 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module ProblemHandlers
5
+ class MountInfoMismatch < Base
6
+
7
+ register_as :mount_info_mismatch
8
+ auto_resolution :ignore
9
+
10
+ def initialize(disk_id, data)
11
+ @disk = Models::PersistentDisk[disk_id]
12
+ @data = data
13
+
14
+ if @disk.nil?
15
+ handler_error("Disk `#{disk_id}' is no longer in the database")
16
+ end
17
+
18
+ @disk_cid = @disk.disk_cid
19
+ @vm_cid = @disk.instance.vm.cid if @disk.instance && @disk.instance.vm
20
+ handler_error("Can't find corresponding vm-cid for disk `#{@disk_cid}'") if @vm_cid.nil?
21
+
22
+ @instance = @disk.instance
23
+ @vm = @instance.vm
24
+
25
+ @disk_owners = @data['owner_vms']
26
+ end
27
+
28
+ def description
29
+ out = "Inconsistent mount information:\n"
30
+ out += "Record shows that disk '#{@disk_cid}' should be mounted on #{@vm_cid}.\n"
31
+ out += "However it is currently :\n"
32
+
33
+ if @disk_owners.size == 0
34
+ out += "\tNot mounted in any VM"
35
+ else
36
+ out += "\tMounted on: #{@disk_owners.join(", ")}"
37
+ end
38
+ out
39
+ end
40
+
41
+ resolution :ignore do
42
+ plan { "Ignore" }
43
+ action { }
44
+ end
45
+
46
+ resolution :reattach_disk do
47
+ plan { "Reattach disk to instance" }
48
+ action { reattach_disk(false) }
49
+ end
50
+
51
+ resolution :reattach_disk_and_reboot do
52
+ plan { "Reattach disk and reboot instance" }
53
+ action { reattach_disk(true) }
54
+ end
55
+
56
+ def reattach_disk(reboot = false)
57
+ cloud.attach_disk(@vm_cid, @disk_cid)
58
+ reboot ? reboot_vm(@vm) : agent_timeout_guard(@vm) { |agent| agent.mount_disk(@disk_cid) }
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,64 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Director
4
+ module ProblemHandlers
5
+ class OutOfSyncVm < Base
6
+
7
+ register_as :out_of_sync_vm
8
+ auto_resolution :ignore
9
+
10
+ def initialize(vm_id, data)
11
+ super
12
+ @vm = Models::Vm[vm_id]
13
+ @data = data
14
+
15
+ if @vm.nil?
16
+ handler_error("VM `#{vm_id}' is no longer in the database")
17
+ end
18
+
19
+ @deployment = @vm.deployment
20
+ @instance = @vm.instance
21
+
22
+ if @deployment.nil?
23
+ handler_error("VM `#{@vm.cid}' doesn't belong to any deployment")
24
+ end
25
+
26
+ end
27
+
28
+ def description
29
+ actual_deployment = @data["deployment"] || "unknown deployment"
30
+ actual_job = @data["job"] || "unknown job"
31
+ actual_index = @data["index"] || "unknown index"
32
+
33
+ expected = "#{@deployment.name}: #{instance_name(@vm)}"
34
+ actual = "#{actual_deployment}: #{actual_job}/#{actual_index}"
35
+
36
+ "VM `#{@vm.cid}' is out of sync: expected `#{expected}', got `#{actual}'"
37
+ end
38
+
39
+ resolution :ignore do
40
+ plan { "Ignore problem" }
41
+ action { }
42
+ end
43
+
44
+ resolution :delete_vm do
45
+ plan { "Delete VM (unless it has persistent disk)"}
46
+ action { validate; delete_vm(@vm) }
47
+ end
48
+
49
+ def validate
50
+ state = agent_timeout_guard(@vm) { |agent | agent.get_state }
51
+ return if state["deployment"] != @deployment.name
52
+
53
+ # VM is no longer out of sync if no instance is referencing it,
54
+ # as this situation can actually be handled by regular deployment
55
+ if @instance.nil? ||
56
+ state["job"] && state["job"]["name"] == @instance.job &&
57
+ state["index"] == @instance.index
58
+ handler_error("VM is now back in sync")
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end