vagrant-pe_build 0.8.8 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26ad8e09d5195df162062a92008f936da3e1316e
4
- data.tar.gz: 2067738932a5c776891cd8e5e1c91e2d04f0a776
3
+ metadata.gz: 269bf2fbb29c95381a0977397d40d4035c4a51e0
4
+ data.tar.gz: e50cff262ba84a0782fe50dedf575a3afc783574
5
5
  SHA512:
6
- metadata.gz: 18a14310e0a59027daa2663ecc7f75cc7c43e10d686edaa0c4ef0b11dd1abda0d9edbff04e1f1b43741d4f8d176d11a0e01ca567364956345c46bbbe4b6c216c
7
- data.tar.gz: 0b44acedc878665142f36a427f59fbd21073645d0da7a5b94490adfdedb0539b7d1ad40db24e6c37f302f0cdb63fbbd4363dd8df84a2b0814fe6963886b53f73
6
+ metadata.gz: b25346e8a16ddd1005c5e6bcec8e86a585b255227fff9b5266a732013d9d7dddee4a9c229867010af66fb7b1868b53bbea2236eab4522e5b8a814b5d23ed0809
7
+ data.tar.gz: 8064eaebceb1ec8e12d11bf9c9d4ad5e22e0cc1b3b4db9524f2d390e9953abf5013791042e440c104940e05c1e5629d1ea5b5f6c2aca0f3f90d15509ddfbe867
data/.gitignore CHANGED
@@ -1 +1,9 @@
1
+ .bundle
2
+ .ruby-version
3
+ .yardoc
1
4
  /doc
5
+ /acceptance/artifacts
6
+ Gemfile.lock
7
+ Gemfile.local
8
+ *.gem
9
+ vagrant-spec.config.rb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown
data/CHANGELOG CHANGED
@@ -1,6 +1,18 @@
1
1
  vagrant-pe_build
2
2
  ================
3
3
 
4
+ 0.9.0
5
+ -----
6
+
7
+ 2014-07-09
8
+
9
+ This is a backwards compatible feature release.
10
+
11
+ * Add two new config attributes, `version_file` and `series`, that add
12
+ flexibility to the installation location.
13
+ * Internal code cleanup and re-organization.
14
+ * Add unit and acceptance tests.
15
+
4
16
  0.8.8
5
17
  -----
6
18
 
data/Gemfile CHANGED
@@ -1,19 +1,28 @@
1
1
  source 'https://rubygems.org'
2
+ ruby '2.0.0' # Required by Vagrant 1.4 and newer.
2
3
 
3
- gemspec
4
+ ENV['TEST_VAGRANT_VERSION'] ||= 'v1.6.3'
5
+
6
+ # Wrapping gemspec in the :plugins group causes Vagrant 1.5 and newer to
7
+ # automagically load this plugin during acceptance tests.
8
+ group :plugins do
9
+ gemspec
10
+ end
4
11
 
5
12
  group :doc do
6
13
  gem 'yard', '~> 0.8.7'
7
14
  gem 'redcarpet'
8
15
  end
9
16
 
10
- group :development do
11
- # We depend on Vagrant for development, but we don't add it as a
12
- # gem dependency because we expect to be installed within the
13
- # Vagrant environment itself using `vagrant plugin`.
14
- gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git", :tag => 'v1.4.0'
15
- end
17
+ group :test do
18
+ if ENV['TEST_VAGRANT_VERSION'] == 'HEAD'
19
+ gem 'vagrant', :github => 'mitchellh/vagrant', :branch => 'master'
20
+ else
21
+ gem 'vagrant', :github => 'mitchellh/vagrant', :tag => ENV['TEST_VAGRANT_VERSION']
22
+ end
16
23
 
17
- if File.exists? "#{__FILE__}.local"
18
- eval(File.read("#{__FILE__}.local"), binding)
24
+ # Pinned on 05/05/2014. Compatible with Vagrant 1.5.x and 1.6.x.
25
+ gem 'vagrant-spec', :github => 'mitchellh/vagrant-spec', :ref => 'aae28ee'
19
26
  end
27
+
28
+ eval_gemfile "#{__FILE__}.local" if File.exists? "#{__FILE__}.local"
data/README.markdown CHANGED
@@ -177,6 +177,8 @@ Requirements
177
177
 
178
178
  [vagranthosts]: https://github.com/adrienthebo/vagrant-hosts
179
179
 
180
+ Ensure VMs have a FQDN set before installing PE. The easiest way to do this is by setting the `hostname` attribute of the VM configuration.
181
+
180
182
  Puppet Enterprise relies on SSL for security so you'll need to ensure that your
181
183
  SSL configuration isn't borked. [vagrant-hosts][vagranthosts] is recommended to
