vagrant-pe_build 0.2.0 → 0.3.0

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 (45) hide show
  1. data/CHANGELOG +59 -0
  2. data/README.markdown +148 -5
  3. data/lib/pe_build.rb +5 -3
  4. data/lib/pe_build/action.rb +5 -0
  5. data/lib/pe_build/action/pe_build_dir.rb +18 -0
  6. data/lib/pe_build/archive.rb +39 -46
  7. data/lib/pe_build/cap.rb +17 -0
  8. data/lib/pe_build/cap/detect_installer/base.rb +15 -0
  9. data/lib/pe_build/cap/detect_installer/debian.rb +23 -0
  10. data/lib/pe_build/cap/detect_installer/posix.rb +73 -0
  11. data/lib/pe_build/cap/detect_installer/redhat.rb +18 -0
  12. data/lib/pe_build/cap/detect_installer/ubuntu.rb +23 -0
  13. data/lib/pe_build/cap/run_install/posix.rb +26 -0
  14. data/lib/pe_build/command.rb +6 -63
  15. data/lib/pe_build/command/base.rb +55 -0
  16. data/lib/pe_build/command/copy.rb +22 -23
  17. data/lib/pe_build/command/download.rb +4 -8
  18. data/lib/pe_build/command/list.rb +1 -6
  19. data/lib/pe_build/config/global.rb +13 -4
  20. data/lib/pe_build/config/pe_bootstrap.rb +4 -0
  21. data/lib/pe_build/idempotent.rb +1 -1
  22. data/lib/pe_build/on_machine.rb +10 -0
  23. data/lib/pe_build/plugin.rb +58 -22
  24. data/lib/pe_build/provisioner/pe_bootstrap.rb +123 -156
  25. data/lib/pe_build/provisioner/pe_bootstrap/answers_file.rb +49 -0
  26. data/lib/pe_build/release.rb +23 -0
  27. data/lib/pe_build/release/2_0.rb +25 -0
  28. data/lib/pe_build/release/2_5.rb +28 -0
  29. data/lib/pe_build/release/2_6.rb +27 -0
  30. data/lib/pe_build/release/2_7.rb +28 -0
  31. data/lib/pe_build/release/2_8.rb +35 -0
  32. data/lib/pe_build/release/3_0.rb +36 -0
  33. data/lib/pe_build/release/instance.rb +63 -0
  34. data/lib/pe_build/transfer.rb +25 -0
  35. data/lib/pe_build/transfer/file.rb +11 -9
  36. data/lib/pe_build/transfer/open_uri.rb +62 -0
  37. data/lib/pe_build/version.rb +1 -1
  38. data/templates/answers/{agent.txt.erb → agent-2.x.txt.erb} +1 -1
  39. data/templates/answers/agent-3.x.txt.erb +16 -0
  40. data/templates/answers/{master.txt.erb → master-2.x.txt.erb} +0 -0
  41. data/templates/answers/master-3.x.txt.erb +44 -0
  42. data/templates/locales/en.yml +16 -3
  43. metadata +28 -6
  44. data/lib/pe_build/transfer/uri.rb +0 -53
  45. data/templates/answers/master-existing-db.txt.erb +0 -52
@@ -6,33 +6,69 @@ if Vagrant::VERSION < "1.1.0"
6
6
  end
7
7
 
8
8
  module PEBuild
9
- class Plugin < Vagrant.plugin('2')
9
+ class Plugin < Vagrant.plugin('2')
10
10
 
11
- name 'pe_build'
11
+ name 'pe_build'
12
12
 
13
- description <<-DESC
14
- This plugin adds commands and provisioners to automatically install Puppet
15
- Enterprise on Vagrant guests.
16
- DESC
13
+ description <<-DESC
14
+ This plugin adds commands and provisioners to automatically install Puppet
15
+ Enterprise on Vagrant guests.
16
+ DESC
17
17
 
18
- config(:pe_bootstrap, :provisioner) do
19
- require_relative 'config/pe_bootstrap'
20
- PEBuild::Config::PEBootstrap
21
- end
18
+ # User facing plugin configuration
22
19
 
