Update our boxen template with the latest and greatest
This commit is contained in:
parent
92dd6a9fdb
commit
d4af4bf811
26 changed files with 245 additions and 40 deletions
6
Gemfile
6
Gemfile
|
@ -1,7 +1,9 @@
|
|||
source "http://rubygems.org"
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "boxen", "~> 0.7"
|
||||
gem "boxen", "0.7.3"
|
||||
|
||||
group :development do
|
||||
gem "aws-sdk"
|
||||
gem "net-ssh"
|
||||
gem "rbvmomi"
|
||||
end
|
||||
|
|
21
Gemfile.lock
21
Gemfile.lock
|
@ -1,5 +1,5 @@
|
|||
GEM
|
||||
remote: http://rubygems.org/
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.3.2)
|
||||
ansi (1.4.3)
|
||||
|
@ -7,7 +7,7 @@ GEM
|
|||
json (~> 1.4)
|
||||
nokogiri (>= 1.4.4)
|
||||
uuidtools (~> 2.1)
|
||||
boxen (0.7.1)
|
||||
boxen (0.7.3)
|
||||
ansi (~> 1.4)
|
||||
hiera (~> 1.0.0)
|
||||
highline (~> 1.6)
|
||||
|
@ -15,6 +15,7 @@ GEM
|
|||
librarian-puppet (~> 0.9)
|
||||
octokit (~> 1.15)
|
||||
puppet (~> 3.0)
|
||||
builder (3.1.4)
|
||||
facter (1.6.17)
|
||||
faraday (0.8.5)
|
||||
multipart-post (~> 1.1)
|
||||
|
@ -24,16 +25,17 @@ GEM
|
|||
hiera (1.0.0)
|
||||
highline (1.6.15)
|
||||
json (1.7.6)
|
||||
json_pure (1.7.6)
|
||||
json_pure (1.7.7)
|
||||
librarian-puppet (0.9.7)
|
||||
json
|
||||
puppet
|
||||
thor (~> 0.15)
|
||||
multi_json (1.5.0)
|
||||
multi_json (1.6.0)
|
||||
multipart-post (1.1.5)
|
||||
net-ssh (2.6.5)
|
||||
netrc (0.7.7)
|
||||
nokogiri (1.5.6)
|
||||
octokit (1.22.0)
|
||||
octokit (1.23.0)
|
||||
addressable (~> 2.2)
|
||||
faraday (~> 0.8)
|
||||
faraday_middleware (~> 0.9)
|
||||
|
@ -43,7 +45,12 @@ GEM
|
|||
puppet (3.1.0)
|
||||
facter (~> 1.6)
|
||||
hiera (~> 1.0)
|
||||
rbvmomi (1.6.0)
|
||||
builder
|
||||
nokogiri (>= 1.4.1)
|
||||
trollop
|
||||
thor (0.17.0)
|
||||
trollop (2.0)
|
||||
uuidtools (2.1.3)
|
||||
|
||||
PLATFORMS
|
||||
|
@ -51,4 +58,6 @@ PLATFORMS
|
|||
|
||||
DEPENDENCIES
|
||||
aws-sdk
|
||||
boxen (~> 0.7)
|
||||
boxen (= 0.7.3)
|
||||
net-ssh
|
||||
rbvmomi
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# This file manages Puppet module dependencies.
|
||||
#
|
||||
# It works a lot like Bundler. We provide some core modules by
|
||||
# default. This ensures at least the ability to construct a basic
|
||||
# environment.
|
||||
|
@ -28,7 +30,7 @@ github "inifile", "0.9.0", :repo => "cprice-puppet/puppetlabs-inifile"
|
|||
github "nginx", "0.2.1"
|
||||
github "nodejs", "0.0.2"
|
||||
github "nvm", "0.0.5"
|
||||
github "ruby", "0.5.1"
|
||||
github "ruby", "0.7.1"
|
||||
github "stdlib", "3.0.0", :repo => "puppetlabs/puppetlabs-stdlib"
|
||||
github "sudo", "0.0.1"
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ GITHUBTARBALL
|
|||
GITHUBTARBALL
|
||||
remote: boxen/puppet-ruby
|
||||
specs:
|
||||
ruby (0.5.1)
|
||||
ruby (0.7.1)
|
||||
|
||||
GITHUBTARBALL
|
||||
remote: boxen/puppet-sudo
|
||||
|
@ -74,7 +74,7 @@ DEPENDENCIES
|
|||
nginx (= 0.2.1)
|
||||
nodejs (= 0.0.2)
|
||||
nvm (= 0.0.5)
|
||||
ruby (= 0.5.1)
|
||||
ruby (= 0.7.1)
|
||||
stdlib (= 3.0.0)
|
||||
sudo (= 0.0.1)
|
||||
|
||||
|
|
|
@ -7,9 +7,12 @@ per-user configurations.
|
|||
|
||||
How? The personal manifest.
|
||||
|
||||
## What even is a personal manifest?
|
||||
|
||||
Personal manifests live in `modules/people/manifests/<name>.pp`,
|
||||
where `<name>` is your GitHub username.
|
||||
A basic personal manifest might look like so:
|
||||
|
||||
The simplest personal manifest looks like this:
|
||||
|
||||
``` puppet
|
||||
class people::wfarr {
|
||||
|
@ -17,19 +20,46 @@ class people::wfarr {
|
|||
}
|
||||
```
|
||||
|
||||
Now, each time `wfarr` runs Boxen it'll automatically print out "hello world"
|
||||
somewhere during the run.
|
||||
You can even run `boxen-my-config` to generate a default template for you
|
||||
and open it up in your editor.
|
||||
When you're done, you can simply run `boxen` and it'll include your changes
|
||||
in your personal manifest.
|
||||
**You should always keep your manifest committed and pushed to your repository**.
|
||||
Otherwise, auto-updates won't work!
|
||||
Ah, the good old "Hello World".
|
||||
It's boring, but you can see there's really not much boilerplate involved.
|
||||
Let's try something *real* this time:
|
||||
|
||||
The whole point of these personal manifest are they are _your_ manifest.
|
||||
You shouldn't worry if the things in here are work-related or not.
|
||||
This is about full automation.
|
||||
Want to install Minecraft and Rdio by default?
|
||||
Do it in your personal manifest.
|
||||
``` puppet
|
||||
class people::wfarr {
|
||||
include boxen::development
|
||||
}
|
||||
```
|
||||
|
||||
You can check out the [projects README](../modules/projects/README.md) for further examples.
|
||||
So what does this do?
|
||||
It clones every repo in the Boxen org to `~/src/boxen/<repo>`.
|
||||
How?
|
||||
Well, we can refer to [the source code](https://github.com/boxen/puppet-boxen/blob/master/manifests/development.pp)!
|
||||
If you're new to Puppet, or are unsure of what that class is doing, check out
|
||||
the [intro to puppet](./puppet.md) we've put together.
|
||||
|
||||
## Running different code on multiple machines
|
||||
|
||||
Puppet has conditionals and switching.
|
||||
Typically, the most reliable way to ensure some code runs on one machine but not
|
||||
others is to use the `case` statement on the `hostname` fact.
|
||||
Example:
|
||||
|
||||
``` puppet
|
||||
case $::hostname {
|
||||
'scruffy': {
|
||||
notify { "I'm Scruffy. The Janitor.": }
|
||||
}
|
||||
|
||||
'bender': {
|
||||
notify { "My full name is Bender Bending Rodriguez": }
|
||||
}
|
||||
|
||||
default: {
|
||||
notify { "Wha?": }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
One thing to note here is that Puppet always **requires** a default path
|
||||
on a case statement.
|
||||
Default is equivalent to "anything that isn't matched above".
|
||||
|
|
144
docs/puppet.md
Normal file
144
docs/puppet.md
Normal file
|
@ -0,0 +1,144 @@
|
|||
# wtf is a puppet?
|
||||
|
||||
Puppet is configuration management tool, written in Ruby, that compiles
|
||||
and runs code written in the Puppet language.
|
||||
|
||||
But what does that actually mean in words a human can understand?
|
||||
Puppet is a tool that runs some code and that code can do all sorts of
|
||||
really powerful things to configure computers for you.
|
||||
|
||||
Why do I want code mucking about with my laptop though?
|
||||
For the exact same reasons you want code configuring your server.
|
||||
In particular, homogeneity, reproducibility, reusability, and automation.
|
||||
When you use code to express how a machine should be configured,
|
||||
you know that all of your machines are configured the same way,
|
||||
that you can repeat that configuration any number of times,
|
||||
and that you don't have to do it manually each time.
|
||||
|
||||
## How does Puppet work?
|
||||
|
||||
A Puppet run has two main steps: compilation and application.
|
||||
|
||||
The compilations step starts with reading in what's called the site manifest.
|
||||
The site manifest is a single file that contains Puppet code that is responsible
|
||||
for telling the compiler what other Puppet code it should compile.
|
||||
|
||||
Here are the first few lines of the default site manifest for Boxen:
|
||||
|
||||
```
|
||||
include boxen::environment
|
||||
include homebrew
|
||||
include gcc
|
||||
```
|
||||
|
||||
This tells the Puppet compiler that it must include the classes
|
||||
`boxen::environment`, `homebrew`, and `gcc`.
|
||||
Puppet will look for those classes on the modulepath.
|
||||
Typically, these files would be located at
|
||||
`$modulepath/boxen/manifests/environment.pp` and
|
||||
`$modulepath/homebrew/manifests/init.pp`.
|
||||
|
||||
These might include other classes as well, or define **resources**.
|
||||
Resources are the building blocks of Puppet.
|
||||
A resource is an abstract description about a **thing** and the **state**
|
||||
that thing should be in.
|
||||
Every resource has a **type**, which is just a classification of resources.
|
||||
For example, we might have a resource `Package[mysql]` and its type would be
|
||||
`Package`.
|
||||
Puppet also supports multiple providers for types which act as pluggable
|
||||
backends depending on the operating system it's running on or the tools
|
||||
available on a particular system (in the case of the `Package` type,
|
||||
we might have providers for `yum` and for `aptget`).
|
||||
|
||||
So now the Puppet compiler has finished tracking down and loading all the
|
||||
classes and resources it needs.
|
||||
Assuming we haven't encountered any compile-time errors, Puppet then begins
|
||||
the next phase of a run: applying the catalog.
|
||||
|
||||
All of the resources Puppet has collected into the catalog have formed a
|
||||
DAG (directed, acyclic graph) that represents the order in which all these
|
||||
resources can be applied in a correct order.
|
||||
Puppet simply grabs the first "node" in this graph and traverses all nodes
|
||||
in the graph, applying each resource as it goes.
|
||||
|
||||
Application of an individual resource starts with Puppet asking "is this
|
||||
resource in the state requested?" If the answer is yes, Puppet moves onto the
|
||||
next node and repeats this process. If the answer is no, Puppet will make
|
||||
whatever changes it can to reconcile the current state of the resource with
|
||||
what it should be, and then continues on.
|
||||
|
||||
Once all resources have been applied, the Puppet run is complete.
|
||||
|
||||
## Declarative by nature
|
||||
|
||||
One of the most confusing parts of the Puppet language to many newcomers is
|
||||
how the Puppet catalog orders and applies resources.
|
||||
The key thing to remember is that Puppet is a **declarative** language rather
|
||||
than a procedural one.
|
||||
In human words, the only order that matters in Puppet is order specified by
|
||||
relationships between resources.
|
||||
|
||||
Here's an example of how someone new to Puppet might write a class:
|
||||
|
||||
``` puppet
|
||||
class mysql {
|
||||
file { '/etc/my.cnf': source => 'puppet:///modules/mysql/my.cnf.erb' ; }
|
||||
package { 'mysql': }
|
||||
service { 'mysql': }
|
||||
}
|
||||
```
|
||||
|
||||
Someone expecting Puppet to be procedural would read this manifest as a list
|
||||
saying:
|
||||
|
||||
* First create the my.cnf file
|
||||
* Then install the mysql package
|
||||
* Then start the mysql service
|
||||
|
||||
The problem is, they would be **wrong**.
|
||||
There is no guarantee Puppet will apply these resources in that order,
|
||||
and it's quite likely that it won't.
|
||||
|
||||
The proper way to ensure ordering in Puppet is to use one of the four
|
||||
**relationship metaparameters**:
|
||||
|
||||
* before - Run this resource before another resource
|
||||
* notify - Same as before, but triggers a refresh on that resource
|
||||
* require - Run this resource after another resource
|
||||
* subscribe - Same as require, but triggers a refresh on that resource
|
||||
|
||||
The behavior of these metaparameters should be pretty clear.
|
||||
Triggering a resource simply means that a resource will "refresh" itself.
|
||||
That typically means something like a `Service` resource restarting itself.
|
||||
It's important to remember that these metaparameters are valid on **any** resource.
|
||||
|
||||
So, let's rewrite our example properly:
|
||||
|
||||
``` puppet
|
||||
class mysql {
|
||||
file { '/etc/my.cnf':
|
||||
source => 'puppet:///modules/mysql/my.cnf.erb',
|
||||
notify => Service['mysql']
|
||||
}
|
||||
|
||||
package { 'mysql':
|
||||
notify => Service['mysql']
|
||||
}
|
||||
|
||||
service { 'mysql': }
|
||||
}
|
||||
```
|
||||
|
||||
Now we're telling Puppet what order to apply these resources in:
|
||||
|
||||
* Make sure /etc/my.cnf is in place before we start the mysql service
|
||||
* If /etc/my.cnf changes, tell mysql to restart
|
||||
* Make sure the mysql package is in place before we start the mysql service
|
||||
* If the mysql package changes, tell mysql to restart
|
||||
|
||||
It's important to note that we didn't tell Puppet if `File[/etc/my.cnf]`
|
||||
should come before or after `Package[mysql]`.
|
||||
This is intentional.
|
||||
Most package managers won't overwrite a configuration file that already exists
|
||||
at package install-time, so in this case, we can assume installing the mysql
|
||||
package won't clobber our custom `/etc/my.cnf` file.
|
|
@ -18,11 +18,11 @@ class projects::rails_app {
|
|||
include phantomjs
|
||||
|
||||
boxen::project { 'rails_app':
|
||||
source => 'mycompany/rails_app',
|
||||
ruby => '1.9.3',
|
||||
mysql => true,
|
||||
redis => true,
|
||||
nginx => true,
|
||||
source => 'username/rails_app'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require boxen::environment
|
||||
require homebrew::repo
|
||||
require homebrew
|
||||
require gcc
|
||||
|
||||
Exec {
|
||||
group => 'staff',
|
||||
|
@ -8,6 +9,8 @@ Exec {
|
|||
|
||||
path => [
|
||||
"${boxen::config::home}/rbenv/shims",
|
||||
"${boxen::config::hime}/rbenv/bin",
|
||||
"${boxen::config::hime}/rbenv/plugins/ruby-build/bin",
|
||||
"${boxen::config::home}/homebrew/bin",
|
||||
'/usr/bin',
|
||||
'/bin',
|
||||
|
@ -16,7 +19,7 @@ Exec {
|
|||
],
|
||||
|
||||
environment => [
|
||||
"HOMEBREW_CACHE=${homebrew::cachedir}",
|
||||
"HOMEBREW_CACHE=${homebrew::config::cachedir}",
|
||||
"HOME=/Users/${::luser}"
|
||||
]
|
||||
}
|
||||
|
@ -43,6 +46,8 @@ Service {
|
|||
provider => ghlaunchd
|
||||
}
|
||||
|
||||
Homebrew::Formula <| |> -> Package <| |>
|
||||
|
||||
node default {
|
||||
# core modules, needed for most things
|
||||
include dnsmasq
|
||||
|
|
|
@ -13,10 +13,7 @@ set -e
|
|||
rm -rf .bundle/config
|
||||
rm -rf .librarian/puppet/config
|
||||
|
||||
# Export CC to explicitly set the compiler used for cexts.
|
||||
|
||||
export CC=gcc
|
||||
|
||||
# Bundle install unless we're already up to date.
|
||||
|
||||
export PATH=$(pwd)/vendor/shims:$PATH
|
||||
bundle install --binstubs bin --path .bundle --quiet "$@"
|
||||
|
|
|
@ -19,6 +19,6 @@ unless File.exist? path
|
|||
end
|
||||
end
|
||||
|
||||
exec(editor, path) if editor && system("tty -s")
|
||||
exec(editor, path) if editor && system("test -t 1")
|
||||
|
||||
puts path
|
||||
|
|
24
script/nuke
24
script/nuke
|
@ -14,11 +14,13 @@ services = false
|
|||
OptionParser.new do |o|
|
||||
o.banner = "Remove most traces of Boxen from your machine."
|
||||
|
||||
o.on("--all", "Remove everything possible.") { all = true }
|
||||
o.on("--force", "Actually do it.") { force = true }
|
||||
o.on("--help", "Show this help.") { abort o.to_s }
|
||||
o.on("--opt", "Remove /opt/boxen.") { opt = true }
|
||||
o.on("--services", "Remove and unload services.") { services = true }
|
||||
o.on("--all", "Remove everything possible.") { all = true }
|
||||
o.on("--force", "Actually do it.") { force = true }
|
||||
o.on("--help", "Show this help.") { abort o.to_s }
|
||||
o.on("--opt", "Remove /opt/boxen.") { opt = true }
|
||||
o.on("--services", "Remove and unload services.") { services = true }
|
||||
o.on("--receipts", "Remove package receipts used by Puppet.") { receipts = true }
|
||||
o.on("--gitconfig", "Remove Boxen-provided git credential helper config.") { gitconfig = true }
|
||||
|
||||
o.parse!
|
||||
|
||||
|
@ -31,7 +33,7 @@ end
|
|||
|
||||
if all || services
|
||||
boxen_services = []
|
||||
boxen_services << Dir["/Library/Launch*/com.boxen.*.plist"]
|
||||
boxen_services << Dir["/Library/Launch*/dev.*.plist"]
|
||||
|
||||
boxen_services.flatten.each do |plist|
|
||||
warn "-> Removing #{plist}."
|
||||
|
@ -49,3 +51,13 @@ if all || opt
|
|||
warn "-> Removing /opt/boxen."
|
||||
system "rm", "-rf", "/opt/boxen" if force
|
||||
end
|
||||
|
||||
if all || receipts
|
||||
warn "-> Removing /var/db/.puppet_*."
|
||||
system "rm", "-rf", "/var/db/.puppet_*" if force
|
||||
end
|
||||
|
||||
if all || gitconfig
|
||||
warn "-> Removing git credential helper config."
|
||||
system "/usr/bin/git", "config", "--global", "--unset", "credential.helper"
|
||||
end
|
||||
|
|
BIN
vendor/cache/boxen-0.7.1.gem
vendored
BIN
vendor/cache/boxen-0.7.1.gem
vendored
Binary file not shown.
BIN
vendor/cache/boxen-0.7.3.gem
vendored
Normal file
BIN
vendor/cache/boxen-0.7.3.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/builder-3.1.4.gem
vendored
Normal file
BIN
vendor/cache/builder-3.1.4.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/json_pure-1.7.6.gem
vendored
BIN
vendor/cache/json_pure-1.7.6.gem
vendored
Binary file not shown.
BIN
vendor/cache/json_pure-1.7.7.gem
vendored
Normal file
BIN
vendor/cache/json_pure-1.7.7.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/multi_json-1.5.0.gem
vendored
BIN
vendor/cache/multi_json-1.5.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/multi_json-1.6.0.gem
vendored
Normal file
BIN
vendor/cache/multi_json-1.6.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/net-ssh-2.6.5.gem
vendored
Normal file
BIN
vendor/cache/net-ssh-2.6.5.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/octokit-1.22.0.gem
vendored
BIN
vendor/cache/octokit-1.22.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/octokit-1.23.0.gem
vendored
Normal file
BIN
vendor/cache/octokit-1.23.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/rbvmomi-1.6.0.gem
vendored
Normal file
BIN
vendor/cache/rbvmomi-1.6.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/trollop-2.0.gem
vendored
Normal file
BIN
vendor/cache/trollop-2.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/puppet/cache/boxen-puppet-ruby-0.5.1.tar.gz
vendored
BIN
vendor/puppet/cache/boxen-puppet-ruby-0.5.1.tar.gz
vendored
Binary file not shown.
BIN
vendor/puppet/cache/boxen-puppet-ruby-0.7.1.tar.gz
vendored
Normal file
BIN
vendor/puppet/cache/boxen-puppet-ruby-0.7.1.tar.gz
vendored
Normal file
Binary file not shown.
4
vendor/shims/xcrun
vendored
Executable file
4
vendor/shims/xcrun
vendored
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
# A noop xcrun for initial Boxen runs.
|
||||
|
||||
exec "$@"
|
Loading…
Reference in a new issue