Skip to content

Commit

Permalink
add 'snapshot' command to zerg
Browse files Browse the repository at this point in the history
  • Loading branch information
maratoid committed Sep 9, 2014
1 parent 9c5deb0 commit b02b166
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 8 deletions.
8 changes: 7 additions & 1 deletion zerg/lib/zerg/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def remove(file)

class CLI < Thor
class_option :force, :type => :boolean, :banner => "force overwrite of files"
class_option :debug, :type => :boolean, :banner => "add debug option to driver"
class_option :debug, :type => :boolean, :banner => "add debug option to driver"
class_option :base, :type => :string, :banner => "base name for the snapshot"

def self.exit_on_failure?
true
Expand All @@ -84,6 +85,11 @@ def clean(task)
def halt(task)
puts Zerg::Runner.halt(task, options[:debug])
end

desc "snapshot [TASK]", "takes a snapshot of currently running vms"
def snapshot(task)
puts Zerg::Runner.snapshot(task, options[:base])
end

register(HiveCLI, 'hive', 'hive [COMMAND]', 'Manage hive - a collection of task descriptions.')
end
Expand Down
18 changes: 18 additions & 0 deletions zerg/lib/zerg/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,23 @@ def self.clean(task, debug)
end
puts("SUCCESS!")
end

def self.snapshot(task, base)
# load the hive first
Zerg::Hive.instance.load

puts "Loaded hive. Looking for task #{task}..."
abort("ERROR: Task #{task} not found in current hive!") unless Zerg::Hive.instance.hive.has_key?(task)

begin
pmgr = ZergGemPlugin::Manager.instance
pmgr.load
driver = pmgr.create("/driver/#{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]}")
driver.snapshot Zerg::Hive.instance.load_path, task, Zerg::Hive.instance.hive[task], base
rescue ZergGemPlugin::PluginNotLoaded
abort("ERROR: driver #{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]} not found. Did you install the plugin gem?")
end
puts("SUCCESS!")
end
end
end
2 changes: 1 addition & 1 deletion zerg/lib/zerg/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
#++

module Zerg
VERSION = "0.0.21"
VERSION = "0.0.22"
end
4 changes: 2 additions & 2 deletions zerg/zerg.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Gem::Specification.new do |s|
s.add_dependency "json-schema"
s.add_dependency "thor"
s.add_dependency "highline"
s.add_dependency "zergrush_vagrant", ">= 0.0.4"
s.add_dependency "zergrush_cf", ">= 0.0.14"
s.add_dependency "zergrush_vagrant", ">= 0.0.5"
s.add_dependency "zergrush_cf", ">= 0.0.15"

s.files = `git ls-files`.split("\n")
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
Expand Down
75 changes: 75 additions & 0 deletions zerg_plugins/zergrush_cf/lib/zergrush_cf/init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,81 @@ def clean hive_location, task_name, task_hash, debug
abort ("ERROR: AWS error: #{fog_cf_error.ai}")
end

def snapshot hive_location, task_name, task_hash, base
aws_key_id = task_hash["vm"]["driver"]["driveroptions"][0]["access_key_id"]
aws_secret = task_hash["vm"]["driver"]["driveroptions"][0]["secret_access_key"]

# eval possible environment variables
if aws_key_id =~ /^ENV\['.+'\]$/
aws_key_id = eval(aws_key_id)
end

if aws_secret =~ /^ENV\['.+'\]$/
aws_secret = eval(aws_secret)
end

abort("AWS key id is not specified in task") unless aws_key_id != nil
abort("AWS secret is not specified in task") unless aws_secret != nil

base_name = (base.nil?) ? "#{task_name}" : base

puts("creating AMI Snapshots of all EC2 instances. Will use base name of #{base_name}")

cf = Fog::AWS::CloudFormation.new(
:aws_access_key_id => aws_key_id,
:aws_secret_access_key => aws_secret
)

fogCompute = Fog::Compute.new(
:provider => 'AWS',
:aws_access_key_id => aws_key_id,
:aws_secret_access_key => aws_secret
)