182
184
  configure VMs with semi-sane DNS.
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ task_dir = File.expand_path('../tasks', __FILE__)
2
+
3
+ Dir["#{task_dir}/**/*.rake"].each do |task_file|
4
+ load task_file
5
+ end
@@ -0,0 +1,50 @@
1
+ shared_examples 'provider/provisioner/pe_build' do |provider, options|
2
+ if !File.file?(options[:box])
3
+ raise ArgumentError,
4
+ "A box file must be downloaded for provider: #{provider}. Try: rake acceptance:setup"
5
+ end
6
+
7
+ include_context 'acceptance'
8
+
9
+ before(:each) do
10
+ environment.skeleton('pe_build')
11
+ assert_execute('vagrant', 'box', 'add', 'box', options[:box])
12
+ end
13
+
14
+ after(:each) do
15
+ # Ensure any VMs that survived tests are cleaned up.
16
+ assert_execute('vagrant', 'destroy', '--force', log: false)
17
+ end
18
+
19
+ context 'when download_root is set to a local directory' do
20
+ let(:extra_env) do
21
+ vars = options[:env_vars].dup
22
+ vars['PE_BUILD_DOWNLOAD_ROOT'] = options[:archive_path]
23
+
24
+ vars
25
+ end
26
+
27
+ it 'provisions with pe_build' do
28
+ assert_execute('vagrant', 'up', "--provider=#{provider}", 'explicit-version')
29
+ assert_execute('vagrant', 'up', "--provider=#{provider}", 'latest-version')
30
+ end
31
+ end
32
+
33
+ context 'when download_root is set to a webserver' do
34
+ let(:webserver_port) { 3838 }
35
+ let(:webserver_path) { options[:archive_path] }
36
+ include_context 'webserver'
37
+
38
+ let(:extra_env) do
39
+ vars = options[:env_vars].dup
40
+ vars['PE_BUILD_DOWNLOAD_ROOT'] = "http://localhost:#{webserver_port}/"
41
+
42
+ vars
43
+ end
44
+
45
+ it 'provisions with pe_build' do
46
+ assert_execute('vagrant', 'up', "--provider=#{provider}", 'explicit-version')
47
+ assert_execute('vagrant', 'up', "--provider=#{provider}", 'latest-version')
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,24 @@
1
+ Vagrant.configure('2') do |config|
2
+ config.pe_build.download_root = ENV['PE_BUILD_DOWNLOAD_ROOT']
3
+ config.vm.box = 'box'
4
+
5
+ config.vm.define 'explicit-version' do |node|
6
+ node.vm.provision :pe_bootstrap do |p|
7
+ p.version = '3.2.3'
8
+ p.role = :agent
9
+ # Basically the stock answer file with:
10
+ # q_fail_on_unsuccessful_master_lookup=n
11
+ p.answer_file = File.join(File.dirname(__FILE__), 'agent-3.x.txt.erb')
12
+ end
13
+ end
14
+
15
+ config.vm.define 'latest-version' do |node|
16
+ node.vm.provision :pe_bootstrap do |p|
17
+ p.version_file = 'LATEST'
18
+ p.role = :agent
19
+ # Basically the stock answer file with:
20
+ # q_fail_on_unsuccessful_master_lookup=n
21
+ p.answer_file = File.join(File.dirname(__FILE__), 'agent-3.x.txt.erb')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ q_fail_on_unsuccessful_master_lookup=y
2
+ q_install=y
3
+ q_puppet_cloud_install=n
4
+ q_puppet_enterpriseconsole_install=n
5
+ q_puppet_symlinks_install=y
6
+ q_puppetagent_certname=<%= machine_hostname %>
7
+ q_puppetagent_install=y
8
+ q_puppetagent_server=<%= @config.master %>
9
+ q_puppetca_install=n
10
+ q_puppetdb_hostname=
11
+ q_puppetdb_install=n
12
+ q_puppetdb_port=
13
+ q_puppetmaster_install=n
14
+ q_vendor_packages_install=y
15
+ q_continue_or_reenter_master_hostname=c
16
+ q_verify_packages=y
17
+ q_fail_on_unsuccessful_master_lookup=n
@@ -27,6 +27,11 @@ module PEBuild
27
27
  # @return [String] The version of Puppet Enterprise
28
28
  attr_accessor :version
29
29
 
30
+ # (see PEBuild::Config::Global#series)
31
+ #
32
+ # @see PEBuild::Config::Global#series
33
+ attr_accessor :series
34
+
30
35
  # @!attribute [rw] filename
31
36
  # @return [String] The filename. Thing
32
37
  attr_accessor :filename
@@ -62,8 +67,7 @@ module PEBuild
62
67
  uri = URI.parse(versioned_path("#{str}/#{@filename}"))
63
68
  dst = File.join(@archive_dir, versioned_path(@filename))
64
69
 
65
- transfer = PEBuild::Transfer.generate(uri, dst)
66
- transfer.copy
70
+ PEBuild::Transfer.copy(uri, dst)
67
71
  end
68
72
 
69
73
  # @param fs_dir [String] The base directory to extract the installer to
@@ -103,11 +107,11 @@ module PEBuild
103
107
  end
104
108
 
105
109
  def versioned_path(path)
