cpl 1.3.0 → 2.0.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/command_docs.yml +1 -1
  3. data/.github/workflows/rspec-shared.yml +56 -0
  4. data/.github/workflows/rspec.yml +19 -31
  5. data/.github/workflows/rubocop.yml +2 -10
  6. data/.gitignore +2 -0
  7. data/.simplecov_spawn.rb +10 -0
  8. data/CHANGELOG.md +28 -1
  9. data/CONTRIBUTING.md +32 -2
  10. data/Gemfile.lock +38 -29
  11. data/README.md +43 -17
  12. data/cpl.gemspec +2 -1
  13. data/docs/commands.md +68 -59
  14. data/docs/dns.md +6 -0
  15. data/docs/migrating.md +10 -10
  16. data/docs/tips.md +15 -3
  17. data/examples/circleci.yml +3 -3
  18. data/examples/controlplane.yml +35 -9
  19. data/lib/command/apply_template.rb +66 -18
  20. data/lib/command/base.rb +168 -27
  21. data/lib/command/build_image.rb +4 -9
  22. data/lib/command/cleanup_stale_apps.rb +1 -3
  23. data/lib/command/copy_image_from_upstream.rb +0 -7
  24. data/lib/command/delete.rb +39 -7
  25. data/lib/command/deploy_image.rb +35 -2
  26. data/lib/command/exists.rb +1 -1
  27. data/lib/command/generate.rb +1 -1
  28. data/lib/command/info.rb +7 -3
  29. data/lib/command/logs.rb +22 -2
  30. data/lib/command/maintenance_off.rb +1 -1
  31. data/lib/command/maintenance_on.rb +1 -1
  32. data/lib/command/open.rb +2 -2
  33. data/lib/command/open_console.rb +2 -2
  34. data/lib/command/promote_app_from_upstream.rb +5 -25
  35. data/lib/command/ps.rb +1 -1
  36. data/lib/command/ps_start.rb +2 -1
  37. data/lib/command/ps_stop.rb +40 -8
  38. data/lib/command/ps_wait.rb +3 -2
  39. data/lib/command/run.rb +430 -68
  40. data/lib/command/setup_app.rb +22 -2
  41. data/lib/constants/exit_code.rb +7 -0
  42. data/lib/core/config.rb +11 -3
  43. data/lib/core/controlplane.rb +126 -47
  44. data/lib/core/controlplane_api.rb +15 -1
  45. data/lib/core/controlplane_api_cli.rb +3 -3
  46. data/lib/core/controlplane_api_direct.rb +33 -5
  47. data/lib/core/shell.rb +15 -9
  48. data/lib/cpl/version.rb +1 -1
  49. data/lib/cpl.rb +50 -9
  50. data/lib/deprecated_commands.json +2 -1
  51. data/lib/generator_templates/controlplane.yml +5 -0
  52. data/lib/generator_templates/templates/{gvc.yml → app.yml} +4 -4
  53. data/lib/generator_templates/templates/postgres.yml +1 -1
  54. data/lib/generator_templates/templates/rails.yml +1 -1
  55. data/script/check_cpln_links +3 -3
  56. data/templates/app.yml +18 -0
  57. data/templates/daily-task.yml +3 -2
  58. data/templates/rails.yml +3 -2
  59. data/templates/secrets.yml +11 -0
  60. data/templates/sidekiq.yml +3 -2
  61. metadata +38 -25
  62. data/.rspec +0 -1
  63. data/lib/command/run_cleanup.rb +0 -116
  64. data/lib/command/run_detached.rb +0 -175
  65. data/lib/core/scripts.rb +0 -34
  66. data/templates/gvc.yml +0 -13
  67. data/templates/identity.yml +0 -2
@@ -106,7 +106,7 @@ bindings:
106
106
  # - use
107
107
  # - view
108
108
  principalLinks:
109
- - //gvc/APP_GVC/identity/postgres-poc-identity
109
+ - //gvc/{{APP_NAME}}/identity/postgres-poc-identity
110
110
  targetKind: secret
