Class: Sproutr

Inherits:
Thor
  • Object
show all
Includes:
Thor::Actions
Defined in:
lib/sproutr.rb

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Sproutr

Returns a new instance of Sproutr.



19
20
21
22
# File 'lib/sproutr.rb', line 19

def initialize(*args)
  super
  @ec2 ||= Swirl::AWS.new :ec2, load_config
end

Instance Method Details

#cloneObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/sproutr.rb', line 30

def clone
  options[:instance].each do |ami_to_clone|
    if options[:ami] then
      ami_id = options[:ami]
    else
      ami_id = @ec2.call("CreateImage", "InstanceId" => ami_to_clone, "Name" => "AMI-#{ami_to_clone}-#{Time.now.to_i}",
                         "Description" => "AMI created from #{ami_to_clone} at #{Time.now}", "NoReboot" => "true")["imageId"]
    end
    new_config = clone_ami_config(@ec2.call("DescribeInstances", "InstanceId" => ami_to_clone)["reservationSet"][0]["instancesSet"][0], ami_id)
    until ami_done?(ami_id) do
      say "Ami creation has not completed so this clone can not yet be started. Sleeping 30 seconds", :red
      sleep 30
    end
    new_instance = invoke_launch(new_config)
    say "Created and started #{new_instance}", :green
    tag_instance(new_instance, options[:tags]) if options[:tags]
  end
end

#create_amiObject



54
55
56
# File 'lib/sproutr.rb', line 54

def create_ami
  @ec2.call "CreateImage", "InstanceId" => options[:ami], "Name" => options[:name], "Description" => options[:desc], "NoReboot" => "true"
end

#defineObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sproutr.rb', line 60

def define
  definition = Definition.new do |d|
    d.name = demand "What do you want to call this definition (Required): "
    d.size = demand "What size instance do you want (Required): "
    d.ami = demand "What base AMI image would you like to use (Required): "
    ami_info = Cloud.new.describe_image(d.ami)
    break unless yes? "Is this the Image -- #{ami_info["imagesSet"][0]["name"]} -- you wish to build from?", :red
    d.packages = ask "What additional packages do you want installed (Optional): ", :green
    d.gems = ask "What gems do you want to install on this machine by default (Optional): ", :green
    d.chef_cookbooks = ask "Please name the chef cookbooks you wish to automatically download (Optional): ", :green
    d.chef_recipes = ask "Enter the recipes you wish chef to run after cookbooks are installed (Optional): ", :green
    d.user_data = demand "Please copy/paste your Userdata.sh here now. Note, sproutr will automatically add in the
requisite code to download and install Cheff cookbooks, and aggregate additional volumes
into a singluar raid array (Required): "
    d.tags = ask "Please enter the tags you'd like in name:value format (Optional, Note that the Name will automatically be specified): ", :green
    d.volumes = ask "Please enter the number of additional volumes (Optional, Note that these additional volumes will be RAID/LVM enabled as 1 *logical* volume): ", :green
    d.volume_size = ask "Please enter the size of each component volume in Gigabytes (Optional, Currently all volumes are identical in size): ", :green
    d.availability_zone = demand "Please enter the availability zone you wish to instantiate this machine in: "
    d.key_name = demand "Which key-pair would you like to use? use the key name: "
  end
  definition.save_to_file(definition.name+"_definition.json")
end

#delete_snapshotObject



86
87
88
89
90
91
# File 'lib/sproutr.rb', line 86

def delete_snapshot
  options[:snapshot].each do |snapshot_id|
    result = @ec2.call "DeleteSnapshot", "SnapshotId" => snapshot_id
    say result["return"], :green
  end
end

#describeObject



96
97
98
99
100
# File 'lib/sproutr.rb', line 96

def describe
  options[:ami].each do |ami|
    ap @ec2.call("DescribeInstances", "InstanceId" => ami)["reservationSet"][0]["instancesSet"][0]
  end
end

#growObject



106
107
108
109
110
111
112
# File 'lib/sproutr.rb', line 106

def grow
  options[:ami].each do |ami|
    Instance::call_on(@ec2, "StopInstances", ami)
    @ec2.call "ModifyInstanceAttribute", "InstanceId" => ami, "InstanceType" => options[:size]
    Instance::call_on(@ec2, "StartInstances", ami)
  end
end

#launchObject



117
118
119
120
121
# File 'lib/sproutr.rb', line 117

