cpl 1.0.0 → 1.0.1

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: 410e8bfdc923cabc36b900bb6cc3bb98e586cc2789579ec01cc33fe9c9c39fe1
4
- data.tar.gz: a7428c35cff0dabcd1c68469561b82e2c3f24282b92dba9b1eeeb94c51d9d654
3
+ metadata.gz: da0cd8b4b3f57a141b2a148a35555069f4ff4135803e4ae95932cd3887e3a567
4
+ data.tar.gz: dab258fecce6a5948374057418959d736915ab69f84593e1b189c148f62f00be
5
5
  SHA512:
6
- metadata.gz: 9c09fb9477e7dd638220e4ad711161a176daab7e82ed7224d584b6617989e3dd789ae5f66eb75e0086bdcd9690d680e2de668b5698ce322184ecdd23522835a3
7
- data.tar.gz: 82f3a8aaf6b465850f9b577c5f7aed1b8b4313bf0224d52f058fc94e17f334a9cb9f51bb2638600c150184714fb254c2edeea1bb1f77b40a976fe20d0db11b54
6
+ metadata.gz: 31c5cfe13e647abf6f34f6b021c808c220db07a48cd223d0d277ad7814ab0942961a7b75c63d89c3c109e7ca670d478285e5289fdb9fe64ccd828917b7fccf22
7
+ data.tar.gz: 926431c8d7fb4c5f8ba7930a3a156d70718dcce6eb1c717e9859f5a8546900266e4267cee7c755ca4c99612fb1b574a7cbfdd6ca23a2fd5483c1eb3c743a83db
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  .DS_Store
3
3
 
4
4
  /.bundle/
5
+ /.vscode/
5
6
  /.yardoc
6
7
  /_yardoc/
7
8
  /coverage/
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cpl (1.0.0)
4
+ cpl (1.0.1)
5
5
  debug (~> 1.7.1)
6
6
  dotenv (~> 2.8.1)
7
7
  psych (~> 5.1.0)
@@ -25,7 +25,7 @@ GEM
25
25
  hashdiff (1.0.1)
26
26
  iniparse (1.5.0)
27
27
  io-console (0.6.0)
28
- irb (1.6.4)
28
+ irb (1.7.0)
29
29
  reline (>= 0.3.0)
30
30
  json (2.6.3)
31
31
  overcommit (0.60.0)
@@ -41,7 +41,7 @@ GEM
41
41
  rainbow (3.1.1)
42
42
  rake (13.0.6)
43
43
  regexp_parser (2.6.2)
44
- reline (0.3.4)
44
+ reline (0.3.5)
45
45
  io-console (~> 0.5)
46
46
  rexml (3.2.5)
47
47
  rspec (3.12.0)
@@ -83,7 +83,7 @@ GEM
83
83
  simplecov_json_formatter (~> 0.1)
84
84
  simplecov-html (0.12.3)
85
85
  simplecov_json_formatter (0.1.4)
86
- stringio (3.0.6)
86
+ stringio (3.0.7)
87
87
  thor (1.2.2)
88
88
  timecop (0.9.6)
89
89
  unicode-display_width (2.4.2)
