Skip to content

Commit cc006c0

Browse files
authored
Add ability to set user on Tasks (#4433)
* Add ability to set user on Tasks Issue: #4372
1 parent 9016168 commit cc006c0

31 files changed

+523
-42
lines changed

app/actions/task_create.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def create(app, message, user_audit_info, droplet: nil)
2727
state: TaskModel::PENDING_STATE,
2828
droplet: droplet,
2929
command: command(message, template_process),
30+
user: user(message, template_process),
3031
disk_in_mb: disk_in_mb(message, template_process),
3132
memory_in_mb: memory_in_mb(message, template_process),
3233
log_rate_limit: log_rate_limit(message, template_process),
@@ -70,6 +71,13 @@ def command(message, template_process)
7071
template_process.specified_or_detected_command
7172
end
7273

74+
def user(message, template_process)
75+
return message.user if message.requested?(:user)
76+
return template_process.user if message.template_requested?
77+
78+
nil
79+
end
80+
7381
def memory_in_mb(message, template_process)
7482
message.memory_in_mb || template_process.try(:memory) || config.get(:default_app_memory)
7583
end

app/messages/task_create_message.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,29 @@
22

33
module VCAP::CloudController
44
class TaskCreateMessage < MetadataBaseMessage
5-
register_allowed_keys %i[name command disk_in_mb memory_in_mb log_rate_limit_in_bytes_per_second droplet_guid template]
5+
register_allowed_keys %i[name command disk_in_mb memory_in_mb log_rate_limit_in_bytes_per_second droplet_guid template user]
66

77
validates_with NoAdditionalKeysValidator
88

99
def self.validate_template?
1010
@validate_template ||= proc { |a| a.template_requested? }
1111
end
1212

13+
def self.user_requested?
14+
@user_requested ||= proc { |a| a.requested?(:user) }
15+
end
16+
1317
validates :disk_in_mb, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
1418
validates :memory_in_mb, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
1519
validates :log_rate_limit_in_bytes_per_second, numericality: { only_integer: true, greater_than: -2, less_than_or_equal_to: MAX_DB_BIGINT }, allow_nil: true
1620
validates :droplet_guid, guid: true, allow_nil: true
1721
validates :template_process_guid, guid: true, if: validate_template?
1822
validate :has_command
23+
validates :user,
24+
string: true,
25+
length: { in: 1..255, message: 'must be between 1 and 255 characters' },
26+
allow_nil: true,
27+
if: user_requested?
1928

2029
def template_process_guid
2130
return unless template_requested?

app/models/runtime/app_model.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ module VCAP::CloudController
77
class AppModel < Sequel::Model(:apps)
88
include Serializer
99
APP_NAME_REGEX = /\A[[:alnum:][:punct:][:print:]]+\Z/
10+
DEFAULT_CONTAINER_USER = 'vcap'.freeze
11+
DEFAULT_DOCKER_CONTAINER_USER = 'root'.freeze
1012

1113
many_to_many :routes, join_table: :route_mappings, left_key: :app_guid, left_primary_key: :guid, right_primary_key: :guid, right_key: :route_guid
1214
one_to_many :route_mappings, class: 'VCAP::CloudController::RouteMappingModel', key: :app_guid, primary_key: :guid

app/models/runtime/droplet_model.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,22 @@ def docker_ports
125125
exposed_ports
126126
end
127127

128+
def docker_user
129+
return '' unless docker?
130+
131+
container_user = ''
132+
if execution_metadata.present?
133+
begin
134+
docker_exec_metadata = Oj.load(execution_metadata)
135+
container_user = docker_exec_metadata['user']
136+
rescue EncodingError
137+
# ignore
138+
end
139+
end
140+
141+
container_user.presence || AppModel::DEFAULT_DOCKER_CONTAINER_USER
142+
end
143+
128144
def staging?
129145
state == STAGING_STATE
130146
end

app/models/runtime/process_model.rb

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ def after_initialize
3434
NO_APP_PORT_SPECIFIED = -1
3535
DEFAULT_HTTP_PORT = 8080
3636
DEFAULT_PORTS = [DEFAULT_HTTP_PORT].freeze
37-
DEFAULT_USER = 'vcap'.freeze
3837
UNLIMITED_LOG_RATE = -1
3938

4039
many_to_one :app, class: 'VCAP::CloudController::AppModel', key: :app_guid, primary_key: :guid, without_guid_generation: true
@@ -396,7 +395,7 @@ def started_command
396395
def run_action_user
397396
return user if user.present?
398397

399-
docker? ? docker_run_action_user : DEFAULT_USER
398+
docker? ? docker_run_action_user : AppModel::DEFAULT_CONTAINER_USER
400399
end
401400

402401
def specified_or_detected_command
@@ -573,23 +572,13 @@ def open_ports
573572
private
574573

575574
def permitted_users
576-
Set.new([DEFAULT_USER]) + Config.config.get(:additional_allowed_process_users)
575+
Set.new([AppModel::DEFAULT_CONTAINER_USER]) + Config.config.get(:additional_allowed_process_users)
577576
end
578577

579578
def docker_run_action_user
580-
return DEFAULT_USER unless docker?
581-
582-
container_user = ''
583-
if execution_metadata.present?
584-
begin
585-
docker_exec_metadata = Oj.load(execution_metadata)
586-
container_user = docker_exec_metadata['user']
587-
rescue EncodingError
588-
container_user = ''
589-
end
590-
end
579+
return AppModel::DEFAULT_CONTAINER_USER unless docker?
591580

592-
container_user.presence || 'root'
581+
desired_droplet&.docker_user.presence || AppModel::DEFAULT_DOCKER_CONTAINER_USER
593582
end
594583

595584
def non_unique_process_types

app/models/runtime/task_model.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,31 @@ def after_destroy
4444
create_stop_event unless terminal_state?
4545
end
4646

47+
def run_action_user
48+
return user if user.present?
49+
50+
if docker?
51+
docker_run_action_user
52+
elsif cnb?
53+
'root' # TODO: Why do CNB tasks default to this user instead of vcap?
54+
else
55+
AppModel::DEFAULT_CONTAINER_USER
56+
end
57+
end
58+
59+
delegate :docker?, to: :droplet
60+
delegate :cnb?, to: :droplet
61+
4762
private
4863

64+
def permitted_users
65+
Set.new([AppModel::DEFAULT_CONTAINER_USER]) + Config.config.get(:additional_allowed_process_users)
66+
end
67+
68+
def docker_run_action_user
69+
droplet.docker_user.presence || AppModel::DEFAULT_CONTAINER_USER
70+
end
71+
4972
def running_state?
5073
state == RUNNING_STATE
5174
end
@@ -68,6 +91,7 @@ def validate
6891
validate_org_quotas
6992
validate_space_quotas
7093

94+
ProcessUserPolicy.new(self, permitted_users).validate
7195
MinLogRateLimitPolicy.new(self).validate
7296
end
7397

app/presenters/v3/task_presenter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def to_hash
1515
sequence_id: task.sequence_id,
1616
name: task.name,
1717
command: task.command,
18+
user: task.run_action_user,
1819
state: task.state,
1920
memory_in_mb: task.memory_in_mb,
2021
disk_in_mb: task.disk_in_mb,

config/cloud_controller.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ maximum_app_disk_in_mb: 2048
6767
max_retained_deployments_per_app: 100
6868
max_retained_builds_per_app: 100
6969
max_retained_revisions_per_app: 100
70-
additional_allowed_process_users: ['ContainerUser']
70+
additional_allowed_process_users: ['ContainerUser', 'TestUser']
7171

7272
broker_client_default_async_poll_interval_seconds: 60
7373
broker_client_max_async_poll_duration_minutes: 10080
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Sequel.migration do
2+
up do
3+
alter_table :tasks do
4+
add_column :user, String, null: true, default: nil, size: 255 unless @db.schema(:tasks).map(&:first).include?(:user)
5+
end
6+
end
7+
8+
down do
9+
alter_table :tasks do
10+
drop_column :user if @db.schema(:tasks).map(&:first).include?(:user)
11+
end
12+
end
13+
end

docs/v3/source/includes/api_resources/_tasks.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"sequence_id": 1,
55
"name": "migrate",
66
"command": "rake db:migrate",
7+
"user": "vcap",
78
"state": "RUNNING",
89
"memory_in_mb": 512,
910
"disk_in_mb": 1024,
@@ -49,6 +50,7 @@
4950
"sequence_id": 1,
5051
"name": "migrate",
5152
"command": "rake db:migrate",
53+
"user": "vcap",
5254
"state": "CANCELING",
5355
"memory_in_mb": 512,
5456
"disk_in_mb": 1024,
@@ -109,6 +111,7 @@
109111
"guid": "d5cc22ec-99a3-4e6a-af91-a44b4ab7b6fa",
110112
"sequence_id": 1,
111113
"name": "hello",
114+
"user": "vcap",
112115
"state": "SUCCEEDED",
113116
"memory_in_mb": 512,
114117
"disk_in_mb": 1024,
@@ -150,6 +153,7 @@
150153
"guid": "63b4cd89-fd8b-4bf1-a311-7174fcc907d6",
151154
"sequence_id": 2,
152155
"name": "migrate",
156+
"user": "vcap",
153157
"state": "FAILED",
154158
"memory_in_mb": 512,
155159
"disk_in_mb": 1024,

0 commit comments

Comments
 (0)