server-blender-core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ log
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Vitaly Kushner
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,21 @@
1
+ # server-blender-core
2
+
3
+ Core cookbook for [server-blender](http://astrails.com/opensource/server-blender)
4
+
5
+ * [Code](http://github.com/astrails/server-blender-core)
6
+ * [Home](http://astrails.com/opensource/server-blender)
7
+ * [Issues](http://github.com/astrails/server-blender-core/issues)
8
+
9
+ ## Note on Patches/Pull Requests
10
+
11
+ * Fork the project.
12
+ * Make your feature addition or bug fix.
13
+ * Add tests for it. This is important so I don't break it in a
14
+ future version unintentionally.
15
+ * Commit, do not mess with rakefile, version, or history.
16
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
17
+ * Send me a pull request. Bonus points for topic branches.
18
+
19
+ ## Copyright
20
+
21
+ Copyright (c) 2010 Vitaly Kushner. See LICENSE for details.
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "server-blender-core"
8
+ gem.summary = %Q{core recipes cookbook for server-blender}
9
+ gem.description = <<-DESC
10
+ This gem is part of the server-blender family (http://astrails.com/opensource/server-blender)
11
+ It contains core recipes cookbook. See server-blender for more information.
12
+ DESC
13
+ gem.email = "vitaly@astrails.com"
14
+ gem.homepage = "http://astrails.com/opensource/server-blender"
15
+ gem.authors = ["Vitaly Kushner"]
16
+
17
+ gem.add_dependency "server-blender-manifest", ">= 0.0.15"
18
+
19
+ gem.add_development_dependency "rspec", ">= 1.2.9"
20
+ gem.add_development_dependency "yard", ">= 0"
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ task :default => :spec
43
+
44
+ begin
45
+ require 'yard'
46
+ YARD::Rake::YardocTask.new
47
+ rescue LoadError
48
+ task :yardoc do
49
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
50
+ end
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,45 @@
1
+ #!/bin/bash -e
2
+
3
+ VERSION=1.9.1
4
+
5
+ echo
6
+ date
7
+ echo Installing Darwin Ports $VERSION
8
+
9
+ if [ ! -e /usr/bin/gcc ]; then
10
+ echo
11
+ echo "****************************************************************************************************"
12
+ echo "** Xcode is not installed. Please install Xcode from the OSX installation DVD and run this again. **"
13
+ echo "****************************************************************************************************"
14
+ exit 1
15
+ fi
16
+
17
+ cd /var/lib/blender/tmp
18
+ rm -rf macports
19
+ mkdir macports
20
+ cd macports
21
+ curl -O http://distfiles.macports.org/MacPorts/MacPorts-${VERSION}.tar.bz2
22
+ tar -jxf MacPorts-${VERSION}.tar.bz2
23
+ cd MacPorts-$VERSION
24
+ ./configure
25
+ make
26
+ sudo make install
27
+
28
+ if ! grep -1 /opt/local/bin /etc/paths; then
29
+ echo Modifying /etc/paths
30
+ echo /opt/local/bin > /etc/paths.tmp
31
+ echo /opt/local/sbin >> /etc/paths.tmp
32
+ cat /etc/paths >> /etc/paths.tmp
33
+ mv /etc/paths.tmp /etc/paths
34
+ fi
35
+
36
+ if ! grep -1 /opt/local/share/man /etc/manpaths; then
37
+ echo Modifying /etc/manpaths
38
+ echo /opt/local/share/man > /etc/manpaths.tmp
39
+ cat /etc/manpaths >> /etc/manpaths.tmp
40
+ mv /etc/manpaths.tmp /etc/manpaths
41
+ fi
42
+
43
+ /opt/local/bin/port -v selfupdate
44
+
45
+ echo DONE
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ p=`find /var/shadow_puppet -name $1`
4
+ if [ -n "$p" ]; then
5
+ p=$p/contents
6
+ echo PATH: $p
7
+ cat $p
8
+ else
9
+ echo Not found
10
+ fi
@@ -0,0 +1,30 @@
1
+ [core]
2
+ editor = vim
3
+
4
+ [color]
5
+ diff = auto
6
+ status = auto
7
+ branch = auto
8
+ interactive = auto
9
+
10
+ [core]
11
+ editor = vim
12
+
13
+ [alias]
14
+ ci = commit
15
+ co = checkout
16
+ st = status
17
+ br = branch
18
+ lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative
19
+ ls = ls-files
20
+ d = diff -C --stat -p
21
+ dw = diff -C --stat -p --color-words
22
+
23
+ [push]
24
+ default = current
25
+
26
+ [help]
27
+ autocorrect = 1
28
+
29
+ [branch]
30
+ autosetuprebase = always
@@ -0,0 +1 @@
1
+ github.com,65.74.177.129 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
@@ -0,0 +1,11 @@
1
+ module Blender::Recipes::BlenderTools
2
+ # installs blender tools. currently just 'fbucket'
3
+ #
4
+ # @return dependency reference
5
+ def blender_tools
6
+ dep = sys_dir("/usr/local/bin", :require => sys_dir("/usr/local"))
7
+ sys_file "/usr/local/bin/fbucket", :mode => "0755",
8
+ :content => template(find_file("fbucket")),
9
+ :require => dep
10
+ end
11
+ end
@@ -0,0 +1,216 @@
1
+ module Blender::Recipes::Core
2
+
3
+ # render template with the given bindings
4
+ #
5
+ # @param [String] path path to the template file
6
+ # @param [Binding] b (local binding) binding to use
7
+ # @param [Boolean] cleanup (false) cleanup whitespace lines from the result
8
+ #
9
+ # @return [String] rendered template content
10
+ def template(path, b = binding, cleanup = false)
11
+ content = File.read(path)
12
+ begin
13
+ require 'erb'
14
+ res = ERB.new(content).result(b)
15
+ res.gsub!(/^\s+$/, "") if cleanup
16
+ res
17
+ rescue => e
18
+ puts "FAILED TEMPLATE:#{e}\n#{content}\n"
19
+ raise
20
+ end
21
+ end
22
+
23
+ # merge dependencies with :require key from the opts
24
+ #
25
+ # @param opts options hash
26
+ # @option opts [Array] :require (nil)
27
+ # @param [Array] deps dependencies to merge
28
+ def merge_dependencies(opts, *deps)
29
+ ([*opts[:require]] + [*deps]).flatten.compact
30
+ end
31
+
32
+ # running on Darwin?
33
+ #
34
+ # @return true if OS is Darwin
35
+ def darwin?
36
+ "Darwin" == os
37
+ end
38
+
39
+ # running on Ubuntu
40
+ #
41
+ # @return true if OS is Ubuntu
42
+ def ubuntu?
43
+ "Ubuntu" == os
44
+ end
45
+
46
+ # running on Debian?
47
+ #
48
+ # @return true if OS is Debian
49
+ def debian?
50
+ "Debian" == os
51
+ end
52
+
53
+ # running on Debian or Ubuntu?
54
+ #
55
+ # @return true if OS is Debian or Ubuntu
56
+ def debuntu?
57
+ debian? or ubuntu?
58
+ end
59
+
60
+ # detects cookbook of the current (or calling) recipes
61
+ # @param [Integer] (0) at how far in stack to look
62
+ def current_cookbook(at = 0)
63
+ caller[at][/\/cookbooks\/([^\/]+)\//, 1]
64
+ end
65
+
66
+ # find file by name
67
+ # @param [String] file filename to search for relative to `subdir` directory
68
+ # @param [String] cookbook recipes cookbook to search in
69
+ # @return [String] found file path
70
+ # @exammple
71
+ # find_file("install.sh", :files, "cassandra") # will look for install.sh inside cassandra/files
72
+ # find_file("my-key", :keys, "boo") # will look for install.sh inside boo/keys
73
+ def find_file(file, subdir = 'files', cookbook = current_cookbook(1))
74
+
75
+ if cookbook
76
+ pattern = "cookbooks/#{cookbook}/#{subdir}/#{file}"
77
+ else
78
+ pattern = ["#{subdir}/#{file}", "cookbooks/*/#{subdir}/#{file}"]
79
+ end
80
+ files = Dir[*pattern]
81
+
82
+ raise "too many files found: #{files * ', '}" if files.size > 1
83
+ files.first && File.expand_path(files.first) || raise("Couldn't find #{file} in #{pattern.inspect}")
84
+ end
85
+
86
+ # creates file with default params
87
+ # @param [String] path file path
88
+ # @param [Hash] opts standard `file` options
89
+ # Note: by default will create a file with mode 0644 owned by root:root
90
+ # @return [Array] dependency reference
91
+ def sys_file(path, opts = {})
92
+ opts = opts.dup
93
+
94
+ mode = opts.delete(:mode) || "0644"
95
+
96
+ owner = opts.delete(:owner) || "root"
97
+
98
+ group = opts.delete(:group) ||
99
+ if "root" == owner
100
+ darwin? ? "wheel" : "root"
101
+ else
102
+ darwin? ? "staff" : owner
103
+ end
104
+
105
+ opts[:owner] = owner unless false == owner
106
+ opts[:group] = group unless false == group
107
+ opts[:mode] = mode unless false == mode
108
+
109
+ file path, opts
110
+ [file(path)]
111
+ end
112
+
113
+ # create directory
114
+ # @param [String] path directory path
115
+ # @param [Hash] opts options hash
116
+ # @option opts [String] :owner (root) directory owner
117
+ # @option opts [String] :group (same as user) directory group
118
+ # @option opts [String, Integer] :mode (0755) directory group
119
+ # @return [Array] dependency reference
120
+ def sys_dir(path, opts = {})
121
+ sys_file(path, {:ensure => :directory, :mode => "0755"}.merge(opts))
122
+ end
123
+
124
+ # executes command and returns deps array
125
+ # Same like the original `exec` but returns the dependency
126
+ # @return [Array] dependency reference
127
+ def sys_exec(name, opts = {})
128
+ opts = opts.dup
129
+ if rvm_version = opts.delete(:rvm)
130
+ raise "no :with_rvm supported and :rvm option supplied. mix :rvm recipe from server-blender-rvm cookbook" unless respond_to?(:with_rvm)
131
+ opts[:command] = with_rvm(opts[:command], rvm_version) if opts[:command]
132
+ opts[:unless] = with_rvm(opts[:unless], rvm_version) if opts[:unless]
133
+ opts[:onlyif] = with_rvm(opts[:onlyif], rvm_version) if opts[:onlyif]
134
+ opts[:refresh] = with_rvm(opts[:refresh], rvm_version) if opts[:refresh]
135
+ end
136
+ if logfile = opts.delete(:logfile)
137
+ logfile = File.expand_path(logfile, "/var/lib/blender/logs/")
138
+
139
+ command = opts[:command] || name
140
+ opts[:command] = command << " 2>&1 | tee -a #{logfile};exit $PIPESTATUS"
141
+ end
142
+ opts[:logoutput] ||= :on_failure
143
+ exec(name, opts)
144
+ [exec(name)]
145
+ end
146
+
147
+ # Installs packages
148
+ # @param [Array] list list of packages to install
149
+ # @param [Hash] opts standard puppet options
150
+ # @return [Array] dependency references for all the packages
151
+ def sys_pkg(*packages_and_options)
152
+ opts = packages_and_options.extract_options!
153
+ packages_and_options.flatten.map do |p|
154
+ package(p.to_s, {:ensure => :installed}.merge(opts))
155
+ package(p.to_s)
156
+ end
157
+ end
158
+
159
+ def sys_service(name, opts = {})
160
+ status = opts[:ensure] || :running
161
+ service(name, {:ensure => status, :enable => ("running" == status.to_s)}.merge(opts))
162
+ [service(name)]
163
+ end
164
+
165
+ # url for rubygems at github
166
+ GEMS_GITHUB = 'http://gems.github.com'
167
+
168
+ # Install rubygems
169
+ #
170
+ # @param [Array] list of gems to install. each element can be either a string gem name, or an array of [name, version, dependencies, source]
171
+ #
172
+ # @example
173
+ # sys_gem [
174
+ # "will_paginate",
175
+ # ["rails", "2.3.5"]
176
+ # ["thoughtbot-shoulda", "2.9.1", nil, GITHUB]
177
+ # }
178
+ #
179
+ # @return [Array] dependency references for all the gems
180
+ def sys_gem(list, options = {})
181
+ [*list].map do |name, version, depends, source|
182
+ opts = options.merge(:provider => :gem, :ensure => version || :installed)
183
+ opts[:require] = [*depends] if depends
184
+ opts[:source] = source if source
185
+ package name.to_s, opts
186
+ package(name.to_s)
187
+ end
188
+ end
189
+
190
+ # mount a volume
191
+ # @param [String] directory mount point
192
+ # @param [String] volume what volume (device) to mount, e.g. "/dev/sdm"
193
+ # @return [Array] dependency reference
194
+ def sys_mount(directory, volume, opts = {})
195
+ mount(directory, {
196
+ :device => volume,
197
+ :ensure => :mounted,
198
+ :fstype =>"xfs",
199
+ :options => "noatime",
200
+ :atboot => true}.merge(opts).merge(:require => merge_dependencies(opts, file(directory))))
201
+
202
+ [mount(directory)]
203
+ end
204
+
205
+ # mount one directory into another
206
+ # @param [String] to directory of the mount destination
207
+ # @param [String] from directory of the mount source
208
+ # @return [Array] dependency reference
209
+ def bind_mount(to, from, opts = {})
210
+ sys_mount to, from,
211
+ opts.merge(
212
+ :require => merge_dependencies(opts, file(from)),
213
+ :fstype => "none",
214
+ :options => "bind")
215
+ end
216
+ end
@@ -0,0 +1,20 @@
1
+ mix :git, :blender_tools
2
+
3
+ # Install default stuff. This is what we install on all our managed servers.
4
+ module Blender::Recipes::Default
5
+
6
+ def self.included(base)
7
+ base.class_eval { recipe :default }
8
+ end
9
+
10
+ # This recipe will be executed by default. You can override it
11
+ # by declaring function 'default' in any of your mixed plugins
12
+ #
13
+ # @see Blender::Recipes::Git#gitconfig
14
+ # @see Blender::Recipes::BlenderTools#blender_tools
15
+ def default
16
+ gitconfig
17
+ blender_tools
18
+ end
19
+
20
+ end
@@ -0,0 +1,32 @@
1
+ # Git utils
2
+ module Blender::Recipes::Git
3
+
4
+ # setup default /etc/gitconfig
5
+ #
6
+ # @return dependency reference
7
+ def gitconfig
8
+ sys_file path = "/etc/gitconfig",
9
+ :ensure => :present,
10
+ :source => find_file("gitconfig"),
11
+ :group => (darwin? ? "wheel" : "root"),
12
+ :require => sys_pkg("git-core")
13
+ end
14
+
15
+ # initialize git repository
16
+ #
17
+ # @return dependency reference
18
+ def git_repository(repo, opts = {})
19
+ _git = file File.join(repo, ".git"), :checksum => :mtime
20
+ sys_exec "/usr/bin/git --git-dir '#{path}' init-db", opts.merge(
21
+ :require => merge_dependencies(opts, sys_pkg("git-core")),
22
+ :creates => path,
23
+ :before => _git)
24
+ end
25
+
26
+ def git_clone(repo, path, opts = {})
27
+ sys_exec "git clone #{repo} #{path}", opts.merge(
28
+ :creates => path,
29
+ :require => merge_dependencies(opts, sys_pkg("git-core")),
30
+ :cwd => File.dirname(path))
31
+ end
32
+ end
@@ -0,0 +1,20 @@
1
+ mix :core
2
+
3
+ # Setup locales
4
+ module Blender::Recipes::Locales
5
+
6
+ # setup locales on debian / ubuntu machines. you can contribute support for your OS :)
7
+ #
8
+ # @return [Array] dependency reference
9
+ def locales
10
+ raise "only debian/ubuntu supported" unless debuntu?
11
+
12
+ sys_file "/etc/default/locale", :content => "LANG=en_US.UTF-8"
13
+
14
+ path = File.exist?("/var/lib/locales/supported.d") ? "/var/lib/locales/supported.d/local" : "/etc/locale.gen"
15
+
16
+ dep = sys_pkg("locales")
17
+ dep += sys_file(path, :content => "en_US.UTF-8 UTF-8\n", :notify => exec("locale-gen"))
18
+ sys_exec "locale-gen", :refreshonly => true, :require => dep
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ mix :core
2
+
3
+ # Darwin specific stuff
4
+ module Blender::Recipes::Os::Darwin
5
+ # setup Darwin environment.
6
+ # installs darwinports
7
+ # + setup defaultprovider for the 'package' resource to darwinport
8
+ def darwin_setup
9
+ sys_exec "install darwin ports",
10
+ :command => find_file("darwin/install-ports.sh"),
11
+ :creates => "/opt/local/bin/port",
12
+ :logfile => "install-ports.log"
13
+ Puppet::Type.type(:package).defaultprovider = Puppet::Type.type(:package).provider(:darwinport)
14
+ end
15
+
16
+ # Darwin specific initialization
17
+ # This should be called before you do any packages on Darwin
18
+ def darwin
19
+ sys_pkg %w/wget/
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ mix :locales
2
+
3
+ module Blender::Recipes::Os::Debian
4
+ # Debian specific initialization.
5
+ def debian
6
+ dep = sys_pkg %w/vim less wget curl links2 dstat zip unzip gzip bzip2 tar
7
+ rsync tree bind9-host build-essential autotools-dev/
8
+ dep += locales
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ mix "os/debian"
2
+
3
+ module Blender::Recipes::Os::Ubuntu
4
+ # Ubuntu specific initialization
5
+ def ubuntu
6
+ debian
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module Blender::Recipes::Postfix
2
+ # installs postfix and mailutils
3
+ # @param [String, optional] root_alias alias to redirect root's email to
4
+ #
5
+ # @return dependency reference
6
+ def postfix(root_alias = nil)
7
+ mailalias("root", :recipient => root_alias, :ensure => :present, :require => package("postfix")) if root_alias
8
+ sys_pkg "postfix", "mailutils"
9
+ end
10
+ end
@@ -0,0 +1,120 @@
1
+ mix :utils
2
+
3
+ module Blender::Recipes::Users
4
+
5
+ # allow override for user's home_dir
6
+ # call this function before home_dir is called and the value you provide will be returned in
7
+ # the subsequent invocations of home_dir
8
+ # @param [String] user username to override homedir for
9
+ # @param [String] dir homedir to use
10
+ def set_home_dir(user, dir)
11
+ @home_dir ||= {}
12
+ @home_dir[user] = dir
13
+ end
14
+
15
+ # returns homedir for a given user
16
+ # @param [String] user username for which homedir is requested
17
+ # @return [String] user's home directory
18
+ def home_dir(user)
19
+ @home_dir ||= {"root" => (darwin? ? "/var/root" : "/root")}
20
+ @home_dir[user.to_s] ||= darwin? ? "/Users/#{user}": "/home/#{user}"
21
+ end
22
+
23
+ # create an application (i.e. non-system) user and his home dir
24
+ # @param [String] name username
25
+ # 1st creates user, then it's homedirectory (since it obviously needs to be owned buy the user)
26
+ # @return reference for the homedir resource
27
+ def app_user(name, opts = {})
28
+ home = home_dir(name)
29
+
30
+ if opts[:password]
31
+ case os.downcase
32
+ when 'debian', 'ubuntu'
33
+ opts[:require] = merge_dependencies(opts, sys_pkg("libshadow-ruby1.8"))
34
+ end
35
+ end
36
+
37
+ # user resource - this will actually create the user
38
+ user name, {
39
+ :ensure => :present,
40
+ :home => home,
41
+ :shell => "/bin/bash",
42
+ :managehome => true,
43
+ :allowdupe => false,
44
+ }.merge(opts)
45
+
46
+ # create homedirectory for the user
47
+ sys_file home,
48
+ :ensure => :directory,
49
+ :owner => name,
50
+ :mode => "0755",
51
+ :require => user(name)
52
+ end
53
+
54
+ # returns path to the user's .ssh directory
55
+ def dot_ssh_path(user)
56
+ "#{home_dir(user)}/.ssh"
57
+ end
58
+
59
+ # create ~/.ssh directory for the user and return its path
60
+ # @param [String] user username
61
+ # @return [String] path to ~/.ssh
62
+ def dot_ssh(user)
63
+ sys_dir dot_ssh_path(user),
64
+ :mode => 0700, :owner => user,
65
+ :require => (user.to_s == "root" || darwin?) ? [] : [file(home_dir(user))]
66
+ end
67
+
68
+ # authorize given ssh keys to login as given user
69
+ # @param [String] user username to login as
70
+ # @param [Array] keys list of keysnames to allow to login
71
+ # @return reference for ~/.ssh/authorized_keys file resource
72
+ def ssh_authorized_keys(user, keys)
73
+ sys_file "#{dot_ssh_path(user)}/authorized_keys",
74
+ :mode => 0600,
75
+ :owner => user,
76
+ :require => dot_ssh(user),
77
+ :content => keys.map {|k| File.read(find_file(k, :keys, nil)).strip}.join("\n")
78
+ end
79
+
80
+ # setup public/private ssh keys for a user
81
+ # @param [String] user user to setup keys for
82
+ # @param [String] key name of the key. This function expects 2 files to exist: keys/KEY and keys/KEY.pub
83
+ # @option opts [Array] :require (nil) additional requirements
84
+ # @return reference for ~/.ssh/id_dsa.pub resource, it is created last
85
+ def ssh_key(user, key, opts = {})
86
+ deps = merge_dependencies(opts, dot_ssh(user))
87
+
88
+ # create private key
89
+ deps = sys_file("#{dot_ssh_path(user)}/id_dsa",
90
+ :mode => 0600, :owner => user,
91
+ :require => deps,
92
+ :content => File.read(find_file(key, :keys, nil)))
93
+
94
+ # create public key
95
+ sys_file "#{dot_ssh_path(user)}/id_dsa.pub",
96
+ :mode => 0644, :owner => user,
97
+ :require => deps,
98
+ :content => File.read(find_file("#{key}.pub", :keys, nil))
99
+ end
100
+
101
+ # add given key to the ~/.ssh/known_hosts file for the user
102
+ # if the file doesn't exist it will be created
103
+ # if it does exist, only the key line will be added to it
104
+ # @param [String] user username
105
+ # @param [String] key. this function expects file keys/KEY to exist and contain the known_hosts line
106
+ # @option opts [Array] :require (nil) additional requirements
107
+ # @return dependency reference for the line in the known_hosts file
108
+ def ssh_known_host(user, key, opts = {})
109
+ deps = merge_dependencies(opts, dot_ssh(user))
110
+
111
+ path = "#{dot_ssh_path(user)}/known_hosts"
112
+ deps = sys_file(path,
113
+ :mode => 0600, :owner => user,
114
+ :require => deps,
115
+ :ensure => :file)
116
+
117
+ # this will return the dep ref for the line
118
+ line path, File.read(find_file(key, :keys, nil)).strip, :require => deps
119
+ end
120
+ end
@@ -0,0 +1,33 @@
1
+ mix :core
2
+
3
+ module Blender::Recipes::Utils
4
+ # adds or removes lines from a file
5
+ # @param file filename of the file
6
+ # @param line line to add/removes
7
+ # @param opts[:ensure] when :present - the line will be added, when :absent - will be removed
8
+ # @param opts[:regexp] effective only when :ensure => :absent. tread line as a regexp and not as a literal string
9
+ # @return [Array] dependency reference
10
+ def line(file, line, opts = {})
11
+ case opts.delete(:ensure) || :present
12
+
13
+ when :present
14
+ sys_exec("present #{file}:#{line}", opts.merge(
15
+ :command => "/bin/echo '#{line}' >> '#{file}'",
16
+ :unless => "grep -qFx '#{line}' '#{file}'"))
17
+
18
+ when :absent
19
+ if regexp = opts.delete(:regexp)
20
+ sys_exec("absent #{file}: /#{line}/", opts.merge(
21
+ :command => "/usr/bin/perl -ni -e 'print unless /#{line}/' '#{file}'",
22
+ :onlyif => "grep -qP '#{line}' '#{file}'"))
23
+ else
24
+ sys_exec("absent #{file}: \"#{line}\"", opts.merge(
25
+ :command => "/usr/bin/perl -ni -e 'print unless /^\\Q#{line}\\E\$/' '#{file}'",
26
+ :onlyif => "grep -qFx '#{line}' '#{file}'"))
27
+ end
28
+ else
29
+ raise "unknown ensure value #{action}"
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,72 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{server-blender-core}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Vitaly Kushner"]
12
+ s.date = %q{2010-11-28}
13
+ s.description = %q{This gem is part of the server-blender family (http://astrails.com/opensource/server-blender)
14
+ It contains core recipes cookbook. See server-blender for more information.
15
+ }
16
+ s.email = %q{vitaly@astrails.com}
17
+ s.extra_rdoc_files = [
18
+ "LICENSE"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.markdown",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "files/darwin/install-ports.sh",
28
+ "files/fbucket",
29
+ "files/gitconfig",
30
+ "keys/github.com-host_key",
31
+ "recipes/blender_tools.rb",
32
+ "recipes/core.rb",
33
+ "recipes/default.rb",
34
+ "recipes/git.rb",
35
+ "recipes/locales.rb",
36
+ "recipes/os/darwin.rb",
37
+ "recipes/os/debian.rb",
38
+ "recipes/os/ubuntu.rb",
39
+ "recipes/postfix.rb",
40
+ "recipes/users.rb",
41
+ "recipes/utils.rb",
42
+ "server-blender-core.gemspec",
43
+ "spec/recipes/core_spec.rb",
44
+ "spec/spec.opts",
45
+ "spec/spec_helper.rb"
46
+ ]
47
+ s.homepage = %q{http://astrails.com/opensource/server-blender}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.3.7}
51
+ s.summary = %q{core recipes cookbook for server-blender}
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
+ s.add_runtime_dependency(%q<server-blender-manifest>, [">= 0.0.15"])
59
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
60
+ s.add_development_dependency(%q<yard>, [">= 0"])
61
+ else
62
+ s.add_dependency(%q<server-blender-manifest>, [">= 0.0.15"])
63
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
64
+ s.add_dependency(%q<yard>, [">= 0"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<server-blender-manifest>, [">= 0.0.15"])
68
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
69
+ s.add_dependency(%q<yard>, [">= 0"])
70
+ end
71
+ end
72
+
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+ require 'core'
3
+
4
+ describe Blender::Recipes::Core do
5
+ before(:each) do
6
+ @root = Root.new
7
+ @root.instance_eval {mix :core}
8
+ end
9
+
10
+ describe :template do
11
+ it "should ERB parse with binding" do
12
+ stub(File).read("foo/bar") {"foo <%= bar %> baz"}
13
+ bar = 123
14
+ @root.template("foo/bar", binding).should == "foo 123 baz"
15
+ end
16
+
17
+ it "should cleanup whitespace only lines when cleanup = true" do
18
+ stub(File).read("foo/bar") {"aaa\nbbb\n \nccc\n\t \nddd"}
19
+ @root.template("foo/bar", binding, true).should == "aaa\nbbb\n\nccc\n\nddd"
20
+ end
21
+ end
22
+
23
+ describe :merge_dependencies do
24
+ it "should merge deps fro moptions with arguments" do
25
+ @root.merge_dependencies({:require => [:a]}, :b, :c).should == [:a, :b, :c]
26
+ end
27
+
28
+ it "should merge single dep" do
29
+ @root.merge_dependencies({:require => [:a]}, :b).should == [:a, :b]
30
+ end
31
+
32
+ it "should merge deps array" do
33
+ @root.merge_dependencies({:require => [:a]}, [:b, :c]).should == [:a, :b, :c]
34
+ end
35
+
36
+ it "should leave arg if opts dep is nil" do
37
+ @root.merge_dependencies({}, :b).should == [:b]
38
+ end
39
+
40
+ it "should leave arg array if opts dep is nil" do
41
+ @root.merge_dependencies({}, [:b, :c]).should == [:b, :c]
42
+ end
43
+ end
44
+
45
+ describe :find_file do
46
+ it "fail if finds multiple files" do
47
+ stub(Dir).[](anything) {["aaa", "bbb"]}
48
+ proc {
49
+ @root.find_file("foo", "bar", "baz")
50
+ }.should raise_error(RuntimeError, "too many files found: aaa, bbb")
51
+ end
52
+
53
+ it "fail if no files found" do
54
+ stub(Dir).[](anything) {[]}
55
+ proc {
56
+ @root.find_file("foo", "bar", "baz")
57
+ }.should raise_error(RuntimeError, /^Couldn't find foo in/)
58
+ end
59
+
60
+ it "should look in . and all cookbooks when cookbook param is nil" do
61
+ mock(Dir).[]("foo/bar", "cookbooks/*/foo/bar") {["foo/bar"]}
62
+ @root.find_file("bar", "foo", nil)
63
+ end
64
+
65
+ it "should look only in the specific cookbook dir when given cookbook param" do
66
+ mock(Dir).[]("cookbooks/baz/foo/bar") {["cookbooks/baz/foo/bar"]}
67
+ @root.find_file("bar", "foo", "baz")
68
+ end
69
+ end
70
+
71
+ describe :sys_file do
72
+ it "should add file resource with default params" do
73
+ stub(@root).darwin? {false}
74
+ @root.sys_file "foo", :content => "Foo"
75
+ @root.should have_file("foo").
76
+ content("Foo").
77
+ mode("0644").
78
+ owner("root").
79
+ group("root")
80
+ end
81
+
82
+ it "should default to root:root on non-mac" do
83
+ stub(@root).darwin? {false}
84
+ @root.sys_file "foo"
85
+ @root.should have_file("foo").owner("root").group("root")
86
+ end
87
+
88
+ it "should default to root:wheel on mac" do
89
+ stub(@root).darwin? {true}
90
+ @root.sys_file "foo"
91
+ @root.should have_file("foo").owner("root").group("wheel")
92
+ end
93
+
94
+ it "should default to user:user on non-mac" do
95
+ stub(@root).darwin? {false}
96
+ @root.sys_file "foo", :owner => "user"
97
+ @root.should have_file("foo").owner("user").group("user")
98
+ end
99
+
100
+ it "should default to user:staff on mac" do
101
+ stub(@root).darwin? {true}
102
+ @root.sys_file "foo", :owner => "user"
103
+ @root.should have_file("foo").owner("user").group("staff")
104
+ end
105
+
106
+ end
107
+
108
+ describe :sys_dir do
109
+ it "should add directory resource with default params" do
110
+ stub(@root).darwin? {false}
111
+ @root.sys_dir "foo"
112
+ @root.should have_file("foo").
113
+ ensure(:directory).
114
+ mode("0755").
115
+ owner("root").
116
+ group("root")
117
+ end
118
+ end
119
+
120
+ describe :sys_exec do
121
+ it "should add exec with default params" do
122
+ @root.sys_exec(
123
+ "foo",
124
+ :cwd => "/", :command => "pwd",
125
+ :unless => "check-unless",
126
+ :onlyif => "check-if",
127
+ :refresh => "refresh-cmd"
128
+ )
129
+ @root.should(
130
+ have_exec("foo").command("pwd").cwd("/").
131
+ logoutput(:on_failure).unless("check-unless").onlyif("check-if"))
132
+ end
133
+
134
+ it "should wrap with rvm if needed" do
135
+ stub(@root).with_rvm {|c,v| "with-rvm(#{c}, #{v})"}
136
+ @root.sys_exec "foo",
137
+ :command => "do-foo",
138
+ :refresh => "refresh-foo",
139
+ :unless => "unless-foo",
140
+ :onlyif => "if-foo",
141
+ :rvm => "rVm"
142
+ @root.should(
143
+ have_exec("foo").command("with-rvm(do-foo, rVm)").unless("with-rvm(unless-foo, rVm)").
144
+ onlyif("with-rvm(if-foo, rVm)").refresh("with-rvm(refresh-foo, rVm)"))
145
+ end
146
+
147
+ it "should raise error when requesting :rvm when no :rvm support" do
148
+ proc {
149
+ @root.sys_exec "foo",
150
+ :command => "do-foo",
151
+ :rvm => "rVm"
152
+ }.should raise_error(RuntimeError, /no :with_rvm/)
153
+ end
154
+ end
155
+
156
+ describe :sys_pkg do
157
+ it "should create packages with default args" do
158
+ @root.sys_pkg "aaa", "bbb", :source => "there"
159
+ @root.should have_package("aaa").ensure(:installed).source("there")
160
+ @root.should have_package("bbb").ensure(:installed).source("there")
161
+ end
162
+ end
163
+
164
+ describe :sys_service do
165
+ it "should add service" do
166
+ @root.sys_service "foo"
167
+ @root.should have_service("foo").ensure(:running).enable(true)
168
+ end
169
+
170
+ it "should disable if status is not running" do
171
+ @root.sys_service :foo, :ensure => :stopped
172
+ @root.should have_service(:foo).ensure(:stopped).enable(false)
173
+ end
174
+ end
175
+
176
+ describe :sys_gem do
177
+
178
+ end
179
+ end
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format nested
3
+ --format profile:log/spec-benchmark.log
4
+ --loadby mtime
5
+ --reverse
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'ruby-debug'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'recipes'))
6
+
7
+ require 'blender/manifest/root'
8
+ require 'blender/manifest/matchers'
9
+ require 'spec'
10
+ require 'spec/autorun'
11
+ require 'shadow_puppet/test'
12
+
13
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
14
+
15
+ Spec::Runner.configure do |config|
16
+ config.include Blender::Manifest::Matchers
17
+ config.mock_with :rr
18
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: server-blender-core
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Vitaly Kushner
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-28 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: server-blender-manifest
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 0
32
+ - 0
33
+ - 15
34
+ version: 0.0.15
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 13
46
+ segments:
47
+ - 1
48
+ - 2
49
+ - 9
50
+ version: 1.2.9
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: yard
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :development
66
+ version_requirements: *id003
67
+ description: |
68
+ This gem is part of the server-blender family (http://astrails.com/opensource/server-blender)
69
+ It contains core recipes cookbook. See server-blender for more information.
70
+
71
+ email: vitaly@astrails.com
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files:
77
+ - LICENSE
78
+ files:
79
+ - .document
80
+ - .gitignore
81
+ - LICENSE
82
+ - README.markdown
83
+ - Rakefile
84
+ - VERSION
85
+ - files/darwin/install-ports.sh
86
+ - files/fbucket
87
+ - files/gitconfig
88
+ - keys/github.com-host_key
89
+ - recipes/blender_tools.rb
90
+ - recipes/core.rb
91
+ - recipes/default.rb
92
+ - recipes/git.rb
93
+ - recipes/locales.rb
94
+ - recipes/os/darwin.rb
95
+ - recipes/os/debian.rb
96
+ - recipes/os/ubuntu.rb
97
+ - recipes/postfix.rb
98
+ - recipes/users.rb
99
+ - recipes/utils.rb
100
+ - server-blender-core.gemspec
101
+ - spec/recipes/core_spec.rb
102
+ - spec/spec.opts
103
+ - spec/spec_helper.rb
104
+ has_rdoc: true
105
+ homepage: http://astrails.com/opensource/server-blender
106
+ licenses: []
107
+
108
+ post_install_message:
109
+ rdoc_options:
110
+ - --charset=UTF-8
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements: []
132
+
133
+ rubyforge_project:
134
+ rubygems_version: 1.3.7
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: core recipes cookbook for server-blender
138
+ test_files: []
139
+