vagrant-berkshelf-nochefdk 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ require_relative 'base'
2
+
3
+ module VagrantPlugins
4
+ module Berkshelf
5
+ module Action
6
+ class Install < Base
7
+ def call(env)
8
+ if !berkshelf_enabled?(env)
9
+ @logger.info "Berkshelf disabled, skipping"
10
+ return @app.call(env)
11
+ end
12
+
13
+ if !provision_enabled?(env)
14
+ @logger.info "Provisioning disabled, skipping"
15
+ return @app.call(env)
16
+ end
17
+
18
+ vendor(env)
19
+ @app.call(env)
20
+ end
21
+
22
+ # Vendor the cookbooks in the Berkshelf shelf.
23
+ def vendor(env)
24
+ shelf = env[:berkshelf].shelf
25
+ env[:machine].ui.info "Updating Vagrant's Berkshelf..."
26
+
27
+ options = env[:machine].config.berkshelf.to_hash
28
+
29
+ result = berks('vendor', shelf, options)
30
+ env[:machine].ui.output(result.stdout)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'base'
2
+
3
+ module VagrantPlugins
4
+ module Berkshelf
5
+ module Action
6
+ class Load < Base
7
+ def call(env)
8
+ if !berkshelf_enabled?(env)
9
+ @logger.info "Berkshelf disabled, skipping"
10
+ return @app.call(env)
11
+ end
12
+
13
+ if File.exist?(datafile_path(env))
14
+ env[:machine].ui.info "Loading Berkshelf datafile..."
15
+ shelf = File.read(datafile_path(env)).chomp
16
+
17
+ @logger.debug "Shelf: #{shelf.inspect}"
18
+
19
+ env[:berkshelf].shelf = shelf
20
+ end
21
+
22
+ if !env[:berkshelf].shelf
23
+ shelf = mkshelf(env)
24
+ env[:machine].ui.detail "The Berkshelf shelf is at #{shelf.inspect}"
25
+
26
+ @logger.debug "Persisting datafile share to memory"
27
+ env[:berkshelf].shelf = shelf
28
+ end
29
+
30
+ @app.call(env)
31
+ end
32
+
33
+ # Create a new Berkshelf shelf for the current machine.
34
+ # @return [String]
35
+ # the path to the temporary directory
36
+ def mkshelf(env)
37
+ shelves = Berkshelf.shelves_path
38
+
39
+ if !File.exist?(shelves)
40
+ FileUtils.mkdir_p(shelves)
41
+ end
42
+
43
+ Dir.mktmpdir(['berkshelf', "-#{env[:machine].name}"], shelves)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'base'
2
+
3
+ module VagrantPlugins
4
+ module Berkshelf
5
+ module Action
6
+ class Save < Base
7
+ def call(env)
8
+ if !berkshelf_enabled?(env)
9
+ @logger.info "Berkshelf disabled, skipping"
10
+ return @app.call(env)
11
+ end
12
+
13
+ if env[:berkshelf].shelf
14
+ @logger.debug "Saving datafile to disk"
15
+ FileUtils.mkdir_p(datafile_path(env).dirname)
16
+ datafile_path(env).open("w+") do |f|
17
+ f.write(env[:berkshelf].shelf)
18
+ end
19
+ end
20
+
21
+ @app.call(env)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,33 @@
1
+ require_relative 'base'
2
+
3
+ module VagrantPlugins
4
+ module Berkshelf
5
+ module Action
6
+ class Share < Base
7
+ def call(env)
8
+ if !berkshelf_enabled?(env)
9
+ @logger.info "Berkshelf disabled, skipping"
10
+ return @app.call(env)
11
+ end
12
+
13
+ if !chef_solo?(env) && !chef_zero?(env)
14
+ @logger.info "Provisioner does not need a share"
15
+ return @app.call(env)
16
+ end
17
+
18
+ env[:machine].ui.info "Sharing cookbooks with VM"
19
+
20
+ list = provisioners(:chef_solo, env) + provisioners(:chef_zero, env)
21
+ list.each do |chef|
22
+ value = chef.config.send(:prepare_folders_config, env[:berkshelf].shelf)
23
+
24
+ @logger.debug "Setting cookbooks_path = #{value.inspect}"
25
+ chef.config.cookbooks_path = value + Array(chef.config.cookbooks_path)
26
+ end
27
+
28
+ @app.call(env)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,99 @@
1
+ require 'json'
2
+ require 'tempfile'
3
+
4
+ require_relative 'base'
5
+
6
+ module VagrantPlugins
7
+ module Berkshelf
8
+ module Action
9
+ class Upload < Base
10
+ def call(env)
11
+ if !berkshelf_enabled?(env)
12
+ @logger.info "Berkshelf disabled, skipping"
13
+ return @app.call(env)
14
+ end
15
+
16
+ if !provision_enabled?(env)
17
+ @logger.info "Provisioning disabled, skipping"
18
+ return @app.call(env)
19
+ end
20
+
21
+ if !chef_client?(env)
22
+ @logger.info "Provisioner does need to upload"
23
+ return @app.call(env)
24
+ end
25
+
26
+ upload(env)
27
+ @app.call(env)
28
+ end
29
+
30
+ private
31
+
32
+ # Generate a custom Berkshelf config from the existing Berkshelf
33
+ # config on disk, with values in the Vagrantfile taking precedence,
34
+ # based on the current provisioner. It is assumed the provisioner is
35
+ # the "chef_client" provisioner.
36
+ #
37
+ # The path to the temporary configuration file is yielded to the
38
+ # block. This method ensures the temporary file is cleaned up
39
+ # automatically.
40
+ #
41
+ # @param [Vagrant::Provisioner] provisioner
42
+ # @param [Proc] block
43
+ def with_provision_berkshelf_config(provisioner, &block)
44
+ config = current_berkshelf_config
45
+
46
+ config[:chef] ||= {}
47
+ config[:chef].merge(
48
+ chef_server_url: provisioner.config.chef_server_url,
49
+ node_name: provisioner.config.node_name,
50
+ client_key: provisioner.config.client_key_path,
51
+ validation_key: provisioner.config.validation_key_path,
52
+ validation_client_name: provisioner.config.validation_client_name,
53
+ )
54
+
55
+ tmpfile = Tempfile.new('config.json')
56
+ tmpfile.write(config.to_json)
57
+ tmpfile.rewind
58
+ yield tmpfile.path
59
+ ensure
60
+ if defined?(tmpfile) && !tmpfile.nil?
61
+ tmpfile.close
62
+ tmpfile.unlink
63
+ end
64
+ end
65
+
66
+ # The current JSON representation of the Berkshelf config on disk.
67
+ #
68
+ # @return [Hash<Symbol, Object>]
69
+ def current_berkshelf_config
70
+ path = File.expand_path(ENV['BERKSHELF_CONFIG'] || '~/.berkshelf/config.json')
71
+
72
+ if File.exist?(path)
73
+ JSON.parse(File.read(path), symbolize_names: true)
74
+ else
75
+ {}
76
+ end
77
+ end
78
+
79
+ # Upload the resolved Berkshelf cookbooks to the target Chef Server
80
+ # specified in the Vagrantfile.
81
+ #
82
+ # @param [Vagrant::Environment] env
83
+ def upload(env)
84
+ provisioners(:chef_client, env).each do |provisioner|
85
+ with_provision_berkshelf_config(provisioner) do |config|
86
+ env[:machine].ui.info "Uploading cookbooks to #{provisioner.config.chef_server_url}"
87
+ berks("upload",
88
+ config: config,
89
+ berksfile_path: env[:machine].config.berkshelf.berksfile_path,
90
+ force: true,
91
+ freeze: false,
92
+ )
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,107 @@
1
+ require 'pathname'
2
+ require 'vagrant/util/hash_with_indifferent_access'
3
+
4
+ module VagrantPlugins
5
+ module Berkshelf
6
+ class Config < Vagrant.plugin("2", :config)
7
+ MAYBE = Object.new.freeze
8
+
9
+ # The path to the Berksfile to use.
10
+ # @return [String]
11
+ attr_accessor :berksfile_path
12
+
13
+ # Disable the use of Berkshelf in Vagrant.
14
+ # @return [Boolean]
15
+ attr_accessor :enabled
16
+
17
+ # The array of cookbook groups to exclusively install during provisioning.
18
+ # @return [Array<Symbol>]
19
+ attr_accessor :only
20
+
21
+ # The array of cookbook groups to exclude during provisioning.
22
+ # @return [Array<Symbol>]
23
+ attr_accessor :except
24
+
25
+ # An array of additional arguments to pass to the Berkshelf command.
26
+ # @return [Array<String>]
27
+ attr_accessor :args
28
+
29
+ def initialize
30
+ super
31
+
32
+ @berksfile_path = UNSET_VALUE
33
+ @enabled = UNSET_VALUE
34
+ @except = Array.new
35
+ @only = Array.new
36
+ @args = Array.new
37
+
38
+ @__finalized = false
39
+ end
40
+
41
+ def finalize!
42
+ @berksfile_path = nil if @berksfile_path == UNSET_VALUE
43
+ @enabled = MAYBE if @enabled == UNSET_VALUE
44
+
45
+ @__finalized = true
46
+ end
47
+
48
+ def validate(machine)
49
+ errors = _detected_errors
50
+
51
+ if @enabled || @enabled == MAYBE
52
+ # If no Berksfile path was given, check if one is in the working
53
+ # directory
54
+ if !@berksfile_path
55
+ path = File.expand_path("Berksfile", machine.env.root_path)
56
+
57
+ if File.exist?(path)
58
+ @enabled = true
59
+ @berksfile_path = path
60
+ else
61
+ # Disable the plugin unless it was specifically set to "true". If
62
+ # the user set the value, we want to return an error, but if the
63
+ # user did not explicitly enable the plugin, we should just
64
+ # disable it automatically.
65
+ @enabled = false unless @enabled == true
66
+ end
67
+ end
68
+
69
+ if @enabled
70
+ # Berksfile_path validations
71
+ if missing?(@berksfile_path)
72
+ errors << "berksfile_path must be set"
73
+ else
74
+ # Expand the path unless it is absolute
75
+ if !Pathname.new(@berksfile_path).absolute?
76
+ @berksfile_path = File.expand_path(@berksfile_path, machine.env.root_path)
77
+ end
78
+
79
+ # Ensure the path exists
80
+ if !File.exist?(@berksfile_path)
81
+ errors << "Berksfile at '#{@berksfile_path}' does not exist"
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ { "Berkshelf" => errors }
88
+ end
89
+
90
+ def to_hash
91
+ raise "Must finalize first." if !@__finalized
92
+
93
+ {
94
+ enabled: @enabled,
95
+ berksfile_path: @berksfile_path,
96
+ except: @except,
97
+ only: @only,
98
+ args: @args,
99
+ }
100
+ end
101
+
102
+ def missing?(obj)
103
+ obj.to_s.strip.empty?
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,14 @@
1
+ require 'vagrant/ui'
2
+
3
+ module VagrantPlugins
4
+ module Berkshelf
5
+ class Env
6
+ # @return [String]
7
+ attr_accessor :shelf
8
+
9
+ def initialize
10
+ @shelf = nil
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ require 'vagrant/errors'
2
+
3
+ module VagrantPlugins
4
+ module Berkshelf
5
+ class BerkshelfNotFound < Vagrant::Errors::VagrantError
6
+ def error_message
7
+ "Vagrant Berkshelf could not find the 'berks' executable in your PATH."
8
+ end
9
+ end
10
+
11
+ class BerksCommandFailed < Vagrant::Errors::VagrantError
12
+ def initialize(command, stdout, stderr)
13
+ @command, @stdout, @stderr = command, stdout, stderr
14
+ super
15
+ end
16
+
17
+ def error_message
18
+ base = <<-EOH
19
+ The following berks command failed to execute:
20
+
21
+ #{@command}
22
+
23
+ The stdout and stderr are shown below:
24
+
25
+ stdout: #{@stdout}
26
+ stderr: #{@stderr}
27
+ EOH
28
+
29
+ base
30
+ end
31
+ end
32
+
33
+ class InvalidBerkshelfVersionError < Vagrant::Errors::VagrantError
34
+ def initialize(bin, constraint, version)
35
+ @bin = bin
36
+ @constraint = constraint
37
+ @version = version
38
+ super
39
+ end
40
+
41
+ def error_message
42
+ <<-EOH
43
+ The Berkshelf version at #{@bin.inspect} is invalid.
44
+ Vagrant Berkshelf requires #{@constraint}, but the current version is #{@version}.
45
+ EOH
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,150 @@
1
+ require 'json'
2
+ require 'open3'
3
+ require 'vagrant/util'
4
+
5
+ require_relative 'errors'
6
+
7
+ module VagrantPlugins
8
+ module Berkshelf
9
+ # A module of common helper functions that can be mixed into Berkshelf::Vagrant actions
10
+ module Helpers
11
+ include Vagrant::Util
12
+
13
+ # Execute a berkshelf command with the given arguments and flags.
14
+ #
15
+ # @overload berks(command, args)
16
+ # @param [String] berks CLI command to run
17
+ # @param [Object] any number of arguments to pass to CLI
18
+ # @overload berks(command, args, options)
19
+ # @param [String] berks CLI command to run
20
+ # @param [Object] any number of arguments to pass to CLI
21
+ # @param [Hash] options to convert to flags for the CLI
22
+ #
23
+ # @return [String]
24
+ # output of the command
25
+ #
26
+ # @raise [InvalidBerkshelfVersionError]
27
+ # version of Berks installed does not satisfy the application's constraint
28
+ # @raise [BerksNotFoundError]
29
+ # berks command is not found in the user's path
30
+ def berks(command, *args)
31
+ options = args.last.is_a?(Hash) ? args.pop : {}
32
+ args = args.dup
33
+
34
+ if options[:berksfile_path]
35
+ args << "--berksfile"
36
+ args << options[:berksfile_path]
37
+ end
38
+
39
+ if !options.fetch(:except, []).empty?
40
+ args << "--except"
41
+ args += options[:except]
42
+ end
43
+
44
+ if !options.fetch(:only, []).empty?
45
+ args << "--only"
46
+ args += options[:only]
47
+ end
48
+
49
+ if options[:freeze] == false
50
+ args << "--no-freeze"
51
+ end
52
+
53
+ if options[:force]
54
+ args << "--force"
55
+ end
56
+
57
+ if !options.fetch(:args, []).empty?
58
+ args += options[:args]
59
+ end
60
+
61
+ final_command = [berks_bin, command, *args]
62
+
63
+ sanitized_env = ENV.to_h.merge('GEM_HOME' => nil, 'GEM_PATH' => nil)
64
+ command = final_command.join(' ')
65
+ out, err, status = Open3.capture3(sanitized_env, command)
66
+ raise BerksCommandFailed.new(command, out, err) unless status.success?
67
+ OpenStruct.new(stdout: out, stderr: err)
68
+ end
69
+
70
+ # The path to the Berkshelf binary on disk.
71
+ # @return [String, nil]
72
+ def berks_bin
73
+ Which.which("berks")
74
+ end
75
+
76
+ # Filter all of the provisioners of the given vagrant environment with the given name
77
+ #
78
+ # @param [Symbol] name
79
+ # name of provisioner to filter
80
+ # @param [Vagrant::Environment, Hash] env
81
+ # environment to inspect
82
+ #
83
+ # @return [Array]
84
+ def provisioners(type, env)
85
+ env[:machine].config.vm.provisioners.select do |provisioner|
86
+ # Vagrant 1.7 changes provisioner.name to provisioner.type
87
+ if provisioner.respond_to? :type
88
+ provisioner.type.to_sym == type
89
+ else
90
+ provisioner.name.to_sym == type
91
+ end
92
+ end
93
+ end
94
+
95
+ # Determine if the given vagrant environment contains a chef_solo provisioner
96
+ #
97
+ # @param [Vagrant::Environment] env
98
+ #
99
+ # @return [Boolean]
100
+ def chef_solo?(env)
101
+ provisioners(:chef_solo, env).any?
102
+ end
103
+
104
+ # Determine if the given vagrant environment contains a chef_zero provisioner
105
+ #
106
+ # @param [Vagrant::Environment] env
107
+ #
108
+ # @return [Boolean]
109
+ def chef_zero?(env)
110
+ provisioners(:chef_zero, env).any?
111
+ end
112
+
113
+ # Determine if the given vagrant environment contains a chef_client provisioner
114
+ #
115
+ # @param [Vagrant::Environment] env
116
+ #
117
+ # @return [Boolean]
118
+ def chef_client?(env)
119
+ provisioners(:chef_client, env).any?
120
+ end
121
+
122
+ # Determine if the Berkshelf plugin should be run for the given environment
123
+ #
124
+ # @param [Vagrant::Environment] env
125
+ #
126
+ # @return [Boolean]
127
+ def berkshelf_enabled?(env)
128
+ env[:machine].config.berkshelf.enabled == true
129
+ end
130
+
131
+ # Determine if --no-provision was specified
132
+ #
133
+ # @param [Vagrant::Environment] env
134
+ #
135
+ # @return [Boolean]
136
+ def provision_enabled?(env)
137
+ env.fetch(:provision_enabled, true)
138
+ end
139
+
140
+ # The path to the Vagrant Berkshelf data file inside the machine's data
141
+ # directory.
142
+ #
143
+ # @return [String]
144
+ def datafile_path(env)
145
+ env[:machine].data_dir.join("berkshelf")
146
+ end
147
+
148
+ end
149
+ end
150
+ end