image_builder 0.0.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 +7 -0
- data/.gitignore +22 -0
- data/.rubocop.yml +16 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +29 -0
- data/bin/image_builder +234 -0
- data/image_builder.gemspec +30 -0
- data/lib/image_builder.rb +38 -0
- data/lib/image_builder/backends/backend_base.rb +10 -0
- data/lib/image_builder/backends/packer.rb +109 -0
- data/lib/image_builder/builders/aws_base.rb +101 -0
- data/lib/image_builder/builders/aws_chroot.rb +33 -0
- data/lib/image_builder/builders/aws_ebs.rb +15 -0
- data/lib/image_builder/builders/aws_instance.rb +45 -0
- data/lib/image_builder/builders/builder_base.rb +12 -0
- data/lib/image_builder/builders/null.rb +39 -0
- data/lib/image_builder/post_processors/compress.rb +24 -0
- data/lib/image_builder/post_processors/post_processors_base.rb +10 -0
- data/lib/image_builder/post_processors/vagrant.rb +41 -0
- data/lib/image_builder/provisioners/chef_base.rb +96 -0
- data/lib/image_builder/provisioners/chef_client.rb +115 -0
- data/lib/image_builder/provisioners/chef_solo.rb +33 -0
- data/lib/image_builder/provisioners/file.rb +26 -0
- data/lib/image_builder/provisioners/provisioner_base.rb +10 -0
- data/lib/image_builder/provisioners/shell.rb +47 -0
- data/lib/image_builder/version.rb +4 -0
- data/spec/aws_chroot_builder_spec.rb +30 -0
- data/spec/aws_ebs_builder_spec.rb +30 -0
- data/spec/aws_instance_builder_spec.rb +30 -0
- data/spec/chef_client_provisioner_spec.rb +32 -0
- data/spec/chef_solo_provisioner_spec.rb +28 -0
- data/spec/compress_postprocessor_spec.rb +15 -0
- data/spec/fixtures/test-knife.rb +40 -0
- data/spec/null_builder_spec.rb +21 -0
- data/spec/packer_backend_spec.rb +145 -0
- data/spec/vagrant_postprocessor_spec.rb +20 -0
- metadata +236 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
require_relative './backend_base.rb'
|
2
|
+
require 'json'
|
3
|
+
require 'mixlib/shellout'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
# rubocop:disable Style/ClassVars
|
7
|
+
|
8
|
+
module ImageBuilder
|
9
|
+
module Backends
|
10
|
+
# Generic class doc comment
|
11
|
+
class Packer < ImageBuilder::Backends::Base
|
12
|
+
attr_accessor :description
|
13
|
+
attr_accessor :min_packer_version
|
14
|
+
attr_accessor :builders
|
15
|
+
attr_accessor :post_processors
|
16
|
+
attr_accessor :provisioners
|
17
|
+
attr_accessor :variables
|
18
|
+
|
19
|
+
@@default_path = ['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin']
|
20
|
+
@@default_path << ::File.join(ENV['GEM_HOME'], 'bin') if ENV.key? 'GEM_HOME'
|
21
|
+
|
22
|
+
@@packer_exe = 'packer'
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@builders = []
|
26
|
+
@post_processors = []
|
27
|
+
@provisioners = []
|
28
|
+
@variables = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.packer_path(path)
|
32
|
+
@@packer_exe = ::File.expand_path(path)
|
33
|
+
@@default_path.unshift ::File.dirname(::File.expand_path(@@packer_exe))
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.packer_path=(path)
|
37
|
+
packer_path(path)
|
38
|
+
end
|
39
|
+
|
40
|
+
# rubocop:disable Metrics/LineLength
|
41
|
+
def add_builder(builder_obj)
|
42
|
+
fail ArgumentError, 'Invalid builder object, does not respond to packer_hash()' unless builder_obj.respond_to?(:packer_hash)
|
43
|
+
@builders << builder_obj.packer_hash
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_post_processor(post_obj)
|
47
|
+
fail ArgumentError, 'Invalid post-processor object, does not respond to packer_hash()' unless post_obj.respond_to?(:packer_hash)
|
48
|
+
@post_processors << post_obj.packer_hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_provisioner(provisioner_obj)
|
52
|
+
fail ArgumentError, 'Invalid provisioner object, does not respond to packer_hash()' unless provisioner_obj.respond_to?(:packer_hash)
|
53
|
+
@provisioners << provisioner_obj.packer_hash
|
54
|
+
end
|
55
|
+
# rubocop:enable Metrics/LineLength
|
56
|
+
|
57
|
+
def add_variable(name, value = '')
|
58
|
+
@variables[name] = value
|
59
|
+
end
|
60
|
+
|
61
|
+
def build(args = [])
|
62
|
+
validate
|
63
|
+
|
64
|
+
cmd = [@@packer_exe, 'build'].concat(args)
|
65
|
+
cmd << '-'
|
66
|
+
|
67
|
+
# Some provisioners may take a long time to run without giving output (applying OS updates via Chef
|
68
|
+
# to CentOS6 comes to mind), so extend the timeout to an hour.
|
69
|
+
shellout = Mixlib::ShellOut.new(cmd, env: { 'PATH' => @@default_path.join(':') }, input: to_json, timeout: 3600)
|
70
|
+
shellout.live_stdout = STDOUT
|
71
|
+
shellout.live_stderr = STDERR
|
72
|
+
shellout.run_command
|
73
|
+
shellout.error!
|
74
|
+
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
78
|
+
def validate(args = [])
|
79
|
+
cmd = [@@packer_exe, 'validate'].concat(args)
|
80
|
+
cmd << '-'
|
81
|
+
|
82
|
+
shellout = Mixlib::ShellOut.new(cmd, env: { 'PATH' => @@default_path.join(':') }, input: to_json)
|
83
|
+
shellout.inspect
|
84
|
+
shellout.run_command
|
85
|
+
shellout.error!
|
86
|
+
|
87
|
+
shellout.stdout
|
88
|
+
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_json
|
93
|
+
config = {}
|
94
|
+
|
95
|
+
attr_to_hash(config, :description)
|
96
|
+
attr_to_hash(config, :min_packer_version)
|
97
|
+
attr_to_hash(config, :variables)
|
98
|
+
attr_to_hash(config, :builders, true)
|
99
|
+
attr_to_hash(config, :provisioners)
|
100
|
+
|
101
|
+
# Special handling for post-processors, since the packer config name uses '-', and ruby doesn't
|
102
|
+
# like those (you know....subtraction operator, and all that)
|
103
|
+
config['post-processors'] = @post_processors unless @post_processors.nil? || @post_processors.empty?
|
104
|
+
|
105
|
+
config.to_json
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative './builder_base.rb'
|
2
|
+
|
3
|
+
module ImageBuilder
|
4
|
+
module Builders
|
5
|
+
module AWS
|
6
|
+
# Generic class doc comment
|
7
|
+
class Base < ImageBuilder::Builders::Base
|
8
|
+
attr_accessor :access_key
|
9
|
+
attr_accessor :ami_name
|
10
|
+
attr_accessor :instance_type
|
11
|
+
attr_accessor :region
|
12
|
+
attr_accessor :secret_key
|
13
|
+
attr_accessor :source_ami
|
14
|
+
attr_accessor :ssh_username
|
15
|
+
# - opt -
|
16
|
+
attr_accessor :ami_block_device_mappings
|
17
|
+
attr_accessor :ami_description
|
18
|
+
attr_accessor :ami_groups
|
19
|
+
attr_accessor :ami_product_codes
|
20
|
+
attr_accessor :ami_regions
|
21
|
+
attr_accessor :ami_users
|
22
|
+
attr_accessor :ami_virtualization_type
|
23
|
+
attr_accessor :associate_public_ip_address
|
24
|
+
attr_accessor :availability_zone
|
25
|
+
attr_accessor :enhanced_networking
|
26
|
+
attr_accessor :iam_instance_profile
|
27
|
+
attr_accessor :launch_block_device_mappings
|
28
|
+
attr_accessor :run_tags
|
29
|
+
attr_accessor :security_group_id
|
30
|
+
attr_accessor :security_group_ids
|
31
|
+
attr_accessor :spot_price
|
32
|
+
attr_accessor :spot_price_auto_product
|
33
|
+
attr_accessor :ssh_port
|
34
|
+
attr_accessor :ssh_private_key_file
|
35
|
+
attr_accessor :ssh_private_ip
|
36
|
+
attr_accessor :ssh_timeout
|
37
|
+
attr_accessor :subnet_id
|
38
|
+
attr_accessor :tags
|
39
|
+
attr_accessor :temporary_key_pair_name
|
40
|
+
attr_accessor :token
|
41
|
+
attr_accessor :user_data
|
42
|
+
attr_accessor :user_data_file
|
43
|
+
attr_accessor :vpc_id
|
44
|
+
|
45
|
+
attr_reader :type
|
46
|
+
|
47
|
+
def initialize
|
48
|
+
@access_key = ENV['AWS_ACCESS_KEY_ID'] || ENV['AWS_ACCESS_KEY']
|
49
|
+
@secret_key = ENV['AWS_SECRET_ACCESS_KEY'] || ENV['AWS_SECRET_KEY']
|
50
|
+
@region = 'us-east-1'
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.default_block_device_mappings
|
54
|
+
[
|
55
|
+
{ device_name: '/dev/sdf', virtual_name: 'ephemeral0' },
|
56
|
+
{ device_name: '/dev/sdg', virtual_name: 'ephemeral1' },
|
57
|
+
{ device_name: '/dev/sdh', virtual_name: 'ephemeral2' },
|
58
|
+
{ device_name: '/dev/sdi', virtual_name: 'ephemeral3' }
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.default_launch_block_device_mappings
|
63
|
+
[
|
64
|
+
{ device_name: '/dev/sdb', no_device: true },
|
65
|
+
{ device_name: '/dev/sdc', no_device: true },
|
66
|
+
{ device_name: '/dev/sdd', no_device: true }
|
67
|
+
]
|
68
|
+
end
|
69
|
+
|
70
|
+
def packer_hash
|
71
|
+
hash = {}
|
72
|
+
|
73
|
+
req_attrs = [
|
74
|
+
:type, :name, :access_key, :ami_name, :instance_type,
|
75
|
+
:region, :secret_key, :source_ami, :ssh_username
|
76
|
+
]
|
77
|
+
|
78
|
+
opt_attrs = [
|
79
|
+
:ami_description, :ami_groups, :ami_product_codes, :ami_regions, :ami_regions, :ami_users,
|
80
|
+
:ami_virtualization_type, :associate_public_ip_address, :availability_zone, :enhanced_networking,
|
81
|
+
:iam_instance_profile, :run_tags, :security_group_id, :security_group_ids, :spot_price,
|
82
|
+
:spot_price_auto_product, :ssh_port, :ssh_private_key_file, :ssh_private_ip, :ssh_timeout,
|
83
|
+
:subnet_id, :tags, :temporary_key_pair_name, :token, :user_data, :user_data_file, :vpc_id,
|
84
|
+
:launch_block_device_mappings, :ami_block_device_mappings
|
85
|
+
]
|
86
|
+
|
87
|
+
# Required attrs
|
88
|
+
req_attrs.each do |a|
|
89
|
+
attr_to_hash(hash, a, true)
|
90
|
+
end
|
91
|
+
|
92
|
+
opt_attrs.each do |a|
|
93
|
+
attr_to_hash(hash, a)
|
94
|
+
end
|
95
|
+
|
96
|
+
hash
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative './aws_base.rb'
|
2
|
+
|
3
|
+
module ImageBuilder
|
4
|
+
module Builders
|
5
|
+
module AWS
|
6
|
+
# Generic class doc comment
|
7
|
+
class Chroot < ImageBuilder::Builders::AWS::Base
|
8
|
+
attr_accessor :chroot_mounts
|
9
|
+
attr_accessor :command_wrapper
|
10
|
+
attr_accessor :copy_files
|
11
|
+
attr_accessor :device_path
|
12
|
+
attr_accessor :mount_path
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
super
|
16
|
+
@type = 'amazon-chroot'
|
17
|
+
end
|
18
|
+
|
19
|
+
def packer_hash
|
20
|
+
hash = super
|
21
|
+
|
22
|
+
attr_to_hash(hash, :chroot_mounts)
|
23
|
+
attr_to_hash(hash, :command_wrapper)
|
24
|
+
attr_to_hash(hash, :copy_files)
|
25
|
+
attr_to_hash(hash, :device_path)
|
26
|
+
attr_to_hash(hash, :mount_path)
|
27
|
+
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative './aws_base.rb'
|
2
|
+
|
3
|
+
module ImageBuilder
|
4
|
+
module Builders
|
5
|
+
module AWS
|
6
|
+
# Generic class doc comment
|
7
|
+
class Instance < ImageBuilder::Builders::AWS::Base
|
8
|
+
attr_accessor :account_id
|
9
|
+
attr_accessor :s3_bucket
|
10
|
+
attr_accessor :x509_cert_path
|
11
|
+
attr_accessor :x509_key_path
|
12
|
+
# - opt -
|
13
|
+
attr_accessor :bundle_destination
|
14
|
+
attr_accessor :bundle_prefix
|
15
|
+
attr_accessor :bundle_upload_command
|
16
|
+
attr_accessor :bundle_vol_command
|
17
|
+
attr_accessor :x509_upload_path
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
super
|
21
|
+
@type = 'amazon-instance'
|
22
|
+
end
|
23
|
+
|
24
|
+
def packer_hash
|
25
|
+
hash = super
|
26
|
+
|
27
|
+
# Required
|
28
|
+
attr_to_hash(hash, :account_id, true)
|
29
|
+
attr_to_hash(hash, :s3_bucket, true)
|
30
|
+
attr_to_hash(hash, :x509_cert_path, true)
|
31
|
+
attr_to_hash(hash, :x509_key_path, true)
|
32
|
+
|
33
|
+
# Optional
|
34
|
+
attr_to_hash(hash, :bundle_destination)
|
35
|
+
attr_to_hash(hash, :bundle_prefix)
|
36
|
+
attr_to_hash(hash, :bundle_upload_command)
|
37
|
+
attr_to_hash(hash, :bundle_vol_command)
|
38
|
+
attr_to_hash(hash, :x509_upload_path)
|
39
|
+
|
40
|
+
hash
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative './builder_base.rb'
|
2
|
+
require 'etc'
|
3
|
+
|
4
|
+
module ImageBuilder
|
5
|
+
module Builders
|
6
|
+
# Generic class doc comment
|
7
|
+
class Null < ImageBuilder::Builders::Base
|
8
|
+
attr_accessor :host
|
9
|
+
attr_accessor :ssh_password
|
10
|
+
attr_accessor :ssh_username
|
11
|
+
attr_accessor :ssh_private_key_file
|
12
|
+
attr_accessor :port
|
13
|
+
|
14
|
+
attr_reader :type
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@type = 'null'
|
18
|
+
@host = '127.0.0.1'
|
19
|
+
@port = 22
|
20
|
+
@ssh_username = Etc.getlogin
|
21
|
+
@ssh_private_key_file = ::File.join(::Dir.home, '.ssh', 'id_rsa')
|
22
|
+
end
|
23
|
+
|
24
|
+
def packer_hash
|
25
|
+
hash = {}
|
26
|
+
|
27
|
+
attr_to_hash(hash, :type, true)
|
28
|
+
attr_to_hash(hash, :name, true)
|
29
|
+
attr_to_hash(hash, :host, true)
|
30
|
+
attr_to_hash(hash, :ssh_username, true)
|
31
|
+
attr_to_hash(hash, :ssh_password)
|
32
|
+
attr_to_hash(hash, :ssh_private_key_file)
|
33
|
+
attr_to_hash(hash, :port)
|
34
|
+
|
35
|
+
hash
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative './post_processors_base.rb'
|
2
|
+
|
3
|
+
module ImageBuilder
|
4
|
+
module PostProcessors
|
5
|
+
# Generic class doc comment
|
6
|
+
class Compress < ImageBuilder::PostProcessors::Base
|
7
|
+
attr_accessor :output
|
8
|
+
attr_reader :type
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@type = 'compress'
|
12
|
+
end
|
13
|
+
|
14
|
+
def packer_hash
|
15
|
+
hash = {}
|
16
|
+
|
17
|
+
attr_to_hash(hash, :type, true)
|
18
|
+
attr_to_hash(hash, :output, true)
|
19
|
+
|
20
|
+
hash
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative './post_processors_base.rb'
|
2
|
+
|
3
|
+
module ImageBuilder
|
4
|
+
module PostProcessors
|
5
|
+
# Generic class doc comment
|
6
|
+
class Vagrant < ImageBuilder::PostProcessors::Base
|
7
|
+
attr_accessor :compression_level
|
8
|
+
attr_accessor :include
|
9
|
+
attr_accessor :keep_input_artifact
|
10
|
+
attr_accessor :output
|
11
|
+
attr_accessor :vagrantfile_template
|
12
|
+
attr_accessor :override
|
13
|
+
|
14
|
+
attr_reader :type
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@type = 'vagrant'
|
18
|
+
@compression_level = 6
|
19
|
+
@keep_input_artifact = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_override(provider, override_hash)
|
23
|
+
@override[provider] = override_hash
|
24
|
+
end
|
25
|
+
|
26
|
+
def packer_hash
|
27
|
+
hash = {}
|
28
|
+
|
29
|
+
attr_to_hash(hash, :type, true)
|
30
|
+
attr_to_hash(hash, :compression_level)
|
31
|
+
attr_to_hash(hash, :include)
|
32
|
+
attr_to_hash(hash, :keep_input_artifact)
|
33
|
+
attr_to_hash(hash, :output)
|
34
|
+
attr_to_hash(hash, :vagrantfile_template)
|
35
|
+
attr_to_hash(hash, :override)
|
36
|
+
|
37
|
+
hash
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|