cpl 1.3.0 → 2.0.0.rc.0

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.
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