1
by Robin Winslow
All files: branched from https://github.com/nottrobin/charm-bootstrap-wsgi |
1 |
charm-bootstrap-wsgi
|
2 |
====================
|
|
3 |
||
4 |
This repo is a template charm for any [juju][1] deployed wsgi service. |
|
5 |
As is, this charm deploys an example wsgi service with nagios checks and simple |
|
6 |
rolling upgrades. |
|
7 |
||
8 |
You can re-use this charm to deploy any wsgi service by updating the |
|
9 |
playbook.yaml file. All of the wsgi functionality is provided |
|
10 |
by a reusable wsgi-app ansible role (see roles/wsgi-app) together |
|
11 |
with the gunicorn charm. |
|
12 |
||
13 |
Disclaimer: this template does not try to explain what's possible with |
|
14 |
either ansible or juju - but if you know a bit about both, it will |
|
15 |
show you how you can easily use them together. |
|
16 |
||
17 |
||
18 |
## Deploying the charm
|
|
19 |
||
20 |
Make sure you've got a bootstrapped juju environment ready, and then: |
|
21 |
||
22 |
```
|
|
23 |
$ mkdir -p ~/charms/precise && cd ~/charms/precise
|
|
24 |
$ git clone https://github.com/absoludity/charm-bootstrap-wsgi
|
|
25 |
$ cd charm-bootstrap-wsgi
|
|
26 |
$ make deploy
|
|
27 |
```
|
|
28 |
||
29 |
You should now be able to curl your service to see it working: |
|
30 |
||
31 |
```
|
|
32 |
$ make curl
|
|
33 |
juju run --service wsgi-example "curl -s http://localhost:8080"
|
|
34 |
- MachineId: "1"
|
|
35 |
Stdout: 'It works! Revision 1'
|
|
36 |
UnitId: charm-bootstrap-wsgi/0
|
|
37 |
- MachineId: "2"
|
|
38 |
Stdout: 'It works! Revision 1'
|
|
39 |
UnitId: charm-bootstrap-wsgi/1
|
|
40 |
```
|
|
41 |
||
42 |
You can also see the output of all the configured nagios checks, |
|
43 |
including the check_http added by the playbook, by running: |
|
44 |
```
|
|
45 |
$ make nagios
|
|
46 |
```
|
|
47 |
||
48 |
## Your custom deployment code
|
|
49 |
||
50 |
To deploy your own custom wsgi application, open up the playbook.yml |
|
51 |
In addition to the wsgi-app reusable role and the optional nagios reusable role |
|
52 |
(nrpe-external-master), it only has two tasks: |
|
53 |
||
54 |
* installing any package dependencies
|
|
55 |
* Re-rendering the app's config file (and triggering a wsgi restart)
|
|
56 |
||
57 |
If you find yourself needing to do more than this, let me know :-) |
|
58 |
||
59 |
For simplicity, the default example app is deployed from the charm itself with |
|
60 |
the archived code in the charm's files directory. But the wsgi-app role also |
|
61 |
allows you to define a code_assets_uri, which if set, will be used instead of |
|
62 |
the charm's files directory. |
|
63 |
||
64 |
The nagios check used for your app can be updated by adjusting the |
|
65 |
check_params passed to the role in playbook.yml (or you can additionally |
|
66 |
add further nagios checks depending on your needs). |
|
67 |
||
68 |
||
69 |
## A rolling upgrade example
|
|
70 |
||
71 |
Assuming you've already deployed the example service, we first update |
|
72 |
the configuration so that the units continue to run the 'r1' build |
|
73 |
(current_symlink), while simultaneously ensuring that the 'r2' build |
|
74 |
is installed and ready to run: |
|
75 |
```
|
|
76 |
$ juju set wsgi-example current_symlink=r1 build_label=r2
|
|
77 |
```
|
|
78 |
||
79 |
Next, manually set just one unit to use the r2 build: |
|
80 |
||
81 |
``` |
|
82 |
$ juju run --unit wsgi-example/0 "CURRENT_SYMLINK=r2 actions/set-current-symlink" |
|
83 |
||
84 |
PLAY [localhost] ************************************************************** |
|
85 |
||
86 |
GATHERING FACTS *************************************************************** |
|
87 |
ok: [localhost] |
|
88 |
||
89 |
TASK: [wsgi-app | Manually set current symlink.] ****************************** |
|
90 |
changed: [localhost] |
|
91 |
||
92 |
NOTIFIED: [wsgi-app | Restart wsgi] ******************************************* |
|
93 |
changed: ... |
|
94 |
||
95 |
PLAY RECAP ******************************************************************** |
|
96 |
localhost : ok=3 changed=2 unreachable=0 failed=0 |
|
97 |
``` |
|
98 |
||
99 |
Verify that the new revision is working correctly on the one instance: |
|
100 |
||
101 |
```
|
|
102 |
$ make curl
|
|
103 |
juju run --service wsgi-example "curl -s http://localhost:8080"
|
|
104 |
- MachineId: "1"
|
|
105 |
Stdout: 'It works! Revision 2'
|
|
106 |
UnitId: wsgi-example/0
|
|
107 |
- MachineId: "2"
|
|
108 |
Stdout: 'It works! Revision 1'
|
|
109 |
UnitId: wsgi-example/1
|
|
110 |
```
|
|
111 |
||
112 |
Update any others, or when you're confident, update the full set with: |
|
113 |
||
114 |
```
|
|
115 |
$ juju set wsgi-example current_symlink=r2
|
|
116 |
```
|
|
117 |
||
118 |
and then verify that all units are service the latest with `make curl` again.
|
|
119 |
||
120 |
||
121 |
### Note about test Dependencies
|
|
122 |
The makefile to run tests requires the following dependencies |
|
123 |
||
124 |
- python-nose
|
|
125 |
- python-mock
|
|
126 |
- python-flake8
|
|
127 |
||
128 |
installable via: |
|
129 |
||
130 |
```
|
|
131 |
$ sudo apt-get install python-nose python-mock python-flake8
|
|
132 |
```
|
|
133 |
||
134 |
[1]: http://juju.ubuntu.com/ |
|
135 |
[2]: http://ansibleworks.com/ |