cpl 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cfd7383099c36f633d327424fcb36561e2b925120e63f1b814158a43bd55103f
4
- data.tar.gz: eafdf0607fe28d3c24f8132e3a116085020c94639d5b05a5accec4d4de651ca5
3
+ metadata.gz: 410e8bfdc923cabc36b900bb6cc3bb98e586cc2789579ec01cc33fe9c9c39fe1
4
+ data.tar.gz: a7428c35cff0dabcd1c68469561b82e2c3f24282b92dba9b1eeeb94c51d9d654
5
5
  SHA512:
6
- metadata.gz: b443d26a3fa91400dbb6d2e71b730a26bd1405df2f03e7f9446179323e2becb532ec69d81d93f22578fe8793dbabec9a2283efc16a107decdb5aaa9e4a615281
7
- data.tar.gz: 34ab7670bc372af9b8991678de9d99a9c60429b3caebeeeb2775046a9be3d4a7fb7335d9cbeb3a6c2ba06bb29ef40ab7c2cffbcd20737cfb62eb4048b07a8926
6
+ metadata.gz: 9c09fb9477e7dd638220e4ad711161a176daab7e82ed7224d584b6617989e3dd789ae5f66eb75e0086bdcd9690d680e2de668b5698ce322184ecdd23522835a3
7
+ data.tar.gz: 82f3a8aaf6b465850f9b577c5f7aed1b8b4313bf0224d52f058fc94e17f334a9cb9f51bb2638600c150184714fb254c2edeea1bb1f77b40a976fe20d0db11b54
@@ -0,0 +1,24 @@
1
+ name: Command Docs
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ jobs:
10
+ rspec:
11
+ runs-on: ubuntu-latest
12
+ name: Command Docs
13
+ steps:
14
+ - name: Checkout code
15
+ uses: actions/checkout@v3
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: "3.0"
20
+ bundler-cache: true
21
+ - name: Install dependencies
22
+ run: bundle install
23
+ - name: Check if command docs are up to date
24
+ run: bundle exec rake check_command_docs
@@ -8,15 +8,18 @@ on:
8
8
 
9
9
  jobs:
10
10
  rspec:
11
- runs-on: ubuntu-latest
12
- name: RSpec
13
- env:
14
- RAILS_ENV: test
15
11
  strategy:
16
12
  matrix:
13
+ os:
14
+ - ubuntu-latest
15
+ - macos-latest
17
16
  ruby:
18
17
  - "2.7"
19
18
  - "3.0"
19
+ runs-on: ${{ matrix.os }}
20
+ name: RSpec
21
+ env:
22
+ RAILS_ENV: test
20
23
  steps:
21
24
  - name: Checkout code
22
25
  uses: actions/checkout@v3
@@ -28,7 +31,7 @@ jobs:
28
31
  - name: Install dependencies
29
32
  run: bundle install
30
33
  - name: Run tests
31
- run: bundle exec rspec spec
34
+ run: bundle exec rspec
32
35
  - name: Upload coverage results
33
36
  uses: actions/upload-artifact@master
34
37
  if: always()
@@ -8,13 +8,16 @@ on:
8
8
 
9
9
  jobs:
10
10
  rubocop:
11
- runs-on: ubuntu-latest
12
- name: Rubocop
13
11
  strategy:
14
12
  matrix:
13
+ os:
14
+ - ubuntu-latest
15
+ - macos-latest
15
16
  ruby:
16
17
  - "2.7"
17
18
  - "3.0"
19
+ runs-on: ${{ matrix.os }}
20
+ name: Rubocop
18
21
  steps:
19
22
  - name: Checkout code
20
23
  uses: actions/checkout@v3
data/.overcommit.yml CHANGED
@@ -1,4 +1,7 @@
1
1
  PreCommit:
2
+ CommandDocs:
3
+ enabled: true
4
+ command: ["bundle", "exec", "rake", "check_command_docs"]
2
5
  RuboCop:
3
6
  enabled: true
4
7
  on_warn: fail
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 (1.0.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,10 +37,11 @@ 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)
38
- reline (0.3.3)
44
+ reline (0.3.4)
39
45
  io-console (~> 0.5)