data/README.md CHANGED
@@ -13,49 +13,57 @@ _A playbook for migrating from [Heroku](https://heroku.com) to [Control Plane](h
13
13
 
14
14
  [![Gem](https://badge.fury.io/rb/cpl.svg)](https://badge.fury.io/rb/cpl)
15
15
 
16
- This playbook shows how to move "Heroku apps" to "Control Plane workloads" via an open-source `cpl` CLI on top of Control Plane's `cpln` CLI.
16
+ This playbook shows how to move "Heroku apps" to "Control Plane workloads" via an open-source `cpl` CLI on top of
17
+ Control Plane's `cpln` CLI.
17
18
 
18
- Heroku provides a UX and CLI that enables easy publishing of Ruby on Rails and other apps. This ease of use comes via many "Heroku" abstractions and naming conventions.
19
- Control Plane, on the other hand, gives you access to raw cloud computing power. However, you need to know precisely how to use it.
19
+ Heroku provides a UX and CLI that enables easy publishing of Ruby on Rails and other apps. This ease of use comes via
20
+ many "Heroku" abstractions and naming conventions.
20
21
 
21
- To simplify migration to and usage of Control Plane for Heroku users, this repository provides a **concept mapping** and a **helper CLI** based on templates to save lots of day-to-day typing (and human errors).
22
+ Control Plane, on the other hand, gives you access to raw cloud computing power. However, you need to know precisely how
23
+ to use it.
22
24
 
23
- 1. [Key features](#key-features)
24
- 2. [Concept mapping](#concept-mapping)
25
+ To simplify migration to and usage of Control Plane for Heroku users, this repository provides a **concept mapping** and
26
+ a **helper CLI** based on templates to save lots of day-to-day typing (and human errors).
27
+
28
+ 1. [Key Features](#key-features)
29
+ 2. [Concept Mapping](#concept-mapping)
25
30
  3. [Installation](#installation)
26
- 4. [Example CLI flow for application build/deployment](#example-cli-flow-for-application-builddeployment)
27
- 5. [Example project modifications for Control Plane](#example-project-modifications-for-control-plane)
31
+ 4. [Example CLI Flow for Application Build/Deployment](#example-cli-flow-for-application-builddeployment)
32
+ - [Initial Setup and Deployment](#initial-setup-and-deployment)
33
+ - [Promoting Code Upgrades](#promoting-code-upgrades)
34
+ 5. [Example Project Modifications for Control Plane](#example-project-modifications-for-control-plane)
28
35
  6. [Environment](#environment)
29
36
  7. [Database](#database)
30
- 8. [In-memory databases](#in-memory-databases)
31
- 9. [Scheduled jobs](#scheduled-jobs)
32
- 10. [CLI commands reference](#cli-commands-reference)
37
+ 8. [In-memory Databases](#in-memory-databases)
38
+ 9. [Scheduled Jobs](#scheduled-jobs)
39
+ 10. [CLI Commands Reference](#cli-commands-reference)
33
40
  11. [Mapping of Heroku Commands to `cpl` and `cpln`](#mapping-of-heroku-commands-to-cpl-and-cpln)
34
41
  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)
42
+ 13. [Migrating Postgres Database from Heroku Infrastructure](/docs/postgres.md)
43
+ 14. [Migrating Redis Database from Heroku Infrastructure](/docs/redis.md)
44
+ 15. [Tips](/docs/tips.md)
37
45
 
38
- ## Key features
46
+ ## Key Features
39
47
 
40
- - A `cpl` command to complement the default Control Plane `cpln` command with "Heroku style scripting." The Ruby source can serve as inspiration for your own scripts.
48
+ - A `cpl` command to complement the default Control Plane `cpln` command with "Heroku style scripting." The Ruby source
49
+ can serve as inspiration for your own scripts.
41
50
  - Easy to understand Heroku to Control Plane conventions in setup and naming.
42
51
  - **Safe, production-ready** equivalents of `heroku run` and `heroku run:detached` for Control Plane.
43
52
  - Automatic sequential release tagging for Docker images.
44
- - A project-aware CLI which enables working on multiple projects.
53
+ - A project-aware CLI that enables working on multiple projects.
45
54
 
46
- ## Concept mapping
55
+ ## Concept Mapping
47
56
 
48
57
  On Heroku, everything runs as an app, which means an entity that:
49
58
 
50
- 1. Runs code from a Git repo
51
- 2. Runs several process types, as defined in the `Procfile`
52
- 3. Has dynos, which are Linux containers that run these process types
53
- 4. Has add-ons, including the database and other services
54
- 5. Has common environment variables
55
-
56
- On Control Plane, we can map a Heroku app to a GVC (Global Virtual Cloud). Such a cloud consists of workloads, which can be anything that can run as a container.
59
+ - runs code from a Git repository.
60
+ - runs several process types, as defined in the `Procfile`.
61
+ - has dynos, which are Linux containers that run these process types.
62
+ - has add-ons, including the database and other services.
63
+ - has common environment variables.
57
64
 
58
- **Mapping of Concepts:**
65
+ On Control Plane, we can map a Heroku app to a GVC (Global Virtual Cloud). Such a cloud consists of workloads, which can
66
+ be anything that can run as a container.
59
67
 
60
68
  | Heroku | Control Plane |
61
69
  | ---------------- | ------------------------------------------- |
@@ -66,54 +74,61 @@ On Control Plane, we can map a Heroku app to a GVC (Global Virtual Cloud). Such
66
74
  | _staging env_ | _GVC (app)_ in staging _organization_ |
67
75
  | _production env_ | _GVC (app)_ in production _organization_ |
68
76
 
69
- On Heroku, dyno types are specified in the `Procfile` and configured via the CLI/UI; add-ons are configured only via the CLI/UI.
77
+ On Heroku, dyno types are specified in the `Procfile` and configured via the CLI/UI; add-ons are configured only via the
78
+ CLI/UI.
79
+
70
80
  On Control Plane, workloads are created either by _templates_ (preferred way) or via the CLI/UI.
71
81
 
72
82
  For the typical Rails app, this means:
73
83
 
74
- | Function | Examples | On Heroku | On Control Plane |
75
- | ----------------- | -------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------- |
76
- | web traffic | `rails`, `sinatra` | `web` dyno | workload with app image |
77
- | background jobs | `sidekiq`, `resque` | `worker` dyno | workload with app image |
78
- | db | `postgres`, `mysql` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
79
- | in-memory db | `redis`, `memcached` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
80
- | special something | `mailtrap` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
84
+ | Function | Examples | On Heroku | On Control Plane |
85
+ | --------------- | -------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------- |
86
+ | web traffic | `rails`, `sinatra` | `web` dyno | workload with app image |
87
+ | background jobs | `sidekiq`, `resque` | `worker` dyno | workload with app image |
88
+ | db | `postgres`, `mysql` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
89
+ | in-memory db | `redis`, `memcached` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
90
+ | others | `mailtrap` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
81
91
 
82
92
  ## Installation
83
93
 
84
- **Note:** `cpl` CLI is configured either as a Ruby gem, [`cpl`](https://rubygems.org/gems/cpl) install or a local clone. For information on the latter, see [CONTRIBUTING.md](CONTRIBUTING.md).
85
-
86
- 1. Install `node` (required for Control Plane CLI).
87
- 2. Install `ruby` (required for these helpers).
88
- 3. Install Control Plane CLI (adds `cpln` command) and configure credentials by running command `cpln login`.
94
+ 1. Install [Node.js](https://nodejs.org/en) (required for Control Plane CLI).
95
+ 2. Install [Ruby](https://www.ruby-lang.org/en/) (required for these helpers).
96
+ 3. Install Control Plane CLI (adds `cpln` command) and configure credentials.
89
97
 
90
98
  ```sh
91
99
  npm install -g @controlplane/cli
92
100
  cpln login
93
101
  ```
94
102
 
95
- ## Tips
103
+ 4. Install Heroku to Control Plane `cpl` CLI, either as a [Ruby gem](https://rubygems.org/gems/cpl) or a local clone.
104
+ For information on the latter, see [CONTRIBUTING.md](CONTRIBUTING.md).
96
105
 
97
- Do not confuse the `cpl` CLI with the `cpln` CLI. The `cpl` CLI is the Heroku to Control Plane playbook CLI. The `cpln` CLI is the Control Plane CLI.
98
-
99
- - For each Git project that you want to deploy to Control Plane, copy project-specific configs to a `.controlplane` directory at the top of your project. `cpl` will pick those up depending on which project
100
- folder tree it runs. Thus, this automates running several projects with different configs without explicitly switching configs.
106
+ ```sh
107
+ gem install cpl
108
+ ```
101
109
 
102
- 5. Create a `Dockerfile` for your production deployment. See [this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/Dockerfile).
110
+ **Note:** Do not confuse the `cpl` CLI with the `cpln` CLI. The `cpl` CLI is the Heroku to Control Plane playbook CLI.
111
+ The `cpln` CLI is the Control Plane CLI.
103
112
 
104
- ## Example CLI flow for application build/deployment
113
+ ## Example CLI Flow for Application Build/Deployment
105
114
 
106
115
  **Notes:**
107
116
 
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).
109
- 2. Other files in the `.controlplane/templates` directory are used by the `cpl setup-app` and `cpl apply-template` commands.
117
+ - `my-app` is an app name defined in the `.controlplane/controlplane.yml` file, such as `ror-tutorial` in
118
+ [this `controlplane.yml` file](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/controlplane.yml).
119
+ - Other files in the `.controlplane/templates/` directory are used by the `cpl setup-app` and `cpl apply-template`
120
+ commands.
110
121
 
111
122
  ### Initial Setup and Deployment
112
123
 
113
- Before the initial setup, add the templates for the app to `.controlplane/controlplane.yml`, using the `setup` key:
124
+ For each Git project that you want to deploy to Control Plane, copy project-specific configs to a `.controlplane/`
125
+ directory at the top of your project. `cpl` will pick those up depending on which project folder tree it runs. Thus,
126
+ this automates running several projects with different configs without explicitly switching configs.
127
+
128
+ Before the initial setup, add the templates for the app to `.controlplane/controlplane.yml`, using the `setup` key, e.g.:
114
129
 
115
130
  ```yaml
116
- myapp:
131
+ my-app:
117
132
  setup:
118
133
  - gvc
119
134
  - postgres
@@ -123,59 +138,61 @@ myapp:
123
138
  - sidekiq
124
139
  ```
125
140
 
126
- Note how the templates correspond to files in the `.controlplane/templates` directory.
141
+ Note how the templates correspond to files in the `.controlplane/templates/` directory.
142
+
143
+ Then create a `Dockerfile` for your deployment. See
144
+ [this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/Dockerfile).
127
145
 
128
146
  ```sh
129
147
  # Provision infrastructure (one-time-only for new apps) using templates.
130
- cpl setup-app -a myapp
148
+ cpl setup-app -a my-app
131
149
 
132
- # Build and push image with auto-tagging "myapp:1_456".
133
- cpl build-image -a myapp --commit 456
150
+ # Build and push image with auto-tagging, e.g., "my-app:1_456".
151
+ cpl build-image -a my-app --commit 456
134
152
 
135
153
  # Prepare database.
136
- cpl run:detached rails db:prepare -a myapp --image latest
154
+ cpl run:detached -a my-app --image latest -- rails db:prepare
137
155
 
138
156
  # Deploy latest image.
139
- cpl deploy-image -a myapp
157
+ cpl deploy-image -a my-app
140
158
 
141
159
  # Open app in browser.
142
- cpl open -a myapp
160
+ cpl open -a my-app
143
161
  ```
144
162
 
145
- ### Promoting code upgrades
163
+ ### Promoting Code Upgrades
146
164
 
147
165
  ```sh
148
- # Build and push new image with sequential image tagging, e.g. 'ror-tutorial_123'
149
- cpl build-image -a ror-tutorial
166
+ # Build and push new image with sequential tagging, e.g., "my-app:2".
167
+ cpl build-image -a my-app
150
168
 
151
- # OR
152
- # Build and push with sequential image tagging and commit SHA, e.g. 'ror-tutorial_123_ABCD'
153
- cpl build-image -a ror-tutorial --commit ABCD
169
+ # Or build and push new image with sequential tagging and commit SHA, e.g., "my-app:2_ABC".
170
+ cpl build-image -a my-app --commit ABC
154
171
 
155
- # Run database migrations (or other release tasks) with latest image,
156
- # while app is still running on previous image.
172
+ # Run database migrations (or other release tasks) with latest image, while app is still running on previous image.
157
173
  # This is analogous to the release phase.
158
- cpl run:detached rails db:migrate -a ror-tutorial --image latest
174
+ cpl run:detached -a my-app --image latest -- rails db:migrate
159
175
 
160
- # Deploy latest image to app
161
- cpl deploy-image -a ror-tutorial
176
+ # Deploy latest image.
177
+ cpl deploy-image -a my-app
162
178
  ```
163
179
 
164
- ## Example project modifications for Control Plane
180
+ ## Example Project Modifications for Control Plane
165
181
 
166
182
  _See this for a complete example._
167
183
 
168
- To learn how to migrate an app, we recommend that you first follow along with [this example project](https://github.com/shakacode/react-webpack-rails-tutorial).
184
+ To learn how to migrate an app, we recommend following along with
185
+ [this example project](https://github.com/shakacode/react-webpack-rails-tutorial).
169
186
 
170
- 1. Create the `.controlplane` directory at the top of your project and copy files from the `templates` directory of this repo to
171
- something as follows:
187
+ 1. Create the `.controlplane/` directory at the top of your project and copy files from the `templates/` directory of
188
+ this repository to something as follows:
172
189
 
173
190
  ```sh
174
191
  app_main_folder/
175
192
  .controlplane/
176
193
  Dockerfile # Your app's Dockerfile, with some Control Plane changes.
177
194
  controlplane.yml
178
- entrypoint.sh # App-specific, edit as needed.
195
+ entrypoint.sh # App-specific - edit as needed.
179
196
  templates/
180
197
  gvc.yml
181
198
  memcached.yml
@@ -185,9 +202,12 @@ app_main_folder/
185
202
  sidekiq.yml
186
203
  ```
187
204
 
188
- The example [`.controlplane` directory](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane) already contains these files.
205
+ The example
206
+ [`.controlplane/` directory](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane)
207
+ already contains these files.
189
208
 
190
- 2. Edit your `controlplane.yml` file as needed. For example, see [this `controlplane.yml` file](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/controlplane.yml).
209
+ 2. Edit your `controlplane.yml` file as needed. For example, see
210
+ [this `controlplane.yml` file](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/controlplane.yml).
191
211
 
192
212
  ```yaml
193
213
  # Keys beginning with "cpln_" correspond to your settings in Control Plane.
@@ -195,11 +215,10 @@ The example [`.controlplane` directory](https://github.com/shakacode/react-webpa
195
215
  aliases:
196
216
  common: &common
197
217
  # Organization name for staging (customize to your needs).
198
- # Production apps will use a different Control Plane organization, specified below, for security.
218
+ # Production apps will use a different organization, specified below, for security.
199
219
  cpln_org: my-org-staging
200
220
 
201
221
  # Example apps use only one location. Control Plane offers the ability to use multiple locations.
202
- # TODO -- allow specification of multiple locations
203
222
  default_location: aws-us-east-2
204
223
 
205
224
  # Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
@@ -216,52 +235,58 @@ aliases:
216
235
  - postgres
217
236
  - memcached
218
237
 
238
+ # Configure the workload name used when maintenance mode is on (defaults to "maintenance")
239
+ maintenance_workload: maintenance
240
+
219
241
  apps:
220
242
  my-app-staging:
221
243
  # Use the values from the common section above.
222
244
  <<: *common
223
245
  my-app-review:
224
246
  <<: *common
225
- # If `match_if_app_name_starts_with` == `true`, then use this config for app names starting with this name,
247
+ # If `match_if_app_name_starts_with` is `true`, then use this config for app names starting with this name,
226
248
  # e.g., "my-app-review-pr123", "my-app-review-anything-goes", etc.
227
249
  match_if_app_name_starts_with: true
228
250
  my-app-production:
229
251
  <<: *common
230
252
  # Use a different organization for production.
231
253
  cpln_org: my-org-production
232
- # Allows running the command `cpl promote-app-from-upstream -a my-app-production` to promote the staging app to production.
254
+ # Allows running the command `cpl promote-app-from-upstream -a my-app-production`
255
+ # to promote the staging app to production.
233
256
  upstream: my-app-staging
234
257
  my-app-other:
235
258
  <<: *common
236
- # You can specify a different `Dockerfile` relative to the `.controlplane` directory (default is just "Dockerfile").
259
+ # You can specify a different `Dockerfile` relative to the `.controlplane/` directory (defaults to "Dockerfile").
237
260
  dockerfile: ../some_other/Dockerfile
238
261
  ```
239
262
 
240
- 3. We recommend that you try out the commands listed in [the example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/readme.md). These steps will guide you through:
241
- 1. Provision the GVC and workloads
242
- 2. Build the Docker image
243
- 3. Run Rails migrations, like in the Heroku release phase
244
- 4. Promote the lastest Docker image
263
+ 3. We recommend that you try out the commands listed in
264
+ [the example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/readme.md).
265
+ These steps will guide you to the following:
266
+
267
+ 1. Provision the GVC and workloads.
268
+ 2. Build the Docker image.
269
+ 3. Run Rails migrations, like in the Heroku release phase.
270
+ 4. Promote the latest Docker image.
245
271
 
246
272
  ## Environment
247
273
 
248
274
  There are two main places where we can set up environment variables in Control Plane:
249
275
 
250
- - **In `workload/container/env`** - those are container-specific and need to be set up individually for each container.
276
+ - **In `workload/container/env`** - those are container-specific and must be set up individually for each container.
251
277
 
252
- - **In `gvc/env`** - this is a "common" place to keep env vars which we can share among different workloads.
253
- Those common variables are not visible by default, and we should explicitly enable them via the `inheritEnv` property.
278
+ - **In `gvc/env`** - this is a "common" place to keep env vars which we can share among different workloads. Those
279
+ common variables are not visible by default, and we should explicitly enable them via the `inheritEnv` property.
254
280
 
255
- In general, `gvc/env` vars are useful for "app" types of workloads, e.g., `rails`, `sidekiq`, as they can easily share
256
- common configs (the same way as on a Heroku app). They are not needed for non-app workloads,
257
- e.g., `redis`, `memcached`.
281
+ Generally, `gvc/env` vars are useful for "app" types of workloads, e.g., `rails`, `sidekiq`, as they can easily share
282
+ common configs (the same way as on a Heroku app). They are not needed for non-app workloads, e.g., `redis`, `memcached`.
258
283
 
259
284
  It is ok to keep most of the environment variables for non-production environments in the app templates as, in general,
260
285
  they are not secret and can be committed to the repository.
261
286
 
262
- It is also possible to set up a Secret store (of type Dictionary), which we can reference as,
263
- e.g., `cpln://secret/MY_SECRET_STORE_NAME/MY_SECRET_VAR_NAME`.
264
- In such a case, we also need to set up an app Identity and proper Policy to access the secret.
287
+ It is also possible to set up a Secret store (of type `Dictionary`), which we can reference as, e.g.,
288
+ `cpln://secret/MY_SECRET_STORE_NAME/MY_SECRET_VAR_NAME`. In such a case, we must set up an app Identity and proper
289
+ Policy to access the secret.
265
290
 
266
291
  ```yaml
267
292
  # In `templates/gvc.yml`:
@@ -281,31 +306,32 @@ spec:
281
306
  value: 'value'
282
307
  - name: MY_SECRET_LOCAL_VAR
283
308
  value: 'cpln://secret/MY_SECRET_STORE_NAME/MY_SECRET_LOCAL_VAR'
284
- inheritEnv: true # To enable global env inheritance
309
+ inheritEnv: true # To enable global env inheritance.
285
310
  ```
286
311
 
287
312
  ## Database
288
313
 
289
314
  There are several options for a database setup on Control Plane:
290
315
 
291
- 1. **Heroku Postgres**. It is the least recommended but simplest. We only need to provision the Postgres add-on on Heroku and
292
- copy its `XXXXXX_URL` connection string. This is good for quick testing, but unsuitable for the long term.
316
+ - **Heroku Postgres**. It is the least recommended but simplest. We only need to provision the Postgres add-on on Heroku
317
+ and copy its `XXXXXX_URL` connection string. This is good for quick testing but unsuitable for the long term.
293
318
 
294
- 2. **Control Plane container**. We can set it up as a workload using one of the default [Docker Hub](https://hub.docker.com/) images.
295
- However, such a setup lacks persistence between container restarts.
296
- We can use this only for an example or test app
297
- where the database doesn't keep any serious data and where such data is restorable.
319
+ - **Control Plane container**. We can set it up as a workload using one of the default
320
+ [Docker Hub](https://hub.docker.com/) images. However, such a setup lacks persistence between container restarts. We
321
+ can use this only for an example or test app where the database doesn't keep any serious data and where such data is
322
+ restorable.
298
323
 
299
- 3. Any other cloud provider for Postgres, e.g., Amazon's RDS can be a quick go-to. Here are [instructions for setting up a free tier of RDS.](https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-rds-launch/).
324
+ - Any other cloud provider for Postgres, e.g., Amazon's RDS can be a quick go-to. Here are
325
+ [instructions for setting up a free tier of RDS](https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-rds-launch/).
300
326
 
301
327
  **Tip:** If you are using RDS for development/testing purposes, you might consider running such a database publicly
302
- accessible (Heroku actually does that for all of its Postgres databases unless they are within private spaces). Then we can connect to
303
- such a database from everywhere with only the correct username/password.
328
+ accessible (Heroku actually does that for all of its Postgres databases unless they are within private spaces). Then we
329
+ can connect to such a database from everywhere with only the correct username/password.
304
330
 
305
- By default, we have structured our templates to accomplish this with only a single free tier or low tier AWS RDS instance
306
- that can serve all your development/testing needs for small/medium applications, e.g., as follows:
331
+ By default, we have structured our templates to accomplish this with only a single free tier or low tier AWS RDS
332
+ instance that can serve all your development/testing needs for small/medium applications, e.g., as follows:
307
333
 
308
- ```
334
+ ```sh
309
335
  aws-rds-single-pg-instance
310
336
  mydb-staging
311
337
  mydb-review-111
@@ -313,22 +339,22 @@ aws-rds-single-pg-instance
313
339
  mydb-review-333
314
340
  ```
315
341
 
316
- Additionally, we provide a default `postgres` template in this repo optimized for Control Plane and suitable
317
- for development purposes.
342
+ Additionally, we provide a default `postgres` template in this repository optimized for Control Plane and suitable for
343
+ development purposes.
318
344
 
319
- ## In-memory databases
345
+ ## In-memory Databases
320
346
 
321
- E.g. Redis, Memcached.
347
+ E.g., Redis, Memcached.
322
348
 
323
- For development purposes, it's useful to set those up as Control Plane workloads, as in most cases they don't keep any
324
- valuable data and can be safely restarted (sometimes), which doesn't affect application performance.
349
+ For development purposes, it's useful to set those up as Control Plane workloads, as in most cases, they don't keep any
350
+ valuable data and can be safely restarted, which doesn't affect application performance.
325
351
 
326
352
  For production purposes or where restarts are not an option, you should use external cloud services.
327
353
 
328
- We provide default `redis` and `memcached` templates in this repo optimized for Control Plane and suitable
329
- for development purposes.
354
+ We provide default `redis` and `memcached` templates in this repository optimized for Control Plane and suitable for
355
+ development purposes.
330
356
 
331
- ## Scheduled jobs
357
+ ## Scheduled Jobs
332
358
 
333
359
  Control Plane supports scheduled jobs via [cron workloads](https://docs.controlplane.com/reference/workload#cron).
334
360
 
@@ -340,9 +366,9 @@ name: daily-task
340
366
  spec:
341
367
  type: cron
342
368
  job:
343
- # Run daily job at 2am
369
+ # Run daily job at 2am.
344
370
  schedule: 0 2 * * *
345
- # Never or OnFailure
371
+ # "Never" or "OnFailure"
346
372
  restartPolicy: Never
347
373
  containers:
348
374
  - name: daily-task
@@ -354,17 +380,19 @@ spec:
354
380
  image: "/org/APP_ORG/image/APP_IMAGE"
355
381
  ```
356
382
 
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.
383
+ A complete example can be found at [templates/daily-task.yml](templates/daily-task.yml), optimized for Control Plane and
384
+ suitable for development purposes.
358
385
 
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`).
386
+ You can create the cron workload by adding the template for it to the `.controlplane/templates/` directory and running
387
+ `cpl apply-template my-template -a my-app`, where `my-template` is the name of the template file (e.g., `my-template.yml`).
360
388
 
361
389
  Then to view the logs of the cron workload, you can run `cpl logs -a my-app -w my-template`.
362
390
 
363
- ## CLI commands reference:
391
+ ## CLI Commands Reference
364
392
 
365
393
  Click [here](/docs/commands.md) to see the commands.
366
394
 
367
- You can also run:
395
+ You can also run the following command:
368
396
 
369
397
  ```sh
370
398
  cpl --help
@@ -372,8 +400,6 @@ cpl --help
372
400
 
373
401
  ## Mapping of Heroku Commands to `cpl` and `cpln`
374
402
 
375
- **`[WIP]`**
376
-
377
403
  | Heroku Command | `cpl` or `cpln` |
378
404
  | -------------------------------------------------------------------------------------------------------------- | ------------------------------- |
379
405
  | [heroku ps](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-ps-type-type) | `cpl ps` |
@@ -388,5 +414,6 @@ cpl --help
388
414
 
389
415
  ## Examples
390
416
 
391
- 1. See `examples/` and `templates/` folders of this repo.
392
- 2. See `.controlplane` directory of this live example: [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane)
417
+ - See the `examples/` and `templates/` directories of this repository.
418
+ - See the `.controlplane/` directory of this live example:
419
+ [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane)
Binary file
Binary file
data/docs/commands.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <!-- NOTE: This file is automatically generated by running `script/generate_commands_docs`. Do NOT edit it manually. -->
2
2
 
3
- ### Common Options
3
+ ## Common Options
4
4
 
5
5
  ```
6
6
  -a XXX, --app XXX app ref on Control Plane (GVC)
@@ -9,7 +9,7 @@
9
9
  This `-a` option is used in most of the commands and will pick all other app configurations from the project-specific
10
10
  `.controlplane/controlplane.yml` file.
11
11
 
12
- ### Commands
12
+ ## Commands
13
13
 
14
14
  ### `apply-template`
15
15
 
data/docs/tips.md ADDED
@@ -0,0 +1,177 @@
1
+ # Tips
2
+
3
+ 1. [GVCs vs. Orgs](#gvcs-vs-orgs)
4
+ 2. [RAM](#ram)
5
+ 3. [Remote IP](#remote-ip)
6
+ 4. [ENV Values](#env-values)
7
+ 5. [CI](#ci)
8
+ 6. [Memcached](#memcached)
9
+ 7. [Sidekiq](#sidekiq)
10
+ - [Quieting Non-Critical Workers During Deployments](#quieting-non-critical-workers-during-deployments)
11
+ - [Setting Up a Pre Stop Hook](#setting-up-a-pre-stop-hook)
12
+ - [Setting Up a Liveness Probe](#setting-up-a-liveness-probe)
13
+ 8. [Useful Links](#useful-links)
14
+
15
+ ## GVCs vs. Orgs
16
+
17
+ - A "GVC" roughly corresponds to a Heroku "app."
18
+ - Images are available at the org level.
19
+ - Multiple GVCs within an org can use the same image.
20
+ - You can have different images within a GVC and even within a workload. This flexibility is one of the key differences
21
+ compared to Heroku apps.
22
+
23
+ ## RAM
24
+
25
+ Any workload replica that reaches the max memory is terminated and restarted. You can configure alerts for workload
26
+ restarts and the percentage of memory used in the Control Plane UX.
27
+
28
+ Here are the steps for configuring an alert for the percentage of memory used:
29
+
30
+ 1. Navigate to the workload that you want to configure the alert for
31
+ 2. Click "Metrics" on the left menu to go to Grafana
32
+ 3. On Grafana, go to the alerting page by clicking on the alert icon in the sidebar
33
+ 4. Click on "New alert rule"
34
+ 5. In the "Set a query and alert condition" section, select "Grafana managed alert"
35
+ 6. There should be a default query named `A`
36
+ 7. Change the data source of the query to `metrics`
37
+ 8. Click "Code" on the top right of the query and enter `mem_used{workload="workload_name"} / mem_reserved{workload="workload_name"} * 100`
38
+ (replace `workload_name` with the name of the workload)
39
+ 9. There should be a default expression named `B`, with the type `Reduce`, the function `Last`, and the input `A` (this
40
+ ensures that we're getting the last data point of the query)
41
+ 10. There should be a default expression named `C`, with the type `Threshold`, and the input `B` (this is where you
42
+ configure the condition for firing the alert, e.g., `IS ABOVE 95`)
43
+ 11. You can then preview the alert and check if it's firing or not based on the example time range of the query
44
+ 12. In the "Alert evaluation behavior" section, you can configure how often the alert should be evaluated and for how
45
+ long the condition should be true before firing (for example, you might want the alert only to be fired if the
46
+ percentage has been above `95` for more than 20 seconds)
47
+ 13. In the "Add details for your alert" section, fill out the name, folder, group, and summary for your alert
48
+ 14. In the "Notifications" section, you can configure a label for the alert if you're using a custom notification policy,
49
+ but there should be a default root route for all alerts
50
+ 15. Once you're done, save and exit in the top right of the page
51
+ 16. Click "Contact points" on the top menu
52
+ 17. Edit the `grafana-default-email` contact point and add the email where you want to receive notifications
53
+ 18. You should now receive notifications for the alert in your email
54
+
55
+ ![](assets/grafana-alert.png)
56
+
57
+ The steps for configuring an alert for workload restarts are almost identical, but the code for the query would be
58
+ `container_restarts`.
59
+
60
+ For more information on Grafana alerts, see: https://grafana.com/docs/grafana/latest/alerting/
61
+
62
+ ## Remote IP
63
+
64
+ The actual remote IP of the workload container is in the 127.0.0.x network, so that will be the value of the
65
+ `REMOTE_ADDR` env var.
66
+
67
+ However, Control Plane additionally sets the `x-forwarded-for` and `x-envoy-external-address` headers (and others - see:
68
+ https://docs.controlplane.com/concepts/security#headers). On Rails, the `ActionDispatch::RemoteIp` middleware should
69
+ pick those up and automatically populate `request.remote_ip`.
70
+
71
+ So `REMOTE_ADDR` should not be used directly, only `request.remote_ip`.
72
+
73
+ ## ENV Values
74
+
75
+ You can store ENV values used by a container (within a workload) within Control Plane at the following levels:
76
+
77
+ 1. Workload Container
78
+ 2. GVC
79
+
80
+ For your "review apps," it is convenient to have simple ENVs stored in plain text in your source code. You will want to
81
+ keep some ENVs, like the Rails' `SECRET_KEY_BASE`, out of your source code. For staging and production apps, you will
82
+ set these values directly at the GVC or workload levels, so none of these ENV values are committed to the source code.
83
+
84
+ For storing ENVs in the source code, we can use a level of indirection so that you can store an ENV value in your source
85
+ code like `cpln://secret/my-app-review-env-secrets.SECRET_KEY_BASE` and then have the secret value stored at the org
86
+ level, which applies to your GVCs mapped to that org.
87
+
88
+ Here is how you do this:
89
+
90
+ 1. In the upper left "Manage Org" menu, click on "Secrets"
91
+ 2. Create a secret with `Secret Type: Dictionary` (e.g., `my-secrets`) and add the secret env vars there
92
+ 3. In the upper left "Manage GVC" menu, click on "Identities"
93
+ 4. Create an identity (e.g., `my-identity`)
94
+ 5. Navigate to the workload that you want to associate with the identity created
95
+ 6. Click "Identity" on the left menu and select the identity created
96
+ 7. In the lower left "Access Control" menu, click on "Policies"
97
+ 8. Create a policy with `Target Kind: Secret` and add a binding with the `reveal` permission for the identity created
98
+ 9. Use `cpln://secret/...` in the app to access the secret env vars (e.g., `cpln://secret/my-secrets.SOME_VAR`)
99
+
100
+ ## CI
101
+
102
+ **Note:** Docker builds much slower on Apple Silicon, so try configuring CI to build the images when using Apple
103
+ hardware.
104
+
105
+ Make sure to create a profile on CI before running any `cpln` or `cpl` commands.
106
+
107
+ ```sh
108
+ CPLN_TOKEN=...
109
+ cpln profile create default --token ${CPLN_TOKEN}
110
+ ```
111
+
112
+ Also, log in to the Control Plane Docker repository if building and pushing an image.
113
+
114
+ ```sh
115
+ cpln image docker-login
116
+ ```
117
+
118
+ ## Memcached
119
+
120
+ On the workload container for Memcached (using the `memcached:alpine` image), configure the command with the args
121
+ `-l 0.0.0.0`.
122
+
123
+ To do this:
124
+
125
+ 1. Navigate to the workload container for Memcached
126
+ 2. Click "Command" on the top menu
127
+ 3. Add the args and save
128
+
129
+ ![](assets/memcached.png)
130
+
131
+ ## Sidekiq
132
+
133
+ ### Quieting Non-Critical Workers During Deployments
134
+
135
+ To avoid locks in migrations, we can quiet non-critical workers during deployments. Doing this early enough in the CI
136
+ allows all workers to finish jobs gracefully before deploying the new image.
137
+
138
+ There's no need to unquiet the workers, as that will happen automatically after deploying the new image.
139
+
140
+ ```sh
141
+ cpl run 'rails runner "Sidekiq::ProcessSet.new.each { |w| w.quiet! unless w[%q(hostname)].start_with?(%q(criticalworker.)) }"' -a my-app
142
+ ```
143
+
144
+ ### Setting Up a Pre Stop Hook
145
+
146
+ By setting up a pre stop hook in the lifecycle of the workload container for Sidekiq, which sends "QUIET" to the workers,
147
+ we can ensure that all workers will finish jobs gracefully before Control Plane stops the replica. That also works
148
+ nicely for multiple replicas.
149
+
150
+ A couple of notes:
151
+
152
+ - We can't use the process name as regex because it's Ruby, not Sidekiq.
153
+ - We need to add a space after `sidekiq`; otherwise, it sends `TSTP` to the `sidekiqswarm` process as well, and for some
154
+ reason, that doesn't work.
155
+
156
+ So with `^` and `\s`, we guarantee it's sent only to worker processes.
157
+
158
+ ```sh
159
+ pkill -TSTP -f ^sidekiq\s
160
+ ```
161
+
162
+ To do this:
163
+
164
+ 1. Navigate to the workload container for Sidekiq
165
+ 2. Click "Lifecycle" on the top menu
166
+ 3. Add the command and args below "Pre Stop Hook" and save
167
+
168
+ ![](assets/sidekiq-pre-stop-hook.png)
169
+
170
+ ### Setting Up a Liveness Probe
171
+
172
+ To set up a liveness probe on port 7433, see: https://github.com/arturictus/sidekiq_alive
173
+
174
+ ## Useful Links
175
+
176
+ - For best practices for the app's Dockerfile, see: https://lipanski.com/posts/dockerfile-ruby-best-practices
177
+ - For migrating from Heroku Postgres to RDS, see: https://pelle.io/posts/hetzner-rds-postgres
@@ -8,8 +8,8 @@ build-staging:
8
8
  - image: cimg/ruby:3.1-node
9
9
  resource_class: large
10
10
  environment:
11
- CPLN_ORG: myorg
12
- APP_NAME: myapp-staging
11
+ CPLN_ORG: my-org
12
+ APP_NAME: my-app-staging
13
13
  steps:
14
14
  - checkout
15
15
  - setup_remote_docker:
@@ -21,14 +21,13 @@ build-staging:
21
21
  cpln profile create default --token ${CPLN_TOKEN} --org ${CPLN_ORG} --gvc ${APP_NAME}
22
22
  cpln image docker-login
23
23
 
24
- git clone https://github.com/shakacode/heroku-to-control-plane ~/heroku-to-control-plane
25
- sudo ln -s ~/heroku-to-control-plane/cpl /usr/local/bin/cpl
24
+ gem install cpl
26
25
  - run:
27
26
  name: Containerize and push image
28
27
  command: cpl build-image -a ${APP_NAME}
29
28
  - run:
30
29
  name: Database tasks
31
- command: cpl run:detached rails db:migrate -a ${APP_NAME} --image latest
30
+ command: cpl run:detached -a ${APP_NAME} --image latest -- rails db:migrate
32
31
  - run:
33
32
  name: Deploy image
34
33
  command: cpl deploy-image -a ${APP_NAME}
@@ -43,7 +42,7 @@ build-review-app:
43
42
  - image: cimg/ruby:3.1-node
44
43
  resource_class: large
45
44
  environment:
46
- CPLN_ORG: my-org-name
45
+ CPLN_ORG: my-org
47
46
  steps:
48
47
  - checkout
49
48
  - setup_remote_docker:
@@ -65,7 +64,7 @@ build-review-app:
65
64
  - run:
66
65
  name: Provision review app if needed
67
66
  command: |
68
- if ! cpl exist -a ${APP_NAME}; then
67
+ if ! cpl exists -a ${APP_NAME}; then
69
68
  cpl setup-app -a ${APP_NAME}
70
69
  echo "export NEW_APP=true" >> $BASH_ENV
71
70
  fi
@@ -77,9 +76,9 @@ build-review-app:
77
76
  name: Database tasks
78
77
  command: |
79
78
  if [ -n "${NEW_APP}" ]; then
80
- cpl run:detached 'LOG_LEVEL=warn rails db:reset' -a ${APP_NAME} --image latest
79
+ cpl run:detached -a ${APP_NAME} --image latest -- LOG_LEVEL=warn rails db:reset
81
80
  else
82
- cpl run:detached 'LOG_LEVEL=warn rails db:migrate' -a ${APP_NAME} --image latest
81
+ cpl run:detached -a ${APP_NAME} --image latest -- LOG_LEVEL=warn rails db:migrate
83
82
  fi
84
83
  - run:
85
84
  name: Deploy image
@@ -1,47 +1,49 @@
1
+ # Keys beginning with "cpln_" correspond to your settings in Control Plane.
2
+
1
3
  aliases:
2
4
  common: &common
3
- # Org name for staging. (customize to your needs)
4
- # Production apps will use a different Control Plane org, specified below, for security.
5
- # keys beginning with CPLN correspond to your settings in Control Plane
5
+ # Organization name for staging (customize to your needs).
6
+ # Production apps will use a different organization, specified below, for security.
6
7
  cpln_org: my-org-staging
7
8
 
8
- # Example apps use only location. CPLN offers the ability to use multiple locations.
9
- # TODO -- allow specfication of multiple locations
9
+ # Example apps use only one location. Control Plane offers the ability to use multiple locations.
10
+ # TODO: Allow specification of multiple locations.
10
11
  default_location: aws-us-east-2
11
12
 
12
13
  # Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
13
14
  one_off_workload: rails
14
15
 
15
- # Workloads that are application itself and are using application docker image
16
+ # Workloads that are for the application itself and are using application Docker images.
16
17
  app_workloads:
17
18
  - rails
18
19
  - sidekiq
19
20
 
20
- # Additional "service type" workloads, using non-application docker images
21
+ # Additional "service type" workloads, using non-application Docker images.
21
22
  additional_workloads:
22
23
  - redis
23
24
  - postgres
24
25
  - memcached
25
26
 
26
- # Configure the workload name used when maintenance mode is on (defaults to 'maintenance')
27
+ # Configure the workload name used when maintenance mode is on (defaults to "maintenance")
27
28
  maintenance_workload: maintenance
28
29
 
29
30
  apps:
30
31
  my-app-staging:
31
- # Use the values from the common section above
32
+ # Use the values from the common section above.
32
33
  <<: *common
33
34
  my-app-review:
34
35
  <<: *common
35
- # if match_if_app_name_starts_with == true, then use this config for app names beginning,
36
- # like my-app-review-pr123 or my-app-review-anything-goes
36
+ # If `match_if_app_name_starts_with` is `true`, then use this config for app names starting with this name,
37
+ # e.g., "my-app-review-pr123", "my-app-review-anything-goes", etc.
37
38
  match_if_app_name_starts_with: true
38
39
  my-app-production:
39
40
  <<: *common
40
- # Use a different org for production
41
+ # Use a different organization for production.
41
42
  cpln_org: my-org-production
42
- # Allows running command 'cpl pipeline-promote my-app-staging' to promote the staging app to production
43
+ # Allows running the command `cpl promote-app-from-upstream -a my-app-production`
44
+ # to promote the staging app to production.
43
45
  upstream: my-app-staging
44
46
  my-app-other:
45
47
  <<: *common
46
- # you can specify different dockerfile relative to .controlplane folder, default is just 'Dockerfile'
48
+ # You can specify a different `Dockerfile` relative to the `.controlplane/` directory (defaults to "Dockerfile").
47
49
  dockerfile: ../some_other/Dockerfile
data/lib/command/base.rb CHANGED
@@ -210,7 +210,7 @@ module Command
210
210
 
211
211
  # Or special string to indicate no image available
212
212
  if matching_items.empty?
213
- "#{app_name}:#{NO_IMAGE_AVAILABLE}"
213
+ name_only ? "#{app_name}:#{NO_IMAGE_AVAILABLE}" : nil
214
214
  else
215
215
  latest_item = matching_items.max_by { |item| extract_image_number(item["name"]) }
216
216
  name_only ? latest_item["name"] : latest_item
@@ -51,6 +51,7 @@ module Command
51
51
 
52
52
  images = cp.image_query(app_name)["items"].filter { |item| item["name"].start_with?("#{app_name}:") }
53
53
  image = latest_image_from(images, app_name: app_name, name_only: false)
54
+ next unless image
54
55
 
55
56
  created_date = DateTime.parse(image["created"])
56
57
  diff_in_days = (now - created_date).to_i
data/lib/cpl/version.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cpl
4
- VERSION = "1.0.0"
4
+ VERSION = "1.0.1"
5
+ MIN_CPLN_VERSION = "0.0.71"
5
6
  end
data/lib/cpl.rb CHANGED
@@ -40,16 +40,57 @@ end
40
40
  module Cpl
41
41
  class Error < StandardError; end
42
42
 
43
- class Cli < Thor
43
+ class Cli < Thor # rubocop:disable Metrics/ClassLength
44
44
  package_name "cpl"
45
45
  default_task :no_command
46
46
 
47
47
  def self.start(*args)
48
+ check_cpln_version
49
+ check_cpl_version
48
50
  fix_help_option
49
51
 
50
52
  super(*args)
51
53
  end
52
54
 
55
+ def self.check_cpln_version # rubocop:disable Metrics/MethodLength
56
+ return if @checked_cpln_version
57
+
58
+ @checked_cpln_version = true
59
+
60
+ result = `cpln --version 2>/dev/null`
61
+ if $CHILD_STATUS.success?
62
+ data = JSON.parse(result)
63
+
64
+ version = data["npm"]
65
+ min_version = Cpl::MIN_CPLN_VERSION
66
+ if Gem::Version.new(version) < Gem::Version.new(min_version)
67
+ ::Shell.abort("Current 'cpln' version: #{version}. Minimum supported version: #{min_version}. " \
68
+ "Please update it with 'npm update -g @controlplane/cli'.")
69
+ end
70
+ else
71
+ ::Shell.abort("Can't find 'cpln' executable. Please install it with 'npm install -g @controlplane/cli'.")
72
+ end
73
+ end
74
+
75
+ def self.check_cpl_version # rubocop:disable Metrics/MethodLength
76
+ return if @checked_cpl_version
77
+
78
+ @checked_cpl_version = true
79
+
80
+ result = `gem search ^cpl$ --remote 2>/dev/null`
81
+ return unless $CHILD_STATUS.success?
82
+
83
+ matches = result.match(/cpl \((.+)\)/)
84
+ return unless matches
85
+
86
+ version = Cpl::VERSION
87
+ latest_version = matches[1]
88
+ return unless Gem::Version.new(version) < Gem::Version.new(latest_version)
89
+
90
+ ::Shell.warn("You are not using the latest 'cpl' version. Please update it with 'gem update cpl'.")
91
+ $stderr.puts
92
+ end
93
+
53
94
  # This is so that we're able to run `cpl COMMAND --help` to print the help
54
95
  # (it basically changes it to `cpl --help COMMAND`, which Thor recognizes)
55
96
  # Based on https://stackoverflow.com/questions/49042591/how-to-add-help-h-flag-to-thor-command
@@ -46,7 +46,7 @@ file_data =
46
46
  <<~DATA
47
47
  <!-- NOTE: This file is automatically generated by running `script/generate_commands_docs`. Do NOT edit it manually. -->
48
48
 
49
- ### Common Options
49
+ ## Common Options
50
50
 
51
51
  ```
52
52
  -a XXX, --app XXX app ref on Control Plane (GVC)
@@ -55,7 +55,7 @@ file_data =
55
55
  This `-a` option is used in most of the commands and will pick all other app configurations from the project-specific
56
56
  `.controlplane/controlplane.yml` file.
57
57
 
58
- ### Commands
58
+ ## Commands
59
59
 
60
60
  #{commands_str}
61
61
  DATA
@@ -4,23 +4,24 @@ spec:
4
4
  # https://docs.controlplane.com/reference/workload#cron-configuration
5
5
  type: cron
6
6
  job:
7
- # Run daily job at 2am, see cron docs
7
+ # Run daily job at 2am (see cron docs)
8
8
  schedule: 0 2 * * *
9
9
  # Never or OnFailure
10
10
  restartPolicy: Never
11
11
  containers:
12
12
  - name: daily-task
13
+ cpu: 50m
14
+ memory: 256Mi
13
15
  args:
14
16
  - bundle
15
17
  - exec
16
18
  - rails
17
19
  - db:prepare
18
- cpu: 50m
19
20
  inheritEnv: true
20
- image: '/org/APP_ORG/image/APP_IMAGE'
21
- memory: 256Mi
21
+ image: "/org/APP_ORG/image/APP_IMAGE"
22
22
  defaultOptions:
23
23
  autoscaling:
24
+ minScale: 1
24
25
  maxScale: 1
25
26
  capacityAI: false
26
27
  firewallConfig:
@@ -6,15 +6,16 @@ spec:
6
6
  - name: maintenance
7
7
  env:
8
8
  - name: PORT
9
- value: '3000'
9
+ value: "3000"
10
10
  - name: PAGE_URL
11
- value: ''
12
- image: 'shakacode/maintenance-mode'
11
+ value: ""
12
+ image: "shakacode/maintenance-mode"
13
13
  ports:
14
14
  - number: 3000
15
15
  protocol: http
16
16
  defaultOptions:
17
17
  autoscaling:
18
+ minScale: 1
18
19
  maxScale: 1
19
20
  capacityAI: false
20
21
  timeoutSeconds: 60
@@ -7,15 +7,16 @@ spec:
7
7
  cpu: 3m
8
8
  memory: 10Mi
9
9
  args:
10
- - '-l'
10
+ - "-l"
11
11
  - 0.0.0.0
12
- image: 'memcached:alpine'
12
+ image: "memcached:alpine"
13
13
  ports:
14
14
  - number: 11211
15
15
  protocol: tcp
16
16
  defaultOptions:
17
17
  autoscaling:
18
18
  metric: latency
19
+ minScale: 1
19
20
  maxScale: 1
20
21
  capacityAI: false
21
22
  firewallConfig:
@@ -13,17 +13,18 @@ spec:
13
13
  value: password123
14
14
  - name: POSTGRES_USER
15
15
  value: postgres
16
- image: 'postgres:13.8-alpine'
16
+ image: "postgres:13.8-alpine"
17
17
  ports:
18
18
  - number: 5432
19
19
  protocol: tcp
20
20
  volumes:
21
21
  - path: /var/lib/postgresql/data
22
22
  recoveryPolicy: retain
23
- uri: 'scratch://postgres-vol'
23
+ uri: "scratch://postgres-vol"
24
24
  defaultOptions:
25
25
  autoscaling:
26
26
  metric: latency
27
+ minScale: 1
27
28
  maxScale: 1
28
29
  capacityAI: false
29
30
  firewallConfig:
data/templates/rails.yml CHANGED
@@ -5,14 +5,15 @@ spec:
5
5
  containers:
6
6
  - name: rails
7
7
  cpu: 512m
8
- inheritEnv: true
9
- image: '/org/APP_ORG/image/APP_IMAGE'
10
8
  memory: 1Gi
9
+ inheritEnv: true
10
+ image: "/org/APP_ORG/image/APP_IMAGE"
11
11
  ports:
12
12
  - number: 3000
13
13
  protocol: http
14
14
  defaultOptions:
15
15
  autoscaling:
16
+ minScale: 1
16
17
  maxScale: 1
17
18
  capacityAI: false
18
19
  timeoutSeconds: 60
data/templates/redis.yml CHANGED
@@ -6,13 +6,14 @@ spec:
6
6
  - name: redis
7
7
  cpu: 3m
8
8
  memory: 20Mi
9
- image: 'redis:latest'
9
+ image: "redis:latest"
10
10
  ports:
11
11
  - number: 6379
12
12
  protocol: tcp
13
13
  defaultOptions:
14
14
  autoscaling:
15
15
  metric: latency
16
+ minScale: 1
16
17
  maxScale: 1
17
18
  capacityAI: false
18
19
  firewallConfig:
@@ -4,21 +4,30 @@ spec:
4
4
  type: standard
5
5
  containers:
6
6
  - name: sidekiq
7
+ cpu: 50m
8
+ memory: 256Mi
7
9
  args:
8
10
  - bundle
9
11
  - exec
10
12
  - sidekiq
11
- - '-C'
13
+ - "-C"
12
14
  - config/sidekiq.yml
13
- cpu: 50m
14
15
  inheritEnv: true
15
- image: '/org/APP_ORG/image/APP_IMAGE'
16
- memory: 256Mi
16
+ image: "/org/APP_ORG/image/APP_IMAGE"
17
17
  ports:
18
18
  - number: 7433
19
19
  protocol: http
20
+ lifecycle:
21
+ preStop:
22
+ exec:
23
+ command:
24
+ - pkill
25
+ - "-TSTP"
26
+ - "-f"
27
+ - ^sidekiq\s
20
28
  defaultOptions:
21
29
  autoscaling:
30
+ minScale: 1
22
31
  maxScale: 1
23
32
  capacityAI: false
24
33
  firewallConfig:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-05-29 00:00:00.000000000 Z
12
+ date: 2023-06-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: debug
@@ -219,9 +219,13 @@ files:
219
219
  - bin/cpl
220
220
  - cpl
221
221
  - cpl.gemspec
222
+ - docs/assets/grafana-alert.png
223
+ - docs/assets/memcached.png
224
+ - docs/assets/sidekiq-pre-stop-hook.png
222
225
  - docs/commands.md
223
226
  - docs/postgres.md
224
227
  - docs/redis.md
228
+ - docs/tips.md
225
229
  - docs/troubleshooting.md
226
230
  - examples/circleci.yml
227
231
  - examples/controlplane.yml