106
- if @version
107
- path.gsub(/:version/, @version)
108
- else
109
- path
110
- end
110
+ result = path.dup
111
+ result.gsub!(/:version/, @version) if @version
112
+ result.gsub!(/:series/, @series) if @series
113
+
114
+ result
111
115
  end
112
116
  end
113
117
  end
@@ -6,20 +6,49 @@ require 'uri'
6
6
  class PEBuild::Config::Global < Vagrant.plugin('2', :config)
7
7
 
8
8
  # @!attribute download_root
9
+ # @return [String] The root URI from which to download packages. The URI
10
+ # scheme must be one of the values listed in {PEBuild::Transfer::IMPLEMENTATIONS}.
11
+ # @since 0.1.0
9
12
  attr_accessor :download_root
10
13
 
11
14
  # @!attribute version
15
+ # @return [String] The version of PE to install. Must conform to
16
+ # `x.y.x[-optional-arbitrary-stuff]`. Used to determine the name of the
17
+ # PE installer archive if {#filename} is unset.
18
+ # @since 0.1.0
12
19
  attr_accessor :version
13
20
 
21
+ # @!attribute version_file
22
+ # @return [String] The path to a file relative to {#download_root}. The
23
+ # contents of this file will be read and used to specify {#version}.
24
+ # @since 0.9.0
25
+ attr_accessor :version_file
26
+
27
+ # @!attribute series
28
+ # @return [String] The release series of PE. Completely optional and
29
+ # currently has no effect other than being an interpolation token
30
+ # available for use in {#download_root}.
31
+ #
32
+ # @since 0.9.0
33
+ attr_accessor :series
34
+
14
35
  # @!attribute suffix
36
+ # @return [String] The distribution specifix suffix of the Puppet
37
+ # Enterprise installer to use.
38
+ # @since 0.1.0
15
39
  attr_accessor :suffix
16
40
 
17
41
  # @!attribute filename
42
+ # @return [String] The exact name of the PE installer archive. If missing,
43
+ # a name will be constructed from {#version}.
44
+ # @since 0.1.0
18
45
  attr_accessor :filename
19
46
 
20
47
  def initialize
21
48
  @download_root = UNSET_VALUE
22
49
  @version = UNSET_VALUE
50
+ @version_file = UNSET_VALUE
51
+ @series = UNSET_VALUE
23
52
  @suffix = UNSET_VALUE
24
53
  @filename = UNSET_VALUE
25
54
  end
@@ -27,12 +56,14 @@ class PEBuild::Config::Global < Vagrant.plugin('2', :config)
27
56
  include PEBuild::ConfigDefault
28
57
 
29
58
  def finalize!
59
+ set_default :@version, nil
60
+ set_default :@version_file, nil
61
+ set_default :@series, nil
30
62
  set_default :@suffix, :detect
31
63
  set_default :@download_root, nil
32
64
  set_default :@filename, nil
33
65
  end
34
66
 
35
- # @todo Convert error strings to I18n
36
67
  def validate(machine)
37
68
  errors = []
38
69
 
@@ -61,7 +92,7 @@ class PEBuild::Config::Global < Vagrant.plugin('2', :config)
61
92
  if !(@version.match PE_VERSION_REGEX)
62
93
  errors << errmsg
63
94
  end
64
- elsif @version != UNSET_VALUE
95
+ elsif @version != nil
65
96
  errors << errmsg
66
97
  end
67
98
  end
@@ -68,6 +68,10 @@ class PEBuild::Config::PEBootstrap < PEBuild::Config::Global
68
68
  # the provisioner will handle that.
69
69
  def finalize!
70
70
 
71
+ # NOTE: The version default is copied from Config::Global. Can't call
72
+ # `super` here as it does weird things to `download_root`.
73
+ set_default :@version, nil
74
+
71
75
  set_default :@role, :agent
72
76
  set_default :@verbose, true
73
77
  set_default :@master, 'master'
@@ -83,7 +87,6 @@ class PEBuild::Config::PEBootstrap < PEBuild::Config::Global
83
87
  # We also need to run this after a default was set, otherwise we'll try to
84
88
  # normalize UNSET_VALUE
85
89
  @role = @role.intern
86
-
87
90
  end
88
91
 
89
92
  # @param machine [Vagrant::Machine]
@@ -105,12 +108,6 @@ class PEBuild::Config::PEBootstrap < PEBuild::Config::Global
105
108
 
106
109
  private
107
110
 
108
- def validate_version(errors, machine)
109
- if @version == UNSET_VALUE and global_config_from(machine).pe_build.version == UNSET_VALUE
110
- errors << I18n.t('pebuild.config.pe_bootstrap.errors.unset_version')
111
- end
112
- end
113
-
114
111
  def validate_role(errors, machine)
115
112
  unless VALID_ROLES.any? {|sym| @role == sym.intern}
116
113
  errors << I18n.t(
@@ -164,21 +161,4 @@ class PEBuild::Config::PEBootstrap < PEBuild::Config::Global
164
161
  )
