forj 0.0.43 → 0.0.44
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/bin/forj +49 -120
- data/lib/appinit.rb +50 -0
- data/lib/boot.rb +30 -43
- data/lib/connection.rb +28 -5
- data/lib/defaults.yaml +115 -61
- data/lib/forj-account.rb +168 -50
- data/lib/forj-config.rb +204 -148
- data/lib/forj-settings.rb +209 -0
- data/lib/helpers.rb +1 -5
- data/lib/log.rb +1 -25
- data/lib/repositories.rb +5 -4
- data/spec/connection_spec.rb +9 -10
- data/spec/forj-config_spec.rb +21 -20
- metadata +4 -2
data/lib/defaults.yaml
CHANGED
@@ -41,6 +41,8 @@
|
|
41
41
|
:build_config: box
|
42
42
|
:branch: master
|
43
43
|
:box_name: maestro
|
44
|
+
|
45
|
+
:provider_name: hpcloud
|
44
46
|
:description:
|
45
47
|
# Description of build.sh environment variable defined by forj cli for build.sh. (~/.forj/infra/build/<Account>.build.env)
|
46
48
|
:FORJ_HPC: "HPCloud cli Account used to build your Maestro box"
|
@@ -57,64 +59,116 @@
|
|
57
59
|
:FORJ_DNS_ZONE: "HPCloud Domain name service to use for each boxes DNS entries. (Ex: region-a.geo-1)"
|
58
60
|
:FORJ_DNS_DOMAIN: "Domain used for DNS. Each server will be attached to a public IP. An 'A' record in the DNS service will need to be added to your HPCloud DOMAIN."
|
59
61
|
|
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
|
-
|
62
|
+
# Following declares generic FORJ data to handle Fog object (compute/network/dns/...)
|
63
|
+
# It defines the account file structure. section/key=value
|
64
|
+
# All data can be predefined by default value (config.yaml/defaults.yaml) except
|
65
|
+
# those identified by :account_exclusive: true
|
66
|
+
:sections:
|
67
|
+
# This section define updatable data available from config.yaml. But will never be added in an account file.
|
68
|
+
# Used by forj set/get functions
|
69
|
+
:default:
|
70
|
+
:account_name:
|
71
|
+
:desc: "Default account name used by forj cli"
|
72
|
+
:provider_name:
|
73
|
+
:desc: "Default provider name while running forj setup. By default, hpcloud is selected."
|
74
|
+
# Defines account credentials data
|
75
|
+
:account:
|
76
|
+
:name:
|
77
|
+
:desc: "Name of the Forj cli account. use forj account rename <oldName> <NewName> to update it."
|
78
|
+
:readonly: true
|
79
|
+
:account_exclusive: true
|
80
|
+
:provider:
|
81
|
+
:desc: "Provider name attached to the forj cli account. To update it, use forj setup."
|
82
|
+
:readonly: true
|
83
|
+
:account_exclusive: true
|
84
|
+
:default: :provider_name
|
85
|
+
|
86
|
+
# Defines services
|
87
|
+
:services:
|
88
|
+
:compute:
|
89
|
+
:desc: "Generic service identification for compute"
|
90
|
+
:account_exclusive: true
|
91
|
+
:account: true
|
92
|
+
:network:
|
93
|
+
:desc: "Generic service identification for network"
|
94
|
+
:account_exclusive: true
|
95
|
+
:account: true
|
96
|
+
|
97
|
+
# Defines ssh keys credentials
|
98
|
+
:credentials:
|
99
|
+
:keypair_path:
|
100
|
+
:desc: "public key file to send to the cloud under keypair name, and private key to keep on your local forj environment to access your boxes."
|
101
|
+
:keypair_name:
|
102
|
+
:desc: "keypair name defined in your cloud to access your server. By default we named it 'forj'. If it doesn't exist, it will be created."
|
103
|
+
:auth_uri:
|
104
|
+
:desc: "Generic service auth url"
|
105
|
+
:account_exclusive: true
|
106
|
+
:account: true
|
107
|
+
:required: true
|
108
|
+
:ask_sort: 0
|
109
|
+
:account_id:
|
110
|
+
:desc: "Generic Cloud Account name."
|
111
|
+
:account_exclusive: true
|
112
|
+
:account: true
|
113
|
+
:required: true
|
114
|
+
:account_key:
|
115
|
+
:desc: "Generic cloud account key"
|
116
|
+
:account_exclusive: true
|
117
|
+
:account: true
|
118
|
+
:required: true
|
119
|
+
:tenant:
|
120
|
+
:desc: "Generic Tenant identification"
|
121
|
+
:account_exclusive: true
|
122
|
+
:account: true
|
123
|
+
:required: true
|
124
|
+
:os_user:
|
125
|
+
:desc: "User name required by Maestro to access the cloud compute via openstack. Will be obsoleted soon."
|
126
|
+
:account_exclusive: true
|
127
|
+
:account: true
|
128
|
+
:required: true
|
129
|
+
:validate: !ruby/regexp /\w+/
|
130
|
+
:os_enckey:
|
131
|
+
:desc: "Encrypted password required by Maestro to access the cloud compute via openstack. Will be obsoleted soon."
|
132
|
+
:account_exclusive: true
|
133
|
+
:encrypted: true
|
134
|
+
:account: true
|
135
|
+
:required: true
|
136
|
+
|
137
|
+
# Defines DNS services for maestro
|
138
|
+
:dns:
|
139
|
+
:service:
|
140
|
+
:desc: "DNS service region name Maestro will use."
|
141
|
+
:account_exclusive: true
|
142
|
+
:tenant_id:
|
143
|
+
:desc: "DNS Tenant ID Maestro will use"
|
144
|
+
:account_exclusive: true
|
145
|
+
:domain_name:
|
146
|
+
:desc: "Domain name added to each hosts."
|
147
|
+
:account_exclusive: true
|
148
|
+
|
149
|
+
:maestro:
|
150
|
+
:tenant_name:
|
151
|
+
:desc: "Tenant name required by fog/openstack on gardener"
|
152
|
+
:network_name:
|
153
|
+
:desc: "Network name to attach to each forge boxes. By default we use 'forj'. If it doesn't exist, it will be created."
|
154
|
+
:default: network
|
155
|
+
:security_group:
|
156
|
+
:desc: "Security group name to configure and attach to each forge boxes."
|
157
|
+
:maestro_repo:
|
158
|
+
:desc: "To use a different Maestro repository already cloned."
|
159
|
+
:infra_repo:
|
160
|
+
:desc: "Defines your Infra directory to use while booting."
|
161
|
+
:box_name:
|
162
|
+
:desc: "forj cli use 'build.sh' to create Maestro. See box_name option on build.sh to get more information. By default 'maestro'"
|
163
|
+
:build_config:
|
164
|
+
:desc: "forj cli use 'build.sh' to create Maestro. See build_config option on build.sh to get more information. By default 'box'"
|
165
|
+
:bp_flavor:
|
166
|
+
:desc: "Blueprint nodes default flavor. Usually, blueprint node are smaller than Maestro."
|
167
|
+
:flavor:
|
168
|
+
:desc: "Maestro Flavor name. This flavor is for Maestro only. Your blueprint layout defines each node flavors on needs."
|
169
|
+
:image:
|
170
|
+
:desc: "Image used to create Maestro and all forge boxes. By default, it is 'Ubuntu Precise 12.04.4 LTS Server 64-bit 20140414 (Rescue Image)'"
|
171
|
+
:ports:
|
172
|
+
:desc: "List of security group rules (1 port or range of ports) to open to the external network."
|
173
|
+
:branch:
|
174
|
+
:desc: "Branch to use to build your forge"
|
data/lib/forj-account.rb
CHANGED
@@ -45,10 +45,38 @@ class ForjAccounts
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
# ForjAccount manage a list of key/value grouped by section.
|
49
|
+
# The intent of ForjAccount is to attach some keys/values to
|
50
|
+
# an account to help end users to switch between each of them.
|
51
|
+
#
|
52
|
+
# ForjAccount based on ForjConfig (see forj-config.rb)
|
53
|
+
# ensure ForjConfig and ForjAccount defines following common functions
|
54
|
+
# - set (key, value)
|
55
|
+
# - get (key)
|
56
|
+
#
|
57
|
+
# This means that key HAVE to be unique across sections
|
58
|
+
# By default, keys maps with the same key name in ForjConfig.
|
59
|
+
# But we can redefine the ForjConfig mapping of any key on need.
|
60
|
+
#
|
61
|
+
# ForjConfig, loads Account meta structure from defaults.yaml, sections
|
62
|
+
#
|
63
|
+
# defaults.yaml structure is:
|
64
|
+
# sections:
|
65
|
+
# default: => defines key/values recognized by ForjAccount to be only managed by ForjConfig.
|
66
|
+
# <key> :
|
67
|
+
# :desc : <value> => defines the ForjConfig key description.
|
68
|
+
# <section>: Define a section name. For each keys on this section, the account file will kept those data under this section.
|
69
|
+
# <key>:
|
70
|
+
# :desc: defines the key description.
|
71
|
+
# :readonly: true if this key cannot be updated by ForjAccount.set
|
72
|
+
# :account_exclusive: true if this key cannot be predefined on ForjConfig keys list
|
73
|
+
# :default: <ForjConfig real key name> Used to map the ForjAccount key to a different ForjConfig key name.
|
74
|
+
|
48
75
|
class ForjAccount
|
49
76
|
|
50
77
|
attr_reader :sAccountName
|
51
78
|
attr_reader :hAccountData
|
79
|
+
attr_reader :oConfig
|
52
80
|
|
53
81
|
# This object manage data located in oConfig[:hpc_accounts/AccountName]
|
54
82
|
|
@@ -67,53 +95,148 @@ class ForjAccount
|
|
67
95
|
sProvider = @oConfig.get(:provider) if @oConfig.get(:provider)
|
68
96
|
|
69
97
|
@hAccountData = {}
|
70
|
-
|
71
|
-
|
98
|
+
_set(:account, :name, @sAccountName) if exist?(:name) != 'hash'
|
99
|
+
_set(:account, :provider, sProvider) if exist?(:provider) != 'hash'
|
100
|
+
|
72
101
|
end
|
73
102
|
|
74
|
-
# oForjAccount data get
|
75
|
-
#
|
76
|
-
#
|
103
|
+
# oForjAccount data get at several levels:
|
104
|
+
# - get the data from runtime (runtimeSet/runtimeGet)
|
105
|
+
# - otherwise, get data from account file under section described in defaults.yaml (:account_section_mapping), as soon as this mapping exists.
|
106
|
+
# - otherwise, get the data from the local configuration file. Usually ~/.forj/config.yaml
|
107
|
+
# - otherwise, get the data from defaults.yaml
|
77
108
|
# otherwise, use the get default parameter as value. Default is nil.
|
78
109
|
def get(key, default = nil)
|
79
110
|
return nil if not key
|
80
111
|
|
81
112
|
key = key.to_sym if key.class == String
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
113
|
+
|
114
|
+
return @oConfig.runtimeGet(key) if @oConfig.runtimeExist?(key)
|
115
|
+
|
116
|
+
section = ForjDefault.get_meta_section(key)
|
117
|
+
default_key = key
|
118
|
+
|
119
|
+
if not section
|
87
120
|
Logging.debug("ForjAccount.get: No section found for key '%s'." % [key])
|
121
|
+
else
|
122
|
+
return rhGet(@hAccountData, section, key) if rhExist?(@hAccountData, section, key) == 2
|
123
|
+
|
124
|
+
hMeta = @oConfig.getAppDefault(:sections)
|
125
|
+
if rhExist?(hMeta, section, key, :default) == 3
|
126
|
+
default_key = rhGet(hMeta, section, key, :default)
|
127
|
+
Logging.debug("ForjAccount.get: Reading default key '%s' instead of '%s'" % [default_key, key])
|
128
|
+
end
|
129
|
+
return default if rhExist?(hMeta, section, key, :account_exclusive) == 3
|
88
130
|
end
|
89
|
-
|
131
|
+
|
132
|
+
@oConfig.get(default_key , default )
|
90
133
|
end
|
91
134
|
|
92
135
|
def exist?(key)
|
93
136
|
return nil if not key
|
94
137
|
|
95
138
|
key = key.to_sym if key.class == String
|
96
|
-
section =
|
97
|
-
|
98
|
-
|
99
|
-
|
139
|
+
section = ForjDefault.get_meta_section(key)
|
140
|
+
if not section
|
141
|
+
Logging.debug("ForjAccount.exist?: No section found for key '%s'." % [key])
|
142
|
+
return nil
|
143
|
+
end
|
144
|
+
return @sAccountName if rhExist?(@hAccountData, section, key) == 2
|
145
|
+
|
146
|
+
hMeta = @oConfig.getAppDefault(:sections)
|
147
|
+
if rhExist?(hMeta, section, key, :default) == 3
|
148
|
+
default_key = rhGet(hMeta, section, key, :default)
|
149
|
+
Logging.debug("ForjAccount.exist?: Reading default key '%s' instead of '%s'" % [default_key, key])
|
150
|
+
else
|
151
|
+
default_key = key
|
152
|
+
end
|
153
|
+
return nil if rhExist?(hMeta, section, key, :account_exclusive) == 3
|
154
|
+
|
155
|
+
@oConfig.exist?(default_key)
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
# Return true if readonly. set won't be able to update this value.
|
160
|
+
# Only _set (private function) is able.
|
161
|
+
def readonly?(key)
|
162
|
+
return nil if not key
|
163
|
+
|
164
|
+
key = key.to_sym if key.class == String
|
165
|
+
section = ForjDefault.get_meta_section(key)
|
166
|
+
|
167
|
+
rhGet(@oConfig.getAppDefault(:sections, section), key, :readonly)
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
def meta_set(key, hMeta)
|
172
|
+
key = key.to_sym if key.class == String
|
173
|
+
section = ForjDefault.get_meta_section(key)
|
174
|
+
hCurMeta = rhGet(@oConfig.getAppDefault(:sections, section), key)
|
175
|
+
hMeta.each { | mykey, myvalue |
|
176
|
+
rhSet(hCurMeta, myvalue, mykey)
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
def meta_exist?(key)
|
181
|
+
return nil if not key
|
182
|
+
|
183
|
+
key = key.to_sym if key.class == String
|
184
|
+
section = ForjDefault.get_meta_section(key)
|
185
|
+
rhExist?(@oConfig.getAppDefault(:sections, section), key) == 1
|
186
|
+
end
|
187
|
+
|
188
|
+
def get_meta_section(key)
|
189
|
+
key = key.to_sym if key.class == String
|
190
|
+
rhGet(@account_section_mapping, key)
|
191
|
+
end
|
192
|
+
|
193
|
+
def meta_type?(key)
|
194
|
+
return nil if not key
|
195
|
+
|
196
|
+
section = ForjDefault.get_meta_section(key)
|
197
|
+
|
198
|
+
return section if section == :default
|
199
|
+
@sAccountName
|
200
|
+
end
|
201
|
+
|
202
|
+
# Loop on account metadata
|
203
|
+
def metadata_each
|
204
|
+
rhGet(ForjDefault.dump(), :sections).each { | section, hValue |
|
205
|
+
next if section == :default
|
206
|
+
hValue.each { | key, value |
|
207
|
+
yield section, key, value
|
208
|
+
}
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
# Return true if exclusive
|
213
|
+
def exclusive?(key)
|
214
|
+
return nil if not key
|
215
|
+
|
216
|
+
key = key.to_sym if key.class == String
|
217
|
+
section = ForjDefault.get_meta_section(key)
|
100
218
|
|
219
|
+
rhGet(@oConfig.getAppDefault(:sections, section), key, :account_exclusive)
|
101
220
|
end
|
102
221
|
|
222
|
+
# This function update a section/key=value if the account structure is defined.
|
223
|
+
# If no section is defined, set it in runtime config.
|
103
224
|
def set(key, value)
|
104
225
|
return nil if not key
|
105
226
|
|
106
227
|
key = key.to_sym if key.class == String
|
107
|
-
section =
|
108
|
-
|
109
|
-
|
228
|
+
section = ForjDefault.get_meta_section(key)
|
229
|
+
|
230
|
+
return @oConfig.set(key, value) if not section
|
231
|
+
return nil if readonly?(key)
|
232
|
+
_set(section, key, value)
|
110
233
|
end
|
111
234
|
|
112
235
|
def del(key)
|
113
236
|
return nil if not key
|
114
237
|
|
115
238
|
key = key.to_sym if key.class == String
|
116
|
-
section =
|
239
|
+
section = ForjDefault.get_meta_section(key)
|
117
240
|
return nil if not section
|
118
241
|
rhSet(@hAccountData, nil, section, key)
|
119
242
|
end
|
@@ -123,23 +246,30 @@ class ForjAccount
|
|
123
246
|
default
|
124
247
|
end
|
125
248
|
|
126
|
-
def
|
249
|
+
def ac_new(sAccountName)
|
250
|
+
return nil if sAccountName.nil?
|
251
|
+
@sAccountName = sAccountName
|
252
|
+
@sAccountFile = File.join($FORJ_ACCOUNTS_PATH, @sAccountName)
|
253
|
+
|
254
|
+
@hAccountData = {:account => {:name => sAccountName, :provider => @oConfig.get(:provider_name)}}
|
255
|
+
end
|
256
|
+
|
257
|
+
def ac_load(sAccountName = @sAccountName, bHPCloudLoad = true)
|
127
258
|
# Load Account Information
|
128
259
|
|
129
260
|
if sAccountName != @sAccountName
|
130
|
-
|
131
|
-
@sAccountFile = File.join($FORJ_ACCOUNTS_PATH, @sAccountName)
|
261
|
+
ac_new(sAccountName)
|
132
262
|
end
|
133
263
|
|
134
264
|
if File.exists?(@sAccountFile)
|
135
265
|
@hAccountData = @oConfig.ExtraLoad(@sAccountFile, :forj_accounts, @sAccountName)
|
136
266
|
# Check if hAccountData are using symbol or needs to be updated.
|
137
|
-
sProvider = @oConfig.get(:provider,
|
267
|
+
sProvider = @oConfig.get(:provider, 'hpcloud')
|
138
268
|
rhSet(@hAccountData, @sAccountName, :account, :name) if rhExist?(@hAccountData, :account, :name) != 2
|
139
269
|
rhSet(@hAccountData, sProvider, :account, :provider) if rhExist?(@hAccountData, :account, :provider) != 2
|
140
|
-
provider_load()
|
270
|
+
provider_load() if bHPCloudLoad
|
141
271
|
if rhKeyToSymbol?(@hAccountData, 2)
|
142
|
-
@hAccountData = rhKeyToSymbol(@hAccountData, 2)
|
272
|
+
@hAccountData = rhKeyToSymbol(@hAccountData, 2)
|
143
273
|
self.ac_save()
|
144
274
|
end
|
145
275
|
return @hAccountData
|
@@ -178,7 +308,7 @@ class ForjAccount
|
|
178
308
|
|
179
309
|
# Checking cloud connection
|
180
310
|
Logging.message("Checking cloud connection")
|
181
|
-
ForjConnection.new(
|
311
|
+
ForjConnection.new(self)
|
182
312
|
|
183
313
|
Logging.message("Setup '%s' done. Thank you." % @sAccountName)
|
184
314
|
end
|
@@ -236,7 +366,7 @@ class ForjAccount
|
|
236
366
|
if tenant_name
|
237
367
|
Logging.debug("Tenant ID '%s': '%s' found." % [tenant_id, tenant_name])
|
238
368
|
hCompute = { :tenant_name => tenant_name }
|
239
|
-
rhSet(@hAccountData, hCompute, :
|
369
|
+
rhSet(@hAccountData, hCompute, :maestro)
|
240
370
|
else
|
241
371
|
Logging.error("Unable to find the tenant Name for '%s' ID." % tenant_id)
|
242
372
|
end
|
@@ -334,12 +464,12 @@ class ForjAccount
|
|
334
464
|
q.validate = /.*+/
|
335
465
|
end
|
336
466
|
keys_entered = keypair_detect(key_name, key_path)
|
337
|
-
if not keys_entered[:private_key_exist?] and not keys_entered[:public_key_exist?]
|
467
|
+
if not keys_entered[:private_key_exist? ] and not keys_entered[:public_key_exist? ]
|
338
468
|
if agree("The key you entered was not found. Do you want to create this one?")
|
339
469
|
base_dir = keys_entered[:keypair_path]
|
340
470
|
if not File.directory?(base_dir)
|
341
471
|
if agree("'%s' doesn't exist. Do you want to create it?" % base_dir)
|
342
|
-
|
472
|
+
AppInit.ensure_dir_exists(base_dir)
|
343
473
|
end
|
344
474
|
end
|
345
475
|
else
|
@@ -366,7 +496,7 @@ class ForjAccount
|
|
366
496
|
|
367
497
|
|
368
498
|
# Creation sequences
|
369
|
-
if not keys[:private_key_exist?]
|
499
|
+
if not keys[:private_key_exist? ]
|
370
500
|
# Need to create a key. ask if we need so.
|
371
501
|
Logging.message("The private key file attached to keypair named '%s' is not found. forj will propose to create one for you. Please review the proposed private key file name and path.\nYou can press Enter to accept the default value." % keys[:keypair_name])
|
372
502
|
real_key_path = File.expand_path(ask("Private key file path:") do |q|
|
@@ -374,7 +504,7 @@ class ForjAccount
|
|
374
504
|
q.default = private_key_file
|
375
505
|
end)
|
376
506
|
if not File.exists?(real_key_path)
|
377
|
-
|
507
|
+
AppInit.ensure_dir_exists(File.dirname(real_key_path))
|
378
508
|
command = 'ssh-keygen -t rsa -f %s' % real_key_path
|
379
509
|
Logging.debug("Executing '%s'" % command)
|
380
510
|
system(command)
|
@@ -390,7 +520,7 @@ class ForjAccount
|
|
390
520
|
end
|
391
521
|
end
|
392
522
|
|
393
|
-
if not keys[:public_key_exist?]
|
523
|
+
if not keys[:public_key_exist? ]
|
394
524
|
Logging.message("Your public key '%s' was not found. Getting it from the private one. It may require your passphrase." % [public_key_file])
|
395
525
|
command = 'ssh-keygen -y -f %s > %s' % [private_key_file,public_key_file ]
|
396
526
|
Logging.debug("Executing '%s'" % command)
|
@@ -522,24 +652,12 @@ class ForjAccount
|
|
522
652
|
}
|
523
653
|
Logging.info("'%s' written." % cloud_fog)
|
524
654
|
end
|
525
|
-
|
655
|
+
# private functions
|
656
|
+
private
|
657
|
+
def _set(section, key, value)
|
658
|
+
return nil if not key or not section
|
526
659
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
# Defining Global variables
|
531
|
-
$FORJ_DATA_PATH = File.expand_path(File.join('~', '.forj'))
|
532
|
-
$FORJ_ACCOUNTS_PATH = File.join($FORJ_DATA_PATH, 'accounts')
|
533
|
-
$FORJ_KEYPAIRS_PATH = File.join($FORJ_DATA_PATH, 'keypairs')
|
534
|
-
$FORJ_CREDS_PATH = File.expand_path(File.join('~', '.cache', 'forj'))
|
535
|
-
|
536
|
-
# TODO: To move to an hpcloud object.
|
537
|
-
$HPC_KEYPAIRS = File.expand_path(File.join('~', '.hpcloud', 'keypairs'))
|
538
|
-
$HPC_ACCOUNTS = File.expand_path(File.join('~', '.hpcloud', 'accounts'))
|
660
|
+
rhSet(@hAccountData, value, section, key)
|
661
|
+
end
|
539
662
|
|
540
|
-
Helpers.ensure_dir_exists($FORJ_DATA_PATH)
|
541
|
-
Helpers.ensure_dir_exists($FORJ_ACCOUNTS_PATH)
|
542
|
-
Helpers.ensure_dir_exists($FORJ_KEYPAIRS_PATH)
|
543
|
-
FileUtils.chmod(0700, $FORJ_KEYPAIRS_PATH)
|
544
|
-
Helpers.ensure_dir_exists($FORJ_CREDS_PATH)
|
545
663
|
end
|