23
- config(:pe_build) do
24
- require_relative 'config/global'
25
- PEBuild::Config::Global
26
- end
20
+ config(:pe_bootstrap, :provisioner) do
21
+ require_relative 'config/pe_bootstrap'
22
+ PEBuild::Config::PEBootstrap
23
+ end
27
24
 
28
- provisioner(:pe_bootstrap) do
29
- require_relative 'provisioner/pe_bootstrap'
30
- PEBuild::Provisioner::PEBootstrap
31
- end
25
+ config(:pe_build) do
26
+ require_relative 'config/global'
27
+ PEBuild::Config::Global
28
+ end
29
+
30
+ provisioner(:pe_bootstrap) do
31
+ require_relative 'provisioner/pe_bootstrap'
32
+ PEBuild::Provisioner::PEBootstrap
33
+ end
34
+
35
+ command(:'pe-build') do
36
+ require_relative 'command'
37
+ PEBuild::Command::Base
38
+ end
39
+
40
+ # Guest capabilities for installing PE
41
+
42
+ guest_capability('debian', 'detect_installer') do
43
+ require_relative 'cap'
44
+ PEBuild::Cap::DetectInstaller::Debian
45
+ end
32
46
 
33
- command(:'pe-build') do
34
- require_relative 'command'
35
- PEBuild::Command
47
+ guest_capability('redhat', 'detect_installer') do
48
+ require_relative 'cap'
49
+ PEBuild::Cap::DetectInstaller::Redhat
50
+ end
51
+
52
+ guest_capability('ubuntu', 'detect_installer') do
53
+ require_relative 'cap'
54
+ PEBuild::Cap::DetectInstaller::Ubuntu
55
+ end
56
+
57
+ guest_capability('linux', 'run_install') do
58
+ require_relative 'cap'
59
+ PEBuild::Cap::RunInstall::POSIX
60
+ end
61
+
62
+ guest_capability('solaris', 'run_install') do
63
+ require_relative 'cap'
64
+ PEBuild::Cap::RunInstall::POSIX
65
+ end
66
+
67
+ # internal action hooks
68
+
69
+ action_hook('PE Build: initialize build dir') do |hook|
70
+ require 'pe_build/action'
71
+ hook.prepend PEBuild::Action::PEBuildDir
72
+ end
36
73
  end
37
74
  end
38
- end
@@ -5,198 +5,165 @@ require 'pe_build/util/config'
5
5
 
6
6
  require 'log4r'
7
7
  require 'fileutils'
8
- require 'erb'
9
8
 
10
9
  module PEBuild
11
- module Provisioner
10
+ module Provisioner
11
+ class PEBootstrap < Vagrant.plugin('2', :provisioner)
12
12
 
13
- class PEBootstrap < Vagrant.plugin('2', :provisioner)
13
+ require 'pe_build/provisioner/pe_bootstrap/answers_file'
14
14
 
15
- # @!attribute [r] work_dir
16
- # @return [String] The path to the machine pe_build working directory
15
+ # @!attribute [r] work_dir
16
+ # @return [String] The path to the machine pe_build working directory
17
17
 
18
- attr_reader :work_dir
18
+ attr_reader :work_dir
19
19
 
20
- # @!attribute [r] answer_dir
21
- # @return [String] The path to the default answer file template dir
22
- attr_reader :answer_dir
20
+ # @!attribute [r] answer_dir
21
+ # @return [String] The path to the default answer file template dir
22
+ attr_reader :answer_dir
23
23
 
24
- # @!attribute [r] answer_file
25
- # @return [String] The path to the answer file for this machine.
26
- attr_reader :answer_file
24
+ # @!attribute [r] answer_file
25
+ # @return [String] The path to the answer file for this machine.
26
+ attr_reader :answer_file
27
27
 
28
- def initialize(machine, config)
29
- super
28
+ def initialize(machine, config)
29
+ super
30
30
 
31
- @logger = Log4r::Logger.new('vagrant::provisioners::pe_bootstrap')
31
+ @logger = Log4r::Logger.new('vagrant::provisioners::pe_bootstrap')
32
32
 
