lib/testlab.rb in testlab-0.3.0 vs lib/testlab.rb in testlab-0.3.1
- old
+ new
@@ -1,16 +1,92 @@
require 'ztk'
+require 'active_support/inflector'
require 'testlab/version'
require 'testlab/monkeys'
-# Top-Level TestLab Class
+# TestLab - A framework for building lightweight virtual infrastructure using LXC
#
-# @author Zachary Patten <zachary@jovelabs.net>
+# The core concept with the TestLab is the *Labfile*. This file dictates the
+# topology of your virtual infrastructure. With simple commands you can setup
+# and teardown this infrastructure on the fly for all sorts of purposes from
+# automating infrastructure testing to testing new software to experimenting
+# in general where you want to spin up alot of servers but do not want the
+# overhead of virtualization. At it's core TestLab uses Linux Containers (LXC)
+# to accomplish this.
+#
+# @example Sample Labfile:
+# shell_provision_script = <<-EOF
+# set -x
+# apt-get -y update
+# apt-get -y install dnsutils
+# EOF
+#
+# config Hash[
+# :domain => "default.zone"
+# ]
+#
+# node :localhost do
+# components %w(resolv bind)
+#
+# provider TestLab::Provider::Vagrant
+# config Hash[
+# :vagrant => {
+# :id => "mytestlab-#{ENV['USER']}".downcase,
+# :ip => "192.168.13.37",
+# :user => "vagrant",
+# :port => 22,
+# :cpus => 8,
+# :memory => 16384,
+# :box => 'raring64'
+# },
+# :repo => File.join(ENV['HOME'], "code", "personal", "testlab-repo")
+# ]
+#
+# network :east do
+# address '10.10.0.1/16'
+# bridge :br0
+# end
+#
+# container "server-east-1" do
+# domain "east.zone"
+#
+# distro "ubuntu"
+# release "precise"
+#
+# provisioner TestLab::Provisioner::Shell
+# config Hash[
+# :shell => "/bin/bash",
+# :setup => shell_provision_script
+# ]
+#
+# interface do
+# name :eth0
+# network_id :east
+# address '10.10.0.254/16'
+# mac '00:00:5e:b7:e5:15'
+# end
+# end
+#
+# end
+#
+# @example TestLab can be instantiated easily:
+# log_file = File.join(Dir.pwd, "testlab.log")
+# logger = ZTK::Logger.new(log_file)
+# ui = ZTK::UI.new(:logger => logger)
+# testlab = TestLab.new(:ui => ui)
+#
+# @example We can control things via code easily as well:
+# testlab.create # creates the lab
+# testlab.up # ensures the lab is up and running
+# testlab.setup # setup the lab, creating all networks and containers
+# testlab.teardown # teardown the lab, destroy all networks and containers
+#
+# @author Zachary Patten <zachary AT jovelabs DOT com>
class TestLab
- # Top-Level Error Class
+ # TestLab Error Class
class TestLabError < StandardError; end
# Main Classes
autoload :Container, 'testlab/container'
autoload :Interface, 'testlab/interface'
@@ -22,15 +98,14 @@
autoload :Utility, 'testlab/utility'
include TestLab::Utility::Misc
def initialize(options={})
- labfile = (options[:labfile] || 'Labfile')
- labfile_path = ZTK::Locator.find(labfile)
-
self.ui = (options[:ui] || ZTK::UI.new)
+ labfile = (options[:labfile] || 'Labfile')
+ labfile_path = ZTK::Locator.find(labfile)
@labfile = TestLab::Labfile.load(labfile_path)
end
# Test Lab Nodes
#
@@ -69,54 +144,23 @@
@labfile.config
end
# Test Lab Alive?
#
- # Are all of our nodes alive; that is up and running?
+ # Are all of our nodes up and running?
#
- # @return [Boolean] True is all nodes are running; false otherwise.
+ # @return [Boolean] True if all nodes are running; false otherwise.
def alive?
nodes.map(&:state).all?{ |state| state == :running }
end
# Test Lab Dead?
#
- # Are any of our nodes dead; that is not up and running?
+ # Are any of our nodes not up and running?
#
# @return [Boolean] False is all nodes are running; true otherwise.
def dead?
!alive?
- end
-
- # Test Lab Status
- #
- # Iterates our various DSL objects and calls their status methods pushing
- # the results through ZTK::Report to generate nice tabled output for us
- # indicating the state of the lab.
- #
- # This can only be run if the lab is alive.
- #
- # @return [Boolean] True if successful; false otherwise.
- def status
- if alive?
- %w(nodes networks containers).map(&:to_sym).each do |object_symbol|
- self.ui.stdout.puts
- self.ui.stdout.puts("#{object_symbol}:".upcase.green.bold)
-
- klass = object_symbol.to_s.singularize.capitalize
- status_keys = "TestLab::#{klass}::STATUS_KEYS".constantize
-
- ZTK::Report.new(:ui => self.ui).spreadsheet(self.send(object_symbol), status_keys) do |object|
- OpenStruct.new(object.status)
- end
- end
-
- true
- else
- self.ui.stdout.puts("Looks like your test lab is dead; fix this and try again.")
-
- false
- end
end
# Test Lab Setup
#
# Attempts to setup our lab topology. This calls the setup method on all of