builderator 0.3.15 → 1.0.0.pre.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|