ood_core 0.14.0 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +30 -0
- data/CHANGELOG.md +87 -1
- data/README.md +1 -1
- data/lib/ood_core/cluster.rb +20 -5
- data/lib/ood_core/job/adapters/ccq.rb +19 -12
- data/lib/ood_core/job/adapters/kubernetes.rb +1 -1
- data/lib/ood_core/job/adapters/kubernetes/batch.rb +82 -55
- data/lib/ood_core/job/adapters/kubernetes/helper.rb +79 -69
- data/lib/ood_core/job/adapters/kubernetes/k8s_job_info.rb +9 -0
- data/lib/ood_core/job/adapters/kubernetes/resources.rb +38 -10
- data/lib/ood_core/job/adapters/kubernetes/templates/pod.yml.erb +140 -46
- data/lib/ood_core/job/adapters/linux_host/launcher.rb +16 -9
- data/lib/ood_core/job/adapters/slurm.rb +1 -0
- data/lib/ood_core/job/adapters/torque.rb +2 -0
- data/lib/ood_core/job/script.rb +8 -1
- data/lib/ood_core/version.rb +1 -1
- data/ood_core.gemspec +2 -1
- metadata +27 -6
- data/.travis.yml +0 -9
@@ -1,18 +1,17 @@
|
|
1
1
|
class OodCore::Job::Adapters::Kubernetes::Helper
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'resources'
|
4
|
+
require_relative 'k8s_job_info'
|
4
5
|
require 'resolv'
|
5
6
|
require 'base64'
|
7
|
+
require 'active_support/core_ext/hash'
|
6
8
|
|
7
9
|
class K8sDataError < StandardError; end
|
8
10
|
|
9
|
-
Resources = OodCore::Job::Adapters::Kubernetes::Resources
|
10
|
-
|
11
11
|
# Extract info from json data. The data is expected to be from the kubectl
|
12
12
|
# command and conform to kubernetes' datatype structures.
|
13
13
|
#
|
14
|
-
# Returns
|
15
|
-
# object field in lieu of writing a connection.yml
|
14
|
+
# Returns K8sJobInfo in the in lieu of writing a connection.yml
|
16
15
|
#
|
17
16
|
# @param pod_json [#to_h]
|
18
17
|
# the pod data returned from 'kubectl get pod abc-123'
|
@@ -20,16 +19,17 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
20
19
|
# the service data returned from 'kubectl get service abc-123-service'
|
21
20
|
# @param secret_json [#to_h]
|
22
21
|
# the secret data returned from 'kubectl get secret abc-123-secret'
|
23
|
-
# @
|
24
|
-
|
25
|
-
|
22
|
+
# @param ns_prefix [#to_s]
|
23
|
+
# the namespace prefix so that namespaces can be converted back to usernames
|
24
|
+
# @return [OodCore::Job::Adapters::Kubernetes::K8sJobInfo]
|
25
|
+
def info_from_json(pod_json: nil, service_json: nil, secret_json: nil, ns_prefix: nil)
|
26
|
+
pod_hash = pod_info_from_json(pod_json, ns_prefix: ns_prefix)
|
26
27
|
service_hash = service_info_from_json(service_json)
|
27
28
|
secret_hash = secret_info_from_json(secret_json)
|
28
29
|
|
29
|
-
|
30
|
-
pod_hash
|
31
|
-
|
32
|
-
OodCore::Job::Info.new(pod_hash)
|
30
|
+
pod_hash.deep_merge!(service_hash)
|
31
|
+
pod_hash.deep_merge!(secret_hash)
|
32
|
+
OodCore::Job::Adapters::Kubernetes::K8sJobInfo.new(pod_hash)
|
33
33
|
rescue NoMethodError
|
34
34
|
raise K8sDataError, "unable to read data correctly from json"
|
35
35
|
end
|
@@ -38,18 +38,23 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
38
38
|
#
|
39
39
|
# @param container [#to_h]
|
40
40
|
# the input container hash
|
41
|
+
# @param default_env [#to_h]
|
42
|
+
# Default env to merge with defined env
|
41
43
|
# @return [OodCore::Job::Adapters::Kubernetes::Resources::Container]
|
42
|
-
def container_from_native(container)
|
43
|
-
|
44
|
+
def container_from_native(container, default_env)
|
45
|
+
env = container.fetch(:env, {}).to_h.symbolize_keys
|
46
|
+
OodCore::Job::Adapters::Kubernetes::Resources::Container.new(
|
44
47
|
container[:name],
|
45
48
|
container[:image],
|
46
49
|
command: parse_command(container[:command]),
|
47
50
|
port: container[:port],
|
48
|
-
env:
|
51
|
+
env: default_env.merge(env),
|
49
52
|
memory: container[:memory],
|
50
53
|
cpu: container[:cpu],
|
51
54
|
working_dir: container[:working_dir],
|
52
|
-
restart_policy: container[:restart_policy]
|
55
|
+
restart_policy: container[:restart_policy],
|
56
|
+
image_pull_policy: container[:image_pull_policy],
|
57
|
+
image_pull_secret: container[:image_pull_secret]
|
53
58
|
)
|
54
59
|
end
|
55
60
|
|
@@ -76,15 +81,22 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
76
81
|
# the input configmap hash
|
77
82
|
# @param id [#to_s]
|
78
83
|
# the id to use for giving the configmap a name
|
84
|
+
# @param script_content [#to_s]
|
85
|
+
# the batch script content
|
79
86
|
# @return [OodCore::Job::Adapters::Kubernetes::Resources::ConfigMap]
|
80
|
-
def configmap_from_native(native, id)
|
81
|
-
configmap = native.fetch(:configmap,
|
82
|
-
|
83
|
-
|
84
|
-
|
87
|
+
def configmap_from_native(native, id, script_content)
|
88
|
+
configmap = native.fetch(:configmap, {})
|
89
|
+
configmap[:files] ||= []
|
90
|
+
configmap[:files] << {
|
91
|
+
filename: 'script.sh',
|
92
|
+
data: script_content,
|
93
|
+
mount_path: '/ood/script.sh',
|
94
|
+
sub_path: 'script.sh',
|
95
|
+
} unless configmap[:files].any? { |f| f[:filename] == 'script.sh' }
|
96
|
+
|
97
|
+
OodCore::Job::Adapters::Kubernetes::Resources::ConfigMap.new(
|
85
98
|
configmap_name(id),
|
86
|
-
configmap[:
|
87
|
-
configmap[:data]
|
99
|
+
(configmap[:files] || [])
|
88
100
|
)
|
89
101
|
end
|
90
102
|
|
@@ -93,13 +105,15 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
93
105
|
# @param native_data [#to_h]
|
94
106
|
# the native data to parse. Expected key init_ctrs and for that
|
95
107
|
# key to be an array of hashes.
|
108
|
+
# @param default_env [#to_h]
|
109
|
+
# Default env to merge with defined env
|
96
110
|
# @return [Array<OodCore::Job::Adapters::Kubernetes::Resources::Container>]
|
97
111
|
# the array of init containers
|
98
|
-
def init_ctrs_from_native(ctrs)
|
112
|
+
def init_ctrs_from_native(ctrs, default_env)
|
99
113
|
init_ctrs = []
|
100
114
|
|
101
115
|
ctrs&.each do |ctr_raw|
|
102
|
-
ctr = container_from_native(ctr_raw)
|
116
|
+
ctr = container_from_native(ctr_raw, default_env)
|
103
117
|
init_ctrs.push(ctr)
|
104
118
|
end
|
105
119
|
|
@@ -118,25 +132,29 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
118
132
|
id + '-configmap'
|
119
133
|
end
|
120
134
|
|
135
|
+
def seconds_to_duration(s)
|
136
|
+
"%02dh%02dm%02ds" % [s / 3600, s / 60 % 60, s % 60]
|
137
|
+
end
|
138
|
+
|
121
139
|
# Extract pod info from json data. The data is expected to be from the kubectl
|
122
140
|
# command and conform to kubernetes' datatype structures.
|
123
141
|
#
|
124
142
|
# @param json_data [#to_h]
|
125
143
|
# the pod data returned from 'kubectl get pod abc-123'
|
144
|
+
# @param ns_prefix [#to_s]
|
145
|
+
# the namespace prefix so that namespaces can be converted back to usernames
|
126
146
|
# @return [#to_h]
|
127
147
|
# the hash of info expected from adapters
|
128
|
-
def pod_info_from_json(json_data)
|
148
|
+
def pod_info_from_json(json_data, ns_prefix: nil)
|
129
149
|
{
|
130
150
|
id: json_data.dig(:metadata, :name).to_s,
|
131
151
|
job_name: name_from_metadata(json_data.dig(:metadata)),
|
132
152
|
status: pod_status_from_json(json_data),
|
133
|
-
job_owner: json_data
|
153
|
+
job_owner: job_owner_from_json(json_data, ns_prefix),
|
134
154
|
submission_time: submission_time(json_data),
|
135
155
|
dispatch_time: dispatch_time(json_data),
|
136
156
|
wallclock_time: wallclock_time(json_data),
|
137
|
-
|
138
|
-
host: get_host(json_data.dig(:status, :hostIP))
|
139
|
-
},
|
157
|
+
ood_connection_info: { host: get_host(json_data.dig(:status, :hostIP)) },
|
140
158
|
procs: procs_from_json(json_data)
|
141
159
|
}
|
142
160
|
rescue NoMethodError
|
@@ -162,39 +180,24 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
162
180
|
def service_info_from_json(json_data)
|
163
181
|
# all we need is the port - .spec.ports[0].nodePort
|
164
182
|
ports = json_data.dig(:spec, :ports)
|
165
|
-
{
|
166
|
-
native:
|
167
|
-
{
|
168
|
-
port: ports[0].dig(:nodePort)
|
169
|
-
}
|
170
|
-
}
|
183
|
+
{ ood_connection_info: { port: ports[0].dig(:nodePort) } }
|
171
184
|
rescue
|
172
|
-
|
185
|
+
{}
|
173
186
|
end
|
174
187
|
|
175
188
|
def secret_info_from_json(json_data)
|
176
189
|
raw = json_data.dig(:data, :password)
|
177
|
-
{
|
178
|
-
native:
|
179
|
-
{
|
180
|
-
password: Base64.decode64(raw)
|
181
|
-
}
|
182
|
-
}
|
190
|
+
{ ood_connection_info: { password: Base64.decode64(raw) } }
|
183
191
|
rescue
|
184
|
-
|
185
|
-
end
|
186
|
-
|
187
|
-
def empty_native
|
188
|
-
{
|
189
|
-
native: {}
|
190
|
-
}
|
192
|
+
{}
|
191
193
|
end
|
192
194
|
|
193
195
|
def dispatch_time(json_data)
|
194
196
|
status = pod_status_from_json(json_data)
|
195
|
-
|
197
|
+
container_statuses = json_data.dig(:status, :containerStatuses)
|
198
|
+
return nil if container_statuses.nil?
|
196
199
|
|
197
|
-
state_data =
|
200
|
+
state_data = container_statuses[0].dig(:state)
|
198
201
|
date_string = nil
|
199
202
|
|
200
203
|
if status == 'completed'
|
@@ -208,9 +211,10 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
208
211
|
|
209
212
|
def wallclock_time(json_data)
|
210
213
|
status = pod_status_from_json(json_data)
|
211
|
-
|
214
|
+
container_statuses = json_data.dig(:status, :containerStatuses)
|
215
|
+
return nil if container_statuses.nil?
|
212
216
|
|
213
|
-
state_data =
|
217
|
+
state_data = container_statuses[0].dig(:state)
|
214
218
|
start_time = dispatch_time(json_data)
|
215
219
|
return nil if start_time.nil?
|
216
220
|
|
@@ -250,20 +254,21 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
250
254
|
end
|
251
255
|
|
252
256
|
def pod_status_from_json(json_data)
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
257
|
+
phase = json_data.dig(:status, :phase)
|
258
|
+
state = case phase
|
259
|
+
when "Running"
|
260
|
+
"running"
|
261
|
+
when "Pending"
|
262
|
+
"queued"
|
263
|
+
when "Failed"
|
264
|
+
"suspended"
|
265
|
+
when "Succeeded"
|
266
|
+
"completed"
|
267
|
+
when "Unknown"
|
268
|
+
"undetermined"
|
269
|
+
else
|
270
|
+
"undetermined"
|
271
|
+
end
|
267
272
|
|
268
273
|
OodCore::Job::Status.new(state: state)
|
269
274
|
end
|
@@ -295,4 +300,9 @@ class OodCore::Job::Adapters::Kubernetes::Helper
|
|
295
300
|
cpu
|
296
301
|
end
|
297
302
|
end
|
298
|
-
|
303
|
+
|
304
|
+
def job_owner_from_json(json_data = {}, ns_prefix = nil)
|
305
|
+
namespace = json_data.dig(:metadata, :namespace).to_s
|
306
|
+
namespace.delete_prefix(ns_prefix.to_s)
|
307
|
+
end
|
308
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# An object that describes a submitted kubernetes job with extended information
|
2
|
+
class OodCore::Job::Adapters::Kubernetes::K8sJobInfo < OodCore::Job::Info
|
3
|
+
attr_reader :ood_connection_info
|
4
|
+
|
5
|
+
def initialize(ood_connection_info: {}, **options)
|
6
|
+
super(options)
|
7
|
+
@ood_connection_info = ood_connection_info
|
8
|
+
end
|
9
|
+
end
|
@@ -1,22 +1,45 @@
|
|
1
1
|
module OodCore::Job::Adapters::Kubernetes::Resources
|
2
2
|
|
3
3
|
class ConfigMap
|
4
|
-
attr_accessor :name, :
|
4
|
+
attr_accessor :name, :files
|
5
5
|
|
6
|
-
def initialize(name,
|
6
|
+
def initialize(name, files)
|
7
7
|
@name = name
|
8
|
-
@
|
9
|
-
|
8
|
+
@files = []
|
9
|
+
files.each do |f|
|
10
|
+
@files << ConfigMapFile.new(f)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def mounts?
|
15
|
+
@files.any? { |f| f.mount_path }
|
16
|
+
end
|
17
|
+
|
18
|
+
def init_mounts?
|
19
|
+
@files.any? { |f| f.init_mount_path }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class ConfigMapFile
|
24
|
+
attr_accessor :filename, :data, :mount_path, :sub_path, :init_mount_path, :init_sub_path
|
25
|
+
|
26
|
+
def initialize(data)
|
27
|
+
@filename = data[:filename]
|
28
|
+
@data = data[:data]
|
29
|
+
@mount_path = data[:mount_path]
|
30
|
+
@sub_path = data[:sub_path]
|
31
|
+
@init_mount_path = data[:init_mount_path]
|
32
|
+
@init_sub_path = data[:init_sub_path]
|
10
33
|
end
|
11
34
|
end
|
12
35
|
|
13
36
|
class Container
|
14
37
|
attr_accessor :name, :image, :command, :port, :env, :memory, :cpu, :working_dir,
|
15
|
-
:restart_policy
|
38
|
+
:restart_policy, :image_pull_policy, :image_pull_secret, :supplemental_groups
|
16
39
|
|
17
40
|
def initialize(
|
18
|
-
name, image, command: [], port: nil, env:
|
19
|
-
working_dir: "", restart_policy: "Never"
|
41
|
+
name, image, command: [], port: nil, env: {}, memory: "4Gi", cpu: "1",
|
42
|
+
working_dir: "", restart_policy: "Never", image_pull_policy: nil, image_pull_secret: nil, supplemental_groups: []
|
20
43
|
)
|
21
44
|
raise ArgumentError, "containers need valid names and images" unless name && image
|
22
45
|
|
@@ -24,11 +47,14 @@ module OodCore::Job::Adapters::Kubernetes::Resources
|
|
24
47
|
@image = image
|
25
48
|
@command = command.nil? ? [] : command
|
26
49
|
@port = port&.to_i
|
27
|
-
@env = env.nil? ?
|
50
|
+
@env = env.nil? ? {} : env
|
28
51
|
@memory = memory.nil? ? "4Gi" : memory
|
29
52
|
@cpu = cpu.nil? ? "1" : cpu
|
30
53
|
@working_dir = working_dir.nil? ? "" : working_dir
|
31
54
|
@restart_policy = restart_policy.nil? ? "Never" : restart_policy
|
55
|
+
@image_pull_policy = image_pull_policy.nil? ? "IfNotPresent" : image_pull_policy
|
56
|
+
@image_pull_secret = image_pull_secret
|
57
|
+
@supplemental_groups = supplemental_groups.nil? ? [] : supplemental_groups
|
32
58
|
end
|
33
59
|
|
34
60
|
def ==(other)
|
@@ -40,9 +66,11 @@ module OodCore::Job::Adapters::Kubernetes::Resources
|
|
40
66
|
memory == other.memory &&
|
41
67
|
cpu == other.cpu &&
|
42
68
|
working_dir == other.working_dir &&
|
43
|
-
restart_policy == other.restart_policy
|
69
|
+
restart_policy == other.restart_policy &&
|
70
|
+
image_pull_policy == other.image_pull_policy &&
|
71
|
+
image_pull_secret == other.image_pull_secret &&
|
72
|
+
supplemental_groups == other.supplemental_groups
|
44
73
|
end
|
45
|
-
|
46
74
|
end
|
47
75
|
|
48
76
|
class PodSpec
|
@@ -7,100 +7,187 @@ metadata:
|
|
7
7
|
job: <%= id %>
|
8
8
|
app.kubernetes.io/name: <%= container.name %>
|
9
9
|
app.kubernetes.io/managed-by: open-ondemand
|
10
|
+
<%- if !script.accounting_id.nil? && script.accounting_id != "" -%>
|
11
|
+
account: <%= script.accounting_id %>
|
12
|
+
<%- end -%>
|
13
|
+
annotations:
|
14
|
+
<%- unless script.wall_time.nil? -%>
|
15
|
+
pod.kubernetes.io/lifetime: <%= helper.seconds_to_duration(script.wall_time) %>
|
16
|
+
<%- end -%>
|
10
17
|
spec:
|
11
18
|
restartPolicy: <%= spec.container.restart_policy %>
|
12
19
|
securityContext:
|
13
20
|
runAsUser: <%= run_as_user %>
|
14
21
|
runAsGroup: <%= run_as_group %>
|
22
|
+
runAsNonRoot: true
|
23
|
+
<%- if spec.container.supplemental_groups.empty? -%>
|
24
|
+
supplementalGroups: []
|
25
|
+
<%- else -%>
|
26
|
+
supplementalGroups:
|
27
|
+
<%- spec.container.supplemental_groups.each do |supplemental_group| -%>
|
28
|
+
- "<%= supplemental_group %>"
|
29
|
+
<%- end -%>
|
30
|
+
<%- end -%>
|
15
31
|
fsGroup: <%= fs_group %>
|
32
|
+
hostNetwork: false
|
33
|
+
hostIPC: false
|
34
|
+
hostPID: false
|
35
|
+
<%- unless spec.container.image_pull_secret.nil? -%>
|
36
|
+
imagePullSecrets:
|
37
|
+
- name: <%= spec.container.image_pull_secret %>
|
38
|
+
<%- end -%>
|
16
39
|
containers:
|
17
40
|
- name: "<%= spec.container.name %>"
|
18
41
|
image: <%= spec.container.image %>
|
19
|
-
imagePullPolicy:
|
20
|
-
|
42
|
+
imagePullPolicy: <%= spec.container.image_pull_policy %>
|
43
|
+
<%- unless spec.container.working_dir.empty? -%>
|
21
44
|
workingDir: "<%= spec.container.working_dir %>"
|
22
|
-
|
23
|
-
<% unless spec.container.env.empty? %>
|
45
|
+
<%- end -%>
|
24
46
|
env:
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
47
|
+
- name: POD_NAME
|
48
|
+
valueFrom:
|
49
|
+
fieldRef:
|
50
|
+
fieldPath: metadata.name
|
51
|
+
- name: POD_NAMESPACE
|
52
|
+
valueFrom:
|
53
|
+
fieldRef:
|
54
|
+
fieldPath: metadata.namespace
|
55
|
+
<%- spec.container.env.each_pair do |name, value| -%>
|
56
|
+
- name: <%= name %>
|
57
|
+
value: "<%= value %>"
|
58
|
+
<%- end # for each env -%>
|
59
|
+
<%- unless spec.container.command.empty? -%>
|
31
60
|
command:
|
32
|
-
|
61
|
+
<%- spec.container.command.each do |cmd| -%>
|
33
62
|
- "<%= cmd %>"
|
34
|
-
|
35
|
-
|
36
|
-
|
63
|
+
<%- end # for each command -%>
|
64
|
+
<%- end # unless command is nil -%>
|
65
|
+
<%- unless spec.container.port.nil? -%>
|
37
66
|
ports:
|
38
67
|
- containerPort: <%= spec.container.port %>
|
39
|
-
|
68
|
+
<%- end -%>
|
69
|
+
<%- if !all_mounts.empty? || (!configmap.nil? && configmap.mounts?) -%>
|
40
70
|
volumeMounts:
|
41
|
-
|
71
|
+
<%- unless configmap.nil? -%>
|
72
|
+
<%- configmap.files.each do |file| -%>
|
73
|
+
<%- next if file.mount_path.nil? -%>
|
42
74
|
- name: configmap-volume
|
43
|
-
mountPath:
|
44
|
-
|
45
|
-
|
75
|
+
mountPath: <%= file.mount_path %>
|
76
|
+
<%- unless file.sub_path.nil? -%>
|
77
|
+
subPath: <%= file.sub_path %>
|
78
|
+
<%- end # end unless file.sub_path.nil? -%>
|
79
|
+
<%- end # end configmap.files.each -%>
|
80
|
+
<%- end # unless configmap.nil? -%>
|
81
|
+
<%- all_mounts.each do |mount| -%>
|
46
82
|
- name: <%= mount[:name] %>
|
47
83
|
mountPath: <%= mount[:destination_path] %>
|
48
|
-
|
84
|
+
<%- end # for each mount -%>
|
85
|
+
<%- end # configmap mounts? and all_mounts not empty -%>
|
49
86
|
resources:
|
50
87
|
limits:
|
51
88
|
memory: "<%= spec.container.memory %>"
|
52
89
|
cpu: "<%= spec.container.cpu %>"
|
90
|
+
<%- unless script.gpus_per_node.nil? -%>
|
91
|
+
<%= gpu_type %>: <%= script.gpus_per_node %>
|
92
|
+
<%- end -%>
|
53
93
|
requests:
|
54
94
|
memory: "<%= spec.container.memory %>"
|
55
95
|
cpu: "<%= spec.container.cpu %>"
|
56
|
-
|
96
|
+
<%- unless script.gpus_per_node.nil? -%>
|
97
|
+
<%= gpu_type %>: <%= script.gpus_per_node %>
|
98
|
+
<%- end -%>
|
99
|
+
securityContext:
|
100
|
+
allowPrivilegeEscalation: false
|
101
|
+
capabilities:
|
102
|
+
drop:
|
103
|
+
- all
|
104
|
+
privileged: false
|
105
|
+
<%- unless spec.init_containers.empty? -%>
|
57
106
|
initContainers:
|
58
|
-
|
107
|
+
<%- spec.init_containers.each do |ctr| -%>
|
59
108
|
- name: "<%= ctr.name %>"
|
60
109
|
image: "<%= ctr.image %>"
|
110
|
+
imagePullPolicy: <%= ctr.image_pull_policy %>
|
111
|
+
env:
|
112
|
+
- name: POD_NAME
|
113
|
+
valueFrom:
|
114
|
+
fieldRef:
|
115
|
+
fieldPath: metadata.name
|
116
|
+
- name: POD_NAMESPACE
|
117
|
+
valueFrom:
|
118
|
+
fieldRef:
|
119
|
+
fieldPath: metadata.namespace
|
120
|
+
<%- ctr.env.each_pair do |name, value| -%>
|
121
|
+
- name: <%= name %>
|
122
|
+
value: "<%= value %>"
|
123
|
+
<%- end # for each env -%>
|
61
124
|
command:
|
62
|
-
|
125
|
+
<%- ctr.command.each do |cmd| -%>
|
63
126
|
- "<%= cmd %>"
|
64
|
-
|
127
|
+
<%- end # command loop -%>
|
128
|
+
<%- if !all_mounts.empty? || (!configmap.nil? && configmap.init_mounts?) -%>
|
65
129
|
volumeMounts:
|
66
|
-
|
130
|
+
<%- unless configmap.nil? -%>
|
131
|
+
<%- configmap.files.each do |file| -%>
|
132
|
+
<%- next if file.init_mount_path.nil? -%>
|
67
133
|
- name: configmap-volume
|
68
|
-
mountPath:
|
69
|
-
|
70
|
-
|
134
|
+
mountPath: <%= file.init_mount_path %>
|
135
|
+
<%- unless file.init_sub_path.nil? -%>
|
136
|
+
subPath: <%= file.init_sub_path %>
|
137
|
+
<%- end # end unless file.sub_path.nil? -%>
|
138
|
+
<%- end # end configmap.files.each -%>
|
139
|
+
<%- end # unless configmap.nil? -%>
|
140
|
+
<%- all_mounts.each do |mount| -%>
|
71
141
|
- name: <%= mount[:name] %>
|
72
142
|
mountPath: <%= mount[:destination_path] %>
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
143
|
+
<%- end # for each mount -%>
|
144
|
+
<%- end # if config_map init mounts and all_mounts not empty -%>
|
145
|
+
securityContext:
|
146
|
+
allowPrivilegeEscalation: false
|
147
|
+
capabilities:
|
148
|
+
drop:
|
149
|
+
- all
|
150
|
+
privileged: false
|
151
|
+
<%- end # init container loop -%>
|
152
|
+
<%- end # if init containers -%>
|
153
|
+
<%- unless (configmap.to_s.empty? && all_mounts.empty?) -%>
|
77
154
|
volumes:
|
78
|
-
|
79
|
-
<% unless configmap.nil? %>
|
155
|
+
<%- unless configmap.to_s.empty? -%>
|
80
156
|
- name: configmap-volume
|
81
157
|
configMap:
|
82
158
|
name: <%= configmap_name(id) %>
|
83
|
-
|
84
|
-
|
85
|
-
|
159
|
+
<%- end -%>
|
160
|
+
<%- all_mounts.each do |mount| -%>
|
161
|
+
<%- if mount[:type] == 'nfs' -%>
|
86
162
|
- name: <%= mount[:name] %>
|
87
163
|
nfs:
|
88
164
|
server: <%= mount[:host] %>
|
89
165
|
path: <%= mount[:path] %>
|
90
|
-
|
166
|
+
<%- elsif mount[:type] == 'host' -%>
|
91
167
|
- name: <%= mount[:name] %>
|
92
168
|
hostPath:
|
93
169
|
path: <%= mount[:path] %>
|
94
170
|
type: <%= mount[:host_type] %>
|
95
|
-
|
96
|
-
|
171
|
+
<%- end # if mount is [host,nfs] -%>
|
172
|
+
<%- end # for each mount -%>
|
173
|
+
<%- end # (configmap.to_s.empty? || all_mounts.empty?) -%>
|
174
|
+
<%- unless node_selector.empty? -%>
|
175
|
+
nodeSelector:
|
176
|
+
<%- node_selector.each_pair do |key, value| -%>
|
177
|
+
<%= key %>: "<%= value %>"
|
178
|
+
<%- end # node_selector.each_pair -%>
|
179
|
+
<%- end #unless node_selector.empty? -%>
|
97
180
|
---
|
98
|
-
|
181
|
+
<%- unless spec.container.port.nil? -%>
|
99
182
|
apiVersion: v1
|
100
183
|
kind: Service
|
101
184
|
metadata:
|
102
185
|
name: <%= service_name(id) %>
|
103
186
|
namespace: <%= namespace %>
|
187
|
+
labels:
|
188
|
+
job: <%= id %>
|
189
|
+
app.kubernetes.io/name: <%= container.name %>
|
190
|
+
app.kubernetes.io/managed-by: open-ondemand
|
104
191
|
spec:
|
105
192
|
selector:
|
106
193
|
job: <%= id %>
|
@@ -109,15 +196,22 @@ spec:
|
|
109
196
|
port: 80
|
110
197
|
targetPort: <%= spec.container.port %>
|
111
198
|
type: NodePort
|
112
|
-
|
199
|
+
<%- end # end for service -%>
|
200
|
+
<%- unless configmap.nil? -%>
|
113
201
|
---
|
114
|
-
<% unless configmap.nil? %>
|
115
202
|
apiVersion: v1
|
116
203
|
kind: ConfigMap
|
117
204
|
metadata:
|
118
205
|
name: <%= configmap_name(id) %>
|
119
206
|
namespace: <%= namespace %>
|
207
|
+
labels:
|
208
|
+
job: <%= id %>
|
209
|
+
app.kubernetes.io/name: <%= container.name %>
|
210
|
+
app.kubernetes.io/managed-by: open-ondemand
|
120
211
|
data:
|
121
|
-
|
122
|
-
|
123
|
-
|
212
|
+
<%- configmap.files.each do |file| -%>
|
213
|
+
<%- next if file.data.nil? || file.filename.nil? -%>
|
214
|
+
<%= file.filename %>: |
|
215
|
+
<% config_data_lines(file.data).each do |line| %><%= line %><% end %>
|
216
|
+
<%- end # end for configmap files -%>
|
217
|
+
<%- end # end configmap.nil? %>
|