cpl 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/Gemfile.lock +17 -2
- data/README.md +67 -20
- data/Rakefile +2 -2
- data/cpl.gemspec +3 -0
- data/docs/commands.md +72 -5
- data/examples/circleci.yml +1 -1
- data/examples/controlplane.yml +3 -0
- data/lib/command/base.rb +55 -16
- data/lib/command/build_image.rb +15 -3
- data/lib/command/copy_image_from_upstream.rb +1 -1
- data/lib/command/info.rb +9 -5
- data/lib/command/maintenance.rb +37 -0
- data/lib/command/maintenance_off.rb +58 -0
- data/lib/command/maintenance_on.rb +58 -0
- data/lib/command/maintenance_set_page.rb +34 -0
- data/lib/command/no_command.rb +1 -1
- data/lib/command/promote_app_from_upstream.rb +2 -2
- data/lib/command/ps_start.rb +22 -5
- data/lib/command/ps_stop.rb +22 -5
- data/lib/command/run.rb +23 -5
- data/lib/command/run_cleanup.rb +99 -0
- data/lib/command/run_detached.rb +6 -3
- data/lib/command/setup_app.rb +3 -3
- data/lib/core/config.rb +39 -32
- data/lib/core/controlplane.rb +72 -16
- data/lib/core/controlplane_api.rb +39 -0
- data/lib/core/controlplane_api_direct.rb +13 -3
- data/lib/cpl/version.rb +1 -1
- data/templates/daily-task.yml +30 -0
- data/templates/maintenance.yml +24 -0
- metadata +51 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 976c390927b51f67afe7a161b7185242261afb4c24db893026457b205fe61b12
|
4
|
+
data.tar.gz: b55bec82c485eb413c9a8787d34172e2c7e89212c15e319f3f626c652c3ac6e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 678825b452c56d5c481639de70904ab087f29e362c4b8ced34d3c2131f15a176f78c0c928b02449ebc96a0e69bd1e5c2cd1982577e06a0b62000aa0993bd4f91
|
7
|
+
data.tar.gz: a40e2ea6bfb43122c919d9126d6fffdb6a9722396bed1c4b22b5874d06f9b2126ee4f14e6df37047bb417bcb0788b3b19869d03b34801030b6e8e373f47950c2
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cpl (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.
|
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. [
|
32
|
-
10. [
|
33
|
-
11. [
|
34
|
-
12. [
|
35
|
-
13. [Migrating
|
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`
|
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
|
-
|
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
|
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(:
|
7
|
+
RSpec::Core::RakeTask.new(:rspec)
|
8
8
|
|
9
9
|
RuboCop::RakeTask.new
|
10
10
|
|
11
|
-
task default: %i[
|
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
|
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
|
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
|
|
data/examples/circleci.yml
CHANGED
@@ -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
|
69
|
+
cpl setup-app -a ${APP_NAME}
|
70
70
|
echo "export NEW_APP=true" >> $BASH_ENV
|
71
71
|
fi
|
72
72
|
- run:
|
data/examples/controlplane.yml
CHANGED
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.
|
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
|
-
|
216
|
-
image
|
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
|
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
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
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
|
-
|
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
|
-
|
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
|
|
data/lib/command/build_image.rb
CHANGED
@@ -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
|
-
|
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]
|
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]
|
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]
|
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
|
-
|
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,
|
190
|
+
@missing_apps_starting_with.each do |app, _workloads|
|
187
191
|
app_with_suffix = "#{app}#{app.end_with?('-') ? '' : '-'}whatever"
|
188
|
-
puts " - `cpl setup
|
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
|