Move the concept of a Livery around to denote an actual class with more "structure"
This effectively breaks the crap out of existing Blimpfiles with a `ship.livery = :cwd` line, or something similar. I think it's worth it at this point. Liveries will have some access to the box object itself, so that API will need to remain consistent for some time. It's expected that every Livery will have at least: * setup_on(box) * preflight(box) * flight(box) * postflight(box) This should be enough for just about every livery to do what it needs to do with the created box. This should also allow (in the future) a Livery to express variables or other configuration information "outward" for the consumption of other Liveries.
This commit is contained in:
parent
8964005338
commit
9ed4d3ac99
|
@ -4,6 +4,34 @@ Feature: Craft machines based on a livery
|
|||
When I specify a specific livery then that livery should provision
|
||||
the host the way I would expect it to.
|
||||
|
||||
@wip
|
||||
Scenario: Using a configuration-less livery
|
||||
Given the following Blimpfile contents:
|
||||
"""
|
||||
Blimpy.fleet do |fleet|
|
||||
fleet.add(:aws) do |ship|
|
||||
ship.name = 'cucumber-livery'
|
||||
ship.livery = Blimpy::Livery::CWD
|
||||
end
|
||||
end
|
||||
"""
|
||||
When I evaluate the Blimpfile
|
||||
Then the "CWD" livery should be set up
|
||||
|
||||
@slow @destroy @wip
|
||||
Scenario: freebsd_puppet
|
||||
@wip
|
||||
Scenario: Configuration-less liveries
|
||||
Given the following Blimpfile contents:
|
||||
"""
|
||||
Blimpy.fleet do |fleet|
|
||||
fleet.add(:aws) do |ship|
|
||||
ship.name = 'cucumber-livery'
|
||||
ship.livery = Blimpy::Livery::Puppet.configure do |p|
|
||||
p.module_path = './modules'
|
||||
p.manifest_path = './test/site.pp'
|
||||
p.options = '--verbose'
|
||||
end
|
||||
end
|
||||
end
|
||||
"""
|
||||
When I evaluate the Blimpfile
|
||||
Then the Puppet livery should be correctly configured
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
Given /^the following Blimpfile contents:$/ do |buffer|
|
||||
@blimpfile = buffer
|
||||
end
|
||||
|
||||
When /^I evaluate the Blimpfile$/ do
|
||||
@blimpfile.should_not be_nil
|
||||
@fleet = eval(@blimpfile)
|
||||
@fleet.should_not be_nil
|
||||
end
|
||||
|
||||
Then /^the "([^"]*)" livery should be set up$/ do |arg1|
|
||||
pending # express the regexp above with the code you wish you had
|
||||
end
|
||||
|
|
@ -46,4 +46,5 @@ module Blimpy
|
|||
end
|
||||
class UnsupportedFeatureException < Exception
|
||||
end
|
||||
class InvalidLiveryException < Exception; end;
|
||||
end
|
||||
|
|
|
@ -75,10 +75,16 @@ module Blimpy
|
|||
|
||||
def bootstrap
|
||||
@exec_commands = false
|
||||
unless livery.nil?
|
||||
wait_for_sshd
|
||||
bootstrap_livery
|
||||
if @livery.nil?
|
||||
return
|
||||
end
|
||||
|
||||
if @livery.respond_to? :new
|
||||
@livery = @livery.new
|
||||
end
|
||||
|
||||
wait_for_sshd
|
||||
bootstrap_livery
|
||||
end
|
||||
|
||||
def stop
|
||||
|
@ -204,46 +210,14 @@ module Blimpy
|
|||
end
|
||||
|
||||
def bootstrap_livery
|
||||
script = File.expand_path(File.dirname(__FILE__) + "/../../scripts/#{livery}.sh")
|
||||
|
||||
if livery == :cwd
|
||||
script = File.join(Dir.pwd, '/bootstrap.sh')
|
||||
if @livery.kind_of? Symbol
|
||||
raise Blimpy::InvalidLiveryException, 'Symbol liveries are unsupported!'
|
||||
end
|
||||
|
||||
unless File.exists?(script)
|
||||
puts "Could not find `#{script}` which is needed to kick-start the machine"
|
||||
return
|
||||
end
|
||||
|
||||
unpack_command = 'true'
|
||||
dir_name = File.basename(Dir.pwd)
|
||||
|
||||
if can_rsync?
|
||||
unpack_command = "cd #{dir_name}"
|
||||
run_command('rsync', '-avL',
|
||||
'-e',
|
||||
'ssh -o StrictHostKeyChecking=no',
|
||||
'--exclude=.git',
|
||||
'--exclude=.svn',
|
||||
'--exclude=.blimpy.d',
|
||||
'.',
|
||||
"#{username}@#{dns}:#{dir_name}/")
|
||||
else
|
||||
puts "Remote host has no rsync(1), falling back to copying a full tarball over"
|
||||
tarball = Blimpy::Livery.tarball_directory(Dir.pwd)
|
||||
scp_file(tarball)
|
||||
# HAXX
|
||||
basename = File.basename(tarball)
|
||||
ssh_into("tar -zxf #{basename} && cd #{dir_name}")
|
||||
end
|
||||
|
||||
puts 'Bootstrapping the livery'
|
||||
run_sudo = 'sudo'
|
||||
if username == 'root'
|
||||
run_sudo = ''
|
||||
end
|
||||
scp_file(script, dir_name)
|
||||
ssh_into("cd #{dir_name} && #{run_sudo} ./#{File.basename(script)}")
|
||||
@livery.setup_on(self)
|
||||
@livery.preflight(self)
|
||||
@livery.flight(self)
|
||||
@livery.postflight(self)
|
||||
end
|
||||
|
||||
def wait_for_sshd
|
||||
|
|
|
@ -2,8 +2,10 @@ require 'rubygems'
|
|||
require 'zlib'
|
||||
require 'archive/tar/minitar'
|
||||
|
||||
require 'blimpy/livery/cwd'
|
||||
|
||||
module Blimpy
|
||||
class Livery
|
||||
module Livery
|
||||
def self.tarball_directory(directory)
|
||||
if directory.nil? || !(File.directory? directory)
|
||||
raise ArgumentError, "The argument '#{directory}' doesn't appear to be a directory"
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
module Blimpy
|
||||
module Livery
|
||||
class Base
|
||||
def preflight(*args)
|
||||
end
|
||||
|
||||
def flight(*args)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def postflight(*args)
|
||||
end
|
||||
|
||||
def rsync_excludes
|
||||
['.git', '.svn', '.blimpy.d']
|
||||
end
|
||||
|
||||
def rsync_command
|
||||
excludes = rsync_excludes.map { |x| "--exclude=#{x}" }
|
||||
['rsync',
|
||||
'-avL',
|
||||
'-e',
|
||||
'ssh -o StrictHostKeyChecking=no'] + excludes
|
||||
end
|
||||
|
||||
def sync_to(box)
|
||||
if can_rsync?
|
||||
command = rsync_command + ['.', "#{box.username}@#{box.dns}:#{dir_name}/"]
|
||||
box.run_command(*command)
|
||||
else
|
||||
puts "Remote host has no rsync(1), falling back to copying a full tarball over"
|
||||
tarball = Blimpy::Livery.tarball_directory(livery_root)
|
||||
box.scp_file(tarball)
|
||||
# HAXX
|
||||
basename = File.basename(tarball)
|
||||
box.ssh_into("tar -zxf #{basename} && cd #{dir_name}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def livery_root
|
||||
Dir.pwd
|
||||
end
|
||||
|
||||
def dir_name
|
||||
File.basename(livery_root)
|
||||
end
|
||||
|
||||
def setup_on(box)
|
||||
sync_to(box)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
require 'blimpy/livery/base'
|
||||
|
||||
module Blimpy
|
||||
module Livery
|
||||
class CWD < Base
|
||||
def script
|
||||
'bootstrap.sh'
|
||||
end
|
||||
|
||||
def preflight(box)
|
||||
box.scp_file(bootstrap_script, dir_name)
|
||||
end
|
||||
|
||||
def flight(box)
|
||||
run_sudo = 'sudo'
|
||||
|
||||
if box.username == 'root'
|
||||
run_sudo = ''
|
||||
end
|
||||
|
||||
box.ssh_into("cd #{dir_name} && #{run_sudo} ./#{script}")
|
||||
end
|
||||
|
||||
def bootstrap_script
|
||||
File.join(livery_root, script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -144,5 +144,55 @@ describe Blimpy::Box do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#bootstrap_livery' do
|
||||
let(:livery) { double('Mock-livery') }
|
||||
|
||||
it 'should raise an error if the livery is a symbol (old style)' do
|
||||
subject.livery = :deprecated
|
||||
expect {
|
||||
subject.bootstrap_livery
|
||||
}.to raise_error(Blimpy::InvalidLiveryException)
|
||||
end
|
||||
|
||||
it 'should invoke the correct livery methods' do
|
||||
subject.livery = livery
|
||||
livery.should_receive(:setup_on).with(subject)
|
||||
livery.should_receive(:preflight).with(subject)
|
||||
livery.should_receive(:flight).with(subject)
|
||||
livery.should_receive(:postflight).with(subject)
|
||||
|
||||
subject.bootstrap_livery
|
||||
end
|
||||
end
|
||||
|
||||
describe '#bootstrap' do
|
||||
context 'when livery is not defined' do
|
||||
before :each do
|
||||
subject.livery = nil
|
||||
end
|
||||
|
||||
it 'should not call any of the bootstrap methods' do
|
||||
subject.should_receive(:wait_for_sshd).never
|
||||
subject.should_receive(:bootstrap_livery).never
|
||||
subject.bootstrap
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a livery is defined' do
|
||||
before :each do
|
||||
subject.should_receive(:wait_for_sshd)
|
||||
subject.should_receive(:bootstrap_livery)
|
||||
end
|
||||
|
||||
context 'as a class object' do
|
||||
it 'should instantiate the livery' do
|
||||
subject.livery = Blimpy::Livery::CWD
|
||||
subject.livery.should_receive(:new)
|
||||
subject.bootstrap
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
require 'spec_helper'
|
||||
require 'blimpy/livery/base'
|
||||
|
||||
|
||||
describe Blimpy::Livery::Base do
|
||||
describe '#rsync_excludes' do
|
||||
it { subject.rsync_excludes.should be_instance_of Array }
|
||||
end
|
||||
|
||||
describe '#rsync_command' do
|
||||
subject { described_class.new.rsync_command }
|
||||
|
||||
it { expect(subject.first).to eql('rsync') }
|
||||
it { should include('--exclude=.git') }
|
||||
end
|
||||
|
||||
describe '#livery_root' do
|
||||
it { expect(subject.livery_root).to eql(Dir.pwd) }
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
require 'blimpy/livery/cwd'
|
||||
|
||||
describe Blimpy::Livery::CWD do
|
||||
|
||||
end
|
Loading…
Reference in New Issue