cpl 0.6.0 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cfd7383099c36f633d327424fcb36561e2b925120e63f1b814158a43bd55103f
4
- data.tar.gz: eafdf0607fe28d3c24f8132e3a116085020c94639d5b05a5accec4d4de651ca5
3
+ metadata.gz: 976c390927b51f67afe7a161b7185242261afb4c24db893026457b205fe61b12
4
+ data.tar.gz: b55bec82c485eb413c9a8787d34172e2c7e89212c15e319f3f626c652c3ac6e7
5
5
  SHA512:
6
- metadata.gz: b443d26a3fa91400dbb6d2e71b730a26bd1405df2f03e7f9446179323e2becb532ec69d81d93f22578fe8793dbabec9a2283efc16a107decdb5aaa9e4a615281
7
- data.tar.gz: 34ab7670bc372af9b8991678de9d99a9c60429b3caebeeeb2775046a9be3d4a7fb7335d9cbeb3a6c2ba06bb29ef40ab7c2cffbcd20737cfb62eb4048b07a8926
6
+ metadata.gz: 678825b452c56d5c481639de70904ab087f29e362c4b8ced34d3c2131f15a176f78c0c928b02449ebc96a0e69bd1e5c2cd1982577e06a0b62000aa0993bd4f91
7
+ data.tar.gz: a40e2ea6bfb43122c919d9126d6fffdb6a9722396bed1c4b22b5874d06f9b2126ee4f14e6df37047bb417bcb0788b3b19869d03b34801030b6e8e373f47950c2
data/.rubocop.yml CHANGED
@@ -14,3 +14,9 @@ Style/Documentation:
14
14
 
15
15
  Style/StringLiterals:
16
16
  EnforcedStyle: double_quotes
17
+
18
+ RSpec/ExampleLength:
19
+ Enabled: false
20
+
21
+ RSpec/MultipleExpectations:
22
+ Enabled: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cpl (0.6.0)
4
+ cpl (0.7.0)
5
5
  debug (~> 1.7.1)
6
6
  dotenv (~> 2.8.1)
7
7
  psych (~> 5.1.0)
@@ -10,14 +10,19 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
+ addressable (2.8.4)
14
+ public_suffix (>= 2.0.2, < 6.0)
13
15
  ast (2.4.2)
14
16
  childprocess (4.1.0)
17
+ crack (0.4.5)
18
+ rexml
15
19
  debug (1.7.2)
16
20
  irb (>= 1.5.0)
17
21
  reline (>= 0.3.1)
18
22
  diff-lcs (1.5.0)
19
23
  docile (1.4.0)
20
24
  dotenv (2.8.1)
25
+ hashdiff (1.0.1)
21
26
  iniparse (1.5.0)
22
27
  io-console (0.6.0)
23
28
  irb (1.6.4)
@@ -32,6 +37,7 @@ GEM
32
37
  ast (~> 2.4.1)
33
38
  psych (5.1.0)
34
39
  stringio
40
+ public_suffix (5.0.1)
35
41
  rainbow (3.1.1)
36
42
  rake (13.0.6)
37
43
  regexp_parser (2.6.2)
@@ -78,8 +84,14 @@ GEM
78
84
  simplecov-html (0.12.3)
79
85
  simplecov_json_formatter (0.1.4)
80
86
  stringio (3.0.6)
81
- thor (1.2.1)
87
+ thor (1.2.2)
88
+ timecop (0.9.6)
82
89
  unicode-display_width (2.4.2)
90
+ vcr (6.1.0)
91
+ webmock (3.18.1)
92
+ addressable (>= 2.8.0)
93
+ crack (>= 0.3.2)
94
+ hashdiff (>= 0.4.0, < 2.0.0)
83
95
 
84
96
  PLATFORMS
85
97
  ruby
@@ -94,6 +106,9 @@ DEPENDENCIES
94
106
  rubocop-rake (~> 0.6.0)
95
107
  rubocop-rspec (~> 2.18.1)
96
108
  simplecov (~> 0.22.0)
109
+ timecop (~> 0.9.6)
110
+ vcr (~> 6.1.0)
111
+ webmock (~> 3.18.1)
97
112
 
