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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +440 -0
  4. data/README.md +72 -18
  5. data/Rakefile +1 -2
  6. data/VERSION +1 -1
  7. data/bin/build-clean +102 -0
  8. data/bin/build-data +45 -0
  9. data/builderator.gemspec +7 -4
  10. data/docs/configuration.md +154 -0
  11. data/docs/configuration/cookbook.md +19 -0
  12. data/docs/configuration/profile.md +71 -0
  13. data/docs/versioning.md +65 -0
  14. data/lib/builderator.rb +3 -0
  15. data/lib/builderator/config.rb +93 -0
  16. data/lib/builderator/config/attributes.rb +287 -0
  17. data/lib/builderator/config/defaults.rb +163 -0
  18. data/lib/builderator/config/file.rb +336 -0
  19. data/lib/builderator/config/rash.rb +80 -0
  20. data/lib/builderator/control/cleaner.rb +138 -0
  21. data/lib/builderator/control/cookbook.rb +16 -0
  22. data/lib/builderator/control/data.rb +16 -0
  23. data/lib/builderator/control/data/image.rb +98 -0
  24. data/lib/builderator/control/version.rb +128 -0
  25. data/lib/builderator/control/version/auto.rb +48 -0
  26. data/lib/builderator/control/version/bump.rb +82 -0
  27. data/lib/builderator/control/version/comparable.rb +77 -0
  28. data/lib/builderator/control/version/git.rb +45 -0
  29. data/lib/builderator/control/version/scm.rb +92 -0
  30. data/lib/builderator/interface.rb +67 -0
  31. data/lib/builderator/interface/berkshelf.rb +38 -0
  32. data/lib/builderator/interface/packer.rb +75 -0
  33. data/lib/builderator/interface/vagrant.rb +31 -0
  34. data/lib/builderator/metadata.rb +5 -3
  35. data/lib/builderator/model/cleaner.rb +49 -0
  36. data/lib/builderator/model/cleaner/images.rb +93 -0
  37. data/lib/builderator/model/cleaner/instances.rb +58 -0
  38. data/lib/builderator/model/cleaner/launch_configs.rb +47 -0
  39. data/lib/builderator/model/cleaner/scaling_groups.rb +45 -0
  40. data/lib/builderator/model/cleaner/snapshots.rb +50 -0
  41. data/lib/builderator/model/cleaner/volumes.rb +48 -0
  42. data/lib/builderator/patch/berkshelf.rb +18 -0
  43. data/lib/builderator/patch/thor-actions.rb +47 -0
  44. data/lib/builderator/tasks.rb +127 -17
  45. data/lib/builderator/tasks/berkshelf.rb +63 -0
  46. data/lib/builderator/tasks/packer.rb +17 -56
  47. data/lib/builderator/tasks/vagrant.rb +111 -42
  48. data/lib/builderator/tasks/vendor.rb +94 -0
  49. data/lib/builderator/tasks/version.rb +58 -0
  50. data/lib/builderator/util.rb +37 -11
  51. data/lib/builderator/util/aws_exception.rb +1 -1
  52. data/lib/builderator/util/limit_exception.rb +12 -11
  53. data/lib/builderator/util/task_exception.rb +0 -2
  54. data/mkmf.log +4 -0
  55. data/spec/config_spec.rb +30 -0
  56. data/spec/data/Berksfile +6 -0
  57. data/spec/data/Buildfile +0 -0
  58. data/spec/data/Vagrantfile +0 -0
  59. data/spec/data/history.json +483 -0
  60. data/spec/data/packer.json +0 -0
  61. data/spec/interface_spec.rb +36 -0
  62. data/spec/resource/Buildfile +27 -0
  63. data/spec/spec_helper.rb +90 -0
  64. data/spec/version_spec.rb +282 -0
  65. data/template/Berksfile.erb +10 -0
  66. data/template/Buildfile.erb +28 -0
  67. data/template/Gemfile.erb +16 -0
  68. data/template/README.md.erb +61 -0
  69. data/template/Vagrantfile.erb +75 -0
  70. data/template/gitignore.erb +104 -0
  71. data/{.rubocop.yml → template/rubocop.erb} +0 -0
  72. metadata +203 -56
  73. data/.gitignore +0 -14
  74. data/lib/builderator/control/ami.rb +0 -65
  75. data/lib/builderator/control/clean.rb +0 -130
  76. data/lib/builderator/model.rb +0 -46
  77. data/lib/builderator/model/images.rb +0 -89
  78. data/lib/builderator/model/instances.rb +0 -55
  79. data/lib/builderator/model/launch_configs.rb +0 -46
  80. data/lib/builderator/model/scaling_groups.rb +0 -43
  81. data/lib/builderator/model/snapshots.rb +0 -49
  82. data/lib/builderator/model/volumes.rb +0 -48
  83. data/lib/builderator/tasks/ami.rb +0 -47
  84. data/lib/builderator/tasks/berks.rb +0 -68
  85. data/lib/builderator/tasks/clean.rb +0 -97
  86. data/lib/builderator/util/berkshim.rb +0 -34
  87. data/lib/builderator/util/cookbook.rb +0 -87
  88. data/lib/builderator/util/packer.rb +0 -39
  89. data/lib/builderator/util/shell.rb +0 -44
data/.gitignore DELETED
@@ -1,14 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.bundle
11
- *.so
12
- *.o
13
- *.a
14
- mkmf.log
@@ -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
@@ -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