builderator 0.3.15 → 1.0.0.pre.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +9 -0
- data/Gemfile.lock +440 -0
- data/README.md +72 -18
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/bin/build-clean +102 -0
- data/bin/build-data +45 -0
- data/builderator.gemspec +7 -4
- data/docs/configuration.md +154 -0
- data/docs/configuration/cookbook.md +19 -0
- data/docs/configuration/profile.md +71 -0
- data/docs/versioning.md +65 -0
- data/lib/builderator.rb +3 -0
- data/lib/builderator/config.rb +93 -0
- data/lib/builderator/config/attributes.rb +287 -0
- data/lib/builderator/config/defaults.rb +163 -0
- data/lib/builderator/config/file.rb +336 -0
- data/lib/builderator/config/rash.rb +80 -0
- data/lib/builderator/control/cleaner.rb +138 -0
- data/lib/builderator/control/cookbook.rb +16 -0
- data/lib/builderator/control/data.rb +16 -0
- data/lib/builderator/control/data/image.rb +98 -0
- data/lib/builderator/control/version.rb +128 -0
- data/lib/builderator/control/version/auto.rb +48 -0
- data/lib/builderator/control/version/bump.rb +82 -0
- data/lib/builderator/control/version/comparable.rb +77 -0
- data/lib/builderator/control/version/git.rb +45 -0
- data/lib/builderator/control/version/scm.rb +92 -0
- data/lib/builderator/interface.rb +67 -0
- data/lib/builderator/interface/berkshelf.rb +38 -0
- data/lib/builderator/interface/packer.rb +75 -0
- data/lib/builderator/interface/vagrant.rb +31 -0
- data/lib/builderator/metadata.rb +5 -3
- data/lib/builderator/model/cleaner.rb +49 -0
- data/lib/builderator/model/cleaner/images.rb +93 -0
- data/lib/builderator/model/cleaner/instances.rb +58 -0
- data/lib/builderator/model/cleaner/launch_configs.rb +47 -0
- data/lib/builderator/model/cleaner/scaling_groups.rb +45 -0
- data/lib/builderator/model/cleaner/snapshots.rb +50 -0
- data/lib/builderator/model/cleaner/volumes.rb +48 -0
- data/lib/builderator/patch/berkshelf.rb +18 -0
- data/lib/builderator/patch/thor-actions.rb +47 -0
- data/lib/builderator/tasks.rb +127 -17
- data/lib/builderator/tasks/berkshelf.rb +63 -0
- data/lib/builderator/tasks/packer.rb +17 -56
- data/lib/builderator/tasks/vagrant.rb +111 -42
- data/lib/builderator/tasks/vendor.rb +94 -0
- data/lib/builderator/tasks/version.rb +58 -0
- data/lib/builderator/util.rb +37 -11
- data/lib/builderator/util/aws_exception.rb +1 -1
- data/lib/builderator/util/limit_exception.rb +12 -11
- data/lib/builderator/util/task_exception.rb +0 -2
- data/mkmf.log +4 -0
- data/spec/config_spec.rb +30 -0
- data/spec/data/Berksfile +6 -0
- data/spec/data/Buildfile +0 -0
- data/spec/data/Vagrantfile +0 -0
- data/spec/data/history.json +483 -0
- data/spec/data/packer.json +0 -0
- data/spec/interface_spec.rb +36 -0
- data/spec/resource/Buildfile +27 -0
- data/spec/spec_helper.rb +90 -0
- data/spec/version_spec.rb +282 -0
- data/template/Berksfile.erb +10 -0
- data/template/Buildfile.erb +28 -0
- data/template/Gemfile.erb +16 -0
- data/template/README.md.erb +61 -0
- data/template/Vagrantfile.erb +75 -0
- data/template/gitignore.erb +104 -0
- data/{.rubocop.yml → template/rubocop.erb} +0 -0
- metadata +203 -56
- data/.gitignore +0 -14
- data/lib/builderator/control/ami.rb +0 -65
- data/lib/builderator/control/clean.rb +0 -130
- data/lib/builderator/model.rb +0 -46
- data/lib/builderator/model/images.rb +0 -89
- data/lib/builderator/model/instances.rb +0 -55
- data/lib/builderator/model/launch_configs.rb +0 -46
- data/lib/builderator/model/scaling_groups.rb +0 -43
- data/lib/builderator/model/snapshots.rb +0 -49
- data/lib/builderator/model/volumes.rb +0 -48
- data/lib/builderator/tasks/ami.rb +0 -47
- data/lib/builderator/tasks/berks.rb +0 -68
- data/lib/builderator/tasks/clean.rb +0 -97
- data/lib/builderator/util/berkshim.rb +0 -34
- data/lib/builderator/util/cookbook.rb +0 -87
- data/lib/builderator/util/packer.rb +0 -39
- data/lib/builderator/util/shell.rb +0 -44
data/.gitignore
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'aws-sdk'
|
2
|
-
require 'date'
|
3
|
-
|
4
|
-
require_relative '../util'
|
5
|
-
|
6
|
-
module Builderator
|
7
|
-
module Control
|
8
|
-
##
|
9
|
-
# Find AMI IDs to use for sources
|
10
|
-
##
|
11
|
-
module AMI
|
12
|
-
## Account IDs of public image owners
|
13
|
-
module Owners
|
14
|
-
SELF = 'self'.freeze
|
15
|
-
UBUNTU = '099720109477'.freeze
|
16
|
-
AMAZON = 'amazon'.freeze
|
17
|
-
end
|
18
|
-
|
19
|
-
## Filter fields defined in http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Builderator::Util.ec2.html#describe_images-instance_method
|
20
|
-
FILTERS = %w(architecture block-device-mapping.delete-on-termination
|
21
|
-
block-device-mapping.device-name block-device-mapping.snapshot-id
|
22
|
-
block-device-mapping.volume-size block-device-mapping.volume-type
|
23
|
-
description hypervisor image-id image-type is-public kernel-id
|
24
|
-
manifest-location name owner-alias owner-id platform product-code
|
25
|
-
product-code.type ramdisk-id root-device-name root-device-type
|
26
|
-
state state-reason-code state-reason-message virtualization-type).freeze
|
27
|
-
|
28
|
-
class << self
|
29
|
-
def search(filters = {})
|
30
|
-
[].tap do |images|
|
31
|
-
Builderator::Util.ec2.describe_images(search_options(filters)).each { |page| images.push(*page.images) }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def latest(filters)
|
36
|
-
search(filters).sort do |a, b|
|
37
|
-
DateTime.iso8601(b.creation_date) <=> DateTime.iso8601(a.creation_date)
|
38
|
-
end.first
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def search_options(filters)
|
44
|
-
{}.tap do |options|
|
45
|
-
options[:image_ids] = Util.to_array(filters.delete(:image_id)) if filters.include?(:image_id)
|
46
|
-
options[:owners] = Util.to_array(filters.delete(:owner) { 'self' })
|
47
|
-
|
48
|
-
rfilters = [].tap do |f|
|
49
|
-
filters.each do |k, v|
|
50
|
-
next if v.nil?
|
51
|
-
|
52
|
-
f << {
|
53
|
-
:name => FILTERS.include?(k.to_s) ? k : "tag:#{ k }",
|
54
|
-
:values => Util.to_array(v)
|
55
|
-
}
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
options[:filters] = rfilters unless rfilters.empty?
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,130 +0,0 @@
|
|
1
|
-
require_relative '../model'
|
2
|
-
require_relative '../util'
|
3
|
-
|
4
|
-
module Builderator
|
5
|
-
module Control
|
6
|
-
##
|
7
|
-
# Control logic for cleanup tasks
|
8
|
-
##
|
9
|
-
module Clean
|
10
|
-
class << self
|
11
|
-
|
12
|
-
def options(arg = nil)
|
13
|
-
return @options unless arg.is_a?(Hash)
|
14
|
-
|
15
|
-
@options = arg.clone
|
16
|
-
|
17
|
-
Util.region(@options.delete('region'))
|
18
|
-
@commit = @options.delete('commit') { false }
|
19
|
-
@limit = @options.delete('limit') { true }
|
20
|
-
|
21
|
-
@options
|
22
|
-
end
|
23
|
-
|
24
|
-
def configs!
|
25
|
-
resources = Model.launch_configs.unused(options)
|
26
|
-
|
27
|
-
limit!(Model::LaunchConfigs, 'Cleanup Launch Configurations', resources, &Proc.new)
|
28
|
-
aborted!(&Proc.new)
|
29
|
-
|
30
|
-
resources.each do |l, _|
|
31
|
-
yield :remove, "Launch Configuration #{ l }", :red
|
32
|
-
Model.launch_configs.resources.delete(l)
|
33
|
-
|
34
|
-
next unless commit?
|
35
|
-
Util.asg.delete_launch_configuration(:launch_configuration_name => l)
|
36
|
-
end
|
37
|
-
rescue Aws::AutoScaling::Errors::ServiceError => e
|
38
|
-
exceptions << Util::AwsException.new('Cleanup Launch Configurations', e)
|
39
|
-
yield(*exceptions.last.status)
|
40
|
-
end
|
41
|
-
|
42
|
-
def images!
|
43
|
-
resources = Model.images.unused(options)
|
44
|
-
|
45
|
-
limit!(Model::Images, 'Cleanup Images', resources, &Proc.new)
|
46
|
-
aborted!(&Proc.new)
|
47
|
-
|
48
|
-
resources.each do |i, image|
|
49
|
-
yield :remove, "Image #{ i } (#{ image[:properties]['name'] })", :red
|
50
|
-
Model.images.resources.delete(i)
|
51
|
-
|
52
|
-
next unless commit?
|
53
|
-
Util.ec2.deregister_image(:image_id => i)
|
54
|
-
end
|
55
|
-
rescue Aws::EC2::Errors::ServiceError => e
|
56
|
-
exceptions << Util::AwsException.new('Cleanup Images', e)
|
57
|
-
yield(*exceptions.last.status)
|
58
|
-
end
|
59
|
-
|
60
|
-
def snapshots!
|
61
|
-
resources = Model.snapshots.unused
|
62
|
-
|
63
|
-
limit!(Model::Snapshots, 'Cleanup Snapshots', resources, &Proc.new)
|
64
|
-
aborted!(&Proc.new)
|
65
|
-
|
66
|
-
resources.each do |s, _|
|
67
|
-
yield :remove, "Snapshot #{ s }", :red
|
68
|
-
Model.snapshots.resources.delete(s)
|
69
|
-
|
70
|
-
next unless commit?
|
71
|
-
Util.ec2.delete_snapshot(:snapshot_id => s)
|
72
|
-
end
|
73
|
-
rescue Aws::EC2::Errors::ServiceError => e
|
74
|
-
exceptions << Util::AwsException.new('Cleanup Snapshots', e)
|
75
|
-
yield(*exceptions.last.status)
|
76
|
-
end
|
77
|
-
|
78
|
-
def volumes!
|
79
|
-
resources = Model.volumes.unused
|
80
|
-
|
81
|
-
limit!(Model::Volumes, 'Cleanup Volumes', resources, &Proc.new)
|
82
|
-
aborted!(&Proc.new)
|
83
|
-
|
84
|
-
resources.each do |v, _|
|
85
|
-
yield :remove, "Volume #{ v }", :red
|
86
|
-
Model.volumes.resources.delete(v)
|
87
|
-
|
88
|
-
next unless commit?
|
89
|
-
Util.ec2.delete_volume(:volume_id => v)
|
90
|
-
end
|
91
|
-
rescue Aws::EC2::Errors::ServiceError => e
|
92
|
-
exceptions << Util::AwsException.new('Cleanup Volumes', e)
|
93
|
-
yield(*exceptions.last.status)
|
94
|
-
end
|
95
|
-
|
96
|
-
def commit?
|
97
|
-
@commit && !@abort
|
98
|
-
end
|
99
|
-
|
100
|
-
def limit?
|
101
|
-
@limit
|
102
|
-
end
|
103
|
-
|
104
|
-
def aborted?
|
105
|
-
@commit && @abort
|
106
|
-
end
|
107
|
-
|
108
|
-
def exceptions
|
109
|
-
@exceptions ||= []
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
def aborted!
|
115
|
-
yield :aborted, 'The following resources will NOT be removed because'\
|
116
|
-
' safty constraints have not been met!', :yellow if aborted?
|
117
|
-
end
|
118
|
-
|
119
|
-
def limit!(klass, task, resources)
|
120
|
-
return unless limit? && (resources.size >= klass::LIMIT)
|
121
|
-
|
122
|
-
exceptions << Util::LimitException.new(klass, task, resources)
|
123
|
-
@abort = true
|
124
|
-
|
125
|
-
yield(*exceptions.last.status)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
data/lib/builderator/model.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
module Builderator
|
2
|
-
module Model
|
3
|
-
##
|
4
|
-
# Shared model interface
|
5
|
-
##
|
6
|
-
class Base
|
7
|
-
attr_reader :resources
|
8
|
-
LIMIT = 4
|
9
|
-
|
10
|
-
def initialize(*args)
|
11
|
-
fetch(*args)
|
12
|
-
end
|
13
|
-
|
14
|
-
def fetch
|
15
|
-
@resources = {}
|
16
|
-
end
|
17
|
-
|
18
|
-
def find(filters = {})
|
19
|
-
Util.filter(resources, filters)
|
20
|
-
end
|
21
|
-
|
22
|
-
def select(set = [])
|
23
|
-
resources.select { |k, _| set.include?(k) }
|
24
|
-
end
|
25
|
-
|
26
|
-
def reject(set = [])
|
27
|
-
resources.reject { |k, _| set.include?(k) }
|
28
|
-
end
|
29
|
-
|
30
|
-
def in_use(options = {})
|
31
|
-
find(options.fetch('filters', {}))
|
32
|
-
end
|
33
|
-
|
34
|
-
def unused(options = {})
|
35
|
-
Util.filter(reject(in_use(options)), options.fetch('filters', {}))
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
require_relative './model/images'
|
42
|
-
require_relative './model/instances'
|
43
|
-
require_relative './model/launch_configs'
|
44
|
-
require_relative './model/scaling_groups'
|
45
|
-
require_relative './model/snapshots'
|
46
|
-
require_relative './model/volumes'
|
@@ -1,89 +0,0 @@
|
|
1
|
-
require 'aws-sdk'
|
2
|
-
require_relative '../util'
|
3
|
-
|
4
|
-
module Builderator
|
5
|
-
module Model
|
6
|
-
|
7
|
-
def self.images
|
8
|
-
@images ||= Images.new
|
9
|
-
end
|
10
|
-
|
11
|
-
##
|
12
|
-
# EC2 AMI Resources
|
13
|
-
##
|
14
|
-
class Images < Model::Base
|
15
|
-
LIMIT = 24
|
16
|
-
PROPERTIES = %w(image_location state owner_id public architecture image_type
|
17
|
-
name description root_device_type virtualization_type
|
18
|
-
hypervisor)
|
19
|
-
|
20
|
-
def fetch
|
21
|
-
@resources = {}.tap do |i|
|
22
|
-
Util.ec2.describe_images(:filters => [
|
23
|
-
{
|
24
|
-
:name => 'state',
|
25
|
-
:values => %w(available)
|
26
|
-
}
|
27
|
-
], :owners => %w(self)).each do |page|
|
28
|
-
page.images.each do |image|
|
29
|
-
properties = Util.from_tags(image.tags)
|
30
|
-
properties['creation_date'] = DateTime.iso8601(image.creation_date)
|
31
|
-
PROPERTIES.each { |pp| properties[pp] = image[pp.to_sym] }
|
32
|
-
|
33
|
-
i[image.image_id] = {
|
34
|
-
:id => image.image_id,
|
35
|
-
:properties => properties,
|
36
|
-
:snapshots => image.block_device_mappings.map { |b| b.ebs.snapshot_id rescue nil }.reject(&:nil?),
|
37
|
-
:parent => properties.fetch('parent_ami', '(undefined)')
|
38
|
-
}
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def snapshots
|
45
|
-
resources.values.map { |i| i[:snapshots] }.flatten
|
46
|
-
end
|
47
|
-
|
48
|
-
def latest(options = {})
|
49
|
-
{}.tap do |latest|
|
50
|
-
## Group images
|
51
|
-
group_by = options.fetch('group-by', [])
|
52
|
-
groups = {}.tap do |g|
|
53
|
-
break { 'all' => resources.values } if group_by.empty?
|
54
|
-
|
55
|
-
resources.each do |_, image|
|
56
|
-
(g[group_by.map do |gg|
|
57
|
-
image[:properties].fetch(gg.to_s, '(unknown)')
|
58
|
-
end.join(':')] ||= []) << image
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
## Sort each grouping
|
63
|
-
sort_by = options.fetch('sort-by', 'creation_date')
|
64
|
-
groups.each do |_, group|
|
65
|
-
group.sort! { |a, b| b[:properties][sort_by] <=> a[:properties][sort_by] }
|
66
|
-
end
|
67
|
-
|
68
|
-
## Slice to `keep` length
|
69
|
-
keep = options.fetch('keep', 5)
|
70
|
-
groups.each do |_, group|
|
71
|
-
group.slice!(keep..-1)
|
72
|
-
end
|
73
|
-
|
74
|
-
## Reduce
|
75
|
-
groups.values.flatten.each { |i| latest[i[:id]] = i }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def in_use(options = {})
|
80
|
-
{}.tap do |used|
|
81
|
-
used.merge!(select(Model.instances.images))
|
82
|
-
used.merge!(select(Model.launch_configs.images))
|
83
|
-
used.merge!(latest(options))
|
84
|
-
used.merge!(select(used.values.map { |i| i[:parent] }))
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'aws-sdk'
|
2
|
-
require_relative '../util'
|
3
|
-
|
4
|
-
module Builderator
|
5
|
-
module Model
|
6
|
-
|
7
|
-
def self.instances
|
8
|
-
@instances ||= Instances.new
|
9
|
-
end
|
10
|
-
##
|
11
|
-
# EC2 Instance resources
|
12
|
-
##
|
13
|
-
class Instances < Model::Base
|
14
|
-
PROPERTIES = %w(private_dns_name public_dns_name instance_type
|
15
|
-
subnet_id vpc_id private_ip_address public_ip_address
|
16
|
-
architecture root_device_type virtualization_type
|
17
|
-
hypervisor)
|
18
|
-
|
19
|
-
def fetch
|
20
|
-
@resources = {}.tap do |i|
|
21
|
-
Util.ec2.describe_instances(:filters => [
|
22
|
-
{
|
23
|
-
:name => 'instance-state-name',
|
24
|
-
:values => %w(pending running shutting-down stopping stopped)
|
25
|
-
}
|
26
|
-
]).each do |page|
|
27
|
-
page.reservations.each do |r|
|
28
|
-
r.instances.each do |instance|
|
29
|
-
properties = Util.from_tags(instance.tags)
|
30
|
-
properties['availability_zone'] = instance.placement.availability_zone
|
31
|
-
properties['creation_date'] = instance.launch_time.to_datetime
|
32
|
-
PROPERTIES.each { |pp| properties[pp] = instance[pp.to_sym] }
|
33
|
-
|
34
|
-
i[instance.instance_id] = {
|
35
|
-
:id => instance.instance_id,
|
36
|
-
:image => instance.image_id,
|
37
|
-
:volumes => instance.block_device_mappings.map { |b| b.ebs.volume_id },
|
38
|
-
:properties => properties
|
39
|
-
}
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def images
|
47
|
-
resources.values.map { |i| i[:image] }
|
48
|
-
end
|
49
|
-
|
50
|
-
def volumes
|
51
|
-
resources.values.map { |i| i[:volumes] }.flatten
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'aws-sdk'
|
2
|
-
require_relative '../util'
|
3
|
-
|
4
|
-
module Builderator
|
5
|
-
module Model
|
6
|
-
|
7
|
-
def self.launch_configs
|
8
|
-
@launch_configs ||= LaunchConfigs.new
|
9
|
-
end
|
10
|
-
|
11
|
-
##
|
12
|
-
# ASG LaunchConfiguration Resources
|
13
|
-
##
|
14
|
-
class LaunchConfigs < Model::Base
|
15
|
-
LIMIT = 24
|
16
|
-
PROPERTIES = %w(launch_configuration_arn key_name security_groups
|
17
|
-
user_data instance_type spot_price iam_instance_profile
|
18
|
-
ebs_optimized associate_public_ip_address placement_tenancy)
|
19
|
-
|
20
|
-
def fetch
|
21
|
-
@resources = {}.tap do |i|
|
22
|
-
Util.asg.describe_launch_configurations.each do |page|
|
23
|
-
page.launch_configurations.each do |l|
|
24
|
-
properties = { 'creation_date' => l.created_time.to_datetime }
|
25
|
-
PROPERTIES.each { |pp| properties[pp] = l[pp.to_sym] }
|
26
|
-
|
27
|
-
i[l.launch_configuration_name] = {
|
28
|
-
:id => l.launch_configuration_name,
|
29
|
-
:properties => properties,
|
30
|
-
:image => l.image_id
|
31
|
-
}
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def images
|
38
|
-
resources.values.map { |l| l[:image] }
|
39
|
-
end
|
40
|
-
|
41
|
-
def in_use(_)
|
42
|
-
select(Model.scaling_groups.launch_configs)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|