40
46
  rexml (3.2.5)
41
47
  rspec (3.12.0)
@@ -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,13 +4,18 @@ 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
+
13
+ desc "Checks if commands.md file is up to date"
14
+ task :check_command_docs do
15
+ sh "./script/check_command_docs"
16
+ end
12
17
 
13
18
  desc "Updates commands.md file"
14
- task :command_docs do
15
- sh "./script/generate_commands_docs"
19
+ task :update_command_docs do
20
+ sh "./script/update_command_docs"
16
21
  end
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
@@ -164,28 +187,22 @@ module Command
164
187
  end
165
188
  end
166
189
 
167
- def wait_for(title)
168
- progress.print "- Waiting for #{title}"
169
- until yield
170
- progress.print(".")
171
- sleep(1)
172
- end
173
- progress.puts
174
- end
175
-
176
190
  def wait_for_workload(workload)
177
- wait_for("workload to start") { cp.fetch_workload(workload) }
191
+ step("Waiting for workload", retry_on_failure: true) do
192
+ cp.fetch_workload(workload)
193
+ end
178
194
  end
179
195
 
180
196
  def wait_for_replica(workload, location)
181
- wait_for("replica") do
197
+ step("Waiting for replica", retry_on_failure: true) do
182
198
  cp.workload_get_replicas_safely(workload, location: location)&.dig("items", 0)
183
199
  end
184
200
  end
185
201
 
186
202
  def ensure_workload_deleted(workload)
187
- progress.puts "- Ensure workload is deleted"
188
- cp.workload_delete(workload)
203
+ step("Deleting workload") do
204
+ cp.delete_workload(workload)
205
+ end
189
206
  end
190
207
 
191
208
  def latest_image_from(items, app_name: config.app, name_only: true)
@@ -212,8 +229,9 @@ module Command
212
229
  def latest_image_next(app = config.app, org = config.org)
213
230
  @latest_image_next ||= {}
214
231
  @latest_image_next[app] ||= begin
215
- image = latest_image(app, org).split(":").first
216
- image += ":#{extract_image_number(latest_image) + 1}"
232
+ latest_image_name = latest_image(app, org)
233
+ image = latest_image_name.split(":").first
234
+ image += ":#{extract_image_number(latest_image_name) + 1}"
217
235
  image += "_#{config.options[:commit]}" if config.options[:commit]
218
236
  image
219
237
  end
@@ -229,29 +247,44 @@ module Command
229
247
  $stderr
230
248
  end
231
249
 
232
- def step(message, abort_on_error: true) # rubocop:disable Metrics/MethodLength
250
+ def step_error(error, abort_on_error: true)
251
+ message = error.message
252
+ if abort_on_error
253
+ progress.puts(" #{Shell.color('failed!', :red)}\n\n")
254
+ Shell.abort(message)
255
+ else
256
+ Shell.write_to_tmp_stderr(message)
257
+ end
258
+ end
259
+
260
+ def step_finish(success)
261
+ if success
262
+ progress.puts(" #{Shell.color('done!', :green)}")
263
+ else
264
+ progress.puts(" #{Shell.color('failed!', :red)}\n\n#{Shell.read_from_tmp_stderr}\n\n")
265
+ end
266
+ end
267
+
268
+ def step(message, abort_on_error: true, retry_on_failure: false) # rubocop:disable Metrics/MethodLength
233
269
  progress.print("#{message}...")
234
270
 
235
271
  Shell.use_tmp_stderr do
236
272
  success = false
237
273
 
238
274
  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)
275
+ if retry_on_failure
276
+ until (success = yield)
277
+ progress.print(".")
278
+ sleep 1
279
+ end
245
280
  else
246
- Shell.write_to_tmp_stderr(message)
281
+ success = yield
247
282
  end
283
+ rescue RuntimeError => e
284
+ step_error(e, abort_on_error: abort_on_error)
248
285
  end
249
286
 
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
287
+ step_finish(success)
255
288
  end
256
289
  end
257
290
 
@@ -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