toque 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 728adde958810a994d9d16b9d51d2f8cd31ef9dd
4
+ data.tar.gz: f56fb4afebd0bfc9defe5a9e995a4f26a4466f17
5
+ SHA512:
6
+ metadata.gz: 2c689a0d5f297ed1cbd9c4fba502ecf4ab918770afe4eef89c936d1a207dc3593d85e476c5ce127a2e384d1d23d50cb036d4c46c905b0fc938c02cd16ada185f
7
+ data.tar.gz: d13815fc714a02a45cb16a4fb3a783e970b3761910b5387078a3aa8464cf0401104fcc7de1b1b21b5b39716174ad1ca826e4af7b6b9269b9e2a4561ee1c297cd
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.iml
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ .idea
8
+ .vagrant
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
data/Capfile ADDED
@@ -0,0 +1,3 @@
1
+ load 'deploy'
2
+ load 'spec/config/deploy'
3
+ require 'toque'
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in toque.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'vagrant', '>= 1.0.7'
10
+ gem 'bundler', '~> 1.3'
11
+ gem 'capistrano-spec', github: 'jgraichen/capistrano-spec'
12
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jan Graichen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,109 @@
1
+ # Toque - The cap of a Chef
2
+
3
+ [![Build Status](https://travis-ci.org/jgraichen/toque.png?branch=master)](https://travis-ci.org/jgraichen/toque)
4
+
5
+ **Toque** combines the power of *chef-solo* and *capistrano*. It allows you to
6
+ run chef cookbooks with chef-solo as part of your capistrano deploy process.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'toque'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install toque
21
+
22
+ After capifying your project add to your `Capfile`:
23
+
24
+ ```ruby
25
+ require 'toque'
26
+ ```
27
+
28
+ You can install chef by running `cap toque:chef:install` otherwise it will be
29
+ installed on first `run_list` call. **Toque** uses chef omnibus installer to
30
+ install a complete self-contained embedded chef environment.
31
+
32
+ You can specify a specific chef version by setting `:chef_version` to
33
+ something different to `:latest` or `nil`. An already installed version of
34
+ chef will not be upgraded.
35
+
36
+ See `cap toque:config` for more options.
37
+
38
+ ## Usage
39
+
40
+ **Toque** assumes your cookbooks to be in `config/cookbooks` or
41
+ `vendor/cookbooks`. One way is to use `config/cookbooks` for your own
42
+ application cookbook(s) and `vendor/cookbooks` for community cookbooks managed
43
+ by [librarian-chef](https://github.com/applicationsonline/librarian-chef).
44
+
45
+ You can configure *librarian-chef* to use `vendor/cookbooks` as cookbook path:
46
+
47
+ ```bash
48
+ $ librarian-chef config path ./vendor/cookbooks --local
49
+ ```
50
+
51
+ In your deploy configuration you can now run `toque.run_list` with a list of
52
+ recipes you want to execute. You can run chef more then once with different
53
+ list.
54
+
55
+ For example if you want to setup the server before deploying your app run
56
+ your setup recipe right at the start:
57
+
58
+ ```ruby
59
+ before "deploy:update_code" do
60
+ toque.run_list 'recipe[awesome::setup]'
61
+ end
62
+ ```
63
+
64
+ After deploying your app you may need to create a config for your application
65
+ like `database.yml` or redis configuration:
66
+
67
+ after "deploy:create_symlink" do
68
+ toque.run_list 'recipe[awesome::configure]'
69
+ end
70
+
71
+ ## Configuration
72
+
73
+ By default all capistrano options are available in your node configuration:
74
+
75
+ ```ruby
76
+ # config/deploy.rb
77
+
78
+ set :application, 'awesomeium'
79
+ set :deploy_to, "/var/www/#{application}"
80
+ set :user, 'awesomeix'
81
+
82
+ # config/cookbooks/awesome/recipes/configure.rb
83
+
84
+ template File.join(node[:deploy_to], 'config', 'database.yml') do
85
+ source 'database.yml.erb'
86
+ owner node[:user]
87
+ recursive true
88
+ end
89
+ ```
90
+
91
+ ## Thanks
92
+
93
+ Thanks to [roundsman](https://github.com/iain/roundsman) doing even some more
94
+ tasks like installing ruby and chef via rubygems. I've decided to make up
95
+ something new to use omnibus installer right from the start.
96
+
97
+ Also take a look at
98
+ [capistrano-spec](https://github.com/technicalpickles/capistrano-spec) allowing
99
+ some really great capistrano testing.
100
+
101
+ ## Contributing
102
+
103
+ 1. Fork it
104
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
105
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
106
+ 4. Push to the branch (`git push origin my-new-feature`)
107
+ 5. Create new Pull Request
108
+
109
+ You can run a simple vagrant based test by running `bundle exec rspec spec/spec_toque.rb`.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,99 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant::Config.run do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = 'precise32'
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ config.vm.box_url = 'http://files.vagrantup.com/precise32.box'
15
+
16
+ # Boot with a GUI so you can see the screen. (Default is headless)
17
+ # config.vm.boot_mode = :gui
18
+
19
+ # Assign this VM to a host-only network IP, allowing you to access it
20
+ # via the IP. Host-only networks can talk to the host machine as well as
21
+ # any other machines on the same network, but cannot be accessed (through this
22
+ # network interface) by any external networks.
23
+ config.vm.network :hostonly, "192.168.33.10"
24
+
25
+ # Assign this VM to a bridged network, allowing you to connect directly to a
26
+ # network using the host's network device. This makes the VM appear as another
27
+ # physical device on your network.
28
+ # config.vm.network :bridged
29
+
30
+ # Forward a port from the guest to the host, which allows for outside
31
+ # computers to access the VM, whereas host only networking does not.
32
+ # config.vm.forward_port 80, 8080
33
+
34
+ # Share an additional folder to the guest VM. The first argument is
35
+ # an identifier, the second is the path on the guest to mount the
36
+ # folder, and the third is the path on the host to the actual folder.
37
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
38
+
39
+ # Enable provisioning with Puppet stand alone. Puppet manifests
40
+ # are contained in a directory path relative to this Vagrantfile.
41
+ # You will need to create the manifests directory and a manifest in
42
+ # the file base.pp in the manifests_path directory.
43
+ #
44
+ # An example Puppet manifest to provision the message of the day:
45
+ #
46
+ # # group { "puppet":
47
+ # # ensure => "present",
48
+ # # }
49
+ # #
50
+ # # File { owner => 0, group => 0, mode => 0644 }
51
+ # #
52
+ # # file { '/etc/motd':
53
+ # # content => "Welcome to your Vagrant-built virtual machine!
54
+ # # Managed by Puppet.\n"
55
+ # # }
56
+ #
57
+ # config.vm.provision :puppet do |puppet|
58
+ # puppet.manifests_path = "manifests"
59
+ # puppet.manifest_file = "base.pp"
60
+ # end
61
+
62
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
63
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
64
+ # some recipes and/or roles.
65
+ #
66
+ # config.vm.provision :chef_solo do |chef|
67
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
68
+ # chef.roles_path = "../my-recipes/roles"
69
+ # chef.data_bags_path = "../my-recipes/data_bags"
70
+ # chef.add_recipe "mysql"
71
+ # chef.add_role "web"
72
+ #
73
+ # # You may also specify custom JSON attributes:
74
+ # chef.json = { :mysql_password => "foo" }
75
+ # end
76
+
77
+ # Enable provisioning with chef server, specifying the chef server URL,
78
+ # and the path to the validation key (relative to this Vagrantfile).
79
+ #
80
+ # The Opscode Platform uses HTTPS. Substitute your organization for
81
+ # ORGNAME in the URL and validation key.
82
+ #
83
+ # If you have your own Chef Server, use the appropriate URL, which may be
84
+ # HTTP instead of HTTPS depending on your configuration. Also change the
85
+ # validation key to validation.pem.
86
+ #
87
+ # config.vm.provision :chef_client do |chef|
88
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
89
+ # chef.validation_key_path = "ORGNAME-validator.pem"
90
+ # end
91
+ #
92
+ # If you're using the Opscode platform, your validator client is
93
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
94
+ #
95
+ # IF you have your own Chef Server, the default validation client name is
96
+ # chef-validator, unless you changed the configuration.
97
+ #
98
+ # chef.validation_client_name = "ORGNAME-validator"
99
+ end
@@ -0,0 +1,18 @@
1
+ require 'capistrano'
2
+
3
+ require 'toque/version'
4
+ require 'toque/helpers'
5
+ require 'toque/tasks'
6
+ require 'toque/chef'
7
+
8
+ module Toque
9
+ def self.load_into(configuration)
10
+ Toque::Helpers.load_into configuration
11
+ Toque::Tasks.load_into configuration
12
+ Toque::Chef.load_into configuration
13
+ end
14
+ end
15
+
16
+ if Capistrano::Configuration.instance
17
+ Toque.load_into Capistrano::Configuration.instance
18
+ end
@@ -0,0 +1,145 @@
1
+ require 'tempfile'
2
+
3
+ module Toque
4
+
5
+ # Tasks and method to interact with chef.
6
+ #
7
+ module Chef
8
+ def self.load_into(configuration)
9
+ configuration.load do
10
+
11
+ namespace :toque do
12
+ namespace :chef do
13
+
14
+ set_default :chef_omnibus_installer_url, 'http://www.opscode.com/chef/install.sh'
15
+ set_default :cookbooks_paths, %w(config/cookbooks vendor/cookbooks)
16
+ set_default :databags_path, 'config/databags'
17
+ set_default :chef_version, :latest
18
+ set_default :chef_debug, false
19
+ set_default :chef_solo, '/opt/chef/bin/chef-solo'
20
+
21
+ # Check if chef-solo installed on remote machine.
22
+ #
23
+ def installed?
24
+ !installed_version.nil?
25
+ end
26
+
27
+ # Return installed chef-solo version.
28
+ #
29
+ def installed_version
30
+ capture("#{chef_solo} -v || true") =~ /Chef: (\d+\.\d+\.\d+)/ ? $1 : nil
31
+ end
32
+
33
+ # Return path to chef solo executable.
34
+ #
35
+ def chef_solo
36
+ fetch(:chef_solo).to_s || 'chef-solo'
37
+ end
38
+
39
+ # Return list of current recipes in run_list.
40
+ #
41
+ def recipes
42
+ Array fetch(:run_list)
43
+ end
44
+
45
+ # Return list of existing cookbook paths.
46
+ #
47
+ def cookbooks_paths
48
+ fetch(:cookbooks_paths).to_a.select { |path| File.exists? path }
49
+ end
50
+
51
+ # Abort if no existing cookbook paths are setted.
52
+ #
53
+ def ensure_cookbooks!
54
+ raise 'No existing cookbook paths found.' if cookbooks_paths.empty?
55
+ end
56
+
57
+ # Return existing databag path or nil if path does not exist.
58
+ #
59
+ def databags_path
60
+ File.exists?((path = fetch(:databags_path))) ? path : nil
61
+ end
62
+
63
+ # Create and return omnibus installer command
64
+ #
65
+ def install_command
66
+ cmd = "#{top.sudo} bash"
67
+ cmd += " -s -- -v #{fetch :chef_version}" unless fetch(:chef_version) == :latest or fetch(:chef_version).nil?
68
+ cmd
69
+ end
70
+
71
+ #
72
+ # Tasks
73
+ #
74
+
75
+ desc 'Install chef via omnibus installed if not preset.'
76
+ task :check do
77
+ install unless installed?
78
+ end
79
+
80
+ desc 'Installs chef using omnibus installer.'
81
+ task :install do
82
+ require_curl
83
+ run "#{top.sudo} true && curl -L #{fetch :chef_omnibus_installer_url} | #{install_command}"
84
+ end
85
+
86
+ namespace :setup do
87
+ desc 'Upload local cookbook to remote server.'
88
+ task :cookbooks do
89
+ pwd!
90
+
91
+ tar = ::Tempfile.new("cookbooks.tar")
92
+ begin
93
+ tar.close
94
+ system "tar -cjf #{tar.path} #{cookbooks_paths.join(' ')} #{databags_path.to_s}"
95
+ upload tar.path, toque.pwd("cookbooks.tar"), :via => :scp
96
+ run "cd #{toque.pwd} && tar -xjf cookbooks.tar"
97
+ ensure
98
+ tar.unlink
99
+ end
100
+ end
101
+
102
+ desc 'Generate and upload chef solo script.'
103
+ task :script do
104
+ pwd!
105
+
106
+ cookbooks = cookbooks_paths.map { |p| %("#{pwd p}") }.join(', ')
107
+ solo = <<-HEREDOC
108
+ file_cache_path "#{pwd! 'cache'}"
109
+ cookbook_path [ #{cookbooks} ]
110
+ data_bag_path "#{pwd databags_path}"
111
+ HEREDOC
112
+ put solo, pwd("node.rb"), :via => :scp
113
+ end
114
+
115
+ desc 'Generate and upload node json configuration.'
116
+ task :configuration do
117
+ pwd!
118
+
119
+ attrs = variables.dup
120
+ attrs[:run_list] = recipes
121
+ put attrs.to_json, pwd("node.json"), :via => :scp
122
+ end
123
+ end
124
+
125
+ desc 'Run list of recipes from `:run_list` option.'
126
+ task :run_list do
127
+ ensure_cookbooks!
128
+
129
+ check
130
+ setup.cookbooks
131
+ setup.script
132
+ setup.configuration
133
+
134
+ logger.info "Now running #{recipes.join(', ')}"
135
+
136
+ sudo "#{chef_solo} -c #{pwd "node.rb"} -j #{pwd "node.json"}#{' -l debug' if fetch(:chef_debug)}"
137
+ end
138
+
139
+ end
140
+ end
141
+
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,69 @@
1
+ module Toque
2
+
3
+ # Toque helpers
4
+ #
5
+ module Helpers
6
+ def self.load_into(configuration)
7
+ configuration.load do
8
+
9
+ namespace :toque do
10
+
11
+ # Set toque default variable.
12
+ #
13
+ def set_default(variable, *args, &block)
14
+ @_toque_variables ||= []
15
+ @_toque_overridden ||= []
16
+ @_toque_variables << variable
17
+ if exists? variable
18
+ @_toque_overridden << variable
19
+ else
20
+ set variable, *args, &block
21
+ end
22
+ end
23
+
24
+ # Return toque remote working directory.
25
+ #
26
+ def pwd(*path)
27
+ File.join(fetch(:toque_pwd).to_s, *path.map(&:to_s))
28
+ end
29
+ set_default :toque_pwd, '/tmp/toque'
30
+
31
+ # Return toque remote working directory. Will be created remotely if not existing.
32
+ #
33
+ def pwd!(*path)
34
+ run "mkdir -p #{pwd = pwd(*path)}"
35
+ pwd
36
+ end
37
+
38
+ # Search if curl is present
39
+ #
40
+ def curl?
41
+ !(capture('curl || true') =~ /not found/)
42
+ end
43
+
44
+ # Install curl if not present
45
+ #
46
+ def require_curl
47
+ sudo 'apt-get install --no-install-recommends -yq curl' unless curl?
48
+ end
49
+
50
+ desc 'List current toque configuration'
51
+ task :config do
52
+ @_toque_variables.sort_by(&:to_s).each do |name|
53
+ display_name = ":#{name},".ljust(30)
54
+ if variables[name].is_a?(Proc)
55
+ value = "<block>"
56
+ else
57
+ value = fetch(name).inspect
58
+ value = "#{value[0..40]}... (truncated)" if value.length > 40
59
+ end
60
+ overridden = @_toque_overridden.include?(name) ? " (overridden)" : ""
61
+ puts "set #{display_name} #{value}#{overridden}"
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,20 @@
1
+ module Toque
2
+ module Tasks
3
+ def self.load_into(configuration)
4
+ configuration.load do
5
+
6
+ namespace :toque do
7
+
8
+ # Run list of recipes. Install chef if not already preset.
9
+ #
10
+ def run_list(*recipes)
11
+ set :run_list, recipes
12
+ chef.run_list
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ module Toque
2
+ module VERSION
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
+ STAGE = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
9
+
10
+ def self.to_s; STRING end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+
2
+ bash 'Be awesome!' do
3
+ cwd node[:toque_pwd]
4
+ code <<-EOH
5
+ touch awesome
6
+ EOH
7
+ creates "#{node[:toque_pwd]}/awesome"
8
+ end
@@ -0,0 +1,7 @@
1
+
2
+ bash 'Be awesome again!' do
3
+ cwd node[:toque_pwd]
4
+ code <<-EOH
5
+ rm -f awesome
6
+ EOH
7
+ end
@@ -0,0 +1,35 @@
1
+ require 'vagrant'
2
+
3
+ set :application, 'awesomeium'
4
+
5
+ set :repository, '.'
6
+ set :scm, :none # not recommended in production
7
+ set :deploy_via, :copy
8
+
9
+ server '192.168.33.10', :web, :app, :db, :primary => true
10
+
11
+ set :user, 'vagrant'
12
+ set :password, 'vagrant' # not recommended in production
13
+
14
+ set :deploy_to, "/home/#{user}/#{application}"
15
+
16
+ set :use_sudo, false
17
+ default_run_options[:pty] = true
18
+
19
+ # Toque options
20
+ set :cookbooks_paths, %w(spec/config/cookbooks)
21
+
22
+ namespace :vagrant do
23
+ task :up do
24
+ Vagrant::Environment.new.cli 'up'
25
+ end
26
+
27
+ task :destroy do
28
+ Vagrant::Environment.new.cli 'destroy'
29
+ end
30
+ end
31
+
32
+ task :spec do
33
+ toque.run_list "recipe[awesomeium]"
34
+ end
35
+ before 'spec', 'vagrant:up'
@@ -0,0 +1,16 @@
1
+ require 'capistrano-spec'
2
+ require 'toque'
3
+
4
+ Dir[File.expand_path('spec/support/**/*.rb')].each {|f| require f}
5
+
6
+ RSpec.configure do |config|
7
+ config.include Capistrano::Spec::Matchers
8
+ config.include Capistrano::Spec::Helpers
9
+
10
+ config.order = "random"
11
+
12
+ config.expect_with :rspec do |c|
13
+ # Only allow expect syntax
14
+ c.syntax = :expect
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'vagrant'
3
+
4
+ describe Toque do
5
+
6
+ before do
7
+ @vagrant = Vagrant::Environment.new
8
+ @vagrant.cli 'up'
9
+
10
+ @configuration = Capistrano::Configuration.new
11
+ Toque.load_into(@configuration)
12
+
13
+ @configuration.load do
14
+
15
+ server '192.168.33.10', :web, :app, :db, :primary => true
16
+ set :user, 'vagrant'
17
+ set :password, 'vagrant'
18
+
19
+ set :use_sudo, false
20
+ default_run_options[:pty] = true
21
+
22
+ # Toque options
23
+ set :cookbooks_paths, %w(spec/config/cookbooks)
24
+ set :chef_version, '10.24.0'
25
+
26
+ task :awesome! do
27
+ toque.run_list 'recipe[awesomeium]'
28
+ end
29
+
30
+ task :awesome_the_second! do
31
+ toque.run_list 'recipe[awesomeium::second]'
32
+ end
33
+ end
34
+
35
+ @configuration.sudo 'apt-get remove -yq curl'
36
+ @configuration.sudo 'apt-get autoremove -yq'
37
+ end
38
+
39
+ it 'should write an awesome file' do
40
+ @configuration.awesome!
41
+
42
+ # should have installed chef version
43
+ expect(@configuration.capture('/opt/chef/bin/chef-solo -v').strip).to be == 'Chef: 10.24.0'
44
+
45
+ # should have executed cookbook and created an awesome file
46
+ file_exists = @vagrant.primary_vm.channel.sudo 'ls /tmp/toque/awesome'
47
+ expect(file_exists).to be == 0
48
+
49
+ @configuration.awesome_the_second!
50
+
51
+ file_exists = @vagrant.primary_vm.channel.sudo 'ls /tmp/toque/awesome', :error_check => false
52
+ expect(file_exists).to_not be == 0
53
+ end
54
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ describe Toque::Chef, 'loaded into capistrano' do
4
+ before do
5
+ @configuration = Capistrano::Configuration.new
6
+ @configuration.extend Capistrano::Spec::ConfigurationExtension
7
+ Toque.load_into(@configuration)
8
+ end
9
+
10
+ it 'should define default omnibus installer URL' do
11
+ expect(@configuration.fetch :chef_omnibus_installer_url).to be == 'http://www.opscode.com/chef/install.sh'
12
+ end
13
+
14
+ it "defines toque:chef:install task" do
15
+ expect(@configuration.find_task 'toque:chef:install').to_not be_nil
16
+ end
17
+
18
+ describe '#installed?' do
19
+ it 'detect if chef-solo is not installed' do
20
+ expect(@configuration.toque.chef.installed?).to be_false
21
+ end
22
+
23
+ it 'detect if chef-solo is installed' do
24
+ @configuration.stub_command '/opt/chef/bin/chef-solo -v || true', data: 'Chef: 11.4.0'
25
+ expect(@configuration.toque.chef.installed?).to be_true
26
+ end
27
+ end
28
+
29
+ describe '#installed_version' do
30
+ it 'should fetch installed chef version' do
31
+ @configuration.stub_command '/opt/chef/bin/chef-solo -v || true', data: 'Chef: 11.4.0'
32
+ expect(@configuration.toque.chef.installed_version).to be == '11.4.0'
33
+ end
34
+ end
35
+
36
+ describe '#cookbooks_paths' do
37
+ it 'should return existing cookbook paths' do
38
+ File.stub(:exists?).with('config/cookbooks').and_return true
39
+ File.stub(:exists?).with('vendor/cookbooks').and_return false
40
+
41
+ expect(@configuration.toque.chef.cookbooks_paths).to be == %w(config/cookbooks)
42
+ end
43
+ end
44
+
45
+ describe '#ensure_cookbooks!' do
46
+ it 'should abort if no cookbook path exist' do
47
+ File.stub(:exists?).with('config/cookbooks').and_return false
48
+ File.stub(:exists?).with('vendor/cookbooks').and_return false
49
+
50
+ expect{ @configuration.toque.chef.ensure_cookbooks! }.to raise_error
51
+ end
52
+ end
53
+
54
+ describe '#databags_path' do
55
+ it 'should return path if exists' do
56
+ File.stub(:exists?).with('config/databags').and_return true
57
+
58
+ expect(@configuration.toque.chef.databags_path).to be == 'config/databags'
59
+ end
60
+
61
+ it 'should return nit if path does not exists' do
62
+ File.stub(:exists?).with('config/databags').and_return false
63
+
64
+ expect(@configuration.toque.chef.databags_path).to be_nil
65
+ end
66
+ end
67
+
68
+ describe '#chef_solo' do
69
+ it 'should return path to chef solo executable' do
70
+ expect(@configuration.toque.chef.chef_solo).to be == '/opt/chef/bin/chef-solo'
71
+ end
72
+
73
+ it 'should return path to custom chef solo executable' do
74
+ @configuration.set :chef_solo, 'chef-solo'
75
+ expect(@configuration.toque.chef.chef_solo).to be == 'chef-solo'
76
+ end
77
+ end
78
+
79
+ describe '#upload_cookbooks' do
80
+ before do
81
+ File.stub(:exists?).and_return false
82
+ File.stub(:exists?).with('config/cookbooks').and_return true
83
+ end
84
+
85
+ it 'should create working dir' do
86
+ @configuration.toque.chef.setup.cookbooks
87
+
88
+ expect(@configuration).to have_run 'mkdir -p /tmp/toque'
89
+ end
90
+
91
+ it 'should upload cookbooks' do
92
+ @configuration.toque.chef.setup.cookbooks
93
+
94
+ expect(@configuration).to have_uploaded.to('/tmp/toque/cookbooks.tar')
95
+ end
96
+
97
+ it 'should extract cookbooks on server' do
98
+ @configuration.toque.chef.setup.cookbooks
99
+
100
+ expect(@configuration).to have_run 'cd /tmp/toque && tar -xjf cookbooks.tar'
101
+ end
102
+ end
103
+
104
+ describe 'toque:chef:install' do
105
+
106
+ it 'should install chef using omnibus installer' do
107
+ @configuration.toque.chef.install
108
+ expect(@configuration).to have_run("sudo -p 'sudo password: ' true && curl -L http://www.opscode.com/chef/install.sh | sudo -p 'sudo password: ' bash")
109
+ end
110
+
111
+ context 'with custom installer URL' do
112
+ before { @configuration.set :chef_omnibus_installer_url, 'http://mysrv.tld/inst.sh' }
113
+
114
+ it 'should install chef using custom omnibus installer' do
115
+ @configuration.toque.chef.install
116
+ expect(@configuration).to have_run("sudo -p 'sudo password: ' true && curl -L http://mysrv.tld/inst.sh | sudo -p 'sudo password: ' bash")
117
+ end
118
+ end
119
+
120
+ context 'with specific chef version' do
121
+ before { @configuration.set :chef_version, '10.24.0' }
122
+
123
+ it 'should install chef using custom omnibus installer' do
124
+ @configuration.toque.chef.install
125
+ expect(@configuration).to have_run("sudo -p 'sudo password: ' true && curl -L http://www.opscode.com/chef/install.sh | sudo -p 'sudo password: ' bash -s -- -v 10.24.0")
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Toque::Helpers, 'loaded into capistrano' do
4
+ before do
5
+ @configuration = Capistrano::Configuration.new
6
+ @configuration.extend Capistrano::Spec::ConfigurationExtension
7
+ Toque.load_into(@configuration)
8
+ end
9
+
10
+ describe '#pwd' do
11
+ it 'return toque working dir' do
12
+ expect(@configuration.toque.pwd).to be == '/tmp/toque'
13
+ end
14
+
15
+ it 'return custom path if set' do
16
+ @configuration.set :toque_pwd, '/tmp/custom_path'
17
+ expect(@configuration.toque.pwd).to be == '/tmp/custom_path'
18
+ end
19
+ end
20
+
21
+ describe '#pwd!' do
22
+ it 'return create remote working dir' do
23
+ @configuration.toque.pwd!
24
+ expect(@configuration).to have_run 'mkdir -p /tmp/toque'
25
+ end
26
+ end
27
+
28
+ describe '#curl?' do
29
+ it 'return true if curl exists' do
30
+ @configuration.stub_command 'curl || true', data: "curl: try 'curl --help' or 'curl --manual' for more information"
31
+ expect(@configuration.toque.curl?).to be_true
32
+ end
33
+
34
+ it 'return false if curl is missing' do
35
+ @configuration.stub_command 'curl || true', data: "sh: command not found"
36
+ expect(@configuration.toque.curl?).to be_false
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'toque/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'toque'
8
+ spec.version = Toque::VERSION
9
+ spec.authors = ['Jan Graichen']
10
+ spec.email = %w(jg@altimos.de)
11
+ spec.description = %q{Toque: Cap of a Chef. Integrate Chef into Capistrano.}
12
+ spec.summary = %q{Toque: Cap of a Chef. Integrate Chef into Capistrano.}
13
+ spec.homepage = 'https://github.com/jgraichen/toque'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = %w(lib)
20
+
21
+ spec.add_dependency 'capistrano'
22
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: toque
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jan Graichen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: 'Toque: Cap of a Chef. Integrate Chef into Capistrano.'
28
+ email:
29
+ - jg@altimos.de
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - .travis.yml
36
+ - Capfile
37
+ - Gemfile
38
+ - LICENSE.txt
39
+ - README.md
40
+ - Rakefile
41
+ - Vagrantfile
42
+ - lib/toque.rb
43
+ - lib/toque/chef.rb
44
+ - lib/toque/helpers.rb
45
+ - lib/toque/tasks.rb
46
+ - lib/toque/version.rb
47
+ - spec/config/cookbooks/awesomeium/recipes/default.rb
48
+ - spec/config/cookbooks/awesomeium/recipes/second.rb
49
+ - spec/config/deploy.rb
50
+ - spec/spec_helper.rb
51
+ - spec/spec_toque.rb
52
+ - spec/toque/chef_spec.rb
53
+ - spec/toque/helpers_spec.rb
54
+ - toque.gemspec
55
+ homepage: https://github.com/jgraichen/toque
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 2.0.3
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: 'Toque: Cap of a Chef. Integrate Chef into Capistrano.'
79
+ test_files:
80
+ - spec/config/cookbooks/awesomeium/recipes/default.rb
81
+ - spec/config/cookbooks/awesomeium/recipes/second.rb
82
+ - spec/config/deploy.rb
83
+ - spec/spec_helper.rb
84
+ - spec/spec_toque.rb
85
+ - spec/toque/chef_spec.rb
86
+ - spec/toque/helpers_spec.rb