vagrant-berkshelf-nochefdk 6.0.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 +7 -0
- data/.gitignore +39 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +8 -0
- data/CONTRIBUTING.md +51 -0
- data/Gemfile +43 -0
- data/Guardfile +16 -0
- data/LICENSE +13 -0
- data/README.md +89 -0
- data/Rakefile +14 -0
- data/lib/vagrant-berkshelf-nochefdk.rb +17 -0
- data/lib/vagrant-berkshelf/action/base.rb +49 -0
- data/lib/vagrant-berkshelf/action/check.rb +49 -0
- data/lib/vagrant-berkshelf/action/clean.rb +29 -0
- data/lib/vagrant-berkshelf/action/install.rb +35 -0
- data/lib/vagrant-berkshelf/action/load.rb +48 -0
- data/lib/vagrant-berkshelf/action/save.rb +27 -0
- data/lib/vagrant-berkshelf/action/share.rb +33 -0
- data/lib/vagrant-berkshelf/action/upload.rb +99 -0
- data/lib/vagrant-berkshelf/config.rb +107 -0
- data/lib/vagrant-berkshelf/env.rb +14 -0
- data/lib/vagrant-berkshelf/errors.rb +49 -0
- data/lib/vagrant-berkshelf/helpers.rb +150 -0
- data/lib/vagrant-berkshelf/plugin.rb +41 -0
- data/lib/vagrant-berkshelf/version.rb +5 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/unit/vagrant-berkshelf/config_spec.rb +158 -0
- data/vagrant-berkshelf-nochefdk.gemspec +37 -0
- metadata +137 -0
@@ -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,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
|