vagrant-pe_build 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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