1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
#
# The Leapfile is the bootstrap configuration file for a LEAP provider.
#
# It is akin to a Gemfile, Rakefile, or Capfile (e.g. it is a ruby file that gets eval'ed)
#
# Additional configuration options are defined in platform's leapfile_extensions.rb
#
module LeapCli
def self.leapfile
@leapfile ||= Leapfile.new
end
class Leapfile
attr_reader :platform_directory_path
attr_reader :provider_directory_path
attr_reader :environment
def initialize
end
#
# The way the Leapfile handles pinning of environment (self.environment) is a little tricky.
# If self.environment is nil, then there is no pin. If self.environment is 'default', then
# there is a pin to the default environment. The problem is that an environment of nil
# is used to indicate the default environment in node properties.
#
# This method returns the environment tag as needed when filtering nodes.
#
def environment_filter
if self.environment == 'default'
nil
else
self.environment
end
end
def load(search_directory=nil)
directory = File.expand_path(find_in_directory_tree('Leapfile', search_directory))
if directory == '/'
return nil
else
#
# set up paths
#
@provider_directory_path = directory
begin
# load leaprc first, so that we can potentially access which environment is pinned in Leapfile
# but also load leaprc last, so that it can override what is set in Leapfile.
read_settings(leaprc_path)
rescue StandardError
end
read_settings(directory + '/Leapfile')
read_settings(leaprc_path)
@platform_directory_path = File.expand_path(@platform_directory_path || '../leap_platform', @provider_directory_path)
#
# load the platform
#
platform_class = "#{@platform_directory_path}/lib/leap/platform"
platform_definition = "#{@platform_directory_path}/platform.rb"
unless File.exist?(platform_definition)
Util.bail! "ERROR: The file `#{platform_file}` does not exist. Please check the value of `@platform_directory_path` in `Leapfile` or `~/.leaprc`."
end
require platform_class
require platform_definition
begin
Leap::Platform.validate!(LeapCli::VERSION, LeapCli::COMPATIBLE_PLATFORM_VERSION, self)
rescue StandardError => exc
Util.bail! exc.to_s
end
leapfile_extensions = "#{@platform_directory_path}/lib/leap_cli/leapfile_extensions.rb"
if File.exist?(leapfile_extensions)
require leapfile_extensions
end
#
# validate
#
instance_variables.each do |var|
var = var.to_s.sub('@', '')
if !self.respond_to?(var)
LeapCli.log :warning, "the variable `#{var}` is set in .leaprc or Leapfile, but it is not supported."
end
end
@valid = validate
return @valid
end
end
def set(property, value)
edit_leaprc(property, value)
end
def unset(property)
edit_leaprc(property)
end
def valid?
!!@valid
end
private
#
# adds or removes a line to .leaprc for this particular provider directory.
# if value is nil, the line is removed. if not nil, it is added or replaced.
#
def edit_leaprc(property, value=nil)
file_path = leaprc_path
lines = []
if File.exist?(file_path)
regexp = /self\.#{Regexp.escape(property)} = .*? if @provider_directory_path == '#{Regexp.escape(@provider_directory_path)}'/
File.readlines(file_path).each do |line|
unless line =~ regexp
lines << line
end
end
end
unless value.nil?
lines << "self.#{property} = #{value.inspect} if @provider_directory_path == '#{@provider_directory_path}'\n"
end
File.open(file_path, 'w') do |f|
f.write(lines.join)
end
rescue Errno::EACCES, IOError => exc
Util::bail! :error, "trying to save ~/.leaprc (#{exc})."
end
def leaprc_path
File.join(ENV['HOME'], '.leaprc')
end
def read_settings(file)
if File.exist? file
LeapCli.log 2, :read, file
instance_eval(File.read(file), file)
end
end
def find_in_directory_tree(filename, directory_tree=nil)
search_dir = directory_tree || Dir.pwd
while search_dir != "/"
Dir.foreach(search_dir) do |f|
return search_dir if f == filename
end
search_dir = File.dirname(search_dir)
end
return search_dir
end
# to be overridden
def validate
return true
end
def method_missing(method, *args)
if method =~ /=$/
self.instance_variable_set('@' + method.to_s.sub('=',''), args.first)
else
self.instance_variable_get('@' + method.to_s)
end
end
end
end
|