ironfan 5.0.11 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/.gitignore +4 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +8 -26
  4. data/Gemfile.lock +38 -41
  5. data/NOTES-REALM.md +172 -0
  6. data/Rakefile +19 -77
  7. data/config/ubuntu12.04-ironfan.erb +7 -0
  8. data/ironfan.gemspec +28 -225
  9. data/lib/chef/cluster_knife.rb +26 -0
  10. data/lib/chef/knife/bootstrap/ubuntu12.04-ironfan.erb +7 -0
  11. data/lib/chef/knife/cluster_bootstrap.rb +1 -3
  12. data/lib/chef/knife/cluster_diff.rb +2 -8
  13. data/lib/chef/knife/cluster_kick.rb +1 -3
  14. data/lib/chef/knife/cluster_kill.rb +1 -2
  15. data/lib/chef/knife/cluster_launch.rb +17 -34
  16. data/lib/chef/knife/cluster_list.rb +6 -5
  17. data/lib/chef/knife/cluster_proxy.rb +1 -3
  18. data/lib/chef/knife/cluster_pry.rb +1 -2
  19. data/lib/chef/knife/cluster_show.rb +6 -7
  20. data/lib/chef/knife/cluster_ssh.rb +10 -8
  21. data/lib/chef/knife/cluster_start.rb +1 -2
  22. data/lib/chef/knife/cluster_stop.rb +1 -2
  23. data/lib/chef/knife/cluster_sync.rb +2 -3
  24. data/lib/chef/knife/ironfan_knife_common.rb +58 -18
  25. data/lib/chef/knife/ironfan_script.rb +0 -3
  26. data/lib/ironfan/broker/computer.rb +14 -11
  27. data/lib/ironfan/broker.rb +17 -12
  28. data/lib/ironfan/cookbook_requirements.rb +155 -0
  29. data/lib/ironfan/dsl/cloud.rb +2 -0
  30. data/lib/ironfan/dsl/cluster.rb +25 -15
  31. data/lib/ironfan/dsl/component.rb +12 -15
  32. data/lib/ironfan/dsl/compute.rb +10 -8
  33. data/lib/ironfan/dsl/ec2.rb +2 -26
  34. data/lib/ironfan/dsl/facet.rb +16 -14
  35. data/lib/ironfan/dsl/openstack.rb +147 -0
  36. data/lib/ironfan/dsl/realm.rb +23 -16
  37. data/lib/ironfan/dsl/security_group.rb +29 -0
  38. data/lib/ironfan/dsl/server.rb +14 -5
  39. data/lib/ironfan/dsl/static.rb +63 -0
  40. data/lib/ironfan/dsl/vsphere.rb +1 -0
  41. data/lib/ironfan/dsl.rb +1 -134
  42. data/lib/ironfan/headers.rb +19 -0
  43. data/lib/ironfan/provider/chef/node.rb +3 -2
  44. data/lib/ironfan/provider/ec2/machine.rb +10 -14
  45. data/lib/ironfan/provider/ec2/security_group.rb +58 -43
  46. data/lib/ironfan/provider/openstack/elastic_ip.rb +96 -0
  47. data/lib/ironfan/provider/openstack/keypair.rb +78 -0
  48. data/lib/ironfan/provider/openstack/machine.rb +371 -0
  49. data/lib/ironfan/provider/openstack/security_group.rb +224 -0
  50. data/lib/ironfan/provider/openstack.rb +69 -0
  51. data/lib/ironfan/provider/static/machine.rb +192 -0
  52. data/lib/ironfan/provider/static.rb +23 -0
  53. data/lib/ironfan/provider.rb +58 -1
  54. data/lib/ironfan/requirements.rb +17 -1
  55. data/lib/ironfan/version.rb +3 -0
  56. data/lib/ironfan.rb +107 -172
  57. data/spec/chef/cluster_bootstrap_spec.rb +2 -7
  58. data/spec/chef/cluster_launch_spec.rb +1 -2
  59. data/spec/fixtures/realms/samurai.rb +26 -0
  60. data/spec/integration/minimal-chef-repo/clusters/.gitkeep +0 -0
  61. data/spec/integration/minimal-chef-repo/config/.gitkeep +0 -0
  62. data/spec/integration/minimal-chef-repo/knife/credentials/.gitignore +1 -0
  63. data/spec/integration/minimal-chef-repo/knife/credentials/certificates/.gitkeep +0 -0
  64. data/spec/integration/minimal-chef-repo/knife/credentials/client_keys/.gitkeep +0 -0
  65. data/spec/integration/minimal-chef-repo/knife/credentials/data_bag_keys/.gitkeep +0 -0
  66. data/spec/integration/minimal-chef-repo/knife/credentials/ec2_certs/.gitkeep +0 -0
  67. data/spec/integration/minimal-chef-repo/knife/credentials/ec2_keys/.gitkeep +0 -0
  68. data/spec/integration/minimal-chef-repo/knife/credentials/ironfantest-validator.pem +27 -0
  69. data/spec/integration/minimal-chef-repo/knife/credentials/ironfantester.pem +27 -0
  70. data/spec/integration/minimal-chef-repo/tasks/.gitkeep +0 -0
  71. data/spec/ironfan/cluster_spec.rb +1 -2
  72. data/spec/ironfan/diff_spec.rb +0 -2
  73. data/spec/ironfan/dsl_spec.rb +6 -3
  74. data/spec/ironfan/ec2/cloud_provider_spec.rb +17 -18
  75. data/spec/ironfan/ec2/elb_spec.rb +44 -41
  76. data/spec/ironfan/ec2/security_group_spec.rb +45 -47
  77. data/spec/ironfan/manifest_spec.rb +0 -1
  78. data/spec/ironfan/plugin_spec.rb +55 -40
  79. data/spec/ironfan/realm_spec.rb +42 -30
  80. data/spec/spec_helper.rb +17 -31
  81. data/spec/{spec_helper → support}/dummy_chef.rb +0 -0
  82. data/spec/{spec_helper → support}/dummy_diff_drawer.rb +0 -0
  83. metadata +78 -155
  84. data/.rspec +0 -2
  85. data/.yardopts +0 -19
  86. data/VERSION +0 -2
  87. data/chefignore +0 -41
  88. data/notes/Future-development-proposals.md +0 -266
  89. data/notes/Home.md +0 -55
  90. data/notes/INSTALL-cloud_setup.md +0 -103
  91. data/notes/INSTALL.md +0 -134
  92. data/notes/Ironfan-Roadmap.md +0 -70
  93. data/notes/Upgrading-to-v4.md +0 -66
  94. data/notes/advanced-superpowers.md +0 -16
  95. data/notes/aws_servers.jpg +0 -0
  96. data/notes/aws_user_key.png +0 -0
  97. data/notes/cookbook-versioning.md +0 -11
  98. data/notes/core_concepts.md +0 -200
  99. data/notes/declaring_volumes.md +0 -3
  100. data/notes/design_notes-aspect_oriented_devops.md +0 -36
  101. data/notes/design_notes-ci_testing.md +0 -169
  102. data/notes/design_notes-cookbook_event_ordering.md +0 -249
  103. data/notes/design_notes-meta_discovery.md +0 -59
  104. data/notes/ec2-pricing_and_capacity.md +0 -75
  105. data/notes/ec2-pricing_and_capacity.numbers +0 -0
  106. data/notes/homebase-layout.txt +0 -102
  107. data/notes/knife-cluster-commands.md +0 -21
  108. data/notes/named-cloud-objects.md +0 -11
  109. data/notes/opscode_org_key.png +0 -0
  110. data/notes/opscode_user_key.png +0 -0
  111. data/notes/philosophy.md +0 -13
  112. data/notes/rake_tasks.md +0 -24
  113. data/notes/renamed-recipes.txt +0 -142
  114. data/notes/silverware.md +0 -85
  115. data/notes/style_guide.md +0 -300
  116. data/notes/tips_and_troubleshooting.md +0 -92
  117. data/notes/walkthrough-hadoop.md +0 -168
  118. data/notes/walkthrough-web.md +0 -166
  119. data/spec/fixtures/gunbai.rb +0 -24
  120. data/spec/test_config.rb +0 -20
  121. data/tasks/chef_config.rake +0 -38
