cpl 0.5.1 → 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 +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
|