stem 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -23,7 +23,7 @@ You can monitor the instance's fabrication process via
23
23
 
24
24
  The instance you created will boot, install some packages on top of a stock Ubuntu 10.4 AMI, then (if everything goes according to plan) shut itself down and go into a "stopped" state that indicates success. If any part of the stem fabrication fails, the instance will remain running. Once the instance reaches stopped, type
25
25
 
26
- $ stem create postgres-server <instance-id>
26
+ $ stem create postgres-server <instance-id> appserver,current,tag_3
27
27
 
28
28
  The AMI may take as long as half an hour to build, depending on how the gremlins in EC2 are behaving on any given day. You can check on their progress with
29
29
 
data/lib/stem/cli.rb CHANGED
@@ -19,7 +19,7 @@ module Stem
19
19
  opts.separator " $ stem launch prototype.config prototype-userdata.sh"
20
20
  opts.separator " $ stem launch examples/lxc-server/lxc-server.json examples/lxc-server/"
21
21
  opts.separator " $ stem list"
22
- opts.separator " $ stem create ami-name instance-id"
22
+ opts.separator " $ stem create ami-name instance-id ami_tag1,ami_tag2"
23
23
 
24
24
  opts.separator " "
25
25
  opts.separator "Options:"
@@ -76,9 +76,10 @@ module Stem
76
76
  puts "New instance ID: #{instance}"
77
77
  end
78
78
 
79
- def create name = nil, instance = nil
80
- abort "Usage: create ami-name instance-to-capture" unless name && instance
81
- image_id = Stem::Image::create(name, instance)
79
+ def create name = nil, instance = nil, tag_list = nil
80
+ abort "Usage: create ami-name instance-to-capture ami_tag1,ami_tag2" unless name && instance
81
+ tags = tag_list ? tag_list.split(',') : []
82
+ image_id = Stem::Image::create(name, instance, tags)
82
83
  puts "New image ID: #{image_id}"
83
84
  end
84
85
 
data/lib/stem/image.rb CHANGED
@@ -3,9 +3,11 @@ module Stem
3
3
  include Util
4
4
  extend self
5
5
 
6
- def create name, instance
7
- description = {}
8
- swirl.call("CreateImage", "InstanceId" => instance, "Name" => name, "Description" => "%%" + description.to_json)["imageId"]
6
+ def create name, instance, *tags
7
+ raise "You already have an image named '#{name}'" if named(name)
8
+ image_id = swirl.call("CreateImage", "Name" => name, "InstanceId" => instance)["imageId"]
9
+ Tag::create(image_id, tags) unless tags.empty?
10
+ image_id
9
11
  end
10
12
 
11
13
  def deregister image
@@ -13,8 +15,15 @@ module Stem
13
15
  end
14
16
 
15
17
  def named name
16
- i = swirl.call "DescribeImages", "Owner" => "self"
17
- ami = i["imagesSet"].select {|m| m["name"] == name }.map { |m| m["imageId"] }.first
18
+ i = swirl.call "DescribeImages", "Owner" => "self"
19
+ ami = i["imagesSet"].select {|m| m["name"] == name }.map { |m| m["imageId"] }.first
20
+ end
21
+
22
+ def tagged *tags
23
+ return if tags.empty?
24
+ opts = { "tag-key" => tags.map {|t| t.to_s } }
25
+ opts = get_filter_opts(opts).merge("Owner" => "self")
26
+ swirl.call("DescribeImages", opts)['imagesSet'].map {|image| image['imageId'] }
18
27
  end
19
28
 
20
29
  def describe image
data/lib/stem/instance.rb CHANGED
@@ -12,6 +12,9 @@ module Stem
12
12
  elsif config["ami-name"]
13
13
  ami = Image::named(config["ami-name"])
14
14
  throw "AMI named #{config["ami-name"]} was not found. (Does it need creating?)" unless ami
15
+ elsif config["ami-tags"]
16
+ ami = Image::tagged(config['ami-tags'])
17
+ throw "AMI tagged with #{config['ami-tags'].join(', ')} was not found. (Does it need creating?)" unless ami
15
18
  end
16
19
  throw "No AMI specified." unless ami
17
20
 
@@ -45,10 +48,10 @@ module Stem
45
48
  end
