forj 1.0.1 → 1.0.2

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.gitreview +4 -0
  4. data/Gemfile +21 -19
  5. data/Gemfile.lock +71 -0
  6. data/bin/forj +126 -83
  7. data/forj.gemspec +64 -0
  8. data/{lib → forj}/defaults.yaml +23 -1
  9. data/lib/appinit.rb +5 -5
  10. data/lib/build_tmpl/build-env.py +293 -0
  11. data/lib/cloud_test.rb +121 -0
  12. data/lib/forj-settings.rb +52 -39
  13. data/lib/forj/ForjCli.rb +11 -10
  14. data/lib/forj/ForjCore.rb +8 -6
  15. data/lib/forj/process/ForjProcess.rb +345 -82
  16. data/lib/ssh.rb +81 -20
  17. metadata +110 -80
  18. data/lib/compute.rb +0 -36
  19. data/lib/connection.rb +0 -144
  20. data/lib/down.rb +0 -60
  21. data/lib/forj-account.rb +0 -294
  22. data/lib/forj-config.rb +0 -522
  23. data/lib/helpers.rb +0 -56
  24. data/lib/lib-forj/lib/core/core.rb +0 -1740
  25. data/lib/lib-forj/lib/core/definition.rb +0 -441
  26. data/lib/lib-forj/lib/core/definition_internal.rb +0 -306
  27. data/lib/lib-forj/lib/core_process/CloudProcess.rb +0 -334
  28. data/lib/lib-forj/lib/core_process/global_process.rb +0 -406
  29. data/lib/lib-forj/lib/core_process/network_process.rb +0 -603
  30. data/lib/lib-forj/lib/lib-forj.rb +0 -37
  31. data/lib/lib-forj/lib/providers/hpcloud/Hpcloud.rb +0 -419
  32. data/lib/lib-forj/lib/providers/hpcloud/compute.rb +0 -108
  33. data/lib/lib-forj/lib/providers/hpcloud/network.rb +0 -117
  34. data/lib/lib-forj/lib/providers/hpcloud/security_groups.rb +0 -67
  35. data/lib/lib-forj/lib/providers/templates/compute.rb +0 -42
  36. data/lib/lib-forj/lib/providers/templates/core.rb +0 -61
  37. data/lib/lib-forj/lib/providers/templates/network.rb +0 -33
  38. data/lib/log.rb +0 -162
  39. data/lib/network.rb +0 -365
  40. data/lib/repositories.rb +0 -222
  41. data/lib/security.rb +0 -207
  42. data/lib/ssh.sh +0 -185
  43. data/spec/connection_spec.rb +0 -52
  44. data/spec/forj-config_spec.rb +0 -237
  45. data/spec/repositories_spec.rb +0 -50
