ood_core 0.17.0 → 0.17.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 266e24cd2e11c2c712b6128bdc3f82bf9781ae9885f8f0eb21439cb80c889c90
4
- data.tar.gz: 01e682b6313468371076cdfd4ff2df2f3c06c661af9b4d7d7a65b7dcf3e2d836
3
+ metadata.gz: 88f0fb9eed8a53308dd19e73929e3c7af71ad1295738d69e0bf34d551a2ef0b3
4
+ data.tar.gz: 6437344171900c7b289ee3cf658550f050f95435e46b75eb1e34891e6ec9af08
5
5
  SHA512:
6
- metadata.gz: 22721c9d368ec44533d93914f977576ee77786ad0926976fa24067c7f353104edd32baffac34723b730e7f711c5b7581cf4f72f6232d050c719edcfc1b3cb14f
7
- data.tar.gz: 5d99a3c782aad5e420333653e51073cdb6535b7689053452da7ee7ef234292769e70d4010d751aacd4576daf531700136c2aa0ef7a2efc31edcb29e4c01c8be4
6
+ metadata.gz: b6aa7f5b93547e1c167870146f76766c70f2d26b19c706fd757880b70973281466674c5791bf62eafd5297b6733f20dc8e37128b4715374d764eb6c85d2b2919
7
+ data.tar.gz: 3930e176306b5354d2f451d744c89be9f61a714c31e8a0e4dcf6fc680ad7e70af6eb8769675157c7f7d247258f33d705bd146ac50e22553f8e064898b2ebebe6
data/CHANGELOG.md CHANGED
@@ -7,6 +7,50 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.17.5] - 8-20-2021
11
+
12
+ ### Fixed
13
+
14
+ - kubernetes jobs delete without waiting in [314](https://github.com/OSC/ood_core/pull/314).
15
+
16
+ ## [0.17.4] - 7-29-2021
17
+
18
+ Functionally the same as [0.17.3] but with some CI updates.
19
+
20
+ ## [0.17.3] - 7-29-2021
21
+
22
+ ### Fixed
23
+
24
+ - Fixed handling of pods in a startup phase in [303](https://github.com/OSC/ood_core/pull/303).
25
+
26
+ ### Added
27
+
28
+ - Enable automatic population of supplemental groups in [305](https://github.com/OSC/ood_core/pull/305).
29
+
30
+ ## [0.17.2] - 7-14-2021
31
+
32
+ ### Fixed
33
+
34
+ - Fixed k8s adapter to only show Running pods as running in [300](https://github.com/OSC/ood_core/pull/300).
35
+
36
+ ## [0.17.1] - 6-14-2021
37
+
38
+ ### Fixed
39
+
40
+ - Fixed [278](https://github.com/OSC/ood_core/pull/278) where unschedulable pods will now show up as
41
+ queued_held status.
42
+
43
+ ### Changed
44
+
45
+ - KUBECONFIG now defaults to /dev/null in the kubernetes adapter in [292](https://github.com/OSC/ood_core/pull/292).
46
+
47
+ ### Added
48
+
49
+ - Sites can now set `batch_connect.ssh_allow` on the cluster to disable the buttons to start
50
+ a shell session to compute nodes in [289](https://github.com/OSC/ood_core/pull/289).
51
+ - `POD_PORT` is now available to jobs in the kubernetes adapter in [290](https://github.com/OSC/ood_core/pull/290).
52
+ - Kubernetes pods now support a startProbe in [291](https://github.com/OSC/ood_core/pull/291).
53
+
10
54
  ## [0.17.0] - 5-26-2021
11
55
 
12
56
  ### Fixed
@@ -336,7 +380,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
336
380
  ### Added
337
381
  - Initial release!
338
382
 
339
- [Unreleased]: https://github.com/OSC/ood_core/compare/v0.16.0...HEAD
383
+ [Unreleased]: https://github.com/OSC/ood_core/compare/v0.17.5...HEAD
384
+ [0.17.5]: https://github.com/OSC/ood_core/compare/v0.17.4...v0.17.5
385
+ [0.17.4]: https://github.com/OSC/ood_core/compare/v0.17.3...v0.17.4
386
+ [0.17.3]: https://github.com/OSC/ood_core/compare/v0.17.2...v0.17.3
387
+ [0.17.2]: https://github.com/OSC/ood_core/compare/v0.17.1...v0.17.2
388
+ [0.17.1]: https://github.com/OSC/ood_core/compare/v0.17.0...v0.17.1
340
389
  [0.17.0]: https://github.com/OSC/ood_core/compare/v0.16.1...v0.17.0
341
390
  [0.16.1]: https://github.com/OSC/ood_core/compare/v0.16.0...v0.16.1
342
391
  [0.16.0]: https://github.com/OSC/ood_core/compare/v0.15.1...v0.16.0
@@ -148,12 +148,12 @@ module OodCore
148
148
  end
149
149
 
150
150
  # Whether this cluster supports SSH to batch connect nodes
151
- # @return [Boolean] whether cluster supports SSH to batch connect node
151
+ # @return [Boolean, nil] whether cluster supports SSH to batch connect node
152
152
  def batch_connect_ssh_allow?
153
153
  return @batch_connect_ssh_allow if defined?(@batch_connect_ssh_allow)
154
- return @batch_connect_ssh_allow = true if batch_connect_config.nil?
154
+ return @batch_connect_ssh_allow = nil if batch_connect_config.nil?
155
155
 
156
- @batch_connect_ssh_allow = batch_connect_config.fetch(:ssh_allow, true)
156
+ @batch_connect_ssh_allow = batch_connect_config.fetch(:ssh_allow, nil)
157
157
  end
158
158
 
159
159
  # The comparison operator
@@ -14,6 +14,7 @@ class OodCore::Job::Adapters::Kubernetes::Batch
14
14
  attr_reader :config_file, :bin, :cluster, :mounts
15
15
  attr_reader :all_namespaces, :using_context, :helper
16
16
  attr_reader :username_prefix, :namespace_prefix
17
+ attr_reader :auto_supplemental_groups
17
18
 
18
19
  def initialize(options = {})
19
20
  options = options.to_h.symbolize_keys
@@ -25,6 +26,7 @@ class OodCore::Job::Adapters::Kubernetes::Batch
25
26
  @all_namespaces = options.fetch(:all_namespaces, false)
26
27
  @username_prefix = options.fetch(:username_prefix, '')
27
28
  @namespace_prefix = options.fetch(:namespace_prefix, '')
29
+ @auto_supplemental_groups = options.fetch(:auto_supplemental_groups, false)
28
30
 
29
31
  @using_context = false
30
32
  @helper = OodCore::Job::Adapters::Kubernetes::Helper.new
@@ -123,7 +125,7 @@ class OodCore::Job::Adapters::Kubernetes::Batch
123
125
  when "get"
124
126
  call_json_output('get', resource, id)
125
127
  when "delete"
126
- call("#{namespaced_cmd} delete #{resource} #{id}")
128
+ call("#{namespaced_cmd} delete #{resource} #{id} --wait=false")
127
129
  end
128
130
  rescue NotFoundError
129
131
  {}
@@ -176,6 +178,19 @@ class OodCore::Job::Adapters::Kubernetes::Batch
176
178
  Etc.getgrgid(run_as_group).name
177
179
  end
178
180
 
181
+ def default_supplemental_groups
182
+ OodSupport::User.new.groups.sort_by(&:id).map(&:id).reject { |id| id < 1000 }
183
+ end
184
+
185
+ def supplemental_groups(groups = [])
186
+ sgroups = []
187
+ if auto_supplemental_groups
188
+ sgroups.concat(default_supplemental_groups)
189
+ end
190
+ sgroups.concat(groups.to_a)
191
+ sgroups.uniq.sort
192
+ end
193
+
179
194
  def default_env
180
195
  {
181
196
  USER: username,
@@ -183,6 +198,7 @@ class OodCore::Job::Adapters::Kubernetes::Batch
183
198
  HOME: home_dir,
184
199
  GROUP: group,
185
200
  GID: run_as_group,
201
+ KUBECONFIG: '/dev/null',
186
202
  }
187
203
  end
188
204
 
@@ -190,6 +206,7 @@ class OodCore::Job::Adapters::Kubernetes::Batch
190
206
  # create an id.
191
207
  def generate_id_yml(script)
192
208
  native_data = script.native
209
+ native_data[:container][:supplemental_groups] = supplemental_groups(native_data[:container][:supplemental_groups])
193
210
  container = helper.container_from_native(native_data[:container], default_env)
194
211
  id = generate_id(container.name)
195
212
  configmap = helper.configmap_from_native(native_data, id, script.content)
@@ -54,7 +54,9 @@ class OodCore::Job::Adapters::Kubernetes::Helper
54
54
  working_dir: container[:working_dir],
55
55
  restart_policy: container[:restart_policy],
56
56
  image_pull_policy: container[:image_pull_policy],
57
- image_pull_secret: container[:image_pull_secret]
57
+ image_pull_secret: container[:image_pull_secret],
58
+ supplemental_groups: container[:supplemental_groups],
59
+ startup_probe: container[:startup_probe],
58
60
  )
59
61
  end
60
62
 
@@ -149,7 +151,7 @@ class OodCore::Job::Adapters::Kubernetes::Helper
149
151
  {
150
152
  id: json_data.dig(:metadata, :name).to_s,
151
153
  job_name: name_from_metadata(json_data.dig(:metadata)),
152
- status: pod_status_from_json(json_data),
154
+ status: OodCore::Job::Status.new(state: pod_status_from_json(json_data)),
153
155
  job_owner: job_owner_from_json(json_data, ns_prefix),
154
156
  submission_time: submission_time(json_data),
155
157
  dispatch_time: dispatch_time(json_data),
@@ -239,15 +241,21 @@ class OodCore::Job::Adapters::Kubernetes::Helper
239
241
  def submission_time(json_data)
240
242
  status = json_data.dig(:status)
241
243
  start = status.dig(:startTime)
244
+ creation = json_data.dig(:metadata, :creationTimestamp)
242
245
 
243
- if start.nil?
246
+ if !creation.nil?
247
+ str = creation
248
+ elsif !start.nil?
249
+ str = start
250
+ else
244
251
  # the pod is in some pending state limbo
245
252
  conditions = status.dig(:conditions)
253
+ return nil if conditions.nil?
254
+ return nil if conditions.size == 0
246
255
  # best guess to start time is just the first condition's
247
256
  # transition time
248
257
  str = conditions[0].dig(:lastTransitionTime)
249
- else
250
- str = start
258
+ return nil if str.nil?
251
259
  end
252
260
 
253
261
  DateTime.parse(str).to_time.to_i
@@ -255,11 +263,21 @@ class OodCore::Job::Adapters::Kubernetes::Helper
255
263
 
256
264
  def pod_status_from_json(json_data)
257
265
  phase = json_data.dig(:status, :phase)
266
+ conditions = json_data.dig(:status, :conditions)
267
+ container_statuses = json_data.dig(:status, :containerStatuses)
268
+ unschedulable = conditions.to_a.any? { |c| c.dig(:reason) == "Unschedulable" }
269
+ ready = !container_statuses.to_a.empty? && container_statuses.to_a.all? { |s| s.dig(:ready) == true }
270
+ started = !container_statuses.to_a.empty? && container_statuses.to_a.any? { |s| s.fetch(:state, {}).key?(:running) }
271
+ return "running" if ready
272
+ return "queued" if phase == "Running" && started
273
+
258
274
  state = case phase
259
- when "Running"
260
- "running"
261
275
  when "Pending"
262
- "queued"
276
+ if unschedulable
277
+ "queued_held"
278
+ else
279
+ "queued"
280
+ end
263
281
  when "Failed"
264
282
  "suspended"
265
283
  when "Succeeded"
@@ -269,8 +287,6 @@ class OodCore::Job::Adapters::Kubernetes::Helper
269
287
  else
270
288
  "undetermined"
271
289
  end
272
-
273
- OodCore::Job::Status.new(state: state)
274
290
  end
275
291
 
276
292
  def terminated_state(status)
@@ -33,13 +33,36 @@ module OodCore::Job::Adapters::Kubernetes::Resources
33
33
  end
34
34
  end
35
35
 
36
+ class TCPProbe
37
+ attr_accessor :port, :initial_delay_seconds, :failure_threshold, :period_seconds
38
+
39
+ def initialize(port, data)
40
+ data ||= {}
41
+ @port = port
42
+ @initial_delay_seconds = data[:initial_delay_seconds] || 2
43
+ @failure_threshold = data[:failure_threshold] || 5
44
+ @period_seconds = data[:period_seconds] || 5
45
+ end
46
+
47
+ def to_h
48
+ {
49
+ port: port,
50
+ initial_delay_seconds: initial_delay_seconds,
51
+ failure_threshold: failure_threshold,
52
+ period_seconds: period_seconds,
53
+ }
54
+ end
55
+ end
56
+
36
57
  class Container
37
58
  attr_accessor :name, :image, :command, :port, :env, :memory, :cpu, :working_dir,
38
- :restart_policy, :image_pull_policy, :image_pull_secret, :supplemental_groups
59
+ :restart_policy, :image_pull_policy, :image_pull_secret, :supplemental_groups,
60
+ :startup_probe
39
61
 
40
62
  def initialize(
41
63
  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: []
64
+ working_dir: "", restart_policy: "Never", image_pull_policy: nil, image_pull_secret: nil, supplemental_groups: [],
65
+ startup_probe: {}
43
66
  )
44
67
  raise ArgumentError, "containers need valid names and images" unless name && image
45
68
 
@@ -55,6 +78,7 @@ module OodCore::Job::Adapters::Kubernetes::Resources
55
78
  @image_pull_policy = image_pull_policy.nil? ? "IfNotPresent" : image_pull_policy
56
79
  @image_pull_secret = image_pull_secret
57
80
  @supplemental_groups = supplemental_groups.nil? ? [] : supplemental_groups
81
+ @startup_probe = TCPProbe.new(@port, startup_probe)
58
82
  end
59
83
 
60
84
  def ==(other)
@@ -69,7 +93,8 @@ module OodCore::Job::Adapters::Kubernetes::Resources
69
93
  restart_policy == other.restart_policy &&
70
94
  image_pull_policy == other.image_pull_policy &&
71
95
  image_pull_secret == other.image_pull_secret &&
72
- supplemental_groups == other.supplemental_groups
96
+ supplemental_groups == other.supplemental_groups &&
97
+ startup_probe.to_h == other.startup_probe.to_h
73
98
  end
74
99
  end
75
100
 
@@ -20,14 +20,7 @@ spec:
20
20
  runAsUser: <%= run_as_user %>
21
21
  runAsGroup: <%= run_as_group %>
22
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 -%>
23
+ supplementalGroups: <%= spec.container.supplemental_groups %>
31
24
  fsGroup: <%= fs_group %>
32
25
  hostNetwork: false
33
26
  hostIPC: false
@@ -52,6 +45,10 @@ spec:
52
45
  valueFrom:
53
46
  fieldRef:
54
47
  fieldPath: metadata.namespace
48
+ <%- unless spec.container.port.nil? -%>
49
+ - name: POD_PORT
50
+ value: "<%= spec.container.port %>"
51
+ <%- end -%>
55
52
  <%- spec.container.env.each_pair do |name, value| -%>
56
53
  - name: <%= name %>
57
54
  value: "<%= value %>"
@@ -65,6 +62,12 @@ spec:
65
62
  <%- unless spec.container.port.nil? -%>
66
63
  ports:
67
64
  - containerPort: <%= spec.container.port %>
65
+ startupProbe:
66
+ tcpSocket:
67
+ port: <%= spec.container.startup_probe.port %>
68
+ initialDelaySeconds: <%= spec.container.startup_probe.initial_delay_seconds %>
69
+ failureThreshold: <%= spec.container.startup_probe.failure_threshold %>
70
+ periodSeconds: <%= spec.container.startup_probe.period_seconds %>
68
71
  <%- end -%>
69
72
  <%- if !all_mounts.empty? || (!configmap.nil? && configmap.mounts?) -%>
70
73
  volumeMounts:
@@ -1,4 +1,4 @@
1
1
  module OodCore
2
2
  # The current version of {OodCore}
3
- VERSION = "0.17.0"
3
+ VERSION = "0.17.5"
4
4
  end
data/ood_core.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.license = "MIT"
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
- f.match(%r{^(test|spec|features)/})
18
+ f.match(%r{^(test|spec|features|.github)/})
19
19
  end
20
20
  spec.bindir = "exe"
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ood_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.17.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Franz
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-05-26 00:00:00.000000000 Z
13
+ date: 2021-08-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ood_support
@@ -160,7 +160,6 @@ executables: []
160
160
  extensions: []
161
161
  extra_rdoc_files: []
162
162
  files:
163
- - ".github/workflows/test.yml"
164
163
  - ".gitignore"
165
164
  - ".rspec"
166
165
  - CHANGELOG.md
@@ -1,30 +0,0 @@
1
- name: Unit Tests
2
-
3
- on:
4
- push:
5
- branches:
6
- - master
7
- pull_request:
8
- branches:
9
- - master
10
-
11
- jobs:
12
- tests:
13
- runs-on: ubuntu-latest
14
-
15
- steps:
16
- - name: checkout
17
- uses: actions/checkout@v2
18
-
19
- - name: Setup Ruby using Bundler
20
- uses: ruby/setup-ruby@v1
21
- with:
22
- ruby-version: "2.7.1"
23
- bundler-cache: true
24
- bundler: "2.1.4"
25
-
26
- - name: install gems
27
- run: bundle install
28
-
29
- - name: test
30
- run: bundle exec rake spec