Permalink
Browse files

moving meta-cookbooks/cluster_chef specs into their own deal

  • Loading branch information...
1 parent c20bdb0 commit 470440e6f9f79b2ba7267b6e89948f1455ee5e53 Philip (flip) Kromer committed Dec 7, 2011
View
@@ -11,14 +11,14 @@ def run_spec(file)
puts
end
-# watch("spec/.*/*_spec\.rb") do |match|
-# run_spec match[0]
-# end
-#
-# watch("lib/(.*)\.rb") do |match|
-# file = %{spec/#{match[1]}_spec.rb}
-# run_spec file if File.exists?(file)
-# end
+watch("spec/.*/*_spec\.rb") do |match|
+ run_spec match[0]
+end
+
+watch("lib/(.*)\.rb") do |match|
+ file = %{spec/#{match[1]}_spec.rb}
+ run_spec file if File.exists?(file)
+end
# watch('lib/cluster_chef/cookbook_munger\.rb') do |match|
# system match[0]
@@ -27,12 +27,3 @@ end
# watch('lib/cluster_chef/cookbook_munger/.*\.erb') do |match|
# system 'lib/cluster_chef/cookbook_munger.rb'
# end
-
-watch("spec/.*/discovery_spec\.rb") do |match|
- run_spec match[0]
-end
-
-watch("meta-cookbooks/provides_service/libraries/discovery\.rb") do |match|
- file = %{spec/cluster_chef/discovery_spec.rb}
- run_spec file if File.exists?(file)
-end
View
@@ -79,20 +79,52 @@ For example, I am user `mrflip` and my organization is `infochimps`, so my tree
#
# Systems
#
+
+ #
+ # A server is something that (typically all, but at least most of)
+ # runs a daemon, opens ports, has logs, has directories, etc.
+ #
+ # if there's only one contender for the title of
+ #
[:apache, :server],
[:cassandra, :server],
- [:chef, :client],
- [:cron, :daemon],
- [:cluster_chef, :dashboard],
- # [:dash_dash, :dashboard],
+ [:mongodb, :server],
+ [:mysql, :server],
+ [:nfs, :server],
+ [:nginx, :server],
+ [:ntp, :server],
+ [:redis, :server],
+ [:statsd, :server],
+ [:zabbix, :server],
+ [:zookeeper, :server],
+ [:apt_cacher, :server],
+ [:dashpot, :server], # not dashboard
+ [:resque, :server],
+ [:openssh, :server],
+
+ # !not extra server: an announcement some cassandra servers make!
+ [:cassandra, :seed],
+ [:elasticsearch, :seed],
+ # similarly, a mysql-master is also a mysql-server
+ [:mysql, :master],
+ [:mysql, :slave ],
+ [:redis, :master],
+ [:redis, :slave ],
+
+ # where there are lots of server-y things
+ # give them their system-specific natural name.
+ # If there are multiple server-y names, avoid if possible giving any of them the subsytem name 'server'...
+
+ [:chef, :expander],
+ [:chef, :server], # ... but don't fight city hall: if its name is server go with server
+ [:chef, :solr],
+ [:chef, :webui],
[:elasticsearch, :datanode],
[:elasticsearch, :httpnode],
- [:flume, :client],
[:flume, :master],
[:ganglia, :master],
- [:ganglia, :monitor],
[:graphite, :carbon],
- [:graphite, :dashboard],
+ [:graphite, :dashboard],
[:graphite, :whisper],
[:hadoop, :datanode],
[:hadoop, :hdfs_fuse],
@@ -103,32 +135,32 @@ For example, I am user `mrflip` and my organization is `infochimps`, so my tree
[:hbase, :master],
[:hbase, :regionserver],
[:hbase, :stargate],
- [:mongodb, :server],
- [:mysql, :server],
+ [:jenkins, :master],
+ [:jenkins, :worker],
+ [:resque, :worker],
+
+ #
+ # A 'client' means 'I install all the stuff to let you *use* some other
+ # component. We're not even sure if these announce.
+ #
[:nfs, :client],
- [:nfs, :server],
- [:nginx, :server],
- [:ntp, :server],
- [:redis, :server],
- [:resque, :dashboard],
- [:openssh, :daemon],
- [:statsd, :server],
- [:zabbix, :monitor],
- [:zabbix, :server],
- [:zookeeper, :server],
+ [:redis, :client],
- [:apt_cacher, :server],
- [:bluepill, :monitor],
- [:goliath, :app],
- [:unicorn, :app],
- [:resque, :worker],
+ # An 'agent' is a thing that runs and uses that thing. A client is not
+ # necessarily an agent.
+ [:flume, :agent],
+ [:zabbix, :agent],
+ [:cron, :agent],
+ [:ganglia, :agent],
+ [:bluepill, :agent],
+
+ # The chef-client daemon is in this terminology properly an 'agent' -- if it
+ # conformed to the style guide, chef_client would install the runnable, and
+ # chef_agent would be the daemon which periodically contacts the chef_server
+ # and converges the machine.
+ [:chef, :client],
- [:chef, :dashboard],
- [:chef, :expander],
- [:chef, :server],
- [:chef, :solr],
- [:jenkins, :master],
- [:jenkins, :worker],
+__________________________________________________________________________
#
# Discovery / preparation
View
@@ -32,3 +32,10 @@ a.out
*/.bzr/*
*/.hg/*
*/.svn/*
+
+## Don't send rspecs up in cookbook
+.watchr
+.rspec
+spec/*
+spec/fixtures/*
+
@@ -0,0 +1,3 @@
+--color
+--format documentation
+--drb
@@ -0,0 +1,20 @@
+# -*- ruby -*-
+
+def run_spec(file)
+ unless File.exist?(file)
+ Watchr.debug "#{file} does not exist"
+ return
+ end
+
+ Watchr.debug "Running #{file}"
+ system "rspec #{file}"
+end
+
+watch("spec/.*_spec\.rb") do |match|
+ run_spec match[0]
+end
+
+watch("libraries/(.*)\.rb") do |match|
+ file = %{spec/#{match[1]}_spec.rb}
+ run_spec file if File.exists?(file)
+end
@@ -0,0 +1,15 @@
+source "http://rubygems.org"
+
+gem 'chef', "~> 0.10.4"
+
+# Add dependencies to develop your gem here.
+# Include everything needed to run rake, tests, features, etc.
+group :development do
+ gem 'bundler', "~> 1"
+ gem 'yard', "~> 0.6.7"
+ gem 'jeweler', "~> 1.6.4"
+ gem 'rspec', "~> 2.7.0"
+ gem 'watchr', "~> 0.7"
+ # gem 'ruby-fsevent', "~> 0.2"
+ # gem 'rev'
+end
@@ -61,19 +61,17 @@ def lint!
end
def lint_flavor
- self.class.allowed_flavors.include?(self.flavor) ? [] : ["Unexpected #{klass_handle} flavor #{flavor.inspect}"]
+ self.class.allowed_flavors.include?(self.flavor) ? [] : ["Unexpected #{self.class.handle} flavor #{flavor.inspect}"]
end
- # simple handle for class
- # @example
- # foo = ClusterChef::FooAspect
- # foo.klass_handle # :foo
- def klass_handle() self.class.klass_handle ; end
-
module ClassMethods
include AttrStruct::ClassMethods
include ClusterChef::NodeUtils
+ def register!
+ ClusterChef::Component.has_aspect(self)
+ end
+
#
# Extract attributes matching the given pattern.
#
@@ -110,9 +108,9 @@ def rsrc_matches(rsrc_clxn, resource_name, cookbook_name)
end
# strip off module part and '...Aspect' from class name
- # @example ClusterChef::FooAspect.klass_handle # :foo
- def klass_handle
- @klass_handle ||= self.name.to_s.gsub(/.*::(\w+)Aspect\z/,'\1').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase.to_sym
+ # @example ClusterChef::FooAspect.handle # :foo
+ def handle
+ @handle ||= self.name.to_s.gsub(/.*::(\w+)Aspect\z/,'\1').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase.to_sym
end
end
@@ -119,9 +119,8 @@ def store_into_node(node, a, b=nil)
module ClassMethods
def dsl_attr(name, validation)
name = name.to_sym
- p name
- define_method(name) do |*args|
- set_or_return(name, *args, validation)
+ define_method(name) do |val=nil|
+ set_or_return(name, val, validation)
end
end
end
@@ -1,12 +1,17 @@
+$LOAD_PATH.unshift(File.dirname(__FILE__))
+
+# $LOAD_PATH.unshift(File.expand_path('../../../lib'), File.dirname(__FILE__))
+# require 'cluster_chef/dsl_object'
#
# Dependencies for cluster_chef libraries
#
require File.expand_path('attr_struct.rb', File.dirname(__FILE__))
-require File.expand_path('node_utils.rb', File.dirname(__FILE__))
-require File.expand_path('aspect.rb', File.dirname(__FILE__))
-require File.expand_path('aspects.rb', File.dirname(__FILE__))
-require File.expand_path('discovery.rb', File.dirname(__FILE__))
+require File.expand_path('node_utils.rb', File.dirname(__FILE__))
+require File.expand_path('component.rb', File.dirname(__FILE__))
+require File.expand_path('aspect.rb', File.dirname(__FILE__))
+require File.expand_path('aspects.rb', File.dirname(__FILE__))
+require File.expand_path('discovery.rb', File.dirname(__FILE__))
# FIXME -- remove:
@@ -13,12 +13,12 @@ class Component < Struct.new(
attr_reader :subsys # subsystem name: eg +:server+ or +:datanode+
attr_reader :node # node this component belongs to
- def initialize(node, sys, subsys=nil, hsh={})
+ def initialize(node, sys, subsys, hsh={})
super()
@node = node
@sys = sys
@subsys = subsys
- self.name = subsys ? "#{sys}_#{subsys}".to_sym : sys.to_sym
+ self.name = "#{sys}_#{subsys}".to_sym
self.timestamp = ClusterChef::NodeUtils.timestamp
merge!(hsh)
end
@@ -37,7 +37,7 @@ def fullname
# A segmented name for the component
def self.fullname(realm, sys, subsys=nil)
- subsys ? "#{realm}-#{sys}-#{subsys}".to_s : "#{realm}-#{sys}"
+ "#{realm}-#{sys}-#{subsys}".to_s
end
#
@@ -91,10 +91,9 @@ def self.aspect_types
end
# add this class to the list of registered aspects
- def self.register_aspect(klass)
- aspect_name = klass.klass_handle
- self.aspect_types[aspect_name] = klass
- dsl_attr(aspect_name, :kind_of => [Mash, klass])
+ def self.has_aspect(klass)
+ self.aspect_types[klass.handle] = klass
+ dsl_attr(klass.handle, :kind_of => [Mash, klass])
end
#
@@ -108,8 +107,6 @@ def self.register_aspect(klass)
# subsys hash, the subsys hash's value wins (see +:user+ in the
# example below).
#
- # If subsys is nil, just returns the direct node hash.
- #
# @example
# node.to_hash
# # { :hadoop => {
@@ -127,12 +124,10 @@ def self.register_aspect(klass)
def node_info
unless node[sys] then Chef::Log.warn("no system data in component '#{name}', node '#{node}'") ; return Mash.new ; end
hsh = Mash.new(node[sys].to_hash)
- if subsys
- if node[sys][subsys]
- hsh.merge!(node[sys][subsys])
- else
- Chef::Log.warn("no subsystem data in component '#{name}', node '#{node}'")
- end
+ if node[sys][subsys]
+ hsh.merge!(node[sys][subsys])
+ else
+ Chef::Log.warn("no subsystem data in component '#{name}', node '#{node}'")
end
hsh
end
@@ -144,9 +139,5 @@ def node_attr(attr, required=nil)
node_info[attr]
end
- def self.has_aspect(aspect, klass)
- @aspect_types ||= {}
- @aspect_types[aspect] = klass
- end
end
end
@@ -26,7 +26,7 @@ module Discovery
# @option opts [String] :realm Offer the component within this realm -- by
# default, the current node's cluster
#
- def announce(sys, subsys=nil, opts={})
+ def announce(sys, subsys, opts={})
opts = Mash.new(opts)
opts[:realm] ||= node[:cluster_name]
component = Component.new(run_context, sys, subsys, opts)
@@ -43,7 +43,7 @@ def announce(sys, subsys=nil, opts={})
# discover_all(:cassandra, :seeds, 'bukkit') # all cassandra seeds for 'bukkit' cluster
#
# @return [ClusterChef::Component] component from server to most recently-announce
- def discover_all(sys, subsys=nil, realm=nil)
+ def discover_all(sys, subsys, realm=nil)
realm ||= discovery_realm(sys,subsys)
component_name = ClusterChef::Component.fullname(realm, sys, subsys)
#
@@ -62,20 +62,17 @@ def discover_all(sys, subsys=nil, realm=nil)
# discover(:redis, :server, 'uploader') # redis server for 'uploader' realm
#
# @return [ClusterChef::Component] component from server to most recently-announce
- def discover(sys, subsys=nil, realm=nil)
+ def discover(sys, subsys, realm=nil)
discover_all(sys, subsys, realm).last or raise("Cannot find '#{component_name}'")
end
def discovery_realm(sys, subsys=nil)
- return node[:discovers][sys][subsys] if (node[:discovers][sys][subsys].is_a? String rescue false)
- return node[:discovers][sys] if (node[:discovers][sys].is_a? String rescue false)
- node[:cluster_name]
+ node[:discovers][sys][subsys] rescue node[:cluster_name]
end
def node_components(server)
server[:announces].map do |name, hsh|
realm, sys, subsys = name.split("-", 3)
- subsys = nil if (subsys.to_s == "")
hsh[:realm] = realm
ClusterChef::Component.new(server, sys, subsys, hsh)
end
Oops, something went wrong.

0 comments on commit 470440e

Please sign in to comment.