visor-meta 0.0.1
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.
- data/bin/visor-meta +8 -0
- data/lib/meta/backends/base.rb +302 -0
- data/lib/meta/backends/mongo_db.rb +195 -0
- data/lib/meta/backends/mysql_db.rb +235 -0
- data/lib/meta/cli.rb +333 -0
- data/lib/meta/client.rb +313 -0
- data/lib/meta/server.rb +295 -0
- data/lib/meta/version.rb +5 -0
- data/lib/visor-meta.rb +12 -0
- data/spec/lib/backends/base_spec.rb +209 -0
- data/spec/lib/backends/mongo_db_spec.rb +152 -0
- data/spec/lib/backends/mysql_db_spec.rb +164 -0
- data/spec/lib/client_spec.rb +179 -0
- data/spec/lib/server_spec.rb +214 -0
- metadata +209 -0
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'mysql2'
|
2
|
+
require 'json'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Visor::Meta
|
6
|
+
module Backends
|
7
|
+
|
8
|
+
# The MySQL Backend for the VISoR Meta.
|
9
|
+
#
|
10
|
+
class MySQL < Base
|
11
|
+
include Visor::Common::Exception
|
12
|
+
|
13
|
+
# Connection constants
|
14
|
+
#
|
15
|
+
# Default MySQL database
|
16
|
+
DEFAULT_DB = 'visor'
|
17
|
+
# Default MySQL host address
|
18
|
+
DEFAULT_HOST = '127.0.0.1'
|
19
|
+
# Default MySQL host port
|
20
|
+
DEFAULT_PORT = 3306
|
21
|
+
# Default MySQL user
|
22
|
+
DEFAULT_USER = 'visor'
|
23
|
+
# Default MySQL password
|
24
|
+
DEFAULT_PASSWORD = 'passwd'
|
25
|
+
|
26
|
+
#CREATE DATABASE visor;
|
27
|
+
#CREATE USER 'visor'@'localhost' IDENTIFIED BY 'visor';
|
28
|
+
#SET PASSWORD FOR 'visor'@'localhost' = PASSWORD('passwd');
|
29
|
+
#GRANT ALL PRIVILEGES ON visor.* TO 'visor'@'localhost';
|
30
|
+
|
31
|
+
# Initializes a MongoDB Backend instance.
|
32
|
+
#
|
33
|
+
# @option [Hash] opts Any of the available options can be passed.
|
34
|
+
#
|
35
|
+
# @option opts [String] :uri The connection uri, if provided, no other option needs to be setted.
|
36
|
+
# @option opts [String] :db (DEFAULT_DB) The wanted database.
|
37
|
+
# @option opts [String] :host (DEFAULT_HOST) The host address.
|
38
|
+
# @option opts [Integer] :port (DEFAULT_PORT) The port to be used.
|
39
|
+
# @option opts [String] :user (DEFAULT_USER) The user to be used.
|
40
|
+
# @option opts [String] :password (DEFAULT_PASSWORD) The password to be used.
|
41
|
+
# @option opts [Object] :conn The connection pool to access database.
|
42
|
+
#
|
43
|
+
def self.connect(opts = {})
|
44
|
+
opts[:uri] ||= ''
|
45
|
+
uri = URI.parse(opts[:uri])
|
46
|
+
opts[:db] = uri.path ? uri.path.gsub('/', '') : DEFAULT_DB
|
47
|
+
opts[:host] = uri.host || DEFAULT_HOST
|
48
|
+
opts[:port] = uri.port || DEFAULT_PORT
|
49
|
+
opts[:user] = uri.user || DEFAULT_USER
|
50
|
+
opts[:password] = uri.password || DEFAULT_PASSWORD
|
51
|
+
|
52
|
+
self.new opts
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(opts)
|
56
|
+
super opts
|
57
|
+
@conn = connection
|
58
|
+
@conn.query %[
|
59
|
+
CREATE TABLE IF NOT EXISTS `#{opts[:db]}`.`images` (
|
60
|
+
`_id` VARCHAR(45) NOT NULL ,
|
61
|
+
`uri` VARCHAR(255) NULL ,
|
62
|
+
`name` VARCHAR(45) NOT NULL ,
|
63
|
+
`architecture` VARCHAR(45) NOT NULL ,
|
64
|
+
`access` VARCHAR(45) NOT NULL ,
|
65
|
+
`type` VARCHAR(45) NULL ,
|
66
|
+
`format` VARCHAR(45) NULL ,
|
67
|
+
`store` VARCHAR(45) NULL ,
|
68
|
+
`location` VARCHAR(255) NULL ,
|
69
|
+
`kernel` VARCHAR(45) NULL ,
|
70
|
+
`ramdisk` VARCHAR(45) NULL ,
|
71
|
+
`owner` VARCHAR(45) NULL ,
|
72
|
+
`status` VARCHAR(45) NULL ,
|
73
|
+
`size` INT NULL ,
|
74
|
+
`created_at` DATETIME NULL ,
|
75
|
+
`uploaded_at` DATETIME NULL ,
|
76
|
+
`updated_at` DATETIME NULL ,
|
77
|
+
`accessed_at` DATETIME NULL ,
|
78
|
+
`access_count` INT NULL DEFAULT 0 ,
|
79
|
+
`checksum` VARCHAR(255) NULL ,
|
80
|
+
`others` VARCHAR(255) NULL,
|
81
|
+
PRIMARY KEY (`_id`) )
|
82
|
+
ENGINE = InnoDB;
|
83
|
+
]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Establishes and returns a MySQL database connection and
|
87
|
+
# creates Images table if it does not exists.
|
88
|
+
#
|
89
|
+
# @return [Mysql2::Client] It returns a database client object.
|
90
|
+
#
|
91
|
+
def connection
|
92
|
+
Mysql2::Client.new(host: @host, port: @port, database: @db,
|
93
|
+
username: @user, password: @password)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns the requested image metadata.
|
97
|
+
#
|
98
|
+
# @param [String] id The requested image's _id.
|
99
|
+
#
|
100
|
+
# @return [Hash] The requested image metadata.
|
101
|
+
#
|
102
|
+
# @raise [NotFound] If image not found.
|
103
|
+
#
|
104
|
+
def get_image(id, pass_timestamps = false)
|
105
|
+
meta = @conn.query("SELECT * FROM images WHERE _id='#{id}'", symbolize_keys: true).first
|
106
|
+
raise NotFound, "No image found with id '#{id}'." if meta.nil?
|
107
|
+
|
108
|
+
set_protected_get(id) unless pass_timestamps
|
109
|
+
|
110
|
+
exclude(meta)
|
111
|
+
meta
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns an array with the public images metadata.
|
115
|
+
#
|
116
|
+
# @param [true, false] brief (false) If true, the returned images will
|
117
|
+
# only contain BRIEF attributes.
|
118
|
+
#
|
119
|
+
# @option [Hash] filters Image attributes for filtering the returned results.
|
120
|
+
# Besides common attributes filters, the following options can be passed to.
|
121
|
+
#
|
122
|
+
# @option opts [String] :sort (_id) The image attribute to sort returned results.
|
123
|
+
#
|
124
|
+
# @return [Array] The public images metadata.
|
125
|
+
#
|
126
|
+
# @raise [NotFound] If there is no public images.
|
127
|
+
#
|
128
|
+
def get_public_images(brief = false, filters = {})
|
129
|
+
validate_query_filters filters unless filters.empty?
|
130
|
+
|
131
|
+
sort = [(filters.delete(:sort) || '_id'), (filters.delete(:dir) || 'asc')]
|
132
|
+
filter = {access: 'public'}.merge(filters)
|
133
|
+
fields = brief ? BRIEF.join(', ') : '*'
|
134
|
+
|
135
|
+
pub = @conn.query("SELECT #{fields} FROM images WHERE #{to_sql_where(filter)}
|
136
|
+
ORDER BY #{sort[0]} #{sort[1]}", symbolize_keys: true).to_a
|
137
|
+
|
138
|
+
raise NotFound, "No public images found." if pub.empty? && filters.empty?
|
139
|
+
raise NotFound, "No public images found with given parameters." if pub.empty?
|
140
|
+
pub.each { |meta| exclude(meta) } if fields == '*'
|
141
|
+
pub
|
142
|
+
end
|
143
|
+
|
144
|
+
# Delete an image record.
|
145
|
+
#
|
146
|
+
# @param [String] id The image's _id to remove.
|
147
|
+
#
|
148
|
+
# @return [Hash] The deleted image metadata.
|
149
|
+
#
|
150
|
+
# @raise [NotFound] If image not found.
|
151
|
+
#
|
152
|
+
def delete_image(id)
|
153
|
+
meta = @conn.query("SELECT * FROM images WHERE _id='#{id}'", symbolize_keys: true).first
|
154
|
+
raise NotFound, "No image found with id '#{id}'." if meta.nil?
|
155
|
+
|
156
|
+
@conn.query "DELETE FROM images WHERE _id='#{id}'"
|
157
|
+
meta
|
158
|
+
end
|
159
|
+
|
160
|
+
# Delete all images records.
|
161
|
+
#
|
162
|
+
def delete_all!
|
163
|
+
@conn.query "DELETE FROM images"
|
164
|
+
end
|
165
|
+
|
166
|
+
# Create a new image record for the given metadata.
|
167
|
+
#
|
168
|
+
# @param [Hash] meta The metadata.
|
169
|
+
# @option [Hash] opts Any of the available options can be passed.
|
170
|
+
#
|
171
|
+
# @option opts [String] :owner (Nil) The owner of the image.
|
172
|
+
# @option opts [Integer] :size (Nil) The image file size.
|
173
|
+
#
|
174
|
+
# @return [Hash] The already inserted image metadata.
|
175
|
+
# @raise [Invalid] If image meta validation fails.
|
176
|
+
#
|
177
|
+
def post_image(meta, opts = {})
|
178
|
+
validate_data_post meta
|
179
|
+
|
180
|
+
set_protected_post meta, opts
|
181
|
+
serialize_others(meta)
|
182
|
+
|
183
|
+
keys_values = to_sql_insert(meta)
|
184
|
+
@conn.query "INSERT INTO images #{keys_values[0]} VALUES #{keys_values[1]}"
|
185
|
+
self.get_image(meta[:_id], true)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Update an image's metadata.
|
189
|
+
#
|
190
|
+
# @param [String] id The image _id to update.
|
191
|
+
# @param [Hash] update The image metadata to update.
|
192
|
+
#
|
193
|
+
# @return [Hash] The updated image metadata.
|
194
|
+
# @raise [Invalid] If update metadata validation fails.
|
195
|
+
# @raise [NotFound] If image not found.
|
196
|
+
#
|
197
|
+
def put_image(id, update)
|
198
|
+
validate_data_put update
|
199
|
+
img = @conn.query("SELECT * FROM images WHERE _id='#{id}'", symbolize_keys: true).first
|
200
|
+
raise NotFound, "No image found with id '#{id}'." if img.nil?
|
201
|
+
|
202
|
+
set_protected_put update
|
203
|
+
serialize_others(update)
|
204
|
+
|
205
|
+
@conn.query "UPDATE images SET #{to_sql_update(update)} WHERE _id='#{id}'"
|
206
|
+
self.get_image(id, true)
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
private
|
211
|
+
|
212
|
+
# Excludes details that should not be disclosed on get detailed image meta.
|
213
|
+
# Also deserialize others attributes from the others column.
|
214
|
+
#
|
215
|
+
# @return [Hash] The image parameters that should not be retrieved from database.
|
216
|
+
#
|
217
|
+
def exclude(meta)
|
218
|
+
deserialize_others(meta)
|
219
|
+
DETAIL_EXC.each { |key| meta.delete(key) }
|
220
|
+
end
|
221
|
+
|
222
|
+
# Atomically set protected fields value from a get operation.
|
223
|
+
# Being them the accessed_at and access_count.
|
224
|
+
#
|
225
|
+
# @param [String] id The _id of the image being retrieved.
|
226
|
+
# @param [Mysql2::Client] conn The connection to the database.
|
227
|
+
#
|
228
|
+
def set_protected_get(id)
|
229
|
+
@conn.query "UPDATE images SET accessed_at='#{Time.now}', access_count=access_count+1 WHERE _id='#{id}'"
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
data/lib/meta/cli.rb
ADDED
@@ -0,0 +1,333 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'logger'
|
3
|
+
require 'optparse'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'rack'
|
6
|
+
|
7
|
+
module Visor
|
8
|
+
module Meta
|
9
|
+
class CLI
|
10
|
+
|
11
|
+
attr_reader :app, :cli_name, :argv, :options,
|
12
|
+
:port, :host, :env, :command, :parser
|
13
|
+
|
14
|
+
# Available commands
|
15
|
+
COMMANDS = %w[start stop restart status clean]
|
16
|
+
# Commands that wont load options from the config file
|
17
|
+
NO_CONF_COMMANDS = %w[stop status]
|
18
|
+
# Default config files directories to look at
|
19
|
+
DEFAULT_DIR = File.expand_path('~/.visor')
|
20
|
+
# Default host address
|
21
|
+
DEFAULT_HOST = '0.0.0.0'
|
22
|
+
# Default port
|
23
|
+
DEFAULT_PORT = 4567
|
24
|
+
# Default application environment
|
25
|
+
DEFAULT_ENV = :production
|
26
|
+
|
27
|
+
# Initialize a CLI
|
28
|
+
#
|
29
|
+
def initialize(app, cli_name, argv=ARGV)
|
30
|
+
@app = app
|
31
|
+
@cli_name = cli_name
|
32
|
+
@argv = argv
|
33
|
+
@options = default_opts
|
34
|
+
@parser = parser
|
35
|
+
@command = parse!
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_opts
|
39
|
+
{debug: false,
|
40
|
+
foreground: false,
|
41
|
+
no_proxy: false,
|
42
|
+
environment: DEFAULT_ENV}
|
43
|
+
end
|
44
|
+
|
45
|
+
# OptionParser parser
|
46
|
+
#
|
47
|
+
def parser
|
48
|
+
OptionParser.new do |opts|
|
49
|
+
opts.banner = "Usage: #{cli_name} [OPTIONS] COMMAND"
|
50
|
+
|
51
|
+
opts.separator ""
|
52
|
+
opts.separator "Commands:"
|
53
|
+
opts.separator " start start the server"
|
54
|
+
opts.separator " stop stop the server"
|
55
|
+
opts.separator " restart restart the server"
|
56
|
+
opts.separator " status current server status"
|
57
|
+
|
58
|
+
opts.separator ""
|
59
|
+
opts.separator "Options:"
|
60
|
+
|
61
|
+
opts.on("-c", "--config FILE", "Load a custom configuration file") do |file|
|
62
|
+
options[:config] = File.expand_path(file)
|
63
|
+
end
|
64
|
+
opts.on("-o", "--host HOST", "listen on HOST (default: #{DEFAULT_HOST})") do |host|
|
65
|
+
options[:host] = host.to_s
|
66
|
+
end
|
67
|
+
opts.on("-p", "--port PORT", "use PORT (default: #{DEFAULT_PORT})") do |port|
|
68
|
+
options[:port] = port.to_i
|
69
|
+
end
|
70
|
+
opts.on("-x", "--no-proxy", "ignore proxy settings if any") do
|
71
|
+
options[:no_proxy] = true
|
72
|
+
end
|
73
|
+
opts.on("-e", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: #{DEFAULT_ENV})") do |env|
|
74
|
+
options[:environment] = env.to_sym
|
75
|
+
end
|
76
|
+
opts.on("-F", "--foreground", "don't daemonize, run in the foreground") do
|
77
|
+
options[:foreground] = true
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.separator ""
|
81
|
+
opts.separator "Common options:"
|
82
|
+
|
83
|
+
opts.on_tail("-d", "--debug", "Set debugging on (with foreground only)") do
|
84
|
+
options[:debug] = true
|
85
|
+
end
|
86
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
87
|
+
puts opts
|
88
|
+
exit
|
89
|
+
end
|
90
|
+
opts.on_tail('-v', '--version', "Show version") do
|
91
|
+
puts "VISoR Meta Server v#{Visor::Meta::VERSION}"
|
92
|
+
exit
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Parse the current shell arguments and run the command.
|
98
|
+
# Exits on error.
|
99
|
+
#
|
100
|
+
def run!
|
101
|
+
if command.nil?
|
102
|
+
abort @parser.to_s
|
103
|
+
elsif COMMANDS.include?(command)
|
104
|
+
run_command
|
105
|
+
else
|
106
|
+
abort "Unknown command: #{command}. Available commands: #{COMMANDS.join(', ')}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Execute the command
|
111
|
+
#
|
112
|
+
def run_command
|
113
|
+
unless NO_CONF_COMMANDS.include?(command)
|
114
|
+
@conf = load_conf_file
|
115
|
+
@host = options[:host] || @conf[:bind_host] || DEFAULT_HOST
|
116
|
+
@port = options[:port] || @conf[:bind_port] || DEFAULT_PORT
|
117
|
+
@env = options[:environment]
|
118
|
+
end
|
119
|
+
|
120
|
+
case command
|
121
|
+
when 'start' then start
|
122
|
+
when 'stop' then stop
|
123
|
+
when 'restart' then restart
|
124
|
+
when 'status' then status
|
125
|
+
else clean
|
126
|
+
end
|
127
|
+
exit 0
|
128
|
+
end
|
129
|
+
|
130
|
+
# Remove all files created by the daemon.
|
131
|
+
#
|
132
|
+
def clean
|
133
|
+
begin
|
134
|
+
FileUtils.rm(pid_file) rescue Errno::ENOENT
|
135
|
+
end
|
136
|
+
begin
|
137
|
+
FileUtils.rm(url_file) rescue Errno::ENOENT
|
138
|
+
end
|
139
|
+
put_and_log :warn, "Removed all files created by server start"
|
140
|
+
end
|
141
|
+
|
142
|
+
# Restart server
|
143
|
+
#
|
144
|
+
def restart
|
145
|
+
@restart = true
|
146
|
+
stop
|
147
|
+
sleep 0.1 while running?
|
148
|
+
start
|
149
|
+
end
|
150
|
+
|
151
|
+
# Display current server status
|
152
|
+
#
|
153
|
+
def status
|
154
|
+
if running?
|
155
|
+
STDERR.puts "#{cli_name} is running PID: #{fetch_pid} URL: #{fetch_url}"
|
156
|
+
else
|
157
|
+
STDERR.puts "#{cli_name} is not running."
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# Stop the server
|
162
|
+
#
|
163
|
+
def stop
|
164
|
+
begin
|
165
|
+
pid = File.read(pid_file)
|
166
|
+
put_and_log :warn, "Stopping #{cli_name} with PID: #{pid.to_i} Signal: INT"
|
167
|
+
Process.kill(:INT, pid.to_i)
|
168
|
+
File.delete(url_file)
|
169
|
+
rescue
|
170
|
+
put_and_log :warn, "Cannot stop #{cli_name}, is it running?"
|
171
|
+
exit! 1
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Start the server
|
176
|
+
#
|
177
|
+
def start
|
178
|
+
FileUtils.mkpath(DEFAULT_DIR)
|
179
|
+
begin
|
180
|
+
is_it_running?
|
181
|
+
can_use_port?
|
182
|
+
write_url
|
183
|
+
launch!
|
184
|
+
rescue => e
|
185
|
+
put_and_log :warn, "ERROR starting #{cli_name}: #{e}"
|
186
|
+
exit! 1
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Launch the server
|
191
|
+
#
|
192
|
+
def launch!
|
193
|
+
put_and_log :info, "Starting #{cli_name} at #{host}:#{port}"
|
194
|
+
debug_settings
|
195
|
+
|
196
|
+
Rack::Server.start(app: app,
|
197
|
+
Host: host,
|
198
|
+
Port: port,
|
199
|
+
environment: get_env,
|
200
|
+
daemonize: daemonize?,
|
201
|
+
pid: pid_file)
|
202
|
+
end
|
203
|
+
|
204
|
+
protected
|
205
|
+
|
206
|
+
def is_it_running?
|
207
|
+
if files_exist?(pid_file, url_file)
|
208
|
+
if running?
|
209
|
+
put_and_log :warn, "'#{cli_name}' is already running at #{fetch_url}"
|
210
|
+
exit! 1
|
211
|
+
else
|
212
|
+
clean
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def running?
|
218
|
+
begin
|
219
|
+
Process.kill 0, fetch_pid
|
220
|
+
true
|
221
|
+
rescue Errno::ESRCH
|
222
|
+
false
|
223
|
+
rescue Errno::EPERM
|
224
|
+
true
|
225
|
+
rescue
|
226
|
+
false
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def can_use_port?
|
231
|
+
unless port_open?
|
232
|
+
put_and_log :warn, "Port #{port} already in use. Please try other."
|
233
|
+
exit! 1
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def port_open?
|
238
|
+
begin
|
239
|
+
options[:no_proxy] ? open(url, proxy: nil) : open(url)
|
240
|
+
false
|
241
|
+
rescue OpenURI::HTTPError #TODO: quick-fix, try solve this
|
242
|
+
false
|
243
|
+
rescue Errno::ECONNREFUSED
|
244
|
+
true
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def daemonize?
|
249
|
+
!options[:foreground]
|
250
|
+
end
|
251
|
+
|
252
|
+
def get_env
|
253
|
+
env == 'development' ? env : 'deployment'
|
254
|
+
end
|
255
|
+
|
256
|
+
def logger
|
257
|
+
@conf ||= load_conf_file
|
258
|
+
@logger ||=
|
259
|
+
begin
|
260
|
+
log = options[:foreground] ? Logger.new(STDERR) : Visor::Common::Config.build_logger(:visor_meta)
|
261
|
+
conf_level = @conf[:log_level] == 'INFO' ? 1 : 0
|
262
|
+
log.level = options[:debug] ? 0 : conf_level
|
263
|
+
log.formatter = Proc.new {|s, t, n, msg| "[#{t.strftime("%Y-%m-%d %H:%M:%S")}] #{s} - #{msg}\n"}
|
264
|
+
log
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def put_and_log(level, msg)
|
269
|
+
STDERR.puts msg
|
270
|
+
logger.send level, msg
|
271
|
+
end
|
272
|
+
|
273
|
+
def parse!
|
274
|
+
parser.parse! argv
|
275
|
+
argv.shift
|
276
|
+
end
|
277
|
+
|
278
|
+
def debug_settings
|
279
|
+
logger.debug "Configurations loaded from #{@conf[:file]}:"
|
280
|
+
logger.debug "***************************************************"
|
281
|
+
@conf.each { |k, v| logger.debug "#{k}: #{v}" }
|
282
|
+
logger.debug "***************************************************"
|
283
|
+
|
284
|
+
logger.debug "Configurations passed from #{cli_name} CLI:"
|
285
|
+
logger.debug "***************************************************"
|
286
|
+
options.each { |k, v| logger.debug "#{k}: #{v}" if options[k] != default_opts[k] }
|
287
|
+
logger.debug "***************************************************"
|
288
|
+
end
|
289
|
+
|
290
|
+
def files_exist?(*files)
|
291
|
+
files.each { |file| return false unless File.exists?(File.expand_path(file)) }
|
292
|
+
true
|
293
|
+
end
|
294
|
+
|
295
|
+
def write_url
|
296
|
+
File.open(url_file, 'w') { |f| f << url }
|
297
|
+
end
|
298
|
+
|
299
|
+
def load_conf_file
|
300
|
+
Visor::Common::Config.load_config(:visor_meta, options[:config])
|
301
|
+
end
|
302
|
+
|
303
|
+
def safe_cli_name
|
304
|
+
cli_name.gsub('-', '_')
|
305
|
+
end
|
306
|
+
|
307
|
+
def fetch_pid
|
308
|
+
IO.read(pid_file).to_i
|
309
|
+
rescue
|
310
|
+
nil
|
311
|
+
end
|
312
|
+
|
313
|
+
def fetch_url
|
314
|
+
IO.read(url_file).split('//').last
|
315
|
+
rescue
|
316
|
+
nil
|
317
|
+
end
|
318
|
+
|
319
|
+
def pid_file
|
320
|
+
File.join(DEFAULT_DIR, "#{safe_cli_name}.pid")
|
321
|
+
end
|
322
|
+
|
323
|
+
def url_file
|
324
|
+
File.join(DEFAULT_DIR, "#{safe_cli_name}.url")
|
325
|
+
end
|
326
|
+
|
327
|
+
def url
|
328
|
+
"http://#{host}:#{port}"
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|