@@ -1,66 +0,0 @@
1
- While the refactoring that lead to version 4 was intended to be as backwards compatible as possible, there have been some small but important changes to the way homebases and the DSL work.
2
-
3
- ## Bundler
4
- Ironfan v4 uses bundler to manage its dependencies. In order to take advantage of it, the homebase's Gemfile should be updated to use ```gem 'ironfan', "~> 4.0"```
5
-
6
- We highly recommend that you run all your knife commands via bundle exec. This can be accomplished with an alias:
7
- ```
8
- knife() {
9
- bundle exec knife "$@"
10
- }
11
- ```
12
-
13
- If you are comfortable with having bundle run every knife command (e.g. - you only have one homebase, or are using a Ironfan > 3.1.6 for all homebases you do use), you can add the above snippet to your .bashrc.
14
-
15
- ## Vagrant
16
- Vagrant support has been discontinued for the time being. One of the first targets for the multicloud capabilities of Ironfan v4 will be a Virtualbox or Vagrant extension.
17
-
18
- ## DSL Changes
19
- ### Role implications removed
20
- In v3, certain roles could trigger further steps via role_implications.rb, which was used to add servers to corresponding EC2 Security Groups. This was deemed to be too risky and indirect, and has been removed for now. (A better mechanism for binding roles and provider-specific resources into repeatable components is being worked on.)
21
-
22
- If you used any of the roles below, you will probably want to add the following stanzas next to them in the clusters file, to replace the removed implications. **Be aware that EC2 instances can only be added to a security group at startup; if you fail to add the security groups before launch, you will have to kill and relaunch the machines to change them.**
23
-
24
- * `role :systemwide`
25
- ```
26
- cloud(:ec2).security_group :systemwide
27
- ```
28
- * `role :nfs_server`
29
- ```
30
- cloud(:ec2).security_group(:nfs_server).authorize_group :nfs_client
31
- ```
32
- * `role :nfs_client`
33
- ```
34
- cloud(:ec2).security_group :nfs_client
35
- ```
36
- * `role :ssh`
37
- ```
38
- cloud(:ec2).security_group(:ssh).authorize_port_range 22..22
39
- ```
40
- * `role :chef_server`
41
- ```
42
- cloud(:ec2).security_group :chef_server do
43
- authorize_port_range 4000..4000 # chef-server-api
44
- authorize_port_range 4040..4040 # chef-server-webui
45
- end
46
- ```
47
- * `role :web_server`
48
- ```
49
- cloud(:ec2).security_group("#{self.cluster_name}-web_server") do
50
- authorize_port_range 80..80
51
- authorize_port_range 443..443
52
- end
53
- ```
54
- * `role :redis_server`
55
- ```
56
- cloud(:ec2).security_group("#{self.cluster_name}-redis_server") do
57
- authorize_group("#{self.cluster_name}-redis_client")
58
- end
59
- ```
60
- * `role :redis_client`
61
- ```
62
- cloud(:ec2).security_group("#{self.cluster_name}-redis_client")
63
- ```
64
-
65
- ### Default statements removed
66
- Defaults should not need to be selected, and have been removed as a statement from the cluster DSL (in both cluster and volume). Although this is a non-breaking change, it has been flagged to raise a halting error, to alert people to the role_implications change above (which lacks well-defined indicators of its usage).
@@ -1,16 +0,0 @@
1
- ### Set up Knife on your local machine, and a Chef Server in the cloud
2
-
3
- If you already have a working chef installation you can skip this section.
4
-
5
- To get started with knife and chef, follow the "Chef Quickstart,":http://wiki.opscode.com/display/chef/Quick+Start We use the hosted chef service and are very happy, but there are instructions on the wiki to set up a chef server too. Stop when you get to "Bootstrap the Ubuntu system" -- cluster chef is going to make that much easier.
6
-
7
- * [Launch Cloud Instances with Knife](http://wiki.opscode.com/display/chef/Launch+Cloud+Instances+with+Knife)
8
- * [EC2 Bootstrap Fast Start Guide](http://wiki.opscode.com/display/chef/EC2+Bootstrap+Fast+Start+Guide)
9
-
10
- ### Auto-vivifying machines (no bootstrap required!)
11
-
12
- On EC2, you can make a machine that auto-vivifies -- no bootstrap necessary. Burn an AMI that has the `config/client.rb` file in /etc/chef/client.rb. It will use the ec2 userdata (passed in by knife) to realize its purpose in life, its identity, and the chef server to connect to; everything happens automagically from there. No parallel ssh required!
13
-
14
- ### EBS Volumes
15
-
16
- Define a `snapshot_id` for your volumes, and set `create_at_launch` true.
Binary file
Binary file
@@ -1,11 +0,0 @@
1
- Cookbook Versioning and Tracking
2
- ================================
3
-
4
- @temujin9 please complete and correct
5
-
6
- * git tag labels the *release* of a cookbook version: tag 'cookbooks-elasticsearch-3.1.7' denotes the *last* commit to that tag.
7
- * The next commit will be the one that bumps the version number: the `metadata.rb` will then read '3.1.8'.
8
-
9
- Periodically, we will release a 'gold' version set and push those to the opscode cookbook community site.
10
-
11
- *
@@ -1,200 +0,0 @@
1
- # Ironfan Core Concepts
2
-
3
- <a name="TOC"></a>
4
-
5
- * [Build your architecture from clusters of cooperating machines](#clusters)
6
-
7
- * [Decoupled *Components* connect](#components)
8
-
9
- * [Components *Announce* their capabilities](#announcements)
10
-
11
- * [Announcements enable *Service Discovery*](#discovery)
12
-
13
- * [Components announce cross-cutting *Aspects*](#aspects)
14
-
15
- * [Aspects enable zero-conf *Amenities*](#amenities) -
16
-
17
- * [Announcements effectively define a component's *Contract*](#contract)
18
-
19
- * [Contracts enable zero-conf *specification testing*](#specs)
20
-
21
- * [Specs + monitoring enable zero-conf *integration testing*](#ci)
22
-
23
- * [Systems *Bind* to provisioned resources](#binding)
24
-
25
- * [Binding declarations enable *Resource Sharing*](#resource-sharing)
26
-
27
- <a name="overview"></a>
28
- ### Overview
29
-
30
- Ironfan is your system diagram come to life. In ironfan, you use Chef to assemble and configure components on each machine. Ironfan assembles those machines into clusters -- a group of machines united to provide an important service. For example, at Infochimps one cluster of machines serves the webpages for infochimps.com; another consists only of elasticsearch machines to power our API; and another runs the lightweight goliath proxies that implement our API. Our data scientists are able to spin up and shut down terabyte-scale hadoop clusters in minutes. All this is supported by an Ops team of one -- who spends most of his time hacking on Ironfan.
31
-
32
- The powerful abstractions provided by Chef and Ironfan enables an autowiring system diagram, inevitable best practices in the form of "amenities", and a readable, testable contract for each component in the stack.
33
-
34
- <a name="clusters"></a><a name="facets"></a>
35
- ### Clusters and Facets
36
-
37
- A `cluster`, as mentioned, groups a set of machines around a common purpose. Within that cluster, you define `facet`s: a set of servers with identical components (and nearly identical configuration).
38
-
39
- For example, a typical web stack cluster might have these facets:
40
-
41
- * `webnode`s: nginx reverse-proxies requests to a pool of unicorns running Rails
42
- * `mysql`: one or many MySQL servers, with attached persistent storage
43
- * `qmaster`s: a redis DB and resque front end to distribute batch-processing tasks
44
- * `qworkers`s: resque worker processes
45
-
46
- <a name="components"></a>
47
- ### Components
48
-
49
- As you can see, the details of a machine largely follow from the list its `component`s: `mysql_server`, `resque_dashboard`, and so forth. What's a component? If you would draw it in a box on your system diagram, want to discover it from elsewhere, or it it forms part of the contract for your machine, it's a component.
50
-
51
- Some systems have more than one component: the `ganglia` monitoring system has a component named `agent` to gather operating metrics, and a component named `master` to aggregate those metrics.
52
-
53
- Those examples all describe daemon processes that listen on ports, but component is more general that that -- it's any isolatable piece of functionality that is interesting to an outside consumer. Here is a set of example systems we'll refer to repeatedly:
54
-
55
- * *Ganglia*, a distributed system monitoring tool. The `agent` components gather and exchange system metrics, and the `master` component aggregates them. A basic setup would run the `master` component on a single machine, and the `agent` component on many machines (including the master). In order to work, the master must discover all agents, and each agent must discover the master.
56
-
57
- * *Elasticsearch* is a powerful distributed document database. A basic setup runs a single `server` component on each machine. Elasticsearch handles discovery, but needs a stable subset of them to declare as discovery `seed`s.
58
-
59
- * *Nginx* is a fast, lightweight webserver (similar to apache). Its `server` component can proxy web requests for one or many web apps. Those apps register a `site` component, which defines the receiving address (public/private/local), how the app connects to nginx (socket, port, files).
60
-
61
- * *Pig* is a Big Data analysis tool that works with Hadoop, Elasticsearch and more. It provides an executable, and imports jars from hadoop, elasticsearch and others.
62
-
63
- <a name="announcements"></a>
64
- ### Components *Announce* their capabilities
65
-
66
- Notice the recurring patterns: *capabilities* (serve webpages, execute script, send metrics, answer queries), *handles* (ip+port, jars, swarm), *aspects* (ports, daemons, logs, files, dashboards).
67
-
68
- The Silverware cookbook lets your services `announce` their capabilities and `discover` other resources.
69
-
70
- Chef cookbooks describe the related components that form a system. You should always have a recipe, separate from the `default` recipe, that clearly corresponds to the component: the `ganglia` cookbook has `master` and `agent` recipes; the `pig` cookbook has `install_from_package` and `install_from_release` recipes. Those recipes are grouped together into Chef roles that encapsulate the component: the `elasticsearch_server` role calls the recipes to install the software, start the daemon process, and write the config files, each in the correct order.
71
-
72
- Cookbooks do *not* bake in assumptions about their scale or about the machine they're on. The same Elasticsearch cookbook can deploy a tiny little search box to sit next to a web app, or one server in a distributed terabyte scale database.
73
-
74
- <a name="discovery"></a>
75
- ### Announcements enable *Service Discovery*
76
-
77
- The `discover` and `discover_all` connect decoupled components. Your systems
78
-
79
- * Don't care whether the discovered components are on the same machine, different machines, or a remote data center.
80
- * Don't care about the number of underlying machines -- the whole thing might run on your laptop while developing, across a handful of nodes in staging, and on dozens of nodes in production.
81
- * Don't necessarily care about the actual system -- your load balancer doesn't care whether it's nginx or apache or anything else, it just wants to discover the correct set of `webnode`s.
82
-
83
- <a name="aspects"></a>
84
- ### Components announce cross-cutting *Aspects*
85
-
86
- Besides the component's capabilities, the announcement also describes its aspects: cross-cutting attributes common to many components.
87
-
88
- * **log**: write data to a log file.
89
- * **daemon**: long-running process. Can specify run state, resource bounds, etc.
90
- * **port**: serves data over a port. Can specify the protocol, performance expectations, etc.
91
- * **dashboard**: HTML, JMX, etc -- internal component metrics and control
92
- * **executable**: executes scripts
93
- * **export**: libraries, `jar`s, `conf` files, etc
94
- * **consumes**: registered whenever you `discover` another component
95
-
96
- <a name="amenities"></a>
97
- ### Aspects enable zero-conf *Amenities*
98
-
99
- Typically, consumers discover their provider, and the provider is unconcerned with which consumers it attends to. Ironfan lets you invert this pattern: decoupled `amenities` find components they can cater to.
100
-
101
- * A log aspect would enable the following amenities
102
- - `logrotated` to intelligently manage its logs
103
- - `flume` to archive logs to a predictable location
104
- - If the log is known to be an apache web log, a flume decorator can track rate and duration of requests and errors.
105
- * A port aspect would enable
106
- - zeroconf configuration of firewall and security groups
107
- - remote monitors to regularly pinging the port for uptime and latency
108
- - and pings the interfaces that it should *not* appear on to ensure the firewall is in place?
109
-
110
- <a name="contracts"></a>
111
- ### Announcements effectively define a component's *Contract*
112
-
113
- The announcements that components make don’t just facilitate discovery. In a larger sense, they describe the external contract for the component.
114
-
115
- When `nginx` announces that it listens on `node[:nginx][:http_port] = 80`, it is promising a capability (namely, that http requests to that port return certain results). When elasticsearch announces that it runs the `elasticsearch` daemon, it promised that the daemon will be running, with the right privileges, and not consuming more than its fair share of resources.
116
-
117
- <a name="specs"></a>
118
- ### Contracts enable zero-conf *Specification Testing*
119
-
120
-
121
-
122
- * A daemon aspect
123
- - implies a process should be running
124
- - owned by the right user
125
- - with a stable PID
126
- - and live within defined memory bounds
127
- * A log aspect
128
- - should be open and receiving content from the process
129
- - should contain lines showing successful startup (and not contain lines matching an error).
130
- * A dashboard/JMX/metrics aspect:
131
- - actual configuration settings as read out of the running app should match those drawn from the node attributes. No more finding out a setting was overridden by some hidden config file.
132
- - should have a healthy heartbeat and status
133
-
134
- [Ironfan-CI](http://github.com/infochimps-labs/ironfan-ci) uses the announcement to create a suite of detailed [Cucumber](http://cukes.info) (via [Cuken](https://github.com/hedgehog/cuken)) feature tests that document and enforce the machine's contract. You're not limited to just the zeroconf tests: it's easy to drop in additional cucumber specs.
135
-
136
- Ironfan-CI is young -- it's for the tenacious zealot only -- but is the subject of current work and developing fast.
137
-
138
- <a name="ci"></a>
139
- ### Specs + Monitoring enable zero-conf *Full-stack Testing*
140
-
141
- You can now look at monitoring as the equivalent of a full-stack continuous integration test suite. The same announcement that Ironfan-CI maps into cucumber statements can as well drive your favorite monitoring suite (or more likely, the monitoring suite you hate the least).
142
-
143
- The Ironfan Enterprise product ships with Zabbix, which is actually pretty loveable -- even moreso when you don't have to perform fiddly repeated template definitions.
144
-
145
- <a name="binding"></a>
146
- ### Systems *Bind* to provisioned resources
147
-
148
- Components should adapt to their machine, but be largely unaware of its defaul arrangement. One common anti-pattern we see in many cookbooks is to place data at some application-specific absolute path, to assume a certain layout of volumes.
149
-
150
- When my grandmother comes to visit, she quite reasonably asks for a room with a comfortable bed and a short climb. This means that at my apartment, she stays in the main bedroom and I use the couch. At my brother's house, she stays in the downstairs guest room, while my brother and sister-in-law stay in their bedroom.
151
-
152
- Suppose Grandmom instead always chose 'the master bedroom on the first floor' no matter how the house was set up. At my apartment, she'd find herself in the parking garage. At my brother's house, she'd find herself in a crowded bed and uninvited from returning to visit.
153
-
154
- Similarly, the well-mannered cookbook does not hard-code a large data directory onto the root partition. The root drive is the private domain of the operating system; typically, there's a large and comfortably-appointed volume just for it to use. On the other hand, hard-coding a location of `/mnt/external2` will end in tears if I'm testing the cookbook on my laptop, where no such drive exists.
155
-
156
- The solution is to request for volumes by their characteristics, and defer to the machine's best effort in meeting that request.
157
-
158
- # Data striped across all persistent dirs
159
- volume_dirs('foo.datanode.data') do
160
- type :persistent, :bulk, :fallback
161
- selects :all
162
- mode "0700"
163
- end
164
-
165
- # Scratch space for indexing, striped across all scratch dirs
166
- volume_dirs('foo.indexer.journal') do
167
- type :fast, local, :bulk, :fallback
168
- selects :first
169
- mode "0755"
170
- end
171
-
172
- Another example of this is binding to a network interface. Unfortunately most cookbooks choose the primary address; most of ours choose the 'private' interface if any and fall back to the primary.
173
-
174
- The right pattern here is
175
- * provisioners tag resources
176
- * cookbooks to request the best match to their purpose
177
- * at the cookbook's option, if no good match is found use a fallback or raise an exception
178
-
179
- <a name="resource-sharing"></a>
180
- ### Binding declarations enable *Resource Sharing*
181
-
182
- Resource sharing is yet another place where an assertive announcement can enable best practices.
183
-
184
- Right now, most java-based components hard-code a default JVM heap size. This can lead to a situation where a component shows up on a 16GB machine with 1GB heap allocated, or where five components show up on a 0.7GB machine each with 1GB allocated.
185
-
186
- We instead deserve a deft but highly predictable way to apportion resources (disks, ram, etc). Nothing that gets in the way of explicit tuning, but one which gives a reasonable result in the default case.
187
-
188
- The Hadoop cookbook has an initial stab at this, but for the most part Resource Sharing is on the roadmap but not yet in place.
189
-
190
-
191
- __________________________________________________________________________
192
-
193
- ### Learn More
194
-
195
- [Aspect-Oriented Programming](http://en.wikipedia.org/wiki/Aspect-oriented_programming): The Ironfan concept of `aspects` as cross-cutting concerns is taken from AOP. Amenities don't correspond precisely to join cuts etc., so don't take the analogy too far. (Or perhaps instead help us understand how to take the analogy the rest of the way.)
196
-
197
-
198
- Ironfan's primary models form a component-based approach to building a [Service-Oriented Architecture](http://msdn.microsoft.com/en-us/library/aa480021.aspx). Model examples of a modern SOA include the [Netflix API](http://www.slideshare.net/danieljacobson/the-futureofnetflixapi) (see [also](http://techblog.netflix.com/2011/12/making-netflix-api-more-resilient.html)) and [Postrank](http://www.igvita.com/2011/03/08/goliath-non-blocking-ruby-19-web-server/) (see [also](http://www.igvita.com/2010/01/28/cluster-monitoring-with-ganglia-ruby/)).
199
-
200
-
@@ -1,3 +0,0 @@
1
-
2
- Please see the [README from the volumes cookbook](https://github.com/infochimps-labs/ironfan-pantry/blob/master/cookbooks/volumes/README.md) for more information.
3
-
@@ -1,36 +0,0 @@
1
-
2
- Examples of concerns that tend to be crosscutting include:
3
-
4
- Synchronization -- (declare an action dependency, trigger, event)
5
- Real-time constraints
6
- Feature interaction
7
- Memory management
8
- - data checks
9
- - feature checks
10
- * security
11
- - firewall rules
12
- - access control
13
- Logging
14
- Monitoring
15
- Business rules
16
- Tuning
17
- Refactor pivot
18
-
19
-
20
- AOP:
21
-
22
- - Scattered (1:n) / Tangled (n:1)
23
- - join point: hook
24
- - point cut: matches join points
25
- - advice: behavior evoked at point cut
26
-
27
- * Interception
28
- - Interjection of advice, at least around methods.
29
- * Introduction
30
- - Enhancing with new (orthogonal!) state and behavior .
31
- * Inspection
32
- - Access to meta-information that may be exploited by pointcuts or
33
- advice.
34
- * Modularization
35
- - Encapsulate as aspects.
36
-
@@ -1,169 +0,0 @@
1
-
2
-
3
- https://github.com/acrmp/chefspec
4
-
5
-
6
- pre-testing -- converge machine
7
- https://github.com/acrmp/chefspec
8
-
9
- http://wiki.opscode.com/display/chef/Knife#Knife-test
10
-
11
- benchmarks
12
-
13
- bonnie++
14
- hdparm -t
15
- iozone
16
-
17
-
18
- in-machine
19
-
20
- * x ports on x interfaces open
21
- * daemon is running
22
- * file exists and has string
23
-
24
- * log file is accumulating lines at rate X
25
- * script x runs successfully
26
-
27
- in-chef
28
-
29
- * runlist is X
30
- * chef attribute X should be Y
31
-
32
- meta
33
-
34
- * chef run was idempotent
35
-
36
-
37
-
38
-
39
-
40
- __________________________________________________________________________
41
-
42
- ## Notes from around the web
43
-
44
-
45
- * ...
46
-
47
- > I'm thinking that the useful thing to test is NOT did chef install
48
- > some package or setup a user, but rather after chef has run can I
49
- > interact with the system as I would expect from an external
50
- > perspective. For example:
51
- >
52
- > * Is the website accessible?
53
- > * Are unused ports blocked?
54
- > * When I send an email thorough the website does it end up in my inbox?
55
- >
56
- > Capybara (http://github.com/jnicklas/capybara) enforces this external
57
- > perspective for webapp testing:
58
- >
59
- > "Access to session, request and response from the test is not
60
- > possible. Maybe we’ll do response headers at some point in the future,
61
- > but the others really shouldn’t be touched in an integration test
62
- > anyway. "
63
- >
64
- > They only let you interact with screen elements that a user could
65
- > interact with. It makes sense because the things that users interact
66
- > with are what provides the business value
67
-
68
- * Andrew Shafer < andrew@cloudscaling.com>
69
-
70
- > Here's my thinking at this point... which could be wrong on every level.
71
- > There is really no good way to TDD/BDD configuration management for several
72
- > reasons:
73
- > The recipes are already relatively declarative
74
- > Mocking is useless because it may not reflect 'ground truth'
75
- > The cycle times to really test convergence are relatively long
76
- > Trying to test if a package is installed or not is testing the framework,
77
- > not the recipe IMHO.
78
- > I agree with the general sentiment that the functional service is the true
79
- > test.
80
- > I'm leaning towards 'testing' at that level, ideally with (a superset of?)
81
- > what should be used for the production monitoring system.
82
- > So the CI builds services, runs all the checks in test, green can go live
83
- > and that's that.
84
-
85
-
86
- * Jeremy Deininger < jeremy@rightscale.com>
87
-
88
- > Thought I'd chime in with my experience testing system configuration code @ RightScale so far. What we've been building are integration style cucumber tests to run a cookbook through it's paces on all platforms and OSs that we support.
89
- > First we use our API to spin up 'fresh' server clusters in EC2, one for every platform/OS (variation) that the cookbook will be supporting. The same could be done using other cloud APIs (anyone else doing this with VMware or etc?) Starting from scratch is important because of chef's idempotent nature.
90
- > Then a cucumber test is run against every variation in parallel. The cucumber test runs a series of recipes on the cluster then uses what we call 'spot checks' to ensure the cluster is configured and functional. The spot checks are updated when we find a bug, to cover the bug. An example spot check would be, sshing to every server and checking the mysql.err file for bad strings.
91
- > These high level integration tests are long running but have been very useful flushing out bugs.
92
- > ...
93
- > If you stop by the #rightscale channel on Freenode I'd be happy to embarrass myself by giving you a sneak peak at the features etc.. Would love to bounce ideas around and collaborate if you're interested. jeremydei on Freenode IRC
94
-
95
- Ranjib Dey < ranjibd@th...s.com>
96
-
97
- > So far, what we've done for testing is to use rspec for implementing tests. Here's an example:
98
- >
99
- > it "should respond on port 80" do
100
- > lambda {
101
- > TCPSocket.open(@server, 'http')
102
- > }.should_not raise_error
103
- > end
104
- >
105
- > Before running the tests, I have to manually bootstrap a node using knife. If my instance is the only one in its environment, the spec can find it using knife's search feature. The bootstrap takes a few minutes, and the 20 or so tests take about half a minute to run.
106
- >
107
- > While I'm iteratively developing a recipe, my work cycle is to edit source, upload a cookbook, and rerun chef-client (usually by rerunning knife boostrap, because the execution environment is different from invoking chef-client directly). This feels a bit slower than the cycle I'm used to when coding in Ruby because of the upload and bootstrap steps.
108
- >
109
- > I like rspec over other testing tools because of how it generates handy reports, such as this one, which displays an English list of covered test cases:
110
- >
111
- > $ rspec spec/ -f doc
112
- >
113
- > Foo role
114
- > should respond on port 80
115
- > should run memcached
116
- > should accept memcached connections
117
- > should have mysql account
118
- > should allow passwordless sudo to user foo as user bar
119
- > should allow passwordless sudo to root as a member of sysadmin
120
- > should allow key login as user bar
121
- > should mount homedirs on ext4, not NFS
122
- > should rotate production.log
123
- > should have baz as default vhost
124
- > ...
125
- >
126
- > That sample report also gives a feel for sort of things we check. So far, nearly all of our checks are non-intrusive enough to run on a production system. (The exception is testing of local email delivery configurations.)
127
- >
128
- > Areas I'd love to see improvement:
129
- >
130
- > * Shortening the edit-upload-bootstrap-test cycle
131
- > * Automating the bootstrap in the context of testing
132
- > * Adding rspec primitives for Chef-related testing, which might
133
- > include support for multiple platforms
134
- >
135
- > As an example of rspec primitives, instead of:
136
- >
137
- > it "should respond on port 80" do
138
- > lambda {
139
- > TCPSocket.open(@server, 'http')
140
- > }.should_not raise_error
141
- > end
142
- >
143
- > I'd like to write:
144
- >
145
- > it { should respond_on_port(80) }
146
- >
147
- > Rspec supports the the syntactic sugar; it's just a matter of adding some "matcher" plugins.
148
- >
149
- > How do other chef users verify that recipes work as expected?
150
- >
151
- > I'm not sure how applicable my approach is to opscode/cookbooks because it relies on having a specific server configuration and can only test a cookbook in the context of that single server. If we automated the boostrap step so it could be embedded into the rspec setup blocks, it would be possible to test a cookbook in several sample contexts, but the time required to setup each server instance might be prohibitive.
152
- >
153
-
154
-
155
- Andrew Crump < acrump@gmail.com>
156
-
157
- > Integration tests that exercise the service you are building definitely give you the most bang for buck.
158
- >
159
- > We found the feedback cycle slow as well so I wrote chefspec which builds on RSpec to support unit testing cookbooks:
160
- >
161
- > https://github.com/acrmp/chefspec
162
- >
163
- > This basically fakes a convergence and allows you to make assertions about the created resources. At first glance Chef's declarative nature makes this less useful, but once you start introducing conditional execution I've found this to be a time saver.
164
- >
165
- > If you're looking to do CI (which you should be) converging twice goes some way to verifying that your recipes are idempotent.
166
- >
167
- > knife cookbook test is a useful first gate for CI:
168
- >
169
- > http://wiki.opscode.com/display/chef/Knife#Knife-test