165
162
  end
166
163
  end
167
-
168
- # Safely access the global config
169
- def global_config_from(machine)
170
- case Vagrant::VERSION
171
- when /^1\.[1234]/
172
- # If we try to access the global config object directly from a validating
173
- # machine, horrible things happen. To avoid this we access the environment's
174
- # global config which should already be finalized.
175
- env = machine.env.config_global
176
- else # Vagrant 1.5.x and above
177
- # This kinda seemed like the most direct replacement for config_global,
178
- # but turned out not to really work. Returned a dummy object of some
179
- # kind.
180
- #env = vagrantfile.config
181
- env = machine.config
182
- end
183
- end
184
164
  end
@@ -6,6 +6,20 @@ class PEBuild::ConfigBuilder::Global < ::ConfigBuilder::Model::Base
6
6
  # @return [String] The version of Puppet Enterprise to install.
7
7
  def_model_attribute :version
8
8
 
9
+ # @!attribute [rw] version_file
10
+ # @return [String] The path to a file relative to {#download_root}. The
11
+ # contents of this file will be read and used to specify {#version}.
12
+ # @since 0.9.0
13
+ def_model_attribute :version_file
14
+
15
+ # @!attribute [rw] series
16
+ # @return [String] The release series of PE. Completely optional and
17
+ # currently has no effect other than being an interpolation token
18
+ # available for use in {#download_root}.
19
+ #
20
+ # @since 0.9.0
21
+ def_model_attribute :series
22
+
9
23
  # @!attribute [rw] suffix
10
24
  # @return [String] The distribution specifix suffix of the Puppet
11
25
  # Enterprise installer to use.
@@ -24,6 +38,8 @@ class PEBuild::ConfigBuilder::Global < ::ConfigBuilder::Model::Base
24
38
  Proc.new do |global_config|
25
39
  global_config.pe_build.download_root = attr(:download_root) if attr(:download_root)
26
40
  global_config.pe_build.version = attr(:version) if attr(:version)
41
+ global_config.pe_build.version_file = attr(:version_file) if attr(:version_file)
42
+ global_config.pe_build.series = attr(:series) if attr(:series)
27
43
  global_config.pe_build.suffix = attr(:suffix) if attr(:suffix)
28
44
  global_config.pe_build.filename = attr(:filename) if attr(:filename)
29
45
  end
@@ -46,6 +46,8 @@ class PEBuild::ConfigBuilder::PEBootstrap < ::PEBuild::ConfigBuilder::Global
46
46
  # Globally settable attributes
47
47
  pe.download_root = attr(:download_root) if attr(:download_root)
48
48
  pe.version = attr(:version) if attr(:version)
49
+ pe.version_file = attr(:version_file) if attr(:version_file)
50
+ pe.series = attr(:series) if attr(:series)
49
51
  pe.suffix = attr(:suffix) if attr(:suffix)
50
52
  pe.filename = attr(:filename) if attr(:filename)
51
53
 
@@ -2,6 +2,7 @@ require 'vagrant'
2
2
 
3
3
  require 'pe_build/archive'
4
4
  require 'pe_build/util/config'
5
+ require 'pe_build/util/versioned_path'
5
6
 
6
7
  require 'log4r'
7
8
  require 'fileutils'
@@ -13,6 +14,10 @@ module PEBuild
13
14
  require 'pe_build/provisioner/pe_bootstrap/answers_file'
14
15
  require 'pe_build/provisioner/pe_bootstrap/post_install'
15
16
 
17
+ class UnsetVersionError < Vagrant::Errors::VagrantError
18
+ error_key(:unset_version, 'pebuild.provisioner.pe_bootstrap.errors')
19
+ end
20
+
16
21
  # @!attribute [r] work_dir
17
22
  # @return [String] The path to the machine pe_build working directory
18
23
 
@@ -81,6 +86,15 @@ module PEBuild
81
86
  end
82
87
 
83
88
  def load_archive
89
+ # If a version file is set, use its contents to specify the PE version.
90
+ unless @config.version_file.nil?
91
+ path = "#{@config.download_root}/#{@config.version_file}"
92
+ path = PEBuild::Util::VersionedPath.versioned_path(path, @config.version, @config.series)
93
+ @config.version = PEBuild::Transfer.read(URI.parse(path))
94
+ end
95
+
96
+ raise UnsetVersionError if @config.version.nil?
97
+
84
98
  if @config.suffix == :detect and @config.filename.nil?
85
99
  filename = @machine.guest.capability('detect_installer', @config.version)
86
100
  else
@@ -88,6 +102,7 @@ module PEBuild
88
102
  end
89
103
 
90
104
  @archive = PEBuild::Archive.new(filename, @machine.env)
105
+ @archive.series = @config.series
91
106
  @archive.version = @config.version
92
107
  end
93
108
 
@@ -16,11 +16,31 @@ module PEBuild
16
16
  nil => PEBuild::Transfer::File, # Assume that URIs without a scheme are files
