cpl 0.5.1 → 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 +4 -4
- data/.rubocop.yml +6 -0
- data/Gemfile.lock +19 -4
- data/README.md +67 -20
- data/Rakefile +2 -2
- data/cpl.gemspec +3 -0
- data/docs/commands.md +108 -21
- data/examples/circleci.yml +1 -1
- data/examples/controlplane.yml +3 -0
- data/lib/command/{setup.rb → apply_template.rb} +89 -15
- data/lib/command/base.rb +68 -18
- 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 +53 -14
- data/lib/command/run_cleanup.rb +99 -0
- data/lib/command/run_detached.rb +22 -14
- data/lib/command/setup_app.rb +29 -0
- data/lib/core/config.rb +39 -32
- data/lib/core/controlplane.rb +78 -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/lib/cpl.rb +6 -1
- data/lib/deprecated_commands.json +2 -1
- data/templates/daily-task.yml +30 -0
- data/templates/maintenance.yml +24 -0
- metadata +54 -4
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,17 +10,22 @@ 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
|
-
irb (1.6.
|
28
|
+
irb (1.6.4)
|
24
29
|
reline (>= 0.3.0)
|
25
30
|
json (2.6.3)
|
26
31
|
overcommit (0.60.0)
|
@@ -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)
|
@@ -77,9 +83,15 @@ GEM
|
|
77
83
|
simplecov_json_formatter (~> 0.1)
|
78
84
|
simplecov-html (0.12.3)
|
79
85
|
simplecov_json_formatter (0.1.4)
|
80
|
-
stringio (3.0.
|
81
|
-
thor (1.2.
|
86
|
+
stringio (3.0.6)
|
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
@@ -11,11 +11,36 @@ This `-a` option is used in most of the commands and will pick all other app con
|
|
11
11
|
|
12
12
|
### Commands
|
13
13
|
|
14
|
+
### `apply-template`
|
15
|
+
|
16
|
+
- Applies application-specific configs from templates (e.g., for every review-app)
|
17
|
+
- Publishes (creates or updates) those at Control Plane infrastructure
|
18
|
+
- Picks templates from the `.controlplane/templates` directory
|
19
|
+
- Templates are ordinary Control Plane templates but with variable preprocessing
|
20
|
+
|
21
|
+
**Preprocessed template variables:**
|
22
|
+
|
23
|
+
```
|
24
|
+
APP_GVC - basically GVC or app name
|
25
|
+
APP_LOCATION - default location
|
26
|
+
APP_ORG - organization
|
27
|
+
APP_IMAGE - will use latest app image
|
28
|
+
```
|
29
|
+
|
30
|
+
```sh
|
31
|
+
# Applies single template.
|
32
|
+
cpl apply-template redis -a $APP_NAME
|
33
|
+
|
34
|
+
# Applies several templates (practically creating full app).
|
35
|
+
cpl apply-template gvc postgres redis rails -a $APP_NAME
|
36
|
+
```
|
37
|
+
|
14
38
|
### `build-image`
|
15
39
|
|
16
40
|
- Builds and pushes the image to Control Plane
|
17
41
|
- Automatically assigns image numbers, e.g., `app:1`, `app:2`, etc.
|
18
|
-
- 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`
|
19
44
|
|
20
45
|
```sh
|
21
46
|
cpl build-image -a $APP_NAME
|
@@ -143,6 +168,51 @@ cpl logs -a $APP_NAME
|
|
143
168
|
cpl logs -a $APP_NAME -w $WORKLOAD_NAME
|
144
169
|
```
|
145
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
|
+
|
146
216
|
### `open`
|
147
217
|
|
148
218
|
- Opens the app endpoint URL in the default browser
|
@@ -220,6 +290,7 @@ cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
|
|
220
290
|
- Runs one-off **_interactive_** replicas (analog of `heroku run`)
|
221
291
|
- Uses `Standard` workload type and `cpln exec` as the execution method, with CLI streaming
|
222
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`)
|
223
294
|
|
224
295
|
> **IMPORTANT:** Useful for development where it's needed for interaction, and where network connection drops and
|
225
296
|
> task crashing are tolerable. For production tasks, it's better to use `cpl run:detached`.
|
@@ -228,6 +299,12 @@ cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
|
|
228
299
|
# Opens shell (bash by default).
|
229
300
|
cpl run -a $APP_NAME
|
230
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
|
+
|
231
308
|
# Runs command, displays output, and exits shell.
|
232
309
|
cpl run ls / -a $APP_NAME
|
233
310
|
cpl run rails db:migrate:status -a $APP_NAME
|
@@ -238,6 +315,24 @@ cpl run rails c -a $APP_NAME
|
|
238
315
|
# Uses a different image (which may not be promoted yet).
|
239
316
|
cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
|
240
317
|
cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
|
318
|
+
|
319
|
+
# Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
|
320
|
+
cpl run bash -a $APP_NAME -w other-workload
|
321
|
+
|
322
|
+
# Overrides remote CPLN_TOKEN env variable with local token.
|
323
|
+
# Useful when superuser rights are needed in remote container.
|
324
|
+
cpl run bash -a $APP_NAME --use-local-token
|
325
|
+
```
|
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
|
241
336
|
```
|
242
337
|
|
243
338
|
### `run:detached`
|
@@ -251,9 +346,12 @@ cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential i
|
|
251
346
|
```sh
|
252
347
|
cpl run:detached rails db:prepare -a $APP_NAME
|
253
348
|
|
254
|
-
# Need to quote COMMAND if setting ENV value or passing args
|
349
|
+
# Need to quote COMMAND if setting ENV value or passing args.
|
255
350
|
cpl run:detached 'LOG_LEVEL=warn rails db:migrate' -a $APP_NAME
|
256
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
|
+
|
257
355
|
# Uses some other image.
|
258
356
|
cpl run:detached rails db:migrate -a $APP_NAME --image /some/full/image/path
|
259
357
|
|
@@ -263,30 +361,19 @@ cpl run:detached rails db:migrate -a $APP_NAME --image latest
|
|
263
361
|
# Uses a different image (which may not be promoted yet).
|
264
362
|
cpl run:detached rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
|
265
363
|
cpl run:detached rails db:migrate -a $APP_NAME --image latest # Latest sequential image
|
364
|
+
|
365
|
+
# Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
|
366
|
+
cpl run:detached rails db:migrate:status -a $APP_NAME -w other-workload
|
266
367
|
```
|
267
368
|
|
268
|
-
### `setup`
|
369
|
+
### `setup-app`
|
269
370
|
|
270
|
-
-
|
271
|
-
-
|
272
|
-
-
|
273
|
-
- Templates are ordinary Control Plane templates but with variable preprocessing
|
274
|
-
|
275
|
-
**Preprocessed template variables:**
|
276
|
-
|
277
|
-
```
|
278
|
-
APP_GVC - basically GVC or app name
|
279
|
-
APP_LOCATION - default location
|
280
|
-
APP_ORG - organization
|
281
|
-
APP_IMAGE - will use latest app image
|
282
|
-
```
|
371
|
+
- Creates an app and all its workloads
|
372
|
+
- Specify the templates for the app and workloads through `setup` in the `.controlplane/controlplane.yml` file
|
373
|
+
- This should should only be used for temporary apps like review apps, never for persistent apps like production (to update workloads for those, use 'cpl apply-template' instead)
|
283
374
|
|
284
375
|
```sh
|
285
|
-
|
286
|
-
cpl setup redis -a $APP_NAME
|
287
|
-
|
288
|
-
# Applies several templates (practically creating full app).
|
289
|
-
cpl setup gvc postgres redis rails -a $APP_NAME
|
376
|
+
cpl setup-app -a $APP_NAME
|
290
377
|
```
|
291
378
|
|
292
379
|
### `version`
|
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
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Command
|
4
|
-
class
|
5
|
-
NAME = "
|
6
|
-
USAGE = "
|
4
|
+
class ApplyTemplate < Base # rubocop:disable Metrics/ClassLength
|
5
|
+
NAME = "apply-template"
|
6
|
+
USAGE = "apply-template TEMPLATE [TEMPLATE] ... [TEMPLATE]"
|
7
7
|
REQUIRES_ARGS = true
|
8
8
|
OPTIONS = [
|
9
|
-
app_option(required: true)
|
9
|
+
app_option(required: true),
|
10
|
+
skip_confirm_option
|
10
11
|
].freeze
|
11
12
|
DESCRIPTION = "Applies application-specific configs from templates"
|
12
13
|
LONG_DESCRIPTION = <<~DESC
|
@@ -27,28 +28,35 @@ module Command
|
|
27
28
|
EXAMPLES = <<~EX
|
28
29
|
```sh
|
29
30
|
# Applies single template.
|
30
|
-
cpl
|
31
|
+
cpl apply-template redis -a $APP_NAME
|
31
32
|
|
32
33
|
# Applies several templates (practically creating full app).
|
33
|
-
cpl
|
34
|
+
cpl apply-template gvc postgres redis rails -a $APP_NAME
|
34
35
|
```
|
35
36
|
EX
|
36
37
|
|
37
38
|
def call # rubocop:disable Metrics/MethodLength
|
39
|
+
ensure_templates!
|
40
|
+
|
38
41
|
@app_status = :existing
|
39
42
|
@created_workloads = []
|
40
43
|
@failed_workloads = []
|
44
|
+
@skipped_workloads = []
|
41
45
|
|
42
|
-
|
43
|
-
filename = "#{config.app_cpln_dir}/templates/#{template}.yml"
|
46
|
+
@asked_for_confirmation = false
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
pending_templates = templates.select do |template|
|
49
|
+
if template == "gvc"
|
50
|
+
confirm_app(template)
|
51
|
+
else
|
52
|
+
confirm_workload(template)
|
53
|
+
end
|
54
|
+
end
|
48
55
|
|
49
|
-
|
50
|
-
end
|
56
|
+
progress.puts if @asked_for_confirmation
|
51
57
|
|
58
|
+
pending_templates.each do |template, filename|
|
59
|
+
step("Applying template '#{template}'", abort_on_error: false) do
|
52
60
|
apply_template(filename)
|
53
61
|
if $CHILD_STATUS.success?
|
54
62
|
report_success(template)
|
@@ -63,10 +71,58 @@ module Command
|
|
63
71
|
print_app_status
|
64
72
|
print_created_workloads
|
65
73
|
print_failed_workloads
|
74
|
+
print_skipped_workloads
|
66
75
|
end
|
67
76
|
|
68
77
|
private
|
69
78
|
|
79
|
+
def templates
|
80
|
+
@templates ||= config.args.to_h do |template|
|
81
|
+
[template, "#{config.app_cpln_dir}/templates/#{template}.yml"]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def ensure_templates!
|
86
|
+
missing_templates = templates.filter { |_template, filename| !File.exist?(filename) }.to_h
|
87
|
+
return if missing_templates.empty?
|
88
|
+
|
89
|
+
missing_templates_str = missing_templates.map do |template, filename|
|
90
|
+
" - #{template} (#{filename})"
|
91
|
+
end.join("\n")
|
92
|
+
progress.puts("#{Shell.color('Missing templates:', :red)}\n#{missing_templates_str}\n\n")
|
93
|
+
|
94
|
+
raise "Can't find templates above, please create them."
|
95
|
+
end
|
96
|
+
|
97
|
+
def confirm_apply(message)
|
98
|
+
return true if config.options[:yes]
|
99
|
+
|
100
|
+
@asked_for_confirmation = true
|
101
|
+
Shell.confirm(message)
|
102
|
+
end
|
103
|
+
|
104
|
+
def confirm_app(template)
|
105
|
+
app = cp.fetch_gvc
|
106
|
+
return true unless app
|
107
|
+
|
108
|
+
confirmed = confirm_apply("App '#{config.app}' already exists, do you want to re-create it?")
|
109
|
+
return true if confirmed
|
110
|
+
|
111
|
+
report_skipped(template)
|
112
|
+
false
|
113
|
+
end
|
114
|
+
|
115
|
+
def confirm_workload(template)
|
116
|
+
workload = cp.fetch_workload(template)
|
117
|
+
return true unless workload
|
118
|
+
|
119
|
+
confirmed = confirm_apply("Workload '#{template}' already exists, do you want to re-create it?")
|
120
|
+
return true if confirmed
|
121
|
+
|
122
|
+
report_skipped(template)
|
123
|
+
false
|
124
|
+
end
|
125
|
+
|
70
126
|
def apply_template(filename)
|
71
127
|
data = File.read(filename)
|
72
128
|
.gsub("APP_GVC", config.app)
|
@@ -93,13 +149,24 @@ module Command
|
|
93
149
|
end
|
94
150
|
end
|
95
151
|
|
152
|
+
def report_skipped(template)
|
153
|
+
if template == "gvc"
|
154
|
+
@app_status = :skipped
|
155
|
+
else
|
156
|
+
@skipped_workloads.push(template)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
96
160
|
def print_app_status
|
97
161
|
return if @app_status == :existing
|
98
162
|
|
99
|
-
|
163
|
+
case @app_status
|
164
|
+
when :success
|
100
165
|
progress.puts("\n#{Shell.color("Created app '#{config.app}'.", :green)}")
|
101
|
-
|
166
|
+
when :failure
|
102
167
|
progress.puts("\n#{Shell.color("Failed to create app '#{config.app}'.", :red)}")
|
168
|
+
when :skipped
|
169
|
+
progress.puts("\n#{Shell.color("Skipped app '#{config.app}' (already exists).", :blue)}")
|
103
170
|
end
|
104
171
|
end
|
105
172
|
|
@@ -116,5 +183,12 @@ module Command
|
|
116
183
|
workloads = @failed_workloads.map { |template| " - #{template}" }.join("\n")
|
117
184
|
progress.puts("\n#{Shell.color('Failed to create workloads:', :red)}\n#{workloads}")
|
118
185
|
end
|
186
|
+
|
187
|
+
def print_skipped_workloads
|
188
|
+
return unless @skipped_workloads.any?
|
189
|
+
|
190
|
+
workloads = @skipped_workloads.map { |template| " - #{template}" }.join("\n")
|
191
|
+
progress.puts("\n#{Shell.color('Skipped workloads (already exist):', :blue)}\n#{workloads}")
|
192
|
+
end
|
119
193
|
end
|
120
194
|
end
|