33
- @work_dir = File.join(@machine.env.root_path, '.pe_build')
34
- @answer_dir = File.join(work_dir, 'answers')
35
- end
36
-
37
- # Instantiate all working directory content and stage the PE installer.
38
- #
39
- # @param root_config [Object] ???
40
- # @return [void]
41
- def configure(root_config)
42
- late_config_merge(root_config)
43
-
44
- unless File.directory? work_dir
45
- FileUtils.mkdir_p work_dir
46
- end
47
-
48
- unless File.directory? answer_dir
49
- FileUtils.mkdir_p answer_dir
50
- end
51
-
52
- archive = PEBuild::Archive.new(@config.filename, @machine.env)
53
- archive.version = @config.version
54
-
55
- archive.download_from(@config.download_root)
56
- archive.unpack_to(@work_dir)
57
- end
58
-
59
- def provision
60
- prepare_answers_file
61
-
62
- [:base, @config.role].each do |rolename|
63
- process_step rolename, :pre
64
- end
65
-
66
- perform_installation
33
+ @work_dir = File.join(@machine.env.root_path.join, PEBuild::WORK_DIR)
34
+ @answer_dir = File.join(work_dir, 'answers')
35
+ end
67
36
 
68
- if @config.relocate_manifests
69
- relocate_installation
70
- end
37
+ # Instantiate all working directory content and stage the PE installer.
38
+ #
39
+ # @param root_config [Object] ???
40
+ # @return [void]
41
+ def configure(root_config)
42
+ late_config_merge(root_config)
71
43
 
72
- [:base, @config.role].each do |rolename|
73
- process_step rolename, :post
74
- end
75
- end
76
-
77
- private
44
+ unless File.directory? work_dir
45
+ FileUtils.mkdir_p work_dir
46
+ end
47
+ end
78
48
 
79
- def late_config_merge(root_config)
80
- provision = @config
81
- global = root_config.pe_build
49
+ def provision
50
+ prepare_answers_file
51
+ load_archive
52
+ fetch_installer
82
53
 
83
- # We don't necessarily know if the configs have been merged. If a config
84
- # is being used for default values and was never directly touched then it
85
- # may have bad values, so we re-finalize everything. This may not be
86
- # generally safe but inside of this plugin it should be ok.
87
- provision.finalize!
88
- global.finalize!
54
+ [:base, @config.role].each { |rolename| process_step rolename, :pre }
89
55
 
90
- merged = PEBuild::Util::Config.local_merge(provision, global)
56
+ perform_installation
57
+ relocate_installation if @config.relocate_manifests
91
58
 
92
- @config = merged
93
- end
59
+ [:base, @config.role].each { |rolename| process_step rolename, :post }
60
+ end
94
61
 
95
- def generate_answers
96
- if @config.answer_file
97
- template_path = @config.answer_file
98
- else
99
- default_template_path = File.join(PEBuild.template_dir, 'answers', "#{@config.role}.txt.erb")
100
- template_path = default_template_path
101
- end
102
- @machine.ui.info "Using #{template_path} as answers template"
103
- template = File.read(template_path)
104
- str = ERB.new(template).result(binding)
105
- end
62
+ private
106
63
 
107
- def prepare_answers_file
108
- str = generate_answers
64
+ def late_config_merge(root_config)
65
+ provision = @config
66
+ global = root_config.pe_build
109
67
 
110
- dest_file = File.join(@answer_dir, "#{@machine.name}.txt")
68
+ # We don't necessarily know if the configs have been merged. If a config
69
+ # is being used for default values and was never directly touched then it
70
+ # may have bad values, so we re-finalize everything. This may not be
71
+ # generally safe but inside of this plugin it should be ok.
72
+ provision.finalize!
73
+ global.finalize!
111
74
 
112
- @machine.ui.info "Writing answers file to #{dest_file}"
113
- File.open(dest_file, "w") do |file|
114
- file.write(str)
115
- end
116
- end
75
+ merged = PEBuild::Util::Config.local_merge(provision, global)
117
76
 
118
- def process_step(role, stepname)
77
+ @config = merged
78
+ end
119
79
 