17
17
  }
18
18
 
19
- def self.generate(src, dst)
19
+ # @param src [URI] The local file path path to the file to copy
20
+ # @param dst [String] The path to destination of the copied file
21
+ def self.copy(src, dst)
20
22
  scheme = src.scheme
21
23
 
22
- if (klass = IMPLEMENTATIONS[scheme])
23
- klass.new(src, dst)
24
+ if (mod = IMPLEMENTATIONS[scheme])
25
+ mod.copy(src, dst)
26
+ else
27
+ raise UnhandledURIScheme, :scheme => scheme,
28
+ :supported => IMPLEMENTATIONS.keys
29
+ end
30
+ end
31
+
32
+ # Return the contents of a local or remote file.
33
+ #
34
+ # @param src [URI] The URI of the source file.
35
+ # @raises [UnhandledURIScheme] If the URI uses an unsupported scheme.
36
+ # @return [String] The contents of the source file.
37
+ #
38
+ # @since 0.9.0
39
+ def self.read(src)
40
+ scheme = src.scheme
41
+
42
+ if (mod = IMPLEMENTATIONS[scheme])
43
+ mod.read(src)
24
44
  else
25
45
  raise UnhandledURIScheme, :scheme => scheme,
26
46
  :supported => IMPLEMENTATIONS.keys
@@ -28,4 +48,3 @@ module PEBuild
28
48
  end
29
49
  end
30
50
  end
31
-
@@ -1,20 +1,26 @@
1
1
  require 'fileutils'
2
2
  require 'pe_build/idempotent'
3
3
 
4
- class PEBuild::Transfer::File
4
+ # @todo These methods fail in a messy way if something goes wrong. They should
5
+ # be refactored to raise proper errors.
6
+ # @api private
7
+ module PEBuild::Transfer::File
8
+ extend PEBuild::Idempotent
5
9
 
6
10
  # @param src [URI] The local file path path to the file to copy
7
11
  # @param dst [String] The path to destination of the copied file
8
- def initialize(uri, dst)
9
- @src = uri.path
10
- @dst = dst
11
-
12
- @logger = Log4r::Logger.new('vagrant::pe_build::transfer::file')
12
+ def self.copy(src, dst)
13
+ idempotent(dst) { FileUtils.cp src.path, dst }
13
14
  end
14
15
 
15
- include PEBuild::Idempotent
16
-
17
- def copy
18
- idempotent(@dst) { FileUtils.cp @src, @dst }
16
+ # @param src [URI] The local file path path to the file to read
17
+ # @return [String] The contents of the file with leading and trailing
18
+ # whitespace removed.
19
+ #
20
+ # @since 0.9.0
21
+ def self.read(src)
22
+ File.read(src.path).strip
19
23
  end
24
+
25
+ # TODO: Raise an appropriate exception when files do not exist.
20
26
  end
@@ -4,7 +4,11 @@ require 'pe_build/idempotent'
4
4
  require 'open-uri'
5
5
  require 'progressbar'
6
6
 
7
- class PEBuild::Transfer::OpenURI
7
+ # @api private
8
+ module PEBuild::Transfer::OpenURI
9
+ extend PEBuild::Idempotent
10
+
11
+ HEADERS = {'User-Agent' => "Vagrant/PEBuild (v#{PEBuild::VERSION})"}
8
12
 
9
13
  class DownloadFailed < Vagrant::Errors::VagrantError
10
14
  error_key(:download_failed, 'pebuild.transfer.open_uri')
@@ -12,36 +16,37 @@ class PEBuild::Transfer::OpenURI
12
16
 
13
17
  # @param uri [URI] The http(s) URI to the file to copy
14
18
  # @param dst [String] The path to destination of the copied file
15
- def initialize(uri, dst)
16
- @uri, @dst = uri, dst
17
-
18
- @logger = Log4r::Logger.new('vagrant::pe_build::transfer::open_uri')
19
- end
20
-
21
- include PEBuild::Idempotent
22
-
23
- def copy
24
- idempotent(@dst) do
25
- tmpfile = download_file
26
- FileUtils.mv(tmpfile, @dst)
19
+ def self.copy(uri, dst)
20
+ idempotent(dst) do
21
+ tmpfile = download_file(uri)
22
+ FileUtils.mv(tmpfile, dst)
27
23
  end
28
24
  rescue StandardError => e
29
- raise DownloadFailed, :uri => @uri, :msg => e.message
25
+ raise DownloadFailed, :uri => uri, :msg => e.message
30
26
  end
31
27
 
32
- HEADERS = {'User-Agent' => "Vagrant/PEBuild (v#{PEBuild::VERSION})"}
33
-
34
- private
28
+ # @param uri [URI] The http(s) URI to the file to copy
29
+ # @return [String] The contents of the file with leading and trailing
30
+ # whitespace removed.
31
+ #
32
+ # @since 0.9.0
33
+ def self.read(uri)
34
+ uri.read(HEADERS.merge({'Accept' => 'text/plain'})).strip
35
+ rescue StandardError => e
36
+ raise DownloadFailed, :uri => uri, :msg => e.message
37
+ end
35
38
 