def launch
  config = JSON.parse(File.new(options[:config_file]).read) if File.exists? options[:config_file]
  throw "Failed to read config file, or config file does not specify an ImageId" unless config["ami"]
  say invoke_launch(validate_launch_config(config)), :blue
end

#listObject



125
126
127
128
# File 'lib/sproutr.rb', line 125

def list
  invoke :list_instances
  invoke :list_amis
end

#list_amisObject



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/sproutr.rb', line 132

def list_amis
  @ami_images = Cloud.new.get_images
  ami_table = table do |a|
    a.headings = 'Name', 'AMI Id', 'Type', 'State', 'Size', 'Architecture', 'Public?', 'Description'
    @ami_images.each do |ami|
      begin
        ami_size = ami.blockDeviceMapping.first["ebs"]["volumeSize"]
      rescue
        ami_size = "unknown"
      end
      a << [ami.name, ami.imageId, ami.rootDeviceType, ami.imageState, ami_size,
            ami.architecture, ami.isPublic, ami.description]
    end
  end
  puts ami_table
end

#list_instancesObject



151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/sproutr.rb', line 151

def list_instances
  instances = Cloud.new.get_instances
  instance_table = table do |i|
    i.headings = 'Name', 'Instance Id', 'Status', 'ip Address', 'Instance Type', 'AMI Image', 'Availablity Zone', 'DNS Cname'
    instances.each do |instance|
      p instance.inspect
      i << [((instance.tagSet.nil?) ? "Name Not Set" : instance.tagSet[0]["value"]),
            instance.instanceId, instance.instanceState["name"], instance.ipAddress,
            instance.instanceType, instance.imageId, instance.placement["availabilityZone"], instance.dnsName]
    end
  end
  puts instance_table
end

#list_snapshotsObject Also known as: list_snapshot



167
168
169
170
171
172
173
174
175
176
# File 'lib/sproutr.rb', line 167

def list_snapshots
  snapshots = @ec2.call("DescribeSnapshots", "Owner" => "self")["snapshotSet"]
  snapshots_table = table do |s|
    s.headings = snapshots.first.keys
    snapshots.each do |snap|
      s << snap.values
    end
  end
  puts snapshots_table
end

#migrateObject



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/sproutr.rb', line 182

def migrate
  ami_id = @ec2.call("CreateImage", "InstanceId" => ami_to_clone, "Name" => "AMI-#{options["ami"]}-#{Time.now.to_i}",
                     "Description" => "AMI created from #{options["ami"]} at #{Time.now}", "NoReboot" => "true")["imageId"]

  current_config = @ec2.call("DescribeInstances", "InstanceId" => options["ami"])["reservationSet"][0]["instancesSet"][0]
  new_config = clone_ami_config(current_config, ami_id)

  until ami_done?(ami_id) do
    say "Ami creation has not completed so the new instance can not yet be started. Sleeping 30 seconds", :red
    sleep 30
  end
  new_instance = invoke_launch(validate_launch_config(new_config, options[:target]))
  say "Created and started #{new_instance}", :green
  tag_instance(new_instance, options[:tags]) if options[:tags]
end

#restartObject



201
202
203
# File 'lib/sproutr.rb', line 201

def restart
  options[:ami].each { |ami| Instance::call_on(@ec2, "RebootInstances", ami) }
end

#snapshotObject



209
210
211
212
213
214
# File 'lib/sproutr.rb', line 209

def snapshot
  options[:ami].each do |ami|
    instance_volumes = @ec2.call("DescribeInstances", "InstanceId" => ami)["reservationSet"][0]["instancesSet"][0]["blockDeviceMapping"]
    instance_volumes.each { |volume| ap @ec2.call("CreateSnapshot", "VolumeId" => volume["ebs"]["volumeId"], "Description" => options[:desc]) }
  end
end

#startObject



220
221
222
# File 'lib/sproutr.rb', line 220

def start
  options[:ami].each { |ami| Instance::call_on(@ec2, "StartInstances", ami) }
end

#stopObject



227
228
229
# File 'lib/sproutr.rb', line 227

def stop
  options[:ami].each { |ami| Instance::call_on(@ec2, "StopInstances", ami) if yes? "Do you really want to stop the #{ami} instance? ", :red }
end

#terminateObject Also known as: destroy, shrink



235
236
237
238
239
240
# File 'lib/sproutr.rb', line 235

def terminate
  options[:ami].each do |ami|
    verify = ask "Do you really want to terminate the #{ami} instance? ", :red
    Instance::call_on(@ec2, "TerminateInstances", ami) if verify.downcase == "y" || verify.downcase == "yes"
  end
end