120
- if role != :base && config.step[stepname]
121
- if File.file? config.step[stepname]
122
- script_list = [*config.step[stepname]]
123
- else
124
- script_list = []
125
- @machine.ui.warn "Cannot find defined step for #{role}/#{stepname.to_s} at \'#{config.step[stepname]}\'"
80
+ def prepare_answers_file
81
+ af = AnswersFile.new(@machine, @config, @work_dir)
82
+ af.generate
126
83
  end
127
- else
128
- # We do not have a user defined step for this role or we're processing the :base step
129
- script_dir = File.join(PEBuild.source_root, 'bootstrap', role.to_s, stepname.to_s)
130
- script_list = Dir.glob("#{script_dir}/*")
131
- end
132
84
 
133
- if script_list.empty?
134
- @logger.info "No steps for #{role}/#{stepname}", :color => :cyan
135
- end
85
+ def load_archive
86
+ if @config.suffix == :detect
87
+ filename = @machine.guest.capability('detect_installer', @config.version)
88
+ else
89
+ filename = @config.filename
90
+ end
136
91
 
137
- script_list.each do |template_path|
138
- # A message to show which step's action is running
139
- @machine.ui.info "Running action for #{role}/#{stepname}"
140
- template = File.read(template_path)
141
- contents = ERB.new(template).result(binding)
92
+ @archive = PEBuild::Archive.new(filename, @machine.env)
93
+ @archive.version = @config.version
94
+ end
142
95
 
143
- on_remote contents
144
- end
145
- end
96
+ # @todo panic if @config.download_root is undefined
97
+ def fetch_installer
98
+ uri = @config.download_root
99
+ @archive.fetch(@config.download_root)
100
+ @archive.unpack_to(@work_dir)
101
+ end
146
102
 
147
- # Determine the proper invocation of the PE installer
148
- def installer_cmd
149
- root = "/vagrant/.pe_build"
103
+ def process_step(role, stepname)
150
104
 
151
- installer_dir = "puppet-enterprise-#{@config.version}-#{@config.suffix}"
152
- installer = "puppet-enterprise-installer"
105
+ if role != :base && config.step[stepname]
106
+ if File.file? config.step[stepname]
107
+ script_list = [*config.step[stepname]]
108
+ else
109
+ script_list = []
110
+ @machine.ui.warn "Cannot find defined step for #{role}/#{stepname.to_s} at \'#{config.step[stepname]}\'"
111
+ end
112
+ else
113
+ # We do not have a user defined step for this role or we're processing the :base step
114
+ script_dir = File.join(PEBuild.source_root, 'bootstrap', role.to_s, stepname.to_s)
115
+ script_list = Dir.glob("#{script_dir}/*")
116
+ end
153
117
 
154
- answers = "#{root}/answers/#{@machine.name}.txt"
155
- log_file = "/root/puppet-enterprise-installer-#{Time.now.strftime('%s')}.log"
118
+ if script_list.empty?
119
+ @logger.info "No steps for #{role}/#{stepname}"
120
+ end
156
121
 
157
- cmd = File.join(root, installer_dir, installer)
122
+ script_list.each do |template_path|
123
+ # A message to show which step's action is running
124
+ @machine.ui.info "Running action for #{role}/#{stepname}"
125
+ template = File.read(template_path)
126
+ contents = ERB.new(template).result(binding)
158
127
 
159
- @installer_cmd = "#{cmd} -a #{answers} -l #{log_file}"
160
- end
128
+ on_remote contents
129
+ end
130
+ end
161
131
 
162
- def perform_installation
163
- if @machine.communicate.test('test -f /opt/puppet/pe_version')
164
- @machine.ui.warn "Puppet Enterprise is already installed, skipping installation.",
165
- :name => @machine.name
166
- else
167
- on_remote installer_cmd
168
- @machine.ui.info "Scheduling puppet run to prime pe_mcollective"
169
- on_remote "echo '/opt/puppet/bin/puppet agent -t' | at next minute"
170
- end
171
- end
132
+ def perform_installation
133
+ if @machine.communicate.test('test -f /opt/puppet/pe_version')
134
+ @machine.ui.warn I18n.t('pebuild.provisioner.pe_bootstrap.already_installed'),
135
+ :name => @machine.name
136
+ else
137
+ @machine.guest.capability('run_install', @config, @archive)
138
+ end
139
+ end
172
140
 