36
39
  # Open a open-uri file handle for the given URL
37
40
  #
41
+ # @param uri [URI]
38
42
  # @return [IO]
39
- def download_file
43
+ def self.download_file(uri)
40
44
  progress = nil
41
45
 
42
46
  content_length_proc = lambda do |length|
43
47
  if length and length > 0
44
- progress = ProgressBar.new('Fetching file', length)
48
+ STDERR.puts "Fetching: #{uri}"
49
+ progress = ProgressBar.new("Fetching file", length, STDERR)
45
50
  progress.file_transfer_mode
46
51
  end
47
52
  end
@@ -55,8 +60,6 @@ class PEBuild::Transfer::OpenURI
55
60
  :progress_proc => progress_proc,
56
61
  })
57
62
 
58
- @logger.info "Fetching file from #{@uri}"
59
-
60
- @uri.open(options)
63
+ uri.open(options)
61
64
  end
62
65
  end
@@ -0,0 +1,33 @@
1
+ module PEBuild
2
+ module Util
3
+ # @api private
4
+ #
5
+ # @since 0.9.0
6
+ module VersionedPath
7
+
8
+ # Substitute release information into a path.
9
+ #
10
+ # @param path [String] A path.
11
+ # @param version [String, nil] A string that will be substituted for any
12
+ # `:version` token in `path`.
13
+ # @param series [String, nil] A string that will be substituted for any
14
+ # `:series` token in `path`.
15
+ #
16
+ # @return [String]
17
+ def self.versioned_path(path, version = nil, series = nil)
18
+ result = path.dup
19
+ result.gsub!(/:version/, version) unless version.nil?
20
+ result.gsub!(/:series/, series) unless series.nil?
21
+
22
+ result
23
+ end
24
+
25
+ # FIXME: This code is basically lifted from:
26
+ #
27
+ # PEBuild::Archive#versioned_path
28
+ #
29
+ # These two uses need to be cleaned up and consolidated.
30
+
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module PEBuild
2
- VERSION = '0.8.8'
2
+ VERSION = '0.9.0'
3
3
  end
