├── lib └── .gitkeep ├── .ruby-version ├── vendor ├── puppet │ ├── cache │ │ ├── .gitkeep │ │ ├── boxen-puppet-gcc-2.0.1.tar.gz │ │ ├── boxen-puppet-git-1.2.5.tar.gz │ │ ├── boxen-puppet-hub-1.0.3.tar.gz │ │ ├── boxen-puppet-nvm-1.0.0.tar.gz │ │ ├── boxen-puppet-ruby-6.3.4.tar.gz │ │ ├── boxen-puppet-sudo-1.0.0.tar.gz │ │ ├── boxen-puppet-boxen-3.0.2.tar.gz │ │ ├── boxen-puppet-nginx-1.4.2.tar.gz │ │ ├── boxen-puppet-nodejs-3.2.9.tar.gz │ │ ├── boxen-puppet-rbenv-0.1.0.tar.gz │ │ ├── boxen-puppet-autoconf-1.0.0.tar.gz │ │ ├── boxen-puppet-dnsmasq-1.0.0.tar.gz │ │ ├── boxen-puppet-homebrew-1.4.1.tar.gz │ │ ├── boxen-puppet-inifile-0.0.1.tar.gz │ │ ├── boxen-puppet-openssl-1.0.0.tar.gz │ │ ├── boxen-puppet-xquartz-1.1.0.tar.gz │ │ ├── boxen-puppet-repository-2.2.0.tar.gz │ │ ├── puppetlabs-puppetlabs-inifile-1.0.0.tar.gz │ │ └── puppetlabs-puppetlabs-stdlib-4.1.0.tar.gz │ └── source │ │ └── .gitkeep ├── shims │ └── xcrun └── cache │ ├── ansi-1.4.3.gem │ ├── json-1.8.0.gem │ ├── rgen-0.6.6.gem │ ├── aws-sdk-1.8.2.gem │ ├── boxen-2.0.0.gem │ ├── builder-3.1.4.gem │ ├── facter-1.7.2.gem │ ├── faraday-0.8.8.gem │ ├── hiera-1.2.1.gem │ ├── net-ssh-2.6.5.gem │ ├── octokit-2.0.0.gem │ ├── open4-1.3.0.gem │ ├── puppet-3.2.4.gem │ ├── rbvmomi-1.6.0.gem │ ├── sawyer-0.3.0.gem │ ├── thor-0.18.1.gem │ ├── trollop-2.0.gem │ ├── highline-1.6.19.gem │ ├── json_pure-1.8.0.gem │ ├── nokogiri-1.5.6.gem │ ├── uuidtools-2.1.3.gem │ ├── uri_template-0.5.3.gem │ ├── multipart-post-1.2.0.gem │ └── librarian-puppet-0.9.10.gem ├── modules ├── people │ ├── manifests │ │ └── .gitkeep │ └── README.md └── projects │ ├── manifests │ ├── .gitkeep │ └── all.pp │ ├── templates │ └── shared │ │ └── nginx.conf.erb │ └── README.md ├── shared └── README.md ├── script ├── boxen-bootstrap ├── boxen-my-config ├── bootstrap ├── boxen-git-credential ├── nuke ├── boxen └── sync ├── .gitignore ├── Gemfile ├── docs ├── faq.md ├── personal-configuration.md ├── modules.md ├── rails.md └── puppet.md ├── config ├── basic.rb └── boxen.rb ├── LICENSE ├── Puppetfile ├── Gemfile.lock ├── Puppetfile.lock ├── manifests └── site.pp └── README.md /lib/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | system 2 | -------------------------------------------------------------------------------- /vendor/puppet/cache/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/people/manifests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/puppet/source/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/projects/manifests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/projects/manifests/all.pp: -------------------------------------------------------------------------------- 1 | class projects::all { 2 | include_all_projects() 3 | } 4 | -------------------------------------------------------------------------------- /vendor/shims/xcrun: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # A noop xcrun for initial Boxen runs. 3 | 4 | exec "$@" 5 | -------------------------------------------------------------------------------- /shared/README.md: -------------------------------------------------------------------------------- 1 | # Shared Puppet Modules 2 | 3 | This module directory is managed by librarian-puppet. 4 | -------------------------------------------------------------------------------- /vendor/cache/ansi-1.4.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/ansi-1.4.3.gem -------------------------------------------------------------------------------- /vendor/cache/json-1.8.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/json-1.8.0.gem -------------------------------------------------------------------------------- /vendor/cache/rgen-0.6.6.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/rgen-0.6.6.gem -------------------------------------------------------------------------------- /vendor/cache/aws-sdk-1.8.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/aws-sdk-1.8.2.gem -------------------------------------------------------------------------------- /vendor/cache/boxen-2.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/boxen-2.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/builder-3.1.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/builder-3.1.4.gem -------------------------------------------------------------------------------- /vendor/cache/facter-1.7.2.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/facter-1.7.2.gem -------------------------------------------------------------------------------- /vendor/cache/faraday-0.8.8.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/faraday-0.8.8.gem -------------------------------------------------------------------------------- /vendor/cache/hiera-1.2.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/hiera-1.2.1.gem -------------------------------------------------------------------------------- /vendor/cache/net-ssh-2.6.5.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/net-ssh-2.6.5.gem -------------------------------------------------------------------------------- /vendor/cache/octokit-2.0.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/octokit-2.0.0.gem -------------------------------------------------------------------------------- /vendor/cache/open4-1.3.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/open4-1.3.0.gem -------------------------------------------------------------------------------- /vendor/cache/puppet-3.2.4.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/puppet-3.2.4.gem -------------------------------------------------------------------------------- /vendor/cache/rbvmomi-1.6.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/rbvmomi-1.6.0.gem -------------------------------------------------------------------------------- /vendor/cache/sawyer-0.3.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/sawyer-0.3.0.gem -------------------------------------------------------------------------------- /vendor/cache/thor-0.18.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/thor-0.18.1.gem -------------------------------------------------------------------------------- /vendor/cache/trollop-2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/trollop-2.0.gem -------------------------------------------------------------------------------- /vendor/cache/highline-1.6.19.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/highline-1.6.19.gem -------------------------------------------------------------------------------- /vendor/cache/json_pure-1.8.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/json_pure-1.8.0.gem -------------------------------------------------------------------------------- /vendor/cache/nokogiri-1.5.6.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/nokogiri-1.5.6.gem -------------------------------------------------------------------------------- /vendor/cache/uuidtools-2.1.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/uuidtools-2.1.3.gem -------------------------------------------------------------------------------- /vendor/cache/uri_template-0.5.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/uri_template-0.5.3.gem -------------------------------------------------------------------------------- /vendor/cache/multipart-post-1.2.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/multipart-post-1.2.0.gem -------------------------------------------------------------------------------- /vendor/cache/librarian-puppet-0.9.10.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/cache/librarian-puppet-0.9.10.gem -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-gcc-2.0.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-gcc-2.0.1.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-git-1.2.5.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-git-1.2.5.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-hub-1.0.3.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-hub-1.0.3.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-nvm-1.0.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-nvm-1.0.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-ruby-6.3.4.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-ruby-6.3.4.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-sudo-1.0.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-sudo-1.0.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-boxen-3.0.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-boxen-3.0.2.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-nginx-1.4.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-nginx-1.4.2.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-nodejs-3.2.9.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-nodejs-3.2.9.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-rbenv-0.1.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-rbenv-0.1.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-autoconf-1.0.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-autoconf-1.0.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-dnsmasq-1.0.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-dnsmasq-1.0.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-homebrew-1.4.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-homebrew-1.4.1.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-inifile-0.0.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-inifile-0.0.1.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-openssl-1.0.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-openssl-1.0.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-xquartz-1.1.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-xquartz-1.1.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/boxen-puppet-repository-2.2.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/boxen-puppet-repository-2.2.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/puppetlabs-puppetlabs-inifile-1.0.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/puppetlabs-puppetlabs-inifile-1.0.0.tar.gz -------------------------------------------------------------------------------- /vendor/puppet/cache/puppetlabs-puppetlabs-stdlib-4.1.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lyric/our-boxen/master/vendor/puppet/cache/puppetlabs-puppetlabs-stdlib-4.1.0.tar.gz -------------------------------------------------------------------------------- /script/boxen-bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Make sure a project's deps are up-to-date. 3 | 4 | if File.executable? "script/bootstrap" 5 | exec "script/bootstrap", *ARGV 6 | end 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle 2 | /.librarian 3 | /.projects 4 | /.snapshot 5 | /.tmp 6 | /bin 7 | /config/local.rb 8 | /log 9 | /tmp 10 | /shared/* 11 | !/shared/README.md 12 | /vendor/gems/ 13 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "boxen", "~> 2.0.0" 4 | gem "open4", "~> 1.3" 5 | 6 | group :development do 7 | gem "aws-sdk" 8 | gem "net-ssh" 9 | gem "rbvmomi" 10 | end 11 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | Below you can find common questions and answers. 4 | 5 | ### Q: How do you uninstall an application and get it to reinstall in the application folder with boxen? 6 | 7 | When removing applications make sure to remove the corresponding `/var/db/.puppet_appdmg_installed_application` so that boxen will reinstall it. 8 | 9 | ### Q: How do you remove Boxen? 10 | 11 | Run `script/nuke` from inside the `/opt/boxen/repo` directory. 12 | -------------------------------------------------------------------------------- /script/boxen-my-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Show the path to your manifest in Boxen, creating if necessary. 3 | 4 | user = ENV["BOXEN_GITHUB_LOGIN"] 5 | 6 | unless user 7 | abort "BOXEN_GITHUB_LOGIN is not defined. Please re-run Boxen." 8 | end 9 | 10 | editor = ENV["VISUAL"] || ENV["EDITOR"] 11 | home = ENV["BOXEN_HOME"] + "/repo" 12 | user = user.downcase.tr('-', '_') 13 | path = "#{home}/modules/people/manifests/#{user}.pp" 14 | 15 | unless File.exist? path 16 | File.open path, "wb" do |f| 17 | f.puts "class people::#{user} {" 18 | f.puts "}" 19 | end 20 | end 21 | 22 | exec([editor, path].join(' ')) if editor && system("test -t 1") 23 | 24 | puts path 25 | -------------------------------------------------------------------------------- /config/basic.rb: -------------------------------------------------------------------------------- 1 | # Set up the execution environment. Load this file before trying to do 2 | # anything else. This file assumes that the repo's been bootstrapped. 3 | 4 | require "pathname" 5 | 6 | # Make sure we're in the repo's root directory. 7 | 8 | Dir.chdir Pathname.new(__FILE__).realpath + "../.." 9 | 10 | # Load custom config. 11 | 12 | load File.expand_path "../boxen.rb", __FILE__ 13 | 14 | # Load local config if it exists. This file is ignored by Git, and can 15 | # be used for personal config. 16 | 17 | local = File.expand_path "../local.rb", __FILE__ 18 | load local if File.file? local 19 | 20 | # Add local deps to the load path. 21 | 22 | require "rubygems" 23 | require "bundler/setup" 24 | 25 | # Add local lib to the front of the load path if it exists. 26 | 27 | lib = File.expand_path "../../lib", __FILE__ 28 | $:.unshift lib if File.directory? lib 29 | -------------------------------------------------------------------------------- /script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Make sure all our local dependencies are available. 3 | 4 | set -e 5 | 6 | # FIX: only sudo if gem home isn't writable 7 | 8 | (/usr/bin/gem list -i bundler -v '~> 1.3.0' > /dev/null) || { 9 | /usr/bin/sudo -p "Need to install Bundler for system ruby, password for sudo: " \ 10 | /usr/bin/gem install bundler -v '~> 1.3.0' --no-rdoc --no-ri 11 | } 12 | 13 | # We don't want old config hanging around. 14 | 15 | rm -rf .bundle/config 16 | rm -rf .librarian/puppet/config 17 | 18 | # Put xcrun shim on PATH if on MoLo 19 | set +e 20 | OSX_VERSION_CHECK=`sw_vers | grep ProductVersion | cut -f 2 -d ':' | egrep '10\.8'` 21 | if [ $? -eq 0 ]; then 22 | export PATH=$(pwd)/vendor/shims:$PATH 23 | fi 24 | set -e 25 | 26 | # Bundle install unless we're already up to date. 27 | /usr/bin/bundle install --binstubs bin --path .bundle --quiet "$@" 28 | -------------------------------------------------------------------------------- /modules/projects/templates/shared/nginx.conf.erb: -------------------------------------------------------------------------------- 1 | upstream <%= @server_name %> { 2 | server unix:<%= scope.lookupvar "boxen::config::socketdir" %>/<%= @name %>; 3 | } 4 | 5 | server { 6 | access_log <%= scope.lookupvar "nginx::config::logdir" %>/<%= @name %>.access.log main; 7 | listen 80; 8 | root <%= scope.lookupvar "boxen::config::srcdir" %>/<%= @name %>/public; 9 | server_name <%= @server_name %> *.<%= @server_name %>; 10 | 11 | client_max_body_size 50M; 12 | error_page 500 502 503 504 /50x.html; 13 | 14 | location = /50x.html { 15 | root html; 16 | } 17 | 18 | try_files $uri/index.html $uri @<%= @server_name %>; 19 | location @<%= @server_name %> { 20 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 21 | proxy_set_header Host $http_host; 22 | proxy_redirect off; 23 | proxy_pass http://<%= @server_name %>; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /config/boxen.rb: -------------------------------------------------------------------------------- 1 | # This file will be loaded by config/basic early in a Boxen run. Use 2 | # it to provide any custom code or behavior your Boxen setup requires. 3 | 4 | # Change the prefix boxen is installed to. 5 | # ENV['BOXEN_HOME'] = '/opt/boxen' 6 | 7 | # Change the repo boxen will use. 8 | # ENV['BOXEN_REPO_NAME'] = 'boxen/our-boxen' 9 | 10 | # Boxen binary packaging 11 | # ENV["BOXEN_S3_ACCESS_KEY"] = '' 12 | # ENV["BOXEN_S3_SECRET_KEY"] = '' 13 | # ENV["BOXEN_S3_BUCKET"] = '' 14 | 15 | # Auto-report issues on failed runs 16 | # ENV["BOXEN_ISSUES_ENABLED"] = 'yes' 17 | 18 | # Submit audit data to an arbitrary HTTP endpoint 19 | # ENV["BOXEN_WEB_HOOK_URL"] = 'https://some-uri.com/boxen' 20 | # 21 | # required for Github Enterprise 22 | # ENV["BOXEN_GITHUB_ENTERPRISE_URL"] = 'https://github.yourdomain.com' 23 | 24 | # required for Github Enterprise (defaults to "https://github.com/%s") 25 | # ENV['BOXEN_REPO_URL_TEMPLATE'] = 'https://github.yourdomain.com/%s' 26 | -------------------------------------------------------------------------------- /modules/people/README.md: -------------------------------------------------------------------------------- 1 | # Personal Manifests 2 | 3 | Per-user manifests live in `modules/people/manifests/$login.pp`, where 4 | `$login` is a GitHub login. A simple user manifest example: 5 | 6 | ```puppet 7 | class people::jbarnette { 8 | include emacs # requires emacs module in Puppetfile 9 | include sparrow # requires sparrow module in Puppetfile 10 | 11 | $home = "/Users/${::boxen_user}" 12 | $my = "${home}/my" 13 | $dotfiles = "${my}/dotfiles" 14 | 15 | file { $my: 16 | ensure => directory 17 | } 18 | 19 | repository { $dotfiles: 20 | source => 'jbarnette/dotfiles', 21 | require => File[$my] 22 | } 23 | } 24 | ``` 25 | 26 | Note that if your GitHub username contains dashes, you should replace them by underscores in both the manifest name and the class name. 27 | 28 | ## Projects 29 | 30 | While you _can_ include projects one by one, sometimes you might just want 31 | all of them. 32 | You can do that easily with: 33 | 34 | ``` 35 | include projects::all 36 | ``` 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 GitHub, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /modules/projects/README.md: -------------------------------------------------------------------------------- 1 | # Project Manifests 2 | 3 | Project manifests live in `modules/projects/manifests/$project.pp`. A 4 | simple project manifest example: 5 | 6 | ```puppet 7 | class projects::trollin { 8 | include icu4c 9 | include phantomjs 10 | 11 | boxen::project { 'trollin': 12 | dotenv => true, 13 | elasticsearch => true, 14 | mysql => true, 15 | nginx => true, 16 | redis => true, 17 | ruby => '1.9.3', 18 | source => 'boxen/trollin' 19 | } 20 | } 21 | ``` 22 | 23 | With the above, as long as our app is configured to listen on a **socket** at 24 | `"#{ENV['BOXEN_SOCKET_DIR']}"/trollin`, you'll now be able to run its local 25 | server and visit http://trollin.dev/ to access the app in dev. 26 | 27 | Provide the full repository URL in the 'source' option when referencing 28 | code that is not hosted at github.com, such as Github Enterprise 29 | repositories. 30 | 31 | For further documentation on how to use the `boxen::project` type, 32 | take a look at the documentation in the 33 | [source](https://github.com/boxen/puppet-boxen/blob/master/manifests/project.pp#L1-L61). 34 | -------------------------------------------------------------------------------- /script/boxen-git-credential: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # Provide git credentials using Boxen's config. 3 | 4 | unless command = ARGV[0] 5 | this = File.basename $0 6 | abort "Usage: #{this} " 7 | end 8 | 9 | require "pathname" 10 | 11 | # Put us where we belong, in the root dir of our boxen repo. 12 | 13 | Dir.chdir Pathname.new(__FILE__).realpath + "../.." 14 | 15 | # Because we can be called from inside other Ruby processes, unset any 16 | # `BUNDLE_` environment variables. 17 | 18 | ENV.keys.select { |k| /^BUNDLE_/i }.each { |k| ENV.delete k } 19 | 20 | # Set up our local configuration, deps, and load path. 21 | 22 | load "config/basic.rb" 23 | require "boxen/config" 24 | 25 | config = Boxen::Config.load 26 | input = $stdin.read 27 | attrs = Hash[input.split($/).map { |l| l.split("=") }] 28 | 29 | if command == "get" && attrs["host"] =~ /(^|\.)github\.com$/ 30 | puts "username=#{config.token}" 31 | puts "password=x-oauth-basic" 32 | else 33 | require "open4" 34 | 35 | fallback = ENV["BOXEN_GIT_CREDENTIAL_FALLBACK"] 36 | fallback ||= "#{config.homedir}/homebrew/bin/git-credential-osxkeychain" 37 | 38 | status = Open4.popen4 fallback, *ARGV do |pid, stdin, stdout, stderr| 39 | stdin.write input 40 | stdin.puts 41 | 42 | $stdout.write stdout.read 43 | end 44 | 45 | exit status.exitstatus 46 | end 47 | -------------------------------------------------------------------------------- /Puppetfile: -------------------------------------------------------------------------------- 1 | # This file manages Puppet module dependencies. 2 | # 3 | # It works a lot like Bundler. We provide some core modules by 4 | # default. This ensures at least the ability to construct a basic 5 | # environment. 6 | 7 | def github(name, version, options = nil) 8 | options ||= {} 9 | options[:repo] ||= "boxen/puppet-#{name}" 10 | mod name, version, :github_tarball => options[:repo] 11 | end 12 | 13 | # Includes many of our custom types and providers, as well as global 14 | # config. Required. 15 | 16 | github "boxen", "3.0.2" 17 | 18 | # Core modules for a basic development environment. You can replace 19 | # some/most of these if you want, but it's not recommended. 20 | 21 | github "autoconf", "1.0.0" 22 | github "dnsmasq", "1.0.0" 23 | github "gcc", "2.0.1" 24 | github "git", "1.2.5" 25 | github "homebrew", "1.4.1" 26 | github "hub", "1.0.3" 27 | github "inifile", "1.0.0", :repo => "puppetlabs/puppetlabs-inifile" 28 | github "nginx", "1.4.2" 29 | github "nodejs", "3.2.9" 30 | github "openssl", "1.0.0" 31 | github "repository", "2.2.0" 32 | github "ruby", "6.3.4" 33 | github "stdlib", "4.1.0", :repo => "puppetlabs/puppetlabs-stdlib" 34 | github "sudo", "1.0.0" 35 | github "xquartz", "1.1.0" 36 | 37 | # Optional/custom modules. There are tons available at 38 | # https://github.com/boxen. 39 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | ansi (1.4.3) 5 | aws-sdk (1.8.2) 6 | json (~> 1.4) 7 | nokogiri (>= 1.4.4) 8 | uuidtools (~> 2.1) 9 | boxen (2.0.0) 10 | ansi (~> 1.4) 11 | hiera (~> 1.0) 12 | highline (~> 1.6) 13 | json_pure (>= 1.7.7, < 2.0) 14 | librarian-puppet (~> 0.9.9) 15 | octokit (~> 2.0.0) 16 | puppet (~> 3.0) 17 | builder (3.1.4) 18 | facter (1.7.2) 19 | faraday (0.8.8) 20 | multipart-post (~> 1.2.0) 21 | hiera (1.2.1) 22 | json_pure 23 | highline (1.6.19) 24 | json (1.8.0) 25 | json_pure (1.8.0) 26 | librarian-puppet (0.9.10) 27 | json 28 | thor (~> 0.15) 29 | multipart-post (1.2.0) 30 | net-ssh (2.6.5) 31 | nokogiri (1.5.6) 32 | octokit (2.0.0) 33 | sawyer (~> 0.3.0) 34 | open4 (1.3.0) 35 | puppet (3.2.4) 36 | facter (~> 1.6) 37 | hiera (~> 1.0) 38 | rgen (~> 0.6.5) 39 | rbvmomi (1.6.0) 40 | builder 41 | nokogiri (>= 1.4.1) 42 | trollop 43 | rgen (0.6.6) 44 | sawyer (0.3.0) 45 | faraday (~> 0.8, < 0.10) 46 | uri_template (~> 0.5.0) 47 | thor (0.18.1) 48 | trollop (2.0) 49 | uri_template (0.5.3) 50 | uuidtools (2.1.3) 51 | 52 | PLATFORMS 53 | ruby 54 | 55 | DEPENDENCIES 56 | aws-sdk 57 | boxen (~> 2.0.0) 58 | net-ssh 59 | open4 (~> 1.3) 60 | rbvmomi 61 | -------------------------------------------------------------------------------- /Puppetfile.lock: -------------------------------------------------------------------------------- 1 | GITHUBTARBALL 2 | remote: boxen/puppet-autoconf 3 | specs: 4 | autoconf (1.0.0) 5 | 6 | GITHUBTARBALL 7 | remote: boxen/puppet-boxen 8 | specs: 9 | boxen (3.0.2) 10 | 11 | GITHUBTARBALL 12 | remote: boxen/puppet-dnsmasq 13 | specs: 14 | dnsmasq (1.0.0) 15 | 16 | GITHUBTARBALL 17 | remote: boxen/puppet-gcc 18 | specs: 19 | gcc (2.0.1) 20 | 21 | GITHUBTARBALL 22 | remote: boxen/puppet-git 23 | specs: 24 | git (1.2.5) 25 | 26 | GITHUBTARBALL 27 | remote: boxen/puppet-homebrew 28 | specs: 29 | homebrew (1.4.1) 30 | 31 | GITHUBTARBALL 32 | remote: boxen/puppet-hub 33 | specs: 34 | hub (1.0.3) 35 | 36 | GITHUBTARBALL 37 | remote: boxen/puppet-nginx 38 | specs: 39 | nginx (1.4.2) 40 | 41 | GITHUBTARBALL 42 | remote: boxen/puppet-nodejs 43 | specs: 44 | nodejs (3.2.9) 45 | 46 | GITHUBTARBALL 47 | remote: boxen/puppet-openssl 48 | specs: 49 | openssl (1.0.0) 50 | 51 | GITHUBTARBALL 52 | remote: boxen/puppet-repository 53 | specs: 54 | repository (2.2.0) 55 | 56 | GITHUBTARBALL 57 | remote: boxen/puppet-ruby 58 | specs: 59 | ruby (6.3.4) 60 | 61 | GITHUBTARBALL 62 | remote: boxen/puppet-sudo 63 | specs: 64 | sudo (1.0.0) 65 | 66 | GITHUBTARBALL 67 | remote: boxen/puppet-xquartz 68 | specs: 69 | xquartz (1.1.0) 70 | 71 | GITHUBTARBALL 72 | remote: puppetlabs/puppetlabs-inifile 73 | specs: 74 | inifile (1.0.0) 75 | 76 | GITHUBTARBALL 77 | remote: puppetlabs/puppetlabs-stdlib 78 | specs: 79 | stdlib (4.1.0) 80 | 81 | DEPENDENCIES 82 | autoconf (= 1.0.0) 83 | boxen (= 3.0.2) 84 | dnsmasq (= 1.0.0) 85 | gcc (= 2.0.1) 86 | git (= 1.2.5) 87 | homebrew (= 1.4.1) 88 | hub (= 1.0.3) 89 | inifile (= 1.0.0) 90 | nginx (= 1.4.2) 91 | nodejs (= 3.2.9) 92 | openssl (= 1.0.0) 93 | repository (= 2.2.0) 94 | ruby (= 6.3.4) 95 | stdlib (= 4.1.0) 96 | sudo (= 1.0.0) 97 | xquartz (= 1.1.0) 98 | 99 | -------------------------------------------------------------------------------- /docs/personal-configuration.md: -------------------------------------------------------------------------------- 1 | # Personal Configuration 2 | 3 | One of the design choices of Boxen very early on was that we didn't want to 4 | dictate down to users "you can do this, but you can't do that". 5 | We do so as little as possible in the core, and we don't do it at all for 6 | per-user configurations. 7 | 8 | How? The personal manifest. 9 | 10 | ## What even is a personal manifest? 11 | 12 | Personal manifests live in `modules/people/manifests/.pp`, 13 | where `` is your GitHub username. 14 | 15 | The simplest personal manifest looks like this: 16 | 17 | ``` puppet 18 | class people::wfarr { 19 | notify { 'hello world': } 20 | } 21 | ``` 22 | 23 | Ah, the good old "Hello World". 24 | It's boring, but you can see there's really not much boilerplate involved. 25 | Let's try something *real* this time: 26 | 27 | ``` puppet 28 | class people::wfarr { 29 | include boxen::development 30 | } 31 | ``` 32 | 33 | So what does this do? 34 | It clones every repo in the Boxen org to `~/src/boxen/`. 35 | How? 36 | Well, we can refer to [the source code](https://github.com/boxen/puppet-boxen/blob/master/manifests/development.pp)! 37 | If you're new to Puppet, or are unsure of what that class is doing, check out 38 | the [intro to puppet](./puppet.md) we've put together. 39 | 40 | ## Running different code on multiple machines 41 | 42 | Puppet has conditionals and switching. 43 | Typically, the most reliable way to ensure some code runs on one machine but not 44 | others is to use the `case` statement on the `hostname` fact. 45 | Example: 46 | 47 | ``` puppet 48 | case $::hostname { 49 | 'scruffy': { 50 | notify { "I'm Scruffy. The Janitor.": } 51 | } 52 | 53 | 'bender': { 54 | notify { "My full name is Bender Bending Rodriguez": } 55 | } 56 | 57 | default: { 58 | notify { "Wha?": } 59 | } 60 | } 61 | ``` 62 | 63 | One thing to note here is that Puppet always **requires** a default path 64 | on a case statement. 65 | Default is equivalent to "anything that isn't matched above". 66 | -------------------------------------------------------------------------------- /manifests/site.pp: -------------------------------------------------------------------------------- 1 | require boxen::environment 2 | require homebrew 3 | require gcc 4 | 5 | Exec { 6 | group => 'staff', 7 | logoutput => on_failure, 8 | user => $boxen_user, 9 | 10 | path => [ 11 | "${boxen::config::home}/rbenv/shims", 12 | "${boxen::config::home}/rbenv/bin", 13 | "${boxen::config::home}/rbenv/plugins/ruby-build/bin", 14 | "${boxen::config::home}/homebrew/bin", 15 | '/usr/bin', 16 | '/bin', 17 | '/usr/sbin', 18 | '/sbin' 19 | ], 20 | 21 | environment => [ 22 | "HOMEBREW_CACHE=${homebrew::config::cachedir}", 23 | "HOME=/Users/${::boxen_user}" 24 | ] 25 | } 26 | 27 | File { 28 | group => 'staff', 29 | owner => $boxen_user 30 | } 31 | 32 | Package { 33 | provider => homebrew, 34 | require => Class['homebrew'] 35 | } 36 | 37 | Repository { 38 | provider => git, 39 | extra => [ 40 | '--recurse-submodules' 41 | ], 42 | require => File["${boxen::config::bindir}/boxen-git-credential"], 43 | config => { 44 | 'credential.helper' => "${boxen::config::bindir}/boxen-git-credential" 45 | } 46 | } 47 | 48 | Service { 49 | provider => ghlaunchd 50 | } 51 | 52 | Homebrew::Formula <| |> -> Package <| |> 53 | 54 | node default { 55 | # core modules, needed for most things 56 | include dnsmasq 57 | include git 58 | include hub 59 | include nginx 60 | 61 | # fail if FDE is not enabled 62 | if $::root_encrypted == 'no' { 63 | fail('Please enable full disk encryption and try again') 64 | } 65 | 66 | # node versions 67 | include nodejs::v0_4 68 | include nodejs::v0_6 69 | include nodejs::v0_8 70 | include nodejs::v0_10 71 | 72 | # default ruby versions 73 | include ruby::1_8_7 74 | include ruby::1_9_2 75 | include ruby::1_9_3 76 | include ruby::2_0_0 77 | 78 | # common, useful packages 79 | package { 80 | [ 81 | 'ack', 82 | 'findutils', 83 | 'gnu-tar' 84 | ]: 85 | } 86 | 87 | file { "${boxen::config::srcdir}/our-boxen": 88 | ensure => link, 89 | target => $boxen::config::repodir 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /script/nuke: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require "optparse" 4 | 5 | unless ENV["USER"] == "root" 6 | exec "sudo", $0, *ARGV 7 | end 8 | 9 | all = false 10 | force = false 11 | opt = false 12 | services = false 13 | receipts = false 14 | gitconfig = false 15 | 16 | OptionParser.new do |o| 17 | o.banner = "Remove most traces of Boxen from your machine." 18 | 19 | o.on("--all", "Remove everything possible.") { all = true } 20 | o.on("--force", "Actually do it.") { force = true } 21 | o.on("--help", "Show this help.") { abort o.to_s } 22 | o.on("--opt", "Remove /opt/boxen.") { opt = true } 23 | o.on("--services", "Remove and unload services.") { services = true } 24 | o.on("--receipts", "Remove package receipts used by Puppet.") { receipts = true } 25 | o.on("--gitconfig", "Remove Boxen-provided git credential helper config.") { gitconfig = true } 26 | 27 | o.parse! 28 | 29 | abort o.to_s unless all || opt || services || receipts || gitconfig 30 | end 31 | 32 | unless force 33 | warn "** I won't actually do anything unless you pass --force." 34 | end 35 | 36 | if all || services 37 | boxen_services = [] 38 | boxen_services << Dir["/Library/Launch*/dev.*.plist"] 39 | 40 | boxen_services.flatten.each do |plist| 41 | warn "-> Removing #{plist}." 42 | 43 | if force 44 | system "launchctl", "unload", "-w", plist 45 | system "rm", "-f", plist 46 | end 47 | end 48 | 49 | system "rm", "-f", "/etc/resolver/dev" 50 | end 51 | 52 | if all || opt 53 | warn "-> Removing /opt/boxen." 54 | system "rm", "-rf", "/opt/boxen" if force 55 | end 56 | 57 | if all || receipts 58 | warn "-> Removing /var/db/.puppet_*." 59 | # can't use a bare system call here, because we need globbing. 60 | system 'sh -c "rm -rf /var/db/.puppet_*"' if force 61 | end 62 | 63 | if all || gitconfig 64 | warn "-> Removing git credential helper config." 65 | system "/usr/bin/git", "config", "--global", "--unset", "credential.helper" 66 | end 67 | -------------------------------------------------------------------------------- /script/boxen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # Run Boxen. 3 | 4 | require "pathname" 5 | 6 | if ENV["USER"] == "root" 7 | abort "Run this as a normal user, I'll sudo if I need to." 8 | end 9 | 10 | # Make sure only one boxen process runs at a time. 11 | 12 | myself = File.new __FILE__ 13 | 14 | unless myself.flock File::LOCK_EX | File::LOCK_NB 15 | abort "You're already running a boxen process! Know a patience." 16 | end 17 | 18 | # Yeah yeah, I like to be explicit. 19 | 20 | at_exit { myself.flock File::LOCK_UN } 21 | 22 | # Put us where we belong, in the root dir of our boxen repo. 23 | 24 | Dir.chdir Pathname.new(__FILE__).realpath + "../.." 25 | 26 | # Auto-update code. This is done as early as possible so that changes 27 | # to boxen support code or dependencies can be grabbed. 28 | NO_PULL_ARGS = %w[--no-pull -h -? --help] + [/-service/] 29 | unless ENV["BOXEN_NO_PULL"] || 30 | ARGV.any? { |arg| NO_PULL_ARGS.any? { |no| arg.match(no) } } 31 | quietly = "> /dev/null 2>&1" 32 | 33 | if system("which git > /dev/null") && File.directory?(".git") \ 34 | && fetch = system("git fetch -q origin") 35 | 36 | clean = `git status --porcelain`.empty? 37 | current_branch = `git symbolic-ref HEAD`.chomp 38 | master = current_branch == "refs/heads/master" 39 | 40 | upstream_changes = `git rev-list --count master..origin/master`.chomp != '0' 41 | fast_forwardable = `git rev-list --count origin/master..master`.chomp == '0' 42 | 43 | if current_branch.empty? 44 | ref = `git log -1 --pretty=format:%h` 45 | warn "Boxen not currently on any branch (ref: #{ref}), won't auto-update!" 46 | elsif !master 47 | local_branch = current_branch.split('/')[2..-1].join('/') 48 | warn "Boxen on a non-master branch '#{local_branch}', won't auto-update!" 49 | elsif !fast_forwardable 50 | warn "Boxen's master branch is out of sync, won't auto-update!" 51 | elsif !clean 52 | warn "Boxen has a dirty tree, won't auto-update!" 53 | elsif !upstream_changes 54 | warn "Boxen is up-to-date." 55 | end 56 | 57 | if clean && master && fast_forwardable && upstream_changes 58 | reset = "(git reset --hard origin/master #{quietly})" 59 | reclean = "(git clean -qdf)" 60 | 61 | unless system "#{reset} && #{reclean}" 62 | warn "Auto-update of Boxen FAILED, continuing." 63 | end 64 | end 65 | end 66 | end 67 | 68 | # Make sure our local dependencies are up to date. 69 | 70 | strap = %w(script/bootstrap --deployment --local --without development:test --no-cache) 71 | abort "Can't bootstrap, dependencies are outdated." unless system *strap 72 | 73 | # Set up our local configuration, deps, and load path. 74 | 75 | load "config/basic.rb" 76 | require "boxen/cli" 77 | 78 | # Okay, let's run this thing. 79 | 80 | exit Boxen::CLI.run ARGV 81 | -------------------------------------------------------------------------------- /script/sync: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | # Sync binary snapshots to S3. 3 | 4 | require "pathname" 5 | require "tempfile" 6 | 7 | # Put us where we belong, in the root dir of our boxen repo. 8 | 9 | Dir.chdir Pathname.new(__FILE__).realpath + "../.." 10 | 11 | # Make sure our local dependencies are up to date. 12 | 13 | abort "Sorry, can't bootstrap." unless system "script/bootstrap" 14 | 15 | # Set up our local configuration, deps, and load path. 16 | 17 | load "config/basic.rb" 18 | 19 | require "aws-sdk" 20 | require "boxen/config" 21 | 22 | access_key = ENV["BOXEN_S3_ACCESS_KEY"] 23 | secret_key = ENV["BOXEN_S3_SECRET_KEY"] 24 | bucket_name = ENV["BOXEN_S3_BUCKET"] 25 | 26 | unless access_key && secret_key && bucket_name 27 | abort "Please set the BOXEN_S3_{ACCESS_KEY,SECRET_KEY,BUCKET} env vars." 28 | end 29 | 30 | s3 = AWS::S3.new :access_key_id => access_key, :secret_access_key => secret_key 31 | os = `sw_vers -productVersion`.strip.split(".")[0..1].join "." 32 | 33 | bucket = s3.buckets[bucket_name] 34 | config = Boxen::Config.load 35 | 36 | # Sync Homebrew packages. 37 | 38 | Dir.chdir "#{config.homedir}/homebrew/Cellar" do 39 | Dir["*/*"].each do |dir| 40 | name, version = File.split dir 41 | 42 | file = "homebrew/#{os}/#{name}-#{version}.tar.bz2" 43 | temp = Tempfile.new "homebrew" 44 | obj = bucket.objects[file] 45 | 46 | next if obj.exists? 47 | 48 | printf "Snapshotting #{name} #{version}... " 49 | $stdout.flush 50 | 51 | system "tar", "-cjf", temp.path, dir 52 | puts "done." 53 | 54 | printf "Shipping #{name} #{version} to S3... " 55 | $stdout.flush 56 | 57 | obj.write :acl => :public_read, :file => temp.path 58 | puts "done." 59 | end 60 | end 61 | 62 | # Sync rbenv rubies. 63 | 64 | Dir.chdir "#{config.homedir}/rbenv/versions" do 65 | Dir["*"].each do |dir| 66 | next if File.symlink? dir 67 | 68 | version = File.basename dir 69 | file = "rbenv/#{os}/#{version}.tar.bz2" 70 | temp = Tempfile.new "rbenv" 71 | obj = bucket.objects[file] 72 | 73 | next if obj.exists? 74 | 75 | printf "Snapshotting ruby #{version}... " 76 | $stdout.flush 77 | 78 | system "tar -cjf #{temp.path} #{version}" 79 | puts "done." 80 | 81 | printf "Shipping ruby #{version} to S3... " 82 | $stdout.flush 83 | 84 | obj.write :acl => :public_read, :file => temp.path 85 | puts "done." 86 | end 87 | end 88 | 89 | # Sync NVM nodes. 90 | 91 | Dir.chdir "#{config.homedir}/nvm" do 92 | Dir["v*"].each do |dir| 93 | version = File.basename dir 94 | file = "nvm/#{os}/#{version}.tar.bz2" 95 | temp = Tempfile.new "nvm" 96 | obj = bucket.objects[file] 97 | 98 | next if obj.exists? 99 | 100 | printf "Snapshotting node.js #{version}... " 101 | $stdout.flush 102 | 103 | system "tar -cjf #{temp.path} #{version}" 104 | puts "done." 105 | 106 | printf "Shipping node.js #{version} to S3... " 107 | $stdout.flush 108 | 109 | obj.write :acl => :public_read, :file => temp.path 110 | puts "done." 111 | end 112 | end 113 | -------------------------------------------------------------------------------- /docs/modules.md: -------------------------------------------------------------------------------- 1 | # Writing Puppet modules for Boxen 2 | 3 | Writing Puppet modules for Boxen is easy. 4 | 5 | ## Tooling 6 | 7 | * Always use Bundler 8 | * Always use librarian-puppet 9 | * Always use puppet-lint 10 | * Always use rspec-puppet 11 | 12 | ## Directory structure 13 | 14 | We follow Puppet's recommended structure very closely. 15 | Here's the directory structure from the boxen Puppet module: 16 | 17 | ``` 18 | ├── Gemfile 19 | ├── Gemfile.lock 20 | ├── README.md 21 | ├── files 22 | │   ├── README.md 23 | │   └── gemrc 24 | ├── lib 25 | │   ├── facter 26 | │   │   ├── boxen.rb 27 | │   │   └── root_encrypted.rb 28 | │   └── puppet 29 | │   ├── parser 30 | │   │   └── functions 31 | │   │   ├── file_exists.rb 32 | │   │   ├── include_all_projects.rb 33 | │   │   └── include_projects_from_boxen_cli.rb 34 | │   ├── provider 35 | │   │   ├── package 36 | │   │   │   ├── compressed_app.rb 37 | │   │   │   ├── hax.rb 38 | │   │   │   └── homebrew.rb 39 | │   │   ├── repository 40 | │   │   │   └── git.rb 41 | │   │   └── service 42 | │   │   └── ghlaunchd.rb 43 | │   └── type 44 | │   └── repository.rb 45 | ├── manifests 46 | │   ├── bin.pp 47 | │   ├── config.pp 48 | │   ├── development 49 | │   │   └── project.pp 50 | │   ├── development.pp 51 | │   ├── environment.pp 52 | │   ├── gemrc.pp 53 | │   ├── janitor.pp 54 | │   ├── osx_defaults.pp 55 | │   ├── personal.pp 56 | │   ├── profile.pp 57 | │   ├── project.pp 58 | │   ├── repo.pp 59 | │   ├── security.pp 60 | │   ├── sudoers.pp 61 | │   └── zipped_widget.pp 62 | ├── script 63 | │   ├── bootstrap 64 | │   ├── cibuild 65 | │   ├── lint 66 | │   ├── specs 67 | │   └── syntax 68 | ├── spec 69 | │   ├── classes 70 | │   │   ├── bin_spec.rb 71 | │   │   └── environment_spec.rb 72 | │   ├── fixtures 73 | │   │   ├── Puppetfile 74 | │   │   ├── Puppetfile.lock 75 | │   │   ├── manifests 76 | │   │   │   └── site.pp 77 | │   │   └── modules 78 | │   │   ├── boxen 79 | │   │   │   ├── files -> ../../../../files 80 | │   │   │   ├── lib -> ../../../../lib 81 | │   │   │   ├── manifests -> ../../../../manifests 82 | │   │   │   └── templates -> ../../../../templates 83 | │   │   └── projects 84 | │   │   └── manifests 85 | │   │   └── test.pp 86 | │   ├── spec_helper.rb 87 | │   └── unit 88 | │   └── puppet 89 | │   └── type 90 | │   └── repository_spec.rb 91 | └── templates 92 | ├── config.sh.erb 93 | ├── env.sh.erb 94 | └── gh_creds.sh.erb 95 | ``` 96 | 97 | Of note, we do not use things like `rake` to drive specs. 98 | Instead, we bias towards simple, portable shell scripts that can be consumed 99 | by other shell scripts. 100 | 101 | ## Facts and variables 102 | 103 | The core boxen module provides [a number of variables to use](https://github.com/boxen/puppet-boxen/blob/master/manifests/config.pp#L8-L21). 104 | 105 | In addition to these, you may always assume the presence of a `boxen_user` fact, 106 | which is the local user running Boxen. 107 | 108 | Other modules may provide their own globally available variables. 109 | The recommendation is to put any variables that might be consumed by 110 | multiple classes/manifests in a scoped config class 111 | (e.g. `modules/boxen/manifests/config.pp`). 112 | -------------------------------------------------------------------------------- /docs/rails.md: -------------------------------------------------------------------------------- 1 | # Using Boxen with Rails Projects 2 | 3 | Boxen is designed to work extremely well with Rails. 4 | Let's break down some of the basics: 5 | 6 | ## Project Management 7 | 8 | We make a few assumptions about how you run Rails in development for ease and consistency: 9 | 10 | * You use a web server that listens on a socket 11 | * You use environment variables and something like [dotenv](https://github.com/bkeepers/dotenv) for managing secrets 12 | 13 | A typical Rails app that uses things like MySQL, Resque, and phantomjs 14 | might have a [project definition](../modules/projects/README.md) like so: 15 | 16 | ``` puppet 17 | class projects::rails_app { 18 | include phantomjs 19 | 20 | boxen::project { 'rails_app': 21 | ruby => '1.9.3', 22 | mysql => true, 23 | redis => true, 24 | nginx => true, 25 | source => 'username/rails_app' 26 | } 27 | } 28 | ``` 29 | 30 | This does a few things for you: 31 | 32 | * Clones `https://github.com/username/rails_app.git` to `~/src/rails_app` 33 | * Ensures the default 1.9.3 version of Ruby is installed 34 | * Creates `~/src/rails_app/.ruby-version` with `1.9.3` in it 35 | * Ensures mysql is installed and running 36 | * Creates two mysql databases: `rails_app_test` and `rails_app_development` 37 | * Ensures redis is installed and running 38 | * Ensures nginx is installed and running 39 | * Copies the [template nginx config](../modules/projects/templates/shared/nginx.conf.erb) into the nginx config dir 40 | 41 | It won't necessarily do all of them in that order, but it will guarantee 42 | that if they run successfully they're all done in a correct order. 43 | 44 | See the section below for some handy configuration tips on how to configure 45 | your app best to work with Boxen. 46 | 47 | ## Configuration 48 | 49 | ### MySQL 50 | 51 | ``` yaml 52 | # config/database.yml 53 | 54 | <% 55 | def boxen?; ENV['BOXEN_HOME']; end 56 | 57 | socket = [ 58 | ENV["BOXEN_MYSQL_SOCKET"], 59 | "/var/run/mysql5/mysqld.sock", 60 | "/tmp/mysql.sock" 61 | ].compact.detect { |f| File.exist? f } 62 | 63 | port = ENV["BOXEN_MYSQL_PORT"] || "3306" 64 | %> 65 | 66 | development: 67 | adapter: mysql2 68 | database: rails_app_development 69 | username: root 70 | password: 71 | <% if socket %> 72 | host: localhost 73 | socket: <%= socket %> 74 | <% else %> 75 | host: 127.0.0.1 76 | port: <%= port %> 77 | <% end %> 78 | 79 | test: 80 | adapter: mysql2 81 | database: rails_app_test 82 | username: root 83 | password: 84 | <% if socket %> 85 | host: localhost 86 | socket: <%= socket %> 87 | <% else %> 88 | host: 127.0.0.1 89 | port: <%= port %> 90 | <% end %> 91 | ``` 92 | 93 | ### PostgreSQL 94 | 95 | ``` yaml 96 | # config/database.yml 97 | 98 | development: 99 | adapter: postgresql 100 | database: rails_app_development 101 | encoding: unicode 102 | port: <%= ENV["BOXEN_POSTGRESQL_PORT"] || 5432 %> 103 | host: localhost 104 | 105 | test: 106 | adapter: postgresql 107 | database: rails_app_test 108 | encoding: unicode 109 | port: <%= ENV["BOXEN_POSTGRESQL_PORT"] || 5432 %> 110 | host: localhost 111 | ``` 112 | 113 | ### Redis 114 | 115 | ``` ruby 116 | # config/initializers/redis.rb 117 | 118 | $redis = Redis.new(ENV['BOXEN_REDIS_URL'] || 'redis://localhost:6379/') 119 | ``` 120 | 121 | ### Elasticsearch 122 | 123 | ``` ruby 124 | # config/initializers/elasticsearch.rb 125 | 126 | Tire.configure do 127 | url (ENV['BOXEN_ELASTICSEARCH_URL'] || 'http://localhost:9200/') 128 | end 129 | ``` 130 | 131 | ### MongoDB 132 | 133 | ``` yaml 134 | # config/mongo.yml 135 | 136 | development: 137 | host: 127.0.0.1 138 | port: <%= ENV['BOXEN_MONGODB_PORT'] || 27017 %> 139 | database: rails_app_development 140 | 141 | test: 142 | host: 127.0.0.1 143 | port: <%= ENV['BOXEN_MONGODB_PORT'] || 27017 %> 144 | database: rails_app_test 145 | ``` 146 | 147 | ### Memcached 148 | 149 | ``` ruby 150 | # config/initializers/memcached.rb 151 | 152 | $memcached = Dalli::Client.new( 153 | ENV['BOXEN_MEMCACHED_URL'] || 'memcached://localhost:11211/' 154 | ) 155 | ``` 156 | 157 | ### Unicorn 158 | 159 | ``` ruby 160 | # config/unicorn.rb 161 | 162 | if ENV['RACK_ENV'] == 'development' 163 | worker_processes 1 164 | listen "#{ENV['BOXEN_SOCKET_DIR']}/rails_app", :backlog => 1024 165 | timeout 120 166 | end 167 | 168 | after_fork do |server, worker| 169 | ActiveRecord::Base.establish_connection if defined?(ActiveRecord) 170 | end 171 | ``` 172 | 173 | ``` shell 174 | # script/server 175 | 176 | #!/bin/sh 177 | 178 | set -e 179 | 180 | cd $(dirname "$0")/.. 181 | : ${RAILS_ENV:=development} 182 | : ${RACK_ENV:=development} 183 | 184 | export RAILS_ENV RACK_ENV 185 | 186 | bin/unicorn_rails -E "$RAILS_ENV" -c config/unicorn.rb 187 | ``` 188 | 189 | -------------------------------------------------------------------------------- /docs/puppet.md: -------------------------------------------------------------------------------- 1 | # wtf is a puppet? 2 | 3 | Puppet is configuration management tool, written in Ruby, that compiles 4 | and runs code written in the Puppet language. 5 | 6 | But what does that actually mean in words a human can understand? 7 | Puppet is a tool that runs some code and that code can do all sorts of 8 | really powerful things to configure computers for you. 9 | 10 | Why do I want code mucking about with my laptop though? 11 | For the exact same reasons you want code configuring your server. 12 | In particular, homogeneity, reproducibility, reusability, and automation. 13 | When you use code to express how a machine should be configured, 14 | you know that all of your machines are configured the same way, 15 | that you can repeat that configuration any number of times, 16 | and that you don't have to do it manually each time. 17 | 18 | ## How does Puppet work? 19 | 20 | A Puppet run has two main steps: compilation and application. 21 | 22 | The compilations step starts with reading in what's called the site manifest. 23 | The site manifest is a single file that contains Puppet code that is responsible 24 | for telling the compiler what other Puppet code it should compile. 25 | 26 | Here are the first few lines of the default site manifest for Boxen: 27 | 28 | ``` 29 | include boxen::environment 30 | include homebrew 31 | include gcc 32 | ``` 33 | 34 | This tells the Puppet compiler that it must include the classes 35 | `boxen::environment`, `homebrew`, and `gcc`. 36 | Puppet will look for those classes on the modulepath. 37 | Typically, these files would be located at 38 | `$modulepath/boxen/manifests/environment.pp` and 39 | `$modulepath/homebrew/manifests/init.pp`. 40 | 41 | These might include other classes as well, or define **resources**. 42 | Resources are the building blocks of Puppet. 43 | A resource is an abstract description about a **thing** and the **state** 44 | that thing should be in. 45 | Every resource has a **type**, which is just a classification of resources. 46 | For example, we might have a resource `Package[mysql]` and its type would be 47 | `Package`. 48 | Puppet also supports multiple providers for types which act as pluggable 49 | backends depending on the operating system it's running on or the tools 50 | available on a particular system (in the case of the `Package` type, 51 | we might have providers for `yum` and for `aptget`). 52 | 53 | So now the Puppet compiler has finished tracking down and loading all the 54 | classes and resources it needs. 55 | Assuming we haven't encountered any compile-time errors, Puppet then begins 56 | the next phase of a run: applying the catalog. 57 | 58 | All of the resources Puppet has collected into the catalog have formed a 59 | DAG (directed, acyclic graph) that represents the order in which all these 60 | resources can be applied in a correct order. 61 | Puppet simply grabs the first "node" in this graph and traverses all nodes 62 | in the graph, applying each resource as it goes. 63 | 64 | Application of an individual resource starts with Puppet asking "is this 65 | resource in the state requested?" If the answer is yes, Puppet moves onto the 66 | next node and repeats this process. If the answer is no, Puppet will make 67 | whatever changes it can to reconcile the current state of the resource with 68 | what it should be, and then continues on. 69 | 70 | Once all resources have been applied, the Puppet run is complete. 71 | 72 | ## Declarative by nature 73 | 74 | One of the most confusing parts of the Puppet language to many newcomers is 75 | how the Puppet catalog orders and applies resources. 76 | The key thing to remember is that Puppet is a **declarative** language rather 77 | than a procedural one. 78 | In human words, the only order that matters in Puppet is order specified by 79 | relationships between resources. 80 | 81 | Here's an example of how someone new to Puppet might write a class: 82 | 83 | ``` puppet 84 | class mysql { 85 | file { '/etc/my.cnf': source => 'puppet:///modules/mysql/my.cnf.erb' ; } 86 | package { 'mysql': } 87 | service { 'mysql': } 88 | } 89 | ``` 90 | 91 | Someone expecting Puppet to be procedural would read this manifest as a list 92 | saying: 93 | 94 | * First create the my.cnf file 95 | * Then install the mysql package 96 | * Then start the mysql service 97 | 98 | The problem is, they would be **wrong**. 99 | There is no guarantee Puppet will apply these resources in that order, 100 | and it's quite likely that it won't. 101 | 102 | The proper way to ensure ordering in Puppet is to use one of the four 103 | **relationship metaparameters**: 104 | 105 | * before - Run this resource before another resource 106 | * notify - Same as before, but triggers a refresh on that resource 107 | * require - Run this resource after another resource 108 | * subscribe - Same as require, but triggers a refresh on that resource 109 | 110 | The behavior of these metaparameters should be pretty clear. 111 | Triggering a resource simply means that a resource will "refresh" itself. 112 | That typically means something like a `Service` resource restarting itself. 113 | It's important to remember that these metaparameters are valid on **any** resource. 114 | 115 | So, let's rewrite our example properly: 116 | 117 | ``` puppet 118 | class mysql { 119 | file { '/etc/my.cnf': 120 | source => 'puppet:///modules/mysql/my.cnf.erb', 121 | notify => Service['mysql'] 122 | } 123 | 124 | package { 'mysql': 125 | notify => Service['mysql'] 126 | } 127 | 128 | service { 'mysql': } 129 | } 130 | ``` 131 | 132 | Now we're telling Puppet what order to apply these resources in: 133 | 134 | * Make sure /etc/my.cnf is in place before we start the mysql service 135 | * If /etc/my.cnf changes, tell mysql to restart 136 | * Make sure the mysql package is in place before we start the mysql service 137 | * If the mysql package changes, tell mysql to restart 138 | 139 | It's important to note that we didn't tell Puppet if `File[/etc/my.cnf]` 140 | should come before or after `Package[mysql]`. 141 | This is intentional. 142 | Most package managers won't overwrite a configuration file that already exists 143 | at package install-time, so in this case, we can assume installing the mysql 144 | package won't clobber our custom `/etc/my.cnf` file. 145 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Our Boxen 2 | 3 | This is a template Boxen project designed for your organization to fork and 4 | modify appropriately. 5 | The Boxen rubygem and the Boxen puppet modules are only a framework for getting 6 | things done. 7 | This repository template is just a basic example of _how_ to do things with them. 8 | 9 | ## Getting Started 10 | 11 | To give you a brief overview, we're going to: 12 | 13 | * Install dependencies (basically Xcode) 14 | * Bootstrap a boxen for your self/team/org/company 15 | * Then convert your local copy of that boxen to the post-bootstrapped version 16 | 17 | There are a few potential conflicts to keep in mind. 18 | Boxen does its best not to get in the way of a dirty system, 19 | but you should check into the following before attempting to install your 20 | boxen on any machine (we do some checks before every Boxen run to try 21 | and detect most of these and tell you anyway): 22 | 23 | * Boxen __requires__ at least the Xcode Command Line Tools installed. 24 | * Boxen __will not__ work with an existing rvm install. 25 | * Boxen __may not__ play nice with a GitHub username that includes dash(-) 26 | * Boxen __may not__ play nice with an existing rbenv install. 27 | * Boxen __may not__ play nice with an existing chruby install. 28 | * Boxen __may not__ play nice with an existing homebrew install. 29 | * Boxen __may not__ play nice with an existing nvm install. 30 | * Boxen __recommends__ installing the full Xcode. 31 | 32 | ### Dependencies 33 | 34 | **Install the Xcode Command Lines Tools and/or full Xcode.** 35 | This will grant you the most predictable behavior in building apps like 36 | MacVim. 37 | 38 | How do you do it? 39 | 40 | 1. Install Xcode from the Mac App Store. 41 | 1. Open Xcode. 42 | 1. Open the Preferences window (`Cmd-,`). 43 | 1. Go to the Downloads tab. 44 | 1. Install the Command Line Tools. 45 | 46 | ### Bootstrapping 47 | 48 | Create a **new** git repository somewhere. 49 | It can be private or public -- it really doesn't matter. 50 | If you're making a repository on GitHub, you _may not_ want to fork this repo 51 | to get started. 52 | The reason for that is that you can't really make private forks of public 53 | repositories easily. 54 | 55 | Once you've done that, you can run the following to bootstrap 56 | your boxen: 57 | 58 | ``` 59 | sudo mkdir -p /opt/boxen 60 | sudo chown ${USER}:staff /opt/boxen 61 | git clone https://github.com/boxen/our-boxen /opt/boxen/repo 62 | cd /opt/boxen/repo 63 | git remote rm origin 64 | git remote add origin 65 | git push -u origin master 66 | ``` 67 | 68 | ### Distributing 69 | 70 | That's enough to get your boxen into a usable state on other machines, 71 | usually. 72 | From there, we recommend setting up 73 | [boxen-web](https://github.com/boxen/boxen-web) 74 | as an easy way to automate letting other folks install your boxen. 75 | 76 | If you _don't_ want to use boxen-web, folks can get using your boxen like so: 77 | 78 | ``` 79 | sudo mkdir -p /opt/boxen 80 | sudo chown ${USER}:staff /opt/boxen 81 | git clone /opt/boxen/repo 82 | cd /opt/boxen/repo 83 | script/boxen 84 | ``` 85 | 86 | Keep in mind this requires you to encrypt your hard drive by default. 87 | If you do not want to do encrypt your hard drive, you can use the `--no-fde`. 88 | 89 | ``` 90 | script/boxen --no-fde 91 | ``` 92 | 93 | It should run successfully, and should tell you to source a shell script 94 | in your environment. 95 | For users without a bash or zsh config or a `~/.profile` file, 96 | Boxen will create a shim for you that will work correctly. 97 | If you do have a `~/.bashrc` or `~/.zshrc`, your shell will not use 98 | `~/.profile` so you'll need to add a line like so at _the end of your config_: 99 | 100 | ``` sh 101 | [ -f /opt/boxen/env.sh ] && source /opt/boxen/env.sh 102 | ``` 103 | 104 | Once your shell is ready, open a new tab/window in your Terminal 105 | and you should be able to successfully run `boxen --env`. 106 | If that runs cleanly, you're in good shape. 107 | 108 | ## What You Get 109 | 110 | This template project provides the following by default: 111 | 112 | * Homebrew 113 | * Git 114 | * Hub 115 | * dnsmasq w/ .dev resolver for localhost 116 | * rbenv 117 | * Full Disk Encryption requirement 118 | * Node.js 0.4 119 | * Node.js 0.6 120 | * Node.js 0.8 121 | * Ruby 1.8.7 122 | * Ruby 1.9.2 123 | * Ruby 1.9.3 124 | * ack 125 | * Findutils 126 | * GNU tar 127 | 128 | ## Customizing 129 | 130 | You can always check out the number of existing modules we already 131 | provide as optional installs under the 132 | [boxen organization](https://github.com/boxen). These modules are all 133 | tested to be compatible with Boxen. Use the `Puppetfile` to pull them 134 | in dependencies automatically whenever `boxen` is run. 135 | 136 | ### Including boxen modules from github (boxen/puppet-) 137 | 138 | You must add the github information for your added Puppet module into your Puppetfile at the root of your 139 | boxen repo (ex. /path/to/your-boxen/Puppetfile): 140 | 141 | # Core modules for a basic development environment. You can replace 142 | # some/most of these if you want, but it's not recommended. 143 | 144 | github "repository", "2.0.2" 145 | github "dnsmasq", "1.0.0" 146 | github "gcc", "1.0.0" 147 | github "git", "1.2.2" 148 | github "homebrew", "1.1.2" 149 | github "hub", "1.0.0" 150 | github "inifile", "0.9.0", :repo => "cprice404/puppetlabs-inifile" 151 | github "nginx", "1.4.0" 152 | github "nodejs", "2.2.0" 153 | github "ruby", "4.1.0" 154 | github "stdlib", "4.0.2", :repo => "puppetlabs/puppetlabs-stdlib" 155 | github "sudo", "1.0.0" 156 | 157 | # Optional/custom modules. There are tons available at 158 | # https://github.com/boxen. 159 | 160 | github "java", "1.1.0" 161 | 162 | In the above snippet of a customized Puppetfile, the bottom line 163 | includes the Java module from Github using the tag "1.1.0" from the github repository 164 | "boxen/puppet-java". The function "github" is defined at the top of the Puppetfile 165 | and takes the name of the module, the version, and optional repo location: 166 | 167 | def github(name, version, options = nil) 168 | options ||= {} 169 | options[:repo] ||= "boxen/puppet-#{name}" 170 | mod name, version, :github_tarball => options[:repo] 171 | end 172 | 173 | Now Puppet knows where to download the module from when you include it in your site.pp or mypersonal.pp file: 174 | 175 | # include the java module referenced in my Puppetfile with the line 176 | # github "java", "1.1.0" 177 | include java 178 | 179 | ### Node definitions 180 | 181 | Puppet has the concept of a 182 | ['node'](http://docs.puppetlabs.com/references/glossary.html#agent), 183 | which is essentially the machine on which Puppet is running. Puppet looks for 184 | [node definitions](http://docs.puppetlabs.com/learning/agent_master_basic.html#node-definitions) 185 | in the `manifests/site.pp` file in the Boxen repo. You'll see a default node 186 | declaration that looks like the following: 187 | 188 | ``` puppet 189 | node default { 190 | # core modules, needed for most things 191 | include dnsmasq 192 | 193 | # more... 194 | } 195 | ``` 196 | 197 | ### How Boxen interacts with Puppet 198 | 199 | Boxen runs everything declared in `manifests/site.pp` by default. 200 | But just like any other source code, throwing all your work into one massive 201 | file is going to be difficult to work with. Instead, we recommend you 202 | use modules in the `Puppetfile` when you can and make new modules 203 | in the `modules/` directory when you can't. Then add `include $modulename` 204 | for each new module in `manifests/site.pp` to include them. 205 | One pattern that's very common is to create a module for your organization 206 | (e.g., `modules/github`) and put an environment class in that module 207 | to include all of the modules your organization wants to install for 208 | everyone by default. An example of this might look like so: 209 | 210 | ``` puppet 211 | # modules/github/manifests/environment.pp 212 | 213 | class github::environment { 214 | include github::apps::mac 215 | 216 | include ruby::1-8-7 217 | 218 | include projects::super-top-secret-project 219 | } 220 | ``` 221 | 222 | If you'd like to read more about how Puppet works, we recommend 223 | checking out [the official documentation](http://docs.puppetlabs.com/) 224 | for: 225 | 226 | * [Modules](http://docs.puppetlabs.com/learning/modules1.html#modules) 227 | * [Classes](http://docs.puppetlabs.com/learning/modules1.html#classes) 228 | * [Defined Types](http://docs.puppetlabs.com/learning/definedtypes.html) 229 | * [Facts](http://docs.puppetlabs.com/guides/custom_facts.html) 230 | 231 | ### Creating a personal module 232 | 233 | See [the documentation in the 234 | `modules/people`](modules/people/README.md) 235 | directory for creating per-user modules that don't need to be applied 236 | globally to everyone. 237 | 238 | ### Creating a project module 239 | 240 | See [the documentation in the 241 | `modules/projects`](modules/projects/README.md) 242 | directory for creating organization projects (i.e., repositories that people 243 | will be working in). 244 | 245 | ## Binary packages 246 | 247 | We support binary packaging for everything in Homebrew, rbenv, and nvm. 248 | See `config/boxen.rb` for the environment variables to define. 249 | 250 | ## Sharing Boxen Modules 251 | 252 | If you've got a Boxen module you'd like to be grouped under the Boxen org, 253 | (so it can easily be found by others), please file an issue on this 254 | repository with a link to your module. 255 | We'll review the code briefly, and if things look pretty all right, 256 | we'll fork it under the Boxen org and give you read+write access to our 257 | fork. 258 | You'll still be the maintainer, you'll still own the issues and PRs. 259 | It'll just be listed under the boxen org so folks can find it more easily. 260 | 261 | ## Integrating with Github Enterprise 262 | 263 | If you're using a Github Enterprise instance rather than github.com, 264 | you will need to set the `BOXEN_GITHUB_ENTERPRISE_URL` and 265 | `BOXEN_REPO_URL_TEMPLATE` variables in your 266 | [Boxen config](config/boxen.rb). 267 | 268 | ## Halp! 269 | 270 | See [FAQ](https://github.com/boxen/our-boxen/blob/master/docs/faq.md). 271 | 272 | Use Issues or #boxen on irc.freenode.net. 273 | --------------------------------------------------------------------------------