data/lib/network.rb DELETED
@@ -1,365 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
-
18
- require 'rubygems'
19
- require 'require_relative'
20
-
21
- require_relative 'connection.rb'
22
-
23
-
24
- #
25
- # Network module
26
- #
27
- module Network
28
-
29
- # Network management
30
- def get_or_create_network(oFC, name)
31
- Logging.state("Searching for network '%s'" % [name])
32
- network = get_network(oFC, name)
33
- if not network
34
- network = create_network(oFC, name)
35
- end
36
- network
37
- end
38
-
39
- def get_network(oFC, name)
40
- begin
41
- networks = oFC.oNetwork.networks.all(:name => name)
42
- case networks.length()
43
- when 0
44
- Logging.debug("No network found")
45
- nil
46
- when 1
47
- Logging.debug("Found network '%s'" % [networks[0].name])
48
- networks[0]
49
- else
50
- Logging.warning("Several network was found with '%s'. Selecting the first one '%s'." % [name, networks[0].name])
51
- networks[0]
52
- end
53
- rescue => e
54
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
55
- end
56
- end
57
-
58
- def create_network(oFC, name)
59
- begin
60
- Logging.debug('creating network %s' % [name])
61
- oFC.oNetwork.networks.create(:name => name)
62
- rescue => e
63
- Logging.fatal(1, "Unable to create '%s'network" % name, e)
64
- end
65
- end
66
-
67
- def delete_network(oFC, network_name)
68
- begin
69
- network = get_network(oFC, network_name)
70
- oFC.oNetwork.networks.get(network.id).destroy
71
- rescue => e
72
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
73
- end
74
- end
75
-
76
-
77
- # Subnet management
78
- def get_or_create_subnet(oFC, network_id, name)
79
- Logging.state("Searching for sub-network attached '%s'." % [name])
80
- begin
81
- subnets = oFC.oNetwork.subnets.all(:network_id => network_id)
82
- rescue => e
83
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
84
- end
85
- if subnets
86
- case subnets.length()
87
- when 0
88
- Logging.debug("No subnet found from '%s' network" % [name])
89
- subnet = nil
90
- when 1
91
- Logging.debug("Found '%s' subnet from '%s' network" % [subnets[0].name, name])
92
- subnet = subnets[0]
93
- else
94
- Logging.warning("Several subnet was found on '%s'. Choosing the first one = '%s'" % [name, subnets[0].name])
95
- subnet = subnets[0]
96
- end
97
- end
98
- if not subnet
99
- # Create the subnet with 'sub-' prefixing the network name.
100
- begin
101
- subnet = create_subnet(oFC, network_id, 'sub-%s' % [name])
102
- rescue => e
103
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
104
- end
105
- end
106
- return subnet
107
- end
108
-
109
- def create_subnet(oFC, network_id, name)
110
- Logging.debug("Creating subnet '%s'" % [name])
111
- begin
112
- oFC.oNetwork.subnets.create(
113
- :network_id => network_id,
114
- :name => name,
115
- :cidr => get_next_subnet(oFC),
116
- :ip_version => '4'
117
- )
118
- rescue => e
119
- Logging.fatal(1, "Unable to create '%s' subnet." % name, e)
120
- end
121
- end
122
-
123
- def delete_subnet(oFC, subnet)
124
- Logging.debug("Deleting subnet '%s'" % [subnet.name])
125
- begin
126
- oFC.oNetwork.subnets.get(subnet.id).destroy
127
- rescue => e
128
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
129
- end
130
- end
131
-
132
- def get_subnet(oFC, name)
133
- begin
134
- oFC.oNetwork.subnets.all(:name => name)[0]
135
- rescue => e
136
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
137
- end
138
- end
139
-
140
-
141
- # Router management
142
- def get_or_create_router(oFC, network, subnet)
143
- port = get_router_interface_attached(oFC, network)
144
- if not port
145
- # Trying to get router
146
- router = get_router(oFC, 'router-%s' % network.name)
147
- router = create_router(oFC, 'router-%s' % network.name) if not router
148
- create_router_interface(subnet, router) if router
149
- else
150
- routers = oFC.oNetwork.routers.all({:id => port.device_id})
151
- if routers.length() == 1
152
- if routers[0].external_gateway_info
153
- Logging.debug("Found router '%s' attached to an external gateway." % [ routers[0].name ] )
154
- else
155
- Logging.debug("Found router '%s' but need to be attached to an external gateway. Attaching..." % [ routers[0].name ] )
156
- netty=search_gateway(oFC)
157
- if netty
158
- routers[0].external_gateway_info = { 'network_id' => netty.id }
159
- routers[0].save
160
- Logging.debug("Router '%s' attached to the external network '%s'." % [ routers[0].name, netty.name ] )
161
- else
162
- Logging.fatal(1, "Unable to attach router '%s' to an external gateway. Required for boxes to get internet access. " % [ routers[0].name ] )
163
- end
164
- end
165
- router = routers[0]
166
- else
167
- Logging.warning("Unable to find the router id '%s'" % [ port.device_id ])
168
- router = nil
169
- end
170
- end
171
- router
172
- end
173
-
174
- def get_router(oFC, name)
175
- Logging.state("Searching for router '%s'..." % [name] )
176
- begin
177
- routers = oFC.oNetwork.routers.all({:name => name})
178
- if routers.length() == 1
179
- if routers[0].external_gateway_info.has_key?('id')
180
- Logging.debug("Found router '%s' attached to an external gateway." % [ routers[0].name ] )
181
- else
182
- Logging.warning("Found router '%s' but not attached to an external." % [ routers[0].name ] )
183
- end
184
- routers[0]
185
- else
186
- Logging.debug("Router '%s' not found." % [ name ] )
187
- nil
188
- end
189
- rescue => e
190
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
191
- end
192
- end
193
-
194
- def create_router(oFC, name)
195
-
196
- netty = search_gateway(oFC)
197
-
198
- begin
199
- if netty
200
- Logging.debug("Creating router '%s' attached to the external Network '%s'." % [name, netty.name])
201
- oFC.oNetwork.routers.create(
202
- :name => name,
203
- :admin_state_up => true,
204
- :external_gateway_info => { 'network_id' => netty.id }
205
- )
206
- else
207
- Logging.debug("Creating router '%s' without external Network." % [name])
208
- oFC.oNetwork.routers.create(
209
- :name => name,
210
- :admin_state_up => true
211
- )
212
- end
213
- rescue => e
214
- Logging.fatal(1, "Unable to create '%s' router" % name, e)
215
- end
216
- end
217
-
218
- def delete_router(oFC, router_id)
219
- Logging.debug("Deleting router '%s'" % [router.name])
220
- begin
221
- oFC.oNetwork.routers.get(router.id).destroy
222
- rescue => e
223
- Logging.error("Unable to delete '%s' router ID" % router_id, e)
224
- end
225
- end
226
-
227
-
228
- # Router interface to connect to the network
229
- def create_router_interface(subnet, router)
230
- Logging.fatal(1, "Internal Error: subnet/router object not passed.") if not subnet or not router
231
-
232
- Logging.debug("Attaching subnet '%s' to router '%s'" % [subnet.name, router.name])
233
- begin
234
- router.add_interface(subnet.id, nil)
235
- rescue => e
236
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
237
- end
238
- end
239
-
240
- def delete_router_interface(subnet_id, router)
241
- Logging.debug("Removing subnet '%s' from router '%s'" % [subnet.name, router.name])
242
- begin
243
- router.remove_interface(subnet_id)
244
- rescue => e
245
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
246
- end
247
- end
248
-
249
- def get_router_interface(oFC, network_id, device_id)
250
- begin
251
- # Searching for router port attached
252
- ports=oFC.oNetwork.ports.all({:network_id => network_id, :device_id => device_id})
253
- case ports.length()
254
- when 0
255
- nil
256
- else
257
- port[0]
258
- end
259
- rescue => e
260
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
261
- end
262
- end
263
-
264
- def get_router_interface_attached(oFC, network)
265
- Logging.state("Searching for router port attached to the network '%s'" % [network.name] )
266
- begin
267
- # Searching for router port attached
268
- ports=oFC.oNetwork.ports.all({:network_id => network.id, :device_type => 'network:router_interface'})
269
- case ports.length()
270
- when 0
271
- Logging.debug("No router port attached to the network '%s'" % [network.name] )
272
- nil
273
- else
274
- Logging.debug("Found a router port attached to the network '%s' " % [network.name] )
275
- ports[0]
276
- end
277
- rescue => e
278
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
279
- end
280
- end
281
-
282
- # Gateway management
283
- def get_gateway(oFC, name)
284
-
285
- return nil if not name or not oFC
286
-
287
- Logging.state("Getting gateway '%s'" % [name])
288
- networks = oFC.oNetwork
289
- begin
290
- netty = networks.get(name)
291
- rescue => e
292
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
293
- end
294
- Logging.state("Found gateway '%s'" % [name]) if netty
295
- Logging.state("Unable to find gateway '%s'" % [name]) if not netty
296
- return netty
297
- end
298
-
299
- def search_gateway(oFC)
300
- Logging.state("Identifying External gateway ...")
301
- begin
302
- # Searching for router port attached
303
- networks=oFC.oNetwork.networks.all({ :router_external => true })
304
- case networks.length()
305
- when 0
306
- Logging.debug("No external network")
307
- nil
308
- when 1
309
- Logging.debug("Found external network '%s'." % [networks[0].name] )
310
- networks[0]
311
- else
312
- Logging.debug("Found several external networks. Selecting the first one '%s'" % [networks[0].name] )
313
- networks[0]
314
- end
315
- rescue => e
316
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
317
- end
318
- end
319
-
320
- end
321
-
322
-
323
- def get_next_subnet(oFC)
324
- begin
325
- subnet_values = Array.new
326
- subnets = oFC.oNetwork.subnets.all
327
-
328
- subnets.each do|s|
329
- subnet_values.push(s.cidr)
330
- end
331
-
332
- gap = false
333
- count = 0
334
- range_used = Array.new
335
- new_subnet = 0
336
- new_cidr = ''
337
-
338
- subnet_values = subnet_values.sort!
339
-
340
- subnet_values.each do|value|
341
- range_used.push(value[5])
342
- end
343
-
344
- range_used.each do |n|
345
- if count.to_i == n.to_i
346
- else
347
- new_subnet = count
348
- gap = true
349
- break
350
- end
351
- count += 1
352
- end
353
-
354
- if gap
355
- new_cidr = '10.0.%s.0/24' % [count]
356
- else
357
- max_value = range_used.max
358
- new_subnet = max_value.to_i + 1
359
- new_cidr = '10.0.%s.0/24' % [new_subnet]
360
- end
361
- new_cidr
362
- rescue => e
363
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
364
- end
365
- end
data/lib/repositories.rb DELETED
@@ -1,222 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
-
18
- require 'rubygems'
19
- require 'git'
20
- require 'fileutils'
21
-
22
- #
23
- # Repositories module
24
- #
25
-
26
- # Current version of the infra. Compatible with forj version or higher.
27
- $INFRA_VERSION = "0.0.37"
28
-
29
- module Repositories
30
- def clone_repo(maestro_url, oConfig)
31
- current_dir = Dir.pwd
32
-
33
- home = File.expand_path('~')
34
- path = home + '/.forj/'
35
-
36
- begin
37
- if File.directory?(path)
38
- if File.directory?(path + 'maestro')
39
- FileUtils.rm_r path + 'maestro'
40
- end
41
- git = Git.clone(maestro_url, 'maestro', :path => path)
42
- git.checkout(oConfig[:branch]) if oConfig[:branch] != 'master'
43
- Logging.info("Maestro repo '%s' cloned on branch '%s'" % [path, oConfig[:branch]])
44
- end
45
- rescue => e
46
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
47
- puts 'Error while cloning the repo from %s' % [maestro_url]
48
- puts 'If this error persist you could clone the repo manually in ~/.forj/'
49
- end
50
- Dir.chdir(current_dir)
51
- end
52
-
53
- def ensure_build_env_file(maestro_url, maestro_repo, branch)
54
- infra = File.join($FORJ_DATA_PATH, 'infra')
55
- template = File.join(maestro_repo, 'templates', 'infra')
56
-
57
- template_file = 'maestro.box.master.env'
58
- env_file = 'maestro.box.' + branch + '.env'
59
-
60
- source_build_env = File.join(template, template_file)
61
- dest_build_env = File.join(infra, env_file)
62
-
63
- if not File.exist?(source_build_env)
64
- raise <<-END
65
- Your Maestro repository branch is too old.
66
- Suggestion:
67
- 1. Clone #{maestro_url} to a different location.
68
- $ mkdir -p ~/src/forj-oss
69
- $ cd ~/src/forj-oss
70
- $ git clone #{maestro_url}
71
- 2. Use this master branch of maestro repository with forj
72
- $ forj set maestro_repo=~/src/forj-oss/maestro
73
-
74
- then retry your boot.
75
- END
76
- end
77
- return if File.exist?(dest_build_env)
78
-
79
- Logging.info("Creating '%s' to '%s'" % [source_build_env, dest_build_env])
80
- FileUtils.copy(source_build_env, dest_build_env)
81
- end
82
-
83
- def create_infra(maestro_repo, branch)
84
- # Build our own infra from maestro infra templates.
85
- infra = File.join($FORJ_DATA_PATH, 'infra')
86
- dest_cloud_init = File.join(infra, 'cloud-init')
87
- template = File.join(maestro_repo, 'templates', 'infra')
88
- cloud_init = File.join(template, 'cloud-init')
89
-
90
- if File.directory?(infra)
91
- Logging.debug("Cleaning up '%s'" % [infra])
92
- FileUtils.rm_r(infra)
93
- end
94
- AppInit.ensure_dir_exists(dest_cloud_init)
95
- if not File.exist?(cloud_init)
96
- raise <<-END
97
- Your Maestro repository branch is too old.
98
- Suggestion:
99
- 1. Clone %s to a different location.
100
- $ mkdir -p ~/src/forj-oss
101
- $ cd ~/src/forj-oss
102
- $ git clone %s
103
- 2. Use this master branch of maestro repository with forj
104
- $ forj set maestro_repo=~/src/forj-oss/maestro
105
-
106
- then retry your boot.
107
- END
108
- end
109
- Logging.debug("Copying recursively '%s' to '%s'" % [cloud_init, infra])
110
- FileUtils.copy_entry(cloud_init, dest_cloud_init)
111
-
112
- file_ver = File.join(infra, 'forj-cli.ver')
113
- File.write(file_ver, $INFRA_VERSION)
114
- end
115
-
116
- # Infra repository compatibility
117
- # < 0.0.37 - Use a template file of build env file.
118
- # => Migration required.
119
- # >= 0.0.37 - Using a generic version of build env file, fully managed by forj cli.
120
- # => No migration
121
-
122
- def infra_rebuild_required?(oConfig, infra_dir)
123
- # This function check if the current infra is compatible with current gem version.
124
-
125
- return false if not File.exists?(infra_dir)
126
-
127
- if infra_dir != File.join($FORJ_DATA_PATH, 'infra')
128
- # Do not take care. We do not manage it, ourself.
129
- return false
130
- end
131
-
132
- file_ver = File.join(infra_dir, 'forj-cli.ver')
133
- forj_infra_version = nil
134
- forj_infra_version = File.read(file_ver) if File.exist?(file_ver)
135
-
136
- if forj_infra_version
137
- return false if Gem::Version.new(forj_infra_version) == Gem::Version.new($INFRA_VERSION)
138
- return true if Gem::Version.new(forj_infra_version) < Gem::Version.new($INFRA_VERSION)
139
- end
140
- # Before version 0.0.37, version file did not exist. So return true
141
- true
142
- end
143
-
144
- def infra_rebuild(oConfig, infra_dir)
145
- return false if not File.exists?(infra_dir)
146
-
147
- file_ver = File.join(infra_dir, 'forj-cli.ver')
148
- forj_infra_version = nil
149
- forj_infra_version = File.read(file_ver) if File.exist?(file_ver)
150
-
151
- if forj_infra_version.nil? or forj_infra_version == ""
152
- # Prior version 37
153
- return(old_infra_data_update(oConfig, '0.0.36', infra_dir))
154
- elsif Gem::Version.new(forj_infra_version) < Gem::Version.new($INFRA_VERSION)
155
- return(old_infra_data_update(oConfig, forj_infra_version, infra_dir))
156
- end
157
- end
158
-
159
- def old_infra_data_update(oConfig, version, infra_dir)
160
- Logging.info("Migrating your local infra repo (%s) to the latest version." % version)
161
- bRebuild = false # Be default migration is successful. No need to rebuild it.
162
- case version
163
- when '0.0.36'
164
- # Moving from 0.0.36 or less to 0.0.37 or higher.
165
- # SET_COMPUTE="{SET_COMPUTE!}" => Setting for Compute. ignored. Coming from HPC
166
- # SET_TENANT_NAME="{SET_TENANT_NAME!}" => Setting for Compute. ignored. Need to query HPC from current Tenant ID
167
-
168
- # SET_DNS_TENANTID="{SET_DNS_TENANTID!}" => Setting for DNS. meta = dns_tenantid
169
- # ==> :forj_accounts, sAccountName, :dns, :tenant_id
170
-
171
- # SET_DNS_ZONE="{SET_DNS_ZONE!}" => Setting for DNS. meta = dns_zone
172
- # ==> :forj_accounts, sAccountName, :dns, :service
173
-
174
- # SET_DOMAIN="{SET_DOMAIN!}" => Setting for Maestro (required) and DNS if enabled.
175
- # ==> :forj_accounts, sAccountName, :dns, :domain_name
176
- sAccountName = oConfig.get(:account_name)
177
-
178
- yDns = {}
179
- yDns = oConfig.oConfig.ExtraGet(:forj_accounts, sAccountName, :dns) if oConfig.oConfig.ExtraExist?(:forj_accounts, sAccountName, :dns)
180
- Dir.foreach(infra_dir) do | file |
181
- next if not /^maestro\.box\..*\.env$/ =~ file
182
- build_env = File.join(infra_dir, file)
183
- Logging.debug("Reading data from '%s'" % build_env)
184
- tags = {'SET_DNS_TENANTID' => :tenant_id,
185
- 'SET_DNS_ZONE' => :service,
186
- 'SET_DOMAIN' => :domain_name
187
- }
188
- begin
189
- bUpdate = nil
190
-
191
- File.open(build_env) do |f|
192
- f.each_line do |line|
193
- mObj = line.match(/^(SET_[A-Z_]+)=["'](.*)["'].*$/)
194
- if mObj
195
- Logging.debug("Reviewing detected '%s' tag" % [mObj[1]])
196
- tag = (tags[mObj[1]]? tags[mObj[1]] : nil)
197
- if tag and mObj[2]
198
- if bUpdate == nil and rhGet(yDns, tag) and rhGet(yDns, tag) != mObj[2]
199
- Logging.message("Your account setup is different than build env.")
200
- Logging.message("We suggest you to update your account setup with data from your build env.")
201
- bUpdate = agree("Do you want to update your setup with those build environment data?")
202
- end
203
- if bUpdate != nil and bUpdate
204
- Logging.debug("Saved: '%s' = '%s'" % [mObj[1],mObj[2]])
205
- rhSet(yDns, mObj[2], tag)
206
- end
207
- end
208
- end
209
- end
210
- end
211
- rescue => e
212
- Logging.fatal(1, "Failed to open the build environment file '%s'" % build_env, e)
213
- end
214
- end
215
- file_ver = File.join(infra_dir, 'forj-cli.ver')
216
- File.write(file_ver, $INFRA_VERSION)
217
- oConfig.oConfig.ExtraSet(:forj_accounts, sAccountName, :dns, yDns)
218
- oConfig.oConfig.ExtraSave(File.join($FORJ_ACCOUNTS_PATH, sAccountName), :forj_accounts, sAccountName)
219
- return bRebuild
220
- end
221
- end
222
- end