46
49
 
47
50
  response = swirl.call "RunInstances", opt
51
+ instance_id = response["instancesSet"].first["instanceId"]
48
52
 
49
- response["instancesSet"].each do |i|
50
- return i["instanceId"]
51
- end
53
+ Tag::create(instance_id, config['tags']) if config['tags'] && !config['tags'].empty?
54
+ instance_id
52
55
  end
53
56
 
54
57
  def restart instance_id
@@ -119,5 +122,19 @@ module Stem
119
122
  end
120
123
  end
121
124
  end
125
+
126
+ def tagged *tags
127
+ return if tags.empty?
128
+ opts = { "tag-key" => tags.map {|t| t.to_s } }
129
+ instances = swirl.call "DescribeInstances", get_filter_opts(opts)
130
+
131
+ ids = []
132
+ instances["reservationSet"].each do |r|
133
+ r["instancesSet"].each do |i|
134
+ ids << i["instanceId"]
135
+ end
136
+ end
137
+ ids
138
+ end
122
139
  end
123
140
  end
data/lib/stem/tag.rb ADDED
@@ -0,0 +1,28 @@
1
+ module Stem
2
+ module Tag
3
+ include Util
4
+ extend self
5
+
6
+ def create resource_ids, tags
7
+ resource_ids = [ resource_ids ] unless resource_ids.is_a? Array
8
+ swirl.call("CreateTags", tag_opts(tags).merge("ResourceId" => resource_ids) )
9
+ end
10
+
11
+ def destroy resource_ids, tags
12
+ resource_ids = [ resource_ids ] unless resource_ids.is_a? Array
13
+ swirl.call("DeleteTags", tag_opts(tags).merge("ResourceId" => resource_ids) )
14
+ end
15
+
16
+ def tag_opts(tags)
17
+ if tags.is_a? Array
18
+ {
19
+ "Tag.#.Key" => tags,
20
+ "Tag.#.Value" => (1..tags.size).map { '' }
21
+ }
22
+ else
23
+ { "Tag.1.Key" => tags.to_s, "Tag.1.Value" => '' }
24
+ end
25
+ end
26
+
27
+ end
28
+ end
data/lib/stem/util.rb CHANGED
@@ -1,10 +1,37 @@
1
1
  module Stem
2
2
  module Util
3
3
  def swirl
4
- @swirl ||= Swirl::EC2.new(
5
- :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
6
- :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
7
- )
4
+ account = "default"
5
+ etc = "#{ENV["HOME"]}/.swirl"
6
+ config = \
7
+ if ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
8
+ {
9
+ :aws_access_key_id => ENV["AWS_ACCESS_KEY_ID"],
10
+ :aws_secret_access_key => ENV["AWS_SECRET_ACCESS_KEY"]
11
+ }
12
+ else
13
+ account = account.to_sym
14
+ data = YAML.load_file(etc)
15
+ if data.key?(account)
16
+ data[account]
17
+ else
18
+ abort("I don't see the account you're looking for")
19
+ end
20
+ end
21
+
22
+ @swirl = Swirl::EC2.new config
23
+ end
24
+
25
+ def get_filter_opts(filters)
26
+ opts = {}
27
+ filters.each do |k, v|
28
+ opts["Filter.1.Name"] = k
29
+ v = [ v ] unless v.is_a? Array
30
+ v.each_with_index do |v, i|
31
+ opts["Filter.1.Value.#{i}"] = v.to_s
32
+ end
33
+ end
34
+ opts
8
35
  end
9
36
  end
10
37
  end
data/lib/stem.rb CHANGED
@@ -10,4 +10,5 @@ require 'stem/userdata'
10
10
  require 'stem/instance'
11
11
  require 'stem/image'
12
12
  require 'stem/ip'
13
+ require 'stem/tag'
13
14
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stem
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
8
  - 4
10
- version: 0.3.4
9
+ - 0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Peter van Hardenberg
@@ -53,6 +53,7 @@ files:
53
53
  - lib/stem/image.rb
54
54
  - lib/stem/instance.rb
55
55
  - lib/stem/ip.rb
56
+ - lib/stem/tag.rb
56
57
  - lib/stem/userdata.rb
57
58
  - lib/stem/util.rb
58
59
  - lib/stem.rb