@@ -0,0 +1,30 @@
1
+ require 'webrick'
2
+
3
+ # This context runs a WEBRick server that is accessible to tests.
4
+ # The `webserver_port` and `webserver_path` will need to be specified before
5
+ # this context is included:
6
+ #
7
+ # let(:webserver_port) { ... }
8
+ # let(:webserver_path) { ... }
9
+ # include 'webserver'
10
+ shared_context 'webserver' do
11
+ before(:each) do
12
+ mime_types = {
13
+ 'gz' => 'application/gzip',
14
+ 'zip' => 'application/zip',
15
+ 'tar' => 'application/x-tar',
16
+ }
17
+
18
+ @server = WEBrick::HTTPServer.new(
19
+ AccessLog: [],
20
+ Port: webserver_port,
21
+ DocumentRoot: webserver_path,
22
+ MimeTypes: mime_types)
23
+ @thr = Thread.new { @server.start }
24
+ end
25
+
26
+ after(:each) do
27
+ @server.shutdown rescue nil
28
+ @thr.join rescue nil
29
+ end
30
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
+
3
+ # Disable Vagrant autoloading so that other plugins defined in the Gemfile for
4
+ # Acceptance tests are not loaded.
5
+ ENV['VAGRANT_NO_PLUGINS'] = '1'
6
+
7
+ require 'vagrant-spec/unit'
8
+ require 'pe_build'
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ require 'pe_build/config'
4
+
5
+ describe PEBuild::Config::Global do
6
+ # The `machine` is a required argument to the validation routine, but
7
+ # currently is not used by the Global config validation checks.
8
+ let(:machine) { double('machine') }
9
+
10
+ context 'when finalized with default values' do
11
+ before(:each) { subject.finalize! }
12
+
13
+ it 'passes validation' do
14
+ errors = subject.validate(machine)
15
+
16
+ expect(errors).to include('PE build global config' => [])
17
+ end
18
+ end
19
+
20
+ describe 'version' do
21
+ it 'may be of the form x.y.z' do
22
+ subject.version = '3.0.0'
23
+
24
+ subject.finalize!
25
+ errors = subject.validate(machine)
26
+
27
+ expect(errors).to include('PE build global config' => [])
28
+ end
29
+
30
+ it 'may be of the form x.y.z[-other-arbitrary-stuff]' do
31
+ subject.version = '2.8.0-42-gsomesha'
32
+
33
+ subject.finalize!
34
+ errors = subject.validate(machine)
35
+
36
+ expect(errors).to include('PE build global config' => [])
37
+ end
38
+
39
+ it 'may not be x.y' do
40
+ subject.version = '3.1'
41
+
42
+ subject.finalize!
43
+ errors = subject.validate(machine)
44
+
45
+ # Casting the array to a string and using a regex matcher gives a nice
46
+ # diff in the case of failure.
47
+ expect(errors['PE build global config'].to_s).to match(/String is malformed/)
48
+ end
49
+ end
50
+
51
+ describe 'download_root' do
52
+ PEBuild::Transfer::IMPLEMENTATIONS.keys.compact.each do |scheme|
53
+ it "accepts #{scheme}://" do
54
+ subject.download_root = "#{scheme}://foo"
55
+
56
+ subject.finalize!
57
+ errors = subject.validate(machine)
58
+
59
+ expect(errors).to include('PE build global config' => [])
60
+ end
61
+ end
62
+
63
+ it 'accepts a raw path' do
64
+ subject.download_root = 'foo/bar'
65
+
66
+ subject.finalize!
67
+ errors = subject.validate(machine)
68
+
69
+ expect(errors).to include('PE build global config' => [])
70
+ end
71
+
72
+ it 'rejects foo://' do
73
+ subject.download_root = 'foo://bar'
74
+
75
+ subject.finalize!
76
+ errors = subject.validate(machine)
77
+
78
+ expect(errors['PE build global config'].to_s).to match(/cannot be handled by any file transferrers/)
79
+ end
80
+ end
81
+
82
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ require 'pe_build/config'
4
+
5
+ describe PEBuild::Config::PEBootstrap do
6
+ let(:machine) { double('machine') }
7
+
8
+ context 'when finalized with default values' do
9
+ before(:each) { subject.finalize! }
10
+
11
+ it 'passes validation' do
12
+ errors = subject.validate(machine)
13
+
14
+ expect(errors).to include('PE Bootstrap' => [])
15
+ end
16
+ end
17
+
18
+ # TODO: Spec test the validation functions. Not critical right now since it
19
+ # is pretty much testing tests. But, having specs is a good way for people to
20
+ # see precisely _what_ is allowed.
21
+
22
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ require 'pe_build/provisioner/pe_bootstrap'
4
+
5
+ describe PEBuild::Provisioner::PEBootstrap do
6
+ include_context 'vagrant-unit'
7
+
8
+ let(:test_env) do
9
+ test_env = isolated_environment
10
+ test_env.vagrantfile <<-EOF
11
+ Vagrant.configure('2') do |config|
12
+ config.vm.define :test
13
+ end
14
+ EOF
15
+
16
+ test_env
17
+ end
18
+ let(:env) { test_env.create_vagrant_env }
19
+ let(:machine) { env.machine(:test, :dummy) }
20
+ let(:bootstrap_config) { PEBuild::Config::PEBootstrap.new }
21
+
22
+ # Mock the communicator to prevent SSH commands for being executed.
23
+ let(:communicator) { double('communicator') }
24
+ # Mock the guest operating system.
25
+ let(:guest) { double('guest') }
26
+
27
+ before (:each) do
28
+ machine.stub(:guest => guest)
29
+ machine.stub(:communicator => communicator)
30
+ end
31
+
32
+ after(:each) { test_env.close }
33
+
34
+ subject(:provisioner) { described_class.new(machine, bootstrap_config) }
35
+
36
+
37
+ describe 'when configured' do
38
+ context 'and no version is set' do
39
+ it 'raises an error' do
40
+ pending 'This is now done in the `provision` method which is difficult to isolate for a test'
41
+ expect { subject.configure(machine.config) }.to raise_error(
42
+ PEBuild::Provisioner::PEBootstrap::UnsetVersionError,
43
+ /version must be set/ )
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+ namespace :acceptance do
2
+ ARTIFACT_DIR = File.join('acceptance', 'artifacts')
3
+ TEST_BOXES = %w[
4
+ https://vagrantcloud.com/puppetlabs/centos-6.5-64-nocm/version/2/provider/virtualbox.box
5
+ ]
6
+
7
+ directory ARTIFACT_DIR
8
+ TEST_BOXES.each do |box_url|
9
+ file File.join(ARTIFACT_DIR, File.basename(box_url)) => ARTIFACT_DIR do |path|
10
+ puts 'Downloading: ' + box_url
11
+ Kernel.system 'curl', '-L', '-o', path.to_s, box_url
12
+ end
13
+ end
14
+
15
+ desc 'downloads test boxes and other artifacts'
16
+ task :setup => TEST_BOXES.map {|box_url| File.join(ARTIFACT_DIR, File.basename(box_url))}
17
+
18
+ desc 'runs acceptance tests'
19
+ task :run => :setup do
20
+ command = 'vagrant-spec test'
21
+ puts command
22
+ puts
23
+ exec(command)
24
+ end
25
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,3 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
@@ -17,6 +17,10 @@ en:
17
17
  pe_bootstrap:
18
18
  post_install: |-
19
19
  Applying post-install configuration to Puppet Enterprise.
20
+ errors:
21
+ unset_version: |-
22
+ The Puppet Enterprise version must be set either on the global pe_build config
23
+ object or specified on a per-provisioner basis, but both were unset.
20
24
  transfer:
