chake 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chake.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Antonio Terceiro
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.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # chake
2
+
3
+ Simple host management with chef and rake. No chef server required.
4
+
5
+ ## Installation
6
+
7
+ $ gem install chake
8
+
9
+ ## Usage
10
+
11
+ Require chake on your `Rakefile`:
12
+
13
+ ```ruby
14
+ require 'chake'
15
+ ```
16
+
17
+ Initializing the repository:
18
+
19
+ $ rake init
20
+
21
+
22
+ Important files that are generated:
23
+
24
+ ```
25
+ config.rb
26
+ nodes.yaml
27
+ config/
28
+ config/roles/
29
+ cookbooks/
30
+ cookbooks/myhost/
31
+ cookbooks/myhost/recipes/
32
+ cookbooks/myhost/recipes/default.rb
33
+
34
+ ```
35
+
36
+ * `nodes.yaml`, where you will list the hosts you will be managing.
37
+ * a `cookbooks` directory where you will store your cookbooks. A sample
38
+ cookbook called "myhost" is created, but feel free to remove it and add
39
+ actual cookbooks.
40
+
41
+
42
+ Sample `nodes.yaml`:
43
+
44
+ ```yaml
45
+ host1.mycompany.com:
46
+ run_list:
47
+ - recipe[common]
48
+ - recipe[webserver]
49
+ host2.mycompany.com:
50
+ run_list:
51
+ - recipe[common]
52
+ - recipe[mailserver]
53
+ ```
54
+
55
+ Check the output of `rake -T` to see what else you can do.
56
+
57
+ ## Contributing
58
+
59
+ 1. Fork it ( http://github.com/terceiro/chake/fork )
60
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
61
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
62
+ 4. Push to the branch (`git push origin my-new-feature`)
63
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/chake.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chake/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "chake"
8
+ spec.version = Chake::VERSION
9
+ spec.authors = ["Antonio Terceiro"]
10
+ spec.email = ["terceiro@softwarelivre.org"]
11
+ spec.summary = %q{Simple host management with chef and rake. No chef server required.}
12
+ spec.description = %q{chake provides a set of rake tasks that you can use to manage any number of hosts via SSH. It doesn't require a chef server; all you need is a workstation from where you can SSH into all your hosts.}
13
+ spec.homepage = "https://github.com/terceiro/chake"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
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 = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency "rake"
25
+ end
@@ -0,0 +1,4 @@
1
+ a70248580db38a6659bba1887c16ead12d8d2f6c config.rb
2
+ 3f89ae2a25368bb08d8ecbe1b12028cdbd29bb23 nodes.yaml
3
+ 7e805ef45e1ee657afb162fd98e882caf9113bc0 cookbooks/myhost/recipes/default.rb
4
+ ff86a66c0e8bb3dd6f526ab94ffd57f23c7153f1 Rakefile
@@ -0,0 +1,11 @@
1
+ begin
2
+ require 'chake'
3
+ rescue LoadError
4
+ $: << '../../lib'
5
+ retry
6
+ end
7
+
8
+ desc 'removes everything'
9
+ task :clean do
10
+ rm_rf Dir.glob('*') - ['Rakefile']
11
+ end
@@ -0,0 +1,4 @@
1
+ root = File.expand_path(File.dirname(__FILE__))
2
+ file_cache_path root + '/cache'
3
+ cookbook_path root + '/cookbooks'
4
+ role_path root + '/config/roles'
@@ -0,0 +1 @@
1
+ package 'openssh-server'
@@ -0,0 +1,3 @@
1
+ lvh.me:
2
+ run_list:
3
+ - recipe[myhost]
data/lib/chake.rb ADDED
@@ -0,0 +1,153 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'yaml'
4
+ require 'json'
5
+ require 'tmpdir'
6
+ require 'readline'
7
+
8
+ $nodes_file = ENV['NODES'] || 'nodes.yaml'
9
+ $node_data = File.exists?($nodes_file) && YAML.load_file($nodes_file) || {}
10
+ $nodes = $node_data.keys
11
+
12
+ $sample_nodes = <<EOF
13
+ host1.my.tld:
14
+ run_list:
15
+ - recipe[myhost]
16
+ EOF
17
+
18
+ desc "Initializes current directory with sample structure"
19
+ task :init do
20
+ if !File.exists?('nodes.yaml')
21
+ File.open('nodes.yaml', 'w') do |f|
22
+ f.write($sample_nodes)
23
+ puts "→ nodes.yaml"
24
+ end
25
+ end
26
+ if !File.exists?('config.rb')
27
+ File.open('config.rb', 'w') do |f|
28
+ f.puts "root = File.expand_path(File.dirname(__FILE__))"
29
+ f.puts "file_cache_path root + '/cache'"
30
+ f.puts "cookbook_path root + '/cookbooks'"
31
+ f.puts "role_path root + '/config/roles'"
32
+ end
33
+ puts "→ config.rb"
34
+ end
35
+ mkdir_p 'config/roles'
36
+ mkdir_p 'cookbooks/myhost/recipes/'
37
+ recipe = 'cookbooks/myhost/recipes/default.rb'
38
+ if !File.exists?(recipe)
39
+ File.open(recipe, 'w') do |f|
40
+ f.puts "package 'openssh-server'"
41
+ end
42
+ puts "→ #{recipe}"
43
+ end
44
+ end
45
+
46
+ desc 'list nodes'
47
+ task :nodes do
48
+ puts $nodes
49
+ end
50
+
51
+ def encrypted_for(node)
52
+ Dir.glob("**/files/{default,#{node}}/*.{asc,gpg}").inject({}) do |hash, key|
53
+ hash[key] = key.sub(/\.(asc|gpg)$/, '')
54
+ hash
55
+ end
56
+ end
57
+
58
+ def if_files_changed(node, group_name, files)
59
+ if files.empty?
60
+ return
61
+ end
62
+ hash = IO.popen(['sha1sum', *files]).read
63
+ hash_file = File.join('.tmp', node + '.' + group_name + '.sha1sum')
64
+ if !File.exists?(hash_file) || File.read(hash_file) != hash
65
+ yield
66
+ end
67
+ File.open(hash_file, 'w') do |f|
68
+ f.write(hash)
69
+ end
70
+ end
71
+
72
+ $nodes.each do |node|
73
+
74
+ desc "bootstrap #{node}"
75
+ task "bootstrap:#{node}" do
76
+ mkdir_p '.tmp', :verbose => false
77
+ config = '.tmp/' + node + '.json'
78
+
79
+ seen_before = File.exists?(config)
80
+
81
+ # overwrite config with current contents
82
+ File.open(config, 'w') do |f|
83
+ json_data = $node_data[node]
84
+ f.write(JSON.dump(json_data))
85
+ f.write("\n")
86
+ end
87
+
88
+ unless seen_before
89
+ begin
90
+ sh "ssh root@#{node} 'apt-get -q -y install rsync chef'"
91
+ rescue
92
+ rm_f config
93
+ raise
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ desc "upload data to #{node}"
100
+ task "upload:#{node}" do
101
+ encrypted = encrypted_for(node)
102
+ excludes = encrypted.values.map { |f| "--exclude #{f}" }.join(' ')
103
+
104
+ rsync = "rsync -avp --delete --exclude .git/ #{excludes}"
105
+
106
+ Dir.mktmpdir do |tmpdir|
107
+ sh "#{rsync} --quiet ./ #{tmpdir}/"
108
+ files = Dir.chdir(tmpdir) { Dir.glob("**/*").select { |f| !File.directory?(f) } }
109
+ if_files_changed(node, 'plain', files) do
110
+ rsync_logging = Rake.application.options.silent && '--quiet' || '--verbose'
111
+ sh "#{rsync} #{rsync_logging} ./ root@#{node}:/srv/chef/"
112
+ end
113
+ end
114
+
115
+ if_files_changed(node, 'enc', encrypted.keys) do
116
+ encrypted.each do |encrypted_file, target_file|
117
+ sh "gpg --quiet --batch --use-agent --decrypt #{encrypted_file} | ssh root@#{node} 'cat > /srv/chef/#{target_file}; chmod 600 /srv/chef/#{target_file}'"
118
+ end
119
+ end
120
+ end
121
+
122
+ desc "converge #{node}"
123
+ task "converge:#{node}" => ["bootstrap:#{node}", "upload:#{node}"] do
124
+ chef_logging = Rake.application.options.silent && '-l fatal' || ''
125
+ sh "ssh root@#{node} 'chef-solo -c /srv/chef/config.rb #{chef_logging} -j /srv/chef/.tmp/#{node}.json'"
126
+ end
127
+
128
+ desc "run a command on #{node}"
129
+ task "run:#{node}" => 'run_input' do
130
+ cmd = ['ssh', "root@#{node}", $cmd]
131
+ IO.popen(cmd).lines.each do |line|
132
+ puts "#{node}: #{line}"
133
+ end
134
+ end
135
+ end
136
+
137
+ task :run_input do
138
+ $cmd = ENV['CMD'] || Readline.readline('$ ')
139
+ end
140
+
141
+ desc "upload to all nodes"
142
+ task :upload => $nodes.map { |node| "upload:#{node}" }
143
+
144
+ desc "bootstrap all nodes"
145
+ task :bootstrap => $nodes.map { |node| "bootstrap:#{node}" }
146
+
147
+ desc "converge all nodes (default)"
148
+ task "converge" => $nodes.map { |node| "converge:#{node}" }
149
+
150
+ task "run a command on all nodes"
151
+ task :run => $nodes.map { |node| "run:#{node}" }
152
+
153
+ task :default => :converge
@@ -0,0 +1,3 @@
1
+ module Chake
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chake
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Antonio Terceiro
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.5'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.5'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: chake provides a set of rake tasks that you can use to manage any number
63
+ of hosts via SSH. It doesn't require a chef server; all you need is a workstation
64
+ from where you can SSH into all your hosts.
65
+ email:
66
+ - terceiro@softwarelivre.org
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - chake.gemspec
77
+ - examples/test/.tmp/lvh.me.plain.sha1sum
78
+ - examples/test/Rakefile
79
+ - examples/test/config.rb
80
+ - examples/test/cookbooks/myhost/recipes/default.rb
81
+ - examples/test/nodes.yaml
82
+ - lib/chake.rb
83
+ - lib/chake/version.rb
84
+ homepage: https://github.com/terceiro/chake
85
+ licenses:
86
+ - MIT
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.23
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: Simple host management with chef and rake. No chef server required.
109
+ test_files: []