server-blender-core 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.
@@ -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
+