From 75985e72faa2760593267b94a673ed442bd72f57 Mon Sep 17 00:00:00 2001 From: Chris Kelly Date: Tue, 26 Jun 2012 22:48:34 -0700 Subject: [PATCH 1/9] Bare repo creation class and spec --- chef/lib/chef/knife/repo_create.rb | 9 +++++++++ chef/spec/unit/knife/repo_create_spec.rb | 6 ++++++ 2 files changed, 15 insertions(+) create mode 100644 chef/lib/chef/knife/repo_create.rb create mode 100644 chef/spec/unit/knife/repo_create_spec.rb diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb new file mode 100644 index 00000000000..5f562109853 --- /dev/null +++ b/chef/lib/chef/knife/repo_create.rb @@ -0,0 +1,9 @@ +require 'chef/knife' + +class Chef + class Knife + class RepoCreate < Knife + + end + end +end diff --git a/chef/spec/unit/knife/repo_create_spec.rb b/chef/spec/unit/knife/repo_create_spec.rb new file mode 100644 index 00000000000..a2aa4f4b525 --- /dev/null +++ b/chef/spec/unit/knife/repo_create_spec.rb @@ -0,0 +1,6 @@ +require 'spec_helper' +require 'tmpdir' + +describe Chef::Knife::RepoCreate do + +end From 141e213b680fd0185e39802e747e92b5732a1890 Mon Sep 17 00:00:00 2001 From: Chris Kelly Date: Wed, 27 Jun 2012 11:09:23 -0700 Subject: [PATCH 2/9] Create directory structure --- chef/lib/chef/knife/repo_create.rb | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb index 5f562109853..17985527c0b 100644 --- a/chef/lib/chef/knife/repo_create.rb +++ b/chef/lib/chef/knife/repo_create.rb @@ -1,9 +1,33 @@ require 'chef/knife' +require 'fileutils' class Chef class Knife class RepoCreate < Knife + banner "knife repo create REPO" + + def run + self.config = Chef::Config.merge! config + + if @name_args.length < 1 + show_usage + ui.fatal "You must specify a repo name" + exit 1 + end + + repo_name = @name_args.first + create_repo repo_name + end + + def create_repo(repo_name) + msg "** Creating repo #{repo_name}" + FileUtils.mkdir_p "#{repo_name}" + + %w[ certificates config cookbooks data_bags environments roles ].each do |dir| + FileUtils.mkdir_p "#{File.join repo_name, dir}" + end + end end end end From ecf53ecb5884031b68d08b5cf96b90290976694e Mon Sep 17 00:00:00 2001 From: Chris Kelly Date: Wed, 27 Jun 2012 14:52:24 -0700 Subject: [PATCH 3/9] Create all required directories and files --- chef/lib/chef/knife/repo_create.rb | 464 ++++++++++++++++++++++++++++- 1 file changed, 462 insertions(+), 2 deletions(-) diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb index 17985527c0b..f83fcfa97be 100644 --- a/chef/lib/chef/knife/repo_create.rb +++ b/chef/lib/chef/knife/repo_create.rb @@ -7,6 +7,11 @@ class RepoCreate < Knife banner "knife repo create REPO" + option :repo_path, + :short => "-p PATH", + :long => "--repo-path PATH", + :description => "The directory where the repo will be created" + def run self.config = Chef::Config.merge! config @@ -24,10 +29,465 @@ def create_repo(repo_name) msg "** Creating repo #{repo_name}" FileUtils.mkdir_p "#{repo_name}" - %w[ certificates config cookbooks data_bags environments roles ].each do |dir| - FileUtils.mkdir_p "#{File.join repo_name, dir}" + create_certificates repo_name + create_config repo_name + create_cookbooks repo_name + create_data_bags repo_name + create_environments repo_name + create_roles repo_name + + create_gitignore repo_name + create_root_readme repo_name + create_rakefile repo_name + create_chefignore repo_name + end + + private + + def create_dir(repo_name, dir) + FileUtils.mkdir_p "#{File.join repo_name, dir}" + end + + def create_file(repo_name, dir, filename, body) + unless File.exists?(File.join repo_name, dir, filename) + open(File.join(repo_name, dir, filename), "w") do |file| + file.puts body + end end end + + def create_certificates(repo_name) + dir = "certificates" + create_dir repo_name, dir + + readme_body = < secret_key + +You may use this secret_key to add items to a data bag during a create. + + knife data bag create --secret-file secret_key passwords mysql + +You may also use it when adding ITEMs from files, + + knife data bag create passwords + knife data bag from file passwords data_bags/passwords/mysql.json --secret-file secret_key + +The JSON for the ITEM must contain a key named "id" with a value equal to "ITEM" and the contents will be encrypted when uploaded. For example, + + { + "id": "mysql", + "password": "abc123" + } + +Without the secret_key, the contents are encrypted. + + knife data bag show passwords mysql + id: mysql + password: 2I0XUUve1TXEojEyeGsjhw== + +Use the secret_key to view the contents. + + knife data bag show passwords mysql --secret-file secret_key + id: mysql + password: abc123 +EOH + + create_file repo_name, dir, "README.md", readme_body + end + + def create_environments(repo_name) + dir = "environments" + create_dir repo_name, dir + + readme_body = <) +# Copyright:: Copyright (c) 2008 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' +require 'json' + +# Load constants from rake config file. +require File.join(File.dirname(__FILE__), 'config', 'rake') + +# Detect the version control system and assign to $vcs. Used by the update +# task in chef_repo.rake (below). The install task calls update, so this +# is run whenever the repo is installed. +# +# Comment out these lines to skip the update. + +if File.directory?(File.join(TOPDIR, ".svn")) + $vcs = :svn +elsif File.directory?(File.join(TOPDIR, ".git")) + $vcs = :git +end + +# Load common, useful tasks from Chef. +# rake -T to see the tasks this loads. + +load 'chef/tasks/chef_repo.rake' + +desc "Bundle a single cookbook for distribution" +task :bundle_cookbook => [ :metadata ] +task :bundle_cookbook, :cookbook do |t, args| + tarball_name = "\#{args.cookbook}.tar.gz" + temp_dir = File.join(Dir.tmpdir, "chef-upload-cookbooks") + temp_cookbook_dir = File.join(temp_dir, args.cookbook) + tarball_dir = File.join(TOPDIR, "pkgs") + FileUtils.mkdir_p(tarball_dir) + FileUtils.mkdir(temp_dir) + FileUtils.mkdir(temp_cookbook_dir) + + child_folders = [ "cookbooks/\#{args.cookbook}", "site-cookbooks/\#{args.cookbook}" ] + child_folders.each do |folder| + file_path = File.join(TOPDIR, folder, ".") + FileUtils.cp_r(file_path, + temp_cookbook_dir) if + + File.directory?(file_path) + end + + system("tar", "-C", temp_dir, "-cvzf", File.join(tarball_dir, tarball_name), "./\#{args.cookbook}") + + FileUtils.rm_rf temp_dir +end +EOH + create_file repo_name, dir, "Rakefile", body + end + + def create_chefignore(repo_name) + dir = "" + + body = < Date: Wed, 27 Jun 2012 17:01:24 -0700 Subject: [PATCH 4/9] Support user defined path --- chef/lib/chef/knife/repo_create.rb | 106 +++++++++++++++-------------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb index f83fcfa97be..3e44090c410 100644 --- a/chef/lib/chef/knife/repo_create.rb +++ b/chef/lib/chef/knife/repo_create.rb @@ -5,60 +5,66 @@ class Chef class Knife class RepoCreate < Knife - banner "knife repo create REPO" + banner "knife repo create REPO (options)" option :repo_path, :short => "-p PATH", - :long => "--repo-path PATH", - :description => "The directory where the repo will be created" + :long => "--repository-path PATH", + :description => "The directory where the repository will be created" def run self.config = Chef::Config.merge! config if @name_args.length < 1 show_usage - ui.fatal "You must specify a repo name" + ui.fatal "You must specify a repository name" exit 1 end repo_name = @name_args.first - create_repo repo_name + + path = config[:repo_path] || '' + path = File.expand_path(path) + + create_repo repo_name, path end - def create_repo(repo_name) + def create_repo(repo_name, path) msg "** Creating repo #{repo_name}" - FileUtils.mkdir_p "#{repo_name}" - - create_certificates repo_name - create_config repo_name - create_cookbooks repo_name - create_data_bags repo_name - create_environments repo_name - create_roles repo_name - - create_gitignore repo_name - create_root_readme repo_name - create_rakefile repo_name - create_chefignore repo_name + + repo_path = File.join path, repo_name + FileUtils.mkdir_p repo_path + + create_certificates repo_path + create_config repo_path + create_cookbooks repo_path + create_data_bags repo_path + create_environments repo_path + create_roles repo_path + + create_gitignore repo_path + create_root_readme repo_path + create_rakefile repo_path + create_chefignore repo_path end private - def create_dir(repo_name, dir) - FileUtils.mkdir_p "#{File.join repo_name, dir}" + def create_dir(repo_path, dir) + FileUtils.mkdir_p "#{File.join repo_path, dir}" end - def create_file(repo_name, dir, filename, body) - unless File.exists?(File.join repo_name, dir, filename) - open(File.join(repo_name, dir, filename), "w") do |file| + def create_file(repo_path, dir, filename, body) + unless File.exists?(File.join repo_path, dir, filename) + open(File.join(repo_path, dir, filename), "w") do |file| file.puts body end end end - def create_certificates(repo_name) + def create_certificates(repo_path) dir = "certificates" - create_dir repo_name, dir + create_dir repo_path, dir readme_body = < Date: Thu, 28 Jun 2012 09:39:51 -0700 Subject: [PATCH 5/9] Init the new repo --- chef/lib/chef/knife/repo_create.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb index 3e44090c410..88a732d68b8 100644 --- a/chef/lib/chef/knife/repo_create.rb +++ b/chef/lib/chef/knife/repo_create.rb @@ -46,6 +46,8 @@ def create_repo(repo_name, path) create_root_readme repo_path create_rakefile repo_path create_chefignore repo_path + + init_repo repo_path end private @@ -62,6 +64,10 @@ def create_file(repo_path, dir, filename, body) end end + def init_repo(repo_path) + exec "git init #{repo_path}" + end + def create_certificates(repo_path) dir = "certificates" create_dir repo_path, dir From 2840edc3c9390b9040f6bb1d2b97b7f6dcccc0ee Mon Sep 17 00:00:00 2001 From: Chris Kelly Date: Thu, 28 Jun 2012 12:55:00 -0700 Subject: [PATCH 6/9] Catch exception if git is not present and print message --- chef/lib/chef/knife/repo_create.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb index 88a732d68b8..804889d09a9 100644 --- a/chef/lib/chef/knife/repo_create.rb +++ b/chef/lib/chef/knife/repo_create.rb @@ -65,7 +65,12 @@ def create_file(repo_path, dir, filename, body) end def init_repo(repo_path) - exec "git init #{repo_path}" + begin + exec "git init #{repo_path}" + rescue Errno::ENOENT + # Skip init if git is not found + msg("** git not found: Could not initialize repository") + end end def create_certificates(repo_path) From bb08a70ea8a1e241feac4ad45578cfa8e417b6c4 Mon Sep 17 00:00:00 2001 From: Chris Kelly Date: Thu, 28 Jun 2012 13:11:24 -0700 Subject: [PATCH 7/9] Clean up create_file method to just take the path, filename and content --- chef/lib/chef/knife/repo_create.rb | 55 +++++++++++------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb index 804889d09a9..c87b94983b7 100644 --- a/chef/lib/chef/knife/repo_create.rb +++ b/chef/lib/chef/knife/repo_create.rb @@ -56,9 +56,9 @@ def create_dir(repo_path, dir) FileUtils.mkdir_p "#{File.join repo_path, dir}" end - def create_file(repo_path, dir, filename, body) - unless File.exists?(File.join repo_path, dir, filename) - open(File.join(repo_path, dir, filename), "w") do |file| + def create_file(directory, filename, body) + unless File.exists?(File.join directory, filename) + open(File.join(directory, filename), "w") do |file| file.puts body end end @@ -74,8 +74,7 @@ def init_repo(repo_path) end def create_certificates(repo_path) - dir = "certificates" - create_dir repo_path, dir + create_dir repo_path, "certificates" readme_body = < Date: Fri, 29 Jun 2012 14:24:13 -0700 Subject: [PATCH 8/9] Improve the error message for failing git init --- chef/lib/chef/knife/repo_create.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chef/lib/chef/knife/repo_create.rb b/chef/lib/chef/knife/repo_create.rb index c87b94983b7..b9cae8c8840 100644 --- a/chef/lib/chef/knife/repo_create.rb +++ b/chef/lib/chef/knife/repo_create.rb @@ -68,8 +68,8 @@ def init_repo(repo_path) begin exec "git init #{repo_path}" rescue Errno::ENOENT - # Skip init if git is not found - msg("** git not found: Could not initialize repository") + # Skip init if there is a problem + msg("** Unable to initialize git repository") end end From 77f756284cedab5f685a99eba414aaed6fe744b4 Mon Sep 17 00:00:00 2001 From: Chris Kelly Date: Fri, 29 Jun 2012 14:25:12 -0700 Subject: [PATCH 9/9] Remove repo create spec since we aren't doing anything very dynamic --- chef/spec/unit/knife/repo_create_spec.rb | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 chef/spec/unit/knife/repo_create_spec.rb diff --git a/chef/spec/unit/knife/repo_create_spec.rb b/chef/spec/unit/knife/repo_create_spec.rb deleted file mode 100644 index a2aa4f4b525..00000000000 --- a/chef/spec/unit/knife/repo_create_spec.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'spec_helper' -require 'tmpdir' - -describe Chef::Knife::RepoCreate do - -end