rabbit_objects = initRabbitConnection(task_hash["vm"]["driver"]["driveroptions"][0]["rabbit"])

# create the cloudformation stack
stack_name = "#{task_name}"
processStack(stack_name, base_name, cf, fogCompute)
return 0

rescue Fog::Errors::Error => fog_cf_error
abort ("ERROR: AWS error: #{fog_cf_error.message}")
end

def processStack stack_name, base_name, fogCF, fogCompute
fogCF.describe_stack_resources({ 'StackName' => stack_name })[:body]['StackResources'].each { |stack_resource|
if stack_resource['ResourceType'] == 'AWS::EC2::Instance'
saveAmi(stack_resource, base_name, fogCompute)
elsif stack_resource['ResourceType'] == 'AWS::CloudFormation::Stack'
processStack(stack_resource['PhysicalResourceId'].split('/')[1], base_name, fogCF, fogCompute)
end
}
end

def saveAmi ec2res, base_name, fogCompute
liveInstance = fogCompute.describe_instances({ 'instance-id' => ec2res['PhysicalResourceId'] })[:body]
nameTag = liveInstance['reservationSet'][0]['instancesSet'][0]['tagSet']['Name'].split(':')[1].downcase

ap "Creating AMI #{base_name}-#{nameTag}. Stack resource:"
ap ec2res

ap 'Checking if image already exists...'
imageSet = fogCompute.describe_images( { 'name' => "#{base_name}-#{nameTag}" } )[:body]
if imageSet['imagesSet'].length > 0
imageId = imageSet[0]['imageId']
ap "Deregistering old image #{imageId}..."
response = fogCompute.deregister_image(imageId)
abort("ERROR: deregistering #{imageId} failed!") unless response[:body]['return'] == true
end

ap 'Saving new image...'
newId = fogCompute.create_image(ec2res['PhysicalResourceId'], "#{base_name}-#{nameTag}", "#{base_name}-#{nameTag} snapshot")[:body]['imageId']
ap "Created new AMI #{newId}"
ap "Tagging #{newId} with #{base_name}"
fogCompute.create_tags(newId, { base_name => base_name })
end

def logEvents events
events.each do |event|
puts "Timestamp: #{Time.parse(event['Timestamp'].to_s).iso8601}"
Expand Down
2 changes: 1 addition & 1 deletion zerg_plugins/zergrush_cf/lib/zergrush_cf/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
#++

module ZergrushCF
VERSION = "0.0.14"
VERSION = "0.0.15"
end
2 changes: 1 addition & 1 deletion zerg_plugins/zergrush_cf/zergrush_cf.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Gem::Specification.new do |s|

s.add_development_dependency "bundler", ">= 1.0.0"
s.add_development_dependency "rake"
s.add_development_dependency "zergrush", ">= 0.0.21"
s.add_development_dependency "zergrush", ">= 0.0.22"

s.add_dependency "fog", ">=1.20.0"
s.add_dependency "bunny", ">=1.2.1"
Expand Down
4 changes: 4 additions & 0 deletions zerg_plugins/zergrush_vagrant/lib/zergrush_vagrant/init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ def halt hive_location, task_name, task_hash, debug
end
end

def snapshot hive_location, task_name, task_hash, base
abort("ERROR: Not implemented!")
end

def task_schema
return File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "tasks_schema.template"), 'r').read
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
#++

module ZergrushVagrant
VERSION = "0.0.4"
VERSION = "0.0.5"
end
2 changes: 1 addition & 1 deletion zerg_plugins/zergrush_vagrant/zergrush_vagrant.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Gem::Specification.new do |s|

s.add_development_dependency "bundler", ">= 1.0.0"
s.add_development_dependency "rake"
s.add_development_dependency "zergrush", ">= 0.0.7"
s.add_development_dependency "zergrush", ">= 0.0.22"

s.add_dependency "ipaddress"

Expand Down

0 comments on commit b02b166

Please sign in to comment.