bosh-director 1.3160.0 → 1.3163.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bosh-director-worker +2 -14
- data/db/migrations/director/20150513225143_ip_addresses.rb +11 -0
- data/db/migrations/director/20150702004608_add_links.rb +8 -0
- data/db/migrations/director/20150708231924_add_link_spec.rb +7 -0
- data/db/migrations/director/20150724183256_add_debugging_to_ip_addresses.rb +8 -0
- data/db/migrations/director/20150730225029_add_uuid_to_instances.rb +16 -0
- data/db/migrations/director/20150803215805_add_availabililty_zone_and_cloud_properties_to_instances.rb +8 -0
- data/db/migrations/director/20150804211419_add_compilation_flag_to_instance.rb +7 -0
- data/db/migrations/director/20150918003455_add_bootstrap_node_to_instance.rb +7 -0
- data/db/migrations/director/20151008232214_add_dns_records.rb +7 -0
- data/db/migrations/director/20151015172551_add_orphan_disks_and_snapshots.rb +29 -0
- data/db/migrations/director/20151030222853_add_templates_to_instance.rb +10 -0
- data/db/migrations/director/20151031001039_add_spec_to_instance.rb +19 -0
- data/db/migrations/director/20151109190602_rename_orphan_columns.rb +13 -0
- data/lib/bosh/director.rb +19 -9
- data/lib/bosh/director/agent_client.rb +0 -17
- data/lib/bosh/director/api/cloud_config_manager.rb +7 -5
- data/lib/bosh/director/api/controllers/base_controller.rb +3 -2
- data/lib/bosh/director/api/controllers/cleanup_controller.rb +15 -0
- data/lib/bosh/director/api/controllers/deployments_controller.rb +38 -26
- data/lib/bosh/director/api/controllers/disks_controller.rb +20 -0
- data/lib/bosh/director/api/controllers/info_controller.rb +2 -2
- data/lib/bosh/director/api/controllers/releases_controller.rb +1 -16
- data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -9
- data/lib/bosh/director/api/deployment_manager.rb +2 -1
- data/lib/bosh/director/api/instance_lookup.rb +17 -0
- data/lib/bosh/director/api/instance_manager.rb +20 -10
- data/lib/bosh/director/api/release_manager.rb +28 -8
- data/lib/bosh/director/api/resurrector_manager.rb +9 -2
- data/lib/bosh/director/api/route_configuration.rb +2 -0
- data/lib/bosh/director/api/snapshot_manager.rb +9 -5
- data/lib/bosh/director/api/stemcell_manager.rb +50 -0
- data/lib/bosh/director/app.rb +1 -1
- data/lib/bosh/director/cloudcheck_helper.rb +119 -132
- data/lib/bosh/director/compile_task.rb +1 -1
- data/lib/bosh/director/compile_task_generator.rb +2 -2
- data/lib/bosh/director/config.rb +21 -12
- data/lib/bosh/director/deployment_deleter.rb +69 -0
- data/lib/bosh/director/deployment_plan.rb +35 -4
- data/lib/bosh/director/deployment_plan/agent_state_migrator.rb +47 -0
- data/lib/bosh/director/deployment_plan/assembler.rb +115 -241
- data/lib/bosh/director/deployment_plan/availability_zone.rb +27 -0
- data/lib/bosh/director/deployment_plan/cloud_manifest_parser.rb +144 -35
- data/lib/bosh/director/deployment_plan/compilation_config.rb +21 -19
- data/lib/bosh/director/deployment_plan/compilation_instance_pool.rb +169 -0
- data/lib/bosh/director/deployment_plan/deployment_repo.rb +4 -8
- data/lib/bosh/director/deployment_plan/deployment_spec_parser.rb +13 -1
- data/lib/bosh/director/deployment_plan/deployment_validator.rb +17 -0
- data/lib/bosh/director/deployment_plan/desired_instance.rb +15 -0
- data/lib/bosh/director/deployment_plan/{disk_pool.rb → disk_type.rb} +14 -19
- data/lib/bosh/director/deployment_plan/dynamic_network.rb +105 -53
- data/lib/bosh/director/deployment_plan/dynamic_network_subnet.rb +13 -0
- data/lib/bosh/director/deployment_plan/env.rb +18 -0
- data/lib/bosh/director/deployment_plan/global_network_resolver.rb +77 -0
- data/lib/bosh/director/deployment_plan/instance.rb +222 -390
- data/lib/bosh/director/deployment_plan/instance_network_reservations.rb +71 -0
- data/lib/bosh/director/deployment_plan/instance_plan.rb +336 -0
- data/lib/bosh/director/deployment_plan/instance_plan_factory.rb +54 -0
- data/lib/bosh/director/deployment_plan/instance_plan_sorter.rb +61 -0
- data/lib/bosh/director/deployment_plan/instance_planner.rb +101 -0
- data/lib/bosh/director/deployment_plan/instance_repository.rb +36 -0
- data/lib/bosh/director/deployment_plan/instance_spec.rb +154 -0
- data/lib/bosh/director/deployment_plan/ip_provider/database_ip_repo.rb +136 -0
- data/lib/bosh/director/deployment_plan/ip_provider/in_memory_ip_repo.rb +81 -0
- data/lib/bosh/director/deployment_plan/ip_provider/ip_provider.rb +153 -0
- data/lib/bosh/director/deployment_plan/ip_provider/ip_provider_factory.rb +22 -0
- data/lib/bosh/director/deployment_plan/job.rb +116 -53
- data/lib/bosh/director/deployment_plan/job_availability_zone_parser.rb +49 -0
- data/lib/bosh/director/deployment_plan/job_migrator.rb +90 -0
- data/lib/bosh/director/deployment_plan/job_network.rb +42 -0
- data/lib/bosh/director/deployment_plan/job_network_parser.rb +118 -0
- data/lib/bosh/director/deployment_plan/job_spec_parser.rb +123 -126
- data/lib/bosh/director/deployment_plan/links/link.rb +30 -0
- data/lib/bosh/director/deployment_plan/links/link_lookup.rb +66 -0
- data/lib/bosh/director/deployment_plan/links/link_path.rb +27 -0
- data/lib/bosh/director/deployment_plan/links/links_resolver.rb +70 -0
- data/lib/bosh/director/deployment_plan/links/template_link.rb +21 -0
- data/lib/bosh/director/deployment_plan/manifest_migrator.rb +3 -17
- data/lib/bosh/director/deployment_plan/manifest_validator.rb +46 -0
- data/lib/bosh/director/deployment_plan/manual_network.rb +70 -97
- data/lib/bosh/director/deployment_plan/manual_network_subnet.rb +148 -0
- data/lib/bosh/director/deployment_plan/network.rb +50 -39
- data/lib/bosh/director/deployment_plan/network_planner.rb +4 -0
- data/lib/bosh/director/deployment_plan/network_planner/plan.rb +26 -0
- data/lib/bosh/director/deployment_plan/network_planner/planner.rb +21 -0
- data/lib/bosh/director/deployment_plan/network_planner/reservation_reconciler.rb +81 -0
- data/lib/bosh/director/deployment_plan/network_planner/vip_static_ips_planner.rb +50 -0
- data/lib/bosh/director/deployment_plan/network_settings.rb +65 -0
- data/lib/bosh/director/deployment_plan/options/skip_drain.rb +7 -0
- data/lib/bosh/director/deployment_plan/package_validator.rb +79 -0
- data/lib/bosh/director/deployment_plan/placement_planner.rb +8 -0
- data/lib/bosh/director/deployment_plan/placement_planner/availability_zone_picker.rb +90 -0
- data/lib/bosh/director/deployment_plan/placement_planner/bruteforce_ip_allocation.rb +124 -0
- data/lib/bosh/director/deployment_plan/placement_planner/index_assigner.rb +32 -0
- data/lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb +125 -0
- data/lib/bosh/director/deployment_plan/placement_planner/placed_desired_instances.rb +40 -0
- data/lib/bosh/director/deployment_plan/placement_planner/plan.rb +42 -0
- data/lib/bosh/director/deployment_plan/placement_planner/static_ips_availability_zone_picker.rb +237 -0
- data/lib/bosh/director/deployment_plan/placement_planner/unplaced_existing_instances.rb +53 -0
- data/lib/bosh/director/deployment_plan/planner.rb +186 -74
- data/lib/bosh/director/deployment_plan/planner_factory.rb +30 -147
- data/lib/bosh/director/deployment_plan/release_version.rb +3 -3
- data/lib/bosh/director/deployment_plan/resource_pool.rb +2 -174
- data/lib/bosh/director/deployment_plan/stemcell.rb +57 -14
- data/lib/bosh/director/deployment_plan/steps/package_compile_step.rb +28 -135
- data/lib/bosh/director/deployment_plan/steps/update_step.rb +23 -44
- data/lib/bosh/director/deployment_plan/template.rb +15 -4
- data/lib/bosh/director/deployment_plan/vip_network.rb +14 -42
- data/lib/bosh/director/deployment_plan/vm.rb +1 -99
- data/lib/bosh/director/deployment_plan/vm_type.rb +27 -0
- data/lib/bosh/director/disk_manager.rb +268 -0
- data/lib/bosh/director/dns/canonicalizer.rb +28 -0
- data/lib/bosh/director/dns/dns_manager.rb +163 -0
- data/lib/bosh/director/dns/local_dns_repo.rb +20 -0
- data/lib/bosh/director/dns/powerdns.rb +170 -0
- data/lib/bosh/director/errand/job_manager.rb +18 -29
- data/lib/bosh/director/error_ignorer.rb +16 -0
- data/lib/bosh/director/errors.rb +51 -20
- data/lib/bosh/director/event_log.rb +6 -0
- data/lib/bosh/director/instance_deleter.rb +53 -81
- data/lib/bosh/director/instance_reuser.rb +89 -0
- data/lib/bosh/director/instance_updater.rb +139 -281
- data/lib/bosh/director/instance_updater/preparer.rb +8 -5
- data/lib/bosh/director/instance_updater/state_applier.rb +21 -0
- data/lib/bosh/director/ip_util.rb +46 -26
- data/lib/bosh/director/job_renderer.rb +22 -10
- data/lib/bosh/director/job_runner.rb +1 -4
- data/lib/bosh/director/job_updater.rb +47 -35
- data/lib/bosh/director/job_updater_factory.rb +5 -4
- data/lib/bosh/director/jobs/base_job.rb +8 -0
- data/lib/bosh/director/jobs/cleanup_artifacts.rb +93 -0
- data/lib/bosh/director/jobs/delete_deployment.rb +10 -154
- data/lib/bosh/director/jobs/delete_deployment_snapshots.rb +1 -1
- data/lib/bosh/director/jobs/delete_orphan_disks.rb +44 -0
- data/lib/bosh/director/jobs/delete_release.rb +19 -196
- data/lib/bosh/director/jobs/delete_stemcell.rb +10 -76
- data/lib/bosh/director/jobs/export_release.rb +41 -121
- data/lib/bosh/director/jobs/fetch_logs.rb +0 -6
- data/lib/bosh/director/jobs/helpers.rb +10 -0
- data/lib/bosh/director/jobs/helpers/blob_deleter.rb +24 -0
- data/lib/bosh/director/jobs/helpers/compiled_package_deleter.rb +24 -0
- data/lib/bosh/director/jobs/helpers/name_version_release_deleter.rb +48 -0
- data/lib/bosh/director/jobs/helpers/package_deleter.rb +33 -0
- data/lib/bosh/director/jobs/helpers/release_deleter.rb +52 -0
- data/lib/bosh/director/jobs/helpers/release_version_deleter.rb +115 -0
- data/lib/bosh/director/jobs/helpers/releases_to_delete_picker.rb +31 -0
- data/lib/bosh/director/jobs/helpers/stemcell_deleter.rb +61 -0
- data/lib/bosh/director/jobs/helpers/stemcells_to_delete_picker.rb +30 -0
- data/lib/bosh/director/jobs/helpers/template_deleter.rb +20 -0
- data/lib/bosh/director/jobs/release/release_job.rb +18 -7
- data/lib/bosh/director/jobs/run_errand.rb +57 -36
- data/lib/bosh/director/jobs/scheduled_orphan_cleanup.rb +46 -0
- data/lib/bosh/director/jobs/ssh.rb +50 -17
- data/lib/bosh/director/jobs/update_deployment.rb +29 -11
- data/lib/bosh/director/jobs/update_release.rb +25 -4
- data/lib/bosh/director/jobs/vm_state.rb +23 -32
- data/lib/bosh/director/lock.rb +13 -8
- data/lib/bosh/director/logs_fetcher.rb +1 -1
- data/lib/bosh/director/models.rb +3 -0
- data/lib/bosh/director/models/compiled_package.rb +3 -3
- data/lib/bosh/director/models/deployment.rb +10 -0
- data/lib/bosh/director/models/instance.rb +77 -1
- data/lib/bosh/director/models/ip_address.rb +26 -0
- data/lib/bosh/director/models/orphan_disk.rb +23 -0
- data/lib/bosh/director/models/orphan_snapshot.rb +14 -0
- data/lib/bosh/director/models/template.rb +32 -9
- data/lib/bosh/director/models/vm.rb +5 -8
- data/lib/bosh/director/network_reservation.rb +69 -99
- data/lib/bosh/director/problem_handlers/inactive_disk.rb +5 -20
- data/lib/bosh/director/problem_handlers/missing_disk.rb +2 -13
- data/lib/bosh/director/problem_resolver.rb +2 -2
- data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +2 -21
- data/lib/bosh/director/scheduler.rb +23 -6
- data/lib/bosh/director/{instance_updater/stopper.rb → stopper.rb} +24 -18
- data/lib/bosh/director/tagged_logger.rb +30 -0
- data/lib/bosh/director/transactor.rb +9 -0
- data/lib/bosh/director/version.rb +1 -1
- data/lib/bosh/director/vm_creator.rb +91 -19
- data/lib/bosh/director/vm_deleter.rb +25 -0
- data/lib/bosh/director/vm_recreator.rb +15 -0
- data/lib/cloud/dummy.rb +381 -94
- metadata +110 -30
- data/lib/bosh/director/deployment_plan/dns_binder.rb +0 -45
- data/lib/bosh/director/deployment_plan/instance_vm_binder.rb +0 -37
- data/lib/bosh/director/deployment_plan/network_subnet.rb +0 -166
- data/lib/bosh/director/deployment_plan/resource_pools.rb +0 -68
- data/lib/bosh/director/dns_helper.rb +0 -223
- data/lib/bosh/director/instance_updater/network_updater.rb +0 -110
- data/lib/bosh/director/instance_updater/vm_updater.rb +0 -189
- data/lib/bosh/director/problem_handlers/out_of_sync_vm.rb +0 -64
- data/lib/bosh/director/problem_handlers/unbound_instance_vm.rb +0 -85
- data/lib/bosh/director/resource_pool_updater.rb +0 -174
- data/lib/bosh/director/vm_data.rb +0 -63
- data/lib/bosh/director/vm_reuser.rb +0 -63
@@ -1,15 +1,15 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Bosh::Director
|
2
4
|
module DeploymentPlan
|
3
5
|
# Represents a single job instance.
|
4
6
|
class Instance
|
5
|
-
include DnsHelper
|
6
|
-
|
7
|
-
# @return [DeploymentPlan::Job] Associated job
|
8
|
-
attr_reader :job
|
9
7
|
|
10
8
|
# @return [Integer] Instance index
|
11
9
|
attr_reader :index
|
12
10
|
|
11
|
+
attr_reader :uuid
|
12
|
+
|
13
13
|
# @return [Models::Instance] Instance model
|
14
14
|
attr_reader :model
|
15
15
|
|
@@ -22,350 +22,251 @@ module Bosh::Director
|
|
22
22
|
# @return [Bosh::Director::Core::Templates::RenderedTemplatesArchive]
|
23
23
|
attr_accessor :rendered_templates_archive
|
24
24
|
|
25
|
-
# @return [Hash<String, NetworkReservation>] network reservations
|
26
|
-
attr_accessor :network_reservations
|
27
|
-
|
28
25
|
# @return [String] job state
|
29
|
-
|
26
|
+
attr_reader :virtual_state
|
30
27
|
|
31
|
-
# @return [Hash] current state as provided by the BOSH Agent
|
32
28
|
attr_reader :current_state
|
33
29
|
|
30
|
+
attr_reader :availability_zone
|
31
|
+
|
34
32
|
# @return [DeploymentPlan::Vm] Associated resource pool VM
|
35
33
|
attr_reader :vm
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
35
|
+
attr_reader :existing_network_reservations
|
36
|
+
|
37
|
+
def self.create_from_job(job, index, virtual_state, deployment_model, instance_state, availability_zone, logger)
|
38
|
+
new(
|
39
|
+
job.name,
|
40
|
+
index,
|
41
|
+
virtual_state,
|
42
|
+
job.vm_type,
|
43
|
+
job.stemcell,
|
44
|
+
job.env,
|
45
|
+
job.compilation?,
|
46
|
+
deployment_model,
|
47
|
+
instance_state,
|
48
|
+
availability_zone,
|
49
|
+
logger
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(
|
54
|
+
job_name,
|
55
|
+
index,
|
56
|
+
virtual_state,
|
57
|
+
vm_type,
|
58
|
+
stemcell,
|
59
|
+
env,
|
60
|
+
compilation,
|
61
|
+
deployment_model,
|
62
|
+
instance_state,
|
63
|
+
availability_zone,
|
64
|
+
logger
|
65
|
+
)
|
48
66
|
@index = index
|
67
|
+
@availability_zone = availability_zone
|
49
68
|
@logger = logger
|
69
|
+
@deployment_model = deployment_model
|
70
|
+
@job_name = job_name
|
71
|
+
@name = "#{job_name}/#{@index}"
|
72
|
+
@vm_type = vm_type
|
73
|
+
@stemcell = stemcell
|
74
|
+
@env = env
|
75
|
+
@compilation = compilation
|
50
76
|
|
51
77
|
@configuration_hash = nil
|
52
78
|
@template_hashes = nil
|
53
79
|
@vm = nil
|
54
|
-
@current_state =
|
80
|
+
@current_state = instance_state || {}
|
55
81
|
|
56
|
-
|
57
|
-
@
|
82
|
+
# reservation generated from current state/DB
|
83
|
+
@existing_network_reservations = InstanceNetworkReservations.new(logger)
|
84
|
+
@dns_manager = DnsManager.create
|
58
85
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
86
|
+
@virtual_state = virtual_state
|
87
|
+
end
|
88
|
+
|
89
|
+
def bootstrap?
|
90
|
+
@model && @model.bootstrap
|
91
|
+
end
|
92
|
+
|
93
|
+
def compilation?
|
94
|
+
@compilation
|
95
|
+
end
|
96
|
+
|
97
|
+
def job_name
|
98
|
+
@job_name
|
68
99
|
end
|
69
100
|
|
70
101
|
def to_s
|
71
|
-
|
102
|
+
@name
|
72
103
|
end
|
73
104
|
|
74
105
|
# Looks up instance model in DB and binds it to this instance spec.
|
75
106
|
# Instance model is created if it's not found in DB. New VM is
|
76
107
|
# allocated if instance DB record doesn't reference one.
|
77
108
|
# @return [void]
|
109
|
+
# TODO: This should just be responsible to allocating the VMs and not creating instance_models
|
78
110
|
def bind_unallocated_vm
|
79
|
-
|
80
|
-
|
81
|
-
allocate_vm
|
82
|
-
end
|
111
|
+
ensure_model_bound
|
112
|
+
ensure_vm_allocated
|
83
113
|
end
|
84
114
|
|
85
|
-
|
86
|
-
|
87
|
-
def bind_existing_instance(instance_model, state, reservations)
|
88
|
-
check_model_not_bound
|
89
|
-
|
90
|
-
@model = instance_model
|
91
|
-
@current_state = state
|
92
|
-
|
93
|
-
take_network_reservations(reservations)
|
94
|
-
add_allocated_vm(instance_model.vm, state)
|
115
|
+
def ensure_model_bound
|
116
|
+
@model ||= find_or_create_model
|
95
117
|
end
|
96
118
|
|
97
|
-
def
|
98
|
-
@
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
# Our assumption here is that director database access
|
109
|
-
# is much less likely to fail than VM agent communication
|
110
|
-
# so we only update database after we see a successful agent apply.
|
111
|
-
# If database update fails subsequent deploy will try to
|
112
|
-
# assign a new VM to this instance which is ok.
|
113
|
-
@vm.model.db.transaction do
|
114
|
-
@vm.model.update(:apply_spec => state)
|
115
|
-
@model.update(:vm => @vm.model)
|
116
|
-
end
|
117
|
-
|
118
|
-
@current_state = state
|
119
|
+
def bind_new_instance_model
|
120
|
+
@model = Models::Instance.create({
|
121
|
+
deployment_id: @deployment_model.id,
|
122
|
+
job: @job_name,
|
123
|
+
index: index,
|
124
|
+
state: state,
|
125
|
+
compilation: @compilation,
|
126
|
+
uuid: SecureRandom.uuid,
|
127
|
+
bootstrap: false
|
128
|
+
})
|
129
|
+
@uuid = @model.uuid
|
119
130
|
end
|
120
131
|
|
121
|
-
def
|
122
|
-
@
|
123
|
-
|
124
|
-
|
125
|
-
'deployment' => @job.deployment.name,
|
126
|
-
'networks' => network_settings,
|
127
|
-
'resource_pool' => @job.resource_pool.spec,
|
128
|
-
'job' => @job.spec,
|
129
|
-
'index' => @index,
|
130
|
-
}
|
131
|
-
|
132
|
-
if disk_size > 0
|
133
|
-
state['persistent_disk'] = disk_size
|
132
|
+
def ensure_vm_allocated
|
133
|
+
@uuid = @model.uuid
|
134
|
+
if @model.vm.nil?
|
135
|
+
allocate_vm
|
134
136
|
end
|
137
|
+
end
|
135
138
|
|
136
|
-
|
139
|
+
def vm_type
|
140
|
+
@vm_type
|
141
|
+
end
|
137
142
|
|
138
|
-
|
139
|
-
|
143
|
+
def stemcell
|
144
|
+
@stemcell
|
145
|
+
end
|
140
146
|
|
141
|
-
|
142
|
-
|
143
|
-
@current_state = agent.get_state
|
147
|
+
def env
|
148
|
+
@env.spec
|
144
149
|
end
|
145
150
|
|
146
|
-
|
147
|
-
|
148
|
-
# not all instance states are available in the deployment manifest and we
|
149
|
-
# we cannot really persist this data in the agent state (as VM might be
|
150
|
-
# stopped or detached).
|
151
|
-
# @return [void]
|
152
|
-
def sync_state_with_db
|
153
|
-
check_model_bound
|
154
|
-
|
155
|
-
if @state
|
156
|
-
# Deployment plan explicitly sets state for this instance
|
157
|
-
@model.update(:state => @state)
|
158
|
-
elsif @model.state
|
159
|
-
# Instance has its state persisted from the previous deployment
|
160
|
-
@state = @model.state
|
161
|
-
else
|
162
|
-
# Target instance state should either be persisted in DB or provided
|
163
|
-
# via deployment plan, otherwise something is really wrong
|
164
|
-
raise InstanceTargetStateUndefined,
|
165
|
-
"Instance `#{self}' target state cannot be determined"
|
166
|
-
end
|
151
|
+
def deployment_model
|
152
|
+
@deployment_model
|
167
153
|
end
|
168
154
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
if old_reservation
|
177
|
-
raise NetworkReservationAlreadyExists,
|
178
|
-
"`#{self}' already has reservation " +
|
179
|
-
"for network `#{name}', IP #{old_reservation.ip}"
|
180
|
-
end
|
181
|
-
@network_reservations[name] = reservation
|
155
|
+
# Updates this domain object to reflect an existing instance running on an existing vm
|
156
|
+
def bind_existing_instance_model(existing_instance_model)
|
157
|
+
@uuid = existing_instance_model.uuid
|
158
|
+
check_model_not_bound
|
159
|
+
@model = existing_instance_model
|
160
|
+
allocate_vm
|
161
|
+
@vm.model = existing_instance_model.vm
|
182
162
|
end
|
183
163
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
default_properties = {}
|
188
|
-
@job.default_network.each do |key, value|
|
189
|
-
(default_properties[value] ||= []) << key
|
190
|
-
end
|
164
|
+
def bind_existing_reservations(reservations)
|
165
|
+
@existing_network_reservations = reservations
|
166
|
+
end
|
191
167
|
|
192
|
-
|
193
|
-
@
|
194
|
-
network = @job.deployment.network(name)
|
195
|
-
network_settings[name] = network.network_settings(reservation, default_properties[name])
|
196
|
-
|
197
|
-
# Temporary hack for running errands.
|
198
|
-
# We need to avoid RunErrand task thinking that
|
199
|
-
# network configuration for errand VM differs
|
200
|
-
# from network configuration for its Instance.
|
201
|
-
#
|
202
|
-
# Obviously this does not account for other changes
|
203
|
-
# in network configuration that errand job might need.
|
204
|
-
# (e.g. errand job desires static ip)
|
205
|
-
if @job.starts_on_deploy?
|
206
|
-
network_settings[name]['dns_record_name'] = dns_record_name(name)
|
207
|
-
end
|
168
|
+
def apply_vm_state(spec)
|
169
|
+
@logger.info('Applying VM state')
|
208
170
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
if @current_state.is_a?(Hash) &&
|
213
|
-
@current_state['networks'].is_a?(Hash) &&
|
214
|
-
@current_state['networks'][name].is_a?(Hash) &&
|
215
|
-
network_settings[name]['type'] == 'dynamic'
|
216
|
-
%w(ip netmask gateway).each do |key|
|
217
|
-
network_settings[name][key] = @current_state['networks'][name][key]
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
network_settings
|
171
|
+
@current_state = spec.full_spec
|
172
|
+
agent_client.apply(spec.as_apply_spec)
|
173
|
+
@model.update(spec: @current_state)
|
222
174
|
end
|
223
175
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
176
|
+
def apply_initial_vm_state(spec)
|
177
|
+
# Agent will return dynamic network settings, we need to update spec with it
|
178
|
+
# so that we can render templates with new spec later.
|
179
|
+
agent_spec_keys = ['networks', 'deployment', 'job', 'index', 'id']
|
180
|
+
agent_partial_state = spec.as_apply_spec.select { |k, _| agent_spec_keys.include?(k) }
|
181
|
+
agent_client.apply(agent_partial_state)
|
228
182
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
183
|
+
instance_spec_keys = agent_spec_keys + ['stemcell', 'vm_type']
|
184
|
+
instance_partial_state = spec.full_spec.select { |k, _| instance_spec_keys.include?(k) }
|
185
|
+
@current_state.merge!(instance_partial_state)
|
186
|
+
|
187
|
+
agent_state = agent_client.get_state
|
188
|
+
unless agent_state.nil?
|
189
|
+
@current_state['networks'] = agent_state['networks']
|
190
|
+
@model.update(spec: @current_state)
|
233
191
|
end
|
234
192
|
end
|
235
193
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
194
|
+
def update_trusted_certs
|
195
|
+
agent_client.update_settings(Config.trusted_certs)
|
196
|
+
@model.vm.update(:trusted_certs_sha1 => Digest::SHA1.hexdigest(Config.trusted_certs))
|
197
|
+
end
|
240
198
|
|
241
|
-
|
242
|
-
|
243
|
-
else
|
244
|
-
{}
|
245
|
-
end
|
199
|
+
def update_cloud_properties!
|
200
|
+
@model.update(cloud_properties: JSON.dump(cloud_properties))
|
246
201
|
end
|
247
202
|
|
248
|
-
|
249
|
-
|
250
|
-
def dns_record_info
|
251
|
-
dns_record_info = {}
|
252
|
-
network_settings.each do |network_name, network|
|
253
|
-
name = dns_record_name(network_name)
|
254
|
-
dns_record_info[name] = network['ip']
|
255
|
-
end
|
256
|
-
dns_record_info
|
203
|
+
def agent_client
|
204
|
+
@agent_client ||= AgentClient.with_vm(@model.vm)
|
257
205
|
end
|
258
206
|
|
259
207
|
##
|
260
208
|
# @return [String] dns record name
|
261
|
-
def dns_record_name(network_name)
|
262
|
-
[
|
209
|
+
def dns_record_name(hostname, network_name)
|
210
|
+
[hostname, job.canonical_name, Canonicalizer.canonicalize(network_name), Canonicalizer.canonicalize(@deployment_model.name), @dns_manager.dns_domain_name].join('.')
|
263
211
|
end
|
264
212
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
213
|
+
def cloud_properties_changed?
|
214
|
+
changed = cloud_properties != @model.cloud_properties_hash
|
215
|
+
log_changes(__method__, @model.cloud_properties_hash, cloud_properties) if changed
|
216
|
+
changed
|
269
217
|
end
|
270
218
|
|
271
219
|
##
|
272
|
-
# @return [Boolean] returns true if the
|
273
|
-
|
274
|
-
|
220
|
+
# @return [Boolean] returns true if the expected configuration hash
|
221
|
+
# differs from the one provided by the VM
|
222
|
+
def configuration_changed?
|
223
|
+
changed = configuration_hash != @current_state['configuration_hash']
|
224
|
+
log_changes(__method__, @current_state['configuration_hash'], configuration_hash) if changed
|
225
|
+
changed
|
275
226
|
end
|
276
227
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
if @recreate || @job.deployment.recreate
|
281
|
-
return true
|
282
|
-
end
|
283
|
-
|
284
|
-
if @job.resource_pool.spec != @current_state['resource_pool']
|
285
|
-
return true
|
286
|
-
end
|
287
|
-
|
288
|
-
# env is not a part of a resource pool spec but rather gets persisted
|
289
|
-
# in director DB, hence the check below
|
290
|
-
# NOTE: we only update VMs that have env persisted to avoid recreating
|
291
|
-
# everything, so if the director gets updated from the version that
|
292
|
-
# doesn't persist VM env to the version that does, there needs to
|
293
|
-
# be at least one deployment that recreates all VMs before the following
|
294
|
-
# code path gets exercised.
|
295
|
-
if @model && @model.vm && @model.vm.env && @job.resource_pool.env != @model.vm.env
|
296
|
-
return true
|
297
|
-
end
|
228
|
+
def current_job_spec
|
229
|
+
@current_state['job']
|
230
|
+
end
|
298
231
|
|
299
|
-
|
232
|
+
def current_packages
|
233
|
+
@current_state['packages']
|
300
234
|
end
|
301
235
|
|
302
|
-
|
303
|
-
|
304
|
-
# differs from the one provided by the VM
|
305
|
-
def configuration_changed?
|
306
|
-
configuration_hash != @current_state['configuration_hash']
|
236
|
+
def current_job_state
|
237
|
+
@current_state['job_state']
|
307
238
|
end
|
308
239
|
|
309
|
-
|
310
|
-
|
311
|
-
# from the one provided by the VM
|
312
|
-
def job_changed?
|
313
|
-
return true if @current_state.nil?
|
314
|
-
|
315
|
-
job_spec = @job.spec
|
316
|
-
if job_spec != @current_state['job']
|
317
|
-
# The agent job spec could be in legacy form. job_spec cannot be,
|
318
|
-
# though, because we got it from the spec function in job.rb which
|
319
|
-
# automatically makes it non-legacy.
|
320
|
-
return job_spec != Job.convert_from_legacy_spec(@current_state['job'])
|
321
|
-
end
|
322
|
-
return false
|
240
|
+
def update_state
|
241
|
+
@model.update(state: state)
|
323
242
|
end
|
324
243
|
|
325
|
-
|
326
|
-
|
327
|
-
# instance differ from the ones provided by the VM
|
328
|
-
def packages_changed?
|
329
|
-
@job.package_spec != @current_state['packages']
|
244
|
+
def update_description
|
245
|
+
@model.update(job: job_name, index: index)
|
330
246
|
end
|
331
247
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
def persistent_disk_changed?
|
336
|
-
new_disk_size = @job.persistent_disk_pool ? @job.persistent_disk_pool.disk_size : 0
|
337
|
-
new_disk_cloud_properties = @job.persistent_disk_pool ? @job.persistent_disk_pool.cloud_properties : {}
|
338
|
-
return true if new_disk_size != disk_size
|
248
|
+
def mark_as_bootstrap
|
249
|
+
@model.update(bootstrap: true)
|
250
|
+
end
|
339
251
|
|
340
|
-
|
252
|
+
def unmark_as_bootstrap
|
253
|
+
@model.update(bootstrap: false)
|
341
254
|
end
|
342
255
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
def dns_changed?
|
347
|
-
if Config.dns_enabled?
|
348
|
-
dns_record_info.any? do |name, ip|
|
349
|
-
Models::Dns::Record.find(:name => name, :type => 'A',
|
350
|
-
:content => ip).nil?
|
351
|
-
end
|
352
|
-
else
|
353
|
-
false
|
354
|
-
end
|
256
|
+
def assign_availability_zone(availability_zone)
|
257
|
+
@availability_zone = availability_zone
|
258
|
+
@model.update(availability_zone: availability_zone_name)
|
355
259
|
end
|
356
260
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
@state == 'detached' ||
|
367
|
-
@state == 'started' && @current_state['job_state'] != 'running' ||
|
368
|
-
@state == 'stopped' && @current_state['job_state'] == 'running'
|
261
|
+
def state
|
262
|
+
case @virtual_state
|
263
|
+
when 'recreate'
|
264
|
+
'started'
|
265
|
+
when 'restart'
|
266
|
+
'started'
|
267
|
+
else
|
268
|
+
@virtual_state
|
269
|
+
end
|
369
270
|
end
|
370
271
|
|
371
272
|
##
|
@@ -375,128 +276,86 @@ module Bosh::Director
|
|
375
276
|
#
|
376
277
|
# @return [Boolean] true if the VM needs to be sent a new set of trusted certificates
|
377
278
|
def trusted_certs_changed?
|
378
|
-
|
279
|
+
model_trusted_certs = @model.vm ? @model.vm.trusted_certs_sha1 : nil
|
280
|
+
config_trusted_certs = Digest::SHA1.hexdigest(Bosh::Director::Config.trusted_certs)
|
281
|
+
changed = config_trusted_certs != model_trusted_certs
|
282
|
+
log_changes(__method__, model_trusted_certs, config_trusted_certs) if changed
|
283
|
+
changed
|
379
284
|
end
|
380
285
|
|
381
|
-
|
382
|
-
|
383
|
-
# differ from the ones provided by the VM
|
384
|
-
def changed?
|
385
|
-
!changes.empty?
|
286
|
+
def vm_created?
|
287
|
+
!@vm.model.nil? && @vm.model.vm_exists?
|
386
288
|
end
|
387
289
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
unless @state == 'detached' && @current_state.nil?
|
393
|
-
changes << :restart if @restart
|
394
|
-
changes << :resource_pool if resource_pool_changed?
|
395
|
-
changes << :network if networks_changed?
|
396
|
-
changes << :packages if packages_changed?
|
397
|
-
changes << :persistent_disk if persistent_disk_changed?
|
398
|
-
changes << :configuration if configuration_changed?
|
399
|
-
changes << :job if job_changed?
|
400
|
-
changes << :state if state_changed?
|
401
|
-
changes << :dns if dns_changed?
|
402
|
-
changes << :trusted_certs if trusted_certs_changed?
|
403
|
-
end
|
404
|
-
changes
|
290
|
+
def bind_to_vm_model(vm_model)
|
291
|
+
@model.update(vm: vm_model)
|
292
|
+
@vm.model = vm_model
|
293
|
+
@vm.bound_instance = self
|
405
294
|
end
|
406
295
|
|
407
|
-
|
408
|
-
#
|
409
|
-
|
410
|
-
|
411
|
-
def spec
|
412
|
-
spec = {
|
413
|
-
'deployment' => @job.deployment.name,
|
414
|
-
'job' => job.spec,
|
415
|
-
'index' => index,
|
416
|
-
'networks' => network_settings,
|
417
|
-
'resource_pool' => job.resource_pool.spec,
|
418
|
-
'packages' => job.package_spec,
|
419
|
-
'configuration_hash' => configuration_hash,
|
420
|
-
'properties' => job.properties,
|
421
|
-
'dns_domain_name' => dns_domain_name
|
422
|
-
}
|
296
|
+
# Allocates an VM in this job resource pool and binds current instance to that VM.
|
297
|
+
# @return [void]
|
298
|
+
def allocate_vm
|
299
|
+
vm = Vm.new
|
423
300
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
else
|
430
|
-
spec['persistent_disk'] = 0
|
431
|
-
end
|
301
|
+
# VM is not created yet: let's just make it reference this instance
|
302
|
+
# so later it knows what it needs to become
|
303
|
+
vm.bound_instance = self
|
304
|
+
@vm = vm
|
305
|
+
end
|
432
306
|
|
433
|
-
|
434
|
-
|
307
|
+
def cloud_properties
|
308
|
+
if @availability_zone.nil?
|
309
|
+
vm_type.cloud_properties
|
310
|
+
else
|
311
|
+
@availability_zone.cloud_properties.merge(vm_type.cloud_properties)
|
435
312
|
end
|
313
|
+
end
|
436
314
|
|
437
|
-
|
438
|
-
|
439
|
-
# Go BOSH Agent has no ability to render ERB so pre-rendered templates are provided.
|
440
|
-
if rendered_templates_archive
|
441
|
-
spec['rendered_templates_archive'] = rendered_templates_archive.spec
|
442
|
-
end
|
315
|
+
def availability_zone_name
|
316
|
+
return nil if @availability_zone.nil?
|
443
317
|
|
444
|
-
|
318
|
+
@availability_zone.name
|
445
319
|
end
|
446
320
|
|
447
|
-
def
|
448
|
-
|
449
|
-
|
450
|
-
|
321
|
+
def update_templates(templates)
|
322
|
+
transactor = Transactor.new
|
323
|
+
transactor.retryable_transaction(Bosh::Director::Config.db) do
|
324
|
+
@model.remove_all_templates
|
325
|
+
templates.map(&:model).each do |template_model|
|
326
|
+
@model.add_template(template_model)
|
327
|
+
end
|
328
|
+
end
|
451
329
|
end
|
452
330
|
|
331
|
+
private
|
332
|
+
|
453
333
|
# Looks up instance model in DB
|
454
334
|
# @return [Models::Instance]
|
455
335
|
def find_or_create_model
|
456
|
-
if @
|
336
|
+
if @deployment_model.nil?
|
457
337
|
raise DirectorError, 'Deployment model is not bound'
|
458
338
|
end
|
459
339
|
|
460
340
|
conditions = {
|
461
|
-
deployment_id: @
|
462
|
-
job: @
|
341
|
+
deployment_id: @deployment_model.id,
|
342
|
+
job: @job_name,
|
463
343
|
index: @index
|
464
344
|
}
|
465
345
|
|
466
346
|
Models::Instance.find_or_create(conditions) do |model|
|
467
347
|
model.state = 'started'
|
348
|
+
model.compilation = @compilation
|
349
|
+
model.uuid = SecureRandom.uuid
|
468
350
|
end
|
469
351
|
end
|
470
352
|
|
471
|
-
#
|
472
|
-
# @return [
|
473
|
-
def
|
474
|
-
|
475
|
-
vm = resource_pool.allocate_vm
|
476
|
-
network = resource_pool.network
|
477
|
-
|
478
|
-
if vm.model
|
479
|
-
# There's already a resource pool VM that can become our instance,
|
480
|
-
# so we can try to reuse its reservation
|
481
|
-
instance_reservation = @network_reservations[network.name]
|
482
|
-
if instance_reservation
|
483
|
-
instance_reservation.take(vm.network_reservation)
|
484
|
-
end
|
485
|
-
else
|
486
|
-
# VM is not created yet: let's just make it reference this instance
|
487
|
-
# so later it knows what it needs to become
|
488
|
-
vm.bound_instance = self
|
489
|
-
|
490
|
-
# this also means we no longer need previous VM network reservation
|
491
|
-
# (instance has its own)
|
492
|
-
vm.release_reservation
|
493
|
-
end
|
494
|
-
|
495
|
-
@vm = vm
|
353
|
+
# @param [Hash] network_settings map of network name to settings
|
354
|
+
# @return [Hash] map of network name to IP address
|
355
|
+
def network_to_ip(network_settings)
|
356
|
+
Hash[network_settings.map { |network_name, settings| [network_name, settings['ip']] }]
|
496
357
|
end
|
497
358
|
|
498
|
-
private
|
499
|
-
|
500
359
|
def check_model_bound
|
501
360
|
if @model.nil?
|
502
361
|
raise DirectorError, "Instance `#{self}' model is not bound"
|
@@ -507,35 +366,8 @@ module Bosh::Director
|
|
507
366
|
raise DirectorError, "Instance `#{self}' model is already bound" if @model
|
508
367
|
end
|
509
368
|
|
510
|
-
|
511
|
-
|
512
|
-
# @param [Hash<String, NetworkReservation>] reservations
|
513
|
-
# @return [void]
|
514
|
-
def take_network_reservations(reservations)
|
515
|
-
reservations.each do |name, provided_reservation|
|
516
|
-
reservation = @network_reservations[name]
|
517
|
-
if reservation
|
518
|
-
@logger.debug("Copying job instance `#{self}' network reservation #{provided_reservation}")
|
519
|
-
reservation.take(provided_reservation)
|
520
|
-
end
|
521
|
-
end
|
522
|
-
end
|
523
|
-
|
524
|
-
def add_allocated_vm(vm_model, state)
|
525
|
-
resource_pool = @job.resource_pool
|
526
|
-
vm = resource_pool.add_allocated_vm
|
527
|
-
|
528
|
-
reservation = @network_reservations[vm.resource_pool.network.name]
|
529
|
-
|
530
|
-
@logger.debug("Found VM '#{vm_model.cid}' running job instance '#{self}'" +
|
531
|
-
" in resource pool `#{resource_pool.name}'" +
|
532
|
-
" with reservation '#{reservation}'")
|
533
|
-
vm.model = vm_model
|
534
|
-
vm.bound_instance = self
|
535
|
-
vm.current_state = state
|
536
|
-
vm.use_reservation(reservation)
|
537
|
-
|
538
|
-
@vm = vm
|
369
|
+
def log_changes(method_sym, old_state, new_state)
|
370
|
+
@logger.debug("#{method_sym} changed FROM: #{old_state} TO: #{new_state}")
|
539
371
|
end
|
540
372
|
end
|
541
373
|
end
|