server-blender-manifest 0.0.8

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,26 @@
1
+ ## MISC
2
+ pkg
3
+ tags
4
+ .yardoc
5
+
6
+ ## MAC OS
7
+ .DS_Store
8
+
9
+ ## TEXTMATE
10
+ *.tmproj
11
+ tmtags
12
+
13
+ ## EMACS
14
+ *~
15
+ \#*
16
+ .\#*
17
+
18
+ ## VIM
19
+ *.swp
20
+
21
+ ## PROJECT::GENERAL
22
+ coverage
23
+ rdoc
24
+ pkg
25
+
26
+ ## PROJECT::SPECIFIC
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.
data/README.markdown ADDED
@@ -0,0 +1,23 @@
1
+ # server-blender-manifest
2
+
3
+ This gem is part of the [server-blender](http://astrails.com/opensource/server-blender) family.
4
+
5
+ It contains server-side root manifest implementation for blender recipes. See server-blender for more information.
6
+
7
+ * Home: [http://astrails.com/opensource/server-blender](http://astrails.com/opensource/server-blender)
8
+ * Code: [http://github.com/astrails/server-blender-manifest](http://github.com/astrails/server-blender-manifest)
9
+ * Blog: [http://blog.astrails.com/server-blender](http://blog.astrails.com/server-blender)
10
+
11
+ ## Note on Patches/Pull Requests
12
+
13
+ * Fork the project.
14
+ * Make your feature addition or bug fix.
15
+ * Add tests for it. This is important so I don't break it in a
16
+ future version unintentionally.
17
+ * Commit, do not mess with rakefile, version, or history.
18
+ (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)
19
+ * Send me a pull request. Bonus points for topic branches.
20
+
21
+ ## Copyright
22
+
23
+ Copyright (c) 2010 Vitaly Kushner. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "server-blender-manifest"
8
+ gem.summary = %Q{server-side root manifest implementation 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 server-side root manifest implementation for blender recipes. 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
+ gem.add_development_dependency "rspec", ">= 1.2.9"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :spec => :check_dependencies
37
+
38
+ task :default => :spec
39
+
40
+ # documentaion is included in the parent server-blender gem
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.8
@@ -0,0 +1,23 @@
1
+ module Blender::Manifest::Init
2
+ def self.included(base)
3
+ base.class_eval do
4
+ recipe :create_blender_directories
5
+ end
6
+ end
7
+
8
+ # create blender directories
9
+ # @return dependency ref for the direcotires creation
10
+ def create_blender_directories
11
+ @create_blender_directories ||=
12
+ begin
13
+ dep = directory "/var/lib/blender", :mode => 0700
14
+ dep = directory "/var/lib/blender/logs", :require => dep
15
+ dep = directory "/var/lib/blender/tmp", :require => dep
16
+ end
17
+ end
18
+
19
+ # @return dependency for blender directories
20
+ def builder_deps
21
+ create_blender_directories
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module Blender::Manifest::Mixer
2
+ # mixes recipe module
3
+ #
4
+ # The purpose is to make the mixing of recipes cleaner and easier on the eyes :)
5
+ # i.e. instead of
6
+ # require 'foo'
7
+ # include Blender::Recipes::Foo
8
+ # require 'bar'
9
+ # include Blender::Recipes::Bar
10
+ # you can just
11
+ # mix :foo, :bar
12
+ # @param [[String, Symbol, Module]] recipes to mix
13
+ def mix(*recipes)
14
+
15
+ recipes.each do |recipe|
16
+
17
+ next if Root.mixed_recipes.include?(recipe)
18
+ Root.mixed_recipes << recipe
19
+
20
+ case recipe
21
+ when String, Symbol
22
+ require recipe.to_s
23
+ mixin = "Blender::Recipes::#{recipe.to_s.camelize}".constantize
24
+ when Module
25
+ mixin = recipe
26
+ else
27
+ raise "Expecting String, Symbol or Module. don't know what do do with #{recipe.inspect}"
28
+ end
29
+
30
+ puts "MIX: #{mixin}"
31
+ ::Root.send :include, mixin
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,94 @@
1
+ # This module encapsulates nodes handeling
2
+ # Nodes can be declared both on a class level and inside a recipe
3
+ # When defining a node an 'id' is associated with its hostname
4
+ # and the node can later be reffered by this id (for example
5
+ # to get its ip)
6
+ module Blender::Manifest::Nodes
7
+
8
+ def self.included(base)
9
+ base.send :extend, self
10
+ end
11
+
12
+ # this holds the map from host ids to hostnames
13
+ @@internal_hostnames = {}
14
+ @@external_hostnames = {}
15
+
16
+ # returns hostname by id or local host's name if the id is nil
17
+ def hostname(id = nil, external = false)
18
+ if id
19
+ (external ? @@external_hostnames : @@internal_hostnames)[id]
20
+ else
21
+ external ? Facter.fqdn : Facter.hostname
22
+ end
23
+ end
24
+
25
+ # returns id of the node we are running at
26
+ # Note: will ONLY return non-nil value after (or during) node definition
27
+ # unless node is forced by environment NODE variable or /etc/node file
28
+ def current_node
29
+ node = ENV['NODE'] ||
30
+ (File.exists?("/etc/node") && File.read("/etc/node").strip) ||
31
+ @@internal_hostnames.index(hostname) ||
32
+ @@external_hostnames.index(hostname(nil, true))
33
+ node && node.to_sym
34
+ end
35
+
36
+ # @return true if we are running on the node with the given `id`
37
+ def current_node?(id)
38
+ current_node == id.to_sym
39
+ end
40
+
41
+ # resolves host name using 'host' executable
42
+ # @return host's IP by its name or nil if not found
43
+ def host_ip(name)
44
+ res = `host #{name}`.split("\n").grep(/has address/).first
45
+ res && res.split.last
46
+ end
47
+
48
+ # define node and conditionally execute code block only on the specific node
49
+ # Note: can be called multiple times without internal_name and external_name parameters
50
+ # in which case will only do the conditional execution
51
+ # @param [Symbol, String] id of the host to define or test for
52
+ # @param [String] internal_name short hostname for the host
53
+ # @param [String] external_name full dns hostname for the host
54
+ # @example
55
+ # node :app, "host5", "host5.serverfarm2.localdomain" do
56
+ # ...
57
+ # end
58
+ #
59
+ # node :app do
60
+ # ...
61
+ # end
62
+ #
63
+ def node(id, internal_name = nil, external_name = internal_name)
64
+ return if false == internal_name # can be used to temporary 'disable' host's definition
65
+ # like:
66
+ # host :app2, false do .. end
67
+ @@internal_hostnames[id] = internal_name if internal_name
68
+ @@external_hostnames[id] = external_name if external_name
69
+
70
+ if block_given? && current_node?(id)
71
+ puts "NODE: #{id} / #{current_node}"
72
+ @node = id
73
+ yield
74
+ end
75
+ end
76
+
77
+ # find out node addr. try to use external, then internal, then the host id to determine ip
78
+ # @param [Symbol, String] id id of the host to resolve
79
+ def addr(id)
80
+ [hostname(id, true).to_s, hostname(id).to_s, id.to_s].each do |name|
81
+ ip = host_ip(name)
82
+ return ip if ip
83
+ end
84
+
85
+ # if all else fails, we should still be able to address the current node
86
+ current_node?(id) ? "127.0.0.1" : nil
87
+ end
88
+
89
+ # same as addr but throws exception if IP can't be found
90
+ def addr!(id)
91
+ addr(id) or raise "Can't find address for '#{id}'"
92
+ end
93
+
94
+ end
@@ -0,0 +1,40 @@
1
+ module Blender::Manifest::Roles
2
+
3
+ def self.included(base)
4
+ base.send :extend, self
5
+ end
6
+
7
+ # A very simple mechanism to define roles
8
+ #
9
+ # Roles to accept can be defined from environment, /etc/roles file
10
+ # or can be explicitly defined like 'roles xxx, yyy'
11
+ # usually the 'roles a,b,c' call will come inside of
12
+ # a `node` block and so will be conditionally executed depending on the
13
+ # running host
14
+
15
+ def current_roles
16
+ @current_roles ||=
17
+ if ENV['ROLES']
18
+ ENV['ROLES'].split(",")
19
+ elsif File.exists?("/etc/roles")
20
+ File.read("/etc/roles").strip.split
21
+ else
22
+ []
23
+ end
24
+ end
25
+
26
+ # ADDS roles to the currently defined roles
27
+ def roles *roles
28
+ current_roles.concat(roles.map {|r| r.to_s})
29
+ end
30
+
31
+ # conditionally runs the code block if the role 'r' is
32
+ # currently defined
33
+ def role r
34
+ if block_given? && current_roles.include?(r.to_s)
35
+ puts "ROLE: #{r}"
36
+ yield
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,38 @@
1
+ require 'ruby-debug'
2
+ $: << File.dirname(__FILE__) # FIXME: remove?
3
+
4
+ module Blender
5
+ module Manifest; end
6
+ module Recipes; end
7
+ end
8
+ require 'init'
9
+ require 'nodes'
10
+ require 'roles'
11
+ require 'mixer'
12
+
13
+ class Root < ::ShadowPuppet::Manifest
14
+ include Blender::Manifest::Init
15
+ include Blender::Manifest::Nodes
16
+ include Blender::Manifest::Roles
17
+
18
+ @@mixed_recipes = []
19
+ def self.mixed_recipes
20
+ @@mixed_recipes
21
+ end
22
+
23
+ def execute_user_recipe
24
+ raise "no RECIPE to execute" unless recipe = ENV['RECIPE']
25
+
26
+ code = open(recipe).read
27
+ instance_eval(code, recipe)
28
+ end
29
+ recipe :execute_user_recipe
30
+ end
31
+
32
+ include Blender::Manifest::Mixer
33
+
34
+ # "standard" recipe directories
35
+ $: << "recipes" << "recipes/astrails" << "lib/astrails/blender/recipes"
36
+
37
+ # add all libs in the ./vendor directory to the path
38
+ $:.concat Dir["vendor/*/"]
@@ -0,0 +1,58 @@
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-manifest}
8
+ s.version = "0.0.8"
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-06-15}
13
+ s.description = %q{This gem is part of the server-blender family (http://astrails.com/opensource/server-blender)
14
+ It contains server-side root manifest implementation for blender recipes. See server-blender for more information.
15
+ }
16
+ s.email = %q{vitaly@astrails.com}
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.markdown"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.markdown",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/blender/manifest/init.rb",
28
+ "lib/blender/manifest/mixer.rb",
29
+ "lib/blender/manifest/nodes.rb",
30
+ "lib/blender/manifest/roles.rb",
31
+ "lib/blender/manifest/root.rb",
32
+ "server-blender-manifest.gemspec",
33
+ "spec/spec.opts",
34
+ "spec/spec_helper.rb"
35
+ ]
36
+ s.homepage = %q{http://astrails.com/opensource/server-blender}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.6}
40
+ s.summary = %q{server-side root manifest implementation for server-blender}
41
+ s.test_files = [
42
+ "spec/spec_helper.rb"
43
+ ]
44
+
45
+ if s.respond_to? :specification_version then
46
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
50
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
51
+ else
52
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
53
+ end
54
+ else
55
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
56
+ end
57
+ end
58
+
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'server-blender-manifest'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: server-blender-manifest
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 8
9
+ version: 0.0.8
10
+ platform: ruby
11
+ authors:
12
+ - Vitaly Kushner
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-15 00:00:00 +03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
31
+ version: 1.2.9
32
+ type: :development
33
+ version_requirements: *id001
34
+ description: |
35
+ This gem is part of the server-blender family (http://astrails.com/opensource/server-blender)
36
+ It contains server-side root manifest implementation for blender recipes. See server-blender for more information.
37
+
38
+ email: vitaly@astrails.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - LICENSE
45
+ - README.markdown
46
+ files:
47
+ - .gitignore
48
+ - LICENSE
49
+ - README.markdown
50
+ - Rakefile
51
+ - VERSION
52
+ - lib/blender/manifest/init.rb
53
+ - lib/blender/manifest/mixer.rb
54
+ - lib/blender/manifest/nodes.rb
55
+ - lib/blender/manifest/roles.rb
56
+ - lib/blender/manifest/root.rb
57
+ - server-blender-manifest.gemspec
58
+ - spec/spec.opts
59
+ - spec/spec_helper.rb
60
+ has_rdoc: true
61
+ homepage: http://astrails.com/opensource/server-blender
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.6
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: server-side root manifest implementation for server-blender
90
+ test_files:
91
+ - spec/spec_helper.rb