-
Notifications
You must be signed in to change notification settings - Fork 69
/
app_development.prolific
411 lines (291 loc) · 21.3 KB
/
app_development.prolific
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
Create an org and space
### What?
Cloud Foundry uses role-based access control, with each role granting permissions in either an **[organization](https://docs.cloudfoundry.org/concepts/roles.html#orgs)** or an **[application space](https://docs.cloudfoundry.org/concepts/roles.html#spaces)**. Let's make a new organization and associated space!
Customer Operators use this to assign different orgs and spaces to different teams and can assign quotas to manage load across their company.
### How?
1. View orgs `cf orgs` and spaces `cf spaces` (each space is scoped to an org)
1. Target the system org `cf target -o system` and view spaces `cf spaces` and apps `cf apps`
1. Create a new `onboarding-org` organization with an `onboarding-space` space
### Expected Result
When creating the organization the current user will be assigned the role of 'Org Manager'.
Run `cf org-users onboarding-org` to verify.
When creating the space the current user will be assigned two new roles in the space - 'Space Manager' and 'Space Developer'
Run `cf space-users onboarding-org onboarding-space` to verify.
### Resources
[Orgs, Spaces, Roles, and Permissions](https://docs.cloudfoundry.org/concepts/roles.html)
[Creating and managing users with the cf CLI](https://docs.cloudfoundry.org/adminguide/cli-user-management.html)
### Relevant Repos and Teams
**CLI:** [cloudfoundry/cli](https://github.com/cloudfoundry/cli)
**CAPI:** [cloudfoundry/cloud_controller_ng](https://github.com/cloudfoundry/cloud_controller_ng)
L: app-dev
---
Create a new user
### What?
Cloud Foundry uses role-based access control, with each role granting permissions in either an [organization](https://docs.cloudfoundry.org/concepts/roles.html#orgs) or an [application space](https://docs.cloudfoundry.org/concepts/roles.html#spaces). **[View the types of roles and their abilities](https://docs.cloudfoundry.org/concepts/roles.html#roles)**. Without a certain role in an org and space you won't be able to perform specific actions.
### How?
1. Create a new user
`cf create-user some-user some-password`
1. Login as that user
`cf auth some-user some-password`
1. And view orgs
`cf orgs`
Not much there, huh? By default `some-user` cannot view or perform any actions, so as an admin, you'll have to assign some roles. Log back in as the admin user and update `some-user`'s roles so they can push an application in the onboarding-org / onboarding-space org and space.
1. Login back in as admin
`cf auth admin <your-password>`
1. And give some-user the SpaceDeveloper role for onboarding-org/onboarding-space
`cf set-space-role some-user onboarding-org onboarding-space SpaceDeveloper`
### Expected Result
When logged in as `some-user`, you can see "onboarding-org" in your list of orgs and "onboarding-space" in your list of spaces.
### Resources
[Role permissions](https://docs.cloudfoundry.org/concepts/roles.html)
[Setting user roles](https://docs.cloudfoundry.org/concepts/roles.html#roles)
### Relevant Repos and Teams
**CLI:** [cloudfoundry/cli](https://github.com/cloudfoundry/cli)
**CAPI:** [cloudfoundry/cloud_controller_ng](https://github.com/cloudfoundry/cloud_controller_ng)
L: app-dev
---
Push a sample app
### What?
This is the "magic" that makes TAS such a compelling product.
Cloud Foundry applications are deployed by `cf push`-ing your code or some compiled artifact. The appropriate [buildpack](https://docs.cloudfoundry.org/buildpacks/) is identified by the buildpack detect scripts, a [staging container](https://docs.cloudfoundry.org/concepts/how-applications-are-staged.html) is created to prepare your app's environment, and a droplet is produced. This droplet will be used by the cells to run your application instances. When you push an app, you can optionally include an [application manifest.yml](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html) that contains properties about your application's deployment.
### How?
1. Clone the **[cloudfoundry/cf-acceptance-tests](https://github.com/cloudfoundry/cf-acceptance-tests)** repo to your local workstation.
1. `cd ./cf-acceptance-tests/assets/dora`
1. **[Create a `manifest.yml` file](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#minimal-manifest)**
1. In the `manifest.yml`, set "dora" as the app's name
1. In the `manifest.yml`, set the [disk quota](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#disk-quota) to 1024M
1. In the `manifest.yml`, set the [number of instances](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#instances) to 2
1. In the `manifest.yml`, [generate a unique route](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#random-route) for your app the first time you push.
1. `cf push` your app
### Expected Result
`cf app dora` will print the app's status, including the URL. When your visit the URL in your browser you should see the words "Hi, I'm Dora!"
### Resources
[Cf Buildpacks](https://docs.cloudfoundry.org/buildpacks/)
[CF application manifests](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html)
[How Applications are Staged](https://docs.cloudfoundry.org/concepts/how-applications-are-staged.html)
[A beginner-friendly introduction to containers, VMs, and Docker](https://medium.freecodecamp.com/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b)
L: app-dev
---
HTTP trace a CLI command
### What?
Behind the scenes the command line depends on several components in Cloud Foundry. If a cf CLI command fails or produces unexpected results, re-run it with HTTP tracing enabled to view raw requests and responses between the cf CLI and the other components. The majority of those calls will be to the Cloud Controller REST API, but for logging the CLI hits the Loggregator.
### How?
Enable HTTP tracing with the CF_TRACE environment variable (`CF_TRACE=true`) or the -v flag (`-v`).
Try this now with `cf app` by running `cf app dora -v`.
### Expected Result
You should see each of the requests and responses that resulted in `cf app` delivering information about your app. Now give it a shot with other cf CLI commands!
### Resources
[Trace Cloud Controller REST API Calls](https://docs.cloudfoundry.org/devguide/deploy-apps/troubleshoot-app-health.html#trace)
L: app-dev
---
Get recent app logs
### What?
Cloud Foundry applications are expected to log to [stdout and stderr](https://en.wikipedia.org/wiki/Standard_streams). This is part of [Twelve-Factor app design](https://12factor.net/logs).
A set of Cloud Foundry components (cumulatively named [Loggregator](https://github.com/cloudfoundry/loggregator)) provide a stream of log output from your app and from system components that interact with your app during updates and execution. Logs are gathered and stored in a best-effort manner. If a client is unable to consume log lines quickly enough, logs will be lost. The `--recent` flag will print the logs that are being buffered.
The log output has a [specific format](https://docs.cloudfoundry.org/devguide/deploy-apps/streaming-logs.html). It's important to note that when your application logs, the instance number is prepended to the message (i.e. [APP/*instance_number*]).
System components logs will also appear in relation to your application. Below is a description of a few important ones:
- The stager `STG` is responsible for using a Buildpack to create a droplet.
- The Diego cell `CELL` is responsible for running your application instance.
- The Router `RTR` logs your application has responded to an HTTP request.
- [See more components](https://docs.cloudfoundry.org/devguide/deploy-apps/streaming-logs.html#format)
### How?
`cf logs dora --recent`
### Expected Result
The output will look something like:
```
20116-12-05T21:37:29.96-0500 [STG/0] OUT Uploaded build artifacts cache (109B)
2016-12-05T21:37:33.77-0500 [STG/0] OUT Uploaded droplet (75.7M)
2016-12-05T21:37:33.78-0500 [STG/0] OUT Uploading complete
2016-12-05T21:37:34.11-0500 [CELL/0] OUT Creating container
2016-12-05T21:37:35.07-0500 [CELL/0] OUT Successfully created container
2016-12-05T21:37:39.40-0500 [CELL/0] OUT Starting health monitoring of container
2016-12-05T21:37:42.08-0500 [APP/0] OUT 2016-12-06 02:37:42.078 INFO 14 --- [ main] pertySourceApplicationContextInitializer : Adding 'cloud' PropertySource to ApplicationContext
2016-12-05T21:45:25.23-0500 [RTR/0] OUT dora.pcfdev.io - "GET /favicon.ico HTTP/1.1" 200 0 946 "http://dora.local.pcfdev.io/service" ....
```
### Resources
[Logs for CF components](https://docs.cloudfoundry.org/running/managing-cf/logging.html)
[Logs for applications](https://docs.cloudfoundry.org/devguide/deploy-apps/streaming-logs.html)
L: app-dev
---
Get streaming logs
### What?
By omitting the `--recent` from your `cf logs dora` command, Loggregator will stream logs from the application in realtime. You'll use this most often as a diagnosing tool. Let's trigger some app activity to verify that it shows up in the logs.
### How?
1. Run `cf logs dora`
1. In another terminal buffer, run `watch cf app dora`. (If you don't have `watch` installed, you can get it by running `brew install watch`).
1. Visit the dora endpoint `/sigterm/KILL`
### Expected Result
Cloud Foundry applications are monitored with a constant health check that ensure they are listening on a specific port. When your application stops listening it'll be automatically restarted.
You can see this in the logs tagged with `CELL` and `API`
When your application is down, in the `RTR` logs, you will see that HTTP requests will return a 502 Bad Gateway.
Refer to the **[dora app README.md](https://github.com/cloudfoundry/cf-acceptance-tests/tree/master/assets/dora)** to find other useful endpoints to experiment with. It's good to know what common logs, warnings, and errors look like so you can recognize them in the wild.
L: app-dev
---
View a list of app events
### What?
Cloud Foundry stores a history of events about your application. You'll generally use `cf logs` when debugging your app's behavior, but every once and awhile the select, well-formatted information contained in `cf events` is more helpful than a firehose of data.
### How?
1. `cf stop dora`
1. `cf start dora`
1. `cf events dora`
### Expected Result
You should see the list of events including the recent stop & start.
### Resources
[StackOverflow: When to use cf events?](http://stackoverflow.com/questions/24545838/when-to-use-cf-events)
[cf CLI docs](http://docs.cloudfoundry.org/cf-cli/cf-help.html)
L: app-dev
---
Scale your app with the CLI
### What?
Your application runs in a container hosted on a Diego Cell. A Cloud Foundry deployment may have many cells distributed among multiple Availability Zones. Diego will automatically balance the applications you deploy across the defined AZs. If an AZ went down (along with your application), Diego would start a new instance of your application in a healthy cell in a different AZ. Depending on demand, you may want to scale your application horizontally (more instances) and/or vertically (more disk & memory).
You already have two instances of `dora`. Now we'll scale your app _horizontally_ by bumping your instance count up to five and scale _vertically_ by increasing your memory to 512M.
### How?
1. Refer to the **[`cf scale` docs](https://docs.cloudfoundry.org/devguide/deploy-apps/cf-scale.html)** to scale your app vertically and horizontally.
1. In another terminal buffer, run `watch cf app dora` to watch the updates happen.
### Expected Result
`cf app dora` should show five instances and the disk and memory they are each allotted.
`cf env dora` should show my new disk and memory limits listed under VCAP_APPLICATION.
### Resources
[Scaling apps on CF](https://docs.cloudfoundry.org/devguide/deploy-apps/cf-scale.html)
L: app-dev
---
View your app's environment variables
### What?
Environment variables are the means by which the Cloud Foundry [runtime](https://www.techopedia.com/definition/5466/runtime-environment-rte) communicates with a deployed application about its environment. You can use them too!
### How?
1. `cf set-env dora MY_VAR hello`
1. `cf env dora`
### Expected Result
The cf CLI will show the application's environment variables classified as System-Provided (i.e. `VCAP_APPLICATION`) and User Provided (`MY_VAR`). Running and Staging variables are provided by operators that apply to all applications.
### Resources
[Cloud Foundry Environment Variables](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html)
[What is a Runtime Environment (RTE)?](https://docs.cloudfoundry.org/definition/5466/runtime-environment-rte)
[VCAP_APPLICATION](https://docs.cloudfoundry.org/environment-variable.html#VCAP-APPLICATION)
[VCAP_SERVICES](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES)
L: app-dev
---
SSH into a running app container
### What?
Your applications run on Diego Cells, which create containers for each of your application instances. One of the features of [Diego (the new CF Runtime)](http://www.starkandwayne.com/blog/demystifying-cloud-foundrys-diego/) versus DEAs (the original Runtime) is that you have the ability to [SSH](https://en.wikipedia.org/wiki/Secure_Shell) into the containers for debugging purposes.
### How?
1. `cf ssh dora`
1. `ls` around the directory tree
1. Use the `ps aux` command to see what processes are running.
1. Run `env` to view environment variables. You'll see there are additional environment variables that the cf CLI doesn't print, but that are available to your application. The full [list of variables can be viewed here](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html).
1. `exit`, then SSH back into a specific instance of your app, using the `-i app-instance-index` flag (when you run `cf app app-name` you'll see the indexes of the instances displayed in turquoise to the left of their information). View the [cf CLI SSH flags](http://cli.cloudfoundry.org/en-US/cf/ssh.html) to see what else is possible.
**TRIVIA:** did you notice that you're SSH-ed in as the `vcap` user? VCAP stands for "VMware's Cloud Application Platform," an old name for Cloud Foundry. Catchy, right?
### Resources
[Differences Between DEA and Diego Architectures](https://docs.cloudfoundry.org/concepts/diego/dea-vs-diego.html)
[Demystifying Cloud Foundry's Diego](http://www.starkandwayne.com/blog/demystifying-cloud-foundrys-diego/)
[Unix/Linux StackExchange: What does aux mean in `ps aux`?](http://unix.stackexchange.com/questions/106847/what-does-aux-mean-in-ps-aux)
L: app-dev
---
Kill a specific instance of an application
### What?
Sometimes it's clear that a particular instance of your app is having a problem, but it isn't being identified and culled by the [HealthCheck](https://docs.cloudfoundry.org/devguide/deploy-apps/healthchecks.html). This is a good way to take it out yourself.
### How?
Run `watch cf app dora`.
In another buffer, restart a specific instance of dora using `cf restart-app-instance APP_NAME INSTANCE_INDEX`.
Alternatively, you can also kill a specific instance of dora using `cf curl /v2/apps/APP_GUID/instances/0 -d '' -X DELETE` (reading the `cf curl` help content and [API Docs: Terminate the running app instance at the given index](http://v2-apidocs.cloudfoundry.org/apps/terminate_the_running_app_instance_at_the_given_index.html) may clarify some things).
### Expected Result
You should see the correct instance of your app dying and recovering.
### Explanation
You might notice that `cf restart-app-instance` is way more straightforward. The alternative way of terminating an app instance using `cf curl` is part of Cloud Controller API v2.
### Resources
[Cloud Foundry CLI Reference Guide: restart-app-instance](http://cli.cloudfoundry.org/en-US/cf/restart-app-instance.html)
L: app-dev
---
Add an additional route to the application
### What?
CF creates a route for your app when it is first pushed, but you can create additional routes using the cf CLI.
### How?
**[Create and map a new route in your space](https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#map-route)**
### Expected Result
1. Run `cf routes` to verify your route has been created and correctly mapped to dora
1. Visit route and see dora content
### Additional notes
Combinations of route and domain names must be unique. Even though you may not see a particular route listed in your space, that doesn't mean it's available—it may be taken by another application in a different org or space.
If you had created the new route using `cf create-route` without mapping it to the dora app, it would have existed un-mapped and the router would have returned 404 Not Found. While at first glance this might seem like a useless feature, it allows you to claim a route before you're ready to use it.
### Resources
[CF Routes and Domains](https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html)
[Basic Linux Networking reference](http://www.penguintutor.com/linux/basic-network-reference)
L: app-dev
---
Run a task against the application
### What?
When we run `cf push MY_APP`, we're creating a long running process or LRP in
Diego terminology.
However, sometimes you want to run a short-lived script instead like running
`rake db:migrate` after your Ruby process starts up.
A task is an application or script whose code is included as part of a deployed application, but runs independently in its own container.
These tasks execute, print their STDOUT and STDERR to the parent app's log, and
exit with a zero status code for success or non-zero for failure.
### Run a simple task
1. Push the Dora app as described in the "Push a sample app" story
1. In one terminal run `cf logs dora`
1. In another terminal run `cf run-task dora 'sleep 15 && echo "Hello task!"'`
1. Run `cf tasks dora`
### Expected Result
1. You should see "Hello task!" appear in the app logs after ~15 seconds
1. Tasks are asynchronous so the `cf run-task` command returns immediately without
waiting for the task to finish running. `cf tasks` shows you which tasks are
currently running.
### Run a failing task
1. Run `cf run-task dora 'cat missing-file.txt'`
1. Run `cf tasks dora`
### Expected Result
1. You should see that the task is soon marked as "FAILED" as running `cat`
against an invalid filepath will exit non-zero.
### Understanding containers
1. Continue tailing app logs in one terminal
1. Run `cf run-task dora 'touch NEW_FILE.txt && ls'`
1. Run `cf tasks dora` and wait for task to finish
1. Run `cf run-task dora 'ls'`
### Expected Result
1. The `ls` output in the first task should show `NEW_FILE.txt` listed along
with some other files from the dora app, but the second `ls` will not show
`NEW_FILE.txt`. Why would that be?
- A: Each task is run in a new container which contain the contents of the parent
app's droplet. This is why you see the app files like `Gemfile`. However,
any new files or modifications you make to the file system while in the
container are discarded when the task exits. Each new task gets a fresh
copy of the filesystem containing the droplet files and any writes are only
viewable from within the current container.
### Understanding container placement
1. Continue tailing app logs in one terminal
1. Run `cf run-task dora 'echo MY INSTANCE IP: $CF_INSTANCE_INTERNAL_IP'` (single quotes
are important)
1. Run `cf run-task dora 'echo MY INSTANCE IP: $CF_INSTANCE_INTERNAL_IP'` a couple more
times
### Expected Result
1. If you have more than one Diego cell VM in your deployment (which you
will not if you used the 'scale-to-one-az.yml' opsfile), you should see
different IP addresses printed in the logs each time you run the above task.
This shows that Diego will schedule task containers on whatever cell happens
to have capacity at that moment. The tasks do not need to be scheduled on the
same cell as the parent app as tasks are created in a new container
independent of the parent app container. If you need access to the parent app
container use `cf ssh` instead.
### Resources
[Running Tasks](https://docs.cloudfoundry.org/devguide/using-tasks.html)
[Tasks API Docs](http://v3-apidocs.cloudfoundry.org/version/3.51.0/index.html#tasks)
L: app-dev
---
Advanced: Pushing an application using CF API directly
### What?
The `cf push` command suffices common use cases of running an app on Cloud Foundry, with a lot of tasks automated and running under the hood. But for more complicated workflows, as an advanced user, you might want to make requests to the Cloud Controller(CC) API directly. Are you up for the challenge?
### How?
1. If dora is still running, `cf delete dora` to start fresh.
1. ** Follow instructions on [How to Create an App Using V3 of the CC API](https://github.com/cloudfoundry/cloud_controller_ng/wiki/How-to-Create-an-App-Using-V3-of-the-CC-API)**
### Expected Result
1. `cf app dora` will print the app's status, including the URL. When your visit the URL in your browser you should see the words "Hi, I'm Dora!"
### Additional notes
Using the API directly lets users do as much or as little of `cf push` as they like. Some example workflows:
- Rolling back to a previous droplet
- Running a task without having to run the app first
### Resources
[V3 API docs](http://v3-apidocs.cloudfoundry.org)
[V2 API docs](https://v2-apidocs.cloudfoundry.org/)
[Component: Cloud Controller](https://docs.cloudfoundry.org/concepts/architecture/cloud-controller.html)
[Using Experimental of CLI Commands](https://docs.cloudfoundry.org/devguide/v3-commands.html)
L: app-dev