173
- # Modify the PE puppet master config to use alternate /manifests and /modules
174
- #
175
- # Manifests and modules need to be mounted on the master via shared folders,
176
- # but the default /vagrant mount has permissions and ownership that conflicts
177
- # with the puppet master process and the pe-puppet user. Those directories
178
- # need to be mounted with permissions like 'fmode=644,dmode=755,fmask=022,dmask=022'
179
- #
180
- def relocate_installation
181
- script_path = File.join(PEBuild.template_dir, 'scripts', 'relocate_installation.sh')
182
- script = File.read script_path
183
- on_remote script
184
- end
141
+ # Modify the PE puppet master config to use alternate /manifests and /modules
142
+ #
143
+ # Manifests and modules need to be mounted on the master via shared folders,
144
+ # but the default /vagrant mount has permissions and ownership that conflicts
145
+ # with the puppet master process and the pe-puppet user. Those directories
146
+ # need to be mounted with permissions like 'fmode=644,dmode=755,fmask=022,dmask=022'
147
+ #
148
+ def relocate_installation
149
+ script_path = File.join(PEBuild.template_dir, 'scripts', 'relocate_installation.sh')
150
+ script = File.read script_path
151
+ on_remote script
152
+ end
185
153
 
186
- def on_remote(cmd)
187
- @machine.communicate.sudo(cmd) do |type, data|
188
- if type == :stdout
189
- if @config.verbose
190
- @machine.ui.info(data.chomp, :color => :green, :prefix => true)
191
- else
192
- @machine.ui.info('.', :color => :green)
154
+ def on_remote(cmd)
155
+ @machine.communicate.sudo(cmd) do |type, data|
156
+ if type == :stdout
157
+ if @config.verbose
158
+ @machine.ui.info(data.chomp, :color => :green, :prefix => true)
159
+ else
160
+ @machine.ui.info('.', :color => :green)
161
+ end
162
+ else
163
+ @machine.ui.info(data.chomp, :color => :red, :prefix => true)
164
+ end
193
165
  end
194
- else
195
- @machine.ui.info(data.chomp, :color => :red, :prefix => true)
196
166
  end
197
167
  end
198
168
  end
199
169
  end
200
-
201
- end
202
- end
@@ -0,0 +1,49 @@
1
+ require 'pe_build/release'
2
+
3
+ require 'erb'
4
+
5
+ class PEBuild::Provisioner::PEBootstrap::AnswersFile
6
+
7
+ # @param machine [Vagrant::Machine]
8
+ # @param config [Object < Vagrant.plugin('2', :config)]
9
+ # @param work_dir [String]
10
+ def initialize(machine, config, work_dir)
11
+ @machine, @config = machine, config
12
+ @work_dir = Pathname.new(work_dir)
13
+
14
+ @logger = Log4r::Logger.new('vagrant::provisioner::pe_bootstrap::answers_file')
15
+
16
+ @answer_dir = @work_dir.join('answers')
17
+ @output_file = @answer_dir.join "#{@machine.name}.txt"
18
+
19
+ set_template_path
20
+ end
21
+
22
+ def generate
23
+ @logger.info "Writing answers file for #{@machine.inspect} to #{@output_file}"
24
+ @answer_dir.mkpath unless @answer_dir.exist?
25
+
26
+ @output_file.open('w') { |fh| fh.write(render_answers) }
27
+ end
28
+
29
+ private
30
+
31
+ def set_template_path
32
+ if @config.answer_file
33
+ @template = @config.answer_file
34
+ mode = 'explicit'
35
+ else
36
+ release_info = PEBuild::Release[@config.version]
37
+
38
+ @template = release_info.answer_file(@config.role)
39
+ mode = 'default'
40
+ end
41
+
42
+ @logger.info "Using #{mode} answers file template #{@template} for #{@machine.inspect}"
43
+ end
44
+
45
+ def render_answers
46
+ template_data = File.read(@template)
47
+ ERB.new(template_data).result(binding)
48
+ end
49
+ end