conan 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ Conan The Deployer
2
+ ==================
3
+
4
+ Conan will set up a project to enable you to configure servers using Chef via Capistrano.
5
+
6
+ cd /path/to/rails/app
7
+ conan init
8
+
9
+ Follow the instructions to complete configuration.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ require "conan/initializer"
3
+
4
+ case ARGV.first
5
+ when "init"
6
+ Conan::Initializer.run
7
+ puts File.read("CONAN_TODO")
8
+ else
9
+ raise "Unrecognised command: #{ARGV.first}"
10
+ end
@@ -0,0 +1,6 @@
1
+ require "bundler/capistrano"
2
+ require "conan/deployment"
3
+
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ Conan::Deployment.define_tasks(self)
6
+ end
@@ -0,0 +1,65 @@
1
+ module Conan
2
+ class Deployment
3
+ module Helpers
4
+ def with_user(new_user, &blk)
5
+ old_user = user
6
+ return if old_user == new_user
7
+ set :user, new_user
8
+ close_sessions
9
+ yield
10
+ set :user, old_user
11
+ close_sessions
12
+ end
13
+
14
+ def close_sessions
15
+ sessions.values.each { |session| session.close }
16
+ sessions.clear
17
+ end
18
+
19
+ def rake(command, options={})
20
+ path = options[:path] || current_path
21
+ run "cd #{path}; rake #{command} RAILS_ENV=#{rails_env}"
22
+ end
23
+
24
+ def git_tag(source, dest)
25
+ system "git fetch origin --tags"
26
+ sha1 = `git rev-parse "#{source}"`
27
+ system %{git update-ref "refs/tags/#{dest}" #{sha1}}
28
+ system %{git push -f origin tag #{dest}}
29
+ end
30
+
31
+ def add_role(*roles)
32
+ roles = Hash.new{ |h,k| h[k] = [] }
33
+
34
+ server_config.each do |s, c|
35
+ c["roles"].each do |r|
36
+ roles[r.to_sym] << s
37
+ end
38
+ end
39
+
40
+ roles.each do |r, ss|
41
+ next unless roles.include?(r)
42
+ ss.each_with_index do |s, i|
43
+ role r, s, :primary => (i == 0)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ class <<self
50
+ def define_tasks(context)
51
+ load_script(context, "deploy")
52
+ load_script(context, "chef")
53
+ load_script(context, "git")
54
+ end
55
+
56
+ def load_script(context, fragment)
57
+ path = File.expand_path("../deployment/#{fragment}.rb", __FILE__)
58
+ code = File.read(path)
59
+ context.instance_eval(code, path)
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ include Conan::Deployment::Helpers
@@ -0,0 +1,79 @@
1
+ require "fileutils"
2
+
3
+ namespace :chef do
4
+ task :update_aliases do
5
+ require "json"
6
+
7
+ cache_path = "tmp/cache/server_internal_addresses.json"
8
+
9
+ cache =
10
+ if File.exist?(cache_path)
11
+ JSON.parse(File.read(cache_path))
12
+ else
13
+ {}
14
+ end
15
+
16
+ aliases = {}
17
+ server_config.each do |host, config|
18
+ cache[host] ||= `ssh #{host} ifconfig`[/inet addr:(10\.\d+\.\d+\.\d+)/, 1]
19
+ aliases[config["alias"]] = cache[host]
20
+ end
21
+
22
+ FileUtils.mkdir_p File.dirname(cache_path)
23
+ File.open(cache_path, "w") do |io|
24
+ io << JSON.dump(cache)
25
+ end
26
+
27
+ File.open("deploy/chef/dna/aliases.json", "w") do |io|
28
+ io << JSON.dump({"hosts" => aliases})
29
+ end
30
+ end
31
+
32
+ before "chef:rsync", "chef:update_aliases"
33
+ task :rsync do
34
+ require "json"
35
+ require "conan/smart_hash_merge"
36
+
37
+ ssh_options = {
38
+ 'BatchMode' => 'yes',
39
+ 'CheckHostIP' => 'no',
40
+ 'ForwardAgent' => 'yes',
41
+ 'StrictHostKeyChecking' => 'no',
42
+ 'UserKnownHostsFile' => '/dev/null'
43
+ }.map{|k, v| "-o #{k}=#{v}"}.join(' ')
44
+
45
+ server_config.each do |host, config|
46
+ dna = {}
47
+ (["base", "aliases"] + config["roles"]).each do |role|
48
+ path = "deploy/chef/dna/#{role}.json"
49
+ next unless File.exist?(path)
50
+ dna = Conan::SmartHashMerge.merge(dna, JSON.parse(File.read(path)))
51
+ end
52
+
53
+ File.open("deploy/chef/dna/generated.json", "w") do |io|
54
+ io << JSON.dump(dna)
55
+ end
56
+
57
+ system "rsync -Caz --rsync-path='sudo rsync' --delete --exclude .git --exclude '.*.swp' --rsh='ssh -l ubuntu #{ssh_options}' deploy/chef/ #{host}:/etc/chef"
58
+ end
59
+ end
60
+
61
+ before "chef:bootstrap", "chef:rsync"
62
+ task :bootstrap do
63
+ with_user "ubuntu" do
64
+ run "sudo /etc/chef/bootstrap.sh"
65
+ end
66
+ end
67
+
68
+ before "chef:update", "chef:bootstrap"
69
+ task "update" do
70
+ with_user "ubuntu" do
71
+ run "sudo chef-solo -j /etc/chef/dna/generated.json"
72
+ end
73
+ end
74
+ end
75
+
76
+ desc "Install and configure server(s)"
77
+ task "configure" do
78
+ chef.update
79
+ end
@@ -0,0 +1,53 @@
1
+ require "json"
2
+ set :server_config, JSON.parse(File.read("config/servers.json"))[stage] || {}
3
+
4
+ add_role :app, :db
5
+
6
+ namespace :deploy do
7
+ task :start, :roles => :app do; end
8
+ task :stop, :roles => :app do; end
9
+
10
+ task :restart, :roles => :app do
11
+ run "touch #{current_path}/tmp/restart.txt"
12
+ end
13
+ after "deploy:restart", "deploy:cleanup"
14
+
15
+ namespace :maintenance do
16
+ task :start, :roles => :app do
17
+ run "cp #{current_path}/public/maintenance.html #{current_path}/public/system/maintenance.html || echo"
18
+ end
19
+
20
+ task :stop, :roles => :app do
21
+ run "rm -f #{current_path}/public/system/maintenance.html"
22
+ end
23
+ end
24
+
25
+ task :link_shared, :roles => :app do
26
+ shared_paths.each do |s|
27
+ run "rm -f #{release_path}/#{s}"
28
+ run "ln -nfs #{shared_path}/#{s} #{release_path}/#{s}"
29
+ end
30
+ end
31
+ after "deploy:update_code", "deploy:link_shared"
32
+
33
+ desc "Deploy and run migrations"
34
+ task :default do
35
+ maintenance.start
36
+ update_code
37
+ migrate
38
+ symlink
39
+ restart
40
+ maintenance.stop
41
+ end
42
+
43
+ task :smoke_test do
44
+ if File.exist?("test/deploy/smoke_test.rb")
45
+ system "ruby test/deploy/smoke_test.rb #{stage}"
46
+ unless $? == 0
47
+ deploy.maintenance.start
48
+ raise CommandError, "Smoke tests failed"
49
+ end
50
+ end
51
+ end
52
+ after "deploy", "deploy:smoke_test"
53
+ end
@@ -0,0 +1,11 @@
1
+ namespace :git do
2
+ before "deploy:update_code", "git:tag_attempted_deploy"
3
+ task :tag_attempted_deploy do
4
+ git_tag branch, "#{stage}.last-deploy"
5
+ end
6
+
7
+ task :tag_successful_deploy do
8
+ git_tag branch, "#{stage}.last-successful-deploy"
9
+ end
10
+ after "deploy:smoke_test", "git:tag_successful_deploy"
11
+ end
@@ -0,0 +1,55 @@
1
+ require "fileutils"
2
+
3
+ module Conan
4
+ class Initializer
5
+ TEMPLATE_PATH = File.expand_path("../template", __FILE__)
6
+ ShellCommandError = Class.new(RuntimeError)
7
+
8
+ def self.run(where=Dir.pwd)
9
+ new(where).run
10
+ end
11
+
12
+ def initialize(where)
13
+ @destination = File.expand_path(where)
14
+ end
15
+
16
+ def run
17
+ copy_template
18
+ add_gitignore
19
+ add_git_submodule
20
+ end
21
+
22
+ private
23
+ def add_gitignore
24
+ gitignore = ".gitignore"
25
+ add_newline = File.exist?(gitignore) && File.read(gitignore).match(/[^\n]\Z/)
26
+ File.open(".gitignore", "a") do |f|
27
+ f.puts if add_newline
28
+ f.puts "/deploy/chef/dna/generated.json"
29
+ f.puts "/deploy/chef/dna/aliases.json"
30
+ end
31
+ end
32
+
33
+ def add_git_submodule
34
+ return unless File.directory?(".git")
35
+ sh "git submodule add git://github.com/madebymany/cookbooks.git deploy/chef/recipes/cookbooks >/dev/null 2>&1"
36
+ end
37
+
38
+ def copy_template
39
+ Dir.chdir(TEMPLATE_PATH) do
40
+ Dir["**/*"].each do |source|
41
+ target = File.join(@destination, source)
42
+ if File.directory?(source)
43
+ FileUtils.mkdir_p target
44
+ else
45
+ FileUtils.cp source, target
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def sh(command)
52
+ system command or raise ShellCommandError, command
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ module Conan
2
+ class SmartHashMerge
3
+ def self.merge(lhash, rhash)
4
+ new(lhash, rhash).merge
5
+ end
6
+
7
+ def initialize(lhash, rhash)
8
+ @lhash, @rhash = lhash, rhash
9
+ end
10
+
11
+ def merge
12
+ lhash = @lhash.dup
13
+ deep_merge(lhash, @rhash)
14
+ end
15
+
16
+ private
17
+ def deep_merge(lhash, rhash)
18
+ merged = lhash.dup
19
+ rhash.each do |key, rvalue|
20
+ lvalue = lhash[key]
21
+ if lvalue.is_a?(Hash) and rvalue.is_a?(Hash)
22
+ merged[key] = deep_merge(lhash[key], rhash[key])
23
+ elsif lvalue.is_a?(Array) and rvalue.is_a?(Array)
24
+ merged[key] = lvalue + rvalue
25
+ elsif rvalue.is_a?(Array) && !lvalue.nil?
26
+ merged[key] = [lvalue] + rvalue
27
+ else
28
+ merged[key] = rvalue
29
+ end
30
+ end
31
+ merged
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ Conan the Deployer has set up your project.
2
+
3
+ Next, set up your deployment:
4
+
5
+ * Edit config/servers.json to specify your stages, servers, and roles
6
+
7
+ * Edit the TODOs in deploy/chef/dna/*.json
8
+
9
+ * Add stage-/role-/server-specific files in deploy/chef/dna/*.json
10
+
11
+ * Add some post-deployment tests in test/deploy/smoke_test.rb that test the
12
+ deployed app.
13
+
14
+ * Add your own recipes to deploy/chef/recipes/site-cookbooks
15
+
16
+ Finally, use Capistrano to configure your servers and deploy your application
17
+ to the desired stage:
18
+
19
+ * cap staging configure deploy
20
+
21
+ This list has been left in CONAN_TODO for you to peruse at your leisure.
@@ -0,0 +1,3 @@
1
+ load 'deploy' if respond_to?(:namespace) # cap2 differentiator
2
+ Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
3
+ load 'config/deploy'
@@ -0,0 +1,45 @@
1
+ # Configuration
2
+
3
+ # Assume that we are deploying from the "origin" remote.
4
+ set :repository, `git remote -v | grep 'origin.*fetch' | awk '{print $2}'`.chomp
5
+
6
+ # Hopefully, your application name matches the repository name.
7
+ set :application, File.basename(repository, ".git")
8
+
9
+ # Files and directories to persist between deployments:
10
+ set :shared_paths, %w[
11
+ config/database.yml
12
+ log
13
+ ]
14
+
15
+ # Your stages. The default assumes:
16
+ #
17
+ # * There is a staging and a production environment.
18
+ # * Staging is deployed from the master branch
19
+ # * Deployment to production is always made from the last branch successfully
20
+ # deployed to staging.
21
+ #
22
+
23
+ task :staging do; end
24
+ task :production do; end
25
+
26
+ case ARGV.first.to_sym
27
+ when :staging
28
+ set :stage, "staging"
29
+ set :branch, "master"
30
+ when :production
31
+ set :stage, "production"
32
+ set :branch, "staging.last-successful-deploy"
33
+ end
34
+
35
+ # You probably don't need to edit these
36
+ default_run_options[:pty] = true
37
+ set :use_sudo, false
38
+ set :deploy_via, :remote_cache
39
+ set :keep_releases, 5
40
+ set :scm, "git"
41
+ set :user, "rails"
42
+ set :deploy_to, "/mnt/#{application}"
43
+
44
+ # Let Conan take over
45
+ require "conan/capistrano"
@@ -0,0 +1,14 @@
1
+ {
2
+ "staging": {
3
+ "TODO e.g. something.amazonaws.com": {
4
+ "roles": ["app", "db", "staging"],
5
+ "alias": "staging"
6
+ }
7
+ },
8
+ "production": {
9
+ "TODO e.g. something-else.amazonaws.com": {
10
+ "roles": ["app", "db", "production"],
11
+ "alias": "app1"
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,52 @@
1
+ #!/bin/bash
2
+ # Bootstrap chef on Ubuntu 10.04
3
+
4
+ function inform {
5
+ status=$1
6
+ echo
7
+ echo -e "\e[33m• ${1}\e[0m"
8
+ echo
9
+ }
10
+
11
+ function happy_ending {
12
+ echo
13
+ echo -e "\e[32m✓ ${1}\e[0m"
14
+ exit 0
15
+ }
16
+
17
+ function croak {
18
+ echo
19
+ echo -e "\e[31m✗ $status failed. Aborting.\e[0m"
20
+ exit 1
21
+ }
22
+
23
+ command -v chef-solo >/dev/null && \
24
+ happy_ending "Chef is already bootstrapped. Nothing more to do."
25
+
26
+ inform "Updating package index"
27
+ apt-get update || croak
28
+
29
+ inform "Setting up build environment"
30
+ apt-get install -y build-essential || croak
31
+
32
+ inform "Installing Ruby Enterprise Edition"
33
+ case `uname -m` in
34
+ x86_64)
35
+ REE="http://rubyforge.org/frs/download.php/71098/ruby-enterprise_1.8.7-2010.02_amd64_ubuntu10.04.deb"
36
+ ;;
37
+ *)
38
+ REE="http://rubyforge.org/frs/download.php/71100/ruby-enterprise_1.8.7-2010.02_i386_ubuntu10.04.deb"
39
+ ;;
40
+ esac
41
+ echo "Fetching ${REE}"
42
+ curl -s -L -o ree.deb "${REE}" || croak
43
+ dpkg -i ree.deb || croak
44
+ rm ree.deb
45
+
46
+ inform "Installing Chef"
47
+ gem install -v 0.5.8 ohai --no-rdoc --no-ri || croak
48
+ gem install -v 0.9.12 chef --no-rdoc --no-ri || croak
49
+
50
+ mkdir -p /etc/chef
51
+
52
+ happy_ending "Chef has been bootstrapped!"
@@ -0,0 +1,6 @@
1
+ {
2
+ "recipes": [
3
+ "mysql::client",
4
+ "rails_app"
5
+ ]
6
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "rails_app": {
3
+ "user": "rails",
4
+ "name": "TODO",
5
+ "home": "/mnt/TODO",
6
+ "packages": [
7
+ "git-core",
8
+ "libxml2-dev",
9
+ "libxslt1-dev"
10
+ ],
11
+ "canonical_domain": "TODO e.g. www.example.com",
12
+ "domain_aliases": [
13
+ "TODO e.g. example.com"
14
+ ],
15
+ "redirections": [
16
+ "TODO e.g. ^example.com$"
17
+ ],
18
+ "database": {
19
+ "adapter": "mysql2",
20
+ "encoding": "utf8",
21
+ "collation": "utf8_general_ci"
22
+ },
23
+ "s3": {
24
+ "access_key_id": "TODO",
25
+ "secret_access_key": "TODO"
26
+ }
27
+ },
28
+ "apache": {
29
+ "listen_ports": ["80"]
30
+ },
31
+ "passenger": {
32
+ "version": "2.2.14"
33
+ },
34
+ "recipes": [
35
+ "hosts"
36
+ ]
37
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "rails_app": {
3
+ "domain_aliases": [],
4
+ "database": {
5
+ "host": "TODO",
6
+ "username": "TODO",
7
+ "password": "TODO",
8
+ "database": "TODO"
9
+ },
10
+ "s3": {
11
+ "bucket_name": "TODO"
12
+ }
13
+ }
14
+ }
15
+
@@ -0,0 +1,14 @@
1
+ {
2
+ "rails_app": {
3
+ "domain_aliases": [],
4
+ "database": {
5
+ "host": "TODO",
6
+ "username": "TODO",
7
+ "password": "TODO",
8
+ "database": "TODO"
9
+ },
10
+ "s3": {
11
+ "bucket_name": "TODO"
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,181 @@
1
+ #
2
+ # Rakefile for Chef Server Repository
3
+ #
4
+ # Author:: Adam Jacob (<adam@opscode.com>)
5
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ require File.join(File.dirname(__FILE__), 'config', 'rake')
22
+
23
+ require 'tempfile'
24
+
25
+ if File.directory?(File.join(TOPDIR, ".svn"))
26
+ $vcs = :svn
27
+ elsif File.directory?(File.join(TOPDIR, ".git"))
28
+ $vcs = :git
29
+ end
30
+
31
+ desc "Update your repository from source control"
32
+ task :update do
33
+ puts "** Updating your repository"
34
+
35
+ case $vcs
36
+ when :svn
37
+ sh %{svn up}
38
+ when :git
39
+ pull = false
40
+ pull = true if File.join(TOPDIR, ".git", "remotes", "origin")
41
+ IO.foreach(File.join(TOPDIR, ".git", "config")) do |line|
42
+ pull = true if line =~ /\[remote "origin"\]/
43
+ end
44
+ if pull
45
+ sh %{git pull}
46
+ else
47
+ puts "* Skipping git pull, no origin specified"
48
+ end
49
+ else
50
+ puts "* No SCM configured, skipping update"
51
+ end
52
+ end
53
+
54
+ desc "Test your cookbooks for syntax errors"
55
+ task :test do
56
+ puts "** Testing your cookbooks for syntax errors"
57
+
58
+ recipes = ["*cookbooks"].map { |folder|
59
+ Dir[File.join(TOPDIR, folder, "**", "*.rb")]
60
+ }.flatten
61
+
62
+ recipes.each do |recipe|
63
+ print "Testing recipe #{recipe}: "
64
+ sh %{ruby -c #{recipe}} do |ok, res|
65
+ if ! ok
66
+ raise "Syntax error in #{recipe}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ desc "Install the latest copy of the repository on this Chef Server"
73
+ task :install => [ :update, :test ] do
74
+ puts "** Installing your cookbooks"
75
+ directories = [
76
+ COOKBOOK_PATH,
77
+ SITE_COOKBOOK_PATH,
78
+ CHEF_CONFIG_PATH
79
+ ]
80
+ puts "* Creating Directories"
81
+ directories.each do |dir|
82
+ sh "sudo mkdir -p #{dir}"
83
+ sh "sudo chown root #{dir}"
84
+ end
85
+ puts "* Installing new Cookbooks"
86
+ sh "sudo rsync -rlP --delete --exclude '.svn' cookbooks/ #{COOKBOOK_PATH}"
87
+ puts "* Installing new Site Cookbooks"
88
+ sh "sudo rsync -rlP --delete --exclude '.svn' site-cookbooks/ #{SITE_COOKBOOK_PATH}"
89
+ # puts "* Installing new Chef Server Config"
90
+ # sh "sudo cp config/server.rb #{CHEF_SERVER_CONFIG}"
91
+ # puts "* Installing new Chef Client Config"
92
+ # sh "sudo cp config/client.rb #{CHEF_CLIENT_CONFIG}"
93
+ end
94
+
95
+ desc "By default, run rake test"
96
+ task :default => [ :test ]
97
+
98
+ desc "Create a new cookbook (with COOKBOOK=name, optional CB_PREFIX=site-)"
99
+ task :new_cookbook do
100
+ create_cookbook(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
101
+ end
102
+
103
+ def create_cookbook(dir)
104
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
105
+ puts "** Creating cookbook #{ENV["COOKBOOK"]}"
106
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "attributes")}"
107
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "recipes")}"
108
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "definitions")}"
109
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "libraries")}"
110
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "files", "default")}"
111
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "templates", "default")}"
112
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"))
113
+ open(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"), "w") do |file|
114
+ file.puts <<-EOH
115
+ #
116
+ # Cookbook Name:: #{ENV["COOKBOOK"]}
117
+ # Recipe:: default
118
+ #
119
+ # Copyright #{Time.now.year}, #{COMPANY_NAME}
120
+ #
121
+ EOH
122
+ case NEW_COOKBOOK_LICENSE
123
+ when :apachev2
124
+ file.puts <<-EOH
125
+ # Licensed under the Apache License, Version 2.0 (the "License");
126
+ # you may not use this file except in compliance with the License.
127
+ # You may obtain a copy of the License at
128
+ #
129
+ # http://www.apache.org/licenses/LICENSE-2.0
130
+ #
131
+ # Unless required by applicable law or agreed to in writing, software
132
+ # distributed under the License is distributed on an "AS IS" BASIS,
133
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134
+ # See the License for the specific language governing permissions and
135
+ # limitations under the License.
136
+ #
137
+ EOH
138
+ when :none
139
+ file.puts <<-EOH
140
+ # All rights reserved - Do Not Redistribute
141
+ #
142
+ EOH
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ desc "Create a new self-signed SSL certificate for FQDN=foo.example.com"
149
+ task :ssl_cert do
150
+ $expect_verbose = true
151
+ fqdn = ENV["FQDN"]
152
+ fqdn =~ /^(.+?)\.(.+)$/
153
+ hostname = $1
154
+ domain = $2
155
+ raise "Must provide FQDN!" unless fqdn && hostname && domain
156
+ puts "** Creating self signed SSL Certificate for #{fqdn}"
157
+ sh("(cd #{CADIR} && openssl genrsa 2048 > #{fqdn}.key)")
158
+ sh("(cd #{CADIR} && chmod 644 #{fqdn}.key)")
159
+ puts "* Generating Self Signed Certificate Request"
160
+ tf = Tempfile.new("#{fqdn}.ssl-conf")
161
+ ssl_config = <<EOH
162
+ [ req ]
163
+ distinguished_name = req_distinguished_name
164
+ prompt = no
165
+
166
+ [ req_distinguished_name ]
167
+ C = #{SSL_COUNTRY_NAME}
168
+ ST = #{SSL_STATE_NAME}
169
+ L = #{SSL_LOCALITY_NAME}
170
+ O = #{COMPANY_NAME}
171
+ OU = #{SSL_ORGANIZATIONAL_UNIT_NAME}
172
+ CN = #{fqdn}
173
+ emailAddress = #{SSL_EMAIL_ADDRESS}
174
+ EOH
175
+ tf.puts(ssl_config)
176
+ tf.close
177
+ sh("(cd #{CADIR} && openssl req -config '#{tf.path}' -new -x509 -nodes -sha1 -days 3650 -key #{fqdn}.key > #{fqdn}.crt)")
178
+ sh("(cd #{CADIR} && openssl x509 -noout -fingerprint -text < #{fqdn}.crt > #{fqdn}.info)")
179
+ sh("(cd #{CADIR} && cat #{fqdn}.crt #{fqdn}.key > #{fqdn}.pem)")
180
+ sh("(cd #{CADIR} && chmod 644 #{fqdn}.pem)")
181
+ end
@@ -0,0 +1 @@
1
+ This directory contains certificates created by the Rakefile.
@@ -0,0 +1,13 @@
1
+ #
2
+ # Chef Client Config File
3
+ #
4
+
5
+ log_level :info
6
+ log_location STDOUT
7
+ ssl_verify_mode :verify_none
8
+ registration_url "http://chef:4000"
9
+ openid_url "http://chef:4001"
10
+ template_url "http://chef:4000"
11
+ remotefile_url "http://chef:4000"
12
+ search_url "http://chef:4000"
13
+
@@ -0,0 +1,54 @@
1
+ ###
2
+ # Company and SSL Details
3
+ ###
4
+
5
+ # The company name - used for SSL certificates, and in srvious other places
6
+ COMPANY_NAME = "Example Com"
7
+
8
+ # The Country Name to use for SSL Certificates
9
+ SSL_COUNTRY_NAME = "US"
10
+
11
+ # The State Name to use for SSL Certificates
12
+ SSL_STATE_NAME = "Washington"
13
+
14
+ # The Locality Name for SSL - typically, the city
15
+ SSL_LOCALITY_NAME = "Seattle"
16
+
17
+ # What department?
18
+ SSL_ORGANIZATIONAL_UNIT_NAME = "Operations"
19
+
20
+ # The SSL contact email address
21
+ SSL_EMAIL_ADDRESS = "operations@example.com"
22
+
23
+ # License for new Cookbooks
24
+ # Can be :apachev2 or :none
25
+ NEW_COOKBOOK_LICENSE = :apachev2
26
+
27
+ ##########################
28
+ # Chef Repository Layout #
29
+ ##########################
30
+
31
+ # Where to find upstream cookbooks
32
+ COOKBOOK_PATH = "/var/chef/cookbooks"
33
+
34
+ # Where to find site-local modifications to upstream cookbooks
35
+ SITE_COOKBOOK_PATH = "/var/chef/site-cookbooks"
36
+
37
+ # Chef Config Path
38
+ CHEF_CONFIG_PATH = "/etc/chef"
39
+
40
+ # The location of the Chef Server Config file (on the server)
41
+ CHEF_SERVER_CONFIG = File.join(CHEF_CONFIG_PATH, "server.rb")
42
+
43
+ # The location of the Chef Client Config file (on the client)
44
+ CHEF_CLIENT_CONFIG = File.join(CHEF_CONFIG_PATH, "client.rb")
45
+
46
+ ###
47
+ # Useful Extras (which you probably don't need to change)
48
+ ###
49
+
50
+ # The top of the repository checkout
51
+ TOPDIR = File.expand_path(File.join(File.dirname(__FILE__), ".."))
52
+
53
+ # Where to store certificates generated with ssl_cert
54
+ CADIR = File.expand_path(File.join(TOPDIR, "certificates"))
@@ -0,0 +1,16 @@
1
+ #
2
+ # Chef Server Config File
3
+ #
4
+
5
+ log_level :info
6
+ log_location STDOUT
7
+ ssl_verify_mode :verify_none
8
+ registration_url "http://chef:4000"
9
+ openid_url "http://chef:4001"
10
+ template_url "http://chef:4000"
11
+ remotefile_url "http://chef:4000"
12
+ search_url "http://chef:4000"
13
+ cookbook_path [ "/var/chef/site-cookbooks", "/var/chef/cookbooks" ]
14
+ merb_log_path "/var/log/chef-server-merb.log"
15
+
16
+ Chef::Log::Formatter.show_time = false
@@ -0,0 +1,9 @@
1
+ #
2
+ # Chef Solo Config File
3
+ #
4
+
5
+ log_level :info
6
+ log_location STDOUT
7
+ file_cache_path "/var/chef/cookbooks"
8
+ ssl_verify_mode :verify_none
9
+ Chef::Log::Formatter.show_time = false
@@ -0,0 +1 @@
1
+ This directory contains cookbooks that modify upstream ones, or that are specific to your site.
@@ -0,0 +1,6 @@
1
+ log_level :info
2
+ log_location STDOUT
3
+ ssl_verify_mode :verify_none
4
+ cookbook_path ["/etc/chef/recipes/site-cookbooks", "/etc/chef/recipes/cookbooks"]
5
+ file_store_path "/etc/chef/recipes/"
6
+ file_cache_path "/etc/chef/recipes/"
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: conan
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Paul Battley
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-09 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: Set up a project to enable the configuration of servers using Chef via Capistrano.
36
+ email:
37
+ - pbattley@gmail.com
38
+ executables:
39
+ - conan
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - bin/conan
46
+ - lib/conan/capistrano.rb
47
+ - lib/conan/smart_hash_merge.rb
48
+ - lib/conan/deployment/git.rb
49
+ - lib/conan/deployment/chef.rb
50
+ - lib/conan/deployment/deploy.rb
51
+ - lib/conan/deployment.rb
52
+ - lib/conan/template/config/servers.json
53
+ - lib/conan/template/config/deploy.rb
54
+ - lib/conan/template/deploy/chef/dna/base.json
55
+ - lib/conan/template/deploy/chef/dna/staging.json
56
+ - lib/conan/template/deploy/chef/dna/app.json
57
+ - lib/conan/template/deploy/chef/dna/production.json
58
+ - lib/conan/template/deploy/chef/solo.rb
59
+ - lib/conan/template/deploy/chef/recipes/config/server.rb
60
+ - lib/conan/template/deploy/chef/recipes/config/rake.rb
61
+ - lib/conan/template/deploy/chef/recipes/config/client.rb
62
+ - lib/conan/template/deploy/chef/recipes/config/solo.rb
63
+ - lib/conan/template/deploy/chef/recipes/Rakefile
64
+ - lib/conan/template/deploy/chef/recipes/certificates/README
65
+ - lib/conan/template/deploy/chef/recipes/site-cookbooks/README
66
+ - lib/conan/template/deploy/chef/bootstrap.sh
67
+ - lib/conan/template/CONAN_TODO
68
+ - lib/conan/template/Capfile
69
+ - lib/conan/initializer.rb
70
+ - README.md
71
+ has_rdoc: true
72
+ homepage: http://github.com/madebymany/conan
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Conan The Deployer
105
+ test_files: []
106
+