bitswarmbox 1.0.0.pre16

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 (122) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +70 -0
  3. data/.idea/.rakeTasks +7 -0
  4. data/.idea/compiler.xml +22 -0
  5. data/.idea/composerJson.xml +9 -0
  6. data/.idea/copyright/profiles_settings.xml +3 -0
  7. data/.idea/misc.xml +23 -0
  8. data/.idea/modules.xml +8 -0
  9. data/.ruby-version +1 -0
  10. data/.travis.yml +3 -0
  11. data/Gemfile +3 -0
  12. data/LICENSE +21 -0
  13. data/README.md +67 -0
  14. data/Rakefile +34 -0
  15. data/Vagrantfile +116 -0
  16. data/bin/bitswarmbox +6 -0
  17. data/bitswarmbox.gemspec +48 -0
  18. data/bitswarmbox.iml +51 -0
  19. data/builders/aws/build-all.sh +17 -0
  20. data/builders/aws/debian/build-base-jessie64.sh +11 -0
  21. data/builders/aws/debian/build-base-wheezy64.sh +11 -0
  22. data/builders/aws/debian/build-puppetmaster-jessie64.sh +11 -0
  23. data/builders/aws/ubuntu/build-base-precise64.sh +11 -0
  24. data/builders/aws/ubuntu/build-base-trusty64.sh +11 -0
  25. data/builders/aws/ubuntu/build-base-wily64.sh +11 -0
  26. data/builders/aws/ubuntu/build-base-xenial64.sh +11 -0
  27. data/builders/aws/ubuntu/build-puppetmaster-trusty64.sh +11 -0
  28. data/builders/aws/ubuntu/build-puppetmaster-xenial64.sh +11 -0
  29. data/builders/vagrant/build-all.sh +18 -0
  30. data/builders/vagrant/debian/build-base-jessie64.sh +9 -0
  31. data/builders/vagrant/debian/build-base-wheezy64.sh +9 -0
  32. data/builders/vagrant/debian/build-puppetmaster-jessie64.sh +9 -0
  33. data/builders/vagrant/ubuntu/build-base-precise64.sh +9 -0
  34. data/builders/vagrant/ubuntu/build-base-trusty64.sh +9 -0
  35. data/builders/vagrant/ubuntu/build-base-wily64.sh +9 -0
  36. data/builders/vagrant/ubuntu/build-base-xenial64.sh +9 -0
  37. data/builders/vagrant/ubuntu/build-puppetmaster-trusty64.sh +17 -0
  38. data/builders/vagrant/ubuntu/build-puppetmaster-xenial64.sh +17 -0
  39. data/features/boxes.feature +8 -0
  40. data/features/build.feature +16 -0
  41. data/features/env.feature +18 -0
  42. data/features/support/env.rb +1 -0
  43. data/lib/bitswarmbox/builder.rb +181 -0
  44. data/lib/bitswarmbox/command/build/aws.rb +90 -0
  45. data/lib/bitswarmbox/command/build/vagrant.rb +78 -0
  46. data/lib/bitswarmbox/command/build.rb +42 -0
  47. data/lib/bitswarmbox/command/env.rb +50 -0
  48. data/lib/bitswarmbox/command.rb +15 -0
  49. data/lib/bitswarmbox/config.rb +87 -0
  50. data/lib/bitswarmbox/environment.rb +128 -0
  51. data/lib/bitswarmbox/errors.rb +19 -0
  52. data/lib/bitswarmbox/subprocess.rb +39 -0
  53. data/lib/bitswarmbox/template.rb +50 -0
  54. data/lib/bitswarmbox/version.rb +4 -0
  55. data/lib/bitswarmbox.rb +29 -0
  56. data/lib/boxes.rb +29 -0
  57. data/puppet/Puppetfile +58 -0
  58. data/puppet/environments/aws/manifests/base.pp +3 -0
  59. data/puppet/environments/vagrant/environment.conf +1 -0
  60. data/puppet/environments/vagrant/manifests/base.pp +3 -0
  61. data/puppet/hiera.yaml +15 -0
  62. data/puppet/hieradata/aws.yaml +11 -0
  63. data/puppet/hieradata/common.yaml +9 -0
  64. data/puppet/hieradata/debian.yaml +6 -0
  65. data/puppet/hieradata/puppetmaster.yaml +7 -0
  66. data/puppet/hieradata/ubuntu.yaml +3 -0
  67. data/puppet/hieradata/vagrant.yaml +3 -0
  68. data/puppet/hieradata/vsphere.yaml +3 -0
  69. data/puppet/manifests/r10k_bootstrap.pp +37 -0
  70. data/puppet/modules/packer/manifests/aws/cloudinit.pp +20 -0
  71. data/puppet/modules/packer/manifests/aws/networking/params.pp +46 -0
  72. data/puppet/modules/packer/manifests/aws/networking.pp +23 -0
  73. data/puppet/modules/packer/manifests/aws/sshd.pp +10 -0
  74. data/puppet/modules/packer/manifests/aws/users.pp +26 -0
  75. data/puppet/modules/packer/manifests/aws.pp +7 -0
  76. data/puppet/modules/packer/manifests/clock.pp +10 -0
  77. data/puppet/modules/packer/manifests/updates.pp +27 -0
  78. data/puppet/modules/packer/manifests/vagrant/params.pp +14 -0
  79. data/puppet/modules/packer/manifests/vagrant.pp +63 -0
  80. data/puppet/modules/packer/manifests/vmtools/params.pp +35 -0
  81. data/puppet/modules/packer/manifests/vmtools.pp +52 -0
  82. data/puppet/modules/packer/manifests/vsphere/fw.pp +9 -0
  83. data/puppet/modules/packer/manifests/vsphere/networking.pp +29 -0
  84. data/puppet/modules/packer/manifests/vsphere/params.pp +56 -0
  85. data/puppet/modules/packer/manifests/vsphere/repos.pp +87 -0
  86. data/puppet/modules/packer/manifests/vsphere.pp +45 -0
  87. data/puppet/modules/packer/templates/ec2/ubuntu-cloud-cfg.erb +111 -0
  88. data/puppet/modules/packer/templates/vsphere/debian.rb.erb +45 -0
  89. data/puppet/modules/packer/templates/vsphere/rc.local +5 -0
  90. data/puppet/modules/packer/templates/vsphere/redhat.rb.erb +66 -0
  91. data/puppet/modules/packer/templates/vsphere/ubuntu.rb.erb +50 -0
  92. data/scripts/ansible.sh +17 -0
  93. data/scripts/chef.sh +30 -0
  94. data/scripts/cleanup-aws.sh +6 -0
  95. data/scripts/cleanup-vagrant.sh +26 -0
  96. data/scripts/cleanup.sh +48 -0
  97. data/scripts/docker.sh +23 -0
  98. data/scripts/local-ssh-keygen.sh +16 -0
  99. data/scripts/prepare-done.sh +3 -0
  100. data/scripts/prepare.sh +32 -0
  101. data/scripts/puppet.sh +31 -0
  102. data/scripts/puppetserver-post.sh +8 -0
  103. data/scripts/puppetserver.sh +44 -0
  104. data/scripts/ruby.sh +42 -0
  105. data/scripts/vagrant.sh +42 -0
  106. data/scripts/vmtools.sh +37 -0
  107. data/spec/boxes/builder_spec.rb +52 -0
  108. data/spec/boxes/config_spec.rb +142 -0
  109. data/spec/boxes/environment_spec.rb +73 -0
  110. data/spec/boxes/subprocess_spec.rb +35 -0
  111. data/spec/boxes/template_spec.rb +53 -0
  112. data/spec/spec_helper.rb +5 -0
  113. data/spec/support/subprocess_command.rb +7 -0
  114. data/templates/debian/jessie64.erb +206 -0
  115. data/templates/debian/preseed.cfg +70 -0
  116. data/templates/debian/wheezy64.erb +206 -0
  117. data/templates/ubuntu/precise64.erb +205 -0
  118. data/templates/ubuntu/preseed.cfg +61 -0
  119. data/templates/ubuntu/trusty64.erb +205 -0
  120. data/templates/ubuntu/wily64.erb +209 -0
  121. data/templates/ubuntu/xenial64.erb +209 -0
  122. metadata +349 -0
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build aws \
6
+ --name="bitswarm-puppetmaster-ubuntu-xenial64-hvm-ebs-ssd" \
7
+ --template="ubuntu/trusty64" \
8
+ --description="Bitswarm Puppetmaster bootstrap running Ubuntu Xenial 16.04 LTS amd64 hvm:ebs-ssd" \
9
+ --aws_region="us-west-1" \
10
+ --aws_source_ami="ami-08490c68" \
11
+ --puppetserver --bootstrap
@@ -0,0 +1,18 @@
1
+ #!/bin/bash
2
+
3
+ echo "Building all Vagrant boxes..."
4
+
5
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6
+
7
+ cd "${DIR}/../../"
8
+ echo " - Using context root $(pwd)"
9
+
10
+ set -ex
11
+
12
+
13
+ $DIR/debian/build-base-jessie64.sh
14
+ $DIR/debian/build-base-wheezy64.sh
15
+ $DIR/ubuntu/build-base-precise64.sh
16
+ $DIR/ubuntu/build-base-trusty64.sh
17
+ $DIR/ubuntu/build-base-wily64.sh
18
+ $DIR/ubuntu/build-base-xenial64.sh
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name="base-debian-jessie" \
7
+ --template="debian/jessie64" \
8
+ --provider="virtualbox" \
9
+ --puppet --bootstrap
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name="base-debian-wheezy" \
7
+ --template="debian/wheezy64" \
8
+ --provider="virtualbox" \
9
+ --puppet --bootstrap
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name="puppetserver-debian-jessie" \
7
+ --template="debian/jessie64" \
8
+ --provider="virtualbox" \
9
+ --puppetserver --bootstrap
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name=ubuntu-precise64-base \
7
+ --template=ubuntu/precise64 \
8
+ --provider=virtualbox \
9
+ --puppet --bootstrap
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name=ubuntu-trusty64-base \
7
+ --template=ubuntu/trusty64 \
8
+ --provider=virtualbox \
9
+ --puppet --bootstrap
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name=ubuntu-wily64-base \
7
+ --template=ubuntu/wily64 \
8
+ --provider=virtualbox \
9
+ --puppet --bootstrap
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name=ubuntu-xenial64-base \
7
+ --template=ubuntu/xenial64 \
8
+ --provider=virtualbox \
9
+ --puppet --bootstrap
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name=ubuntu-trusty64-puppetserver \
7
+ --template=ubuntu/trusty64 \
8
+ --provider=virtualbox \
9
+ --puppetserver --bootstrap
10
+
11
+ #bitswarmbox build aws \
12
+ # --name=ubuntu-trusty64-puppetserver \
13
+ # --description='Puppetmaster Base' \
14
+ # --aws_region=us-west-1 \
15
+ # --aws_source_ami=ami-48286c28 \
16
+ # --template='ubuntu/trusty64' \
17
+ # --puppetserver --bootstrap
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+
3
+ which bitswarmbox || gem install bitswarmbox
4
+
5
+ bitswarmbox build vagrant \
6
+ --name=ubuntu-xenial64-puppetserver \
7
+ --template=ubuntu/xenial64 \
8
+ --provider=virtualbox \
9
+ --puppetserver --bootstrap
10
+
11
+ #bitswarmbox build aws \
12
+ # --name=ubuntu-xenial64-puppetserver \
13
+ # --description='Puppetmaster Base' \
14
+ # --aws_region=us-west-1 \
15
+ # --aws_source_ami=ami-08490c68 \
16
+ # --template='ubuntu/trusty64' \
17
+ # --puppetserver --bootstrap
@@ -0,0 +1,8 @@
1
+ Feature: We can return the boxes help
2
+
3
+ Scenario: A successful response
4
+ When I run `boxes --help`
5
+ Then the output should contain "$ boxes"
6
+ Then the output should contain "Usage:"
7
+ Then the output should contain "Options:"
8
+ And the exit status should be 0
@@ -0,0 +1,16 @@
1
+ Feature: We can build boxes
2
+
3
+ Scenario: It will error without a name
4
+ When I run `boxes build --template=ubuntu/trusty64 --provider=vmware`
5
+ Then the output should contain "[!] A name is required!"
6
+ And the exit status should be 1
7
+
8
+ Scenario: It will error without a provider
9
+ When I run `boxes build --name=trusty64-standard --template=ubuntu/trusty64`
10
+ Then the output should contain "[!] A provider is required!"
11
+ And the exit status should be 1
12
+
13
+ Scenario: It will error without a template
14
+ When I run `boxes build --name=trusty64-standard --provider=vmware`
15
+ Then the output should contain "[!] A template is required!"
16
+ And the exit status should be 1
@@ -0,0 +1,18 @@
1
+ Feature: We can manage the boxes environment
2
+
3
+ Scenario: It shows the environment by default
4
+ When I run `boxes env`
5
+ Then the output should contain "Configuration:"
6
+ Then the output should contain "Environment Variables:"
7
+ And the exit status should be 0
8
+
9
+ Scenario: It has a show command
10
+ When I run `boxes env show`
11
+ Then the output should contain "Configuration:"
12
+ Then the output should contain "Environment Variables:"
13
+ And the exit status should be 0
14
+
15
+ Scenario: It can clean the environment
16
+ When I run `boxes env clean`
17
+ Then the directory named "~/.boxes/env" does not exist
18
+ And the exit status should be 0
@@ -0,0 +1 @@
1
+ require 'aruba/cucumber'
@@ -0,0 +1,181 @@
1
+ module BitswarmBox
2
+ # Class which drives the build process.
3
+ class Builder
4
+ include BitswarmBox::Errors
5
+
6
+ attr_accessor :name, :description
7
+ attr_accessor :template, :scripts, :provider, :provisioner, :packer_shell_exec_cmd
8
+ attr_accessor :puppet, :puppetserver, :ansible, :chef, :docker, :bootstrap
9
+ attr_accessor :app_creator, :app_project, :app_version
10
+ attr_accessor :aws_access_key, :aws_secret_key, :aws_region, :aws_source_ami, :aws_user_data
11
+
12
+ # Initialise a new build.
13
+ #
14
+ # @param env [BitswarmBox::Environment] environment to operate in.
15
+ # @param args [Hash]
16
+ # @param template [String] the name of the template.
17
+ # @param scripts [Array] scripts to include in the build.
18
+ def initialize(env, args) # rubocop:disable Metrics/MethodLength
19
+ @environment = env
20
+ @provisioner = args[:provisioner] || fail(MissingArgumentError,
21
+ 'The provisioner must be specified.')
22
+ @packer_shell_exec_cmd = args[:packer_shell_exec_cmd] || 'chmod +x {{ .Path }}; {{ .Vars }} {{ .Path }}'
23
+ @name = args[:name] || fail(MissingArgumentError,
24
+ 'The name must be specified.')
25
+ @description = args[:description]
26
+ @provider = args[:provider] || fail(MissingArgumentError,
27
+ 'The provider must be specified.')
28
+ template = args[:template] || fail(MissingArgumentError,
29
+ 'The template must be specified.')
30
+ scripts = args.fetch(:scripts, [])
31
+
32
+ @template = Template.new(env, template)
33
+ @scripts = scripts.collect do |c|
34
+ env.available_scripts.include?(c) ? c : fail(ScriptNotFoundError)
35
+ end
36
+
37
+ @puppet = args[:puppet]
38
+ @puppetserver = args[:puppetserver]
39
+ @chef = args[:chef]
40
+ @ansible = args[:ansible]
41
+ @docker = args[:docker]
42
+
43
+ @app_creator = args[:app_creator] || ENV['USER']
44
+ @app_project = args[:app_project] || 'default'
45
+ @app_version = args[:app_version] || BitswarmBox::VERSION
46
+
47
+ if @provisioner == 'aws'
48
+ @aws_access_key = args[:aws_access_key]
49
+ @aws_secret_key = args[:aws_secret_key]
50
+ @aws_region = args[:aws_region]
51
+ @aws_source_ami = args[:aws_source_ami]
52
+ @aws_user_data = args[:aws_user_data]
53
+ end
54
+
55
+ @bootstrap = args[:bootstrap]
56
+ end
57
+
58
+ # Run the build.
59
+ def run # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
60
+ original_directory = FileUtils.pwd
61
+ box_name = ''
62
+ ami = ''
63
+
64
+ # render the template
65
+ if provisioner == 'aws'
66
+ rendered_template = template.render(name: name,
67
+ description: description,
68
+ provider: provider,
69
+ provisioner: provisioner,
70
+ shell_exec_cmd: packer_shell_exec_cmd,
71
+ scripts: scripts,
72
+ puppet: puppet,
73
+ puppetserver: puppetserver,
74
+ chef: chef,
75
+ ansible: ansible,
76
+ docker: docker,
77
+ bootstrap: bootstrap,
78
+ app_creator: app_creator,
79
+ app_project: app_project,
80
+ app_version: app_version,
81
+ aws_access_key: aws_access_key,
82
+ aws_secret_key: aws_secret_key,
83
+ aws_region: aws_region,
84
+ aws_source_ami: aws_source_ami,
85
+ aws_user_data: aws_user_data,
86
+ )
87
+ else
88
+ rendered_template = template.render(name: name,
89
+ provider: provider,
90
+ provisioner: provisioner,
91
+ shell_exec_cmd: packer_shell_exec_cmd,
92
+ scripts: scripts,
93
+ puppet: puppet,
94
+ puppetserver: puppetserver,
95
+ chef: chef,
96
+ ansible: ansible,
97
+ docker: docker,
98
+ bootstrap: bootstrap,
99
+ app_creator: app_creator,
100
+ app_project: app_project,
101
+ app_version: app_version,
102
+ )
103
+ end
104
+
105
+ # write the template to a file
106
+ File.open(BitswarmBox.config.working_dir + "#{build_name}.json", 'w') do |f|
107
+ f.puts rendered_template
108
+ end
109
+
110
+ # set the environment vars
111
+ BitswarmBox.config.environment_vars.each do |e|
112
+ e.each do |k, v|
113
+ ENV[k] = v.to_s
114
+ end
115
+ end
116
+
117
+ # execute the packer validate command
118
+ FileUtils.chdir(BitswarmBox.config.working_dir)
119
+ cmd = "packer validate #{build_name}.json"
120
+ status = Subprocess.run(cmd) do |stdout, stderr, _thread|
121
+ puts stdout unless stdout.nil?
122
+ puts stderr unless stderr.nil?
123
+ fail() unless stderr.nil?
124
+ end
125
+
126
+ # execute the packer inspect command
127
+ # FileUtils.chdir(BitswarmBox.config.working_dir)
128
+ # cmd = "packer inspect #{build_name}.json"
129
+ # status = Subprocess.run(cmd) do |stdout, stderr, _thread|
130
+ # puts stdout unless stdout.nil?
131
+ # puts stderr unless stderr.nil?
132
+ # fail() unless stderr.nil?
133
+ # end
134
+
135
+ # execute the packer build command
136
+ FileUtils.chdir(BitswarmBox.config.working_dir)
137
+ cmd = "packer build --force #{build_name}.json"
138
+ status = Subprocess.run(cmd) do |stdout, stderr, _thread|
139
+ puts stdout unless stdout.nil?
140
+ puts stderr unless stderr.nil?
141
+
142
+ # catch the name of the artifact
143
+ if @provisioner == 'vagrant' && stdout =~ /\.box/
144
+ box_name = stdout.gsub(/[a-zA-Z0-9:\.\-_]*?\.box/).first
145
+ end
146
+
147
+ if @provisioner == 'aws' && stdout =~ /ami\-[a-f0-9]+/
148
+ ami = stdout.gsub(/ami\-[a-f0-9]+/).first
149
+ end
150
+ end
151
+
152
+ if status.exitstatus == 0
153
+ if @provisioner == 'vagrant'
154
+ FileUtils.mv(BitswarmBox.config.working_dir + box_name,
155
+ "#{original_directory}/#{box_name}")
156
+ elsif @provisioner == 'aws'
157
+ puts "All done! AWS EC2 AMI #{ami} created."
158
+ end
159
+
160
+ else
161
+ fail BuildRunError,
162
+ 'The build didn\'t complete successfully. Check the logs.'
163
+ end
164
+ end
165
+
166
+ def finalize
167
+ @environment.sync_ssh_keys(true)
168
+ end
169
+
170
+ # Clean any temporary files used during building.
171
+ def clean
172
+ FileUtils.rm("#{build_name}.json")
173
+ end
174
+
175
+ private
176
+
177
+ def build_name
178
+ @build_name ||= "#{@name}-#{Time.now.strftime('%Y%m%d%H%M%S')}"
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,90 @@
1
+ module BitswarmBox
2
+ class Command
3
+ class Build < Command
4
+ class Aws < Build
5
+ self.summary = 'Build a Bitswarm AWS AMI'
6
+ self.description = 'Builds an EC2 AMI for running the Bitswarm ecosystem using templates and scripts.'
7
+
8
+ def self.options
9
+ [
10
+ ['--name=<box_name>', 'The AMI name (required)'],
11
+ ['--description', 'The AMI description'],
12
+ ['--provider=[amazon-ebs]', 'Packer provider model to utilize (defaults to amazon-ebs)'],
13
+ ['--template=<path/to/template>', 'Relative path within templates/ to build the box with (required)'],
14
+ ['--app_creator', 'app_creator metadata fact, for use with Puppet'],
15
+ ['--app_project', 'app_project metadata fact, for use with Puppet. Ignored if --puppetserver flag is used'],
16
+ ['--app_version', 'app_version metadata fact, for use with Puppet'],
17
+ ['--aws_access_key', 'AWS API Access Key (defaults to ENV[AWS_ACCESS_KEY])'],
18
+ ['--aws_secret_key', 'AWS API Secret Key (defaults to ENV[AWS_SECRET_KEY])'],
19
+ ['--aws_region', 'AWS Region (defaults to us-west-1)'],
20
+ ['--aws_source_ami', 'AMI upon which to work (must be available in aws_region)'],
21
+ ['--aws_user_data', 'User data to send to AWS builder'],
22
+ ['--puppet', 'Install basic Puppet client'],
23
+ ['--puppetserver', 'Install Puppet Server and provision'],
24
+ ['--docker', 'Install latest Docker'],
25
+ ['--chef', 'Install basic Chef client'],
26
+ ['--ansible', 'Install basic Ansible client'],
27
+ ['--scripts', 'Extra scripts to apply to the box (comma delimited paths)'],
28
+ ['--bootstrap', 'Execute bootstrap provisioning during build (Puppet apply etc)']
29
+ ].concat(super)
30
+ end
31
+
32
+ def initialize(argv)
33
+ @build = {}
34
+ @build[:provisioner] = 'aws'
35
+ @build[:packer_shell_exec_cmd] = "{{ .Vars }} sudo -E sh '{{ .Path }}'"
36
+
37
+ @build[:name] = argv.option('name')
38
+ @build[:description] = argv.option('description')
39
+ @build[:provider] = argv.option('provider') || 'amazon-ebs'
40
+ @build[:template] = argv.option('template')
41
+
42
+ @build[:app_creator] = argv.option('app_creator')
43
+ @build[:app_project] = argv.option('app_project')
44
+ @build[:app_version] = argv.option('app_version')
45
+
46
+ @build[:aws_access_key] = argv.option('aws_access_key') || ENV['AWS_ACCESS_KEY']
47
+ @build[:aws_secret_key] = argv.option('aws_secret_key') || ENV['AWS_SECRET_KEY']
48
+ @build[:aws_region] = argv.option('aws_region') || ENV['AWS_DEFAULT_REGION']
49
+ @build[:aws_source_ami] = argv.option('aws_source_ami')
50
+ @build[:aws_user_data] = argv.option('aws_user_data')
51
+
52
+ @build[:puppet] = argv.flag?('puppet')
53
+ @build[:puppetserver] = argv.flag?('puppetserver')
54
+ @build[:docker] = argv.flag?('docker')
55
+ @build[:chef] = argv.flag?('chef')
56
+ @build[:ansible] = argv.flag?('ansible')
57
+
58
+ scripts = argv.option('scripts') || ''
59
+ @build[:scripts] = scripts.split(',')
60
+
61
+ @build[:bootstrap] = argv.flag?('bootstrap')
62
+
63
+ super
64
+ end
65
+
66
+ def validate!
67
+ super
68
+
69
+ %w(name provider template).each do |key|
70
+ help! "A #{key} is required!" if @build[key.to_sym].nil?
71
+ end
72
+
73
+ if @build[:puppetserver] && !@build[:app_project]
74
+ @build[:app_project] = 'puppetmaster'
75
+ end
76
+ end
77
+
78
+ def run
79
+ env = BitswarmBox::Environment.new
80
+ builder = BitswarmBox::Builder.new(env, @build)
81
+ builder.run
82
+ builder.clean
83
+ rescue BitswarmBox::Errors::BuildRunError => e
84
+ puts "[!] #{e}".red
85
+ exit 1
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,78 @@
1
+ module BitswarmBox
2
+ class Command
3
+ class Build < Command
4
+ class Vagrant < Build
5
+ self.summary = 'Build a Bitswarm Vagrant box'
6
+ self.description = 'Builds a vagrant box for testing Bitswarm ecosystem using templates and scripts.'
7
+
8
+ def self.options
9
+ [
10
+ ['--name=<box_name>', 'The name for the build and resulting box (required)'],
11
+ ['--provider=[virtualbox|vmware]', 'The host VM provider to build the box for (required)'],
12
+ ['--template=<path/to/template>', 'Relative path within templates/ to build the box with (required)'],
13
+ ['--app_creator', 'app_creator metadata fact, for use with Puppet'],
14
+ ['--app_project', 'app_project metadata fact, for use with Puppet'],
15
+ ['--app_version', 'app_version metadata fact, for use with Puppet'],
16
+ ['--puppet', 'Install basic Puppet client'],
17
+ ['--puppetserver', 'Install Puppet Server and provision'],
18
+ ['--docker', 'Install latest Docker'],
19
+ ['--chef', 'Install basic Chef client'],
20
+ ['--ansible', 'Install basic Ansible client'],
21
+ ['--scripts', 'Extra scripts to apply to the box (comma delimited paths)'],
22
+ ['--bootstrap', 'Execute bootstrap provisioning during build (Puppet apply etc)']
23
+ ].concat(super)
24
+ end
25
+
26
+ def initialize(argv)
27
+ @build = {}
28
+ @build[:provisioner] = 'vagrant'
29
+ @build[:packer_shell_exec_cmd] = "echo 'vagrant' | {{ .Vars }} sudo -E -S bash '{{ .Path }}'"
30
+
31
+ @build[:name] = argv.option('name')
32
+ @build[:provider] = argv.option('provider')
33
+ @build[:template] = argv.option('template')
34
+
35
+ @build[:app_creator] = argv.option('app_creator')
36
+ @build[:app_project] = argv.option('app_project')
37
+ @build[:app_version] = argv.option('app_version')
38
+
39
+ @build[:puppet] = argv.flag?('puppet')
40
+ @build[:puppetserver] = argv.flag?('puppetserver')
41
+ @build[:docker] = argv.flag?('docker')
42
+ @build[:chef] = argv.flag?('chef')
43
+ @build[:ansible] = argv.flag?('ansible')
44
+
45
+ scripts = argv.option('scripts') || ''
46
+ @build[:scripts] = scripts.split(',')
47
+
48
+ @build[:bootstrap] = argv.flag?('bootstrap')
49
+
50
+ super
51
+ end
52
+
53
+ def validate!
54
+ super
55
+
56
+ %w(name provider template).each do |key|
57
+ help! "A #{key} is required!" if @build[key.to_sym].nil?
58
+ end
59
+
60
+ if @build[:puppetserver] && !@build[:app_project]
61
+ @build[:app_project] = 'puppetmaster'
62
+ end
63
+ end
64
+
65
+ def run
66
+ env = BitswarmBox::Environment.new
67
+ builder = BitswarmBox::Builder.new(env, @build)
68
+ builder.run
69
+ builder.finalize
70
+ builder.clean
71
+ rescue BitswarmBox::Errors::BuildRunError => e
72
+ puts "[!] #{e}".red
73
+ exit 1
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,42 @@
1
+ module BitswarmBox
2
+ class Command
3
+ # Command handling for the box building functionality.
4
+ class Build < Command
5
+ self.abstract_command = true
6
+
7
+ self.summary = 'Build Bitswarm\'s boxes'
8
+ self.description = 'Builds boxes for Bitswarm ecosystem using templates and scripts.'
9
+
10
+ # def self.options
11
+ # [
12
+ # ['--name', 'The name for the build'],
13
+ # ['--template', 'Template to build the box with'],
14
+ # ].concat(super)
15
+ # end
16
+
17
+ # def initialize(argv)
18
+ # @build = {}
19
+ # @build[:name] = argv.option('name')
20
+ # @build[:template] = argv.option('template')
21
+ # scripts = argv.option('scripts') || ''
22
+ # @build[:scripts] = scripts.split(',')
23
+ #
24
+ # super
25
+ # end
26
+
27
+ def validate!
28
+ super
29
+ end
30
+
31
+ def run
32
+ env = BitswarmBox::Environment.new
33
+ builder = BitswarmBox::Builder.new(env, @build)
34
+ builder.run
35
+ builder.clean
36
+ rescue BitswarmBox::Errors::BuildRunError => e
37
+ puts "[!] #{e}".red
38
+ exit 1
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,50 @@
1
+ module BitswarmBox
2
+ class Command
3
+ # Command handling for the environment used for building bitswarmbox.
4
+ class Env < Command
5
+ self.abstract_command = true
6
+ self.default_subcommand = 'show'
7
+
8
+ self.summary = 'Manage the build environment'
9
+ self.description = 'Expore the environment that bitswarmbox uses for building '\
10
+ 'inside of.'
11
+
12
+ # Prints out the environment and configuration.
13
+ class Show < Env
14
+ self.summary = 'Show the environment and configuration'
15
+ self.description = <<-DESC
16
+ This lists the environment variables and other parts of the
17
+ configuration that bitswarmbox uses to handle builds.
18
+ DESC
19
+
20
+ def run # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
21
+ puts 'Configuration:'.underline
22
+ puts ''
23
+ puts "HOME_DIR=\"#{BitswarmBox.config.home_dir}\""
24
+ puts "WORKING_DIR=\"#{BitswarmBox.config.working_dir}\""
25
+ puts "TEMPLATE_PATHS=\"#{BitswarmBox.config.template_paths.join(', ')}\""
26
+ puts "SCRIPT_PATHS=\"#{BitswarmBox.config.script_paths.join(', ')}\""
27
+
28
+ puts ''
29
+ puts 'Environment Variables:'.underline
30
+ puts ''
31
+ BitswarmBox.config.environment_vars.each do |e|
32
+ puts "#{e.keys.join}=\"#{e.values.join}\""
33
+ end
34
+ end
35
+ end
36
+
37
+ # Tidies up the working environment
38
+ class Clean < Env
39
+ self.summary = 'Clean up the environment.'
40
+ self.description = 'Removes any files from the working directory.'
41
+
42
+ def run
43
+ working_dir = BitswarmBox.config.working_dir
44
+
45
+ FileUtils.rm_rf(working_dir) if working_dir.exist?
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,15 @@
1
+ module BitswarmBox
2
+ # Class which encapsulates the command line handling.
3
+ class Command < CLAide::Command
4
+ require 'bitswarmbox/command/build'
5
+ require 'bitswarmbox/command/build/vagrant'
6
+ require 'bitswarmbox/command/build/aws'
7
+
8
+ require 'bitswarmbox/command/env'
9
+
10
+ self.abstract_command = true
11
+ self.command = 'bitswarmbox'
12
+ self.version = VERSION
13
+ self.description = 'Toolkit for building Vagrantboxes, VM and cloud images.'
14
+ end
15
+ end