111
111
  targetLinks:
112
112
  - //secret/postgres-poc-credentials
@@ -14,7 +14,7 @@ spec:
14
14
  value: debug
15
15
  # Inherit other ENV values from GVC
16
16
  inheritEnv: true
17
- image: '/org/APP_ORG/image/APP_IMAGE'
17
+ image: {{APP_IMAGE_LINK}}
18
18
  # 512 corresponds to a standard 1x dyno type
19
19
  memory: 512Mi
20
20
  ports:
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- bad_links=("controlplane.com/shakacode")
4
- proper_links=("shakacode.controlplane.com")
3
+ bad_links=("controlplane.com/shakacode" "https://docs.controlplane.com")
4
+ proper_links=("shakacode.controlplane.com" "https://shakadocs.controlplane.com")
5
5
 
6
6
  bold=$(tput bold)
7
7
  normal=$(tput sgr0)
@@ -19,7 +19,7 @@ for ((idx = 0; idx < ${#bad_links[@]}; idx++)); do
19
19
  --heading \
20
20
  --color=always -- \
21
21
  "${bad_links[idx]}" \
22
- ':!script/check_cpln_links')
22
+ ':!script/check_cpln_links' '*.md')
23
23
 
24
24
  # Line would become really unwieldly if everything was mushed into the
25
25
  # conditional, so let's ignore this check here.
data/templates/app.yml ADDED
@@ -0,0 +1,18 @@
1
+ kind: gvc
2
+ name: {{APP_NAME}}
3
+ spec:
4
+ env:
5
+ - name: MEMCACHE_SERVERS
6
+ value: memcached.{{APP_NAME}}.cpln.local
7
+ - name: REDIS_URL
8
+ value: redis://redis.{{APP_NAME}}.cpln.local:6379
9
+ - name: DATABASE_URL
10
+ value: postgres://postgres:password123@postgres.{{APP_NAME}}.cpln.local:5432/{{APP_NAME}}
11
+ staticPlacement:
12
+ locationLinks:
13
+ - {{APP_LOCATION_LINK}}
14
+ ---
15
+ # Identity is needed to access secrets
16
+ kind: identity
17
+ name: {{APP_IDENTITY}}
18
+
@@ -18,7 +18,7 @@ spec:
18
18
  - rails
19
19
  - db:prepare
20
20
  inheritEnv: true
21
- image: "/org/APP_ORG/image/APP_IMAGE"
21
+ image: {{APP_IMAGE_LINK}}
22
22
  defaultOptions:
23
23
  autoscaling:
24
24
  minScale: 1
@@ -28,4 +28,5 @@ spec:
28
28
  external:
29
29
  outboundAllowCIDR:
30
30
  - 0.0.0.0/0
31
- identityLink: /org/APP_ORG/gvc/APP_GVC/identity/APP_GVC-identity
31
+ # Identity is used for binding workload to secrets
32
+ identityLink: {{APP_IDENTITY_LINK}}
data/templates/rails.yml CHANGED
@@ -7,7 +7,7 @@ spec:
7
7
  cpu: 512m
8
8
  memory: 1Gi
9
9
  inheritEnv: true
10
- image: "/org/APP_ORG/image/APP_IMAGE"
10
+ image: {{APP_IMAGE_LINK}}
11
11
  ports:
12
12
  - number: 3000
13
13
  protocol: http
@@ -23,4 +23,5 @@ spec:
23
23
  - 0.0.0.0/0
24
24
  outboundAllowCIDR:
25
25
  - 0.0.0.0/0
26
- identityLink: /org/APP_ORG/gvc/APP_GVC/identity/APP_GVC-identity
26
+ # Identity is used for binding workload to secrets
27
+ identityLink: {{APP_IDENTITY_LINK}}
@@ -0,0 +1,11 @@
1
+ kind: secret
2
+ name: {{APP_SECRETS}}
3
+ type: dictionary
4
+ data: {}
5
+ ---
6
+ # Policy is needed to allow identities to access secrets
7
+ kind: policy
8
+ name: {{APP_SECRETS_POLICY}}
9
+ targetKind: secret
10
+ targetLinks:
11
+ - //secret/{{APP_SECRETS}}
@@ -13,7 +13,7 @@ spec:
13
13
  - "-C"
14
14
  - config/sidekiq.yml
15
15
  inheritEnv: true
16
- image: "/org/APP_ORG/image/APP_IMAGE"
16
+ image: {{APP_IMAGE_LINK}}
17
17
  ports:
18
18
  - number: 7433
19
19
  protocol: http
@@ -34,4 +34,5 @@ spec:
34
34
  external:
35
35
  outboundAllowCIDR:
36
36
  - 0.0.0.0/0
37
- identityLink: /org/APP_ORG/gvc/APP_GVC/identity/APP_GVC-identity
37
+ # Identity is used for binding workload to secrets
38
+ identityLink: {{APP_IDENTITY_LINK}}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.0.0.rc.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-03-19 00:00:00.000000000 Z
12
+ date: 2024-05-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: debug
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
41
  version: 2.8.1
42
+ - !ruby/object:Gem::Dependency
43
+ name: jwt
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 2.8.1
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 2.8.1
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: psych
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -95,6 +109,20 @@ dependencies:
95
109
  - - "~>"
96
110
  - !ruby/object:Gem::Version
97
111
  version: 3.12.0
112
+ - !ruby/object:Gem::Dependency
113
+ name: rspec-retry
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: 0.6.2
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: 0.6.2
98
126
  - !ruby/object:Gem::Dependency
99
127
  name: rubocop
100
128
  requirement: !ruby/object:Gem::Requirement
@@ -165,20 +193,6 @@ dependencies:
165
193
  - - "~>"
166
194
  - !ruby/object:Gem::Version
167
195
  version: 0.9.6
168
- - !ruby/object:Gem::Dependency
169
- name: vcr
170
- requirement: !ruby/object:Gem::Requirement
171
- requirements:
172
- - - "~>"
173
- - !ruby/object:Gem::Version
174
- version: 6.1.0
175
- type: :development
176
- prerelease: false
177
- version_requirements: !ruby/object:Gem::Requirement
178
- requirements:
179
- - - "~>"
180
- - !ruby/object:Gem::Version
181
- version: 6.1.0
182
196
  - !ruby/object:Gem::Dependency
183
197
  name: webmock
184
198
  requirement: !ruby/object:Gem::Requirement
@@ -204,12 +218,13 @@ extra_rdoc_files: []
204
218
  files:
205
219
  - ".github/workflows/check_cpln_links.yml"
206
220
  - ".github/workflows/command_docs.yml"
221
+ - ".github/workflows/rspec-shared.yml"
207
222
  - ".github/workflows/rspec.yml"
208
223
  - ".github/workflows/rubocop.yml"
209
224
  - ".gitignore"
210
225
  - ".overcommit.yml"
211
- - ".rspec"
212
226
  - ".rubocop.yml"
227
+ - ".simplecov_spawn.rb"
213
228
  - CHANGELOG.md
214
229
  - CONTRIBUTING.md
215
230
  - Gemfile
@@ -262,18 +277,16 @@ files:
262
277
  - lib/command/ps_stop.rb
263
278
  - lib/command/ps_wait.rb
264
279
  - lib/command/run.rb
265
- - lib/command/run_cleanup.rb
266
- - lib/command/run_detached.rb
267
280
  - lib/command/setup_app.rb
268
281
  - lib/command/test.rb
269
282
  - lib/command/version.rb
283
+ - lib/constants/exit_code.rb
270
284
  - lib/core/config.rb
271
285
  - lib/core/controlplane.rb
272
286
  - lib/core/controlplane_api.rb
273
287
  - lib/core/controlplane_api_cli.rb
274
288
  - lib/core/controlplane_api_direct.rb
275
289
  - lib/core/helpers.rb
276
- - lib/core/scripts.rb
277
290
  - lib/core/shell.rb
278
291
  - lib/cpl.rb
279
292
  - lib/cpl/version.rb
@@ -281,7 +294,7 @@ files:
281
294
  - lib/generator_templates/Dockerfile
282
295
  - lib/generator_templates/controlplane.yml
283
296
  - lib/generator_templates/entrypoint.sh
284
- - lib/generator_templates/templates/gvc.yml
297
+ - lib/generator_templates/templates/app.yml
285
298
  - lib/generator_templates/templates/postgres.yml
286
299
  - lib/generator_templates/templates/rails.yml
287
300
  - rakelib/create_release.rake
@@ -290,14 +303,14 @@ files:
290
303
  - script/check_cpln_links
291
304
  - script/rename_command
292
305
  - script/update_command_docs
306
+ - templates/app.yml
293
307
  - templates/daily-task.yml
294
- - templates/gvc.yml
295
- - templates/identity.yml
296
308
  - templates/maintenance.yml
297
309
  - templates/memcached.yml
298
310
  - templates/postgres.yml
299
311
  - templates/rails.yml
300
312
  - templates/redis.yml
313
+ - templates/secrets.yml
301
314
  - templates/sidekiq.yml
302
315
  homepage: https://github.com/shakacode/heroku-to-control-plane
303
316
  licenses:
@@ -315,9 +328,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
315
328
  version: 2.7.0
316
329
  required_rubygems_version: !ruby/object:Gem::Requirement
317
330
  requirements:
318
- - - ">="
331
+ - - ">"
319
332
  - !ruby/object:Gem::Version
320
- version: '0'
333
+ version: 1.3.1
321
334
  requirements: []
322
335
  rubygems_version: 3.4.21
323
336
  signing_key:
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --require spec_helper
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Command
4
- class RunCleanup < Base
5
- NAME = "run:cleanup"
6
- OPTIONS = [
7
- app_option(required: true),
8
- skip_confirm_option
9
- ].freeze
10
- DESCRIPTION = "Deletes stale run workloads for an app"
11
- LONG_DESCRIPTION = <<~DESC
12
- - Deletes stale run workloads for an app
13
- - Workloads are considered stale based on how many days since created
14
- - `stale_run_workload_created_days` in the `.controlplane/controlplane.yml` file specifies the number of days after created that the workload is considered stale
15
- - Works for both interactive workloads (created with `cpl run`) and non-interactive workloads (created with `cpl run:detached`)
16
- - Will ask for explicit user confirmation of deletion
17
- DESC
18
-
19
- def call # rubocop:disable Metrics/MethodLength
20
- return progress.puts("No stale run workloads found.") if stale_run_workloads.empty?
21
-
22
- progress.puts("Stale run workloads:")
23
- stale_run_workloads.each do |workload|
24
- output = ""
25
- output += if config.should_app_start_with?(config.app)
26
- " #{workload[:app]} - #{workload[:name]}"
27
- else
28
- " #{workload[:name]}"
29
- end
30
- output += " (#{Shell.color("#{workload[:date]} - #{workload[:days]} days ago", :red)})"
31
- progress.puts(output)
32
- end
33
-
34
- return unless confirm_delete
35
-
36
- progress.puts
37
- stale_run_workloads.each do |workload|
38
- delete_workload(workload)
39
- end
40
- end
41
-
42
- private
43
-
44
- def app_matches?(app, app_name, app_options)
45
- app == app_name.to_s || (app_options[:match_if_app_name_starts_with] && app.start_with?(app_name.to_s))
46
- end
47
-
48
- def find_app_options(app)
49
- @app_options ||= {}
50
- @app_options[app] ||= config.apps.find do |app_name, app_options|
51
- app_matches?(app, app_name, app_options)
52
- end&.last
53
- end
54
-
55
- def find_workloads(app)
56
- app_options = find_app_options(app)
57
- return [] if app_options.nil?
58
-
59
- (app_options[:app_workloads] + app_options[:additional_workloads] + [app_options[:one_off_workload]]).uniq
60
- end
61
-
62
- def stale_run_workloads # rubocop:disable Metrics/MethodLength
63
- @stale_run_workloads ||=
64
- begin
65
- defined_workloads = find_workloads(config.app)
66
-
67
- run_workloads = []
68
-
69
- now = DateTime.now
70
- stale_run_workload_created_days = config[:stale_run_workload_created_days]
71
-
72
- interactive_workloads = cp.query_workloads("-run-", partial_workload_match: true)["items"]
73
- non_interactive_workloads = cp.query_workloads("-runner-", partial_workload_match: true)["items"]
74
- workloads = interactive_workloads + non_interactive_workloads
75
-
76
- workloads.each do |workload|
77
- app_name = workload["links"].find { |link| link["rel"] == "gvc" }["href"].split("/").last
78
- workload_name = workload["name"]
79
-
80
- original_workload_name, workload_number = workload_name.split(/-run-|-runner-/)
81
- next unless defined_workloads.include?(original_workload_name) && workload_number.match?(/^\d{4}$/)
82
-
83
- created_date = DateTime.parse(workload["created"])
84
- diff_in_days = (now - created_date).to_i
85
- next unless diff_in_days >= stale_run_workload_created_days
86
-
87
- run_workloads.push({
88
- app: app_name,
89
- name: workload_name,
90
- date: created_date,
91
- days: diff_in_days
92
- })
93
- end
94
-
95
- run_workloads
96
- end
97
- end
98
-
99
- def confirm_delete
100
- return true if config.options[:yes]
101
-
102
- Shell.confirm("\nAre you sure you want to delete these #{stale_run_workloads.length} run workloads?")
103
- end
104
-
105
- def delete_workload(workload)
106
- message = if config.should_app_start_with?(config.app)
107
- "Deleting run workload '#{workload[:app]} - #{workload[:name]}'"
108
- else
109
- "Deleting run workload '#{workload[:name]}'"
110
- end
111
- step(message) do
112
- cp.delete_workload(workload[:name], workload[:app])
113
- end
114
- end
115
- end
116
- end
@@ -1,175 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Command
4
- class RunDetached < Base # rubocop:disable Metrics/ClassLength
5
- NAME = "run:detached"
6
- USAGE = "run:detached COMMAND"
7
- REQUIRES_ARGS = true
8
- OPTIONS = [
9
- app_option(required: true),
10
- image_option,
11
- workload_option,
12
- location_option,
13
- use_local_token_option,
14
- clean_on_failure_option
15
- ].freeze
16
- DESCRIPTION = "Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)"
17
- LONG_DESCRIPTION = <<~DESC
18
- - Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)
19
- - Uses `Cron` workload type with log async fetching
20
- - Implemented with only async execution methods, more suitable for production tasks
21
- - Has alternative log fetch implementation with only JSON-polling and no WebSockets
22
- - Less responsive but more stable, useful for CI tasks
23
- - Deletes the workload whenever finished with success
24
- - Deletes the workload whenever finished with failure by default
25
- - Use `--no-clean-on-failure` to disable cleanup to help with debugging failed runs
26
- DESC
27
- EXAMPLES = <<~EX
28
- ```sh
29
- cpl run:detached rails db:prepare -a $APP_NAME
30
-
31
- # Need to quote COMMAND if setting ENV value or passing args.
32
- cpl run:detached -a $APP_NAME -- 'LOG_LEVEL=warn rails db:migrate'
33
-
34
- # Uses a different image (which may not be promoted yet).
35
- cpl run:detached -a $APP_NAME --image appimage:123 -- rails db:migrate # Exact image name
36
- cpl run:detached -a $APP_NAME --image latest -- rails db:migrate # Latest sequential image
37
-
38
- # Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
39
- cpl run:detached -a $APP_NAME -w other-workload -- rails db:migrate:status
40
-
41
- # Overrides remote CPLN_TOKEN env variable with local token.
42
- # Useful when superuser rights are needed in remote container.
43
- cpl run:detached -a $APP_NAME --use-local-token -- rails db:migrate:status
44
- ```
45
- EX
46
-
47
- WORKLOAD_SLEEP_CHECK = 2
48
-
49
- attr_reader :location, :workload_to_clone, :workload_clone, :container
50
-
51
- def call
52
- @location = config.location
53
- @workload_to_clone = config.options["workload"] || config[:one_off_workload]
54
- @workload_clone = "#{workload_to_clone}-runner-#{random_four_digits}"
55
-
56
- step("Cloning workload '#{workload_to_clone}' on app '#{config.options[:app]}' to '#{workload_clone}'") do
57
- clone_workload
58
- end
59
-
60
- wait_for_workload(workload_clone)
61
- show_logs_waiting
62
- ensure
63
- exit(1) if @crashed
64
- end
65
-
66
- private
67
-
68
- def clone_workload # rubocop:disable Metrics/MethodLength
69
- # Get base specs of workload
70
- spec = cp.fetch_workload!(workload_to_clone).fetch("spec")
71
- container_spec = spec["containers"].detect { _1["name"] == workload_to_clone } || spec["containers"].first
72
- @container = container_spec["name"]
73
-
74
- # remove other containers if any
75
- spec["containers"] = [container_spec]
76
-
77
- # Set runner
78
- container_spec["command"] = "bash"
79
- container_spec["args"] = ["-c", 'eval "$CONTROLPLANE_RUNNER"']
80
-
81
- # Ensure one-off workload will be running
82
- spec["defaultOptions"]["suspend"] = false
83
-
84
- # Ensure no scaling
85
- spec["defaultOptions"]["autoscaling"]["minScale"] = 1
86
- spec["defaultOptions"]["autoscaling"]["maxScale"] = 1
87
- spec["defaultOptions"]["capacityAI"] = false
88
-
89
- # Override image if specified
90
- image = config.options[:image]
91
- image = latest_image if image == "latest"
92
- container_spec["image"] = "/org/#{config.org}/image/#{image}" if image
93
-
94
- # Set cron job props
95
- spec["type"] = "cron"
96
- spec["job"] = { "schedule" => "* * * * *", "restartPolicy" => "Never" }
97
- spec["defaultOptions"]["autoscaling"] = {}
98
- container_spec.delete("ports")
99
-
100
- container_spec["env"] ||= []
101
- container_spec["env"] << { "name" => "CONTROLPLANE_TOKEN", "value" => ControlplaneApiDirect.new.api_token }
102
- container_spec["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
103
-
104
- # Create workload clone
105
- cp.apply_hash("kind" => "workload", "name" => workload_clone, "spec" => spec)
106
- end
107
-
108
- def runner_script # rubocop:disable Metrics/MethodLength
109
- script = "echo '-- STARTED RUNNER SCRIPT --'\n"
110
- script += Scripts.helpers_cleanup
111
-
112
- if config.options["use_local_token"]
113
- script += <<~SHELL
114
- CPLN_TOKEN=$CONTROLPLANE_TOKEN
115
- SHELL
116
- end
117
-
118
- script += <<~SHELL
119
- crashed=0
120
- if ! eval "#{args_join(config.args)}"; then
121
- crashed=1
122
- echo "----- CRASHED -----"
123
- fi
124
- clean_on_failure=#{config.options[:clean_on_failure] ? 1 : 0}
125
- if [ $crashed -eq 0 ] || [ $clean_on_failure -eq 1 ]; then
126
- echo "-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --"
127
- sleep 30 # grace time for logs propagation
128
- curl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H "Authorization: ${CONTROLPLANE_TOKEN}" -X DELETE -s -o /dev/null
129
- while true; do sleep 1; done # wait for SIGTERM
130
- else
131
- echo "-- FINISHED RUNNER SCRIPT --"
132
- fi
133
- SHELL
134
-
135
- script
136
- end
137
-
138
- def show_logs_waiting # rubocop:disable Metrics/MethodLength
139
- progress.puts("Scheduled, fetching logs (it's a cron job, so it may take up to a minute to start)...\n\n")
140
- begin
141
- @finished = false
142
- while cp.fetch_workload(workload_clone) && !@finished
143
- sleep(WORKLOAD_SLEEP_CHECK)
144
- print_uniq_logs
145
- end
146
- rescue RuntimeError => e
147
- progress.puts(Shell.color("ERROR: #{e}", :red))
148
- retry
149
- end
150
- progress.puts("\nFinished workload and logger.")
151
- end
152
-
153
- def print_uniq_logs
154
- @printed_log_entries ||= []
155
- ts = Time.now.to_i
156
- entries = normalized_log_entries(from: ts - 60, to: ts)
157
-
158
- (entries - @printed_log_entries).sort.each do |(_ts, val)|
159
- @crashed = true if val.match?(/^----- CRASHED -----$/)
160
- @finished = true if val.match?(/^-- FINISHED RUNNER SCRIPT(, DELETING WORKLOAD)? --$/)
161
- puts val
162
- end
163
-
164
- @printed_log_entries = entries # as well truncate old entries if any
165
- end
166
-
167
- def normalized_log_entries(from:, to:)
168
- log = cp.log_get(workload: workload_clone, from: from, to: to)
169
-
170
- log["data"]["result"]
171
- .each_with_object([]) { |obj, result| result.concat(obj["values"]) }
172
- .select { |ts, _val| ts[..-10].to_i > from }
173
- end
174
- end
175
- end
data/lib/core/scripts.rb DELETED
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Scripts
4
- module_function
5
-
6
- def assert_replicas(gvc:, workload:, location:)
7
- <<~SHELL
8
- REPLICAS_QTY=$( \
9
- curl ${CPLN_ENDPOINT}/org/shakacode-staging/gvc/#{gvc}/workload/#{workload}/deployment/#{location} \
10
- -H "Authorization: ${CONTROLPLANE_TOKEN}" -s | grep -o '"replicas":[0-9]*' | grep -o '[0-9]*')
11
-
12
- if [ "$REPLICAS_QTY" -gt 0 ]; then
13
- echo "-- MULTIPLE REPLICAS ATTEMPT: $REPLICAS_QTY --"
14
- exit -1
15
- fi
16
- SHELL
17
- end
18
-
19
- def helpers_cleanup
20
- <<~SHELL
21
- unset CONTROLPLANE_RUNNER
22
- SHELL
23
- end
24
-
25
- # NOTE: please escape all '/' as '//' (as it is ruby interpolation here as well)
26
- def http_dummy_server_ruby
27
- 'require "socket";s=TCPServer.new(ENV["PORT"] || 80);' \
28
- 'loop do c=s.accept;c.puts("HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk");c.close end'
29
- end
30
-
31
- def http_ping_ruby
32
- 'require "net/http";uri=URI(ENV["CPLN_GLOBAL_ENDPOINT"]);loop do puts(Net::HTTP.get(uri));sleep(5);end'
33
- end
34
- end
data/templates/gvc.yml DELETED
@@ -1,13 +0,0 @@
1
- kind: gvc
2
- name: APP_GVC
3
- spec:
4
- env:
5
- - name: MEMCACHE_SERVERS
6
- value: memcached.APP_GVC.cpln.local
7
- - name: REDIS_URL
8
- value: redis://redis.APP_GVC.cpln.local:6379
9
- - name: DATABASE_URL
10
- value: postgres://postgres:password123@postgres.APP_GVC.cpln.local:5432/APP_GVC
11
- staticPlacement:
12
- locationLinks:
13
- - /org/APP_ORG/location/APP_LOCATION
@@ -1,2 +0,0 @@
1
- kind: identity
2
- name: APP_GVC-identity