Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rebuild command #90

Merged
merged 3 commits into from
Feb 11, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions lib/tugboat/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,40 @@ def create(name)
})
end

desc "rebuild FUZZY_NAME IMAGE_NAME", "Rebuild a droplet."
method_option "id",
:type => :string,
:aliases => "-i",
:desc => "The ID of the droplet."
method_option "name",
:type => :string,
:aliases => "-n",
:desc => "The exact name of the droplet"
method_option "confirm",
:type => :boolean,
:aliases => "-c",
:desc => "Skip confirmation of the action"
method_option "image_id",
:type => :numeric,
:aliases => "-k",
:desc => "The ID of the image"
method_option "image_name",
:type => :string,
:aliases => "-m",
:desc => "The exact name of the image"
def rebuild(name=nil, image_name=nil)
Middleware.sequence_rebuild_droplet.call({
"user_droplet_id" => options[:id],
"user_droplet_name" => options[:name],
"user_droplet_fuzzy_name" => name,
"user_image_id" => options[:image_id],
"user_image_name" => options[:image_name],
"user_image_fuzzy_name" => image_name,
"user_confirm_action" => options[:confirm],
"user_quiet" => options[:quiet]
})
end

desc "destroy FUZZY_NAME", "Destroy a droplet"
method_option "id",
:type => :string,
Expand Down
15 changes: 15 additions & 0 deletions lib/tugboat/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ module Middleware
autoload :CheckDropletInactive, "tugboat/middleware/check_droplet_inactive"
autoload :ConfirmAction, "tugboat/middleware/confirm_action"
autoload :CreateDroplet, "tugboat/middleware/create_droplet"
autoload :RebuildDroplet, "tugboat/middleware/rebuild_droplet"
autoload :DestroyDroplet, "tugboat/middleware/destroy_droplet"
autoload :FindDroplet, "tugboat/middleware/find_droplet"
autoload :FindImage, "tugboat/middleware/find_image"
autoload :HaltDroplet, "tugboat/middleware/halt_droplet"
autoload :InfoDroplet, "tugboat/middleware/info_droplet"
autoload :InjectClient, "tugboat/middleware/inject_client"
Expand Down Expand Up @@ -141,6 +143,19 @@ def self.sequence_create_droplet
end
end

# Rebuild a droplet
def self.sequence_rebuild_droplet
::Middleware::Builder.new do
use InjectConfiguration
use CheckConfiguration
use InjectClient
use FindDroplet
use FindImage
use ConfirmAction
use RebuildDroplet
end
end

# Destroy a droplet
def self.sequence_destroy_droplet
::Middleware::Builder.new do
Expand Down
113 changes: 113 additions & 0 deletions lib/tugboat/middleware/find_image.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
module Tugboat
module Middleware
# Check if the client has set-up configuration yet.
class FindImage < Base
def call(env)
ocean = env["ocean"]
user_fuzzy_name = env['user_image_fuzzy_name']
user_image_name = env['user_image_name']
user_image_id = env['user_image_id']

# First, if nothing is provided to us, we should quit and
# let the user know.
if !user_fuzzy_name && !user_image_name && !user_image_id
say "Tugboat attempted to find an image with no arguments. Try `tugboat help`", :red
exit 1
end

# If you were to `tugboat restart foo -n foo-server-001` then we'd use
# 'foo-server-001' without looking up the fuzzy name.
#
# This is why we check in this order.

# Easy for us if they provide an id. Just set it to the image_id
if user_image_id
say "Image id provided. Finding Image...", nil, false
req = ocean.images.show user_image_id

if req.status == "ERROR"
say "#{req.status}: #{req.error_message}", :red
exit 1
end

env["image_id"] = req.image.id
env["image_name"] = "(#{req.image.name})"
end

# If they provide a name, we need to get the ID for it.
# This requires a lookup.
if user_image_name && !env["image_id"]
say "Image name provided. Finding image ID...", nil, false

# Look for the image by an exact name match.
ocean.images.list.images.each do |d|
if d.name == user_image_name
env["image_id"] = d.id
env["image_name"] = "(#{d.name})"
end
end

# If we coulnd't find it, tell the user and drop out of the
# sequence.
if !env["image_id"]
say "error\nUnable to find a image named '#{user_image_name}'.", :red
exit 1
end
end

# We only need to "fuzzy find" a image if a fuzzy name is provided,
# and we don't want to fuzzy search if an id or name is provided
# with a flag.
#
# This requires a lookup.
if user_fuzzy_name && !env["image_id"]
say "Image fuzzy name provided. Finding image ID...", nil, false

found_images = []
choices = []

ocean.images.list.images.each_with_index do |d, i|
# Check to see if one of the image names have the fuzzy string.
if d.name.upcase.include? user_fuzzy_name.upcase
found_images << d
end
end

# Check to see if we have more then one image, and prompt
# a user to choose otherwise.
if found_images.length == 1
env["image_id"] = found_images.first.id
env["image_name"] = "(#{found_images.first.name})"
elsif found_images.length > 1
# Did we run the multiple questionairre?
did_run_multiple = true

say "Multiple images found."
say
found_images.each_with_index do |d, i|
say "#{i}) #{d.name} (#{d.id})"
choices << i.to_s
end
say
choice = ask "Please choose a image:", :limited_to => choices
env["image_id"] = found_images[choice.to_i].id
env["image_name"] = found_images[choice.to_i].name
end

# If we coulnd't find it, tell the user and drop out of the
# sequence.
if !env["image_id"]
say "error\nUnable to find an image named '#{user_fuzzy_name}'.", :red
exit 1
end
end

if !did_run_multiple
say "done#{CLEAR}, #{env["image_id"]} #{env["image_name"]}", :green
end
@app.call(env)
end
end
end
end

23 changes: 23 additions & 0 deletions lib/tugboat/middleware/rebuild_droplet.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Tugboat
module Middleware
class RebuildDroplet < Base
def call(env)
ocean = env["ocean"]

say "Queuing rebuild for droplet #{env["droplet_id"]} #{env["droplet_name"]} with image #{env["image_id"]} #{env["image_name"]}...", nil, false

req = ocean.droplets.rebuild env["droplet_id"],
:image_id => env["image_id"]

if req.status == "ERROR"
say req.error_message, :red
exit 1
end

say "done", :green

@app.call(env)
end
end
end
end
Loading