vagrant-pe_build 0.8.8 → 0.9.0

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