21
25
  open_uri:
22
26
  download_failed: |-
@@ -48,9 +52,6 @@ en:
48
52
  information on the shell provisioner can be found on the Vagrant website at
49
53
  http://docs.vagrantup.com/v2/provisioning/shell.html
50
54
  errors:
51
- unset_version: |-
52
- The Puppet Enterprise version must be set either on the global pe_build config
53
- object or specified on a per-provisioner basis, but both were unset.
54
55
  unknown_role: |-
55
56
  The specified role %{role} is unhandled, must be one of %{known_roles}.
56
57
  invalid_autosign_role: |-
@@ -13,11 +13,15 @@ Gem::Specification.new do |gem|
13
13
 
14
14
  gem.summary = "Vagrant provisioner for installing Puppet Enterprise"
15
15
 
16
- gem.add_dependency 'progressbar'
17
- gem.add_dependency 'minitar'
18
-
19
16
  gem.files = %x{git ls-files -z}.split("\0")
20
17
  gem.require_path = 'lib'
21
18
 
22
19
  gem.license = 'Apache 2.0'
20
+
21
+ gem.add_runtime_dependency 'progressbar'
22
+ gem.add_runtime_dependency 'minitar'
23
+
24
+ gem.add_development_dependency 'rake'
25
+ # Pin to 2.14.x for compatibility with vagrant-spec.
26
+ gem.add_development_dependency 'rspec', '~> 2.14.0'
23
27
  end
@@ -0,0 +1,19 @@
1
+ require 'pathname'
2
+ require 'vagrant-spec/acceptance'
3
+
4
+ require_relative 'spec/shared/helpers/webserver_context'
5
+
6
+ Vagrant::Spec::Acceptance.configure do |c|
7
+ acceptance_dir = Pathname.new File.expand_path('../acceptance', __FILE__)
8
+
9
+ c.component_paths = [acceptance_dir.to_s]
10
+ c.skeleton_paths = [(acceptance_dir + 'skeletons').to_s]
11
+
12
+ c.provider 'virtualbox',
13
+ box: (acceptance_dir + 'artifacts' + 'virtualbox.box').to_s,
14
+ # This folder should be filled with PE tarballs for CentOS.
15
+ archive_path: (acceptance_dir + 'artifacts' + 'pe_archives').to_s,
16
+ env_vars: {
17
+ 'VBOX_USER_HOME' => '{{homedir}}',
18
+ }
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-pe_build
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.8
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrien Thebo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-11 00:00:00.000000000 Z
11
+ date: 2014-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: progressbar
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.14.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 2.14.0
41
69
  description:
42
70
  email: adrien@somethingsinistral.net
43
71
  executables: []
@@ -45,10 +73,16 @@ extensions: []
45
73
  extra_rdoc_files: []
46
74
  files:
47
75
  - .gitignore
76
+ - .rspec
77
+ - .yardopts
48
78
  - CHANGELOG
49
79
  - Gemfile
50
80
  - LICENSE
51
81
  - README.markdown
82
+ - Rakefile
83
+ - acceptance/pe_build/pe_build_spec.rb
84
+ - acceptance/skeletons/pe_build/Vagrantfile
85
+ - acceptance/skeletons/pe_build/agent-3.x.txt.erb
52
86
  - doc/answers/README.markdown
53
87
  - doc/answers/agent.txt
54
88
  - doc/answers/master-1.1.txt
@@ -108,8 +142,16 @@ files:
108
142
  - lib/pe_build/unpack/tar.rb
109
143
  - lib/pe_build/unpack/tar_gz.rb
110
144
  - lib/pe_build/util/config.rb
145
+ - lib/pe_build/util/versioned_path.rb
111
146
  - lib/pe_build/version.rb
112
147
  - lib/vagrant-pe_build.rb
148
+ - spec/shared/helpers/webserver_context.rb
149
+ - spec/spec_helper.rb
150
+ - spec/unit/config/global_spec.rb
151
+ - spec/unit/config/pe_bootstrap_spec.rb
152
+ - spec/unit/provisioner/pe_bootstrap_spec.rb
153
+ - tasks/acceptance.rake
154
+ - tasks/spec.rake
113
155
  - templates/answers/agent-1.x.txt.erb
114
156
  - templates/answers/agent-2.0.x.txt.erb
115
157
  - templates/answers/agent-2.x.txt.erb
@@ -120,6 +162,7 @@ files:
120
162
  - templates/answers/master-3.x.txt.erb
121
163
  - templates/locales/en.yml
122
164
  - vagrant-pe_build.gemspec
165
+ - vagrant-spec.config.example.rb
123
166
  homepage: https://github.com/adrienthebo/vagrant-pe_build
124
167
  licenses:
125
168
  - Apache 2.0
@@ -145,3 +188,4 @@ signing_key:
145
188
  specification_version: 4
146
189
  summary: Vagrant provisioner for installing Puppet Enterprise
147
190
  test_files: []
191
+ has_rdoc: