vagrant-pe_build 0.12.0 → 0.13.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.
- checksums.yaml +4 -4
- data/CHANGELOG +24 -0
- data/README.markdown +152 -71
- data/acceptance/pe_build/pe_bootstrap_2015x_spec.rb +61 -13
- data/acceptance/pe_build/pe_bootstrap_3x_spec.rb +6 -3
- data/acceptance/pe_build/pe_bootstrap_latest_spec.rb +6 -3
- data/acceptance/skeletons/2015x_acceptance/Vagrantfile +25 -49
- data/acceptance/skeletons/pe_build/Vagrantfile +1 -1
- data/lib/pe_build/cap.rb +9 -0
- data/lib/pe_build/cap/detect_installer/base.rb +18 -0
- data/lib/pe_build/cap/detect_installer/posix.rb +0 -15
- data/lib/pe_build/cap/detect_installer/windows.rb +22 -4
- data/lib/pe_build/cap/facts/base.rb +119 -0
- data/lib/pe_build/cap/facts/debian.rb +37 -0
- data/lib/pe_build/cap/facts/posix.rb +36 -0
- data/lib/pe_build/cap/facts/redhat.rb +37 -0
- data/lib/pe_build/cap/facts/solaris.rb +46 -0
- data/lib/pe_build/cap/facts/suse.rb +38 -0
- data/lib/pe_build/cap/facts/ubuntu.rb +35 -0
- data/lib/pe_build/cap/facts/windows.rb +58 -0
- data/lib/pe_build/command.rb +1 -0
- data/lib/pe_build/command/base.rb +2 -1
- data/lib/pe_build/command/facts.rb +63 -0
- data/lib/pe_build/config.rb +1 -0
- data/lib/pe_build/config/pe_agent.rb +120 -0
- data/lib/pe_build/config_builder.rb +1 -0
- data/lib/pe_build/config_builder/pe_agent.rb +44 -0
- data/lib/pe_build/plugin.rb +44 -0
- data/lib/pe_build/provisioner/pe_agent.rb +262 -0
- data/lib/pe_build/release.rb +1 -1
- data/lib/pe_build/release/2015_2.rb +1 -0
- data/lib/pe_build/util/machine_comms.rb +51 -0
- data/lib/pe_build/util/pe_packaging.rb +57 -0
- data/lib/pe_build/version.rb +1 -1
- data/spec/unit/config/pe_agent_spec.rb +154 -0
- data/spec/unit/provisioner/pe_agent_spec.rb +101 -0
- data/tasks/acceptance.rake +2 -1
- data/templates/locales/en.yml +53 -0
- data/vagrant-pe_build.gemspec +4 -4
- data/vagrant-spec.config.example.rb +1 -1
- metadata +24 -5
data/lib/pe_build/plugin.rb
CHANGED
@@ -22,6 +22,11 @@ module PEBuild
|
|
22
22
|
PEBuild::Config::PEBootstrap
|
23
23
|
end
|
24
24
|
|
25
|
+
config(:pe_agent, :provisioner) do
|
26
|
+
require_relative 'config'
|
27
|
+
PEBuild::Config::PEAgent
|
28
|
+
end
|
29
|
+
|
25
30
|
config(:pe_build) do
|
26
31
|
require_relative 'config'
|
27
32
|
PEBuild::Config::Global
|
@@ -32,6 +37,11 @@ module PEBuild
|
|
32
37
|
PEBuild::Provisioner::PEBootstrap
|
33
38
|
end
|
34
39
|
|
40
|
+
provisioner(:pe_agent) do
|
41
|
+
require_relative 'provisioner/pe_agent'
|
42
|
+
PEBuild::Provisioner::PEAgent
|
43
|
+
end
|
44
|
+
|
35
45
|
command(:'pe-build') do
|
36
46
|
require_relative 'command'
|
37
47
|
PEBuild::Command::Base
|
@@ -92,6 +102,40 @@ module PEBuild
|
|
92
102
|
PEBuild::Cap::RunInstall::Windows
|
93
103
|
end
|
94
104
|
|
105
|
+
# Retrieve Facts
|
106
|
+
guest_capability('redhat', 'pebuild_facts') do
|
107
|
+
require_relative 'cap'
|
108
|
+
PEBuild::Cap::Facts::RedHat
|
109
|
+
end
|
110
|
+
|
111
|
+
guest_capability('debian', 'pebuild_facts') do
|
112
|
+
require_relative 'cap'
|
113
|
+
PEBuild::Cap::Facts::Debian
|
114
|
+
end
|
115
|
+
|
116
|
+
guest_capability('ubuntu', 'pebuild_facts') do
|
117
|
+
require_relative 'cap'
|
118
|
+
PEBuild::Cap::Facts::Ubuntu
|
119
|
+
end
|
120
|
+
|
121
|
+
guest_capability('suse', 'pebuild_facts') do
|
122
|
+
require_relative 'cap'
|
123
|
+
PEBuild::Cap::Facts::SUSE
|
124
|
+
end
|
125
|
+
|
126
|
+
[:solaris, :solaris11].each do |os|
|
127
|
+
guest_capability(os, 'pebuild_facts') do
|
128
|
+
require_relative 'cap'
|
129
|
+
PEBuild::Cap::Facts::Solaris
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
guest_capability('windows', 'pebuild_facts') do
|
134
|
+
require_relative 'cap'
|
135
|
+
PEBuild::Cap::Facts::Windows
|
136
|
+
end
|
137
|
+
|
138
|
+
|
95
139
|
# internal action hooks
|
96
140
|
|
97
141
|
action_hook('PE Build: initialize build dir') do |hook|
|
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'pe_build/util/pe_packaging'
|
2
|
+
require 'pe_build/util/machine_comms'
|
3
|
+
|
4
|
+
module PEBuild
|
5
|
+
module Provisioner
|
6
|
+
# Provision PE agents using simplified install
|
7
|
+
#
|
8
|
+
# @since 0.13.0
|
9
|
+
class PEAgent < Vagrant.plugin('2', :provisioner)
|
10
|
+
include ::PEBuild::Util::PEPackaging
|
11
|
+
include ::PEBuild::Util::MachineComms
|
12
|
+
|
13
|
+
attr_reader :facts
|
14
|
+
attr_reader :agent_version
|
15
|
+
|
16
|
+
def provision
|
17
|
+
provision_init!
|
18
|
+
|
19
|
+
# As of 2015.x, pe_repo doesn't support windows installation, so skip
|
20
|
+
# provisioning the repositories.
|
21
|
+
unless config.master_vm.nil? || provision_windows?
|
22
|
+
provision_pe_repo
|
23
|
+
end
|
24
|
+
provision_agent
|
25
|
+
provision_agent_cert if config.autosign
|
26
|
+
end
|
27
|
+
|
28
|
+
# This gets run during agent destruction and will remove the agent's
|
29
|
+
# certificate from the master, if requested.
|
30
|
+
def cleanup
|
31
|
+
unless config.master_vm.is_a?(::Vagrant::Machine)
|
32
|
+
vm_def = machine.env.active_machines.find {|vm| vm[0].to_s == config.master_vm.to_s}
|
33
|
+
if vm_def.nil?
|
34
|
+
config.master_vm.ui.warn I18n.t(
|
35
|
+
'pebuild.provisioner.pe_agent.skip_purge_no_master',
|
36
|
+
:master => config.master_vm.to_s
|
37
|
+
)
|
38
|
+
return
|
39
|
+
end
|
40
|
+
config.master_vm = machine.env.machine(*vm_def)
|
41
|
+
end
|
42
|
+
|
43
|
+
cleanup_agent_cert if config.autopurge
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Set data items that are only available at provision time
|
49
|
+
def provision_init!
|
50
|
+
@facts = machine.guest.capability(:pebuild_facts)
|
51
|
+
@agent_version = facts['puppetversion']
|
52
|
+
|
53
|
+
# Resolve the master_vm setting to a Vagrant machine reference.
|
54
|
+
unless config.master_vm.nil?
|
55
|
+
vm_def = machine.env.active_machines.find {|vm| vm[0].to_s == config.master_vm.to_s}
|
56
|
+
|
57
|
+
unless vm_def.nil?
|
58
|
+
config.master_vm = machine.env.machine(*vm_def)
|
59
|
+
config.master ||= config.master_vm.config.vm.hostname.to_s
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# A quick test to determine if we are provisioning a Windows agent
|
65
|
+
#
|
66
|
+
# This method requires {#provision_init!} to be called.
|
67
|
+
def provision_windows?
|
68
|
+
facts['os']['family'].downcase == 'windows'
|
69
|
+
end
|
70
|
+
|
71
|
+
def provision_agent
|
72
|
+
unless agent_version.nil?
|
73
|
+
machine.ui.info I18n.t(
|
74
|
+
'pebuild.provisioner.pe_agent.already_installed',
|
75
|
+
:version => agent_version
|
76
|
+
)
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
if provision_windows?
|
81
|
+
provision_windows_agent
|
82
|
+
else
|
83
|
+
provision_posix_agent
|
84
|
+
end
|
85
|
+
|
86
|
+
# Refresh agent facts post-installation.
|
87
|
+
@facts = machine.guest.capability(:pebuild_facts)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Ensure a master VM is able to serve agent packages
|
91
|
+
#
|
92
|
+
# This method inspects the master VM and ensures it is configured to
|
93
|
+
# serve packages for the agent's architecture.
|
94
|
+
def provision_pe_repo
|
95
|
+
# This method will raise an error if commands can't be run on the
|
96
|
+
# master VM.
|
97
|
+
ensure_reachable(config.master_vm)
|
98
|
+
|
99
|
+
platform = platform_tag(facts)
|
100
|
+
# Transform the platform_tag into a Puppet class name.
|
101
|
+
pe_repo_platform = platform.gsub('-', '_').gsub('.', '')
|
102
|
+
# TODO: Support PE 3.x
|
103
|
+
platform_repo = "/opt/puppetlabs/server/data/packages/public/current/#{platform}"
|
104
|
+
|
105
|
+
# Print a message and return if the agent repositories exist on the
|
106
|
+
# master.
|
107
|
+
if config.master_vm.communicate.test("[ -e #{platform_repo} ]")
|
108
|
+
config.master_vm.ui.info I18n.t(
|
109
|
+
'pebuild.provisioner.pe_agent.pe_repo_present',
|
110
|
+
:vm_name => config.master_vm.name,
|
111
|
+
:platform_tag => platform
|
112
|
+
)
|
113
|
+
return
|
114
|
+
end
|
115
|
+
|
116
|
+
config.master_vm.ui.info I18n.t(
|
117
|
+
'pebuild.provisioner.pe_agent.adding_pe_repo',
|
118
|
+
:vm_name => config.master_vm.name,
|
119
|
+
:platform_tag => platform
|
120
|
+
)
|
121
|
+
|
122
|
+
shell_config = Vagrant.plugin('2').manager.provisioner_configs[:shell].new
|
123
|
+
shell_config.privileged = true
|
124
|
+
# TODO: Extend to configuring agent repos which are older than the
|
125
|
+
# master.
|
126
|
+
# TODO: Extend to PE 3.x masters.
|
127
|
+
shell_config.inline = <<-EOS
|
128
|
+
/opt/puppetlabs/bin/puppet apply -e 'include pe_repo::platform::#{pe_repo_platform}'
|
129
|
+
EOS
|
130
|
+
shell_config.finalize!
|
131
|
+
|
132
|
+
shell_provisioner = Vagrant.plugin('2').manager.provisioners[:shell].new(config.master_vm, shell_config)
|
133
|
+
shell_provisioner.provision
|
134
|
+
end
|
135
|
+
|
136
|
+
# Execute a Vagrant shell provisioner to provision POSIX agents
|
137
|
+
#
|
138
|
+
# Performs a `curl | bash` installation.
|
139
|
+
def provision_posix_agent
|
140
|
+
shell_config = Vagrant.plugin('2').manager.provisioner_configs[:shell].new
|
141
|
+
shell_config.privileged = true
|
142
|
+
# Installation is split into to components running under set -e so that
|
143
|
+
# failures are detected. The curl command uses `sS` so that download
|
144
|
+
# progress is silenced, but error messages are still printed.
|
145
|
+
#
|
146
|
+
# TODO: Extend to allow passing agent install options.
|
147
|
+
# TODO: Extend to use `config.version` once {#provision_pe_repo}
|
148
|
+
# supports it.
|
149
|
+
shell_config.inline = <<-EOS
|
150
|
+
set -e
|
151
|
+
curl -ksS -tlsv1 https://#{config.master}:8140/packages/current/install.bash -o pe_frictionless_installer.sh
|
152
|
+
bash pe_frictionless_installer.sh
|
153
|
+
EOS
|
154
|
+
shell_config.finalize!
|
155
|
+
|
156
|
+
machine.ui.info "Running: #{shell_config.inline}"
|
157
|
+
|
158
|
+
shell_provisioner = Vagrant.plugin('2').manager.provisioners[:shell].new(machine, shell_config)
|
159
|
+
shell_provisioner.provision
|
160
|
+
end
|
161
|
+
|
162
|
+
# Install a PE Agent on Windows
|
163
|
+
#
|
164
|
+
# Executes a `pe_bootstrap` provisioner running in agent mode.
|
165
|
+
def provision_windows_agent
|
166
|
+
pe_config = ::PEBuild::Config::PEBootstrap.new
|
167
|
+
pe_config.role = :agent
|
168
|
+
# Windows won't reconize 'current' as a version number, so fall through
|
169
|
+
# to the global default by leaving it unset.
|
170
|
+
pe_config.version = config.version unless config.version == 'current'
|
171
|
+
pe_config.master = config.master
|
172
|
+
pe_config.finalize!
|
173
|
+
|
174
|
+
machine.ui.info "Installing Windows agent with PE Bootstrap"
|
175
|
+
|
176
|
+
pe_provisioner = Vagrant.plugin('2').manager.provisioners[:pe_bootstrap].new(machine, pe_config)
|
177
|
+
pe_provisioner.configure(machine.config)
|
178
|
+
pe_provisioner.provision
|
179
|
+
end
|
180
|
+
|
181
|
+
def provision_agent_cert
|
182
|
+
# This method will raise an error if commands can't be run on the
|
183
|
+
# master VM.
|
184
|
+
ensure_reachable(config.master_vm)
|
185
|
+
|
186
|
+
agent_certname = facts['certname']
|
187
|
+
|
188
|
+
# Return if the cert has already been signed. The return code is
|
189
|
+
# inverted as `grep -q` will exit with 1 if the certificate is not
|
190
|
+
# found.
|
191
|
+
# TODO: Extend paths to PE 3.x masters.
|
192
|
+
if not config.master_vm.communicate.test("/opt/puppetlabs/bin/puppet cert list | grep -q -F #{agent_certname}", :sudo => true)
|
193
|
+
config.master_vm.ui.info I18n.t(
|
194
|
+
'pebuild.provisioner.pe_agent.no_csr_pending',
|
195
|
+
:certname => agent_certname,
|
196
|
+
:master => config.master_vm.name.to_s
|
197
|
+
)
|
198
|
+
return
|
199
|
+
end
|
200
|
+
|
201
|
+
config.master_vm.ui.info I18n.t(
|
202
|
+
'pebuild.provisioner.pe_agent.signing_agent_cert',
|
203
|
+
:certname => agent_certname,
|
204
|
+
:master => config.master_vm.name.to_s
|
205
|
+
)
|
206
|
+
|
207
|
+
shell_config = Vagrant.plugin('2').manager.provisioner_configs[:shell].new
|
208
|
+
shell_config.privileged = true
|
209
|
+
# TODO: Extend paths to PE 3.x masters.
|
210
|
+
shell_config.inline = <<-EOS
|
211
|
+
/opt/puppetlabs/bin/puppet cert sign #{agent_certname}
|
212
|
+
EOS
|
213
|
+
shell_config.finalize!
|
214
|
+
|
215
|
+
shell_provisioner = Vagrant.plugin('2').manager.provisioners[:shell].new(config.master_vm, shell_config)
|
216
|
+
shell_provisioner.provision
|
217
|
+
end
|
218
|
+
|
219
|
+
def cleanup_agent_cert
|
220
|
+
# TODO: This isn't very flexible. But, the VM is destroyed at this
|
221
|
+
# point, so it's the best guess we have available.
|
222
|
+
agent_certname = machine.config.vm.hostname
|
223
|
+
|
224
|
+
unless is_reachable?(config.master_vm)
|
225
|
+
config.master_vm.ui.warn I18n.t(
|
226
|
+
'pebuild.provisioner.pe_agent.skip_purge_master_not_reachable',
|
227
|
+
:vm_name => config.master_vm.name.to_s
|
228
|
+
)
|
229
|
+
return
|
230
|
+
end
|
231
|
+
|
232
|
+
# TODO: Extend paths to PE 3.x masters.
|
233
|
+
if not config.master_vm.communicate.test("/opt/puppetlabs/bin/puppet cert list #{agent_certname}", :sudo => true)
|
234
|
+
config.master_vm.ui.info I18n.t(
|
235
|
+
'pebuild.provisioner.pe_agent.agent_purged',
|
236
|
+
:certname => agent_certname,
|
237
|
+
:master => config.master_vm.name.to_s
|
238
|
+
)
|
239
|
+
return
|
240
|
+
end
|
241
|
+
|
242
|
+
config.master_vm.ui.info I18n.t(
|
243
|
+
'pebuild.provisioner.pe_agent.purging_agent',
|
244
|
+
:certname => agent_certname,
|
245
|
+
:master => config.master_vm.name.to_s
|
246
|
+
)
|
247
|
+
|
248
|
+
shell_config = Vagrant.plugin('2').manager.provisioner_configs[:shell].new
|
249
|
+
shell_config.privileged = true
|
250
|
+
# TODO: Extend to PE 3.x masters.
|
251
|
+
shell_config.inline = <<-EOS
|
252
|
+
/opt/puppetlabs/bin/puppet node purge #{agent_certname}
|
253
|
+
EOS
|
254
|
+
shell_config.finalize!
|
255
|
+
|
256
|
+
shell_provisioner = Vagrant.plugin('2').manager.provisioners[:shell].new(config.master_vm, shell_config)
|
257
|
+
shell_provisioner.provision
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
data/lib/pe_build/release.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'vagrant/errors'
|
2
|
+
|
3
|
+
module PEBuild
|
4
|
+
module Util
|
5
|
+
# Utilities related to Vagrant Machine communications
|
6
|
+
#
|
7
|
+
# This module provides general-purpose utility functions for communicating
|
8
|
+
# with Vagrant machines.
|
9
|
+
#
|
10
|
+
# @since 0.13.0
|
11
|
+
module MachineComms
|
12
|
+
|
13
|
+
# Determine if commands can be executed on a Vagrant machine
|
14
|
+
#
|
15
|
+
# @param machine [Vagrant::Machine] A Vagrant machine.
|
16
|
+
#
|
17
|
+
# @return [true] If the machine can accept communication.
|
18
|
+
# @return [false] If the machine cannot accept communication.
|
19
|
+
def is_reachable?(machine)
|
20
|
+
begin
|
21
|
+
machine.communicate.ready?
|
22
|
+
rescue Vagrant::Errors::VagrantError
|
23
|
+
# WinRM will raise an error if the VM isn't running instead of
|
24
|
+
# returning false (GH-6356).
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
module_function :is_reachable?
|
29
|
+
|
30
|
+
class MachineNotReachable < ::Vagrant::Errors::VagrantError
|
31
|
+
error_key(:machine_not_reachable, 'pebuild.errors')
|
32
|
+
end
|
33
|
+
|
34
|
+
# Raise an error if Vagrant commands cannot be executed on a machine
|
35
|
+
#
|
36
|
+
# This function raises an error if a given vagrant machine is not ready
|
37
|
+
# for communication.
|
38
|
+
#
|
39
|
+
# @param machine [Vagrant::Machine] A Vagrant machine.
|
40
|
+
#
|
41
|
+
# @return [void] If the machine can accept communication.
|
42
|
+
# @raise [MachineNotReachable] If the machine cannot accept
|
43
|
+
# communication.
|
44
|
+
def ensure_reachable(machine)
|
45
|
+
raise MachineNotReachable, :vm_name => machine.name.to_s unless is_reachable?(machine)
|
46
|
+
end
|
47
|
+
module_function :ensure_reachable
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module PEBuild
|
2
|
+
module Util
|
3
|
+
# Utilities related to PE Packages
|
4
|
+
#
|
5
|
+
# This module provides general-purpose utility functions for working with
|
6
|
+
# PE packages.
|
7
|
+
#
|
8
|
+
# @since 0.13.0
|
9
|
+
module PEPackaging
|
10
|
+
|
11
|
+
# Determine package tag from Facts
|
12
|
+
#
|
13
|
+
# The `platform_tag` is a `os-version-archtecture` value that is used in
|
14
|
+
# many PE package filenames and repostiory names.
|
15
|
+
#
|
16
|
+
# @param facts [Hash] A hash of facts which includes `architecture`
|
17
|
+
# and `os` values.
|
18
|
+
#
|
19
|
+
# @return [String] A string representing the platform tag.
|
20
|
+
def platform_tag(facts)
|
21
|
+
case facts['os']['family'].downcase
|
22
|
+
when 'redhat'
|
23
|
+
# TODO: Fedora might be in here.
|
24
|
+
os = 'el'
|
25
|
+
version = facts['os']['release']['major']
|
26
|
+
arch = facts['architecture']
|
27
|
+
when 'windows'
|
28
|
+
os = 'windows'
|
29
|
+
version = nil
|
30
|
+
arch = (facts['architecture'] == 'x64' ? 'x86_64' : 'i386')
|
31
|
+
when 'debian'
|
32
|
+
case os = facts['os']['name'].downcase
|
33
|
+
when 'debian'
|
34
|
+
version = facts['os']['release']['major']
|
35
|
+
when 'ubuntu'
|
36
|
+
version = facts['os']['release']['full']
|
37
|
+
end
|
38
|
+
# TODO: Add "unknown debian" error.
|
39
|
+
arch = (facts['architecture'] == 'x86_64' ? 'amd64' : 'i386')
|
40
|
+
when 'solaris'
|
41
|
+
os = 'solaris'
|
42
|
+
version = facts['os']['release']['major']
|
43
|
+
arch = (facts['architecture'].match(/^i\d+/) ? 'i386' : 'sparc')
|
44
|
+
when 'suse'
|
45
|
+
os = 'sles'
|
46
|
+
version = facts['os']['release']['major']
|
47
|
+
arch = facts['architecture']
|
48
|
+
end
|
49
|
+
# TODO: Add "unknown os" error.
|
50
|
+
|
51
|
+
[os, version, arch].join('-').downcase
|
52
|
+
end
|
53
|
+
module_function :platform_tag
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|