summaryrefslogtreecommitdiff
path: root/lib/chef/tasks/chef_repo.rake
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/tasks/chef_repo.rake')
-rw-r--r--lib/chef/tasks/chef_repo.rake334
1 files changed, 334 insertions, 0 deletions
diff --git a/lib/chef/tasks/chef_repo.rake b/lib/chef/tasks/chef_repo.rake
new file mode 100644
index 0000000000..6f839a486f
--- /dev/null
+++ b/lib/chef/tasks/chef_repo.rake
@@ -0,0 +1,334 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'rubygems'
+require 'chef/json_compat'
+require 'chef'
+require 'chef/role'
+require 'chef/cookbook/metadata'
+require 'tempfile'
+require 'rake'
+
+# Allow REMOTE options to be overridden on the command line
+REMOTE_HOST = ENV["REMOTE_HOST"] if ENV["REMOTE_HOST"] != nil
+REMOTE_SUDO = ENV["REMOTE_SUDO"] if ENV["REMOTE_SUDO"] != nil
+if defined? REMOTE_HOST
+ REMOTE_PATH_PREFIX = "#{REMOTE_HOST}:"
+ REMOTE_EXEC_PREFIX = "ssh #{REMOTE_HOST}"
+ REMOTE_EXEC_PREFIX += " sudo" if defined? REMOTE_SUDO
+ LOCAL_EXEC_PREFIX = ""
+else
+ REMOTE_PATH_PREFIX = ""
+ REMOTE_EXEC_PREFIX = ""
+ LOCAL_EXEC_PREFIX = "sudo"
+end
+
+desc "Update your repository from source control"
+task :update do
+ puts "** Updating your repository"
+
+ case $vcs
+ when :svn
+ sh %{svn up}
+ when :git
+ pull = false
+ IO.foreach(File.join(TOPDIR, ".git", "config")) do |line|
+ pull = true if line =~ /\[remote "origin"\]/
+ end
+ if pull
+ sh %{git pull}
+ else
+ puts "* Skipping git pull, no origin specified"
+ end
+ else
+ puts "* No SCM configured, skipping update"
+ end
+end
+
+desc "Install the latest copy of the repository on this Chef Server"
+task :install => [ :update, :roles, :upload_cookbooks ] do
+ if File.exists?(File.join(TOPDIR, "config", "server.rb"))
+ puts "* Installing new Chef Server Config"
+ sh "#{LOCAL_EXEC_PREFIX} rsync -rlt --delete --exclude '.svn' --exclude '.git*' config/server.rb #{REMOTE_PATH_PREFIX}#{CHEF_SERVER_CONFIG}"
+ end
+ if File.exists?(File.join(TOPDIR, "config", "client.rb"))
+ puts "* Installing new Chef Client Config"
+ sh "#{LOCAL_EXEC_PREFIX} rsync -rlt --delete --exclude '.svn' --exclude '.git*' config/client.rb #{REMOTE_PATH_PREFIX}#{CHEF_CLIENT_CONFIG}"
+ end
+end
+
+desc "By default, run rake test_cookbooks"
+task :default => [ :test_cookbooks ]
+
+desc "Create a new cookbook (with COOKBOOK=name, optional CB_PREFIX=site-)"
+task :new_cookbook do
+ puts "***WARN: rake new_cookbook is deprecated. Please use 'knife cookbook create COOKBOOK' command.***"
+ create_cookbook(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
+ create_readme(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
+ create_metadata(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
+end
+
+def create_cookbook(dir)
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
+ puts "** Creating cookbook #{ENV["COOKBOOK"]}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "attributes")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "recipes")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "definitions")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "libraries")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "resources")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "providers")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "files", "default")}"
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "templates", "default")}"
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"))
+ open(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"), "w") do |file|
+ file.puts <<-EOH
+#
+# Cookbook Name:: #{ENV["COOKBOOK"]}
+# Recipe:: default
+#
+# Copyright #{Time.now.year}, #{COMPANY_NAME}
+#
+EOH
+ case NEW_COOKBOOK_LICENSE
+ when :apachev2
+ file.puts <<-EOH
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+EOH
+ when :none
+ file.puts <<-EOH
+# All rights reserved - Do Not Redistribute
+#
+EOH
+ end
+ end
+ end
+end
+
+def create_readme(dir)
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
+ puts "** Creating README for cookbook: #{ENV["COOKBOOK"]}"
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "README.rdoc"))
+ open(File.join(dir, ENV["COOKBOOK"], "README.md"), "w") do |file|
+ file.puts <<-EOH
+Description
+===========
+
+Requirements
+============
+
+Attributes
+==========
+
+Usage
+=====
+
+EOH
+ end
+ end
+end
+
+def create_metadata(dir)
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
+ puts "** Creating metadata for cookbook: #{ENV["COOKBOOK"]}"
+
+ case NEW_COOKBOOK_LICENSE
+ when :apachev2
+ license = "Apache 2.0"
+ when :none
+ license = "All rights reserved"
+ end
+
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "metadata.rb"))
+ open(File.join(dir, ENV["COOKBOOK"], "metadata.rb"), "w") do |file|
+ if File.exists?(File.join(dir, ENV["COOKBOOK"], 'README.rdoc'))
+ long_description = "long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))"
+ end
+ file.puts <<-EOH
+maintainer "#{COMPANY_NAME}"
+maintainer_email "#{SSL_EMAIL_ADDRESS}"
+license "#{license}"
+description "Installs/Configures #{ENV["COOKBOOK"]}"
+#{long_description}
+version "0.1"
+EOH
+ end
+ end
+end
+
+desc "Create a new self-signed SSL certificate for FQDN=foo.example.com"
+task :ssl_cert do
+ $expect_verbose = true
+ fqdn = ENV["FQDN"]
+ fqdn =~ /^(.+?)\.(.+)$/
+ hostname = $1
+ domain = $2
+ keyfile = fqdn.gsub("*", "wildcard")
+ raise "Must provide FQDN!" unless fqdn && hostname && domain
+ puts "** Creating self signed SSL Certificate for #{fqdn}"
+ sh("(cd #{CADIR} && openssl genrsa 2048 > #{keyfile}.key)")
+ sh("(cd #{CADIR} && chmod 644 #{keyfile}.key)")
+ puts "* Generating Self Signed Certificate Request"
+ tf = Tempfile.new("#{keyfile}.ssl-conf")
+ ssl_config = <<EOH
+[ req ]
+distinguished_name = req_distinguished_name
+prompt = no
+
+[ req_distinguished_name ]
+C = #{SSL_COUNTRY_NAME}
+ST = #{SSL_STATE_NAME}
+L = #{SSL_LOCALITY_NAME}
+O = #{COMPANY_NAME}
+OU = #{SSL_ORGANIZATIONAL_UNIT_NAME}
+CN = #{fqdn}
+emailAddress = #{SSL_EMAIL_ADDRESS}
+EOH
+ tf.puts(ssl_config)
+ tf.close
+ sh("(cd #{CADIR} && openssl req -config '#{tf.path}' -new -x509 -nodes -sha1 -days 3650 -key #{keyfile}.key > #{keyfile}.crt)")
+ sh("(cd #{CADIR} && openssl x509 -noout -fingerprint -text < #{keyfile}.crt > #{keyfile}.info)")
+ sh("(cd #{CADIR} && cat #{keyfile}.crt #{keyfile}.key > #{keyfile}.pem)")
+ sh("(cd #{CADIR} && chmod 644 #{keyfile}.pem)")
+end
+
+rule(%r{\b(?:site-)?cookbooks/[^/]+/metadata\.json\Z} => [ proc { |task_name| task_name.sub(/\.[^.]+$/, '.rb') } ]) do |t|
+ system("knife cookbook metadata from file #{t.source}")
+end
+
+desc "Build cookbook metadata.json from metadata.rb"
+task :metadata => FileList[File.join(TOPDIR, '*cookbooks', ENV['COOKBOOK'] || '*', 'metadata.rb')].pathmap('%X.json')
+
+rule(%r{\broles/\S+\.json\Z} => [ proc { |task_name| task_name.sub(/\.[^.]+$/, '.rb') } ]) do |t|
+ system("knife role from file #{t.source}")
+end
+
+desc "Update roles"
+task :roles => FileList[File.join(TOPDIR, 'roles', '**', '*.rb')].pathmap('%X.json')
+
+desc "Update a specific role"
+task :role, :role_name do |t, args|
+ system("knife role from file #{File.join(TOPDIR, 'roles', args.role_name)}.rb")
+end
+
+desc "Upload all cookbooks"
+task :upload_cookbooks => [ :metadata ]
+task :upload_cookbooks do
+ system("knife cookbook upload --all")
+end
+
+desc "Upload a single cookbook"
+task :upload_cookbook => [ :metadata ]
+task :upload_cookbook, :cookbook do |t, args|
+ system("knife cookbook upload #{args.cookbook}")
+end
+
+desc "Test all cookbooks"
+task :test_cookbooks do
+ system("knife cookbook test --all")
+end
+
+desc "Test a single cookbook"
+task :test_cookbook, :cookbook do |t, args|
+ system("knife cookbook test #{args.cookbook}")
+end
+
+namespace :databag do
+ path = "data_bags"
+
+ desc "Upload a single databag"
+ task :upload, :databag do |t, args|
+ input_databag = args[:databag] || 'none_specified'
+ databag = File.join(path, input_databag)
+
+ if File.exists?(databag) && File.directory?(databag)
+ system "knife data bag create #{input_databag}"
+ Dir.foreach(databag) do |item|
+ name, type = item.split('.')
+ if type == 'json' && name.length > 0
+ system "knife data bag from file #{input_databag} " + File.join(databag, item)
+ end
+ end
+ else
+ puts "ERROR: Could not find the databag in your databag path (" + File.join(path, input_databag) + "), skipping it"
+ end
+ end
+
+ desc "Upload all databags"
+ task :upload_all do
+ if File.exists?(path) && File.directory?(path)
+ Dir.foreach(path) do |databag|
+ if databag == databag[/^[\-[:alnum:]_]+$/]
+ Rake::Task['databag:upload'].execute( { :databag => databag } )
+ end
+ end
+ else
+ puts "ERROR: Could not find any databags, skipping it"
+ end
+ end
+
+ desc "Create a databag"
+ task :create, :databag do |t, args|
+ input_databag = args[:databag] || 'none_specified'
+
+ FileUtils.mkdir(path) unless File.exists?(path)
+ databag = File.join(path, input_databag)
+ FileUtils.mkdir(databag) unless File.exists?(databag)
+ end
+
+ desc "Create a databag item stub"
+ task :create_item, :databag, :item do |t, args|
+ input_databag = args[:databag] || 'none_specified'
+ input_item = args[:item] || false
+
+ databag = File.join(path, input_databag)
+ if File.exists?(databag) && File.directory?(databag)
+ if input_item
+ json_filename = File.join(databag, "#{input_item}.json")
+ if !File.exists?(json_filename)
+ stub = <<EOH
+{
+ "id" : "#{input_item}"
+}
+EOH
+ json_file = File.new(json_filename, "w")
+ json_file.write(stub)
+ json_file.close
+ else
+ puts "ERROR: databag item already exists (#{json_filename}), skipping it"
+ end
+ else
+ puts "ERROR: No item id specified, skipping it"
+ end
+ else
+ puts "ERROR: Could not find your databag (#{databag}), skipping it"
+ end
+ end
+
+end
+