forj 1.0.3 → 1.0.4
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 +4 -4
- data/.rubocop.yml +59 -0
- data/Gemfile +14 -15
- data/Rakefile +11 -3
- data/bin/forj +231 -338
- data/forj.gemspec +4 -7
- data/forj/defaults.yaml +3 -3
- data/lib/appinit.rb +21 -32
- data/lib/boot.rb +156 -0
- data/lib/cloud_connection.rb +42 -0
- data/lib/cloud_test.rb +86 -68
- data/lib/destroy.rb +97 -0
- data/lib/forj-settings.rb +350 -167
- data/lib/forj/ForjCli.rb +12 -14
- data/lib/forj/ForjCore.rb +78 -85
- data/lib/forj/process/ForjProcess.rb +1157 -771
- data/lib/get.rb +51 -0
- data/lib/ssh.rb +86 -78
- data/spec/boot_spec.rb +0 -1
- data/spec/spec_helper.rb +65 -65
- metadata +14 -22
data/forj.gemspec
CHANGED
@@ -19,8 +19,8 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.name = 'forj'
|
20
20
|
s.homepage = 'https://www.forj.io'
|
21
21
|
|
22
|
-
s.version = '1.0.
|
23
|
-
s.date = '
|
22
|
+
s.version = '1.0.4'
|
23
|
+
s.date = '2015-02-10'
|
24
24
|
s.summary = 'forj command line'
|
25
25
|
s.description = 'forj cli - See https://www.forj.io for documentation/information'
|
26
26
|
|
@@ -44,7 +44,7 @@ Gem::Specification.new do |s|
|
|
44
44
|
s.require_paths = %w[lib]
|
45
45
|
|
46
46
|
s.add_runtime_dependency 'thor', '>=0.16.0'
|
47
|
-
s.add_runtime_dependency 'fog', '1.
|
47
|
+
s.add_runtime_dependency 'fog', '~>1.26.0'
|
48
48
|
s.add_runtime_dependency 'git', '>=1.2.7'
|
49
49
|
s.add_runtime_dependency 'highline', '>= 1.6.21'
|
50
50
|
s.add_runtime_dependency 'ansi', '>= 1.4.3'
|
@@ -52,13 +52,10 @@ Gem::Specification.new do |s|
|
|
52
52
|
s.add_runtime_dependency 'json', '1.7.5'
|
53
53
|
s.add_runtime_dependency 'bundler'
|
54
54
|
s.add_runtime_dependency 'nokogiri','1.5.11'
|
55
|
-
s.add_runtime_dependency 'lorj', '~> 0.2
|
55
|
+
s.add_runtime_dependency 'lorj', '~> 1.0.2'
|
56
56
|
|
57
|
-
s.add_development_dependency "bundler"
|
58
57
|
s.add_development_dependency "rake", "~> 10.0"
|
59
58
|
s.add_development_dependency "rspec", "~> 3.1.0"
|
60
59
|
s.rdoc_options << '--title' << 'Lorj - The Process Controllers framework system' <<
|
61
60
|
'--main' << 'README.md'
|
62
|
-
|
63
|
-
|
64
61
|
end
|
data/forj/defaults.yaml
CHANGED
@@ -184,19 +184,19 @@
|
|
184
184
|
:desc: "Domain name added to each hosts."
|
185
185
|
:account_exclusive: true
|
186
186
|
:account: true
|
187
|
-
:post_step_function: :
|
187
|
+
:post_step_function: :forj_dns_settings
|
188
188
|
:ask_step: 3
|
189
189
|
:dns_service:
|
190
190
|
:desc: "DNS service region name Maestro will use."
|
191
191
|
:account_exclusive: true
|
192
192
|
:account: true
|
193
|
-
:pre_step_function: :
|
193
|
+
:pre_step_function: :forj_dns_settings?
|
194
194
|
:ask_step: 3
|
195
195
|
:dns_tenant_id:
|
196
196
|
:desc: "DNS Tenant ID Maestro will use"
|
197
197
|
:account_exclusive: true
|
198
198
|
:account: true
|
199
|
-
:pre_step_function: :
|
199
|
+
:pre_step_function: :forj_dns_settings?
|
200
200
|
:ask_step: 3
|
201
201
|
|
202
202
|
:maestro:
|
data/lib/appinit.rb
CHANGED
@@ -14,39 +14,28 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
|
18
|
-
require 'lorj'
|
19
|
-
|
20
17
|
# Module to initialize the application
|
21
18
|
# TODO: Cleanup about Global variables used. Should be replaced by PrcLib
|
22
19
|
# or other kind of setting.
|
23
|
-
module
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
AppInit.ensure_dir_exists($FORJ_CREDS_PATH)
|
45
|
-
end
|
46
|
-
|
47
|
-
def AppInit.ensure_dir_exists(path)
|
48
|
-
if not PrcLib.dir_exists?(path)
|
49
|
-
FileUtils.mkpath(path) if not File.directory?(path)
|
50
|
-
end
|
51
|
-
end
|
20
|
+
module Forj
|
21
|
+
class << self
|
22
|
+
attr_accessor :build_path, :keypairs_path
|
23
|
+
end
|
24
|
+
|
25
|
+
module_function
|
26
|
+
|
27
|
+
def keypairs_path=(v)
|
28
|
+
@keypairs_path = File.expand_path(v) unless @keypairs_path
|
29
|
+
PrcLib.ensure_dir_exists(@keypairs_path)
|
30
|
+
begin
|
31
|
+
FileUtils.chmod(0700, @keypairs_path) # no-op on windows
|
32
|
+
rescue => e
|
33
|
+
fatal_error(1, e.message)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_path=(v)
|
38
|
+
@build_path = File.expand_path(v) unless @build_path
|
39
|
+
PrcLib.ensure_dir_exists(@build_path)
|
40
|
+
end
|
52
41
|
end
|
data/lib/boot.rb
ADDED
@@ -0,0 +1,156 @@
|
|
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 'highline/import'
|
19
|
+
require 'cloud_connection.rb'
|
20
|
+
#
|
21
|
+
# Boot module
|
22
|
+
#
|
23
|
+
module Forj
|
24
|
+
# This module provides the behavior to boot your forge
|
25
|
+
module Boot
|
26
|
+
@account = nil
|
27
|
+
attr_accessor :account
|
28
|
+
|
29
|
+
def self.deprecated_name?(blueprint, on_or_name,
|
30
|
+
old_accountname, as,
|
31
|
+
old_name
|
32
|
+
)
|
33
|
+
# depreciated: <BluePrint> on <AccountName> as <InstanceName>
|
34
|
+
if old_accountname && as && old_name
|
35
|
+
msg = format(
|
36
|
+
"The syntax `forj boot '%s' on '%s' as '%s'`" \
|
37
|
+
" is depreciated. \nUse `forj boot '%s' '%s' ",
|
38
|
+
blueprint, old_accountname, old_name, blueprint, old_name
|
39
|
+
)
|
40
|
+
|
41
|
+
if account.get('account_name') == old_accountname
|
42
|
+
PrcLib.warning('%s` instead.', msg)
|
43
|
+
else
|
44
|
+
PrcLib.warning("%s -a '%s'` instead.", msg, old_accountname)
|
45
|
+
end
|
46
|
+
name = old_name
|
47
|
+
@account.set(:account_name, old_accountname)
|
48
|
+
else
|
49
|
+
name = on_or_name
|
50
|
+
end
|
51
|
+
name
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.load_options(options, options_map)
|
55
|
+
options_map.each do |opt_key, ac_key|
|
56
|
+
unless options[opt_key].nil?
|
57
|
+
value = yield(opt_key, options[opt_key])
|
58
|
+
@account.set(ac_key, options[opt_key]) unless value.nil?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.validate_keypath(options)
|
64
|
+
if options[:key_path]
|
65
|
+
m_found = options[:key_path].match(/^(.*)(\.pub)?$/)
|
66
|
+
if m_found
|
67
|
+
key_path = File.expand_path(m_found[1])
|
68
|
+
if m_found[2] && !(File.exist?(
|
69
|
+
File.expand_path(m_found[1] + m_found[2])
|
70
|
+
))
|
71
|
+
PrcLib.fatal(
|
72
|
+
1,
|
73
|
+
"'%s' is not a valid keypair files." \
|
74
|
+
' At least the public key (.pub) is have to exist.',
|
75
|
+
key_path
|
76
|
+
)
|
77
|
+
end
|
78
|
+
@account.set(:keypair_path, key_path)
|
79
|
+
else
|
80
|
+
PrcLib.fatal(
|
81
|
+
1,
|
82
|
+
"'%s' is not a valid keypair files." \
|
83
|
+
'At least the public key (.pub) is have to exist.',
|
84
|
+
key_path
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.install_blueprint?(blueprint, name)
|
91
|
+
@account[:instance_name] = name
|
92
|
+
|
93
|
+
if blueprint == 'maestro'
|
94
|
+
PrcLib.info("Starting boot process of '%s'. No blueprint requested.",
|
95
|
+
@account[:instance_name])
|
96
|
+
else
|
97
|
+
@account[:blueprint] = blueprint
|
98
|
+
PrcLib.info("Starting boot process of '%s' with blueprint '%s'.",
|
99
|
+
@account[:instance_name], @account[:blueprint])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.boot(blueprint, on_or_name, deprecated_name, options)
|
104
|
+
@account = Lorj::Account.new(options[:config])
|
105
|
+
|
106
|
+
name = deprecated_name?(blueprint, on_or_name, deprecated_name[0],
|
107
|
+
deprecated_name[1], deprecated_name[2])
|
108
|
+
|
109
|
+
PrcLib.fatal(1, "instance name '%s' not supported. Support only lower" \
|
110
|
+
' case, numeric and dash caracters.',
|
111
|
+
name) unless /^[\d[[:lower:]]-]+$/ =~ name
|
112
|
+
|
113
|
+
# Options are added if they are set.
|
114
|
+
# Otherwise, get will retrieve the default value.
|
115
|
+
|
116
|
+
@account[:account_name] = options[:account_name] if options[:account_name]
|
117
|
+
|
118
|
+
@account.ac_load @account[:account_name]
|
119
|
+
|
120
|
+
options_map = { :infra => :infra_repo, :key_name => :keypair_name,
|
121
|
+
:key_path => :keypair_path,
|
122
|
+
:security_group => :security_group,
|
123
|
+
:image_name => :image_name, :maestro_flavor => :flavor,
|
124
|
+
:bp_flavor => :bp_flavor, :maestro_repo => :maestro_repo,
|
125
|
+
:branch => :branch, :test_box => :test_box }
|
126
|
+
|
127
|
+
load_options(options, options_map) do |key, value|
|
128
|
+
case key
|
129
|
+
when :test_box
|
130
|
+
path = File.expand_path(value)
|
131
|
+
return path if File.directory?(path)
|
132
|
+
return nil
|
133
|
+
end
|
134
|
+
value
|
135
|
+
end
|
136
|
+
|
137
|
+
PrcLib.warning(
|
138
|
+
'test_box is currently disabled in this version.' \
|
139
|
+
'It will be re-activated in newer version.'
|
140
|
+
) if options[:test_box]
|
141
|
+
|
142
|
+
validate_keypath(options)
|
143
|
+
|
144
|
+
# o_cloud = get_o_cloud(o_forj_account)
|
145
|
+
o_cloud = Forj::CloudConnection.connect(@account)
|
146
|
+
|
147
|
+
install_blueprint?(blueprint, name)
|
148
|
+
PrcLib.high_level_msg("Preparing your forge '%s'.Please be patient. "\
|
149
|
+
"more output in '%s'\n",
|
150
|
+
@account[:instance_name],
|
151
|
+
PrcLib.log_file)
|
152
|
+
|
153
|
+
o_cloud.create(:forge)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,42 @@
|
|
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
|
+
module Forj
|
19
|
+
# Provide cloud object
|
20
|
+
module CloudConnection
|
21
|
+
def self.connect(account)
|
22
|
+
a_processes = []
|
23
|
+
|
24
|
+
# Defines how to manage Maestro and forges
|
25
|
+
# create a maestro box. Identify a forge instance, delete it,...
|
26
|
+
a_processes << File.join(LIB_PATH, 'forj', 'ForjCore.rb')
|
27
|
+
|
28
|
+
# Defines how cli will control FORJ features
|
29
|
+
# boot/down/ssh/...
|
30
|
+
a_processes << File.join(LIB_PATH, 'forj', 'ForjCli.rb')
|
31
|
+
|
32
|
+
# Loading CloudCore embedding provider controller + its process.
|
33
|
+
o_cloud = Lorj::CloudCore.new(
|
34
|
+
account,
|
35
|
+
account[:account_name],
|
36
|
+
a_processes
|
37
|
+
)
|
38
|
+
|
39
|
+
o_cloud
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/cloud_test.rb
CHANGED
@@ -1,121 +1,139 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
#require 'byebug'
|
3
|
+
# require 'byebug'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
APP_PATH = File.dirname(__FILE__)
|
6
|
+
LIB_PATH = File.expand_path(File.join(File.dirname(APP_PATH), 'lib'))
|
7
7
|
|
8
|
-
|
8
|
+
LOAD_PATH << LIB_PATH
|
9
9
|
|
10
|
-
|
10
|
+
LOAD_PATH << File.join(LIB_PATH, 'lib-forj', 'lib')
|
11
11
|
|
12
12
|
require 'appinit.rb'
|
13
13
|
|
14
14
|
# Initialize forj paths
|
15
|
-
AppInit
|
15
|
+
AppInit.forj_initialize
|
16
16
|
|
17
17
|
# Initialize global Log object
|
18
|
-
|
18
|
+
FORJ_LOGGER = ForjLog.new
|
19
19
|
|
20
20
|
require 'lib-forj.rb'
|
21
21
|
|
22
22
|
Logging.set_level(Logger::DEBUG)
|
23
23
|
|
24
24
|
# Load global Config
|
25
|
-
|
25
|
+
o_config = ForjConfig.new
|
26
26
|
|
27
|
-
|
27
|
+
a_processes = []
|
28
28
|
|
29
29
|
# Defines how to manage Maestro and forges
|
30
30
|
# create a maestro box. Identify a forge instance, delete it,...
|
31
|
-
|
31
|
+
a_processes << File.join(LIB_PATH, 'forj', 'ForjCore.rb')
|
32
32
|
|
33
33
|
# Defines how cli will control FORJ features
|
34
34
|
# boot/down/ssh/...
|
35
|
-
|
35
|
+
a_processes << File.join(LIB_PATH, 'forj', 'ForjCli.rb')
|
36
36
|
|
37
|
-
|
37
|
+
# PrcLib.core_level = 3 # verbose
|
38
38
|
|
39
|
-
infra_dir = File.expand_path(
|
39
|
+
infra_dir = File.expand_path(o_config.get(:infra_repo))
|
40
40
|
|
41
41
|
# Ask information if needed.
|
42
|
-
|
43
|
-
|
42
|
+
unless Dir.exist?(File.expand_path(infra_dir))
|
43
|
+
Logging.warning(<<-END
|
44
44
|
Your infra workspace directory is missing.
|
45
45
|
|
46
|
-
Forj uses an infra workspace directory to store any kind of data that are
|
47
|
-
|
48
|
-
|
46
|
+
Forj uses an infra workspace directory to store any kind of data that are
|
47
|
+
private to you.
|
48
|
+
We provides ways to send those data securily to your new Forge instance,
|
49
|
+
as metadata.
|
50
|
+
In production case, we suggest you to keep it safe in your SCM preferred
|
51
|
+
database.
|
49
52
|
|
50
|
-
If you already have an existing infra workspace,
|
53
|
+
If you already have an existing infra workspace,
|
54
|
+
use 'forj set infra_repo=<PathToYourRepo>' to set it and restart.
|
51
55
|
|
52
|
-
Otherwise, we will build a new one with some predefined data,
|
56
|
+
Otherwise, we will build a new one with some predefined data,
|
57
|
+
you can review and update later.
|
53
58
|
END
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
)
|
60
|
+
s_ask = format(
|
61
|
+
'Do you want to create a new one from Maestro (yes/no)?',
|
62
|
+
infra_dir
|
63
|
+
)
|
64
|
+
b_build_infra = agree(s_ask)
|
65
|
+
unless b_build_infra
|
66
|
+
puts 'Process aborted on your demand.'
|
67
|
+
exit 0
|
68
|
+
end
|
61
69
|
end
|
62
70
|
|
63
|
-
|
64
|
-
|
65
|
-
#oConfig.set(:instance_name, "test")
|
66
|
-
#oCloud.Create(:metadata)
|
67
|
-
#oCloud.Create(:infra_repository)
|
68
|
-
#oCloud.Create(:userdata)
|
71
|
+
o_cloud = ForjCloud.new(o_config, 'hpcloud', a_processes)
|
69
72
|
|
73
|
+
# o_config.set(:instance_name, "test")
|
74
|
+
# o_cloud.Create(:metadata)
|
75
|
+
# o_cloud.Create(:infra_repository)
|
76
|
+
# o_cloud.Create(:userdata)
|
70
77
|
|
71
|
-
#
|
72
|
-
#
|
78
|
+
# o_cloud.Setup(:server, 'hpcloud')
|
79
|
+
# o_cloud.Setup(:forge, 'hpcloud')
|
73
80
|
|
74
|
-
#
|
81
|
+
# o_cloud.Create(:forge)
|
75
82
|
|
76
|
-
#
|
77
|
-
#
|
83
|
+
# o_config.set(:instance_name, 'servertestluis')
|
84
|
+
# o_cloud.Create(:forge)
|
78
85
|
|
79
|
-
|
86
|
+
o_forge = o_cloud.Get(:forge, 'luistest')
|
80
87
|
|
81
|
-
#Ask the user to get server(s) to destroy
|
88
|
+
# Ask the user to get server(s) to destroy
|
82
89
|
server_id_length = 0
|
83
90
|
server_name_length = 0
|
84
91
|
|
85
|
-
|
86
|
-
if server[:id].length
|
87
|
-
server_id_length = server[:id].length
|
92
|
+
o_forge[:server].each do |server|
|
93
|
+
if server[:id].length > server_id_length
|
94
|
+
server_id_length = server[:id].length
|
88
95
|
end
|
89
96
|
|
90
|
-
if server[:name].length
|
91
|
-
server_name_length = server[:name].length
|
97
|
+
if server[:name].length > server_name_length
|
98
|
+
server_name_length = server[:name].length
|
92
99
|
end
|
93
|
-
|
100
|
+
end
|
94
101
|
|
95
102
|
server_index = 1
|
96
|
-
#Display headers
|
97
|
-
puts
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
103
|
+
# Display headers
|
104
|
+
puts format(
|
105
|
+
'|%s |%s |%s |',
|
106
|
+
'Index '.ljust(6),
|
107
|
+
'Name'.ljust(server_name_length),
|
108
|
+
'ID'.ljust(server_id_length)
|
109
|
+
)
|
110
|
+
# Display Forge servers detail
|
111
|
+
o_forge[:server].each do |server|
|
112
|
+
puts format(
|
113
|
+
'|%s |%s |%s |',
|
114
|
+
server_index.to_s.ljust(6),
|
115
|
+
server[:name].to_s.ljust(server_name_length),
|
116
|
+
server[:id].to_s.ljust(server_id_length)
|
117
|
+
)
|
118
|
+
server_index += 1
|
110
119
|
end
|
111
120
|
|
121
|
+
o_high_line = HighLine.new
|
122
|
+
|
123
|
+
index = o_high_line.ask(
|
124
|
+
'Select the index of the server to create the ssh connection',
|
125
|
+
Integer
|
126
|
+
) do |q|
|
127
|
+
q.below = o_forge[:server].count + 1
|
128
|
+
q.above = 0
|
129
|
+
end
|
112
130
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
|
131
|
+
o_config.set(:instance_name, 'luistest')
|
132
|
+
o_config.set(:forge_server, o_forge[:server][index - 1][:id])
|
133
|
+
o_config.set(:server_name, o_forge[:server][index - 1][:name])
|
134
|
+
# o_config.set(:box, 'maestro')
|
135
|
+
# o_config.set(:instance_name, 'luistest')
|
136
|
+
# o_config.Create(:server)
|
137
|
+
o_cloud.Create(:ssh)
|
120
138
|
|
121
|
-
#
|
139
|
+
# o_cloud.Query(:server, 'maestro')
|