98
113
  BUNDLED WITH
99
114
  2.3.26
data/README.md CHANGED
@@ -28,11 +28,12 @@ To simplify migration to and usage of Control Plane for Heroku users, this repos
28
28
  6. [Environment](#environment)
29
29
  7. [Database](#database)
30
30
  8. [In-memory databases](#in-memory-databases)
31
- 9. [CLI commands reference](#cli-commands-reference)
32
- 10. [Mapping of Heroku Commands to `cpl` and `cpln`](#mapping-of-heroku-commands-to-cpl-and-cpln)
33
- 11. [Examples](#examples)
34
- 12. [Migrating Postgres database from Heroku infrastructure](/docs/postgres.md)
35
- 13. [Migrating Redis database from Heroku infrastructure](/docs/redis.md)
31
+ 9. [Scheduled jobs](#scheduled-jobs)
32
+ 10. [CLI commands reference](#cli-commands-reference)
33
+ 11. [Mapping of Heroku Commands to `cpl` and `cpln`](#mapping-of-heroku-commands-to-cpl-and-cpln)
34
+ 12. [Examples](#examples)
35
+ 13. [Migrating Postgres database from Heroku infrastructure](/docs/postgres.md)
36
+ 14. [Migrating Redis database from Heroku infrastructure](/docs/redis.md)
36
37
 
37
38
  ## Key features
38
39
 
@@ -105,14 +106,28 @@ Do not confuse the `cpl` CLI with the `cpln` CLI. The `cpl` CLI is the Heroku to
105
106
  **Notes:**
106
107
 
107
108
  1. `myapp` is an app name defined in the `.controlplane/controlplane.yml` file, such as `ror-tutorial` in [this `controlplane.yml` file](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/controlplane.yml).
108
- 2. Other files in the `.controlplane/templates` directory are used by the `cpl setup` command.
109
+ 2. Other files in the `.controlplane/templates` directory are used by the `cpl setup-app` and `cpl apply-template` commands.
109
110
 
110
111
  ### Initial Setup and Deployment
111
112
 
113
+ Before the initial setup, add the templates for the app to `.controlplane/controlplane.yml`, using the `setup` key:
114
+
115
+ ```yaml
116
+ myapp:
117
+ setup:
118
+ - gvc
119
+ - postgres
120
+ - redis
121
+ - memcached
122
+ - rails
123
+ - sidekiq
124
+ ```
125
+
126
+ Note how the templates correspond to files in the `.controlplane/templates` directory.
127
+
112
128
  ```sh
113
129
  # Provision infrastructure (one-time-only for new apps) using templates.
114
- # Note how the arguments correspond to files in the `.controlplane/templates` directory.
115
- cpl setup gvc postgres redis memcached rails sidekiq -a myapp
130
+ cpl setup-app -a myapp
116
131
 
117
132
  # Build and push image with auto-tagging "myapp:1_456".
118
133
  cpl build-image -a myapp --commit 456
@@ -214,7 +229,7 @@ apps:
214
229
  <<: *common
215
230
  # Use a different organization for production.
216
231
  cpln_org: my-org-production
217
- # Allows running the command `cpl pipeline-promote my-app-staging` to promote the staging app to production.
232
+ # Allows running the command `cpl promote-app-from-upstream -a my-app-production` to promote the staging app to production.
218
233
  upstream: my-app-staging
219
234
  my-app-other:
220
235
  <<: *common
@@ -313,6 +328,38 @@ For production purposes or where restarts are not an option, you should use exte
313
328
  We provide default `redis` and `memcached` templates in this repo optimized for Control Plane and suitable
314
329
  for development purposes.
315
330
 
331
+ ## Scheduled jobs
332
+
333
+ Control Plane supports scheduled jobs via [cron workloads](https://docs.controlplane.com/reference/workload#cron).
334
+
335
+ Here's a partial example of a template for a cron workload, using the app image:
336
+
337
+ ```yaml
338
+ kind: workload
339
+ name: daily-task
340
+ spec:
341
+ type: cron
342
+ job:
343
+ # Run daily job at 2am
344
+ schedule: 0 2 * * *
345
+ # Never or OnFailure
346
+ restartPolicy: Never
347
+ containers:
348
+ - name: daily-task
349
+ args:
350
+ - bundle
351
+ - exec
352
+ - rails
353
+ - db:prepare
354
+ image: "/org/APP_ORG/image/APP_IMAGE"
355
+ ```
356
+
357
+ A complete example can be found at [templates/daily-task.yml](templates/daily-task.yml), optimized for Control Plane and suitable for development purposes.
358
+
359
+ You can create the cron workload by adding the template for it to the `.controlplane/templates` folder and running `cpl apply-template my-template -a my-app`, where `my-template` is the name of the template file (`my-template.yml`).
360
+
361
+ Then to view the logs of the cron workload, you can run `cpl logs -a my-app -w my-template`.
362
+
316
363
  ## CLI commands reference:
317
364
 
318
365
  Click [here](/docs/commands.md) to see the commands.
@@ -327,17 +374,17 @@ cpl --help
327
374
 
328
375
  **`[WIP]`**
329
376
 
330
- | Heroku Command | `cpl` or `cpln` |
331
- | -------------------------------------------------------------------------------------------------------------- | --------------- |
332
- | [heroku ps](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-ps-type-type) | `cpl ps` |
333
- | [heroku config](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-config) | ? |
334
- | [heroku maintenance](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-maintenance) | ? |
335
- | [heroku logs](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-logs) | `cpl logs` |
336
- | [heroku pg](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pg-database) | ? |
337
- | [heroku pipelines:promote](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pipelines-promote) | `cpl promote` |
338
- | [heroku psql](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-psql-database) | ? |
339
- | [heroku redis](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-redis-database) | ? |
340
- | [heroku releases](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-releases) | ? |
377
+ | Heroku Command | `cpl` or `cpln` |
378
+ | -------------------------------------------------------------------------------------------------------------- | ------------------------------- |
379
+ | [heroku ps](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-ps-type-type) | `cpl ps` |
380
+ | [heroku config](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-config) | ? |
381
+ | [heroku maintenance](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-maintenance) | `cpl maintenance` |
382
+ | [heroku logs](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-logs) | `cpl logs` |
383
+ | [heroku pg](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pg-database) | ? |
384
+ | [heroku pipelines:promote](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pipelines-promote) | `cpl promote-app-from-upstream` |
385
+ | [heroku psql](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-psql-database) | ? |
386
+ | [heroku redis](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-redis-database) | ? |
387
+ | [heroku releases](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-releases) | ? |
341
388
 
342
389
  ## Examples
343
390
 
data/Rakefile CHANGED
@@ -4,11 +4,11 @@ require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
5
  require "rubocop/rake_task"
6
6
 
7
- RSpec::Core::RakeTask.new(:spec)
7
+ RSpec::Core::RakeTask.new(:rspec)
8
8
 
9
9
  RuboCop::RakeTask.new
10
10
 
11
- task default: %i[spec rubocop]
11
+ task default: %i[rspec rubocop]
12
12
 
13
13
  desc "Updates commands.md file"
14
14
  task :command_docs do
data/cpl.gemspec CHANGED
@@ -26,6 +26,9 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "rubocop-rake", "~> 0.6.0"
27
27
  spec.add_development_dependency "rubocop-rspec", "~> 2.18.1"
28
28
  spec.add_development_dependency "simplecov", "~> 0.22.0"
29
+ spec.add_development_dependency "timecop", "~> 0.9.6"
30
+ spec.add_development_dependency "vcr", "~> 6.1.0"
31
+ spec.add_development_dependency "webmock", "~> 3.18.1"
29
32
 
30
33
  spec.files = `git ls-files -z`.split("\x0").reject do |file|
31
34
  file.match(%r{^(coverage|pkg|spec|tmp)/})
data/docs/commands.md CHANGED
@@ -39,7 +39,8 @@ cpl apply-template gvc postgres redis rails -a $APP_NAME
39
39
 
40
40
  - Builds and pushes the image to Control Plane
41
41
  - Automatically assigns image numbers, e.g., `app:1`, `app:2`, etc.
42
- - Uses `.controlplane/Dockerfile`
42
+ - Uses `.controlplane/Dockerfile` or a different Dockerfile specified through `dockerfile` in the `.controlplane/controlplane.yml` file
43
+ - If a commit is provided through `--commit` or `-c`, it will be set as the runtime env var `GIT_COMMIT`
43
44
 
44
45
  ```sh
45
46
  cpl build-image -a $APP_NAME
@@ -167,6 +168,51 @@ cpl logs -a $APP_NAME
167
168
  cpl logs -a $APP_NAME -w $WORKLOAD_NAME
168
169
  ```
169
170
 
171
+ ### `maintenance`
172
+
173
+ - Checks if maintenance mode is on or off for an app
174
+ - Outputs 'on' or 'off'
175
+ - Specify the one-off workload through `one_off_workload` in the `.controlplane/controlplane.yml` file
176
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
177
+ - Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
178
+
179
+ ```sh
180
+ cpl maintenance -a $APP_NAME
181
+ ```
182
+
183
+ ### `maintenance:off`
184
+
185
+ - Disables maintenance mode for an app
186
+ - Specify the one-off workload through `one_off_workload` in the `.controlplane/controlplane.yml` file
187
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
188
+ - Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
189
+
190
+ ```sh
191
+ cpl maintenance:off -a $APP_NAME
192
+ ```
193
+
194
+ ### `maintenance:on`
195
+
196
+ - Enables maintenance mode for an app
197
+ - Specify the one-off workload through `one_off_workload` in the `.controlplane/controlplane.yml` file
198
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
199
+ - Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
200
+
201
+ ```sh
202
+ cpl maintenance:on -a $APP_NAME
203
+ ```
204
+
205
+ ### `maintenance:set-page`
206
+
207
+ - Sets the page for maintenance mode
208
+ - Only works if the maintenance workload uses the `shakacode/maintenance-mode` image
209
+ - Will set the URL as an env var `PAGE_URL` on the maintenance workload
210
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
211
+
212
+ ```sh
213
+ cpl maintenance:set-page PAGE_URL -a $APP_NAME
214
+ ```
215
+
170
216
  ### `open`
171
217
 
172
218
  - Opens the app endpoint URL in the default browser
@@ -244,6 +290,7 @@ cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
244
290
  - Runs one-off **_interactive_** replicas (analog of `heroku run`)
245
291
  - Uses `Standard` workload type and `cpln exec` as the execution method, with CLI streaming
246
292
  - May not work correctly with tasks that last over 5 minutes (there's a Control Plane scaling bug at the moment)
293
+ - If `fix_terminal_size` is `true` in the `.controlplane/controlplane.yml` file, the remote terminal size will be fixed to match the local terminal size (may also be overriden through `--terminal-size`)
247
294
 
248
295
  > **IMPORTANT:** Useful for development where it's needed for interaction, and where network connection drops and
249
296
  > task crashing are tolerable. For production tasks, it's better to use `cpl run:detached`.
@@ -252,6 +299,12 @@ cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
252
299
  # Opens shell (bash by default).
253
300
  cpl run -a $APP_NAME
254
301
 
302
+ # Need to quote COMMAND if setting ENV value or passing args.
303
+ cpl run 'LOG_LEVEL=warn rails db:migrate' -a $APP_NAME
304
+
305
+ # COMMAND may also be passed at the end (in this case, no need to quote).
306
+ cpl run -a $APP_NAME -- rails db:migrate
307
+
255
308
  # Runs command, displays output, and exits shell.
256
309
  cpl run ls / -a $APP_NAME
257
310
  cpl run rails db:migrate:status -a $APP_NAME
@@ -263,14 +316,25 @@ cpl run rails c -a $APP_NAME
263
316
  cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
264
317
  cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
265
318
 
266
- # Uses a different workload
319
+ # Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
267
320
  cpl run bash -a $APP_NAME -w other-workload
268
321
 
269
322
  # Overrides remote CPLN_TOKEN env variable with local token.
270
- # Useful when need superuser rights in remote container
323
+ # Useful when superuser rights are needed in remote container.
271
324
  cpl run bash -a $APP_NAME --use-local-token
272
325
  ```
273
326
 
327
+ ### `run:cleanup`
328
+
329
+ - Deletes stale run workloads for an app
330
+ - Workloads are considered stale based on how many days since created
331
+ - `stale_run_workload_created_days` in the `.controlplane/controlplane.yml` file specifies the number of days after created that the workload is considered stale
332
+ - Will ask for explicit user confirmation of deletion
333
+
334
+ ```sh
335
+ cpl run:cleanup -a $APP_NAME
336
+ ```
337
+
274
338
  ### `run:detached`
275
339
 
276
340
  - Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)
@@ -282,9 +346,12 @@ cpl run bash -a $APP_NAME --use-local-token
282
346
  ```sh
283
347
  cpl run:detached rails db:prepare -a $APP_NAME
284
348
 
285
- # Need to quote COMMAND if setting ENV value or passing args to command to run
349
+ # Need to quote COMMAND if setting ENV value or passing args.
286
350
  cpl run:detached 'LOG_LEVEL=warn rails db:migrate' -a $APP_NAME
287
351
 
352
+ # COMMAND may also be passed at the end (in this case, no need to quote).
353
+ cpl run:detached -a $APP_NAME -- rails db:migrate
354
+
288
355
  # Uses some other image.
289
356
  cpl run:detached rails db:migrate -a $APP_NAME --image /some/full/image/path
290
357
 
@@ -295,7 +362,7 @@ cpl run:detached rails db:migrate -a $APP_NAME --image latest
295
362
  cpl run:detached rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
296
363
  cpl run:detached rails db:migrate -a $APP_NAME --image latest # Latest sequential image
297
364
 
298
- # Uses a different workload
365
+ # Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
299
366
  cpl run:detached rails db:migrate:status -a $APP_NAME -w other-workload
300
367
  ```
301
368
 
@@ -66,7 +66,7 @@ build-review-app:
66
66
  name: Provision review app if needed
67
67
  command: |
68
68
  if ! cpl exist -a ${APP_NAME}; then
69
- cpl setup gvc postgres redis memcached rails sidekiq -a ${APP_NAME}
69
+ cpl setup-app -a ${APP_NAME}
70
70
  echo "export NEW_APP=true" >> $BASH_ENV
71
71
  fi
72
72
  - run:
@@ -23,6 +23,9 @@ aliases:
23
23
  - postgres
24
24
  - memcached
25
25
 
26
+ # Configure the workload name used when maintenance mode is on (defaults to 'maintenance')
27
+ maintenance_workload: maintenance
28
+
26
29
  apps:
27
30
  my-app-staging:
28
31
  # Use the values from the common section above
data/lib/command/base.rb CHANGED
@@ -153,6 +153,29 @@ module Command
153
153
  }
154
154
  end
155
155
 
156
+ def self.terminal_size_option(required: false)
157
+ {
158
+ name: :terminal_size,
159
+ params: {
160
+ banner: "ROWS,COLS",
161
+ desc: "Override remote terminal size (e.g. `--terminal-size 10,20`)",
162
+ type: :string,
163
+ required: required
164
+ }
165
+ }
166
+ end
167
+
168
+ def self.wait_option(title = "", required: false)
169
+ {
170
+ name: :wait,
171
+ params: {
172
+ desc: "Waits for #{title}",
173
+ type: :boolean,
174
+ required: required
175
+ }
176
+ }
177
+ end
178
+
156
179
  def self.all_options
157
180
  methods.grep(/_option$/).map { |method| send(method.to_s) }
158
181
  end
@@ -185,7 +208,7 @@ module Command
185
208
 
186
209
  def ensure_workload_deleted(workload)
187
210
  progress.puts "- Ensure workload is deleted"
188
- cp.workload_delete(workload)
211
+ cp.delete_workload(workload)
189
212
  end
190
213
 
191
214
  def latest_image_from(items, app_name: config.app, name_only: true)
@@ -212,8 +235,9 @@ module Command
212
235
  def latest_image_next(app = config.app, org = config.org)
213
236
  @latest_image_next ||= {}
214
237
  @latest_image_next[app] ||= begin
215
- image = latest_image(app, org).split(":").first
216
- image += ":#{extract_image_number(latest_image) + 1}"
238
+ latest_image_name = latest_image(app, org)
239
+ image = latest_image_name.split(":").first
240
+ image += ":#{extract_image_number(latest_image_name) + 1}"
217
241
  image += "_#{config.options[:commit]}" if config.options[:commit]
218
242
  image
219
243
  end
@@ -229,29 +253,44 @@ module Command
229
253
  $stderr
230
254
  end
231
255
 
232
- def step(message, abort_on_error: true) # rubocop:disable Metrics/MethodLength
256
+ def step_error(error, abort_on_error: true)
257
+ message = error.message
258
+ if abort_on_error
259
+ progress.puts(" #{Shell.color('failed!', :red)}\n\n")
260
+ Shell.abort(message)
261
+ else
262
+ Shell.write_to_tmp_stderr(message)
263
+ end
264
+ end
265
+
266
+ def step_finish(success)
267
+ if success
268
+ progress.puts(" #{Shell.color('done!', :green)}")
269
+ else
270
+ progress.puts(" #{Shell.color('failed!', :red)}\n\n#{Shell.read_from_tmp_stderr}\n\n")
271
+ end
272
+ end
273
+
274
+ def step(message, abort_on_error: true, retry_on_failure: false) # rubocop:disable Metrics/MethodLength
233
275
  progress.print("#{message}...")
234
276
 
235
277
  Shell.use_tmp_stderr do
236
278
  success = false
237
279
 
238
280
  begin
239
- success = yield
240
- rescue RuntimeError => e
241
- message = e.message
242
- if abort_on_error
243
- progress.puts(" #{Shell.color('failed!', :red)}\n\n")
244
- Shell.abort(message)
281
+ if retry_on_failure
282
+ until (success = yield)
283
+ progress.print(".")
284
+ sleep 1
285
+ end
245
286
  else
246
- Shell.write_to_tmp_stderr(message)
287
+ success = yield
247
288
  end
289
+ rescue RuntimeError => e
290
+ step_error(e, abort_on_error: abort_on_error)
248
291
  end
249
292
 
250
- if success
251
- progress.puts(" #{Shell.color('done!', :green)}")
252
- else
253
- progress.puts(" #{Shell.color('failed!', :red)}\n\n#{Shell.read_from_tmp_stderr}\n\n")
254
- end
293
+ step_finish(success)
255
294
  end
256
295
  end
257
296
 
@@ -11,18 +11,30 @@ module Command
11
11
  LONG_DESCRIPTION = <<~DESC
12
12
  - Builds and pushes the image to Control Plane
13
13
  - Automatically assigns image numbers, e.g., `app:1`, `app:2`, etc.
14
- - Uses `.controlplane/Dockerfile`
14
+ - Uses `.controlplane/Dockerfile` or a different Dockerfile specified through `dockerfile` in the `.controlplane/controlplane.yml` file
15
+ - If a commit is provided through `--commit` or `-c`, it will be set as the runtime env var `GIT_COMMIT`
15
16
  DESC
16
17
 
17
- def call
18
+ def call # rubocop:disable Metrics/MethodLength
18
19
  ensure_docker_running!
19
20
 
20
21
  dockerfile = config.current[:dockerfile] || "Dockerfile"
21
22
  dockerfile = "#{config.app_cpln_dir}/#{dockerfile}"
22
23
 
24
+ raise "Can't find Dockerfile at '#{dockerfile}'." unless File.exist?(dockerfile)
25
+
23
26
  progress.puts("Building image from Dockerfile '#{dockerfile}'...\n\n")
24
27
 
25
- cp.image_build(latest_image_next, dockerfile: dockerfile)
28
+ image_name = latest_image_next
29
+ image_url = "#{config.org}.registry.cpln.io/#{image_name}"
30
+
31
+ commit = config.options[:commit]
32
+ build_args = []
33
+ build_args.push("GIT_COMMIT=#{commit}") if commit
34
+
35
+ cp.image_build(image_url, dockerfile: dockerfile, build_args: build_args)
36
+
37
+ progress.puts("\nPushed image to '/org/#{config.org}/image/#{image_name}'.")
26
38
  end
27
39
 
28
40
  private
@@ -29,7 +29,7 @@ module Command
29
29
  ensure_docker_running!
30
30
 
31
31
  @upstream = config[:upstream]
32
- @upstream_org = config.apps[@upstream.to_sym][:cpln_org] || config.apps[@upstream.to_sym][:org]
32
+ @upstream_org = config.apps[@upstream.to_sym][:cpln_org]
33
33
  ensure_upstream_org!
34
34
 
35
35
  create_upstream_profile
data/lib/command/info.rb CHANGED
@@ -90,7 +90,7 @@ module Command
90
90
  config.apps.each do |app_name, app_options|
91
91
  next if config.app && !app_matches?(config.app, app_name, app_options)
92
92
 
93
- org = app_options[:cpln_org] || app_options[:org]
93
+ org = app_options[:cpln_org]
94
94
  result.push(org) unless result.include?(org)
95
95
  end
96
96
  end
@@ -104,7 +104,7 @@ module Command
104
104
  config.apps.each do |app_name, app_options|
105
105
  next if config.app && !app_matches?(config.app, app_name, app_options)
106
106
 
107
- app_org = app_options[:cpln_org] || app_options[:org]
107
+ app_org = app_options[:cpln_org]
108
108
  result.push(app_name.to_s) if app_org == org
109
109
  end
110
110
 
@@ -173,7 +173,11 @@ module Command
173
173
  puts "\nSome apps/workloads are missing. Please create them with:"
174
174
 
175
175
  @missing_apps_workloads.each do |app, workloads|
176
- puts " - `cpl setup #{workloads.join(' ')} -a #{app}`"
176
+ if workloads.include?("gvc")
177
+ puts " - `cpl setup-app -a #{app}`"
178
+ else
179
+ puts " - `cpl apply-template #{workloads.join(' ')} -a #{app}`"
180
+ end
177
181
  end
178
182
  end
179
183
 
@@ -183,9 +187,9 @@ module Command
183
187
  puts "\nThere are no apps starting with some names. If you wish to create any, do so with " \
184
188
  "(replace 'whatever' with whatever suffix you want):"
185
189
 
186
- @missing_apps_starting_with.each do |app, workloads|
190
+ @missing_apps_starting_with.each do |app, _workloads|
187
191
  app_with_suffix = "#{app}#{app.end_with?('-') ? '' : '-'}whatever"
188
- puts " - `cpl setup #{workloads.join(' ')} -a #{app_with_suffix}`"
192
+ puts " - `cpl setup-app -a #{app_with_suffix}`"
189
193
  end
190
194
  end
191
195
 
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Command
4
+ class Maintenance < Base
5
+ NAME = "maintenance"
6
+ OPTIONS = [
7
+ app_option(required: true)
8
+ ].freeze
9
+ DESCRIPTION = "Checks if maintenance mode is on or off for an app"
10
+ LONG_DESCRIPTION = <<~DESC
11
+ - Checks if maintenance mode is on or off for an app
12
+ - Outputs 'on' or 'off'
13
+ - Specify the one-off workload through `one_off_workload` in the `.controlplane/controlplane.yml` file
14
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
15
+ - Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
16
+ DESC
17
+
18
+ def call # rubocop:disable Metrics/MethodLength
19
+ one_off_workload = config[:one_off_workload]
20
+ maintenance_workload = config.current[:maintenance_workload] || "maintenance"
21
+
22
+ domain_data = cp.find_domain_for([one_off_workload, maintenance_workload])
23
+ unless domain_data
24
+ raise "Can't find domain. " \
25
+ "Maintenance mode is only supported for domains that use path based routing mode " \
26
+ "and have a route configured for the prefix '/' on either port 80 or 443."
27
+ end
28
+
29
+ domain_workload = cp.get_domain_workload(domain_data)
30
+ if domain_workload == maintenance_workload
31
+ puts "on"
32
+ else
33
+ puts "off"
34
+ end
35
+ end
36
+ end
37
+ end