-
Notifications
You must be signed in to change notification settings - Fork 369
Expand file tree
/
Copy pathtask_create.rb
More file actions
148 lines (116 loc) · 4.41 KB
/
task_create.rb
File metadata and controls
148 lines (116 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
require 'repositories/task_event_repository'
module VCAP::CloudController
class TaskCreate
class InvalidTask < StandardError; end
class TaskCreateError < StandardError; end
class NoAssignedDroplet < TaskCreateError; end
class MaximumDiskExceeded < TaskCreateError; end
def initialize(config)
@config = config
end
def create(app, message, user_audit_info, droplet: nil)
droplet ||= app.droplet
no_assigned_droplet! unless droplet
validate_maximum_disk!(message)
task = nil
TaskModel.db.transaction do
app.lock!
template_process = process_from_template(message)
task = TaskModel.create(
name: use_requested_name_or_generate_name(message),
app: app,
state: TaskModel::PENDING_STATE,
droplet: droplet,
command: command(message, template_process),
user: user(message, template_process),
disk_in_mb: disk_in_mb(message, template_process),
memory_in_mb: memory_in_mb(message, template_process),
log_rate_limit: log_rate_limit(message, template_process),
sequence_id: app.max_task_sequence_id
)
MetadataUpdate.update(task, message)
app.update(max_task_sequence_id: app.max_task_sequence_id + 1)
task_event_repository.record_task_create(task, user_audit_info)
task
end
submit_task(task)
task
rescue Diego::Buildpack::LifecycleProtocol::InvalidDownloadUri,
Diego::LifecycleBundleUriGenerator::InvalidStack,
Diego::LifecycleBundleUriGenerator::InvalidCompiler => e
raise CloudController::Errors::ApiError.new_from_details('TaskError', e.message)
rescue Sequel::ValidationFailed => e
raise InvalidTask.new(e.message)
end
private
attr_reader :config
def process_from_template(message)
return unless message.template_requested?
process = ProcessModel.find(guid: message.template_process_guid)
raise CloudController::Errors::ApiError.new_from_details('ProcessNotFound', message.template_process_guid) unless process
process
end
def command(message, template_process)
return message.command if message.requested?(:command)
template_process.specified_or_detected_command
end
def user(message, template_process)
return message.user if message.requested?(:user)
return template_process.user if message.template_requested?
nil
end
def memory_in_mb(message, template_process)
message.memory_in_mb || template_process.try(:memory) || config.get(:default_app_memory)
end
def log_rate_limit(message, template_process)
message.log_rate_limit_in_bytes_per_second || template_process.try(:log_rate_limit) || config.get(:default_app_log_rate_limit_in_bytes_per_second)
end
def disk_in_mb(message, template_process)
message.disk_in_mb || template_process.try(:disk_quota) || config.get(:default_app_disk_in_mb)
end
def submit_task(task)
dependency_locator.bbs_task_client.desire_task(task, Diego::TASKS_DOMAIN)
mark_task_as_running(task)
rescue StandardError => e
fail_task(task)
raise e
end
def use_requested_name_or_generate_name(message)
message.requested?(:name) ? message.name : Random.new.bytes(4).unpack1('H*')
end
def validate_maximum_disk!(message)
return unless message.requested?(:disk_in_mb)
return unless message.disk_in_mb.to_i > config.get(:maximum_app_disk_in_mb)
raise MaximumDiskExceeded.new(
"Cannot request disk_in_mb greater than #{config.get(:maximum_app_disk_in_mb)}"
)
end
def dependency_locator
CloudController::DependencyLocator.instance
end
def no_assigned_droplet!
raise NoAssignedDroplet.new('Task must have a droplet. Specify droplet or assign current droplet to app.')
end
def app_usage_event_repository
Repositories::AppUsageEventRepository.new
end
def task_event_repository
Repositories::TaskEventRepository.new
end
def fail_task(task)
task.db.transaction do
task.lock!
task.state = TaskModel::FAILED_STATE
task.failure_reason = 'Unable to request task to be run'
task.save
end
end
def mark_task_as_running(task)
task.db.transaction do
task.lock!
task.state = TaskModel::RUNNING_STATE
task.save
end
end
end
end